summaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorSrinath Parvathaneni <srinath.parvathaneni@arm.com>2024-01-15 09:37:32 +0000
committerNick Clifton <nickc@redhat.com>2024-01-15 11:45:41 +0000
commit39092c7a1fb0927fbbdb40e1142de816d6f3f097 (patch)
tree39c066e97256ea52262332db3601294caf5708b6 /opcodes
parent88601c2d941b004b443dc4bfdf3b93ea1983d136 (diff)
aarch64: Add SVE2.1 dupq, eorqv and extq instructions.
Hi, This patch add support for SVE2.1 instruction dupq, eorqv and extq. Regression testing for aarch64-none-elf target and found no regressions. Ok for binutils-master? Regards, Srinath.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/aarch64-asm.c16
-rw-r--r--opcodes/aarch64-asm.h1
-rw-r--r--opcodes/aarch64-dis.c31
-rw-r--r--opcodes/aarch64-dis.h1
-rw-r--r--opcodes/aarch64-opc.c14
-rw-r--r--opcodes/aarch64-tbl.h10
6 files changed, 73 insertions, 0 deletions
diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c
index 1dfd59df42d..0de09f0435a 100644
--- a/opcodes/aarch64-asm.c
+++ b/opcodes/aarch64-asm.c
@@ -1220,6 +1220,21 @@ aarch64_ins_sve_index (const aarch64_operand *self,
return true;
}
+/* Encode Zn.<T>[<imm>], where <imm> is an immediate with range of 0 to one less
+ than the number of elements in 128 bit, which can encode il:tsz. */
+bool
+aarch64_ins_sve_index_imm (const aarch64_operand *self,
+ const aarch64_opnd_info *info, aarch64_insn *code,
+ const aarch64_inst *inst ATTRIBUTE_UNUSED,
+ aarch64_operand_error *errors ATTRIBUTE_UNUSED)
+{
+ insert_field (self->fields[0], code, info->reglane.regno, 0);
+ unsigned int esize = aarch64_get_qualifier_esize (info->qualifier);
+ insert_fields (code, (info->reglane.index * 2 + 1) * esize, 0,
+ 2, self->fields[1],self->fields[2]);
+ return true;
+}
+
/* Encode a logical/bitmask immediate for the MOV alias of SVE DUPM. */
bool
aarch64_ins_sve_limm_mov (const aarch64_operand *self,
@@ -2079,6 +2094,7 @@ aarch64_encode_variant_using_iclass (struct aarch64_inst *inst)
case sme_shift:
case sve_index:
+ case sve_index1:
case sve_shift_pred:
case sve_shift_unpred:
case sve_shift_tsz_hsd:
diff --git a/opcodes/aarch64-asm.h b/opcodes/aarch64-asm.h
index d4b6407dc5d..e48bf0db8a8 100644
--- a/opcodes/aarch64-asm.h
+++ b/opcodes/aarch64-asm.h
@@ -93,6 +93,7 @@ AARCH64_DECL_OPD_INSERTER (ins_sve_float_half_one);
AARCH64_DECL_OPD_INSERTER (ins_sve_float_half_two);
AARCH64_DECL_OPD_INSERTER (ins_sve_float_zero_one);
AARCH64_DECL_OPD_INSERTER (ins_sve_index);
+AARCH64_DECL_OPD_INSERTER (ins_sve_index_imm);
AARCH64_DECL_OPD_INSERTER (ins_sve_limm_mov);
AARCH64_DECL_OPD_INSERTER (ins_sve_quad_index);
AARCH64_DECL_OPD_INSERTER (ins_sve_reglist);
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
index d395438966f..bffa760004a 100644
--- a/opcodes/aarch64-dis.c
+++ b/opcodes/aarch64-dis.c
@@ -2097,6 +2097,26 @@ aarch64_ext_sve_index (const aarch64_operand *self,
return true;
}
+/* Decode Zn.<T>[<imm>], where <imm> is an immediate with range of 0 to one less
+ than the number of elements in 128 bit, which can encode il:tsz. */
+bool
+aarch64_ext_sve_index_imm (const aarch64_operand *self,
+ aarch64_opnd_info *info, aarch64_insn code,
+ const aarch64_inst *inst ATTRIBUTE_UNUSED,
+ aarch64_operand_error *errors ATTRIBUTE_UNUSED)
+{
+ int val;
+
+ info->reglane.regno = extract_field (self->fields[0], code, 0);
+ val = extract_fields (code, 0, 2, self->fields[2], self->fields[1]);
+ if ((val & 15) == 0)
+ return 0;
+ while ((val & 1) == 0)
+ val /= 2;
+ info->reglane.index = val / 2;
+ return true;
+}
+
/* Decode a logical immediate for the MOV alias of SVE DUPM. */
bool
aarch64_ext_sve_limm_mov (const aarch64_operand *self,
@@ -3231,6 +3251,17 @@ aarch64_decode_variant_using_iclass (aarch64_inst *inst)
}
break;
+ case sve_index1:
+ i = extract_fields (inst->value, 0, 2, FLD_SVE_tsz, FLD_SVE_i2h);
+ if ((i & 15) == 0)
+ return false;
+ while ((i & 1) == 0)
+ {
+ i >>= 1;
+ variant += 1;
+ }
+ break;
+
case sve_limm:
/* Pick the smallest applicable element size. */
if ((inst->value & 0x20600) == 0x600)
diff --git a/opcodes/aarch64-dis.h b/opcodes/aarch64-dis.h
index 9a38c1ab50f..30212f2ae2c 100644
--- a/opcodes/aarch64-dis.h
+++ b/opcodes/aarch64-dis.h
@@ -117,6 +117,7 @@ AARCH64_DECL_OPD_EXTRACTOR (ext_sve_float_half_one);
AARCH64_DECL_OPD_EXTRACTOR (ext_sve_float_half_two);
AARCH64_DECL_OPD_EXTRACTOR (ext_sve_float_zero_one);
AARCH64_DECL_OPD_EXTRACTOR (ext_sve_index);
+AARCH64_DECL_OPD_EXTRACTOR (ext_sve_index_imm);
AARCH64_DECL_OPD_EXTRACTOR (ext_sve_limm_mov);
AARCH64_DECL_OPD_EXTRACTOR (ext_sve_quad_index);
AARCH64_DECL_OPD_EXTRACTOR (ext_sve_reglist);
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index cf76871930f..1d8ed26c709 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -1794,6 +1794,18 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
return 0;
break;
+ case AARCH64_OPND_SVE_Zm_imm4:
+ if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 15))
+ return 0;
+ break;
+
+ case AARCH64_OPND_SVE_Zn_5_INDEX:
+ size = aarch64_get_qualifier_esize (opnd->qualifier);
+ if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
+ 0, 16 / size - 1))
+ return 0;
+ break;
+
case AARCH64_OPND_SME_PNn3_INDEX1:
case AARCH64_OPND_SME_PNn3_INDEX2:
size = get_operand_field_width (get_operand_from_code (type), 1);
@@ -4074,6 +4086,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
case AARCH64_OPND_SME_Zm_INDEX3_1:
case AARCH64_OPND_SME_Zm_INDEX3_2:
case AARCH64_OPND_SME_Zm_INDEX3_10:
+ case AARCH64_OPND_SVE_Zn_5_INDEX:
case AARCH64_OPND_SME_Zm_INDEX4_1:
case AARCH64_OPND_SME_Zm_INDEX4_10:
case AARCH64_OPND_SME_Zn_INDEX1_16:
@@ -4082,6 +4095,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
case AARCH64_OPND_SME_Zn_INDEX3_14:
case AARCH64_OPND_SME_Zn_INDEX3_15:
case AARCH64_OPND_SME_Zn_INDEX4_14:
+ case AARCH64_OPND_SVE_Zm_imm4:
snprintf (buf, size, "%s[%s]",
(opnd->qualifier == AARCH64_OPND_QLF_NIL
? style_reg (styler, "z%d", opnd->reglane.regno)
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index f433257634e..07f4eb319e9 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -6337,6 +6337,10 @@ const struct aarch64_opcode aarch64_opcode_table[] =
SVE2p1_INSNC("sminqv",0x040e2000, 0xff3fe000, sve2_urqvs, 0, OP3 (Vd, SVE_Pg3, SVE_Zn), OP_SVE_vUS_BHSD_BHSD, F_OPD_SIZE, C_SCAN_MOVPRFX, 0),
SVE2p1_INSNC("umaxqv",0x040d2000, 0xff3fe000, sve2_urqvs, 0, OP3 (Vd, SVE_Pg3, SVE_Zn), OP_SVE_vUS_BHSD_BHSD, F_OPD_SIZE, C_SCAN_MOVPRFX, 0),
SVE2p1_INSNC("uminqv",0x040f2000, 0xff3fe000, sve2_urqvs, 0, OP3 (Vd, SVE_Pg3, SVE_Zn), OP_SVE_vUS_BHSD_BHSD, F_OPD_SIZE, C_SCAN_MOVPRFX, 0),
+ SVE2p1_INSNC("eorqv",0x041d2000, 0xff3fe000, sve2_urqvs, 0, OP3 (Vd, SVE_Pg3, SVE_Zn), OP_SVE_vUS_BHSD_BHSD, F_OPD_SIZE, C_SCAN_MOVPRFX, 0),
+
+ SVE2p1_INSN("dupq",0x05202400, 0xffe0fc00, sve_index1, 0, OP2 (SVE_Zd, SVE_Zn_5_INDEX), OP_SVE_VV_BHSD, 0, 0),
+ SVE2p1_INSN("extq",0x05602400, 0xfff0fc00, sve_misc, 0, OP3 (SVE_Zd, SVE_Zd, SVE_Zm_imm4), OP_SVE_BBB, 0, 0),
{0, 0, 0, 0, 0, 0, {}, {}, 0, 0, 0, NULL},
};
@@ -6816,11 +6820,17 @@ const struct aarch64_opcode aarch64_opcode_table[] =
Y(SVE_REG, sve_quad_index, "SVE_Zm4_11_INDEX", \
4 << OPD_F_OD_LSB, F(FLD_SVE_i2h, FLD_SVE_i3l, FLD_SVE_imm4), \
"an indexed SVE vector register") \
+ Y(SVE_REG, sve_quad_index, "SVE_Zm_imm4", \
+ 5 << OPD_F_OD_LSB, F(FLD_SVE_Zm_5, FLD_SVE_imm4), \
+ "an 4bit indexed SVE vector register") \
Y(SVE_REG, sve_quad_index, "SVE_Zm4_INDEX", \
4 << OPD_F_OD_LSB, F(FLD_SVE_Zm_16), \
"an indexed SVE vector register") \
Y(SVE_REG, regno, "SVE_Zn", 0, F(FLD_SVE_Zn), \
"an SVE vector register") \
+ Y(SVE_REG, sve_index_imm, "SVE_Zn_5_INDEX", 0, \
+ F(FLD_SVE_Zn, FLD_SVE_i2h, FLD_SVE_tsz), \
+ "a 5 bit idexed SVE vector register") \
Y(SVE_REG, sve_index, "SVE_Zn_INDEX", 0, F(FLD_SVE_Zn), \
"an indexed SVE vector register") \
Y(SVE_REGLIST, sve_reglist, "SVE_ZnxN", 0, F(FLD_SVE_Zn), \