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