APCS-32 & 'float' argument passing

John Tytgat John.Tytgat at aaug.net
Wed Jun 9 14:31:26 PDT 2004


In message <40C71BDB.4060409 at dsvr.net>
          Nick Burrett <nick at dsvr.net> wrote:

> John Tytgat wrote:
> > I can only conclude GCC is not completely APCS-32 compliant.
> 
> The reason is that GCC 3.3 and later conforms to the ATPCS:

Uh, this is a suprise to me and would explain what I see.

> [ATPCS spec]
> In section 7.1
> 
> Conceptually primitive floating-point values (float, double) are handled 
> at the machine level and require no conversion.

Indeed for ATPCS, not for APCS-R not APCS-32.

> > Has this been discussed before ? Could this be fixed in GCC please (this
> > means also a couple of fixes in UnixLib) ?
> 
> This has never been an issue before.  I'm 100% certain that APCS-R does 
> not promote 32-bit float arguments to 64-bit double arguments. 
> Otherwise the code would never have been written that way.

I'm afraid that is not correct (cfr. the APCS-32 / APCS-R quotes in my
original mails).  Also a small test with the Norcroft v5.06 (latest
compiler version publically released by Acorn) and v5.54 (one of the
latest versions released by Tematic/Castle) doesn't confirm your view
either :

--8<--
float do_add(float a, float b, float c)
{
return a + b + c;
}
--8<--

Norcroft v5.06 (APCS-R output) :
--8<--
; generated by Norcroft RISC OS ARM C vsn 5.06 (Acorn Computers Ltd) [May 25 1995]

        AREA |C$$code|, CODE, READONLY
|x$codeseg|

        EXPORT  do_add
do_add
        STMDB    sp!,{a1,a2}
        LDFD     f2,[sp],#8
        STMDB    sp!,{a3,a4}
        LDFD     f0,[sp],#8
        LDFD     f1,[sp,#0]
        MVFS     f2,f2
        MVFS     f0,f0
        MVFS     f1,f1
        ADFS     f0,f2,f0
        ADFS     f0,f0,f1
        MOVS     pc,lr

        AREA |C$$data|,DATA

|x$dataseg|

        END
--8<--

Clearly 3 doubles transfered as arguments, not floats.  Likewise for the
following two examples :

Norcroft v5.54 (APCS-R output) :
--8<--
; generated by Norcroft RISC OS ARM C vsn 5.54 [04 Apr 2003]

        AREA |C$$code|, CODE, READONLY
|x$codeseg|

        EXPORT  do_add
do_add
        STMDB    sp!,{a1,a2}
        LDFD     f2,[sp],#8
        STMDB    sp!,{a3,a4}
        LDFD     f0,[sp],#8
        LDFD     f1,[sp,#0]
        MVFS     f2,f2
        MVFS     f0,f0
        MVFS     f1,f1
        ADFS     f0,f2,f0
        ADFS     f0,f0,f1
        MOVS     pc,lr

        AREA |C$$data|,DATA

|x$dataseg|

        END
--8<--

Norcroft v5.54 (APCS-32 output) :
--8<--
; generated by Norcroft RISC OS ARM C vsn 5.54 [04 Apr 2003]

        AREA |C$$code|, CODE, READONLY
|x$codeseg|

        EXPORT  do_add
do_add
        STMDB    sp!,{a1,a2}
        LDFD     f2,[sp],#8
        STMDB    sp!,{a3,a4}
        LDFD     f0,[sp],#8
        LDFD     f1,[sp,#0]
        MVFS     f2,f2
        MVFS     f0,f0
        MVFS     f1,f1
        ADFS     f0,f2,f0
        ADFS     f0,f0,f1
        MOV      pc,lr

        AREA |C$$data|,DATA

|x$dataseg|

        END
--8<--

But it is true that GCC 2.95.4 (release 3) did pass floats as arguments
(wrongly for APCS-R mode IMHO) :

--8<--
; Generated by gcc 2.95.4 20010319 (prerelease) [gccsdk 20020112] for ARM/RISC OS
[snipped the integer/float register definitons]
	AREA |C$$code1|, CODE, READONLY
|gcc2_compiled.|
	ALIGN
	EXPORT	|do_add|
|do_add|
	; args = 0, pretend = 0, frame = 12, alloca = 0
	; frame_needed = 1, anonymous_args = 0, regs_live[14] = 0
	; nonlocal_label = 0, nonlocal_goto = 0, clobbers lr = 0
	mov	__ip, __sp
	stmfd	__sp!, {__v6, __fp, __ip, __lr, __pc}
	sub	__fp, __ip, #4
	cmp	__sp, __sl
	IMPORT	|__rt_stkovf_split_small|
	bllt	|__rt_stkovf_split_small|
	sub	__sp, __sp, #12
	mov	__v6, __sp
	str	__a1, [__v6, #0]	; float
	str	__a2, [__v6, #4]	; float
	str	__a3, [__v6, #8]	; float
	ldfs	__f0, [__v6, #0]
	ldfs	__f2, [__v6, #4]
	adfs	__f1, __f0, __f2
	ldfs	__f0, [__v6, #8]
	adfs	__f1, __f1, __f0
	mvfs	__f0, __f1
	b	|L..2|
|L..2|
	ldmea	__fp, {__v6, __fp, __sp, __pc}^
	END
--8<--

> It should be straightforward to fix this by setting ARM_FLAG_ATPCS 
> rather than ARM_FLAG_APCS_32 in riscos-aof.h.  This will probably change 
> the ABI though.

I'm confused by this statement.  You mean that you set the ARM_FLAG_APCS_32
flags instead of ARM_FLAG_ATPCS ? If so, yes, please do !

John.
-- 
John Tytgat, in his comfy chair at home                                 BASS
John.Tytgat at aaug.net                             ARM powered, RISC OS driven




More information about the gcc mailing list