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)