diff options
Diffstat (limited to 'opcodes/aarch64-opc.c')
-rw-r--r-- | opcodes/aarch64-opc.c | 112 |
1 files changed, 83 insertions, 29 deletions
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c index 4f0c716..f7dae4b 100644 --- a/opcodes/aarch64-opc.c +++ b/opcodes/aarch64-opc.c @@ -329,6 +329,8 @@ const aarch64_field fields[] = { 17, 2 }, /* SVE_size: 2-bit element size, bits [18,17]. */ { 22, 1 }, /* SVE_sz: 1-bit element size select. */ { 30, 1 }, /* SVE_sz2: 1-bit element size select. */ + { 17, 1 }, /* SVE_sz3: 1-bit element size select. */ + { 14, 1 }, /* SVE_sz4: 1-bit element size select. */ { 16, 4 }, /* SVE_tsz: triangular size select. */ { 22, 2 }, /* SVE_tszh: triangular size select high, bits [23,22]. */ { 8, 2 }, /* SVE_tszl_8: triangular size select low, bits [9,8]. */ @@ -381,6 +383,7 @@ const aarch64_field fields[] = { 15, 7 }, /* imm7: in load/store pair pre/post index instructions. */ { 13, 8 }, /* imm8: in floating-point scalar move immediate inst. */ { 12, 9 }, /* imm9: in load/store pre/post index instructions. */ + { 5, 9 }, /* imm9_5: in CB<cc> (immediate). */ { 10, 12 }, /* imm12: in ld/st unsigned imm or add/sub shifted inst. */ { 5, 14 }, /* imm14: in test bit and branch instructions. */ { 0, 16 }, /* imm16_0: in udf instruction. */ @@ -596,6 +599,8 @@ const struct aarch64_name_value_pair aarch64_hint_options[] = { "c", HINT_OPD_C }, /* BTI C. */ { "j", HINT_OPD_J }, /* BTI J. */ { "jc", HINT_OPD_JC }, /* BTI JC. */ + { "keep", HINT_OPD_KEEP }, /* STSHH KEEP */ + { "strm", HINT_OPD_STRM }, /* STSHH STRM */ { NULL, HINT_OPD_NULL }, }; @@ -629,7 +634,7 @@ const struct aarch64_name_value_pair aarch64_prfops[32] = { "pstl3strm", B(2, 3, 1) }, { "pstslckeep", B(2, 4, 0) }, { "pstslcstrm", B(2, 4, 1) }, - { NULL, 0x18 }, + { "ir", B(3, 1, 0) }, { NULL, 0x19 }, { NULL, 0x1a }, { NULL, 0x1b }, @@ -809,7 +814,7 @@ struct operand_qualifier_data }; /* Indexed by the operand qualifier enumerators. */ -struct operand_qualifier_data aarch64_opnd_qualifiers[] = +static const struct operand_qualifier_data aarch64_opnd_qualifiers[] = { {0, 0, 0, "NIL", OQK_NIL}, @@ -1893,6 +1898,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx, return 0; break; + case AARCH64_OPND_SME_Zn_INDEX2_19: case AARCH64_OPND_SVE_Zm2_22_INDEX: size = get_operand_fields_width (get_operand_from_code (type)); if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 3)) @@ -1960,6 +1966,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx, break; case AARCH64_OPND_SME_Zm: + case AARCH64_OPND_SME_Zm_17: if (opnd->reg.regno > 15) { set_invalid_regno_error (mismatch_detail, idx, "z", 0, 15); @@ -2417,6 +2424,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx, } break; + case AARCH64_OPND_ADDR_PCREL9: case AARCH64_OPND_ADDR_PCREL14: case AARCH64_OPND_ADDR_PCREL19: case AARCH64_OPND_ADDR_PCREL21: @@ -2542,12 +2550,16 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx, assert (opnd->shifter.operator_present == 0); break; - case AARCH64_OPND_SVE_ADDR_R: case AARCH64_OPND_SVE_ADDR_RR: case AARCH64_OPND_SVE_ADDR_RR_LSL1: case AARCH64_OPND_SVE_ADDR_RR_LSL2: case AARCH64_OPND_SVE_ADDR_RR_LSL3: case AARCH64_OPND_SVE_ADDR_RR_LSL4: + case AARCH64_OPND_SVE_ADDR_RM: + case AARCH64_OPND_SVE_ADDR_RM_LSL1: + case AARCH64_OPND_SVE_ADDR_RM_LSL2: + case AARCH64_OPND_SVE_ADDR_RM_LSL3: + case AARCH64_OPND_SVE_ADDR_RM_LSL4: case AARCH64_OPND_SVE_ADDR_RX: case AARCH64_OPND_SVE_ADDR_RX_LSL1: case AARCH64_OPND_SVE_ADDR_RX_LSL2: @@ -4012,28 +4024,41 @@ static void print_sme_za_list (char *buf, size_t size, int mask, struct aarch64_styler *styler) { - const char* zan[] = { "za", "za0.h", "za1.h", "za0.s", - "za1.s", "za2.s", "za3.s", "za0.d", - "za1.d", "za2.d", "za3.d", "za4.d", - "za5.d", "za6.d", "za7.d", " " }; - const int zan_v[] = { 0xff, 0x55, 0xaa, 0x11, - 0x22, 0x44, 0x88, 0x01, - 0x02, 0x04, 0x08, 0x10, - 0x20, 0x40, 0x80, 0x00 }; - int i, k; - const int ZAN_SIZE = sizeof(zan) / sizeof(zan[0]); + static const struct { + unsigned char mask; + char name[7]; + } zan[] = { + { 0xff, "za" }, + { 0x55, "za0.h" }, + { 0xaa, "za1.h" }, + { 0x11, "za0.s" }, + { 0x22, "za1.s" }, + { 0x44, "za2.s" }, + { 0x88, "za3.s" }, + { 0x01, "za0.d" }, + { 0x02, "za1.d" }, + { 0x04, "za2.d" }, + { 0x08, "za3.d" }, + { 0x10, "za4.d" }, + { 0x20, "za5.d" }, + { 0x40, "za6.d" }, + { 0x80, "za7.d" }, + { 0x00, " " }, + }; + int k; k = snprintf (buf, size, "{"); - for (i = 0; i < ZAN_SIZE; i++) + for (unsigned int i = 0; i < ARRAY_SIZE (zan); i++) { - if ((mask & zan_v[i]) == zan_v[i]) - { - mask &= ~zan_v[i]; - if (k > 1) + if ((mask & zan[i].mask) == zan[i].mask) + { + mask &= ~zan[i].mask; + if (k > 1) k += snprintf (buf + k, size - k, ", "); - k += snprintf (buf + k, size - k, "%s", style_reg (styler, zan[i])); - } + k += snprintf (buf + k, size - k, "%s", + style_reg (styler, zan[i].name)); + } if (mask == 0) break; } @@ -4327,6 +4352,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, case AARCH64_OPND_SVE_Zn: case AARCH64_OPND_SVE_Zt: case AARCH64_OPND_SME_Zm: + case AARCH64_OPND_SME_Zm_17: if (opnd->qualifier == AARCH64_OPND_QLF_NIL) snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno)); else @@ -4375,6 +4401,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, case AARCH64_OPND_SME_Zn_INDEX1_16: case AARCH64_OPND_SME_Zn_INDEX2_15: case AARCH64_OPND_SME_Zn_INDEX2_16: + case AARCH64_OPND_SME_Zn_INDEX2_19: case AARCH64_OPND_SME_Zn_INDEX3_14: case AARCH64_OPND_SME_Zn_INDEX3_15: case AARCH64_OPND_SME_Zn_INDEX4_14: @@ -4781,6 +4808,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64 , addr)); break; + case AARCH64_OPND_ADDR_PCREL9: case AARCH64_OPND_ADDR_PCREL14: case AARCH64_OPND_ADDR_PCREL19: case AARCH64_OPND_ADDR_PCREL21: @@ -4817,12 +4845,16 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, break; case AARCH64_OPND_ADDR_REGOFF: - case AARCH64_OPND_SVE_ADDR_R: case AARCH64_OPND_SVE_ADDR_RR: case AARCH64_OPND_SVE_ADDR_RR_LSL1: case AARCH64_OPND_SVE_ADDR_RR_LSL2: case AARCH64_OPND_SVE_ADDR_RR_LSL3: case AARCH64_OPND_SVE_ADDR_RR_LSL4: + case AARCH64_OPND_SVE_ADDR_RM: + case AARCH64_OPND_SVE_ADDR_RM_LSL1: + case AARCH64_OPND_SVE_ADDR_RM_LSL2: + case AARCH64_OPND_SVE_ADDR_RM_LSL3: + case AARCH64_OPND_SVE_ADDR_RM_LSL4: case AARCH64_OPND_SVE_ADDR_RX: case AARCH64_OPND_SVE_ADDR_RX_LSL1: case AARCH64_OPND_SVE_ADDR_RX_LSL2: @@ -5017,11 +5049,12 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, break; case AARCH64_OPND_PRFOP: - if (opnd->prfop->name != NULL) - snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->prfop->name)); + if ((opnd->prfop->name == NULL) + || (opcode->iclass != ldst_pos && opnd->prfop->value == 0x18)) + snprintf (buf, size, "%s", + style_imm (styler, "#0x%02x", opnd->prfop->value)); else - snprintf (buf, size, "%s", style_imm (styler, "#0x%02x", - opnd->prfop->value)); + snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->prfop->name)); break; case AARCH64_OPND_RPRFMOP: @@ -5071,6 +5104,10 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, style_sub_mnem (styler, opnd->hint_option->name)); break; + case AARCH64_OPND_STSHH_POLICY: + snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->hint_option->name)); + break; + case AARCH64_OPND_MOPS_ADDR_Rd: case AARCH64_OPND_MOPS_ADDR_Rs: snprintf (buf, size, "[%s]!", @@ -5203,9 +5240,13 @@ const aarch64_sys_ins_reg aarch64_sys_regs_dc[] = { "isw", CPENS (0, C7, C6, 2), F_HASXT, AARCH64_NO_FEATURES }, { "igdvac", CPENS (0, C7, C6, 5), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) }, { "igdsw", CPENS (0, C7, C6, 6), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) }, + { "cigdvaps", CPENS (0, C7, C15, 5), F_HASXT | F_ARCHEXT, AARCH64_FEATURES (2, MEMTAG, PoPS) }, + { "civaps", CPENS (0, C7, C15, 1), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (PoPS) }, { "cvac", CPENS (3, C7, C10, 1), F_HASXT, AARCH64_NO_FEATURES }, { "cgvac", CPENS (3, C7, C10, 3), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) }, { "cgdvac", CPENS (3, C7, C10, 5), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) }, + { "cvaoc", CPENS (3, C7, C11, 0), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (OCCMO) }, + { "cgdvaoc", CPENS (3, C7, C11, 7), F_HASXT | F_ARCHEXT, AARCH64_FEATURES (2, OCCMO, MEMTAG) }, { "csw", CPENS (0, C7, C10, 2), F_HASXT, AARCH64_NO_FEATURES }, { "cgsw", CPENS (0, C7, C10, 4), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) }, { "cgdsw", CPENS (0, C7, C10, 6), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) }, @@ -5222,6 +5263,8 @@ const aarch64_sys_ins_reg aarch64_sys_regs_dc[] = { "cisw", CPENS (0, C7, C14, 2), F_HASXT, AARCH64_NO_FEATURES }, { "cigsw", CPENS (0, C7, C14, 4), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) }, { "cigdsw", CPENS (0, C7, C14, 6), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) }, + { "civaoc", CPENS (3, C7, C15, 0), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (OCCMO) }, + { "cigdvaoc", CPENS (3, C7, C15, 7), F_HASXT | F_ARCHEXT, AARCH64_FEATURES (2, OCCMO, MEMTAG) }, { "cipae", CPENS (4, C7, C14, 0), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (V8_7A) }, { "cigdpae", CPENS (4, C7, C14, 7), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (V8_7A) }, { "cipapa", CPENS (6, C7, C14, 1), F_HASXT, AARCH64_NO_FEATURES }, @@ -5690,10 +5733,21 @@ verify_constraints (const struct aarch64_inst *inst, { /* Check to see if the MOVPRFX SVE instruction is followed by an SVE instruction for better error messages. */ - if (!opcode->avariant - || (!AARCH64_CPU_HAS_FEATURE (*opcode->avariant, SVE) - && !AARCH64_CPU_HAS_FEATURE (*opcode->avariant, SVE2) - && !AARCH64_CPU_HAS_FEATURE (*opcode->avariant, SVE2p1))) + bool sve_operand_p = false; + for (int i = 0; i < AARCH64_MAX_OPND_NUM; ++i) + { + enum aarch64_operand_class op_class + = aarch64_get_operand_class (opcode->operands[i]); + if (op_class == AARCH64_OPND_CLASS_SVE_REG + || op_class == AARCH64_OPND_CLASS_SVE_REGLIST + || op_class == AARCH64_OPND_CLASS_PRED_REG) + { + sve_operand_p = true; + break; + } + } + + if (!sve_operand_p) { mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR; mismatch_detail->error = _("SVE instruction expected after " |