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