X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-aarch64.c;h=4c97703f22ea9825b80e36f78a4864fcd0d5caf7;hb=3a67e1a6b4430374f3073e51bb19347d4c421cfe;hp=085ffa26f0e4594fe97b50d19d79e27f742f34e6;hpb=4f5d2536289c0aedc3234f1bff6e9f4284f267c5;p=binutils-gdb.git diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 085ffa26f0e..4c97703f22e 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -462,6 +462,7 @@ static struct hash_control *aarch64_sys_regs_ic_hsh; static struct hash_control *aarch64_sys_regs_dc_hsh; static struct hash_control *aarch64_sys_regs_at_hsh; static struct hash_control *aarch64_sys_regs_tlbi_hsh; +static struct hash_control *aarch64_sys_regs_sr_hsh; static struct hash_control *aarch64_reg_hsh; static struct hash_control *aarch64_barrier_opt_hsh; static struct hash_control *aarch64_nzcv_hsh; @@ -1992,6 +1993,14 @@ s_aarch64_inst (int ignored ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); } +static void +s_aarch64_cfi_b_key_frame (int ignored ATTRIBUTE_UNUSED) +{ + demand_empty_rest_of_line (); + struct fde_entry *fde = frchain_now->frch_cfi_data->cur_fde_data; + fde->pauth_key = AARCH64_PAUTH_KEY_B; +} + #ifdef OBJ_ELF /* Emit BFD_RELOC_AARCH64_TLSDESC_ADD on the next ADD instruction. */ @@ -2066,6 +2075,7 @@ const pseudo_typeS md_pseudo_table[] = { {"arch", s_aarch64_arch, 0}, {"arch_extension", s_aarch64_arch_extension, 0}, {"inst", s_aarch64_inst, 0}, + {"cfi_b_key_frame", s_aarch64_cfi_b_key_frame, 0}, #ifdef OBJ_ELF {"tlsdescadd", s_tlsdescadd, 0}, {"tlsdesccall", s_tlsdesccall, 0}, @@ -3371,6 +3381,7 @@ parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand, [base,Wm,(S|U)XTW {#imm}] Pre-indexed [base,#imm]! + [base]! // in ld/stgv Post-indexed [base],#imm [base],Xm // in SIMD ld/st structure @@ -3679,10 +3690,11 @@ parse_address_main (char **str, aarch64_opnd_info *operand, } /* If at this point neither .preind nor .postind is set, we have a - bare [Rn]{!}; reject [Rn]! but accept [Rn] as a shorthand for [Rn,#0]. */ + bare [Rn]{!}; reject [Rn]! except for ld/stgv but accept [Rn] + as a shorthand for [Rn,#0]. */ if (operand->addr.preind == 0 && operand->addr.postind == 0) { - if (operand->addr.writeback) + if (operand->type != AARCH64_OPND_ADDR_SIMPLE_2 && operand->addr.writeback) { /* Reject [Rn]! */ set_syntax_error (_("missing offset in the pre-indexed address")); @@ -3932,6 +3944,47 @@ parse_barrier_psb (char **str, return 0; } +/* Parse an operand for BTI. Set *HINT_OPT to the hint-option record + return 0 if successful. Otherwise return PARSE_FAIL. */ + +static int +parse_bti_operand (char **str, + const struct aarch64_name_value_pair ** hint_opt) +{ + char *p, *q; + const struct aarch64_name_value_pair *o; + + p = q = *str; + while (ISALPHA (*q)) + q++; + + o = hash_find_n (aarch64_hint_opt_hsh, p, q - p); + if (!o) + { + set_fatal_syntax_error + ( _("unknown option to BTI")); + return PARSE_FAIL; + } + + switch (o->value) + { + /* Valid BTI operands. */ + case HINT_OPD_C: + case HINT_OPD_J: + case HINT_OPD_JC: + break; + + default: + set_syntax_error + (_("unknown option to BTI")); + return PARSE_FAIL; + } + + *str = q; + *hint_opt = o; + return 0; +} + /* Parse a system register or a PSTATE field name for an MSR/MRS instruction. Returns the encoding for the option, or PARSE_FAIL. @@ -5150,6 +5203,11 @@ process_omitted_operand (enum aarch64_opnd type, const aarch64_opcode *opcode, case AARCH64_OPND_BARRIER_ISB: operand->barrier = aarch64_barrier_options + default_value; + break; + + case AARCH64_OPND_BTI_TARGET: + operand->hint_option = aarch64_hint_options + default_value; + break; default: break; @@ -5695,6 +5753,8 @@ parse_operands (char *str, const aarch64_opcode *opcode) case AARCH64_OPND_SIMM5: case AARCH64_OPND_FBITS: case AARCH64_OPND_UIMM4: + case AARCH64_OPND_UIMM4_ADDG: + case AARCH64_OPND_UIMM10: case AARCH64_OPND_UIMM3_OP1: case AARCH64_OPND_UIMM3_OP2: case AARCH64_OPND_IMM_VLSL: @@ -6088,6 +6148,7 @@ parse_operands (char *str, const aarch64_opcode *opcode) break; case AARCH64_OPND_ADDR_SIMPLE: + case AARCH64_OPND_ADDR_SIMPLE_2: case AARCH64_OPND_SIMD_ADDR_SIMPLE: { /* [{, #}] */ @@ -6097,7 +6158,8 @@ parse_operands (char *str, const aarch64_opcode *opcode) po_misc_or_fail (parse_address (&str, info)); if (info->addr.pcrel || info->addr.offset.is_reg || !info->addr.preind || info->addr.postind - || info->addr.writeback) + || (info->addr.writeback + && operands[i] != AARCH64_OPND_ADDR_SIMPLE_2)) { set_syntax_error (_("invalid addressing mode")); goto failure; @@ -6120,6 +6182,8 @@ parse_operands (char *str, const aarch64_opcode *opcode) } } po_char_or_fail (']'); + if (operands[i] == AARCH64_OPND_ADDR_SIMPLE_2) + po_char_or_fail ('!'); break; } @@ -6165,6 +6229,8 @@ parse_operands (char *str, const aarch64_opcode *opcode) case AARCH64_OPND_ADDR_SIMM9: case AARCH64_OPND_ADDR_SIMM9_2: + case AARCH64_OPND_ADDR_SIMM11: + case AARCH64_OPND_ADDR_SIMM13: po_misc_or_fail (parse_address (&str, info)); if (info->addr.pcrel || info->addr.offset.is_reg || (!info->addr.preind && !info->addr.postind) @@ -6422,14 +6488,22 @@ parse_operands (char *str, const aarch64_opcode *opcode) inst.base.operands[i].sysins_op = parse_sys_ins_reg (&str, aarch64_sys_regs_ic_hsh); goto sys_reg_ins; + case AARCH64_OPND_SYSREG_DC: inst.base.operands[i].sysins_op = parse_sys_ins_reg (&str, aarch64_sys_regs_dc_hsh); goto sys_reg_ins; + case AARCH64_OPND_SYSREG_AT: inst.base.operands[i].sysins_op = parse_sys_ins_reg (&str, aarch64_sys_regs_at_hsh); goto sys_reg_ins; + + case AARCH64_OPND_SYSREG_SR: + inst.base.operands[i].sysins_op = + parse_sys_ins_reg (&str, aarch64_sys_regs_sr_hsh); + goto sys_reg_ins; + case AARCH64_OPND_SYSREG_TLBI: inst.base.operands[i].sysins_op = parse_sys_ins_reg (&str, aarch64_sys_regs_tlbi_hsh); @@ -6474,6 +6548,12 @@ sys_reg_ins: goto failure; break; + case AARCH64_OPND_BTI_TARGET: + val = parse_bti_operand (&str, &(info->hint_option)); + if (val == PARSE_FAIL) + goto failure; + break; + default: as_fatal (_("unhandled operand code %d"), operands[i]); } @@ -6701,6 +6781,14 @@ warn_unpredictable_ldst (aarch64_instruction *instr, char *str) && opnds[1].addr.writeback) as_warn (_("unpredictable transfer with writeback -- `%s'"), str); break; + + case ldstgv_indexed: + /* Load operations must load different registers. */ + if ((opcode->opcode & (1 << 22)) + && opnds[0].reg.regno == opnds[1].addr.base_regno) + as_warn (_("unpredictable load of register -- `%s'"), str); + break; + case ldstpair_off: case ldstnapair_offs: case ldstpair_indexed: @@ -6710,6 +6798,8 @@ warn_unpredictable_ldst (aarch64_instruction *instr, char *str) && (opnds[0].reg.regno == opnds[2].addr.base_regno || opnds[1].reg.regno == opnds[2].addr.base_regno) && opnds[2].addr.base_regno != REG_SP + /* Exempt STGP. */ + && !(opnds[2].type == AARCH64_OPND_ADDR_SIMM11) && opnds[2].addr.writeback) as_warn (_("unpredictable transfer with writeback -- `%s'"), str); /* Load operations must load different registers. */ @@ -7611,6 +7701,8 @@ fix_insn (fixS *fixP, uint32_t flags, offsetT value) case AARCH64_OPND_ADDR_SIMM9_2: case AARCH64_OPND_ADDR_SIMM10: case AARCH64_OPND_ADDR_UIMM12: + case AARCH64_OPND_ADDR_SIMM11: + case AARCH64_OPND_ADDR_SIMM13: /* Immediate offset in an address. */ insn = get_aarch64_insn (buf); @@ -8439,6 +8531,7 @@ md_begin (void) || (aarch64_sys_regs_dc_hsh = hash_new ()) == NULL || (aarch64_sys_regs_at_hsh = hash_new ()) == NULL || (aarch64_sys_regs_tlbi_hsh = hash_new ()) == NULL + || (aarch64_sys_regs_sr_hsh = hash_new ()) == NULL || (aarch64_reg_hsh = hash_new ()) == NULL || (aarch64_barrier_opt_hsh = hash_new ()) == NULL || (aarch64_nzcv_hsh = hash_new ()) == NULL @@ -8477,6 +8570,11 @@ md_begin (void) aarch64_sys_regs_tlbi[i].name, (void *) (aarch64_sys_regs_tlbi + i)); + for (i = 0; aarch64_sys_regs_sr[i].name != NULL; i++) + checked_hash_insert (aarch64_sys_regs_sr_hsh, + aarch64_sys_regs_sr[i].name, + (void *) (aarch64_sys_regs_sr + i)); + for (i = 0; i < ARRAY_SIZE (reg_names); i++) checked_hash_insert (aarch64_reg_hsh, reg_names[i].name, (void *) (reg_names + i)); @@ -8694,6 +8792,7 @@ static const struct aarch64_arch_option_table aarch64_archs[] = { {"armv8.2-a", AARCH64_ARCH_V8_2}, {"armv8.3-a", AARCH64_ARCH_V8_3}, {"armv8.4-a", AARCH64_ARCH_V8_4}, + {"armv8.5-a", AARCH64_ARCH_V8_5}, {NULL, AARCH64_ARCH_NONE} }; @@ -8746,6 +8845,10 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = { AARCH64_ARCH_NONE}, {"sha2", AARCH64_FEATURE (AARCH64_FEATURE_SHA2, 0), AARCH64_ARCH_NONE}, + {"sb", AARCH64_FEATURE (AARCH64_FEATURE_SB, 0), + AARCH64_ARCH_NONE}, + {"predres", AARCH64_FEATURE (AARCH64_FEATURE_PREDRES, 0), + AARCH64_ARCH_NONE}, {"aes", AARCH64_FEATURE (AARCH64_FEATURE_AES, 0), AARCH64_ARCH_NONE}, {"sm4", AARCH64_FEATURE (AARCH64_FEATURE_SM4, 0), @@ -8753,6 +8856,12 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = { {"sha3", AARCH64_FEATURE (AARCH64_FEATURE_SHA2 | AARCH64_FEATURE_SHA3, 0), AARCH64_ARCH_NONE}, + {"rng", AARCH64_FEATURE (AARCH64_FEATURE_RNG, 0), + AARCH64_ARCH_NONE}, + {"ssbs", AARCH64_FEATURE (AARCH64_FEATURE_SSBS, 0), + AARCH64_ARCH_NONE}, + {"memtag", AARCH64_FEATURE (AARCH64_FEATURE_MEMTAG, 0), + AARCH64_ARCH_NONE}, {NULL, AARCH64_ARCH_NONE, AARCH64_ARCH_NONE}, };