aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog14
-rw-r--r--gas/config/tc-arm.c76
2 files changed, 60 insertions, 30 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))