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