Altivec Context Management
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
and vector registers. Recap two approaches:
--> we provide unix semantics:
compile (explicitely or implicitely) -maltivec -mhard-float and
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
what is *really* needed are -fno-implicit-fp / -fno-implicit-altivec gcc
Anything else will always cause headache.
Baseline: the current -maltivec multilib is of no use. It should be replaced
-mcpu=7400 -mno-altivec -mabi=altivec
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
For altivec this is more straightforward to do - more difficult in the
case of FP because
soft-float has implications on libm.
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
>> 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
>>> 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;
> Not particularly useful. An automated version of "don't do that, it
> hurts." I would rather fix the problem.
More information about the users