NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

PR/57638 CVS commit: [netbsd-11] src/external/gpl3/gcc/dist/gcc/config/arm



The following reply was made to PR lib/57638; it has been noted by GNATS.

From: "Martin Husemann" <martin%netbsd.org@localhost>
To: gnats-bugs%gnats.NetBSD.org@localhost
Cc: 
Subject: PR/57638 CVS commit: [netbsd-11] src/external/gpl3/gcc/dist/gcc/config/arm
Date: Fri, 9 Oct 2026 15:25:40 +0000

 Module Name:	src
 Committed By:	martin
 Date:		Fri Oct  9 15:25:40 UTC 2026
 
 Modified Files:
 	src/external/gpl3/gcc/dist/gcc/config/arm [netbsd-11]: arm.cc arm.h
 	    arm.md
 
 Log Message:
 Pull up following revision(s) (requested by riastradh in ticket #515):
 
 	external/gpl3/gcc/dist/gcc/config/arm/arm.cc: revision 1.2
 	external/gpl3/gcc/dist/gcc/config/arm/arm.cc: revision 1.3
 	external/gpl3/gcc/dist/gcc/config/arm/arm.md: revision 1.24
 	external/gpl3/gcc/dist/gcc/config/arm/arm.h: revision 1.27
 
 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@
 
 gcc/arm: For -mtp=soft, ensure stack alignment in leaf functions using
 thread local storage.
 
 For each function compiled, record whether it accesses thread-local
 storage.  When laying out the stack frame for a leaf function, if the
 function needs to use a C runtime subroutine to retrieve the thread
 pointer, make sure that the stack pointer is aligned appropriately.
 
 PR lib/57638: thread local storage broken on evbarm (armv5)
 
 Upstream bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126394
 
 ok skrll@ riastradh@
 
 
 To generate a diff of this commit:
 cvs rdiff -u -r1.1.1.3 -r1.1.1.3.2.1 \
     src/external/gpl3/gcc/dist/gcc/config/arm/arm.cc
 cvs rdiff -u -r1.25 -r1.25.4.1 \
     src/external/gpl3/gcc/dist/gcc/config/arm/arm.h
 cvs rdiff -u -r1.22 -r1.22.2.1 \
     src/external/gpl3/gcc/dist/gcc/config/arm/arm.md
 
 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