APCS-32 & 'float' argument passing
John.Tytgat at aaug.net
Sat Jun 5 06:14:29 PDT 2004
Not sure if this has been discussed before (can't search the mail archives)
but there seems to be an incompatibility between GCC 'float' argument
passing and Norcroft's, both in APCS-32 output mode and results in a
problem when using UnixLib with Norcroft.
APCS-32 specifies that floating point values are passed via the integer
registers instead of the floating point registers (not different than
APCS-R) and that's what you can also see in UnixLib's floorf() assembler
STR a1, [sp, #-4]!
LDFS f0, [sp], #4
RNDSM f0, f0
return AL, pc, lr
However, GCC takes this as sizeof(float) == 4, so only a1 is used to
transfer the value but Norcroft is upgrading the 'float' to 'double'
and passes the value in two registers a1 and a2 :
[ Small piece of produced ARM code calling floorf() by Norcroft. ]
[ Small piece of produced ARM code calling floorf() by GCC. ]
Norcroft's implementation of upgrading 'float' to 'double' when passing
floating point values as arguments seems to be conforming the 'APCS'
documents from Acorn/Castle :
C Language Calling Conventions
A floating point value occupies 1, 2, or 3 words, as appropriate to its type.
Floating point values are encoded in IEEE 754 format, with the most significant
word of a double having the lowest address.
The C compiler widens arguments of type float to type double to support
inter-working between ANSI C and classic C.
I can only conclude GCC is not completely APCS-32 compliant.
This incompatibility is slightly annoying when using UnixLib with Norcroft
because currently floorf() (and a couple of other assembler implemented
routines having 'float' arguments) does not produce the correct result
when called from Norcroft compiled code.
Has this been discussed before ? Could this be fixed in GCC please (this
means also a couple of fixes in UnixLib) ?
John Tytgat, in his comfy chair at home BASS
John.Tytgat at aaug.net ARM powered, RISC OS driven
More information about the gcc