This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Make macro checks ARMv8-M baseline proof


To get optimal performance, newlib provides multiple implementation of several routines such as strcmp which are guarded by macro checks. One common check is to look if the target supports only Thumb-1. ARMv6-M being until now the only architecture in such a case, this check was implemented by looking at the value of __ARM_ARCH or checking whether __ARM_ARCH_6M__ is defined. ARMv8-M make this wrong since ARMv8-M baseline is also (mostly) Thumb-1 only and ARMv8-M mainline is also Thumb-2 only. This patch replace checks for __ARM_ARCH_*__ for checks against __ARM_ARCH_ISA_THUMB and __ARM_ARCH_ISA_ARM instead. For instance, Thumb-1 only can be checked with #if !__ARM_ARCH_ISA_ARM && __ARM_ARCH_ISA_THUMB == 1.


=== Quick overview of ARMv8-M ===

ARMv8-M has two profiles[1]: Baseline and Mainline.  In terms of features they can be defined as:

ARMv8-M Baseline (armv8-m.base):
 * All ARMv6-M features
 * 16-bit immediate moves
 * Wide Branch
 * Compare & branch if (not) zero
 * Integer divide
 * Load/store exclusives
 * Atomic Load/stores
 * Security extensions

ARMv8-M Mainline (armv8-m.main):
 * All ARMv7-M features
 * Atomic load/stores
 * Security extensions.

ARMv8-M Mainline with DSP extension (armv8-m.main+dsp):
 * ARMv8-M Mainline
 * Those instructions added to ARMv7E-M on top of ARMv7-M.

Note that although certain architectural features of the security extensions are optional for cores implementing ARMv8-M, some of the new instructions are always available in the architecture.

Note also that only the instructions from security extensions are new instructions, all other instructions have previously been available in other ARM Architecture profiles.

[1] http://www.arm.com/products/processors/instruction-set-architectures/armv8-m-architecture.php


ChangeLog entries are as follow:

*** libgloss/ChangeLog ***

2015-12-02  Thomas Preud'homme  <thomas.preudhomme@arm.com>

        * arm/arm.h (THUMB_V7_V6M): Rename to ...
        (PREFER_THUMB): This.  Use ACLE macros __ARM_ARCH_ISA_ARM instead of
        __ARM_ARCH_6M__ to decide whether to define it.
        (THUMB_V7M_V6M): Delete.
        (THUMB1_ONLY): Define for Thumb-1 only targets.
        * arm/crt0.S: Use THUMB1_ONLY rather than __ARM_ARCH_6M__,
        !__ARM_ARCH_ISA_ARM rather than THUMB_V7M_V6M, and PREFER_THUMB rather
        than THUMB_V7_V6M.
        * arm/linux-crt0.c: Likewise.
        * arm/redboot-crt0.S: Likewise.
        * arm/swi.h: Likewise.
        * arm/trap.S: Likewise.

*** newlib/ChangeLog ***

2015-12-02  Thomas Preud'homme  <thomas.preudhomme@arm.com>

        * libc/machine/arm/memcpy-stub.c: Use ACLE macros __ARM_ARCH_ISA_THUMB
        and __ARM_ARCH_ISA_ARM to check for Thumb-2 only targets rather than
        __ARM_ARCH and __ARM_ARCH_PROFILE.
        * libc/machine/arm/memcpy.S: Likewise.
        * libc/machine/arm/setjmp.S: Likewise for Thumb-1 only target.
        * libc/machine/arm/strcmp.S: Likewise for Thumb-1 and Thumb-2 only
        target.
        * libc/sys/arm/arm.h (THUMB_V7_V6M): Rename to ...
        (PREFER_THUMB): This.  Use ACLE macro __ARM_ARCH_ISA_ARM instead of
        __ARM_ARCH_6M__ to decide whether to define it.
        (THUMB_V7M_V6M): Delete.
        (THUMB1_ONLY): Define for Thumb-1 only targets.
        * libc/sys/arm/crt0.S: Use !__ARM_ARCH_ISA_ARM rather than
        THUMB_V7M_V6M and PREFER_THUMB rather than THUMB_V7_V6M.
        * libc/sys/arm/swi.h: Likewise.


diff --git a/libgloss/arm/arm.h b/libgloss/arm/arm.h
index 26a1ff1..d50fcb2 100644
--- a/libgloss/arm/arm.h
+++ b/libgloss/arm/arm.h
@@ -29,25 +29,17 @@
 #ifndef _LIBGLOSS_ARM_H
 #define _LIBGLOSS_ARM_H
 
-/* __thumb2__ stands for thumb on armva7(A/R/M/EM) architectures,
-   __ARM_ARCH_6M__ stands for armv6-M(thumb only) architecture,
-   __ARM_ARCH_7M__ stands for armv7-M(thumb only) architecture.
-   __ARM_ARCH_7EM__ stands for armv7e-M(thumb only) architecture.
-   There are some macro combinations used many times in libgloss/arm,
-   like (__thumb2__ || (__thumb__ && __ARM_ARCH_6M__)), so factor
-   it out and use THUMB_V7_V6M instead, which stands for thumb on
-   v6-m/v7 arch as the combination does.  */
-#if defined(__thumb2__) || (defined(__thumb__) && defined(__ARM_ARCH_6M__))
-# define THUMB_V7_V6M
+/* Checking for targets supporting only Thumb instructions (eg. ARMv6-M) or
+   supporting Thumb-2 instructions, whether ARM instructions are available or
+   not, is done many times in libgloss/arm.  So factor it out and use
+   PREFER_THUMB instead.  */
+#if __thumb2__ || (__thumb__ && !__ARM_ARCH_ISA_ARM)
+# define PREFER_THUMB
 #endif
 
-/* The (__ARM_ARCH_7EM__ || __ARM_ARCH_7M__ || __ARM_ARCH_6M__) combination
-   stands for cortex-M profile architectures, which don't support ARM state.
-   Factor it out and use THUMB_V7M_V6M instead.  */
-#if defined(__ARM_ARCH_7M__)     \
-    || defined(__ARM_ARCH_7EM__) \
-    || defined(__ARM_ARCH_6M__)
-# define THUMB_V7M_V6M
+/* Processor only capable of executing Thumb-1 instructions.  */
+#if __ARM_ARCH_ISA_THUMB == 1 && !__ARM_ARCH_ISA_ARM
+# define THUMB1_ONLY
 #endif
 
 /* Defined if this target supports the BLX Rm instruction.  */
diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S
index cb9021d..be5c1b9 100644
--- a/libgloss/arm/crt0.S
+++ b/libgloss/arm/crt0.S
@@ -44,7 +44,7 @@
 /* .text is used instead of .section .text so it works with arm-aout too.  */
 	.text
 	.syntax unified
-#ifdef THUMB_V7_V6M
+#ifdef PREFER_THUMB
 	.thumb
 .macro FUNC_START name
 	.global \name
@@ -98,7 +98,7 @@
 
 	/*  stack limit is at end of data */
 	/*  allow slop for stack overflow handling and small frames */
-#ifdef __ARM_ARCH_6M__
+#ifdef THUMB1_ONLY
 	ldr	r0, .LC2
 	adds	r0, #128
 	adds	r0, #128
@@ -112,7 +112,7 @@
 	/*  Issue Angel SWI to read stack info */
 	movs	r0, #AngelSWI_Reason_HeapInfo
 	adr	r1, .LC0	/*  point at ptr to 4 words to receive data */
-#ifdef THUMB_V7M_V6M
+#ifndef __ARM_ARCH_ISA_ARM
 	bkpt	AngelSWI
 #elif defined(__thumb2__)
 	/*  We are in thumb mode for startup on armv7 architectures. */
@@ -154,7 +154,7 @@
 	cmp	r2, #0
 	beq	.LC27
 	/*  allow slop for stack overflow handling and small frames */
-#ifdef __ARM_ARCH_6M__
+#ifdef THUMB1_ONLY
 	adds	r2, #128
 	adds	r2, #128
 	mov	sl, r2
@@ -180,7 +180,7 @@
 #ifdef __thumb2__
 	it	eq
 #endif	
-#ifdef __ARM_ARCH_6M__
+#ifdef THUMB1_ONLY
 	bne	.LC28
 	ldr	r3, .LC0
 .LC28:
@@ -192,7 +192,7 @@
 		 have somehow missed it below (in which case it gets the same
 		 value as FIQ - not ideal, but better than nothing.) */
 	mov	sp, r3
-#ifdef THUMB_V7_V6M
+#ifdef PREFER_THUMB
 	/* XXX Fill in stack assignments for interrupt modes.  */
 #else
 	mrs	r2, CPSR
@@ -235,7 +235,7 @@
 	   this default 64k is enough for the program being executed.
 	   However, it ensures that this simple crt0 world will not
 	   immediately cause an overflow event:  */
-#ifdef __ARM_ARCH_6M__
+#ifdef THUMB1_ONLY
 	movs	r2, #64
 	lsls	r2, r2, #10
 	subs	r2, r3, r2
@@ -255,7 +255,7 @@
 	subs	a3, a3, a1		/* Third arg: length of block */
 	
 
-#if defined(__thumb__) && !defined(THUMB_V7_V6M)
+#if __thumb__ && !defined(PREFER_THUMB)
 	/* Enter Thumb mode.... */
 	add	a4, pc, #1	/* Get the address of the Thumb block */
 	bx	a4		/* Go there and start Thumb decoding  */
@@ -426,7 +426,7 @@ __change_mode:
 
 	bl	FUNCTION (exit)		/* Should not return.  */
 
-#if defined(__thumb__) && !defined(THUMB_V7_V6M)
+#if __thumb__ && !defined(PREFER_THUMB)
 	/* Come out of Thumb mode.  This code should be redundant.  */
 
 	mov	a4, pc
diff --git a/libgloss/arm/linux-crt0.c b/libgloss/arm/linux-crt0.c
index c313d26..878ece7 100644
--- a/libgloss/arm/linux-crt0.c
+++ b/libgloss/arm/linux-crt0.c
@@ -12,7 +12,7 @@
 
 static int _main(int argc, char *argv[]) __attribute__((noreturn));
 
-#if defined(__thumb__) && !defined(THUMB_V7_V6M)
+#if __thumb__ && !defined(PREFER_THUMB)
 asm("\n"
 	".code 32\n"
 	".global _start\n"
diff --git a/libgloss/arm/redboot-crt0.S b/libgloss/arm/redboot-crt0.S
index 1d90228..0e3a9b4 100644
--- a/libgloss/arm/redboot-crt0.S
+++ b/libgloss/arm/redboot-crt0.S
@@ -14,7 +14,7 @@
     .text
 	.syntax unified
      /* Setup the assembly entry point.  */
-#ifdef THUMB_V7_V6M
+#ifdef PREFER_THUMB
 .macro FUNC_START name
 	.global \name
 	.thumb_func
@@ -31,13 +31,13 @@
 	FUNC_START SYM_NAME(_start)
     /* Unnecessary to set fp for v6-m/v7-m, which don't support
        ARM state.  */
-#ifndef THUMB_V7M_V6M
+#if __ARM_ARCH_ISA_ARM
 	mov	fp, #0	/* Null frame pointer.  */
 #endif
 	movs	r7, #0	/* Null frame pointer for Thumb.  */
 
 	/* Enable interrupts for gdb debugging.  */
-#ifdef THUMB_V7_V6M
+#ifdef PREFER_THUMB
 	cpsie if
 #else
 	mrs    r0, cpsr
@@ -66,7 +66,7 @@
 	/* Nothing to left to clear.  */
 #endif
 
-#if defined(__thumb__) && !defined(THUMB_V7_V6M)
+#if __thumb__ && !defined(PREFER_THUMB)
 	/* Enter Thumb mode. */
 	add	a4, pc, #1	/* Get the address of the Thumb block.  */
 	bx	a4		/* Go there and start Thumb decoding.   */
diff --git a/libgloss/arm/swi.h b/libgloss/arm/swi.h
index 0f93134..76937fa 100644
--- a/libgloss/arm/swi.h
+++ b/libgloss/arm/swi.h
@@ -36,7 +36,7 @@
 #define AngelSWI 			AngelSWI_ARM
 #endif
 /* For thumb only architectures use the BKPT instruction instead of SWI.  */
-#ifdef THUMB_V7M_V6M
+#if !__ARM_ARCH_ISA_ARM
 #define AngelSWIInsn			"bkpt"
 #define AngelSWIAsm			bkpt
 #else
diff --git a/libgloss/arm/trap.S b/libgloss/arm/trap.S
index 9eb3906..d854b57 100644
--- a/libgloss/arm/trap.S
+++ b/libgloss/arm/trap.S
@@ -1,6 +1,6 @@
 #include "arm.h"
         /* Run-time exception support */
-#ifndef THUMB_V7_V6M
+#ifndef PREFER_THUMB
 #include "swi.h"
 
 /* .text is used instead of .section .text so it works with arm-aout too.  */
diff --git a/newlib/libc/machine/arm/memcpy-stub.c b/newlib/libc/machine/arm/memcpy-stub.c
index 52a0f91..6cd0e3b 100644
--- a/newlib/libc/machine/arm/memcpy-stub.c
+++ b/newlib/libc/machine/arm/memcpy-stub.c
@@ -34,7 +34,7 @@
 #elif (__ARM_ARCH >= 7 && __ARM_ARCH_PROFILE == 'A' \
        && defined (__ARM_FEATURE_UNALIGNED))
 /* Defined in memcpy.S.  */
-#elif __ARM_ARCH >= 7 && __ARM_ARCH_PROFILE == 'M'
+#elif __ARM_ARCH_ISA_THUMB == 2 && !__ARM_ARCH_ISA_ARM
 /* Defined in memcpy.S.  */
 #else
 # include "../../string/memcpy.c"
diff --git a/newlib/libc/machine/arm/memcpy.S b/newlib/libc/machine/arm/memcpy.S
index d9d5810..77bd2a6 100644
--- a/newlib/libc/machine/arm/memcpy.S
+++ b/newlib/libc/machine/arm/memcpy.S
@@ -38,7 +38,7 @@
        && defined (__ARM_FEATURE_UNALIGNED))
 #include "memcpy-armv7a.S"
 
-#elif __ARM_ARCH >= 7 && __ARM_ARCH_PROFILE == 'M'
+#elif __ARM_ARCH_ISA_THUMB == 2 && !__ARM_ARCH_ISA_ARM
 #include "memcpy-armv7m.S"
 
 #else
diff --git a/newlib/libc/machine/arm/setjmp.S b/newlib/libc/machine/arm/setjmp.S
index a65fbab..fa35bb2 100644
--- a/newlib/libc/machine/arm/setjmp.S
+++ b/newlib/libc/machine/arm/setjmp.S
@@ -55,8 +55,8 @@
    
    For Thumb-2 do everything in Thumb mode.  */
 
-#if defined(__ARM_ARCH_6M__)
-/* ARMv6-M has to be implemented in Thumb mode.  */
+#if __ARM_ARCH_ISA_THUMB == 1 && !__ARM_ARCH_ISA_ARM
+/* ARMv6-M-like has to be implemented in Thumb mode.  */
 
 .thumb
 .thumb_func
diff --git a/newlib/libc/machine/arm/strcmp.S b/newlib/libc/machine/arm/strcmp.S
index 7b4d7fc..d5fe82b 100644
--- a/newlib/libc/machine/arm/strcmp.S
+++ b/newlib/libc/machine/arm/strcmp.S
@@ -61,7 +61,7 @@
 	.endm
 
 #if defined (__OPTIMIZE_SIZE__) || defined (PREFER_SIZE_OVER_SPEED) \
-	|| (__ARM_ARCH == 6 && __ARM_ARCH_PROFILE == 'M')
+	|| (__ARM_ARCH_ISA_THUMB == 1 && !__ARM_ARCH_ISA_ARM)
 
 # if defined (__thumb__) && !defined (__thumb2__)
 /* Thumb1 only variant.  If size is preferred, use strcmp-armv4t.S.
@@ -78,7 +78,7 @@
 #  include "strcmp-arm-tiny.S"
 # endif
 
-#elif __ARM_ARCH >= 7
+#elif __ARM_ARCH_ISA_THUMB == 2
 
 # ifdef __ARM_FEATURE_SIMD32
 #  include "strcmp-armv7.S"
diff --git a/newlib/libc/sys/arm/arm.h b/newlib/libc/sys/arm/arm.h
index 26a1ff1..d50fcb2 100644
--- a/newlib/libc/sys/arm/arm.h
+++ b/newlib/libc/sys/arm/arm.h
@@ -29,25 +29,17 @@
 #ifndef _LIBGLOSS_ARM_H
 #define _LIBGLOSS_ARM_H
 
-/* __thumb2__ stands for thumb on armva7(A/R/M/EM) architectures,
-   __ARM_ARCH_6M__ stands for armv6-M(thumb only) architecture,
-   __ARM_ARCH_7M__ stands for armv7-M(thumb only) architecture.
-   __ARM_ARCH_7EM__ stands for armv7e-M(thumb only) architecture.
-   There are some macro combinations used many times in libgloss/arm,
-   like (__thumb2__ || (__thumb__ && __ARM_ARCH_6M__)), so factor
-   it out and use THUMB_V7_V6M instead, which stands for thumb on
-   v6-m/v7 arch as the combination does.  */
-#if defined(__thumb2__) || (defined(__thumb__) && defined(__ARM_ARCH_6M__))
-# define THUMB_V7_V6M
+/* Checking for targets supporting only Thumb instructions (eg. ARMv6-M) or
+   supporting Thumb-2 instructions, whether ARM instructions are available or
+   not, is done many times in libgloss/arm.  So factor it out and use
+   PREFER_THUMB instead.  */
+#if __thumb2__ || (__thumb__ && !__ARM_ARCH_ISA_ARM)
+# define PREFER_THUMB
 #endif
 
-/* The (__ARM_ARCH_7EM__ || __ARM_ARCH_7M__ || __ARM_ARCH_6M__) combination
-   stands for cortex-M profile architectures, which don't support ARM state.
-   Factor it out and use THUMB_V7M_V6M instead.  */
-#if defined(__ARM_ARCH_7M__)     \
-    || defined(__ARM_ARCH_7EM__) \
-    || defined(__ARM_ARCH_6M__)
-# define THUMB_V7M_V6M
+/* Processor only capable of executing Thumb-1 instructions.  */
+#if __ARM_ARCH_ISA_THUMB == 1 && !__ARM_ARCH_ISA_ARM
+# define THUMB1_ONLY
 #endif
 
 /* Defined if this target supports the BLX Rm instruction.  */
diff --git a/newlib/libc/sys/arm/crt0.S b/newlib/libc/sys/arm/crt0.S
index b56072f..c5dc17c 100644
--- a/newlib/libc/sys/arm/crt0.S
+++ b/newlib/libc/sys/arm/crt0.S
@@ -44,7 +44,7 @@
 /* .text is used instead of .section .text so it works with arm-aout too.  */
 	.text
 	.syntax unified
-#ifdef THUMB_V7_V6M
+#ifdef PREFER_THUMB
 	.thumb
 .macro FUNC_START name
 	.global \name
@@ -99,7 +99,7 @@
 	/*  Issue Angel SWI to read stack info.  */
 	movs	r0, #AngelSWI_Reason_HeapInfo
 	adr	r1, .LC0	/*  Point at ptr to 4 words to receive data.  */
-#ifdef THUMB_V7M_V6M
+#if !__ARM_ARCH_ISA_ARM
 	bkpt	AngelSWI
 #elif defined(__thumb2__)
 	/*  We are in thumb mode for startup on armv7 architectures.  */
@@ -176,7 +176,7 @@
 		 have somehow missed it below (in which case it gets the same
 		 value as FIQ - not ideal, but better than nothing).  */
 	mov	sp, r3
-#ifdef THUMB_V7_V6M
+#ifdef PREFER_THUMB
 	/* XXX Fill in stack assignments for interrupt modes.  */
 #else
 	mrs	r2, CPSR
@@ -239,7 +239,7 @@
 	subs	a3, a3, a1		/* Third arg: length of block.  */
 	
 
-#if defined(__thumb__) && !defined(THUMB_V7_V6M)
+#if __thumb__ && !defined(PREFER_THUMB)
 	/* Enter Thumb mode...  */
 	add	a4, pc, #1	/* Get the address of the Thumb block.  */
 	bx	a4		/* Go there and start Thumb decoding.  */
@@ -278,7 +278,7 @@ __change_mode:
 #else
 	movs	r0, #AngelSWI_Reason_GetCmdLine
 	adr	r1, .LC30	/* Space for command line.  */
-#ifdef THUMB_V7M_V6M
+#if !__ARM_ARCH_ISA_ARM
 	bkpt	AngelSWI
 #else
  	AngelSWIAsm	AngelSWI
@@ -404,7 +404,7 @@ __change_mode:
 
 	bl	FUNCTION (exit)		/* Should not return.  */
 
-#if defined(__thumb__) && !defined(THUMB_V7_V6M)
+#if __thumb__ && !defined(PREFER_THUMB)
 	/* Come out of Thumb mode.  This code should be redundant.  */
 	mov	a4, pc
 	bx	a4
diff --git a/newlib/libc/sys/arm/swi.h b/newlib/libc/sys/arm/swi.h
index 0f93134..76937fa 100644
--- a/newlib/libc/sys/arm/swi.h
+++ b/newlib/libc/sys/arm/swi.h
@@ -36,7 +36,7 @@
 #define AngelSWI 			AngelSWI_ARM
 #endif
 /* For thumb only architectures use the BKPT instruction instead of SWI.  */
-#ifdef THUMB_V7M_V6M
+#if !__ARM_ARCH_ISA_ARM
 #define AngelSWIInsn			"bkpt"
 #define AngelSWIAsm			bkpt
 #else


Tested by building newlib and comparing all *.a and *.o binaries before and
after with objdump -D and readelf -A for all permutations of:

  Architectures:
    armv4 armv4t armv5 armv5t armv5te armv6 armv6j armv6k
    armv6z armv6kz armv6t2 armv6s-m armv7 armv7-a armv7ve
    armv7-r armv7-m armv7e-m armv8-a armv8-a+crc iwmmxt
    iwmmxt2

  ISAs:
    thumb arm

  Optimization Levels:
    Os O2

  Excluding:
    armv6s-m -marm
    armv7 -marm
    armv7-m -marm
    armv7e-m -marm
    iwmmxt -mthumb
    iwmmxt2 -mthumb

as being rejected by the compiler or assembler. ARMv6-m was not tested because compilation fails due to svc instruction.

Is this ok for the master branch?

Best regards,

Thomas


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]