Gcc 3.2.1 arm-elf apcs32 register mishandling

Ryan Pipkin ryan.pipkin@inet.com
Tue Apr 29 00:41:00 GMT 2003


Can someone please verify that this is a problem.  Referring to the 
APCS  a0 - a3, and ip  are used between procedure calls.  Therefore the 
local routine cannot assume any values for these registers beyond a 
branch and link.  When used again they must be loaded again.  I have 
included two samples from a dissassembled object file in which it looks 
like they are being used incorrectly.  I have tested on 3 compiler 
versions as indicated.


Here are the compiler options used:
-c -nostdinc -O3 -mcpu=xscale -msoft-float -mapcs-32 -fno-rtti 
-fno-exceptions -fsigned-char -fno-builtin -b arm-unknown-elf -V 3.2.1

Using 2.96 is not an option due to a stack corruption problem.  I only 
included it in these results for comparision.


3.2.1    (rebuilt from source --target=arm-unknown-elf)
d8:    e50bc02c     str    ip, [fp, -#44]
dc:    ebfffffe     bl    0 <_ZN12PciXScaleDevC2Ej>     (resolves to 
strncpy)
e0:    e289e09c     add    lr, r9, #156    ; 0x9c
e4:    e58ce21c     str    lr, [ip, #540]


3.1        (GNUPRO xscale-020523)
    d8:    e50b302c     str    r3, [fp, -#44]
    dc:    ebfffffe     bl    0 <_ZN12PciXScaleDevC2Ej>    (resolves to 
strncpy)
    e0:    e289a09c     add    sl, r9, #156    ; 0x9c
    e4:    e583a21c     str    sl, [r3, #540]

Same problem different register.


2.96    (GNUPRO xscale-010827)
   I could not find any instance of r0,r1,r2,r3,ip being used with 
assumed value after a bl call.



The source rther investigation wCan someone please verify that this is a 
problem.  Referring to the APCS  a0 - a3, and ip  are used between 
procedure calls.  Therefore the local routine cannot assume any values 
for these registers beyond a branch and link.  When used again they must 
be loaded again.  I have included two samples from a dissassembled 
object file in which it looks like they are being used incorrectly.  I 
have tested on 3 compiler versions as indicated.


Here are the compiler options used:
-c -nostdinc -O3 -mcpu=xscale -msoft-float -mapcs-32 -fno-rtti 
-fno-exceptions -fsigned-char -fno-builtin -b arm-unknown-elf -V 3.2.1

Using 2.96 is not an option due to a stack corruption problem.  I only 
included it in these results for comparision.


3.2.1    (rebuilt from source --target=arm-unknown-elf)
d8:    e50bc02c     str    ip, [fp, -#44]
dc:    ebfffffe     bl    0 <_ZN12PciXScaleDevC2Ej>
e0:    e289e09c     add    lr, r9, #156    ; 0x9c
e4:    e58ce21c     str    lr, [ip, #540]


3.1        (GNUPRO xscale-020523)
    d8:    e50b302c     str    r3, [fp, -#44]
    dc:    ebfffffe     bl    0 <_ZN12PciXScaleDevC2Ej>
    e0:    e289a09c     add    sl, r9, #156    ; 0x9c
    e4:    e583a21c     str    sl, [r3, #540]

Same problem different register.


2.96    (GNUPRO xscale-010827)
   I could not find any instance of r0,r1,r2,r3,ip being used with 
assumed value after a bl call.


What I see is a C++ function calling a C function. The problem seems to 
go away when I use the -mno-apcs-frame option.

My question is: What is the difference in register usage between 
apcs-frame and no-apcs-frame?

Is there a problem with apcs frames here.

I am still looking for references to the apcs setup in gcc, but any help 
would be greatly appreciated.


*  Gcc 3.2.1 xscale defaults to -mapcs-frame

With -mno-apcs-frame  option.


_ZN12PciXScaleDevC2Ej:
   @ args = 0, pretend = 0, frame = 0
   @ frame_needed = 0, uses_anonymous_args = 0
   stmfd    sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}


strncpy:
   @ args = 0, pretend = 0, frame = 0
   @ frame_needed = 0, uses_anonymous_args = 0



---------------------
With -mapcs-frame


_ZN12PciXScaleDevC2Ej:
   @ args = 0, pretend = 0, frame = 4
   @ frame_needed = 1, uses_anonymous_args = 0
   mov    ip, sp
   stmfd    sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}


strncpy:
   @ args = 0, pretend = 0, frame = 0
   @ frame_needed = 0, uses_anonymous_args = 0






More information about the Gcc-bugs mailing list