Building newlib for Cortex-M with LLVM

Jonathan Roelofs jonathan@codesourcery.com
Thu Nov 12 22:42:00 GMT 2015



On 11/11/15 4:16 PM, Olivier MARTIN wrote:
> Hello all,
> recently I found a warning generated by Clang while building my project
> that is based on Newlib (see
> https://sourceware.org/ml/newlib/2015/msg00714.html).
>
> I was curious... and I was wondering whether I could build newlib with
> Clang.
snip
>
> * The second issue is what I believe to be a Clang issue. Clang does not
> support when macros are defined into inline assembly and used later on.
> Assembly macros are quite used in the ARM string functions (eg:
> 'RETURN', 'optpld' macros).
> I raised a Clang bug for this one:
> https://llvm.org/bugs/show_bug.cgi?id=25495

This one is very unlikely to get fixed in clang. I ran into this same 
exact thing about a year ago... now I feel bad for not upstreaming the 
patches for it.  Attached is what I was able to dig out of version 
control, HTH.


Jon

>
> Any feedback or comment on my investigation are welcome. I am quite
> happy to try few things.
>
> Thanks,
>
> ---
> Olivier MARTIN
> http://labapart.com - Lab A Part

-- 
Jon Roelofs
jonathan@codesourcery.com
CodeSourcery / Mentor Embedded
-------------- next part --------------
commit b1053be367d1273c6d7b40e367423c3943a8302c
Author: Jonathan Roelofs <jonathan@codesourcery.com>
Date:   Thu Jul 10 09:28:03 2014 -0700

    Fix newlib build with Clang IAS. Need to -DCLANG_IAS when using -fintegrated-as

diff --git a/newlib-trunk/newlib/libc/aeabi/clibabi_signal_fns.S b/newlib-trunk/newlib/libc/aeabi/clibabi_signal_fns.S
index a4136f0..a7881b7 100644
--- a/newlib-trunk/newlib/libc/aeabi/clibabi_signal_fns.S
+++ b/newlib-trunk/newlib/libc/aeabi/clibabi_signal_fns.S
@@ -3,7 +3,11 @@
 	.macro sigfn name val
 	.global __aeabi_\name
 	.hidden __aeabi_\name
+#if defined(CLANG_IAS)
+	.type __aeabi_\name, %function
+#else
 	.type __aeabi_\name, function
+#endif
 	.set __aeabi_\name, \val
 	.endm
 	
diff --git a/newlib-trunk/newlib/libc/machine/arm/arm_asm.h b/newlib-trunk/newlib/libc/machine/arm/arm_asm.h
index 5a63a8d..06ca93d 100644
--- a/newlib-trunk/newlib/libc/machine/arm/arm_asm.h
+++ b/newlib-trunk/newlib/libc/machine/arm/arm_asm.h
@@ -78,21 +78,24 @@
 .endm
 
 #else
-asm(".macro  RETURN	cond=\n\t"
 #if defined (_ISA_ARM_4T) || defined (_ISA_THUMB_1)
-    "bx\\cond	lr\n\t"
+#define RETURN_MACRO ".macro  RETURN	cond=\n\t" \
+                     "bx\\cond	lr\n\t" \
+                     ".endm\n\t"
 #else
-    "mov\\cond	pc, lr\n\t"
+#define RETURN_MACRO ".macro  RETURN	cond=\n\t" \
+                     "mov\\cond	pc, lr\n\t" \
+                     ".endmi\n\t"
 #endif
-    ".endm"
-    );
 
-asm(".macro optpld	base, offset=#0\n\t"
 #if defined (_ISA_ARM_7)
-    "pld	[\\base, \\offset]\n\t"
+#define OPTPLD_MACRO ".macro optpld	base, offset=#0\n\t" \
+                     "pld	[\\base, \\offset]\n\t" \
+                     ".endm\n\t"
+#else
+#define OPTPLD_MACRO ".macro optpld	base, offset=#0\n\t" \
+                     ".endm\n\t"
 #endif
-    ".endm"
-    );
 #endif
 
 #endif /* ARM_ASM__H */
diff --git a/newlib-trunk/newlib/libc/machine/arm/setjmp.S b/newlib-trunk/newlib/libc/machine/arm/setjmp.S
index a65fbab..bb319d5 100644
--- a/newlib-trunk/newlib/libc/machine/arm/setjmp.S
+++ b/newlib-trunk/newlib/libc/machine/arm/setjmp.S
@@ -13,7 +13,11 @@
 #define SYM(x) CONCAT (__USER_LABEL_PREFIX__, x)
 
 #ifdef __ELF__
+#if defined(CLANG_IAS)
+#define TYPE(x) .type SYM(x),%function
+#else
 #define TYPE(x) .type SYM(x),function
+#endif
 #define SIZE(x) .size SYM(x), . - SYM(x)
 #else
 #define TYPE(x)
@@ -72,11 +76,19 @@ SYM (setjmp):
 	mov	r5, sp
 	mov	r6, lr
 	stmia	r0!, {r1, r2, r3, r4, r5, r6}
+#if defined(CLANG_IAS)
+	subs	r0, #40
+#else
 	sub	r0, r0, #40
+#endif
 	/* Restore callee-saved low regs.  */
 	ldmia	r0!, {r4, r5, r6, r7}
 	/* Return zero.  */
+#if defined(CLANG_IAS)
+	movs	r0, #0
+#else
 	mov	r0, #0
+#endif
 	bx lr
 
 .thumb_func
@@ -84,7 +96,11 @@ SYM (setjmp):
 	TYPE (longjmp)
 SYM (longjmp):
 	/* Restore High regs.  */
+#if defined(CLANG_IAS)
+	adds	r0, #16
+#else
 	add	r0, r0, #16
+#endif
 	ldmia	r0!, {r2, r3, r4, r5, r6}
 	mov	r8, r2
 	mov	r9, r3
@@ -93,12 +109,20 @@ SYM (longjmp):
 	mov	sp, r6
 	ldmia	r0!, {r3} /* lr */
 	/* Restore low regs.  */
+#if defined(CLANG_IAS)
+	subs	r0, #40
+#else
 	sub	r0, r0, #40
+#endif
 	ldmia	r0!, {r4, r5, r6, r7}
 	/* Return the result argument, or 1 if it is zero.  */
 	mov	r0, r1
 	bne	1f
+#if defined(CLANG_IAS)
+	movs	r0, #1
+#else
 	mov	r0, #1
+#endif
 1:
 	bx	r3
 
@@ -146,27 +170,25 @@ SYM (.arm_start_of.\name):
 .macro PROLOGUE name
 .endm
 #endif
-	
-.macro FUNC_START name
-	.text
-	.align 2
-	MODE
-	.globl SYM (\name)
-	TYPE (\name)
-SYM (\name):
-	PROLOGUE \name
-.endm
+#define FUNC_START(name) \
+	.text ;\
+	.align 2 ;\
+	MODE ;\
+	.globl SYM(name) ;\
+	TYPE(name) ;\
+SYM(name):\
+	PROLOGUE name
+
+#define FUNC_END(name) \
+	RET ; \
+	SIZE(name)
+
 
-.macro FUNC_END name
-	RET
-	SIZE (\name)
-.endm
-	
 /* --------------------------------------------------------------------
                  int setjmp (jmp_buf); 
    -------------------------------------------------------------------- */
 	
-	FUNC_START setjmp
+	FUNC_START(setjmp)
 
 	/* Save all the callee-preserved registers into the jump buffer.  */
 #ifdef __thumb2__
@@ -185,13 +207,13 @@ SYM (\name):
 	/* When setting up the jump buffer return 0.  */
 	mov		a1, #0
 
-	FUNC_END setjmp
+	FUNC_END(setjmp)
 	
 /* --------------------------------------------------------------------
 		volatile void longjmp (jmp_buf, int);
    -------------------------------------------------------------------- */
 	
-	FUNC_START longjmp
+	FUNC_START(longjmp)
 
 	/* If we have stack extension code it ought to be handled here.  */
 	
@@ -217,5 +239,5 @@ SYM (\name):
 #endif
 	moveq		a1, #1
 
-	FUNC_END longjmp
+	FUNC_END(longjmp)
 #endif
diff --git a/newlib-trunk/newlib/libc/machine/arm/strcpy.c b/newlib-trunk/newlib/libc/machine/arm/strcpy.c
index de96109..5ee3088 100644
--- a/newlib-trunk/newlib/libc/machine/arm/strcpy.c
+++ b/newlib-trunk/newlib/libc/machine/arm/strcpy.c
@@ -42,6 +42,8 @@ char* __attribute__((naked))
 strcpy (char* dst, const char* src)
 {
   asm (
+       OPTPLD_MACRO
+       RETURN_MACRO
 #if !(defined(__OPTIMIZE_SIZE__) || defined (PREFER_SIZE_OVER_SPEED) || \
       (defined (__thumb__) && !defined (__thumb2__)))
        "optpld	r1\n\t"
@@ -123,15 +125,28 @@ strcpy (char* dst, const char* src)
 #ifdef __ARMEB__
        "tst	r2, #0xff00\n\t"
        "iteet	ne\n\t"
+#if defined(CLANG_IAS)
+       "strhne	r2, [ip], #2\n\t"
+#else
        "strneh	r2, [ip], #2\n\t"
+#else
        "lsreq	r2, r2, #8\n\t"
+#if defined(CLANG_IAS)
+       "strbeq	r2, [ip]\n\t"
+#else
        "streqb	r2, [ip]\n\t"
+#endif
        "tstne	r2, #0xff\n\t"
 #else
        "tst	r2, #0xff\n\t"
        "itet	ne\n\t"
+#if defined(CLANG_IAS)
+       "strhne	r2, [ip], #2\n\t"
+       "strbeq	r2, [ip]\n\t"
+#else
        "strneh	r2, [ip], #2\n\t"
        "streqb	r2, [ip]\n\t"
+#endif
        "tstne	r2, #0xff00\n\t"
 #endif
        "bne	5b\n\t"
@@ -155,17 +170,21 @@ strcpy (char* dst, const char* src)
        "bne	1b\n\t"
        "RETURN"
 #else
+#if defined(CLANG_IAS)
+       "movs	r3, r0\n\t"
+#else
        "mov	r3, r0\n\t"
+#endif
   "1:\n\t"
        "ldrb	r2, [r1]\n\t"
-#if defined(__clang__)
-       "adds	r1, r1, #1\n\t"
+#if defined(CLANG_IAS)
+       "adds	r1, #1\n\t"
 #else
        "add	r1, r1, #1\n\t"
 #endif
        "strb	r2, [r3]\n\t"
-#if defined(__clang__)
-       "adds	r3, r3, #1\n\t"
+#if defined(CLANG_IAS)
+       "adds	r3, #1\n\t"
 #else
        "add	r3, r3, #1\n\t"
 #endif
diff --git a/newlib-trunk/newlib/libc/machine/arm/strlen.c b/newlib-trunk/newlib/libc/machine/arm/strlen.c
index ed60e95..aefe01d 100644
--- a/newlib-trunk/newlib/libc/machine/arm/strlen.c
+++ b/newlib-trunk/newlib/libc/machine/arm/strlen.c
@@ -41,17 +41,17 @@ strlen (const char* str)
 #if defined (__thumb__) && !defined (__thumb2__)
   size_t len;
   asm (
-#if defined(__clang__)
+#if defined(CLANG_IAS)
        "movs	%0, #0\n"
 #else
        "mov	%0, #0\n"
 #endif
        "1:\n\t"
        "ldrb	%1, [%2, %0]\n\t"
-#if defined(__clang__)
-       "adds 	%0, %0, #1\n\t"
+#if defined(CLANG_IAS)
+       "adds	%0, #1\n\t"
 #else
-       "add 	%0, %0, #1\n\t"
+       "add	%0, %0, #1\n\t"
 #endif
        "cmp	%1, #0\n\t"
        "bne	1b"
@@ -74,7 +74,10 @@ strlen (const char* str)
 size_t __attribute__((naked))
 strlen (const char* str)
 {
-  asm ("len .req r0\n\t"
+  asm (
+       OPTPLD_MACRO
+       RETURN_MACRO
+       "len .req r0\n\t"
        "data .req r3\n\t"
        "addr .req r1\n\t"
 


More information about the Newlib mailing list