summaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2023-03-30 11:09:05 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2023-03-30 11:09:05 +0100
commitff60bcbfbec4f88195ae5cee544c2a7c749169b0 (patch)
tree87af7a706fb9a93d0d9aecaa92726da62e00953a /opcodes
parent1d597b88c85ee3f667e91dd6d282203dd9f41a4c (diff)
downloadbinutils-gdb-ff60bcbfbec4f88195ae5cee544c2a7c749169b0.tar.gz
aarch64: Move ZA range checks to aarch64-opc.c
This patch moves the range checks on ZA vector select offsets from gas to libopcodes. Doing the checks there means that the error messages contain the expected range. It also fits in better with the error severity scheme, which becomes important later. (This is because out-of-range indices are treated as more severe than syntax errors, on the basis that parsing must have succeeded if we get to the point of checking the completed opcode.) The patch also adds a new check_za_access function for checking ZA accesses. That's a bit over the top for one offset check, but the function becomes more complex with later patches. sme-9-illegal.s checked for an invalid .q suffix using: psel p1, p15, p3.q[w15] but this is doubly invalid because it misses the immediate part of the index. The patch keeps that test but adds another with a zero index, so that .q is the only thing wrong. The aarch64-tbl.h change includes neatening up the backslash positions.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/aarch64-opc-2.c8
-rw-r--r--opcodes/aarch64-opc.c45
-rw-r--r--opcodes/aarch64-tbl.h39
3 files changed, 67 insertions, 25 deletions
diff --git a/opcodes/aarch64-opc-2.c b/opcodes/aarch64-opc-2.c
index 6e22690b994..3603f2c8c9b 100644
--- a/opcodes/aarch64-opc-2.c
+++ b/opcodes/aarch64-opc-2.c
@@ -236,12 +236,12 @@ const struct aarch64_operand aarch64_operands[] =
{AARCH64_OPND_CLASS_SVE_REG, "SVE_ZtxN", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Zt}, "a list of SVE vector registers"},
{AARCH64_OPND_CLASS_SVE_REG, "SME_ZAda_2b", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_ZAda_2b}, "an SME ZA tile ZA0-ZA3"},
{AARCH64_OPND_CLASS_SVE_REG, "SME_ZAda_3b", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_ZAda_3b}, "an SME ZA tile ZA0-ZA7"},
- {AARCH64_OPND_CLASS_SVE_REG, "SME_ZA_HV_idx_src", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_5}, "an SME horizontal or vertical vector access register"},
- {AARCH64_OPND_CLASS_SVE_REG, "SME_ZA_HV_idx_dest", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2}, "an SME horizontal or vertical vector access register"},
+ {AARCH64_OPND_CLASS_ZA_ACCESS, "SME_ZA_HV_idx_src", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_5}, "an SME horizontal or vertical vector access register"},
+ {AARCH64_OPND_CLASS_ZA_ACCESS, "SME_ZA_HV_idx_dest", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2}, "an SME horizontal or vertical vector access register"},
{AARCH64_OPND_CLASS_PRED_REG, "SME_Pm", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_Pm}, "an SVE predicate register"},
{AARCH64_OPND_CLASS_SVE_REG, "SME_list_of_64bit_tiles", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_zero_mask}, "a list of 64-bit ZA element tiles"},
- {AARCH64_OPND_CLASS_SVE_REG, "SME_ZA_HV_idx_ldstr", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_size_10,FLD_index2,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2}, "an SME horizontal or vertical vector access register"},
- {AARCH64_OPND_CLASS_SVE_REG, "SME_ZA_array", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_Rv,FLD_imm4_2}, "ZA array"},
+ {AARCH64_OPND_CLASS_ZA_ACCESS, "SME_ZA_HV_idx_ldstr", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_size_10,FLD_index2,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2}, "an SME horizontal or vertical vector access register"},
+ {AARCH64_OPND_CLASS_ZA_ACCESS, "SME_ZA_array", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_Rv,FLD_imm4_2}, "ZA array"},
{AARCH64_OPND_CLASS_ADDRESS, "SME_ADDR_RI_U4xVL", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn,FLD_imm4_2}, "memory offset"},
{AARCH64_OPND_CLASS_ADDRESS, "SME_SM_ZA", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_CRm}, "streaming mode"},
{AARCH64_OPND_CLASS_SVE_REG, "SME_PnT_Wm_imm", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_Rm,FLD_SVE_Pn,FLD_SME_i1,FLD_SME_tszh,FLD_SME_tszl}, "Source scalable predicate register with index "},
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index c92b4e80e35..746edde7516 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -1438,6 +1438,22 @@ set_other_error (aarch64_operand_error *mismatch_detail, int idx,
set_error (mismatch_detail, AARCH64_OPDE_OTHER_ERROR, idx, error);
}
+/* Check that indexed ZA operand OPND has a vector select offset
+ in the range [0, MAX_VALUE]. */
+
+static bool
+check_za_access (const aarch64_opnd_info *opnd,
+ aarch64_operand_error *mismatch_detail, int idx,
+ int max_value)
+{
+ if (!value_in_range_p (opnd->indexed_za.index.imm, 0, max_value))
+ {
+ set_offset_out_of_range_error (mismatch_detail, idx, 0, max_value);
+ return false;
+ }
+ return true;
+}
+
/* General constraint checking based on operand code.
Return 1 if OPNDS[IDX] meets the general constraint of operand code TYPE
@@ -1574,11 +1590,40 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
}
break;
+ case AARCH64_OPND_SME_PnT_Wm_imm:
+ size = aarch64_get_qualifier_esize (opnd->qualifier);
+ max_value = 16 / size - 1;
+ if (!check_za_access (opnd, mismatch_detail, idx, max_value))
+ return 0;
+ break;
+
default:
break;
}
break;
+ case AARCH64_OPND_CLASS_ZA_ACCESS:
+ switch (type)
+ {
+ case AARCH64_OPND_SME_ZA_HV_idx_src:
+ case AARCH64_OPND_SME_ZA_HV_idx_dest:
+ case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
+ size = aarch64_get_qualifier_esize (opnd->qualifier);
+ max_value = 16 / size - 1;
+ if (!check_za_access (opnd, mismatch_detail, idx, max_value))
+ return 0;
+ break;
+
+ case AARCH64_OPND_SME_ZA_array:
+ if (!check_za_access (opnd, mismatch_detail, idx, 15))
+ return 0;
+ break;
+
+ default:
+ abort ();
+ }
+ break;
+
case AARCH64_OPND_CLASS_PRED_REG:
if (opnd->reg.regno >= 8
&& get_operand_fields_width (get_operand_from_code (type)) == 3)
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index ff0b04af794..98b2b01b2a2 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -5909,32 +5909,29 @@ const struct aarch64_opcode aarch64_opcode_table[] =
Y(SVE_REG, sve_reglist, "SVE_ZtxN", 0, F(FLD_SVE_Zt), \
"a list of SVE vector registers") \
Y(SVE_REG, regno, "SME_ZAda_2b", 0, F(FLD_SME_ZAda_2b), \
- "an SME ZA tile ZA0-ZA3") \
+ "an SME ZA tile ZA0-ZA3") \
Y(SVE_REG, regno, "SME_ZAda_3b", 0, F(FLD_SME_ZAda_3b), \
- "an SME ZA tile ZA0-ZA7") \
- Y(SVE_REG, sme_za_hv_tiles, "SME_ZA_HV_idx_src", 0, \
- F(FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_5),\
- "an SME horizontal or vertical vector access register") \
- Y(SVE_REG, sme_za_hv_tiles, "SME_ZA_HV_idx_dest", 0, \
- F(FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2),\
- "an SME horizontal or vertical vector access register") \
+ "an SME ZA tile ZA0-ZA7") \
+ Y(ZA_ACCESS, sme_za_hv_tiles, "SME_ZA_HV_idx_src", 0, \
+ F(FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_5), \
+ "an SME horizontal or vertical vector access register") \
+ Y(ZA_ACCESS, sme_za_hv_tiles, "SME_ZA_HV_idx_dest", 0, \
+ F(FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2), \
+ "an SME horizontal or vertical vector access register") \
Y(PRED_REG, regno, "SME_Pm", 0, F(FLD_SME_Pm), \
"an SVE predicate register") \
- Y(SVE_REG, imm, "SME_list_of_64bit_tiles", 0, \
- F(FLD_SME_zero_mask), "a list of 64-bit ZA element tiles") \
- Y(SVE_REG, sme_za_hv_tiles, "SME_ZA_HV_idx_ldstr", 0, \
+ Y(SVE_REG, imm, "SME_list_of_64bit_tiles", 0, \
+ F(FLD_SME_zero_mask), "a list of 64-bit ZA element tiles") \
+ Y(ZA_ACCESS, sme_za_hv_tiles, "SME_ZA_HV_idx_ldstr", 0, \
F(FLD_SME_size_10,FLD_index2,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2), \
- "an SME horizontal or vertical vector access register") \
- Y(SVE_REG, sme_za_array, "SME_ZA_array", 0, \
- F(FLD_SME_Rv,FLD_imm4_2), \
- "ZA array") \
+ "an SME horizontal or vertical vector access register") \
+ Y(ZA_ACCESS, sme_za_array, "SME_ZA_array", 0, \
+ F(FLD_SME_Rv,FLD_imm4_2), "ZA array") \
Y(ADDRESS, sme_addr_ri_u4xvl, "SME_ADDR_RI_U4xVL", 0 << OPD_F_OD_LSB, \
- F(FLD_Rn,FLD_imm4_2), \
- "memory offset") \
- Y(ADDRESS, sme_sm_za, "SME_SM_ZA", 0, \
- F(FLD_CRm), \
- "streaming mode") \
- Y(SVE_REG, sme_pred_reg_with_index, "SME_PnT_Wm_imm", 0, \
+ F(FLD_Rn,FLD_imm4_2), "memory offset") \
+ Y(ADDRESS, sme_sm_za, "SME_SM_ZA", 0, \
+ F(FLD_CRm), "streaming mode") \
+ Y(SVE_REG, sme_pred_reg_with_index, "SME_PnT_Wm_imm", 0, \
F(FLD_SME_Rm,FLD_SVE_Pn,FLD_SME_i1,FLD_SME_tszh,FLD_SME_tszl), \
"Source scalable predicate register with index ") \
Y(IMMEDIATE, imm, "TME_UIMM16", 0, F(FLD_imm16), \