[PATCH, ARM 1/7] Consolidate Thumb-1/Thumb-2 ISA detection

Thomas Preud'homme thomas.preudhomme@foss.arm.com
Wed Dec 23 06:43:00 GMT 2015


> From: binutils-owner@sourceware.org [mailto:binutils-
> owner@sourceware.org] On Behalf Of Richard Earnshaw (lists)
> Sent: Friday, December 18, 2015 7:55 PM
> 
> non_v6t2_wide_only_insn should be rewritten to be
> v6t2_wide_only_insn
> with its return values giving the opposite sense.  I really don't like
> functions that directly imply a negative in their name as the logic
> becomes very confusing when the result is then inverted.  I note that
> every single use of this function in the patch uses "!non_...".

It was actually a positive statement since the negative for that function would be instructions that are not T32 or that are part of v6t2. That of course shows how confusing was the function name and its comment. Hopefully, this should be addressed in this new version (please note that the function changes its name in patch 3/7 for ARMv8-M Baseline support).

> 
> Otherwise this is OK.
> 
> I'll note for the record here that the use of Thumb-1 and Thumb-2 is now
> somewhat anachronistic.  It would be better if the internal variables
> and terminology could be cleaned up to talk about T16 and T32 encodings
> (I think that's also somewhat cleaner than wide and narrow).  However,
> that's a more general cleanup patch and doesn't specifically apply to
> the changes here.

Should be better here as well, at least in terms of naming and comments. Of course, one of the two uses for this function is related to deciding the value of Tag_THUMB_ISA_use.

New ChangeLog entries are as follow:


*** gas/ChangeLog ***

2015-12-22  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.


*** include/opcode/ChangeLog ***

2015-12-10  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.


diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index f9c76ef7c35960cc06d89d842d79024a6a0d7652..23e3506bcee4d1c67f3c6f1862f11862e09babe8 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -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))
diff --git a/include/opcode/arm.h b/include/opcode/arm.h
index daeb626ee2282c127c2ab5d24a8315fe55c75cae..eb0619ce41ecd5e2b375ee7e752d963aa5cd60ad 100644
--- a/include/opcode/arm.h
+++ b/include/opcode/arm.h
@@ -263,10 +263,10 @@
 #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.  */

Best regards,

Thomas



More information about the Binutils mailing list