path: root/arch
diff options
authorRich Felker <>2015-05-14 18:26:16 -0400
committerRich Felker <>2015-05-14 18:26:16 -0400
commit83340c7a580e91b22f58321b7cf6d976af61084c (patch)
treef230ee7eba74d07521f3f104660b0d318863fbc2 /arch
parentdbf74a98be1e5c7564566c2ad30ce85dcf768df6 (diff)
make arm crt_arch.h compatible with thumb code generation
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.
Diffstat (limited to 'arch')
1 files changed, 6 insertions, 4 deletions
diff --git a/arch/arm/crt_arch.h b/arch/arm/crt_arch.h
index d1f9a662..fcf95273 100644
--- a/arch/arm/crt_arch.h
+++ b/arch/arm/crt_arch.h
@@ -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"