This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

ARMv6-M support


The attached patch adds ARMv6-M architecture support to binutils. This is 
basically the Thumb bits of conventional ARMv6, plus a few system 
instructions from Thumb-2.
Tested on arm-none-eabi.
Applied to cvs head.
Paul
2008年03月04日 Paul Brook <paul@codesourcery.com>
	gas/
	* config/tc-arm.c (arm_ext_barrier, arm_ext_msr): New.
	(arm_ext_v7m): Rename...
	(arm_ext_m): ... to this. Include v6-M.
	(do_t_add_sub): Allow narrow low-reg non flag setting adds.
	(do_t_mrs, do_t_msr, aeabi_set_public_attributes): Use arm_ext_m.
	(md_assemble): Allow wide msr instructions.
	(insns): Add classifications for v6-m instructions.
	(arm_cpu_option_table): Add cortex-m1.
	(arm_arch_option_table): Add armv6-m.
	(cpu_arch): Add ARM_ARCH_V6M. Fix numbering of other v6 variants.
	gas/testsuite/
	* gas/arm/archv6m.d: New test.
	* gas/arm/archv6m.s: New test.
	* gas/arm/t16-bad.s: Test low register non flag setting add.
	* gas/arm/t16-bad.l: Update expected output.
	include/opcode/
	* arm.h (ARM_EXT_V6M, ARM_EXT_BARRIER, ARM_EXT_THUMB_MSR): Define.
	(ARM_AEXT_V6T2, ARM_AEXT_V7_ARM, ARM_AEXT_V7M): Use new flags.
	(ARM_AEXT_V6M, ARM_ARCH_V6M): Define.
Index: gas/config/tc-arm.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/config/tc-arm.c,v
retrieving revision 1.348
diff -u -p -r1.348 tc-arm.c
--- gas/config/tc-arm.c	22 Feb 2008 16:47:01 -0000	1.348
+++ gas/config/tc-arm.c	4 Mar 2008 18:09:26 -0000
@@ -192,11 +192,14 @@ static const arm_feature_set arm_ext_v6k
 static const arm_feature_set arm_ext_v6z = ARM_FEATURE (ARM_EXT_V6Z, 0);
 static const arm_feature_set arm_ext_v6t2 = ARM_FEATURE (ARM_EXT_V6T2, 0);
 static const arm_feature_set arm_ext_v6_notm = ARM_FEATURE (ARM_EXT_V6_NOTM, 0);
+static const arm_feature_set arm_ext_barrier = ARM_FEATURE (ARM_EXT_BARRIER, 0);
+static const arm_feature_set arm_ext_msr = ARM_FEATURE (ARM_EXT_THUMB_MSR, 0);
 static const arm_feature_set arm_ext_div = ARM_FEATURE (ARM_EXT_DIV, 0);
 static const arm_feature_set arm_ext_v7 = ARM_FEATURE (ARM_EXT_V7, 0);
 static const arm_feature_set arm_ext_v7a = ARM_FEATURE (ARM_EXT_V7A, 0);
 static const arm_feature_set arm_ext_v7r = ARM_FEATURE (ARM_EXT_V7R, 0);
-static const arm_feature_set arm_ext_v7m = ARM_FEATURE (ARM_EXT_V7M, 0);
+static const arm_feature_set arm_ext_m =
+ ARM_FEATURE (ARM_EXT_V6M | ARM_EXT_V7M, 0);
 
 static const arm_feature_set arm_arch_any = ARM_ANY;
 static const arm_feature_set arm_arch_full = ARM_FEATURE (-1, -1);
@@ -8497,25 +8500,25 @@ do_t_add_sub (void)
 		 return;
 		}
 
-	 if (inst.instruction == T_MNEM_add)
+	 if (inst.instruction == T_MNEM_add && (Rd == Rs || Rd == Rn))
 		{
-		 if (Rd == Rs)
+		 /* Thumb-1 cores (except v6-M) require at least one high
+		 register in a narrow non flag setting add. */
+		 if (Rd > 7 || Rn > 7
+		 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2)
+		 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_msr))
 		 {
+		 if (Rd == Rn)
+			{
+			 Rn = Rs;
+			 Rs = Rd;
+			}
 		 inst.instruction = T_OPCODE_ADD_HI;
 		 inst.instruction |= (Rd & 8) << 4;
 		 inst.instruction |= (Rd & 7);
 		 inst.instruction |= Rn << 3;
 		 return;
 		 }
-		 /* ... because addition is commutative! */
-		 else if (Rd == Rn)
-		 {
-		 inst.instruction = T_OPCODE_ADD_HI;
-		 inst.instruction |= (Rd & 8) << 4;
-		 inst.instruction |= (Rd & 7);
-		 inst.instruction |= Rs << 3;
-		 return;
-		 }
 		}
 	 }
 	 /* If we get here, it can't be done in 16 bits. */
@@ -9806,7 +9809,7 @@ do_t_mrs (void)
 flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
 if (flags == 0)
 {
- constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7m),
+ constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m),
 		 _("selected processor does not support "
 		 "requested special purpose register"));
 }
@@ -9844,7 +9847,7 @@ do_t_msr (void)
 }
 else
 {
- constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7m),
+ constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m),
 		 _("selected processor does not support "
 		 "requested special purpose register"));
 flags |= PSR_f;
@@ -14225,7 +14228,8 @@ md_assemble (char *str)
 	{
 	 /* Implicit require narrow instructions on Thumb-1. This avoids
 	 relaxation accidentally introducing Thumb-2 instructions. */
-	 if (opcode->tencode != do_t_blx && opcode->tencode != do_t_branch23)
+	 if (opcode->tencode != do_t_blx && opcode->tencode != do_t_branch23
+	 && !ARM_CPU_HAS_FEATURE(*opcode->tvariant, arm_ext_msr))
 	 inst.size_req = 2;
 	}
 
@@ -14279,10 +14283,11 @@ md_assemble (char *str)
 			 *opcode->tvariant);
 /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
 	 set those bits when Thumb-2 32-bit instructions are seen. ie.
-	 anything other than bl/blx.
+	 anything other than bl/blx and v6-M instructions.
 	 This is overly pessimistic for relaxable instructions. */
- if ((inst.size == 4 && (inst.instruction & 0xf800e800) != 0xf000e800)
-	 || inst.relax)
+ if (((inst.size == 4 && (inst.instruction & 0xf800e800) != 0xf000e800)
+	 || inst.relax)
+	 && !ARM_CPU_HAS_FEATURE(*opcode->tvariant, arm_ext_msr))
 	ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
 				arm_ext_v6t2);
 }
@@ -15028,11 +15033,15 @@ static const struct asm_opcode insns[] =
 
 #undef ARM_VARIANT
 #define ARM_VARIANT &arm_ext_v3	/* ARM 6 Status register instructions.	*/
+#undef THUMB_VARIANT
+#define THUMB_VARIANT &arm_ext_msr
 TCE(mrs,	10f0000, f3ef8000, 2, (APSR_RR, RVC_PSR), mrs, t_mrs),
 TCE(msr,	120f000, f3808000, 2, (RVC_PSR, RR_EXi), msr, t_msr),
 
 #undef ARM_VARIANT
 #define ARM_VARIANT &arm_ext_v3m	 /* ARM 7M long multiplies. */
+#undef THUMB_VARIANT
+#define THUMB_VARIANT &arm_ext_v6t2
 TCE(smull,	0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
 CM(smull,s,	0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
 TCE(umull,	0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
@@ -15312,6 +15321,15 @@ static const struct asm_opcode insns[] =
 TCE(sdiv,	0, fb90f0f0, 3, (RR, oRR, RR), 0, t_div),
 TCE(udiv,	0, fbb0f0f0, 3, (RR, oRR, RR), 0, t_div),
 
+ /* ARM V6M/V7 instructions. */
+#undef ARM_VARIANT
+#define ARM_VARIANT &arm_ext_barrier
+#undef THUMB_VARIANT
+#define THUMB_VARIANT &arm_ext_barrier
+ TUF(dmb,	57ff050, f3bf8f50, 1, (oBARRIER), barrier, t_barrier),
+ TUF(dsb,	57ff040, f3bf8f40, 1, (oBARRIER), barrier, t_barrier),
+ TUF(isb,	57ff060, f3bf8f60, 1, (oBARRIER), barrier, t_barrier),
+
 /* ARM V7 instructions. */
 #undef ARM_VARIANT
 #define ARM_VARIANT &arm_ext_v7
@@ -15319,9 +15337,6 @@ static const struct asm_opcode insns[] =
 #define THUMB_VARIANT &arm_ext_v7
 TUF(pli,	450f000, f910f000, 1, (ADDR),	 pli,	 t_pld),
 TCE(dbg,	320f0f0, f3af80f0, 1, (I15),	 dbg,	 t_dbg),
- TUF(dmb,	57ff050, f3bf8f50, 1, (oBARRIER), barrier, t_barrier),
- TUF(dsb,	57ff040, f3bf8f40, 1, (oBARRIER), barrier, t_barrier),
- TUF(isb,	57ff060, f3bf8f60, 1, (oBARRIER), barrier, t_barrier),
 
 #undef ARM_VARIANT
 #define ARM_VARIANT &fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */
@@ -20099,6 +20114,7 @@ static const struct arm_cpu_option_table
 NULL},
 {"cortex-r4",		ARM_ARCH_V7R,	 FPU_NONE,	 NULL},
 {"cortex-m3",		ARM_ARCH_V7M,	 FPU_NONE,	 NULL},
+ {"cortex-m1",		ARM_ARCH_V6M,	 FPU_NONE,	 NULL},
 /* ??? XSCALE is really an architecture. */
 {"xscale",		ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL},
 /* ??? iwmmxt is not a processor. */
@@ -20147,6 +20163,7 @@ static const struct arm_arch_option_tabl
 {"armv6kt2",		ARM_ARCH_V6KT2,	 FPU_ARCH_VFP},
 {"armv6zt2",		ARM_ARCH_V6ZT2,	 FPU_ARCH_VFP},
 {"armv6zkt2",		ARM_ARCH_V6ZKT2, FPU_ARCH_VFP},
+ {"armv6-m",		ARM_ARCH_V6M,	 FPU_ARCH_VFP},
 {"armv7",		ARM_ARCH_V7,	 FPU_ARCH_VFP},
 /* The official spelling of the ARMv7 profile variants is the dashed form.
 Accept the non-dashed form for compatibility with old toolchains. */
@@ -20584,8 +20601,9 @@ static const cpu_arch_ver_table cpu_arch
 {5, ARM_ARCH_V5TEJ},
 {6, ARM_ARCH_V6},
 {7, ARM_ARCH_V6Z},
- {8, ARM_ARCH_V6K},
- {9, ARM_ARCH_V6T2},
+ {9, ARM_ARCH_V6K},
+ {9, ARM_ARCH_V6M},
+ {8, ARM_ARCH_V6T2},
 {10, ARM_ARCH_V7A},
 {10, ARM_ARCH_V7R},
 {10, ARM_ARCH_V7M},
@@ -20647,7 +20665,7 @@ aeabi_set_public_attributes (void)
 bfd_elf_add_proc_attr_int (stdoutput, 7, 'A');
 else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7r))
 bfd_elf_add_proc_attr_int (stdoutput, 7, 'R');
- else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7m))
+ else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_m))
 bfd_elf_add_proc_attr_int (stdoutput, 7, 'M');
 /* Tag_ARM_ISA_use. */
 if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_full))
Index: gas/testsuite/gas/arm/archv6m.d
===================================================================
RCS file: gas/testsuite/gas/arm/archv6m.d
diff -N gas/testsuite/gas/arm/archv6m.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/archv6m.d	4 Mar 2008 18:09:26 -0000
@@ -0,0 +1,15 @@
+# name: ARMv6-M
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> f386 8800 	msr	(APSR|CPSR_f), r6
+0[0-9a-f]+ <[^>]+> f389 8806 	msr	EPSR, r9
+0[0-9a-f]+ <[^>]+> f3ef 8201 	mrs	r2, IAPSR
+0[0-9a-f]+ <[^>]+> bf10 	yield
+0[0-9a-f]+ <[^>]+> bf20 	wfe
+0[0-9a-f]+ <[^>]+> bf30 	wfi
+0[0-9a-f]+ <[^>]+> bf40 	sev
+0[0-9a-f]+ <[^>]+> 4408 	add	r0, r1
+0[0-9a-f]+ <[^>]+> bf00 	nop
Index: gas/testsuite/gas/arm/archv6m.s
===================================================================
RCS file: gas/testsuite/gas/arm/archv6m.s
diff -N gas/testsuite/gas/arm/archv6m.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/archv6m.s	4 Mar 2008 18:09:26 -0000
@@ -0,0 +1,16 @@
+	.arch	armv6-m
+	.syntax unified
+	.thumb
+	.text
+	.align	2
+	.global	foo
+foo:
+	msr apsr,r6
+	msr epsr,r9
+	mrs r2, iapsr
+	yield
+	wfe
+	wfi
+	sev
+	add r0, r0, r1
+	nop
Index: gas/testsuite/gas/arm/t16-bad.l
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/arm/t16-bad.l,v
retrieving revision 1.2
diff -u -p -r1.2 t16-bad.l
--- gas/testsuite/gas/arm/t16-bad.l	18 May 2005 05:40:10 -0000	1.2
+++ gas/testsuite/gas/arm/t16-bad.l	4 Mar 2008 18:09:26 -0000
@@ -184,3 +184,4 @@
 [^:]*:134: Error: Thumb does not support the 2-argument form of this instruction -- `cpsie ai,#5'
 [^:]*:135: Error: Thumb does not support the 2-argument form of this instruction -- `cpsid ai,#5'
 [^:]*:138: Error: Thumb does not support conditional execution
+[^:]*:141: Error: cannot honor width suffix -- `add r0,r1'
Index: gas/testsuite/gas/arm/t16-bad.s
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/arm/t16-bad.s,v
retrieving revision 1.2
diff -u -p -r1.2 t16-bad.s
--- gas/testsuite/gas/arm/t16-bad.s	18 May 2005 05:40:10 -0000	1.2
+++ gas/testsuite/gas/arm/t16-bad.s	4 Mar 2008 18:09:26 -0000
@@ -136,3 +136,7 @@ l:
 
 	@ Conditional suffixes
 	addeq	r0,r1,r2
+	@ low register non flag setting add.
+	.syntax unified
+	add	r0, r1
+
Index: include/opcode/arm.h
===================================================================
RCS file: /var/cvsroot/src-cvs/src/include/opcode/arm.h,v
retrieving revision 1.11
diff -u -p -r1.11 arm.h
--- include/opcode/arm.h	26 Sep 2006 12:04:45 -0000	1.11
+++ include/opcode/arm.h	3 Mar 2008 16:56:30 -0000
@@ -44,6 +44,9 @@
 #define ARM_EXT_V7A	 0x00100000	/* Arm V7A. */
 #define ARM_EXT_V7R	 0x00200000	/* Arm V7R. */
 #define ARM_EXT_V7M	 0x00400000	/* Arm V7M. */
+#define ARM_EXT_V6M	 0x00800000	/* ARM V6M.		 */
+#define ARM_EXT_BARRIER	 0x01000000	/* DSB/DMB/ISB.		 */
+#define ARM_EXT_THUMB_MSR 0x02000000	/* Thumb MSR/MRS.	 */
 
 /* Co-processor space extensions. */
 #define ARM_CEXT_XSCALE 0x00000001	/* Allow MIA etc. */
@@ -87,17 +90,22 @@
 #define ARM_AEXT_V6K (ARM_AEXT_V6 | ARM_EXT_V6K)
 #define ARM_AEXT_V6Z (ARM_AEXT_V6 | ARM_EXT_V6Z)
 #define ARM_AEXT_V6ZK (ARM_AEXT_V6 | ARM_EXT_V6K | ARM_EXT_V6Z)
-#define ARM_AEXT_V6T2 (ARM_AEXT_V6 | ARM_EXT_V6T2 | ARM_EXT_V6_NOTM)
+#define ARM_AEXT_V6T2 (ARM_AEXT_V6 \
+ | ARM_EXT_V6T2 | ARM_EXT_V6_NOTM | ARM_EXT_THUMB_MSR)
 #define ARM_AEXT_V6KT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K)
 #define ARM_AEXT_V6ZT2 (ARM_AEXT_V6T2 | ARM_EXT_V6Z)
 #define ARM_AEXT_V6ZKT2 (ARM_AEXT_V6T2 | ARM_EXT_V6K | ARM_EXT_V6Z)
-#define ARM_AEXT_V7_ARM	(ARM_AEXT_V6ZKT2 | ARM_EXT_V7)
+#define ARM_AEXT_V7_ARM	(ARM_AEXT_V6ZKT2 | ARM_EXT_V7 | ARM_EXT_BARRIER)
 #define ARM_AEXT_V7A	(ARM_AEXT_V7_ARM | ARM_EXT_V7A)
 #define ARM_AEXT_V7R	(ARM_AEXT_V7_ARM | ARM_EXT_V7R | ARM_EXT_DIV)
 #define ARM_AEXT_NOTM \
 (ARM_AEXT_V4 | ARM_EXT_V5ExP | ARM_EXT_V5J | ARM_EXT_V6_NOTM)
+#define ARM_AEXT_V6M \
+ ((ARM_AEXT_V6K | ARM_EXT_BARRIER | ARM_EXT_V6M | ARM_EXT_THUMB_MSR) \
+ & ~(ARM_AEXT_NOTM))
 #define ARM_AEXT_V7M \
- ((ARM_AEXT_V7_ARM | ARM_EXT_V7M | ARM_EXT_DIV) & ~(ARM_AEXT_NOTM))
+ ((ARM_AEXT_V7_ARM | ARM_EXT_V6M | ARM_EXT_V7M | ARM_EXT_DIV) \
+ & ~(ARM_AEXT_NOTM))
 #define ARM_AEXT_V7 (ARM_AEXT_V7A & ARM_AEXT_V7R & ARM_AEXT_V7M)
 
 /* Processors with specific extensions in the co-processor space. */
@@ -158,6 +166,7 @@
 #define ARM_ARCH_V6KT2	ARM_FEATURE (ARM_AEXT_V6KT2, 0)
 #define ARM_ARCH_V6ZT2	ARM_FEATURE (ARM_AEXT_V6ZT2, 0)
 #define ARM_ARCH_V6ZKT2	ARM_FEATURE (ARM_AEXT_V6ZKT2, 0)
+#define ARM_ARCH_V6M	ARM_FEATURE (ARM_AEXT_V6M, 0)
 #define ARM_ARCH_V7	ARM_FEATURE (ARM_AEXT_V7, 0)
 #define ARM_ARCH_V7A	ARM_FEATURE (ARM_AEXT_V7A, 0)
 #define ARM_ARCH_V7R	ARM_FEATURE (ARM_AEXT_V7R, 0)

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

AltStyle によって変換されたページ (->オリジナル) /