static const arm_feature_set fpu_arch_neon_v1 ATTRIBUTE_UNUSED = FPU_ARCH_NEON_V1;
static const arm_feature_set fpu_arch_fpa = FPU_ARCH_FPA;
static const arm_feature_set fpu_any_hard = FPU_ANY_HARD;
+#ifdef OBJ_ELF
static const arm_feature_set fpu_arch_maverick = FPU_ARCH_MAVERICK;
+#endif
static const arm_feature_set fpu_endian_pure = FPU_ARCH_ENDIAN_PURE;
#ifdef CPU_DEFAULT
static const arm_feature_set arm_ext_v7 = ARM_FEATURE_CORE_LOW (ARM_EXT_V7);
static const arm_feature_set arm_ext_v7a = ARM_FEATURE_CORE_LOW (ARM_EXT_V7A);
static const arm_feature_set arm_ext_v7r = ARM_FEATURE_CORE_LOW (ARM_EXT_V7R);
+#ifdef OBJ_ELF
static const arm_feature_set arm_ext_v7m = ARM_FEATURE_CORE_LOW (ARM_EXT_V7M);
+#endif
static const arm_feature_set arm_ext_v8 = ARM_FEATURE_CORE_LOW (ARM_EXT_V8);
static const arm_feature_set arm_ext_m =
ARM_FEATURE_CORE (ARM_EXT_V6M | ARM_EXT_OS | ARM_EXT_V7M,
/* Instructions shared between ARMv8-A and ARMv8-M. */
static const arm_feature_set arm_ext_atomics =
ARM_FEATURE_CORE_HIGH (ARM_EXT2_ATOMICS);
-static const arm_feature_set arm_ext_v8_2 =
- ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_2A);
+#ifdef OBJ_ELF
+/* DSP instructions Tag_DSP_extension refers to. */
+static const arm_feature_set arm_ext_dsp =
+ ARM_FEATURE_CORE_LOW (ARM_EXT_V5E | ARM_EXT_V5ExP | ARM_EXT_V6_DSP);
+#endif
+static const arm_feature_set arm_ext_ras =
+ ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS);
/* FP16 instructions. */
static const arm_feature_set arm_ext_fp16 =
ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST);
static const arm_feature_set arm_arch_full ATTRIBUTE_UNUSED = ARM_FEATURE (-1, -1, -1);
static const arm_feature_set arm_arch_t2 = ARM_ARCH_THUMB2;
static const arm_feature_set arm_arch_none = ARM_ARCH_NONE;
+#ifdef OBJ_ELF
static const arm_feature_set arm_arch_v6m_only = ARM_ARCH_V6M_ONLY;
+#endif
static const arm_feature_set arm_cext_iwmmxt2 =
ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2);
ARM_FEATURE_COPROC (FPU_NEON_EXT_V1);
static const arm_feature_set fpu_vfp_v3_or_neon_ext =
ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_VFP_EXT_V3);
+#ifdef OBJ_ELF
static const arm_feature_set fpu_vfp_fp16 =
ARM_FEATURE_COPROC (FPU_VFP_EXT_FP16);
static const arm_feature_set fpu_neon_ext_fma =
ARM_FEATURE_COPROC (FPU_NEON_EXT_FMA);
+#endif
static const arm_feature_set fpu_vfp_ext_fma =
ARM_FEATURE_COPROC (FPU_VFP_EXT_FMA);
static const arm_feature_set fpu_vfp_ext_armv8 =
#define T2_SUBS_PC_LR 0xf3de8f00
#define DATA_OP_SHIFT 21
+#define SBIT_SHIFT 20
#define T2_OPCODE_MASK 0xfe1fffff
#define T2_DATA_OP_SHIFT 21
+#define T2_SBIT_SHIFT 20
#define A_COND_MASK 0xf0000000
#define A_PUSH_POP_OP_MASK 0x0fff0000
if (*ccp != start && processor <= 15)
return processor;
}
+ /* Fall through. */
case REG_TYPE_MMXWC:
/* WC includes WCG. ??? I'm not sure this is true for all
nlen = strlen (newname);
#endif
- nbuf = xmalloc (nlen + 1);
- memcpy (nbuf, newname, nlen);
- nbuf[nlen] = '\0';
+ nbuf = xmemdup0 (newname, nlen);
/* Create aliases under the new name as stated; an all-lowercase
version of the new name; and an all-uppercase version of the new
namelen = strlen (newname);
#endif
- namebuf = xmalloc (namelen + 1);
- strncpy (namebuf, newname, namelen);
- namebuf[namelen] = '\0';
+ namebuf = xmemdup0 (newname, namelen);
insert_neon_reg_alias (namebuf, basereg->number, basetype,
typeinfo.defined != 0 ? &typeinfo : NULL);
}
pool->literals[entry] = inst.reloc.exp;
+ pool->literals[entry].X_op = O_constant;
pool->literals[entry].X_add_number = 0;
pool->literals[entry++].X_md = (PADDING_SLOT << 8) | 4;
pool->next_free_entry += 1;
static void
encode_arm_shift (int i)
{
+ /* register-shifted register. */
+ if (inst.operands[i].immisreg)
+ {
+ int index;
+ for (index = 0; index <= i; ++index)
+ {
+ gas_assert (inst.operands[index].present);
+ if (inst.operands[index].isreg && inst.operands[index].reg == REG_PC)
+ as_warn (UNPRED_REG ("r15"));
+ }
+
+ if (inst.operands[i].imm == REG_PC)
+ as_warn (UNPRED_REG ("r15"));
+ }
+
if (inst.operands[i].shift_kind == SHIFT_RRX)
inst.instruction |= SHIFT_ROR << 5;
else
return TRUE;
}
}
- else if (t == CONST_VEC)
+ else if (t == CONST_VEC && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
{
int op = 0;
unsigned immbits = 0;
constraint (Rn == REG_PC, BAD_PC);
}
+ /* Only check the MRRC{2} variants. */
+ if ((inst.instruction & 0x0FF00000) == 0x0C500000)
+ {
+ /* If Rd == Rn, error that the operation is
+ unpredictable (example MRRC p3,#1,r1,r1,c4). */
+ constraint (Rd == Rn, BAD_OVERLAP);
+ }
+
inst.instruction |= inst.operands[0].reg << 8;
inst.instruction |= inst.operands[1].imm << 4;
inst.instruction |= Rd << 12;
do_vfp_nsyn_push (void)
{
nsyn_insert_sp ();
+
+ constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
+ _("register list must contain at least 1 and at most 16 "
+ "registers"));
+
if (inst.operands[1].issingle)
do_vfp_nsyn_opcode ("fstmdbs");
else
do_vfp_nsyn_pop (void)
{
nsyn_insert_sp ();
+
+ constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
+ _("register list must contain at least 1 and at most 16 "
+ "registers"));
+
if (inst.operands[1].issingle)
do_vfp_nsyn_opcode ("fldmias");
else
case OT_odd_infix_unc:
if (!unified_syntax)
return 0;
- /* else fall through */
+ /* Fall through. */
case OT_csuffix:
case OT_csuffixF:
&& opcode->tencode == do_t_branch)
return TRUE;
+ /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit. */
+ if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
+ && opcode->tencode == do_t_mov_cmp
+ /* Make sure CMP instruction is not affected. */
+ && opcode->aencode == do_mov)
+ 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. */
/* Table of V7M psr names. */
static const struct asm_psr v7m_psrs[] =
{
- {"apsr", 0 }, {"APSR", 0 },
- {"iapsr", 1 }, {"IAPSR", 1 },
- {"eapsr", 2 }, {"EAPSR", 2 },
- {"psr", 3 }, {"PSR", 3 },
- {"xpsr", 3 }, {"XPSR", 3 }, {"xPSR", 3 },
- {"ipsr", 5 }, {"IPSR", 5 },
- {"epsr", 6 }, {"EPSR", 6 },
- {"iepsr", 7 }, {"IEPSR", 7 },
- {"msp", 8 }, {"MSP", 8 }, {"msp_s", 8 }, {"MSP_S", 8 },
- {"psp", 9 }, {"PSP", 9 }, {"psp_s", 9 }, {"PSP_S", 9 },
- {"primask", 16}, {"PRIMASK", 16},
- {"basepri", 17}, {"BASEPRI", 17},
- {"basepri_max", 18}, {"BASEPRI_MAX", 18},
- {"basepri_max", 18}, {"BASEPRI_MASK", 18}, /* Typo, preserved for backwards compatibility. */
- {"faultmask", 19}, {"FAULTMASK", 19},
- {"control", 20}, {"CONTROL", 20},
- {"msp_ns", 0x88}, {"MSP_NS", 0x88},
- {"psp_ns", 0x89}, {"PSP_NS", 0x89}
+ {"apsr", 0x0 }, {"APSR", 0x0 },
+ {"iapsr", 0x1 }, {"IAPSR", 0x1 },
+ {"eapsr", 0x2 }, {"EAPSR", 0x2 },
+ {"psr", 0x3 }, {"PSR", 0x3 },
+ {"xpsr", 0x3 }, {"XPSR", 0x3 }, {"xPSR", 3 },
+ {"ipsr", 0x5 }, {"IPSR", 0x5 },
+ {"epsr", 0x6 }, {"EPSR", 0x6 },
+ {"iepsr", 0x7 }, {"IEPSR", 0x7 },
+ {"msp", 0x8 }, {"MSP", 0x8 },
+ {"psp", 0x9 }, {"PSP", 0x9 },
+ {"msplim", 0xa }, {"MSPLIM", 0xa },
+ {"psplim", 0xb }, {"PSPLIM", 0xb },
+ {"primask", 0x10}, {"PRIMASK", 0x10},
+ {"basepri", 0x11}, {"BASEPRI", 0x11},
+ {"basepri_max", 0x12}, {"BASEPRI_MAX", 0x12},
+ {"faultmask", 0x13}, {"FAULTMASK", 0x13},
+ {"control", 0x14}, {"CONTROL", 0x14},
+ {"msp_ns", 0x88}, {"MSP_NS", 0x88},
+ {"psp_ns", 0x89}, {"PSP_NS", 0x89},
+ {"msplim_ns", 0x8a}, {"MSPLIM_NS", 0x8a},
+ {"psplim_ns", 0x8b}, {"PSPLIM_NS", 0x8b},
+ {"primask_ns", 0x90}, {"PRIMASK_NS", 0x90},
+ {"basepri_ns", 0x91}, {"BASEPRI_NS", 0x91},
+ {"faultmask_ns", 0x93}, {"FAULTMASK_NS", 0x93},
+ {"control_ns", 0x94}, {"CONTROL_NS", 0x94},
+ {"sp_ns", 0x98}, {"SP_NS", 0x98 }
};
/* Table of all shift-in-operand names. */
/* ARMv8.2 RAS extension. */
#undef ARM_VARIANT
-#define ARM_VARIANT & arm_ext_v8_2
+#define ARM_VARIANT & arm_ext_ras
#undef THUMB_VARIANT
-#define THUMB_VARIANT & arm_ext_v8_2
+#define THUMB_VARIANT & arm_ext_ras
TUE ("esb", 320f010, f3af8010, 0, (), noargs, noargs),
#undef ARM_VARIANT
const char * prefix;
const char * prefix_once;
const char * group_name;
- size_t prefix_len;
- size_t text_len;
char * sec_name;
- size_t sec_name_len;
int type;
int flags;
int linkonce;
text_name += strlen (".gnu.linkonce.t.");
}
- prefix_len = strlen (prefix);
- text_len = strlen (text_name);
- sec_name_len = prefix_len + text_len;
- sec_name = (char *) xmalloc (sec_name_len + 1);
- memcpy (sec_name, prefix, prefix_len);
- memcpy (sec_name + prefix_len, text_name, text_len);
- sec_name[prefix_len + text_len] = '\0';
+ sec_name = concat (prefix, text_name, (char *) NULL);
flags = SHF_ALLOC;
linkonce = 0;
changing the opcode. */
if (newimm == (unsigned int) FAIL)
newimm = negate_data_op (&temp, value);
+ /* MOV accepts both ARM modified immediate (A1 encoding) and
+ UINT16 (A2 encoding) when possible, MOVW only accepts UINT16.
+ When disassembling, MOV is preferred when there is no encoding
+ overlap. */
+ if (newimm == (unsigned int) FAIL
+ && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV
+ && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
+ && !((temp >> SBIT_SHIFT) & 0x1)
+ && value >= 0 && value <= 0xffff)
+ {
+ /* Clear bits[23:20] to change encoding from A1 to A2. */
+ temp &= 0xff0fffff;
+ /* Encoding high 4bits imm. Code below will encode the remaining
+ low 12bits. */
+ temp |= (value & 0x0000f000) << 4;
+ newimm = value & 0x00000fff;
+ }
}
if (newimm == (unsigned int) FAIL)
case BFD_RELOC_ARM_OFFSET_IMM:
if (!fixP->fx_done && seg->use_rela_p)
value = 0;
+ /* Fall through. */
case BFD_RELOC_ARM_LITERAL:
sign = value > 0;
newval |= md_chars_to_number (buf+2, THUMB_SIZE);
newimm = FAIL;
- if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
+ if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
+ /* ARMv8-M Baseline MOV will reach here, but it doesn't support
+ Thumb2 modified immediate encoding (T2). */
+ && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
|| fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
{
newimm = encode_thumb32_immediate (value);
if (newimm == (unsigned int) FAIL)
newimm = thumb32_negate_data_op (&newval, value);
}
- if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE
- && newimm == (unsigned int) FAIL)
+ if (newimm == (unsigned int) FAIL)
{
- /* Turn add/sum into addw/subw. */
- if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
- newval = (newval & 0xfeffffff) | 0x02000000;
- /* No flat 12-bit imm encoding for addsw/subsw. */
- if ((newval & 0x00100000) == 0)
+ if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE)
{
- /* 12 bit immediate for addw/subw. */
- if (value < 0)
+ /* Turn add/sum into addw/subw. */
+ if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
+ newval = (newval & 0xfeffffff) | 0x02000000;
+ /* No flat 12-bit imm encoding for addsw/subsw. */
+ if ((newval & 0x00100000) == 0)
{
- value = -value;
- newval ^= 0x00a00000;
+ /* 12 bit immediate for addw/subw. */
+ if (value < 0)
+ {
+ value = -value;
+ newval ^= 0x00a00000;
+ }
+ if (value > 0xfff)
+ newimm = (unsigned int) FAIL;
+ else
+ newimm = value;
+ }
+ }
+ else
+ {
+ /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
+ UINT16 (T3 encoding), MOVW only accepts UINT16. When
+ disassembling, MOV is preferred when there is no encoding
+ overlap.
+ NOTE: MOV is using ORR opcode under Thumb 2 mode. */
+ if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
+ && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
+ && !((newval >> T2_SBIT_SHIFT) & 0x1)
+ && value >= 0 && value <=0xffff)
+ {
+ /* Toggle bit[25] to change encoding from T2 to T3. */
+ newval ^= 1 << 25;
+ /* Clear bits[19:16]. */
+ newval &= 0xfff0ffff;
+ /* Encoding high 4bits imm. Code below will encode the
+ remaining low 12bits. */
+ newval |= (value & 0x0000f000) << 4;
+ newimm = value & 0x00000fff;
}
- if (value > 0xfff)
- newimm = (unsigned int) FAIL;
- else
- newimm = value;
}
}
newval = md_chars_to_number (buf, INSN_SIZE);
fixP->fx_done = 0;
}
+ /* Fall through. */
case BFD_RELOC_ARM_PLT32:
#endif
code = BFD_RELOC_8_PCREL;
break;
}
+ /* Fall through. */
case BFD_RELOC_16:
if (fixp->fx_pcrel)
code = BFD_RELOC_16_PCREL;
break;
}
+ /* Fall through. */
case BFD_RELOC_32:
if (fixp->fx_pcrel)
code = BFD_RELOC_32_PCREL;
break;
}
+ /* Fall through. */
case BFD_RELOC_ARM_MOVW:
if (fixp->fx_pcrel)
code = BFD_RELOC_ARM_MOVW_PCREL;
break;
}
+ /* Fall through. */
case BFD_RELOC_ARM_MOVT:
if (fixp->fx_pcrel)
code = BFD_RELOC_ARM_MOVT_PCREL;
break;
}
+ /* Fall through. */
case BFD_RELOC_ARM_THUMB_MOVW:
if (fixp->fx_pcrel)
code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
break;
}
+ /* Fall through. */
case BFD_RELOC_ARM_THUMB_MOVT:
if (fixp->fx_pcrel)
code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
break;
}
+ /* Fall through. */
case BFD_RELOC_NONE:
case BFD_RELOC_ARM_PCREL_BRANCH:
/* If it's a .thumb_func, declare it as so,
otherwise tag label as .code 16. */
if (THUMB_IS_FUNC (sym))
- elf_sym->internal_elf_sym.st_target_internal
- = ST_BRANCH_TO_THUMB;
+ ARM_SET_SYM_BRANCH_TYPE (elf_sym->internal_elf_sym.st_target_internal,
+ ST_BRANCH_TO_THUMB);
else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
elf_sym->internal_elf_sym.st_info =
ELF_ST_INFO (bind, STT_ARM_16BIT);
"Cortex-A15"),
ARM_CPU_OPT ("cortex-a17", ARM_ARCH_V7VE, FPU_ARCH_NEON_VFP_V4,
"Cortex-A17"),
- ARM_CPU_OPT ("cortex-a32", ARM_ARCH_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
+ ARM_CPU_OPT ("cortex-a32", ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
"Cortex-A32"),
- ARM_CPU_OPT ("cortex-a35", ARM_ARCH_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
+ ARM_CPU_OPT ("cortex-a35", ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
"Cortex-A35"),
- ARM_CPU_OPT ("cortex-a53", ARM_ARCH_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
+ ARM_CPU_OPT ("cortex-a53", ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
"Cortex-A53"),
- ARM_CPU_OPT ("cortex-a57", ARM_ARCH_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
+ ARM_CPU_OPT ("cortex-a57", ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
"Cortex-A57"),
- ARM_CPU_OPT ("cortex-a72", ARM_ARCH_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
+ ARM_CPU_OPT ("cortex-a72", ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
"Cortex-A72"),
+ ARM_CPU_OPT ("cortex-a73", ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
+ "Cortex-A73"),
ARM_CPU_OPT ("cortex-r4", ARM_ARCH_V7R, FPU_NONE, "Cortex-R4"),
ARM_CPU_OPT ("cortex-r4f", ARM_ARCH_V7R, FPU_ARCH_VFP_V3D16,
"Cortex-R4F"),
ARM_CPU_OPT ("cortex-r8", ARM_ARCH_V7R_IDIV,
FPU_ARCH_VFP_V3D16,
"Cortex-R8"),
+ ARM_CPU_OPT ("cortex-m33", ARM_ARCH_V8M_MAIN_DSP,
+ FPU_NONE, "Cortex-M33"),
+ ARM_CPU_OPT ("cortex-m23", ARM_ARCH_V8M_BASE,
+ FPU_NONE, "Cortex-M23"),
ARM_CPU_OPT ("cortex-m7", ARM_ARCH_V7EM, FPU_NONE, "Cortex-M7"),
ARM_CPU_OPT ("cortex-m4", ARM_ARCH_V7EM, FPU_NONE, "Cortex-M4"),
ARM_CPU_OPT ("cortex-m3", ARM_ARCH_V7M, FPU_NONE, "Cortex-M3"),
ARM_CPU_OPT ("cortex-m1", ARM_ARCH_V6SM, FPU_NONE, "Cortex-M1"),
ARM_CPU_OPT ("cortex-m0", ARM_ARCH_V6SM, FPU_NONE, "Cortex-M0"),
ARM_CPU_OPT ("cortex-m0plus", ARM_ARCH_V6SM, FPU_NONE, "Cortex-M0+"),
- ARM_CPU_OPT ("exynos-m1", ARM_ARCH_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
+ ARM_CPU_OPT ("exynos-m1", ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
"Samsung " \
"Exynos M1"),
- ARM_CPU_OPT ("qdf24xx", ARM_ARCH_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
+ ARM_CPU_OPT ("falkor", ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
+ "Qualcomm "
+ "Falkor"),
+ ARM_CPU_OPT ("qdf24xx", ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
"Qualcomm "
"QDF24XX"),
/* APM X-Gene family. */
ARM_CPU_OPT ("xgene1", ARM_ARCH_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
"APM X-Gene 1"),
- ARM_CPU_OPT ("xgene2", ARM_ARCH_V8A, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
+ ARM_CPU_OPT ("xgene2", ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
"APM X-Gene 2"),
{ NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8),
ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
+ ARM_EXT_OPT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
+ ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
+ ARM_FEATURE_CORE (ARM_EXT_V7M, ARM_EXT2_V8M)),
ARM_EXT_OPT ("fp", FPU_ARCH_VFP_ARMV8, ARM_FEATURE_COPROC (FPU_VFP_ARMV8),
ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
ARM_EXT_OPT ("fp16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
ARM_EXT_OPT ("pan", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_PAN, 0),
ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
+ ARM_EXT_OPT ("ras", ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
+ ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_RAS, 0),
+ ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
ARM_EXT_OPT ("rdma", FPU_ARCH_NEON_VFP_ARMV8_1,
ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
char profile;
int virt_sec = 0;
int fp16_optional = 0;
+ arm_feature_set arm_arch = ARM_ARCH_NONE;
arm_feature_set flags;
arm_feature_set tmp;
arm_feature_set arm_arch_v8m_base = ARM_ARCH_V8M_BASE;
if (ARM_CPU_HAS_FEATURE (tmp, p->flags))
{
arch = p->val;
+ arm_arch = p->flags;
ARM_CLEAR_FEATURE (tmp, tmp, p->flags);
}
}
&& !ARM_CPU_HAS_FEATURE (flags, arm_ext_v7a)
&& ARM_CPU_HAS_FEATURE (flags, arm_ext_v7m)
&& ARM_CPU_HAS_FEATURE (flags, arm_ext_v6_dsp))
- arch = TAG_CPU_ARCH_V7E_M;
+ {
+ arch = TAG_CPU_ARCH_V7E_M;
+ arm_arch = (arm_feature_set) ARM_ARCH_V7EM;
+ }
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;
+ {
+ arch = TAG_CPU_ARCH_V8M_MAIN;
+ arm_arch = (arm_feature_set) ARM_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. */
if (arch == TAG_CPU_ARCH_V8M_MAIN
&& ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any))
- arch = TAG_CPU_ARCH_V8;
+ {
+ arch = TAG_CPU_ARCH_V8;
+ arm_arch = (arm_feature_set) ARM_ARCH_V8A;
+ }
/* Tag_CPU_name. */
if (selected_cpu_name[0])
if (profile != '\0')
aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
+ /* Tag_DSP_extension. */
+ if (ARM_CPU_HAS_FEATURE (flags, arm_ext_dsp))
+ {
+ arm_feature_set ext;
+
+ /* DSP instructions not in architecture. */
+ ARM_CLEAR_FEATURE (ext, flags, arm_arch);
+ if (ARM_CPU_HAS_FEATURE (ext, arm_ext_dsp))
+ aeabi_set_attribute_int (Tag_DSP_extension, 1);
+ }
+
/* Tag_ARM_ISA_use. */
if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
|| arch == 0)
T (Tag_conformance),
T (Tag_T2EE_use),
T (Tag_Virtualization_use),
+ T (Tag_DSP_extension),
/* We deliberately do not include Tag_MPextension_use_legacy. */
#undef T
};