Consolidate Thumb-1/Thumb-2 ISA detection
authorThomas Preud'homme <thomas.preudhomme@arm.com>
Thu, 24 Dec 2015 09:01:42 +0000 (17:01 +0800)
committerThomas Preud'homme <thomas.preudhomme@arm.com>
Thu, 24 Dec 2015 09:03:50 +0000 (17:03 +0800)
2015-12-24  Thomas Preud'homme  <thomas.preudhomme@arm.com>

gas/
    * config/tc-arm.c (move_or_literal_pool): Check mov.w, mvm and movw
    availability against arm_ext_v6t2 instead of checking arm_arch_t2,
    fixing comments along the way.
    (handle_it_state): Check arm_ext_v6t2 instead of arm_arch_t2 to
    generate IT instruction.
    (t1_isa_t32_only_insn): New function.
    (md_assemble): Use above new function to check for invalid wide
    instruction for CPU Thumb ISA and to determine what Thumb extension
    bit is necessary for that instruction.
    (md_apply_fix): Use arm_ext_v6t2 instead of arm_arch_t2 to decide if
    branch is out of range.

include/opcode/
    * arm.h (ARM_ARCH_THUMB2): Add comment explaining its meaning and
    remove extension bit not including any Thumb-2 instruction.

gas/ChangeLog
gas/config/tc-arm.c
include/opcode/ChangeLog
include/opcode/arm.h

index a7ceb30b842371b302d0753f996bf77cb55d4aa5..8a62482ec73f84fca258d65b75d9189168426bc8 100644 (file)
@@ -1,3 +1,17 @@
+2015-12-24  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
+       * config/tc-arm.c (move_or_literal_pool): Check mov.w, mvm and movw
+       availability against arm_ext_v6t2 instead of checking arm_arch_t2,
+       fixing comments along the way.
+       (handle_it_state): Check arm_ext_v6t2 instead of arm_arch_t2 to
+       generate IT instruction.
+       (t1_isa_t32_only_insn): New function.
+       (md_assemble): Use above new function to check for invalid wide
+       instruction for CPU Thumb ISA and to determine what Thumb extension
+       bit is necessary for that instruction.
+       (md_apply_fix): Use arm_ext_v6t2 instead of arm_arch_t2 to decide if
+       branch is out of range.
+
 2015-12-21  Nick Clifton  <nickc@redhat.com>
 
        PR gas/19386
index f9c76ef7c35960cc06d89d842d79024a6a0d7652..23e3506bcee4d1c67f3c6f1862f11862e09babe8 100644 (file)
@@ -7869,10 +7869,10 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
                  return TRUE;
                }
 
-             if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_arch_t2))
+             if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
                {
-                 /* Check if on thumb2 it can be done with a mov.w or mvn.w
-                    instruction.  */
+                 /* Check if on thumb2 it can be done with a mov.w, mvn or
+                    movw instruction.  */
                  unsigned int newimm;
                  bfd_boolean isNegated;
 
@@ -7886,19 +7886,22 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
                        isNegated = TRUE;
                    }
 
+                 /* The number can be loaded with a mov.w or mvn
+                    instruction.  */
                  if (newimm != (unsigned int) FAIL)
                    {
-                     inst.instruction = (0xf04f0000
+                     inst.instruction = (0xf04f0000  /*  MOV.W.  */
                                          | (inst.operands[i].reg << 8));
+                     /* Change to MOVN.  */
                      inst.instruction |= (isNegated ? 0x200000 : 0);
                      inst.instruction |= (newimm & 0x800) << 15;
                      inst.instruction |= (newimm & 0x700) << 4;
                      inst.instruction |= (newimm & 0x0ff);
                      return TRUE;
                    }
+                 /* The number can be loaded with a movw instruction.  */
                  else if ((v & ~0xFFFF) == 0)
                    {
-                     /* The number can be loaded with a mov.w instruction.  */
                      int imm = v & 0xFFFF;
 
                      inst.instruction = 0xf2400000;  /* MOVW.  */
@@ -17563,7 +17566,7 @@ handle_it_state (void)
          else
            {
              if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
-                 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_arch_t2))
+                 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
                {
                  /* Automatically generate the IT instruction.  */
                  new_automatic_it_block (inst.cond);
@@ -17795,6 +17798,22 @@ in_it_block (void)
   return now_it.state != OUTSIDE_IT_BLOCK;
 }
 
+/* Whether OPCODE only has T32 encoding and makes build attribute
+   Tag_THUMB_ISA_use be set to 1 if assembled without any cpu or arch info.  */
+
+static bfd_boolean
+t1_isa_t32_only_insn (const struct asm_opcode *opcode)
+{
+  /* Original Thumb-1 wide instruction.  */
+  if (opcode->tencode == do_t_blx
+      || opcode->tencode == do_t_branch23
+      || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr)
+      || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))
+    return TRUE;
+
+  return FALSE;
+}
+
 void
 md_assemble (char *str)
 {
@@ -17854,24 +17873,24 @@ md_assemble (char *str)
          return;
        }
 
-      if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2))
+      /* Two things are addressed here:
+        1) Implicit require narrow instructions on Thumb-1.
+           This avoids relaxation accidentally introducing Thumb-2
+           instructions.
+        2) Reject wide instructions in non Thumb-2 cores.
+
+        Only instructions with narrow and wide variants need to be handled
+        but selecting all non wide-only instructions is easier.  */
+      if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)
+         && !t1_isa_t32_only_insn (opcode))
        {
-         if (opcode->tencode != do_t_blx && opcode->tencode != do_t_branch23
-             && !(ARM_CPU_HAS_FEATURE(*opcode->tvariant, arm_ext_msr)
-                  || ARM_CPU_HAS_FEATURE(*opcode->tvariant, arm_ext_barrier)))
+         if (inst.size_req == 0)
+           inst.size_req = 2;
+         else if (inst.size_req == 4)
            {
-             /* Two things are addressed here.
-                1) Implicit require narrow instructions on Thumb-1.
-                   This avoids relaxation accidentally introducing Thumb-2
-                    instructions.
-                2) Reject wide instructions in non Thumb-2 cores.  */
-             if (inst.size_req == 0)
-               inst.size_req = 2;
-             else if (inst.size_req == 4)
-               {
-                 as_bad (_("selected processor does not support `%s' in Thumb-2 mode"), str);
-                 return;
-               }
+             as_bad (_("selected processor does not support `%s' in Thumb-2 "
+                       "mode"), str);
+             return;
            }
        }
 
@@ -17906,13 +17925,10 @@ md_assemble (char *str)
       ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
                              *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 and v6-M instructions.
-        The impact of relaxable instructions will be considered later after we
-        finish all relaxation.  */
-      if ((inst.size == 4 && (inst.instruction & 0xf800e800) != 0xf000e800)
-         && !(ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr)
-              || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier)))
+        set those bits when Thumb-2 32-bit instructions are seen.  The impact
+        of relaxable instructions will be considered later after we finish all
+        relaxation.  */
+      if (inst.size == 4 && !t1_isa_t32_only_insn (opcode))
        ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
                                arm_ext_v6t2);
 
@@ -22880,7 +22896,7 @@ md_apply_fix (fixS *    fixP,
 
       if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
        {
-         if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_arch_t2)))
+         if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)))
            as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
          else if ((value & ~0x1ffffff)
                   && ((value & ~0x1ffffff) != ~0x1ffffff))
index ca7492b3de29d72ba90ad4ed4cdd7c8d7b108ac5..e0d3f26662713440ba098195e8067dd922a59917 100644 (file)
@@ -1,3 +1,8 @@
+2015-12-24  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
+       * arm.h (ARM_ARCH_THUMB2): Add comment explaining its meaning and
+       remove extension bit not including any Thumb-2 instruction.
+
 2015-12-15  Matthew Wahab  <matthew.wahab@arm.com>
 
        * arm.h (ARM_ARCH_V8_1A): Add the CRC_EXT_ARMV8 co-processor
index daeb626ee2282c127c2ab5d24a8315fe55c75cae..eb0619ce41ecd5e2b375ee7e752d963aa5cd60ad 100644 (file)
 #define ARM_ANY                ARM_FEATURE (-1, -1, 0) /* Any basic core.  */
 #define ARM_FEATURE_ALL        ARM_FEATURE (-1, -1, -1)/* All CPU and FPU features.  */
 #define FPU_ANY_HARD   ARM_FEATURE_COPROC (FPU_FPA | FPU_VFP_HARD | FPU_MAVERICK)
+/* Extensions containing some Thumb-2 instructions.  If any is present, Thumb
+   ISA is Thumb-2.  */
 #define ARM_ARCH_THUMB2 ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2 | ARM_EXT_V7        \
-                                             | ARM_EXT_V7A | ARM_EXT_V7R \
-                                             | ARM_EXT_V7M | ARM_EXT_DIV \
-                                             | ARM_EXT_V8)
+                                             | ARM_EXT_DIV | ARM_EXT_V8)
 /* v7-a+sec.  */
 #define ARM_ARCH_V7A_SEC ARM_FEATURE_CORE_LOW (ARM_AEXT_V7A | ARM_EXT_SEC)
 /* v7-a+mp+sec.  */