2008-03-04 Paul Brook <paul@codesourcery.com>
authorPaul Brook <paul@codesourcery.com>
Wed, 5 Mar 2008 01:31:26 +0000 (01:31 +0000)
committerPaul Brook <paul@codesourcery.com>
Wed, 5 Mar 2008 01:31:26 +0000 (01:31 +0000)
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.

gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/archv6m.d [new file with mode: 0644]
gas/testsuite/gas/arm/archv6m.s [new file with mode: 0644]
gas/testsuite/gas/arm/t16-bad.l
gas/testsuite/gas/arm/t16-bad.s
include/opcode/ChangeLog
include/opcode/arm.h

index 80337c444b3d7d0cb346109d361c634d74143a8d..e9419a3b9708413217b653aa971362688d3c5d82 100644 (file)
@@ -1,3 +1,16 @@
+2008-03-04  Paul Brook  <paul@codesourcery.com>
+
+       * 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.
+
 2008-03-03  Sterling Augustine  <sterling@tensilica.com>
            Bob Wilson  <bob.wilson@acm.org>
        
index 01a4728353994c71c00144d1449b60d08f1fabdc..48fb1522f80980ef9eb9e695a19c2b72185dbc83 100644 (file)
@@ -192,11 +192,14 @@ static const arm_feature_set arm_ext_v6k = ARM_FEATURE (ARM_EXT_V6K, 0);
 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 arm_cpus[] =
                                                           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_table arm_archs[] =
   {"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_ver[] =
     {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 deef67544b163bf835251329a79691cb6bda1624..6180aa1c6c9228487bee4fafb7967a6e7223b44c 100644 (file)
@@ -1,3 +1,10 @@
+2008-03-04  Paul Brook  <paul@codesourcery.com>
+
+       * 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.
+
 2008-03-03  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR gas/5543
diff --git a/gas/testsuite/gas/arm/archv6m.d b/gas/testsuite/gas/arm/archv6m.d
new file mode 100644 (file)
index 0000000..b6ef1e6
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/arm/archv6m.s b/gas/testsuite/gas/arm/archv6m.s
new file mode 100644 (file)
index 0000000..158b6a6
--- /dev/null
@@ -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 7c322609ffe0e8ce31e0bc2d6732d71456cab479..80cf045ba1e294c55641fb74e04e4c6c5dbb2166 100644 (file)
 [^:]*: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 a80a81ff0586c8f8fffcfbc954a8ccaad5a0d56e..165413f18fe7cdb7cc573c397f18b429732312a2 100644 (file)
@@ -136,3 +136,7 @@ l:
 
        @ Conditional suffixes
        addeq   r0,r1,r2
+       @ low register non flag setting add.
+       .syntax unified
+       add     r0, r1
+
index 9b2c5c346fb40e3fe5cb87c2e7d7b3098d2bf26a..8b440720095aad078cdeaa05d05624d118d1ed74 100644 (file)
@@ -1,3 +1,9 @@
+2008-03-04  Paul Brook  <paul@codesourcery.com>
+
+       * 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.
+
 2008-02-27  Denis Vlasenko  <vda.linux@googlemail.com>
            Nick Clifton  <nickc@redhat.com>
 
index 24a89cfcb1d13c4419b4338c663b54d2e27c2170..5f93fd76368babead78ba6b25517534b71702b5c 100644 (file)
@@ -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.          */
 #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.  */
 #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)