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.
This commit is contained in:
Thomas Preud'homme 2015-12-24 17:01:42 +08:00
parent 443bfd5a37
commit fc289b0a83
4 changed files with 68 additions and 33 deletions

View 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

View 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))

View 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

View file

@ -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. */