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> 2015-12-21 Nick Clifton <nickc@redhat.com>
PR gas/19386 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; 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 /* Check if on thumb2 it can be done with a mov.w, mvn or
instruction. */ movw instruction. */
unsigned int newimm; unsigned int newimm;
bfd_boolean isNegated; bfd_boolean isNegated;
@ -7886,19 +7886,22 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
isNegated = TRUE; isNegated = TRUE;
} }
/* The number can be loaded with a mov.w or mvn
instruction. */
if (newimm != (unsigned int) FAIL) if (newimm != (unsigned int) FAIL)
{ {
inst.instruction = (0xf04f0000 inst.instruction = (0xf04f0000 /* MOV.W. */
| (inst.operands[i].reg << 8)); | (inst.operands[i].reg << 8));
/* Change to MOVN. */
inst.instruction |= (isNegated ? 0x200000 : 0); inst.instruction |= (isNegated ? 0x200000 : 0);
inst.instruction |= (newimm & 0x800) << 15; inst.instruction |= (newimm & 0x800) << 15;
inst.instruction |= (newimm & 0x700) << 4; inst.instruction |= (newimm & 0x700) << 4;
inst.instruction |= (newimm & 0x0ff); inst.instruction |= (newimm & 0x0ff);
return TRUE; return TRUE;
} }
/* The number can be loaded with a movw instruction. */
else if ((v & ~0xFFFF) == 0) else if ((v & ~0xFFFF) == 0)
{ {
/* The number can be loaded with a mov.w instruction. */
int imm = v & 0xFFFF; int imm = v & 0xFFFF;
inst.instruction = 0xf2400000; /* MOVW. */ inst.instruction = 0xf2400000; /* MOVW. */
@ -17563,7 +17566,7 @@ handle_it_state (void)
else else
{ {
if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB) 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. */ /* Automatically generate the IT instruction. */
new_automatic_it_block (inst.cond); new_automatic_it_block (inst.cond);
@ -17795,6 +17798,22 @@ in_it_block (void)
return now_it.state != OUTSIDE_IT_BLOCK; 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 void
md_assemble (char *str) md_assemble (char *str)
{ {
@ -17854,26 +17873,26 @@ md_assemble (char *str)
return; return;
} }
if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)) /* Two things are addressed here:
{
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)))
{
/* Two things are addressed here.
1) Implicit require narrow instructions on Thumb-1. 1) Implicit require narrow instructions on Thumb-1.
This avoids relaxation accidentally introducing Thumb-2 This avoids relaxation accidentally introducing Thumb-2
instructions. instructions.
2) Reject wide instructions in non Thumb-2 cores. */ 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 (inst.size_req == 0) if (inst.size_req == 0)
inst.size_req = 2; inst.size_req = 2;
else if (inst.size_req == 4) else if (inst.size_req == 4)
{ {
as_bad (_("selected processor does not support `%s' in Thumb-2 mode"), str); as_bad (_("selected processor does not support `%s' in Thumb-2 "
"mode"), str);
return; return;
} }
} }
}
inst.instruction = opcode->tvalue; inst.instruction = opcode->tvalue;
@ -17906,13 +17925,10 @@ md_assemble (char *str)
ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
*opcode->tvariant); *opcode->tvariant);
/* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
set those bits when Thumb-2 32-bit instructions are seen. ie. set those bits when Thumb-2 32-bit instructions are seen. The impact
anything other than bl/blx and v6-M instructions. of relaxable instructions will be considered later after we finish all
The impact of relaxable instructions will be considered later after we relaxation. */
finish all relaxation. */ if (inst.size == 4 && !t1_isa_t32_only_insn (opcode))
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)))
ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
arm_ext_v6t2); arm_ext_v6t2);
@ -22880,7 +22896,7 @@ md_apply_fix (fixS * fixP,
if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff)) 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); as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
else if ((value & ~0x1ffffff) else if ((value & ~0x1ffffff)
&& ((value & ~0x1ffffff) != ~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> 2015-12-15 Matthew Wahab <matthew.wahab@arm.com>
* arm.h (ARM_ARCH_V8_1A): Add the CRC_EXT_ARMV8 co-processor * 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_ANY ARM_FEATURE (-1, -1, 0) /* Any basic core. */
#define ARM_FEATURE_ALL ARM_FEATURE (-1, -1, -1)/* All CPU and FPU features. */ #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) #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 \ #define ARM_ARCH_THUMB2 ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2 | ARM_EXT_V7 \
| ARM_EXT_V7A | ARM_EXT_V7R \ | ARM_EXT_DIV | ARM_EXT_V8)
| ARM_EXT_V7M | ARM_EXT_DIV \
| ARM_EXT_V8)
/* v7-a+sec. */ /* v7-a+sec. */
#define ARM_ARCH_V7A_SEC ARM_FEATURE_CORE_LOW (ARM_AEXT_V7A | ARM_EXT_SEC) #define ARM_ARCH_V7A_SEC ARM_FEATURE_CORE_LOW (ARM_AEXT_V7A | ARM_EXT_SEC)
/* v7-a+mp+sec. */ /* v7-a+mp+sec. */