summaryrefslogtreecommitdiff
path: root/opcodes/aarch64-opc.c
diff options
context:
space:
mode:
authorPrzemyslaw Wirkus <przemyslaw.wirkus@arm.com>2021-11-17 20:02:06 +0000
committerPrzemyslaw Wirkus <przemyslaw.wirkus@arm.com>2021-11-17 20:02:24 +0000
commit01a4d0822025084609380fb989d43bda0667db72 (patch)
tree5c1888e350164f67afae5b11ab70b82fa4a353bf /opcodes/aarch64-opc.c
parent1cad938de57a1577e5fe4b4afcabe889a8b9b9d7 (diff)
aarch64: [SME] Add LD1x, ST1x, LDR and STR instructions
This patch is adding new loads and stores defined by SME instructions. gas/ChangeLog: * config/tc-aarch64.c (parse_sme_address): New parser. (parse_sme_za_hv_tiles_operand_with_braces): New parser. (parse_sme_za_array): New parser. (output_operand_error_record): Print error details if present. (parse_operands): Support new operands. * testsuite/gas/aarch64/sme-5-illegal.d: New test. * testsuite/gas/aarch64/sme-5-illegal.l: New test. * testsuite/gas/aarch64/sme-5-illegal.s: New test. * testsuite/gas/aarch64/sme-5.d: New test. * testsuite/gas/aarch64/sme-5.s: New test. * testsuite/gas/aarch64/sme-6-illegal.d: New test. * testsuite/gas/aarch64/sme-6-illegal.l: New test. * testsuite/gas/aarch64/sme-6-illegal.s: New test. * testsuite/gas/aarch64/sme-6.d: New test. * testsuite/gas/aarch64/sme-6.s: New test. * testsuite/gas/aarch64/sme-7-illegal.d: New test. * testsuite/gas/aarch64/sme-7-illegal.l: New test. * testsuite/gas/aarch64/sme-7-illegal.s: New test. * testsuite/gas/aarch64/sme-7.d: New test. * testsuite/gas/aarch64/sme-7.s: New test. include/ChangeLog: * opcode/aarch64.h (enum aarch64_opnd): New operands. (enum aarch64_insn_class): Added sme_ldr and sme_str. (AARCH64_OPDE_UNTIED_IMMS): New operand error kind. opcodes/ChangeLog: * aarch64-asm.c (aarch64_ins_sme_za_hv_tiles): New inserter. (aarch64_ins_sme_za_list): New inserter. (aarch64_ins_sme_za_array): New inserter. (aarch64_ins_sme_addr_ri_u4xvl): New inserter. * aarch64-asm.h (AARCH64_DECL_OPD_INSERTER): Added ins_sme_za_list, ins_sme_za_array and ins_sme_addr_ri_u4xvl. * aarch64-dis.c (aarch64_ext_sme_za_hv_tiles): New extractor. (aarch64_ext_sme_za_list): New extractor. (aarch64_ext_sme_za_array): New extractor. (aarch64_ext_sme_addr_ri_u4xvl): New extractor. * aarch64-dis.h (AARCH64_DECL_OPD_EXTRACTOR): Added ext_sme_za_list, ext_sme_za_array and ext_sme_addr_ri_u4xvl. * aarch64-opc.c (operand_general_constraint_met_p): (aarch64_match_operands_constraint): Handle sme_ldr, sme_str and sme_misc. (aarch64_print_operand): New operands supported. * aarch64-tbl.h (OP_SVE_QUU): New qualifier. (OP_SVE_QZU): New qualifier. aarch64-asm-2.c: Regenerate. aarch64-dis-2.c: Regenerate. aarch64-opc-2.c: Regenerate.
Diffstat (limited to 'opcodes/aarch64-opc.c')
-rw-r--r--opcodes/aarch64-opc.c82
1 files changed, 67 insertions, 15 deletions
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 9f32eb554f..e46763d7a9 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -197,6 +197,8 @@ aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *opcode)
significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
}
+/* Instruction bit-fields.
++ Keep synced with 'enum aarch64_field_kind'. */
const aarch64_field fields[] =
{
{ 0, 0 }, /* NIL. */
@@ -1835,6 +1837,14 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
}
break;
+ case AARCH64_OPND_SME_ADDR_RI_U4xVL:
+ if (!value_in_range_p (opnd->addr.offset.imm, 0, 15))
+ {
+ set_offset_out_of_range_error (mismatch_detail, idx, 0, 15);
+ return 0;
+ }
+ break;
+
case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
@@ -1932,6 +1942,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
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_RX:
case AARCH64_OPND_SVE_ADDR_RX_LSL1:
case AARCH64_OPND_SVE_ADDR_RX_LSL2:
@@ -2750,21 +2761,51 @@ aarch64_match_operands_constraint (aarch64_inst *inst,
DEBUG_TRACE ("enter");
- /* Check for cases where a source register needs to be the same as the
- destination register. Do this before matching qualifiers since if
- an instruction has both invalid tying and invalid qualifiers,
- the error about qualifiers would suggest several alternative
- instructions that also have invalid tying. */
i = inst->opcode->tied_operand;
- if (i > 0 && (inst->operands[0].reg.regno != inst->operands[i].reg.regno))
+
+ if (i > 0)
{
- if (mismatch_detail)
- {
- mismatch_detail->kind = AARCH64_OPDE_UNTIED_OPERAND;
- mismatch_detail->index = i;
- mismatch_detail->error = NULL;
- }
- return 0;
+ /* Check for tied_operands with specific opcode iclass. */
+ switch (inst->opcode->iclass)
+ {
+ /* For SME LDR and STR instructions #imm must have the same numerical
+ value for both operands.
+ */
+ case sme_ldr:
+ case sme_str:
+ assert (inst->operands[0].type == AARCH64_OPND_SME_ZA_array);
+ assert (inst->operands[1].type == AARCH64_OPND_SME_ADDR_RI_U4xVL);
+ if (inst->operands[0].za_tile_vector.index.imm
+ != inst->operands[1].addr.offset.imm)
+ {
+ if (mismatch_detail)
+ {
+ mismatch_detail->kind = AARCH64_OPDE_UNTIED_IMMS;
+ mismatch_detail->index = i;
+ }
+ return 0;
+ }
+ break;
+
+ default:
+ /* Check for cases where a source register needs to be the same as the
+ destination register. Do this before matching qualifiers since if
+ an instruction has both invalid tying and invalid qualifiers,
+ the error about qualifiers would suggest several alternative
+ instructions that also have invalid tying. */
+ if (inst->operands[0].reg.regno
+ != inst->operands[i].reg.regno)
+ {
+ if (mismatch_detail)
+ {
+ mismatch_detail->kind = AARCH64_OPDE_UNTIED_OPERAND;
+ mismatch_detail->index = i;
+ mismatch_detail->error = NULL;
+ }
+ return 0;
+ }
+ break;
+ }
}
/* Match operands' qualifier.
@@ -3403,18 +3444,27 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
case AARCH64_OPND_SME_ZA_HV_idx_src:
case AARCH64_OPND_SME_ZA_HV_idx_dest:
- snprintf (buf, size, "za%d%c.%s[w%d, %d]",
+ case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
+ snprintf (buf, size, "%sza%d%c.%s[w%d, %d]%s",
+ opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "{" : "",
opnd->za_tile_vector.regno,
opnd->za_tile_vector.v == 1 ? 'v' : 'h',
aarch64_get_qualifier_name (opnd->qualifier),
opnd->za_tile_vector.index.regno,
- opnd->za_tile_vector.index.imm);
+ opnd->za_tile_vector.index.imm,
+ opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "}" : "");
break;
case AARCH64_OPND_SME_list_of_64bit_tiles:
print_sme_za_list (buf, size, opnd->reg.regno);
break;
+ case AARCH64_OPND_SME_ZA_array:
+ snprintf (buf, size, "za[w%d, %d]",
+ opnd->za_tile_vector.index.regno,
+ opnd->za_tile_vector.index.imm);
+ break;
+
case AARCH64_OPND_CRn:
case AARCH64_OPND_CRm:
snprintf (buf, size, "C%" PRIi64, opnd->imm.value);
@@ -3678,6 +3728,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
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_RX:
case AARCH64_OPND_SVE_ADDR_RX_LSL1:
case AARCH64_OPND_SVE_ADDR_RX_LSL2:
@@ -3718,6 +3769,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
case AARCH64_OPND_ADDR_SIMM11:
case AARCH64_OPND_ADDR_SIMM13:
case AARCH64_OPND_ADDR_OFFSET:
+ case AARCH64_OPND_SME_ADDR_RI_U4xVL:
case AARCH64_OPND_SVE_ADDR_RI_S4x16:
case AARCH64_OPND_SVE_ADDR_RI_S4x32:
case AARCH64_OPND_SVE_ADDR_RI_S4xVL: