The simple test case is: extern int i; void foo(int j) { i = j; }
Compile it with options -march=armv5te -mthumb -Os -fpic, gcc generates: foo: ldr r3, .L3 ldr r2, .L3+4 .LPIC0: add r3, pc // A ldr r3, [r3, r2] @ sp needed for prologue str r0, [r3] bx lr .L4: .align 2 .L3: .word _GLOBAL_OFFSET_TABLE_-(.LPIC0+4) .word i(GOT) Compile it with options -march=armv7 -mthumb -Os -fpic, gcc generates: foo: ldr r3, .L3 .align 2 .LPIC0: adr r2, .LPIC0 + 4 // B adds r3, r3, r2 // C ldr r2, .L3+4 ldr r3, [r3, r2] str r0, [r3, #0] bx lr .L4: .align 2 .L3: .word _GLOBAL_OFFSET_TABLE_-(.LPIC0+4) .word i(GOT) The different instructions are marked with A and BC. It is caused by different codes for Thumb2 and Thumb1 in function arm_load_pic_register. Actually for Thumb2 we should generate similar codes as Thumb1. -- Summary: Thumb2 generate more instructions than Thumb1 to load GOT address Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: carrot at google dot com GCC build triplet: i686-linux GCC host triplet: i686-linux GCC target triplet: arm-eabi http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42671