diff options
Diffstat (limited to 'opcodes/aarch64-opc.c')
-rw-r--r-- | opcodes/aarch64-opc.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c index c92b4e8..746edde 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) |