make arm crt_arch.h compatible with thumb code generation
authorRich Felker <dalias@aerifal.cx>
Thu, 14 May 2015 22:26:16 +0000 (18:26 -0400)
committerRich Felker <dalias@aerifal.cx>
Thu, 14 May 2015 22:26:16 +0000 (18:26 -0400)
compilers targeting armv7 may be configured to produce thumb2 code
instead of arm code by default, and in the future we may wish to
support targets where only the thumb instruction set is available.

the changes made here avoid operating directly on the sp register,
which is not possible in thumb code, and address an issue with the way
the address of _DYNAMIC is computed.

previously, the relative address of _DYNAMIC was stored with an
additional offset of -8 versus the pc-relative add instruction, since
on arm the pc register evaluates to ".+8". in thumb code, it instead
evaluates to ".+4". both are two (normal-size) instructions beyond "."
in the current execution mode, so the numbered label 2 used in the
relative address expression is simply moved two instructions ahead to
be compatible with both instruction sets.

arch/arm/crt_arch.h

index d1f9a6623974b4c3ab15bdf910662a27000ad3e3..fcf9527392c2a766bf88840f143080f262bbcc47 100644 (file)
@@ -4,12 +4,14 @@ __asm__(
 START ": \n"
 "      mov fp, #0 \n"
 "      mov lr, #0 \n"
-"      mov a1, sp \n"
 "      ldr a2, 1f \n"
-"2:    add a2, pc, a2 \n"
-"      and sp, sp, #-16 \n"
+"      add a2, pc, a2 \n"
+"      mov a1, sp \n"
+"2:    and ip, a1, #-16 \n"
+"      mov sp, ip \n"
 "      bl " START "_c \n"
 ".weak _DYNAMIC \n"
 ".hidden _DYNAMIC \n"
-"1:    .word _DYNAMIC-2b-8 \n"
+".align 2 \n"
+"1:    .word _DYNAMIC-2b \n"
 );