Altivec Context Management

Till Straumann strauman at slac.stanford.edu
Fri Nov 4 20:07:31 UTC 2005


The basic problem is the same any multithreaded, non-unix sytem
has with gcc. It lacks an option to suppress implicit usage of 
floating-point
and vector registers. Recap two approaches:

-->  we provide unix semantics:
      compile (explicitely or implicitely) -maltivec -mhard-float and 
save/restore all
      registers (int, float, vec) on every context switch (strictly, we also
      must do this for interrupts unless ISRs are compiled separately
      with -mno-altivec -msoft-float). Note that I already have experienced
      the ISR/FPU (cf. PR833) issue.

      another option is 'lazy-context switching', i.e., at context switch
      disable fp and vec units but dont save/restore anything.
      Trap 1st use by another task and switch registers from
      the exception handler.

    Note that all of these can be costly (we're talking about ~1kB of data)

--> compile everything -mno-altivec (or a cpu < 7400) but implement
     vector context switching and an API to make tasks 'altivec aware'.
     Code executed by such a vector task must then be compiled with
     -maltivec. (There are a few details to be taken care of like vfprintf
     but I have some ideas there, too. No vecs on C++, probably.).

Currently, I favor the less expensive approach (2). I can't stress it 
enough:
what is *really* needed are -fno-implicit-fp / -fno-implicit-altivec gcc 
options.
Anything else will always cause headache.

Baseline: the current -maltivec multilib is of no use. It should be replaced
by

-mcpu=7400 -mno-altivec -mabi=altivec

That way,

a) code can #ifdef  7400 and compile altivec support (__ALTIVEC__ is not 
defined for -mno-altivec)
b) vector unit is never used by kernel/newlib or ordinary application code
c) stack alignment required by altivec is provided

Code to be executed from an altivec-enabled task is then explicitely 
compiled with -maltivec.
It could use the vector engine, finds an aligned stack and the CPU 
support would provide
context switching.

For altivec this is more straightforward to do - more difficult in the 
case of FP because
soft-float has implications on libm.

T.


Joel Sherrill <joel at OARcorp.com> wrote:

> Ralf Corsepius wrote:
>
>> On Fri, 2005-11-04 at 10:25 -0600, Joel Sherrill  wrote:
>>
>
>> The magic is deeply hidden in GCC's sources:
>>
>> Check gcc-4.0.x/gcc/config/rs6000/rs6000.c for POWERPC_7400_MASK.
>
>
> Yep.  It turns on Altivec.
>
>>>  Then RTEMS should just honor the __ALTIVEC__ flag which is set when 
>>> -mcpu=7400 is set.  It will require no tool changes for gcc 4.0.x.
>>>
>>> The gcc version for 4.6 does not set __ALTIVEC__ when -mcpu=7400 is 
>>> specified.
>>
>>
>>
>> I current don't have such a toolchain at hand, but if I recall
>> correctly, it didn't have an -mcpu=7400 multilib variant ;)
>
>
> I lean to fixing this in 4.6 by saying "don't do that".
>
>> Checking GCC-3.4's source code however indicates that -mcpu=7400 already
>> implied -maltivec and -D__ALTIVEC__ in gcc-3.4. This matches with my
>> memory, because I believe altivec had been introduced in gcc-3.4 and
>> then more or less completely rewritten for gcc-4.x).
>
>
> Apparently since it really uses them now. :)
>
>> It's the old problem with powerpc port:
>> powerpc-RTEMS classifies its internals on "cpu-variants", while GCC is
>> on the move towards classifying its internals on "cpu-features".
>
>
> There is no legacy with this issue.  The context switch code just 
> needs to honor Altivec.
>
> I hope we decide the interrupt code doesn't need serious work.  If it 
> does, we may be in for some refactoring and combining.  It is needed 
> anyway.
>
>>> But RTEMS does need to honor the __ALTIVEC__ flag and based upon 
>>> gcc's use of the vector registers, this would mean it is part of the 
>>> basic integer context when available.
>>
>>
>>
>> I recall we had a discussion on this topic when gcc-4.0 ca. at the time
>> when about to be released or just released. The result of this
>> discussion was to add an m7400 multilib variant.
>
>
> Good.  Then we laid the groundwork and now we know what follow up to do.
>
>> BTW: Check gcc-4.0.x/gcc/config/rs6000/rs6000.c for OS_MISSING_ALTIVEC.
>> I didn't try to investigate what it actually is, but it's looks like it
>> probably related to the RTEMS altivec problem
>
>
> It appears to just disable it:
>
> #ifdef OS_MISSING_ALTIVEC
>   if (OS_MISSING_ALTIVEC)
>     set_masks &= ~MASK_ALTIVEC;
> #endif
>
> Not particularly useful.  An automated version of "don't do that, it 
> hurts." I would rather fix the problem.
>
> --joel





More information about the users mailing list