aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Preud'homme <thomas.preudhomme@arm.com>2015-12-24 17:01:42 +0800
committerThomas Preud'homme <thomas.preudhomme@arm.com>2015-12-24 17:03:50 +0800
commitfc289b0a832c536a2ec324634cb420f39b212696 (patch)
tree3e5e7105c3ab6ae8d8723d4367db1127079713ab
parent443bfd5a371633064bf251a74b27382c7774f217 (diff)
downloadfsf-binutils-gdb-fc289b0a832c536a2ec324634cb420f39b212696.zip
fsf-binutils-gdb-fc289b0a832c536a2ec324634cb420f39b212696.tar.gz
fsf-binutils-gdb-fc289b0a832c536a2ec324634cb420f39b212696.tar.bz2
Consolidate Thumb-1/Thumb-2 ISA detection
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.
-rw-r--r--gas/ChangeLog14
-rw-r--r--gas/config/tc-arm.c76
-rw-r--r--include/opcode/ChangeLog5
-rw-r--r--include/opcode/arm.h6
4 files changed, 68 insertions, 33 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index a7ceb30..8a62482 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index f9c76ef..23e3506 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/ChangeLog b/include/opcode/ChangeLog
index ca7492b..e0d3f26 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -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
diff --git a/include/opcode/arm.h b/include/opcode/arm.h
index daeb626..eb0619c 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. */