[PATCH 3/3] arm: Remove RETURN macro

Pat Pannuto pat.pannuto@gmail.com
Thu Jan 12 04:51:00 GMT 2017


LTO can re-order top-level assembly blocks, which can cause this
macro definition to appear after its use (or not at all), causing
compilation failures. On modern toolchains (armv4t+), assembly
should write `bx lr` in all cases, and linkers will transparently
convert them to `mov pc, lr`, allowing us to simply remove the
macro.
  (source: https://groups.google.com/forum/#!topic/comp.sys.arm/3l7fVGX-Wug
   and verified empirically)

For the armv4.S file, preserve this macro to maximize backwards
compatibility.
---
 newlib/libc/machine/arm/arm_asm.h         | 22 ----------------------
 newlib/libc/machine/arm/strcmp-arm-tiny.S |  2 +-
 newlib/libc/machine/arm/strcmp-armv4.S    | 12 ++++++++++++
 newlib/libc/machine/arm/strcmp-armv7m.S   |  6 +++---
 newlib/libc/machine/arm/strcpy.c          | 12 ++++++------
 newlib/libc/machine/arm/strlen-stub.c     |  2 +-
 6 files changed, 23 insertions(+), 33 deletions(-)

diff --git a/newlib/libc/machine/arm/arm_asm.h b/newlib/libc/machine/arm/arm_asm.h
index bf18c0a03..2708057de 100644
--- a/newlib/libc/machine/arm/arm_asm.h
+++ b/newlib/libc/machine/arm/arm_asm.h
@@ -60,26 +60,4 @@
 # define _ISA_THUMB_1
 #endif
 
-
-/* Now some macros for common instruction sequences.  */
-#ifdef __ASSEMBLER__
-.macro  RETURN     cond=
-#if defined (_ISA_ARM_4T) || defined (_ISA_THUMB_1)
-	bx\cond	lr
-#else
-	mov\cond pc, lr
-#endif
-.endm
-
-#else
-asm(".macro  RETURN	cond=\n\t"
-#if defined (_ISA_ARM_4T) || defined (_ISA_THUMB_1)
-    "bx\\cond	lr\n\t"
-#else
-    "mov\\cond	pc, lr\n\t"
-#endif
-    ".endm"
-    );
-#endif
-
 #endif /* ARM_ASM__H */
diff --git a/newlib/libc/machine/arm/strcmp-arm-tiny.S b/newlib/libc/machine/arm/strcmp-arm-tiny.S
index 6b6bd13cc..607a41daf 100644
--- a/newlib/libc/machine/arm/strcmp-arm-tiny.S
+++ b/newlib/libc/machine/arm/strcmp-arm-tiny.S
@@ -42,6 +42,6 @@ def_fn strcmp
 	beq	1b
 2:
 	subs	r0, r2, r3
-	RETURN
+	bx	lr
 	.cfi_endproc
 	.size	strcmp, . - strcmp
diff --git a/newlib/libc/machine/arm/strcmp-armv4.S b/newlib/libc/machine/arm/strcmp-armv4.S
index 05e3df675..e8d0e2468 100644
--- a/newlib/libc/machine/arm/strcmp-armv4.S
+++ b/newlib/libc/machine/arm/strcmp-armv4.S
@@ -43,6 +43,18 @@
 #define tmp1		r12
 #define syndrome	r12	/* Overlaps tmp1 */
 
+/* For armv4t and newer, toolchains will transparently convert
+   'bx lr' to 'mov pc, lr' if needed. GCC has deprecated support
+   for anything older than armv4t, but this should handle that
+   corner case in case anyone needs it anyway */
+.macro  RETURN
+#if __ARM_ARCH <= 4 && __ARM_ARCH_ISA_THUMB == 0
+	mov	pc, lr
+#else
+	bx	lr
+#endif
+.endm
+
 	.arm
 def_fn strcmp
 	.cfi_sections .debug_frame
diff --git a/newlib/libc/machine/arm/strcmp-armv7m.S b/newlib/libc/machine/arm/strcmp-armv7m.S
index 7b6304925..cdb4912df 100644
--- a/newlib/libc/machine/arm/strcmp-armv7m.S
+++ b/newlib/libc/machine/arm/strcmp-armv7m.S
@@ -106,7 +106,7 @@ def_fn strcmp
 	lsrs	result, result, #24
 	subs	result, result, data2
 #endif
-	RETURN
+	bx	lr
 
 
 #if 0
@@ -356,7 +356,7 @@ def_fn strcmp
 	ldmfd	sp!, {r5}
 	.cfi_restore 5
 	.cfi_def_cfa_offset 0
-	RETURN
+	bx	lr
 
 .Lstrcmp_tail:
 	.cfi_restore_state
@@ -373,6 +373,6 @@ def_fn strcmp
 	ldmfd	sp!, {r5}
 	.cfi_restore 5
 	.cfi_def_cfa_offset 0
-	RETURN
+	bx	lr
 	.cfi_endproc
 	.size strcmp, . - strcmp
diff --git a/newlib/libc/machine/arm/strcpy.c b/newlib/libc/machine/arm/strcpy.c
index b90d5cf73..6f358e489 100644
--- a/newlib/libc/machine/arm/strcpy.c
+++ b/newlib/libc/machine/arm/strcpy.c
@@ -108,7 +108,7 @@ strcpy (char* dst, const char* src)
 #ifndef __thumb2__
        "ldr	r5, [sp], #4\n\t"
 #endif
-       "RETURN\n"
+       "bx	lr\n"
 
        /* Strings have the same offset from word alignment, but it's
 	  not zero.  */
@@ -119,7 +119,7 @@ strcpy (char* dst, const char* src)
        "strb	r2, [ip], #1\n\t"
        "cmp	r2, #0\n\t"
        "it	eq\n"
-       "RETURN	eq\n"
+       "bxeq	lr\n"
   "1:\n\t"
        "tst	r1, #2\n\t"
        "beq	5b\n\t"
@@ -139,7 +139,7 @@ strcpy (char* dst, const char* src)
        "tstne	r2, #0xff00\n\t"
 #endif
        "bne	5b\n\t"
-       "RETURN\n"
+       "bx	lr\n"
 
        /* src and dst do not have a common word-alignement.  Fall back to
 	  byte copying.  */
@@ -148,7 +148,7 @@ strcpy (char* dst, const char* src)
        "strb	r2, [ip], #1\n\t"
        "cmp	r2, #0\n\t"
        "bne	4b\n\t"
-       "RETURN"
+       "bx	lr\n\t"
 
 #elif !defined (__thumb__) || defined (__thumb2__)
        "mov	r3, r0\n\t"
@@ -157,7 +157,7 @@ strcpy (char* dst, const char* src)
        "strb	r2, [r3], #1\n\t"
        "cmp	r2, #0\n\t"
        "bne	1b\n\t"
-       "RETURN"
+       "bx	lr\n\t"
 #else
        "mov	r3, r0\n\t"
   "1:\n\t"
@@ -167,7 +167,7 @@ strcpy (char* dst, const char* src)
        "add	r3, r3, #1\n\t"
        "cmp	r2, #0\n\t"
        "bne	1b\n\t"
-       "RETURN"
+       "bx	lr\n\t"
 #endif
        );
 }
diff --git a/newlib/libc/machine/arm/strlen-stub.c b/newlib/libc/machine/arm/strlen-stub.c
index 69cfa3df0..8f87cba09 100644
--- a/newlib/libc/machine/arm/strlen-stub.c
+++ b/newlib/libc/machine/arm/strlen-stub.c
@@ -168,7 +168,7 @@ strlen (const char* str)
        "addne	len, len, #1\n\t"
 # endif
 #endif
-       "RETURN");
+       "bx	lr\n\t");
 }
 #endif
 #endif
-- 
2.11.0



More information about the Newlib mailing list