aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorThomas Preud'homme <thomas.preudhomme@arm.com>2015-12-24 17:26:08 +0800
committerThomas Preud'homme <thomas.preudhomme@arm.com>2015-12-24 17:27:21 +0800
commitff8646eef8bdef6fe3091eb79627929c1c100c6a (patch)
tree22b3df21915370c9fc6a15be5816f4db93e77edf /gas/config
parent4ed7ed8db2289a9cd61312c14344cb210dc229b7 (diff)
downloadgdb-ff8646eef8bdef6fe3091eb79627929c1c100c6a.zip
gdb-ff8646eef8bdef6fe3091eb79627929c1c100c6a.tar.gz
gdb-ff8646eef8bdef6fe3091eb79627929c1c100c6a.tar.bz2
Add assembler support for ARMv8-M Baseline
2015-12-24 Thomas Preud'homme <thomas.preudhomme@arm.com> bfd/ (tag_cpu_arch_combine): Adjust comment in v4t_plus_v6_m with regards to merging with ARMv8-M Baseline. binutils/ * readelf.c (arm_attr_tag_CPU_arch): Add ARMv8-M Baseline Tag_CPU_arch value. gas/ * config/tc-arm.c (arm_ext_v6t2_v8m): New feature for instructions shared between ARMv6T2 and ARMv8-M. (move_or_literal_pool): Check mov.w/mvn and movw availability against arm_ext_v6t2 and arm_ext_v6t2_v8m respectively instead of checking arm_arch_t2. (do_t_branch): Error out for wide conditional branch instructions if targetting ARMv8-M Baseline. (non_v6t2_wide_only_insn): Add the logic for new wide-only instructions in ARMv8-M Baseline. (wide_insn_ok): New function. (md_assemble): Use wide_insn_ok instead of non_v6t2_wide_only_insn and adapt error message for unsupported wide instruction to ARMv8-M Baseline. (insns): Reorganize instructions shared by ARMv8-M Baseline and ARMv6t2 architecture. (arm_cpus): Set feature bit ARM_EXT2_V6T2_V8M for marvell-pj4 and marvell-whitney cores. (arm_archs): Define armv8-m.base architecture. (cpu_arch_ver): Define ARM_ARCH_V8M_BASE architecture version. (aeabi_set_public_attributes): Add logic to set Tag_CPU_arch to 17 for ARMv8-M Mainline. Set Tag_DIV_use for ARMv8-M Baseline as well. gas/testsuite/ * gas/arm/archv8m-base.d: New file. * gas/arm/attr-march-armv8m.base.d: Likewise. * gas/arm/armv8m.base-idiv.d: Likewise. * gas/arm/any-armv8m.d: Adapt to deal with ARMv8-M Baseline. include/elf/ * arm.h (TAG_CPU_ARCH_V8M_BASE): Declare. include/opcode/ * arm.h (ARM_EXT2_V6T2_V8M): New extension bit. (ARM_AEXT2_V8A): New architecture extension bitfield. (ARM_AEXT2_V8_1A): Use ARM_AEXT2_V8A instead of ARM_EXT2_ATOMICS. (ARM_AEXT_V8M_BASE): New architecture extension bitfield. (ARM_AEXT2_V8M): Add extension bit ARM_EXT2_V6T2_V8M. (ARM_ARCH_V6T2): Use ARM_EXT2_V6T2_V8M for the second extension bitfield. (ARM_ARCH_V6KT2): Likewise. (ARM_ARCH_V6ZT2): Likewise. (ARM_ARCH_V6KZT2): Likewise. (ARM_ARCH_V7): Likewise. (ARM_ARCH_V7A): Likewise. (ARM_ARCH_V7VE): Likewise. (ARM_ARCH_V7R): Likewise. (ARM_ARCH_V7M): Likewise. (ARM_ARCH_V7EM): Likewise. (ARM_ARCH_V8A): Likewise. (ARM_ARCH_V8M_BASE): New architecture bitfield. (ARM_ARCH_THUMB2): Include instructions shared by ARMv6t2 and ARMv8-M. (ARM_ARCH_V7A_SEC): Use ARM_EXT2_V6T2_V8M for the second extension bitfield and reindent. (ARM_ARCH_V7A_MP_SEC): Likewise. (ARM_ARCH_V7R_IDIV): Likewise. (ARM_ARCH_V8A_FP): Use ARM_AEXT2_V8A instead of ARM_EXT2_ATOMICS. (ARM_ARCH_V8A_SIMD): Likewise. (ARM_ARCH_V8A_CRYPTOV1): Likewise. opcodes/ * arm-dis.c (arm_opcodes): Guard movw, movt cbz, cbnz, clrex, ldrex, ldrexb, ldrexh, strex, strexb, strexh shared by ARMv6T2 and ARMv8-M by ARM_EXT2_V6T2_V8M instead of ARM_EXT_V6T2.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-arm.c108
1 files changed, 89 insertions, 19 deletions
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 7992360..d23181c 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -209,6 +209,8 @@ static const arm_feature_set arm_ext_adiv = ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV);
static const arm_feature_set arm_ext_virt = ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT);
static const arm_feature_set arm_ext_pan = ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN);
static const arm_feature_set arm_ext_v8m = ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M);
+static const arm_feature_set arm_ext_v6t2_v8m =
+ ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M);
/* Instructions shared between ARMv8-A and ARMv8-M. */
static const arm_feature_set arm_ext_atomics =
ARM_FEATURE_CORE_HIGH (ARM_EXT2_ATOMICS);
@@ -7873,7 +7875,8 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
return TRUE;
}
- if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
+ if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
+ || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
{
/* Check if on thumb2 it can be done with a mov.w, mvn or
movw instruction. */
@@ -7892,7 +7895,8 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
/* The number can be loaded with a mov.w or mvn
instruction. */
- if (newimm != (unsigned int) FAIL)
+ if (newimm != (unsigned int) FAIL
+ && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
{
inst.instruction = (0xf04f0000 /* MOV.W. */
| (inst.operands[i].reg << 8));
@@ -7904,7 +7908,8 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
return TRUE;
}
/* The number can be loaded with a movw instruction. */
- else if ((v & ~0xFFFF) == 0)
+ else if ((v & ~0xFFFF) == 0
+ && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
{
int imm = v & 0xFFFF;
@@ -10939,6 +10944,10 @@ do_t_branch (void)
reloc = BFD_RELOC_THUMB_PCREL_BRANCH25;
else
{
+ constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2),
+ _("selected architecture does not support "
+ "wide conditional branch instruction"));
+
gas_assert (cond != 0xF);
inst.instruction |= cond << 22;
reloc = BFD_RELOC_THUMB_PCREL_BRANCH20;
@@ -17809,11 +17818,12 @@ 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. */
+/* Whether OPCODE only has T32 encoding. Since this function is only used by
+ t32_insn_ok, OPCODE enabled by v6t2 extension bit do not need to be listed
+ here, hence the "known" in the function name. */
static bfd_boolean
-t1_isa_t32_only_insn (const struct asm_opcode *opcode)
+known_t32_only_insn (const struct asm_opcode *opcode)
{
/* Original Thumb-1 wide instruction. */
if (opcode->tencode == do_t_blx
@@ -17822,6 +17832,39 @@ t1_isa_t32_only_insn (const struct asm_opcode *opcode)
|| ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))
return TRUE;
+ /* Wide-only instruction added to ARMv8-M. */
+ if (ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v8m)
+ || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_atomics)
+ || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v6t2_v8m)
+ || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_div))
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Whether wide instruction variant can be used if available for a valid OPCODE
+ in ARCH. */
+
+static bfd_boolean
+t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode)
+{
+ if (known_t32_only_insn (opcode))
+ return TRUE;
+
+ /* Instruction with narrow and wide encoding added to ARMv8-M. Availability
+ of variant T3 of B.W is checked in do_t_branch. */
+ if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
+ && opcode->tencode == do_t_branch)
+ return TRUE;
+
+ /* Wide instruction variants of all instructions with narrow *and* wide
+ variants become available with ARMv6t2. Other opcodes are either
+ narrow-only or wide-only and are thus available if OPCODE is valid. */
+ if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v6t2))
+ return TRUE;
+
+ /* OPCODE with narrow only instruction variant or wide variant not
+ available. */
return FALSE;
}
@@ -17893,14 +17936,18 @@ md_assemble (char *str)
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))
+ && !t32_insn_ok (variant, opcode))
{
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);
+ if (ARM_CPU_HAS_FEATURE (variant, arm_ext_v8m))
+ as_bad (_("selected processor does not support 32bit wide "
+ "variant of instruction `%s'"), str);
+ else
+ as_bad (_("selected processor does not support `%s' in "
+ "Thumb-2 mode"), str);
return;
}
}
@@ -17939,7 +17986,11 @@ md_assemble (char *str)
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))
+ if (ARM_FEATURE_CORE_EQUAL (cpu_variant, arm_arch_any))
+ variant = arm_arch_none;
+ else
+ variant = cpu_variant;
+ if (inst.size == 4 && !t32_insn_ok (variant, opcode))
ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
arm_ext_v6t2);
@@ -18906,11 +18957,14 @@ static const struct asm_opcode insns[] =
TUF("setend", 1010000, b650, 1, (ENDI), setend, t_setend),
#undef THUMB_VARIANT
-#define THUMB_VARIANT & arm_ext_v6t2
+#define THUMB_VARIANT & arm_ext_v6t2_v8m
TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc_npcsp, ADDR), ldrex, t_ldrex),
TCE("strex", 1800f90, e8400000, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
strex, t_strex),
+#undef THUMB_VARIANT
+#define THUMB_VARIANT & arm_ext_v6t2
+
TUF("mcrr2", c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
TUF("mrrc2", c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
@@ -19056,7 +19110,7 @@ static const struct asm_opcode insns[] =
RRnpcb), strexd, t_strexd),
#undef THUMB_VARIANT
-#define THUMB_VARIANT & arm_ext_v6t2
+#define THUMB_VARIANT & arm_ext_v6t2_v8m
TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc_npcsp,RRnpcb),
rd_rn, rd_rn),
TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc_npcsp, RRnpcb),
@@ -19100,8 +19154,6 @@ static const struct asm_opcode insns[] =
TCE("ubfx", 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
TCE("mls", 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
- TCE("movw", 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
- TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
TCE("rbit", 6ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
TC3("ldrht", 03000b0, f8300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
@@ -19109,6 +19161,11 @@ static const struct asm_opcode insns[] =
TC3("ldrsbt", 03000d0, f9100e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
TC3("strht", 02000b0, f8200e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
+#undef THUMB_VARIANT
+#define THUMB_VARIANT & arm_ext_v6t2_v8m
+ TCE("movw", 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
+ TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
+
/* Thumb-only instructions. */
#undef ARM_VARIANT
#define ARM_VARIANT NULL
@@ -19120,6 +19177,8 @@ static const struct asm_opcode insns[] =
-mimplicit-it=[never | arm] modes. */
#undef ARM_VARIANT
#define ARM_VARIANT & arm_ext_v1
+#undef THUMB_VARIANT
+#define THUMB_VARIANT & arm_ext_v6t2
TUE("it", bf08, bf08, 1, (COND), it, t_it),
TUE("itt", bf0c, bf0c, 1, (COND), it, t_it),
@@ -24888,11 +24947,13 @@ static const struct arm_cpu_option_table arm_cpus[] =
ARM_CPU_OPT ("ep9312", ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
FPU_ARCH_MAVERICK, "ARM920T"),
/* Marvell processors. */
- ARM_CPU_OPT ("marvell-pj4", ARM_FEATURE_CORE_LOW (ARM_AEXT_V7A | ARM_EXT_MP
- | ARM_EXT_SEC),
+ ARM_CPU_OPT ("marvell-pj4", ARM_FEATURE_CORE (ARM_AEXT_V7A | ARM_EXT_MP
+ | ARM_EXT_SEC,
+ ARM_EXT2_V6T2_V8M),
FPU_ARCH_VFP_V3D16, NULL),
- ARM_CPU_OPT ("marvell-whitney", ARM_FEATURE_CORE_LOW (ARM_AEXT_V7A | ARM_EXT_MP
- | ARM_EXT_SEC),
+ ARM_CPU_OPT ("marvell-whitney", ARM_FEATURE_CORE (ARM_AEXT_V7A | ARM_EXT_MP
+ | ARM_EXT_SEC,
+ ARM_EXT2_V6T2_V8M),
FPU_ARCH_NEON_VFP_V4, NULL),
/* APM X-Gene family. */
ARM_CPU_OPT ("xgene1", ARM_ARCH_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
@@ -24962,6 +25023,7 @@ static const struct arm_arch_option_table arm_archs[] =
ARM_ARCH_OPT ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP),
+ ARM_ARCH_OPT ("armv8-m.base", ARM_ARCH_V8M_BASE, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP),
ARM_ARCH_OPT ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP),
@@ -25582,6 +25644,7 @@ static const cpu_arch_ver_table cpu_arch_ver[] =
{10, ARM_ARCH_V7R},
{10, ARM_ARCH_V7M},
{14, ARM_ARCH_V8A},
+ {16, ARM_ARCH_V8M_BASE},
{17, ARM_ARCH_V8M_MAIN},
{0, ARM_ARCH_NONE}
};
@@ -25615,6 +25678,7 @@ aeabi_set_public_attributes (void)
int fp16_optional = 0;
arm_feature_set flags;
arm_feature_set tmp;
+ arm_feature_set arm_arch_v8m_base = ARM_ARCH_V8M_BASE;
const cpu_arch_ver_table *p;
/* Choose the architecture based on the capabilities of the requested cpu
@@ -25669,6 +25733,10 @@ aeabi_set_public_attributes (void)
&& ARM_CPU_HAS_FEATURE (flags, arm_ext_v6_dsp))
arch = TAG_CPU_ARCH_V7E_M;
+ ARM_CLEAR_FEATURE (tmp, flags, arm_arch_v8m_base);
+ if (arch == TAG_CPU_ARCH_V8M_BASE && ARM_CPU_HAS_FEATURE (tmp, arm_arch_any))
+ arch = TAG_CPU_ARCH_V8M_MAIN;
+
/* In cpu_arch_ver ARMv8-A is before ARMv8-M for atomics to be detected as
coming from ARMv8-A. However, since ARMv8-A has more instructions than
ARMv8-M, -march=all must be detected as ARMv8-A. */
@@ -25799,7 +25867,9 @@ aeabi_set_public_attributes (void)
by the base architecture.
For new architectures we will have to check these tests. */
- gas_assert (arch <= TAG_CPU_ARCH_V8 || arch == TAG_CPU_ARCH_V8M_MAIN);
+ gas_assert (arch <= TAG_CPU_ARCH_V8
+ || (arch >= TAG_CPU_ARCH_V8M_BASE
+ && arch <= TAG_CPU_ARCH_V8M_MAIN));
if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
|| ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
aeabi_set_attribute_int (Tag_DIV_use, 0);