public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Srinath Parvathaneni <srinath.parvathaneni@arm.com>
To: binutils@sourceware.org
Cc: richard.earnshaw@arm.com, nickc@redhat.com
Subject: [PATCH 2/6][Binutils] aarch64: Add support for FEAT_SME2p1 instructions.
Date: Mon, 15 Jan 2024 09:34:41 +0000	[thread overview]
Message-ID: <fdb8e035-e762-45f0-a694-51733859ca7f@arm.com> (raw)
In-Reply-To: <73155200-f7c2-4226-b4be-4a320ea82044@arm.com>

[-- Attachment #1: Type: text/plain, Size: 374 bytes --]

Hi,

This patch add support for FEAT_SME2p1 and "movaz" instructions
along with the optional flag +sme2p1.

Following "movaz" instructions are add:
Move and zero two ZA tile slices to vector registers.
Move and zero four ZA tile slices to vector registers.

Regression testing for aarch64-none-elf target and found no regressions.

Ok for binutils-master?

Regards,
Srinath.

[-- Attachment #2: 2_6.patch --]
[-- Type: text/x-patch, Size: 24758 bytes --]

diff --git a/gas/NEWS b/gas/NEWS
index 74df7e61349626926bec1626aa5d89629c5d6c4a..d2c5c0641c4392d66472e535e5f51756fc5d511f 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add support for the AArch64 Scalable Matrix Extension version 2.1 (SME2.1)
+  instructions.
+
 * Add support for 'armv8.9-a' and 'armv9.4-a' for -march in Arm GAS.
 
 * Initial support for Intel APX: 32 GPRs, NDD, PUSH2/POP2 and PUSHP/POPP.
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index bc40d126632e093b02268fd7474f4cf0c6ddf6d7..34159c2168b78fe12d4a549678ae77be88e50313 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -4492,6 +4492,7 @@ parse_sme_immediate (char **str, int64_t *imm)
 
    [<Wv>, <imm>]
    [<Wv>, #<imm>]
+   [<Ws>, <offsf>:<offsl>]
 
    Return true on success, populating OPND with the parsed index.  */
 
@@ -4592,6 +4593,7 @@ parse_sme_za_index (char **str, struct aarch64_indexed_za *opnd)
    <Pm>.<T>[<Wv>< #<imm>]
    ZA[<Wv>, #<imm>]
    <ZAn><HV>.<T>[<Wv>, #<imm>]
+   <ZAn><HV>.<T>[<Ws>, <offsf>:<offsl>]
 
    FLAGS is as for parse_typed_reg.  */
 
@@ -7865,6 +7867,21 @@ parse_operands (char *str, const aarch64_opcode *opcode)
 	  info->qualifier = qualifier;
 	  break;
 
+	case AARCH64_OPND_SME_ZA_array_vrsb_1:
+	case AARCH64_OPND_SME_ZA_array_vrsh_1:
+	case AARCH64_OPND_SME_ZA_array_vrss_1:
+	case AARCH64_OPND_SME_ZA_array_vrsd_1:
+	case AARCH64_OPND_SME_ZA_array_vrsb_2:
+	case AARCH64_OPND_SME_ZA_array_vrsh_2:
+	case AARCH64_OPND_SME_ZA_array_vrss_2:
+	case AARCH64_OPND_SME_ZA_array_vrsd_2:
+	  if (!parse_dual_indexed_reg (&str, REG_TYPE_ZATHV,
+				       &info->indexed_za, &qualifier, 0))
+	    goto failure;
+	  info->qualifier = qualifier;
+	  break;
+
+
 	case AARCH64_OPND_SME_VLxN_10:
 	case AARCH64_OPND_SME_VLxN_13:
 	  po_strict_enum_or_fail (aarch64_sme_vlxn_array);
@@ -10336,6 +10353,7 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = {
   {"d128",		AARCH64_FEATURE (D128),
 			AARCH64_FEATURE (LSE128)},
   {"b16b16",		AARCH64_FEATURE (B16B16), AARCH64_FEATURE (SVE2)},
+  {"sme2p1",		AARCH64_FEATURE (SME2p1), AARCH64_FEATURE (SME2)},
   {NULL,		AARCH64_NO_FEATURES, AARCH64_NO_FEATURES},
 };
 
diff --git a/gas/doc/c-aarch64.texi b/gas/doc/c-aarch64.texi
index ccf18ee2661fed0bb89608d7f122556cb541e5b5..1f3a4fbcafbab652d70f202b33527ae3dde7e1bb 100644
--- a/gas/doc/c-aarch64.texi
+++ b/gas/doc/c-aarch64.texi
@@ -276,6 +276,8 @@ automatically cause those extensions to be disabled.
  @tab Enable TRCIT instruction.
 @item @code{d128} @tab Armv9.4-A @tab No
  @tab Enable the 128-bit Page Descriptor Extension.  This implies @code{lse128}.
+@item @code{sme2p1} @tab N/A @tab No
+ @tab Enable the SME2.1 Extension.
 @end multitable
 
 @node AArch64 Syntax
diff --git a/gas/testsuite/gas/aarch64/sme2p1-1.d b/gas/testsuite/gas/aarch64/sme2p1-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..a6e7b7664024e7f03ddd1d8ece9d6c3bd1c79042
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2p1-1.d
@@ -0,0 +1,42 @@
+#name: Test of SME2.1 movaz instructions.
+#as: -march=armv9.4-a+sme2p1
+#objdump: -dr
+
+[^:]+:     file format .*
+
+
+[^:]+:
+
+[^:]+:
+.*:	c006c260 	movaz	{z0.b-z1.b}, za0v.b \[w14, 6:7\]
+.*:	c046c260 	movaz	{z0.h-z1.h}, za0v.h \[w14, 6:7\]
+.*:	c086c220 	movaz	{z0.s-z1.s}, za0v.s \[w14, 2:3\]
+.*:	c0c6c200 	movaz	{z0.d-z1.d}, za0v.d \[w14, 0:1\]
+.*:	c00602e0 	movaz	{z0.b-z1.b}, za0h.b \[w12, 14:15\]
+.*:	c0462260 	movaz	{z0.h-z1.h}, za0h.h \[w13, 6:7\]
+.*:	c0864220 	movaz	{z0.s-z1.s}, za0h.s \[w14, 2:3\]
+.*:	c0c66200 	movaz	{z0.d-z1.d}, za0h.d \[w15, 0:1\]
+.*:	c006c260 	movaz	{z0.b-z1.b}, za0v.b \[w14, 6:7\]
+.*:	c046c2e0 	movaz	{z0.h-z1.h}, za1v.h \[w14, 6:7\]
+.*:	c086c2a0 	movaz	{z0.s-z1.s}, za2v.s \[w14, 2:3\]
+.*:	c0c6c260 	movaz	{z0.d-z1.d}, za3v.d \[w14, 0:1\]
+.*:	c00602e0 	movaz	{z0.b-z1.b}, za0h.b \[w12, 14:15\]
+.*:	c04622e0 	movaz	{z0.h-z1.h}, za1h.h \[w13, 6:7\]
+.*:	c08642a0 	movaz	{z0.s-z1.s}, za2h.s \[w14, 2:3\]
+.*:	c0c66260 	movaz	{z0.d-z1.d}, za3h.d \[w15, 0:1\]
+.*:	c006c660 	movaz	{z0.b-z3.b}, za0v.b \[w14, 12:15\]
+.*:	c046c620 	movaz	{z0.h-z3.h}, za0v.h \[w14, 4:7\]
+.*:	c086c600 	movaz	{z0.s-z3.s}, za0v.s \[w14, 0:3\]
+.*:	c0c6c600 	movaz	{z0.d-z3.d}, za0v.d \[w14, 0:3\]
+.*:	c0060660 	movaz	{z0.b-z3.b}, za0h.b \[w12, 12:15\]
+.*:	c0462620 	movaz	{z0.h-z3.h}, za0h.h \[w13, 4:7\]
+.*:	c0864600 	movaz	{z0.s-z3.s}, za0h.s \[w14, 0:3\]
+.*:	c0c66600 	movaz	{z0.d-z3.d}, za0h.d \[w15, 0:3\]
+.*:	c006c640 	movaz	{z0.b-z3.b}, za0v.b \[w14, 8:11\]
+.*:	c046c660 	movaz	{z0.h-z3.h}, za1v.h \[w14, 4:7\]
+.*:	c086c640 	movaz	{z0.s-z3.s}, za2v.s \[w14, 0:3\]
+.*:	c0c6c660 	movaz	{z0.d-z3.d}, za3v.d \[w14, 0:3\]
+.*:	c0060660 	movaz	{z0.b-z3.b}, za0h.b \[w12, 12:15\]
+.*:	c0462660 	movaz	{z0.h-z3.h}, za1h.h \[w13, 4:7\]
+.*:	c0864640 	movaz	{z0.s-z3.s}, za2h.s \[w14, 0:3\]
+.*:	c0c66660 	movaz	{z0.d-z3.d}, za3h.d \[w15, 0:3\]
diff --git a/gas/testsuite/gas/aarch64/sme2p1-1.s b/gas/testsuite/gas/aarch64/sme2p1-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..77481d4b874b4688e10c794e6ea9e1ff0c81ef3d
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2p1-1.s
@@ -0,0 +1,39 @@
+	movaz {z0.b - z1.b}, ZA0V.B [w14, 6:7]
+	movaz {z0.h - z1.h}, ZA0V.H [w14, 6:7]
+	movaz {z0.s - z1.s}, ZA0V.S [w14, 2:3]
+	movaz {z0.d - z1.d}, ZA0V.D [w14, 0:1]
+
+	movaz {z0.b - z1.b}, ZA0H.B [w12, 14:15]
+	movaz {z0.h - z1.h}, ZA0H.H [w13, 6:7]
+	movaz {z0.s - z1.s}, ZA0H.S [w14, 2:3]
+	movaz {z0.d - z1.d}, ZA0H.D [w15, 0:1]
+
+	movaz {z0.b - z1.b}, ZA0V.B [w14, 6:7]
+	movaz {z0.h - z1.h}, ZA1V.H [w14, 6:7]
+	movaz {z0.s - z1.s}, ZA2V.S [w14, 2:3]
+	movaz {z0.d - z1.d}, ZA3V.D [w14, 0:1]
+
+	movaz {z0.b - z1.b}, ZA0H.B [w12, 14:15]
+	movaz {z0.h - z1.h}, ZA1H.H [w13, 6:7]
+	movaz {z0.s - z1.s}, ZA2H.S [w14, 2:3]
+	movaz {z0.d - z1.d}, ZA3H.D [w15, 0:1]
+
+	movaz {z0.b - z3.b}, ZA0V.B [w14, 12:15]
+	movaz {z0.h - z3.h}, ZA0V.H [w14, 4:7]
+	movaz {z0.s - z3.s}, ZA0V.S [w14, 0:3]
+	movaz {z0.d - z3.d}, ZA0V.D [w14, 0:3]
+
+	movaz {z0.b - z3.b}, ZA0H.B [w12, 12:15]
+	movaz {z0.h - z3.h}, ZA0H.H [w13, 4:7]
+	movaz {z0.s - z3.s}, ZA0H.S [w14, 0:3]
+	movaz {z0.d - z3.d}, ZA0H.D [w15, 0:3]
+
+	movaz {z0.b - z3.b}, ZA0V.B [w14, 8:11]
+	movaz {z0.h - z3.h}, ZA1V.H [w14, 4:7]
+	movaz {z0.s - z3.s}, ZA2V.S [w14, 0:3]
+	movaz {z0.d - z3.d}, ZA3V.D [w14, 0:3]
+
+	movaz {z0.b - z3.b}, ZA0H.B [w12, 12:15]
+	movaz {z0.h - z3.h}, ZA1H.H [w13, 4:7]
+	movaz {z0.s - z3.s}, ZA2H.S [w14, 0:3]
+	movaz {z0.d - z3.d}, ZA3H.D [w15, 0:3]
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index e2ca92361b46a27f67d315d155eb3a9608176cb7..648e25f3e4242bb738eee5f62079838784223b8a 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -224,6 +224,8 @@ enum aarch64_feature_bit {
   AARCH64_FEATURE_SEBEP,
   /* SVE2.1 and SME2.1 non-widening BFloat16 instructions.  */
   AARCH64_FEATURE_B16B16,
+  /* SME2.1 instructions.  */
+  AARCH64_FEATURE_SME2p1,
   AARCH64_NUM_FEATURES
 };
 
@@ -705,6 +707,14 @@ enum aarch64_opnd
   AARCH64_OPND_SVE_Vd,		/* Scalar SIMD&FP register in Vd.  */
   AARCH64_OPND_SVE_Vm,		/* Scalar SIMD&FP register in Vm.  */
   AARCH64_OPND_SVE_Vn,		/* Scalar SIMD&FP register in Vn.  */
+  AARCH64_OPND_SME_ZA_array_vrsb_1, /* Tile to vector, two registers (B).  */
+  AARCH64_OPND_SME_ZA_array_vrsh_1, /* Tile to vector, two registers (H).  */
+  AARCH64_OPND_SME_ZA_array_vrss_1, /* Tile to vector, two registers (S).  */
+  AARCH64_OPND_SME_ZA_array_vrsd_1, /* Tile to vector, two registers (D).  */
+  AARCH64_OPND_SME_ZA_array_vrsb_2, /* Tile to vector, four registers (B).  */
+  AARCH64_OPND_SME_ZA_array_vrsh_2, /* Tile to vector, four registers (H).  */
+  AARCH64_OPND_SME_ZA_array_vrss_2, /* Tile to vector, four registers (S). */
+  AARCH64_OPND_SME_ZA_array_vrsd_2, /* Tile to vector, four registers (D).  */
   AARCH64_OPND_SVE_Za_5,	/* SVE vector register in Za, bits [9,5].  */
   AARCH64_OPND_SVE_Za_16,	/* SVE vector register in Za, bits [20,16].  */
   AARCH64_OPND_SVE_Zd,		/* SVE vector register in Zd.  */
@@ -962,6 +972,7 @@ enum aarch64_insn_class
   sme_start,
   sme_stop,
   sme2_mov,
+  sme2_movaz,
   sve_cpy,
   sve_index,
   sve_limm,
diff --git a/opcodes/aarch64-asm.h b/opcodes/aarch64-asm.h
index a3bf7bda0130f06623b0b56c18d9eca632b24a3a..d4b6407dc5de8d6e103ee8ca5b5f2c6bb814647f 100644
--- a/opcodes/aarch64-asm.h
+++ b/opcodes/aarch64-asm.h
@@ -100,6 +100,8 @@ AARCH64_DECL_OPD_INSERTER (ins_sve_strided_reglist);
 AARCH64_DECL_OPD_INSERTER (ins_sve_scale);
 AARCH64_DECL_OPD_INSERTER (ins_sve_shlimm);
 AARCH64_DECL_OPD_INSERTER (ins_sve_shrimm);
+AARCH64_DECL_OPD_INSERTER (ins_sme_za_vrs1);
+AARCH64_DECL_OPD_INSERTER (ins_sme_za_vrs2);
 AARCH64_DECL_OPD_INSERTER (ins_sme_za_hv_tiles);
 AARCH64_DECL_OPD_INSERTER (ins_sme_za_hv_tiles_range);
 AARCH64_DECL_OPD_INSERTER (ins_sme_za_list);
diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c
index 1db290eea7e9d23893bfd2bd0a07c13392f6c9f6..3fac127a5899077e2ac19c5e98df737b8ffbe147 100644
--- a/opcodes/aarch64-asm.c
+++ b/opcodes/aarch64-asm.c
@@ -1375,6 +1375,76 @@ aarch64_ins_sve_float_zero_one (const aarch64_operand *self,
   return true;
 }
 
+bool
+aarch64_ins_sme_za_vrs1 (const aarch64_operand *self,
+			     const aarch64_opnd_info *info,
+			     aarch64_insn *code,
+			     const aarch64_inst *inst ATTRIBUTE_UNUSED,
+			     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
+{
+  int za_reg = info->indexed_za.regno;
+  int regno = info->indexed_za.index.regno & 3;
+  int imm = info->indexed_za.index.imm;
+  int v =  info->indexed_za.v;
+  int countm1 = info->indexed_za.index.countm1;
+
+  insert_field (self->fields[0], code, v, 0);
+  insert_field (self->fields[1], code, regno, 0);
+  switch (info->qualifier)
+    {
+    case AARCH64_OPND_QLF_S_B:
+      insert_field (self->fields[2], code, imm / (countm1 + 1), 0);
+      break;
+    case AARCH64_OPND_QLF_S_H:
+    case AARCH64_OPND_QLF_S_S:
+      insert_field (self->fields[2], code, za_reg, 0);
+      insert_field (self->fields[3], code, imm / (countm1 + 1), 0);
+      break;
+    case AARCH64_OPND_QLF_S_D:
+      insert_field (self->fields[2], code, za_reg, 0);
+      break;
+    default:
+      return false;
+    }
+
+  return true;
+}
+
+bool
+aarch64_ins_sme_za_vrs2 (const aarch64_operand *self,
+			     const aarch64_opnd_info *info,
+			     aarch64_insn *code,
+			     const aarch64_inst *inst ATTRIBUTE_UNUSED,
+			     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
+{
+  int za_reg = info->indexed_za.regno;
+  int regno = info->indexed_za.index.regno & 3;
+  int imm = info->indexed_za.index.imm;
+  int v =  info->indexed_za.v;
+  int countm1 = info->indexed_za.index.countm1;
+
+  insert_field (self->fields[0], code, v, 0);
+  insert_field (self->fields[1], code, regno, 0);
+  switch (info->qualifier)
+    {
+    case AARCH64_OPND_QLF_S_B:
+      insert_field (self->fields[2], code, imm / (countm1 + 1), 0);
+      break;
+    case AARCH64_OPND_QLF_S_H:
+      insert_field (self->fields[2], code, za_reg, 0);
+      insert_field (self->fields[3], code, imm / (countm1 + 1), 0);
+      break;
+    case AARCH64_OPND_QLF_S_S:
+    case AARCH64_OPND_QLF_S_D:
+      insert_field (self->fields[2], code, za_reg, 0);
+      break;
+    default:
+      return false;
+    }
+
+  return true;
+}
+
 /* Encode in SME instruction such as MOVA ZA tile vector register number,
    vector indicator, vector selector and immediate.  */
 bool
@@ -2011,6 +2081,7 @@ aarch64_encode_variant_using_iclass (struct aarch64_inst *inst)
       break;
 
     case sme_misc:
+    case sme2_movaz:
     case sve_misc:
       /* These instructions have only a single variant.  */
       break;
diff --git a/opcodes/aarch64-dis.h b/opcodes/aarch64-dis.h
index 20387db7b39e98c081ff88c8c73b437f0b50fd01..9a38c1ab50f7fdb27588c7451ade19c166e69c96 100644
--- a/opcodes/aarch64-dis.h
+++ b/opcodes/aarch64-dis.h
@@ -124,6 +124,8 @@ AARCH64_DECL_OPD_EXTRACTOR (ext_sve_strided_reglist);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sve_scale);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sve_shlimm);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sve_shrimm);
+AARCH64_DECL_OPD_EXTRACTOR (ext_sme_za_vrs1);
+AARCH64_DECL_OPD_EXTRACTOR (ext_sme_za_vrs2);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sme_za_hv_tiles);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sme_za_hv_tiles_range);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sme_za_list);
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
index 7e088a93c107b6152b2df1bb622516d09fce3839..a14b2ca02d2c0fcf6c94f5bb0c587a7168594a5b 100644
--- a/opcodes/aarch64-dis.c
+++ b/opcodes/aarch64-dis.c
@@ -1929,6 +1929,84 @@ aarch64_ext_sme_za_array (const aarch64_operand *self,
   return true;
 }
 
+/* Decode two ZA tile slice (V, Rv, off3| ZAn ,off2 | ZAn, ol| ZAn) feilds.  */
+bool
+aarch64_ext_sme_za_vrs1 (const aarch64_operand *self,
+			  aarch64_opnd_info *info, aarch64_insn code,
+			  const aarch64_inst *inst,
+			  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
+{
+  int v = extract_field (self->fields[0], code, 0);
+  int regno = 12 + extract_field (self->fields[1], code, 0);
+  int imm, za_reg, num_offset = 2;
+
+  switch (info->qualifier)
+    {
+    case AARCH64_OPND_QLF_S_B:
+      imm = extract_field (self->fields[2], code, 0);
+      info->indexed_za.index.imm = imm * num_offset;
+      break;
+    case AARCH64_OPND_QLF_S_H:
+    case AARCH64_OPND_QLF_S_S:
+      za_reg = extract_field (self->fields[2], code, 0);
+      imm = extract_field (self->fields[3], code, 0);
+      info->indexed_za.index.imm = imm * num_offset;
+      info->indexed_za.regno = za_reg;
+      break;
+    case AARCH64_OPND_QLF_S_D:
+      za_reg = extract_field (self->fields[2], code, 0);
+      info->indexed_za.regno = za_reg;
+      break;
+    default:
+      return false;
+    }
+
+  info->indexed_za.index.regno = regno;
+  info->indexed_za.index.countm1 = num_offset - 1;
+  info->indexed_za.v = v;
+  info->indexed_za.group_size = get_opcode_dependent_value (inst->opcode);
+  return true;
+}
+
+/* Decode four ZA tile slice (V, Rv, off3| ZAn ,off2 | ZAn, ol| ZAn) feilds.  */
+bool
+aarch64_ext_sme_za_vrs2 (const aarch64_operand *self,
+			  aarch64_opnd_info *info, aarch64_insn code,
+			  const aarch64_inst *inst,
+			  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
+{
+  int v = extract_field (self->fields[0], code, 0);
+  int regno = 12 + extract_field (self->fields[1], code, 0);
+  int imm, za_reg, num_offset =4;
+
+  switch (info->qualifier)
+    {
+    case AARCH64_OPND_QLF_S_B:
+      imm = extract_field (self->fields[2], code, 0);
+      info->indexed_za.index.imm = imm * num_offset;
+      break;
+    case AARCH64_OPND_QLF_S_H:
+      za_reg = extract_field (self->fields[2], code, 0);
+      imm = extract_field (self->fields[3], code, 0);
+      info->indexed_za.index.imm = imm * num_offset;
+      info->indexed_za.regno = za_reg;
+      break;
+    case AARCH64_OPND_QLF_S_S:
+    case AARCH64_OPND_QLF_S_D:
+      za_reg = extract_field (self->fields[2], code, 0);
+      info->indexed_za.regno = za_reg;
+      break;
+    default:
+      return false;
+    }
+
+  info->indexed_za.index.regno = regno;
+  info->indexed_za.index.countm1 = num_offset - 1;
+  info->indexed_za.v = v;
+  info->indexed_za.group_size = get_opcode_dependent_value (inst->opcode);
+  return true;
+}
+
 bool
 aarch64_ext_sme_addr_ri_u4xvl (const aarch64_operand *self,
                                aarch64_opnd_info *info, aarch64_insn code,
@@ -3160,6 +3238,7 @@ aarch64_decode_variant_using_iclass (aarch64_inst *inst)
       variant = 3;
       break;
 
+    case sme2_movaz:
     case sme_misc:
     case sve_misc:
       /* These instructions have only a single variant.  */
diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h
index f193a90ecc5993645fed573a9a0670aeb4fbf781..587775152e3ef26cb3d09e138eda2791b95cb5d9 100644
--- a/opcodes/aarch64-opc.h
+++ b/opcodes/aarch64-opc.h
@@ -210,6 +210,13 @@ enum aarch64_field_kind
   FLD_sz,
   FLD_type,
   FLD_vldst_size,
+  FLD_off3,
+  FLD_off2,
+  FLD_ZAn_1,
+  FLD_ol,
+  FLD_ZAn_2,
+  FLD_ZAn_3,
+  FLD_ZAn
 };
 
 /* Field description.  */
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index e3ad32f5a1e070fe1cc464e1c0df2b0f4347f45f..cf76871930f9f4e8613a977efb81464dce3d8ba7 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -400,6 +400,16 @@ const aarch64_field fields[] =
     { 22,  1 }, /* sz: 1-bit element size select.  */
     { 22,  2 },	/* type: floating point type field in fp data inst.  */
     { 10,  2 },	/* vldst_size: size field in the AdvSIMD load/store inst.  */
+    {  5,  3 }, /* off3: immediate offset used to calculate slice number in a
+		   ZA tile.  */
+    {  5,  2 }, /* off2: immediate offset used to calculate slice number in
+		   a ZA tile.  */
+    {  7,  1 }, /* ZAn_1: name of the 1bit encoded ZA tile.  */
+    {  5,  1 }, /* ol: immediate offset used to calculate slice number in a ZA
+		   tile.  */
+    {  6,  2 }, /* ZAn_2: name of the 2bit encoded ZA tile.  */
+    {  5,  3 }, /* ZAn_3: name of the 3bit encoded ZA tile.  */
+    {  6,  1 }, /* ZAn: name of the bit encoded ZA tile.  */
 };
 
 enum aarch64_operand_class
@@ -1938,6 +1948,49 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	    return 0;
 	  break;
 
+	case AARCH64_OPND_SME_ZA_array_vrsb_1:
+	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 7, 2,
+				get_opcode_dependent_value (opcode)))
+	    return 0;
+	  break;
+
+	case AARCH64_OPND_SME_ZA_array_vrsh_1:
+	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 2,
+				get_opcode_dependent_value (opcode)))
+	    return 0;
+	  break;
+
+	case AARCH64_OPND_SME_ZA_array_vrss_1:
+	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 2,
+				get_opcode_dependent_value (opcode)))
+	    return 0;
+	  break;
+
+	case AARCH64_OPND_SME_ZA_array_vrsd_1:
+	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 2,
+				get_opcode_dependent_value (opcode)))
+	    return 0;
+	  break;
+
+	case AARCH64_OPND_SME_ZA_array_vrsb_2:
+	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 4,
+				get_opcode_dependent_value (opcode)))
+	    return 0;
+	  break;
+
+	case AARCH64_OPND_SME_ZA_array_vrsh_2:
+	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 4,
+				get_opcode_dependent_value (opcode)))
+	    return 0;
+	  break;
+
+	case AARCH64_OPND_SME_ZA_array_vrss_2:
+	case AARCH64_OPND_SME_ZA_array_vrsd_2:
+	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 4,
+				get_opcode_dependent_value (opcode)))
+	    return 0;
+	  break;
+
 	case AARCH64_OPND_SME_ZA_HV_idx_srcxN:
 	case AARCH64_OPND_SME_ZA_HV_idx_destxN:
 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
@@ -4103,6 +4156,30 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 		? style_sub_mnem (styler, "vgx4") : "");
       break;
 
+    case AARCH64_OPND_SME_ZA_array_vrsb_1:
+    case AARCH64_OPND_SME_ZA_array_vrsh_1:
+    case AARCH64_OPND_SME_ZA_array_vrss_1:
+    case AARCH64_OPND_SME_ZA_array_vrsd_1:
+    case AARCH64_OPND_SME_ZA_array_vrsb_2:
+    case AARCH64_OPND_SME_ZA_array_vrsh_2:
+    case AARCH64_OPND_SME_ZA_array_vrss_2:
+    case AARCH64_OPND_SME_ZA_array_vrsd_2:
+      snprintf (buf, size, "%s [%s, %s%s%s]",
+		style_reg (styler, "za%d%c%s%s",
+			   opnd->indexed_za.regno,
+			   opnd->indexed_za.v ? 'v': 'h',
+			   opnd->qualifier == AARCH64_OPND_QLF_NIL ? "" : ".",
+			   (opnd->qualifier == AARCH64_OPND_QLF_NIL
+			    ? ""
+			    : aarch64_get_qualifier_name (opnd->qualifier))),
+		style_reg (styler, "w%d", opnd->indexed_za.index.regno),
+		style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
+		opnd->indexed_za.index.countm1 ? ":" : "",
+		opnd->indexed_za.index.countm1  ? style_imm (styler, "%d",
+		opnd->indexed_za.index.imm
+		+ opnd->indexed_za.index.countm1):"");
+      break;
+
     case AARCH64_OPND_SME_SM_ZA:
       snprintf (buf, size, "%s",
 		style_reg (styler, opnd->reg.regno == 's' ? "sm" : "za"));
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index a8ccdafd044efd62d11ba1e4c199792f6dd44559..9c7648b0a6df5444cc89f52aef3d455e624eedbb 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -1497,6 +1497,10 @@
 {                                                       \
   QLF2(S_B,S_B),                                        \
 }
+#define OP_SVE_HH					\
+{							\
+  QLF2(S_H,S_H),					\
+}
 #define OP_SVE_BBU                                      \
 {                                                       \
   QLF3(S_B,S_B,NIL),                                \
@@ -2614,6 +2618,8 @@ static const aarch64_feature_set aarch64_feature_d128_the =
   AARCH64_FEATURES (2, D128, THE);
 static const aarch64_feature_set aarch64_feature_b16b16 =
   AARCH64_FEATURE (B16B16);
+static const aarch64_feature_set aarch64_feature_sme2p1 =
+  AARCH64_FEATURE (SME2p1);
 
 #define CORE		&aarch64_feature_v8
 #define FP		&aarch64_feature_fp
@@ -2677,6 +2683,7 @@ static const aarch64_feature_set aarch64_feature_b16b16 =
 #define THE	  &aarch64_feature_the
 #define D128_THE  &aarch64_feature_d128_the
 #define B16B16  &aarch64_feature_b16b16
+#define SME2p1  &aarch64_feature_sme2p1
 
 #define CORE_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
   { NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS, 0, 0, NULL }
@@ -2743,6 +2750,9 @@ static const aarch64_feature_set aarch64_feature_b16b16 =
 #define SVE2_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS,TIED) \
   { NAME, OPCODE, MASK, CLASS, OP, SVE2, OPS, QUALS, \
     FLAGS | F_STRICT, 0, TIED, NULL }
+#define SME2p1_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS,TIED) \
+  { NAME, OPCODE, MASK, CLASS, OP, SME2p1, OPS, QUALS, \
+    FLAGS | F_STRICT, 0, TIED, NULL }
 #define SVE2_INSNC(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS,CONSTRAINTS,TIED) \
   { NAME, OPCODE, MASK, CLASS, OP, SVE2, OPS, QUALS, \
     FLAGS | F_STRICT, CONSTRAINTS, TIED, NULL }
@@ -6289,6 +6299,16 @@ const struct aarch64_opcode aarch64_opcode_table[] =
   B16B16_INSN("bfmls", 0x64200c00, 0xffa0fc00, sve_misc, 0, OP3 (SVE_Zd, SVE_Zn, SVE_Zm3_11_INDEX), OP_SVE_VVV_H, 0, 0),
   B16B16_INSN("bfmul", 0x64202800, 0xffa0fc00, sve_misc, 0, OP3 (SVE_Zd, SVE_Zn, SVE_Zm3_11_INDEX), OP_SVE_VVV_H, 0, 0),
 
+/* SME2.1 movaz instructions.  */
+  SME2p1_INSN ("movaz", 0xc0060600, 0xffff1f83, sme2_movaz, 0, OP2 (SME_Zdnx4, SME_ZA_array_vrsb_2), OP_SVE_BB, 0, 0),
+  SME2p1_INSN ("movaz", 0xc0460600, 0xffff1f83, sme2_movaz, 0, OP2 (SME_Zdnx4, SME_ZA_array_vrsh_2), OP_SVE_HH, 0, 0),
+  SME2p1_INSN ("movaz", 0xc0860600, 0xffff1f83, sme2_movaz, 0, OP2 (SME_Zdnx4, SME_ZA_array_vrss_2), OP_SVE_SS, 0, 0),
+  SME2p1_INSN ("movaz", 0xc0c60600, 0xffff1f03, sme2_movaz, 0, OP2 (SME_Zdnx4, SME_ZA_array_vrsd_2), OP_SVE_DD, 0, 0),
+
+  SME2p1_INSN ("movaz", 0xc0060200, 0xffff1f01, sme2_movaz, 0, OP2 (SME_Zdnx2, SME_ZA_array_vrsb_1), OP_SVE_BB, 0, 0),
+  SME2p1_INSN ("movaz", 0xc0460200, 0xffff1f01, sme2_movaz, 0, OP2 (SME_Zdnx2, SME_ZA_array_vrsh_1), OP_SVE_HH, 0, 0),
+  SME2p1_INSN ("movaz", 0xc0860200, 0xffff1f01, sme2_movaz, 0, OP2 (SME_Zdnx2, SME_ZA_array_vrss_1), OP_SVE_SS, 0, 0),
+  SME2p1_INSN ("movaz", 0xc0c60200, 0xffff1f01, sme2_movaz, 0, OP2 (SME_Zdnx2, SME_ZA_array_vrsd_1), OP_SVE_DD, 0, 0),
   {0, 0, 0, 0, 0, 0, {}, {}, 0, 0, 0, NULL},
 };
 
@@ -6726,6 +6746,22 @@ const struct aarch64_opcode aarch64_opcode_table[] =
     Y(SIMD_REG, regno, "SVE_Vd", 0, F(FLD_SVE_Vd), "a SIMD register")	\
     Y(SIMD_REG, regno, "SVE_Vm", 0, F(FLD_SVE_Vm), "a SIMD register")	\
     Y(SIMD_REG, regno, "SVE_Vn", 0, F(FLD_SVE_Vn), "a SIMD register")	\
+    Y(ZA_ACCESS, sme_za_vrs1, "SME_ZA_array_vrsb_1", 0,			\
+      F(FLD_SME_V,FLD_SME_Rv,FLD_off3), "ZA0 tile")			\
+    Y(ZA_ACCESS, sme_za_vrs1, "SME_ZA_array_vrsh_1", 0,			\
+      F(FLD_SME_V,FLD_SME_Rv,FLD_ZAn_1,FLD_off2), "1 bit ZA tile")	\
+    Y(ZA_ACCESS, sme_za_vrs1, "SME_ZA_array_vrss_1", 0,			\
+      F(FLD_SME_V,FLD_SME_Rv,FLD_ZAn_2,FLD_ol), "2 ZA tile")		\
+    Y(ZA_ACCESS, sme_za_vrs1, "SME_ZA_array_vrsd_1", 0,			\
+      F(FLD_SME_V,FLD_SME_Rv,FLD_ZAn_3), "3 ZA tile")			\
+    Y(ZA_ACCESS, sme_za_vrs2, "SME_ZA_array_vrsb_2", 0,			\
+      F(FLD_SME_V,FLD_SME_Rv,FLD_off2), "ZA0 tile")			\
+    Y(ZA_ACCESS, sme_za_vrs2, "SME_ZA_array_vrsh_2", 0,			\
+      F(FLD_SME_V,FLD_SME_Rv,FLD_ZAn,FLD_ol), "1 bit ZA tile")		\
+    Y(ZA_ACCESS, sme_za_vrs2, "SME_ZA_array_vrss_2", 0,			\
+      F(FLD_SME_V,FLD_SME_Rv,FLD_off2), "2 bit ZA tile")		\
+    Y(ZA_ACCESS, sme_za_vrs2, "SME_ZA_array_vrsd_2", 0,			\
+      F(FLD_SME_V,FLD_SME_Rv,FLD_ZAn_3), "3 bit ZA tile")		\
     Y(SVE_REG, regno, "SVE_Za_5", 0, F(FLD_SVE_Za_5),			\
       "an SVE vector register")						\
     Y(SVE_REG, regno, "SVE_Za_16", 0, F(FLD_SVE_Za_16),			\

  reply	other threads:[~2024-01-15  9:34 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-15  9:28 [PATCH 1/6] [Binutils] aarch64: Add support for FEAT_B16B16 instructions Srinath Parvathaneni
2024-01-15  9:34 ` Srinath Parvathaneni [this message]
2024-01-15  9:35   ` [PATCH 3/6][Binutils] aarch64: Add support for FEAT_SVE2p1 Srinath Parvathaneni
2024-01-15  9:37 ` [PATCH 4/6][Binutils] aarch64: Add SVE2.1 dupq, eorqv and extq instructions Srinath Parvathaneni
2024-01-15  9:38 ` PATCH 5/6][Binutils] aarch64: Add SVE2.1 fmin and fmax instructions Srinath Parvathaneni
2024-01-15  9:40 ` [PATCH 6/6][Binutils] aarch64: Add SVE2.1 Contiguous load/store instructions Srinath Parvathaneni
2024-01-15 11:46 ` [PATCH 1/6] [Binutils] aarch64: Add support for FEAT_B16B16 instructions Nick Clifton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fdb8e035-e762-45f0-a694-51733859ca7f@arm.com \
    --to=srinath.parvathaneni@arm.com \
    --cc=binutils@sourceware.org \
    --cc=nickc@redhat.com \
    --cc=richard.earnshaw@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).