inline cp15 thread pointer load in arm dynamic TLSDESC asm when possible
authorRich Felker <dalias@aerifal.cx>
Mon, 1 Oct 2018 23:36:14 +0000 (19:36 -0400)
committerRich Felker <dalias@aerifal.cx>
Mon, 1 Oct 2018 23:39:24 +0000 (19:39 -0400)
the indirect function call is a significant portion of the code path
for the dynamic case, and most users are probably building for ISA
levels where it can be omitted.

we could drop at least one register save/restore (lr) with this
change, and possibly another (ip) with some clever shuffling, but it's
not clear whether there's a way to do it that's not more expensive, or
whether avoiding the save/restore would have any practical effect, so
in the interest of avoiding complexity it's omitted for now.

src/ldso/arm/tlsdesc.S

index f3d67fcec533bd1de44c32fc89a6ce967be4fa09..b81f3111c98c3dc77e949eba372f079ae05c2ff3 100644 (file)
@@ -19,6 +19,10 @@ __tlsdesc_dynamic:
        ldr r2,[r1,#4]  // r2 = offset
        ldr r1,[r1]     // r1 = modid
 
+#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
+ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
+       mrc p15,0,r0,c13,c0,3
+#else
        ldr r0,1f
        add r0,r0,pc
        ldr r0,[r0]
@@ -28,6 +32,7 @@ __tlsdesc_dynamic:
 #else
        mov lr,pc
        bx r0
+#endif
 #endif
        ldr r3,[r0,#-4] // r3 = dtv
        ldr ip,[r3]     // ip = dtv slot count
@@ -58,5 +63,9 @@ __tlsdesc_dynamic:
        sub r0,r0,r1    // r0 = retval-tp
        b 4b
 
+#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
+ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
+#else
        .align 2
 1:     .word __a_gettp_ptr - 2b
+#endif