NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
PR/57638 CVS commit: src/external/gpl3/gcc/dist/gcc/config/arm
The following reply was made to PR lib/57638; it has been noted by GNATS.
From: "Taylor R Campbell" <riastradh%netbsd.org@localhost>
To: gnats-bugs%gnats.NetBSD.org@localhost
Cc:
Subject: PR/57638 CVS commit: src/external/gpl3/gcc/dist/gcc/config/arm
Date: Sat, 25 Jul 2026 19:01:48 +0000
Module Name: src
Committed By: riastradh
Date: Sat Jul 25 19:01:48 UTC 2026
Modified Files:
src/external/gpl3/gcc/dist/gcc/config/arm: arm.cc
Log Message:
gcc/arm: For -mtp=soft, ensure stack alignment even in leaves.
The option -mtp=soft, which is the default on earmv5, makes queries
to the thread pointer, for access to static (`initial-exec')
thread-local storage, go through the C runtime subroutine
__aeabi_read_tp. (For earmv>=6, we use the cp15 register via a
single instruction.)
Thus procedures which gcc thinks of as leaf procedures that use
__aeabi_read_tp are not really leaf procedures -- and even though
__aeabi_read_tp itself doesn't use the stack pointer at all,
resolving the symbol may take a detour through the dynamic linker,
which does rely on an aligned stack pointer.
Without this change, code like
__thread int x = 0;
int *
get_x(void)
{
return &x;
}
is compiled into:
00000000 <get_x>:
get_x():
0: e52de004 push {lr} @ (str lr, [sp, #-4]!)
4: ebfffffe bl 0 <__aeabi_read_tp>
4: R_ARM_CALL __aeabi_read_tp
8: e59f3004 ldr r3, [pc, #4] @ 14 <get_x+0x14>
c: e0830000 add r0, r3, r0
10: e49df004 pop {pc} @ (ldr pc, [sp], #4)
14: 00000000 .word 0x00000000
14: R_ARM_TLS_LE32 .LANCHOR0
With this change, extend the _existing_ push and pop instructions in
the prologue and epilogue to save and restore r4 arbitrarily (not
that the content is useful for anything; it just keeps the stack
pointer aligned to multiple of 8):
00000000 <get_x>:
get_x():
0: e92d4010 push {r4, lr}
4: ebfffffe bl 0 <__aeabi_read_tp>
4: R_ARM_CALL __aeabi_read_tp
8: e59f3004 ldr r3, [pc, #4] @ 14 <get_x+0x14>
c: e0830000 add r0, r3, r0
10: e8bd8010 pop {r4, pc}
14: 00000000 .word 0x00000000
14: R_ARM_TLS_LE32 .LANCHOR0
Ideally, we would ensure stack alignment only for `leaf' procedures
that actually use __aeabi_read_tp. But I don't know how to query
that in this context. And in any case, this change only applies to
subroutines that are already saving 2n+1 registers for some n,
picking some arbitrary register to round it up to 2n+2. For example:
int y;
int *
get_y(void)
{
return &y;
}
int *
get_y_with_r4(void)
{
asm volatile("" ::: "r4");
return &y;
}
With this change, we get:
00000018 <get_y>:
get_y():
18: e59f0000 ldr r0, [pc] @ 20 <get_y+0x8>
1c: e12fff1e bx lr
20: 00000000 .word 0x00000000
20: R_ARM_ABS32 .bss
00000024 <get_y_with_r4>:
get_y_with_r4():
24: e92d0030 push {r4, r5}
28: e8bd0030 pop {r4, r5}
2c: e59f0000 ldr r0, [pc] @ 34 <get_y_with_r4+0x10>
30: e12fff1e bx lr
34: 00000000 .word 0x00000000
34: R_ARM_ABS32 .bss
In contrast, with earmv>=6, get_y would be unchanged, but
get_y_with_r4 would be:
00000020 <get_y_with_r4>:
get_y_with_r4():
20: e52d4004 push {r4} @ (str r4, [sp, #-4]!)
24: e59f0004 ldr r0, [pc, #4] @ 30 <get_y_with_r4+0x10>
28: e49d4004 pop {r4} @ (ldr r4, [sp], #4)
2c: e12fff1e bx lr
30: 00000000 .word 0x00000000
30: R_ARM_ABS32 .bss
Note that the number of instructions hasn't changed; all that has
changed is whether we save and restore one or two registers in the
function prologue and epilogue (or more generally, 2n+1 vs 2n+2
registers).
PR lib/57638: thread local storage broken on evbarm (armv5)
Upstream bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126394
ok skrll@
To generate a diff of this commit:
cvs rdiff -u -r1.1.1.4 -r1.2 src/external/gpl3/gcc/dist/gcc/config/arm/arm.cc
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Home |
Main Index |
Thread Index |
Old Index