aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/config/tc-aarch64.c219
-rw-r--r--gas/testsuite/gas/aarch64/sme-2-illegal.d3
-rw-r--r--gas/testsuite/gas/aarch64/sme-2-illegal.l27
-rw-r--r--gas/testsuite/gas/aarch64/sme-2-illegal.s32
-rw-r--r--gas/testsuite/gas/aarch64/sme-2.d43
-rw-r--r--gas/testsuite/gas/aarch64/sme-2.s52
-rw-r--r--gas/testsuite/gas/aarch64/sme-2a.d29
-rw-r--r--gas/testsuite/gas/aarch64/sme-2a.s26
-rw-r--r--gas/testsuite/gas/aarch64/sme-3-illegal.d3
-rw-r--r--gas/testsuite/gas/aarch64/sme-3-illegal.l11
-rw-r--r--gas/testsuite/gas/aarch64/sme-3-illegal.s14
-rw-r--r--gas/testsuite/gas/aarch64/sme-3.d31
-rw-r--r--gas/testsuite/gas/aarch64/sme-3.s31
-rw-r--r--gas/testsuite/gas/aarch64/sme-3a.d29
-rw-r--r--gas/testsuite/gas/aarch64/sme-3a.s26
15 files changed, 575 insertions, 1 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 7c94e9b..ce76128 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -99,6 +99,17 @@ enum vector_el_type
NT_merge
};
+/* SME horizontal or vertical slice indicator, encoded in "V".
+ Values:
+ 0 - Horizontal
+ 1 - vertical
+*/
+enum sme_hv_slice
+{
+ HV_horizontal = 0,
+ HV_vertical = 1
+};
+
/* Bits for DEFINED field in vector_type_el. */
#define NTA_HASTYPE 1
#define NTA_HASINDEX 2
@@ -279,6 +290,8 @@ struct reloc_entry
BASIC_REG_TYPE(ZN) /* z[0-31] */ \
BASIC_REG_TYPE(PN) /* p[0-15] */ \
BASIC_REG_TYPE(ZA) /* za[0-15] */ \
+ BASIC_REG_TYPE(ZAH) /* za[0-15]h */ \
+ BASIC_REG_TYPE(ZAV) /* za[0-15]v */ \
/* Typecheck: any 64-bit int reg (inc SP exc XZR). */ \
MULTI_REG_TYPE(R64_SP, REG_TYPE(R_64) | REG_TYPE(SP_64)) \
/* Typecheck: same, plus SVE registers. */ \
@@ -4276,6 +4289,178 @@ parse_sme_zada_operand (char **str, aarch64_opnd_qualifier_t *qualifier)
return regno;
}
+/* Parse STR for unsigned, immediate (1-2 digits) in format:
+
+ #<imm>
+ <imm>
+
+ Function return TRUE if immediate was found, or FALSE.
+*/
+static bool
+parse_sme_immediate (char **str, int64_t *imm)
+{
+ int64_t val;
+ if (! parse_constant_immediate (str, &val, REG_TYPE_R_N))
+ return false;
+
+ *imm = val;
+ return true;
+}
+
+/* Parse index with vector select register and immediate:
+
+ [<Wv>, <imm>]
+ [<Wv>, #<imm>]
+ where <Wv> is in W12-W15 range and # is optional for immediate.
+
+ Function performs extra check for mandatory immediate value if REQUIRE_IMM
+ is set to true.
+
+ On success function returns TRUE and populated VECTOR_SELECT_REGISTER and
+ IMM output.
+*/
+static bool
+parse_sme_za_hv_tiles_operand_index (char **str,
+ int *vector_select_register,
+ int64_t *imm)
+{
+ const reg_entry *reg;
+
+ if (!skip_past_char (str, '['))
+ {
+ set_syntax_error (_("expected '['"));
+ return false;
+ }
+
+ /* Vector select register W12-W15 encoded in the 2-bit Rv field. */
+ reg = parse_reg (str);
+ if (reg == NULL || reg->type != REG_TYPE_R_32
+ || reg->number < 12 || reg->number > 15)
+ {
+ set_syntax_error (_("expected vector select register W12-W15"));
+ return false;
+ }
+ *vector_select_register = reg->number;
+
+ if (!skip_past_char (str, ',')) /* Optional index offset immediate. */
+ {
+ set_syntax_error (_("expected ','"));
+ return false;
+ }
+
+ if (!parse_sme_immediate (str, imm))
+ {
+ set_syntax_error (_("index offset immediate expected"));
+ return false;
+ }
+
+ if (!skip_past_char (str, ']'))
+ {
+ set_syntax_error (_("expected ']'"));
+ return false;
+ }
+
+ return true;
+}
+
+/* Parse SME ZA horizontal or vertical vector access to tiles.
+ Function extracts from STR to SLICE_INDICATOR <HV> horizontal (0) or
+ vertical (1) ZA tile vector orientation. VECTOR_SELECT_REGISTER
+ contains <Wv> select register and corresponding optional IMMEDIATE.
+ In addition QUALIFIER is extracted.
+
+ Field format examples:
+
+ ZA0<HV>.B[<Wv>, #<imm>]
+ <ZAn><HV>.H[<Wv>, #<imm>]
+ <ZAn><HV>.S[<Wv>, #<imm>]
+ <ZAn><HV>.D[<Wv>, #<imm>]
+ <ZAn><HV>.Q[<Wv>, #<imm>]
+
+ Function returns <ZAda> register number or PARSE_FAIL.
+*/
+static int
+parse_sme_za_hv_tiles_operand (char **str,
+ enum sme_hv_slice *slice_indicator,
+ int *vector_select_register,
+ int *imm,
+ aarch64_opnd_qualifier_t *qualifier)
+{
+ char *qh, *qv;
+ int regno;
+ int regno_limit;
+ int64_t imm_limit;
+ int64_t imm_value;
+ const reg_entry *reg;
+
+ qh = qv = *str;
+ if ((reg = parse_reg_with_qual (&qh, REG_TYPE_ZAH, qualifier)) != NULL)
+ {
+ *slice_indicator = HV_horizontal;
+ *str = qh;
+ }
+ else if ((reg = parse_reg_with_qual (&qv, REG_TYPE_ZAV, qualifier)) != NULL)
+ {
+ *slice_indicator = HV_vertical;
+ *str = qv;
+ }
+ else
+ return PARSE_FAIL;
+ regno = reg->number;
+
+ switch (*qualifier)
+ {
+ case AARCH64_OPND_QLF_S_B:
+ regno_limit = 0;
+ imm_limit = 15;
+ break;
+ case AARCH64_OPND_QLF_S_H:
+ regno_limit = 1;
+ imm_limit = 7;
+ break;
+ case AARCH64_OPND_QLF_S_S:
+ regno_limit = 3;
+ imm_limit = 3;
+ break;
+ case AARCH64_OPND_QLF_S_D:
+ regno_limit = 7;
+ imm_limit = 1;
+ break;
+ case AARCH64_OPND_QLF_S_Q:
+ regno_limit = 15;
+ imm_limit = 0;
+ break;
+ default:
+ set_syntax_error (_("invalid ZA tile element size, allowed b, h, s, d and q"));
+ return PARSE_FAIL;
+ }
+
+ /* Check if destination register ZA tile vector is in range for given
+ instruction variant. */
+ if (regno < 0 || regno > regno_limit)
+ {
+ set_syntax_error (_("ZA tile vector out of range"));
+ return PARSE_FAIL;
+ }
+
+ if (!parse_sme_za_hv_tiles_operand_index (str, vector_select_register,
+ &imm_value))
+ return PARSE_FAIL;
+
+ /* Check if optional index offset is in the range for instruction
+ variant. */
+ if (imm_value < 0 || imm_value > imm_limit)
+ {
+ set_syntax_error (_("index offset out of range"));
+ return PARSE_FAIL;
+ }
+
+ *imm = imm_value;
+
+ return regno;
+}
+
+
/* Parse a system register or a PSTATE field name for an MSR/MRS instruction.
Returns the encoding for the option, or PARSE_FAIL.
@@ -6989,6 +7174,26 @@ parse_operands (char *str, const aarch64_opcode *opcode)
info->qualifier = qualifier;
break;
+ case AARCH64_OPND_SME_ZA_HV_idx_src:
+ case AARCH64_OPND_SME_ZA_HV_idx_dest:
+ {
+ enum sme_hv_slice vector_indicator;
+ int vector_select_register;
+ int imm;
+ val = parse_sme_za_hv_tiles_operand (&str, &vector_indicator,
+ &vector_select_register,
+ &imm,
+ &qualifier);
+ if (val == PARSE_FAIL)
+ goto failure;
+ info->za_tile_vector.regno = val;
+ info->za_tile_vector.index.regno = vector_select_register;
+ info->za_tile_vector.index.imm = imm;
+ info->za_tile_vector.v = vector_indicator;
+ info->qualifier = qualifier;
+ break;
+ }
+
default:
as_fatal (_("unhandled operand code %d"), operands[i]);
}
@@ -7533,11 +7738,17 @@ aarch64_canonicalize_symbol_name (char *name)
#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, true }
#define REGDEF_ALIAS(s, n, t) { #s, n, REG_TYPE_##t, false}
#define REGNUM(p,n,t) REGDEF(p##n, n, t)
+#define REGNUMS(p,n,s,t) REGDEF(p##n##s, n, t)
#define REGSET16(p,t) \
REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
+#define REGSET16S(p,s,t) \
+ REGNUMS(p, 0,s,t), REGNUMS(p, 1,s,t), REGNUMS(p, 2,s,t), REGNUMS(p, 3,s,t), \
+ REGNUMS(p, 4,s,t), REGNUMS(p, 5,s,t), REGNUMS(p, 6,s,t), REGNUMS(p, 7,s,t), \
+ REGNUMS(p, 8,s,t), REGNUMS(p, 9,s,t), REGNUMS(p,10,s,t), REGNUMS(p,11,s,t), \
+ REGNUMS(p,12,s,t), REGNUMS(p,13,s,t), REGNUMS(p,14,s,t), REGNUMS(p,15,s,t)
#define REGSET31(p,t) \
REGSET16(p, t), \
REGNUM(p,16,t), REGNUM(p,17,t), REGNUM(p,18,t), REGNUM(p,19,t), \
@@ -7588,7 +7799,13 @@ static const reg_entry reg_names[] = {
REGSET16 (p, PN), REGSET16 (P, PN),
/* SME ZA tile registers. */
- REGSET16 (za, ZA), REGSET16 (ZA, ZA)
+ REGSET16 (za, ZA), REGSET16 (ZA, ZA),
+
+ /* SME ZA tile registers (horizontal slice). */
+ REGSET16S (za, h, ZAH), REGSET16S (ZA, H, ZAH),
+
+ /* SME ZA tile registers (vertical slice). */
+ REGSET16S (za, v, ZAV), REGSET16S (ZA, V, ZAV)
};
#undef REGDEF
diff --git a/gas/testsuite/gas/aarch64/sme-2-illegal.d b/gas/testsuite/gas/aarch64/sme-2-illegal.d
new file mode 100644
index 0000000..0ff10535
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-2-illegal.d
@@ -0,0 +1,3 @@
+#as: -march=armv8-a+sme
+#source: sme-2-illegal.s
+#error_output: sme-2-illegal.l
diff --git a/gas/testsuite/gas/aarch64/sme-2-illegal.l b/gas/testsuite/gas/aarch64/sme-2-illegal.l
new file mode 100644
index 0000000..d364561
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-2-illegal.l
@@ -0,0 +1,27 @@
+[^:]*: Assembler messages:
+[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 3 -- `mova z0\.b,p0/m,za1h\.b\[w12,#0\]'
+[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 3 -- `mova z0\.h,p0/m,za2h\.h\[w12,#0\]'
+[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 3 -- `mova z0\.s,p0/m,za4h\.s\[w12,#0\]'
+[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 3 -- `mova z0\.d,p0/m,za8h\.d\[w12,#0\]'
+[^:]*:[0-9]+: Error: operand 3 must be an SME horizontal or vertical vector access register -- `mova z0\.q,p0/m,za16h.q\[w12\]'
+[^:]*:[0-9]+: Error: index offset out of range at operand 3 -- `mova z31\.b,p7/m,za0v\.b\[w15,#16\]'
+[^:]*:[0-9]+: Error: index offset out of range at operand 3 -- `mova z31\.h,p7/m,za1v\.h\[w15,#8\]'
+[^:]*:[0-9]+: Error: index offset out of range at operand 3 -- `mova z31\.s,p7/m,za3v\.s\[w15,#4\]'
+[^:]*:[0-9]+: Error: index offset out of range at operand 3 -- `mova z31\.d,p7/m,za7v\.d\[w15,#2\]'
+[^:]*:[0-9]+: Error: index offset out of range at operand 3 -- `mova z31\.q,p7/m,za15v\.q\[w15,#1\]'
+[^:]*:[0-9]+: Error: expected ',' at operand 3 -- `mova z31\.q,p7/m,za15v\.q\[w15\]'
+[^:]*:[0-9]+: Error: expected '\[' at operand 3 -- `mova z0\.b,p0/m,za0v.b'
+[^:]*:[0-9]+: Error: expected vector select register W12-W15 at operand 3 -- `mova z31\.b,p7/m,za0v\.b\[15,w15\]'
+[^:]*:[0-9]+: Error: expected ',' at operand 3 -- `mova z0\.h,p0/m,za0v\.h\[w12\. 0\]'
+[^:]*:[0-9]+: Error: expected vector select register W12-W15 at operand 3 -- `mova z0\.s,p0/m,za0v\.s\[x12,0]'
+[^:]*:[0-9]+: Error: expected vector select register W12-W15 at operand 3 -- `mova z0\.d,p0/m,za0v\.d\[w21,0\]'
+[^:]*:[0-9]+: Error: expected vector select register W12-W15 at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[s12\]'
+[^:]*:[0-9]+: Error: expected vector select register W12-W15 at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[d12\]'
+[^:]*:[0-9]+: Error: index offset immediate expected at operand 3 -- `mova z0.q,p0/m,za0v\.q\[w12,\]'
+[^:]*:[0-9]+: Error: expected ',' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12\.\]'
+[^:]*:[0-9]+: Error: index offset immediate expected at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,abc\]'
+[^:]*:[0-9]+: Error: index offset immediate expected at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,#abc\]'
+[^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,1a\]'
+[^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,#1a\]'
+[^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,1a2\]'
+[^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,#1a2\]'
diff --git a/gas/testsuite/gas/aarch64/sme-2-illegal.s b/gas/testsuite/gas/aarch64/sme-2-illegal.s
new file mode 100644
index 0000000..28eb671
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-2-illegal.s
@@ -0,0 +1,32 @@
+/* Scalable Matrix Extension (SME). */
+
+/* MOVA (tile to vector) variant. */
+mova z0.b, p0/m, za1h.b[w12, #0]
+mova z0.h, p0/m, za2h.h[w12, #0]
+mova z0.s, p0/m, za4h.s[w12, #0]
+mova z0.d, p0/m, za8h.d[w12, #0]
+mova z0.q, p0/m, za16h.q[w12]
+
+mova z31.b, p7/m, za0v.b[w15, #16]
+mova z31.h, p7/m, za1v.h[w15, #8]
+mova z31.s, p7/m, za3v.s[w15, #4]
+mova z31.d, p7/m, za7v.d[w15, #2]
+mova z31.q, p7/m, za15v.q[w15, #1]
+mova z31.q, p7/m, za15v.q[w15]
+
+/* Syntax issues. */
+mova z0.b, p0/m, za0v.b
+mova z31.b, p7/m, za0v.b[15, w15]
+mova z0.h, p0/m, za0v.h[w12. 0]
+mova z0.s, p0/m, za0v.s[x12, 0]
+mova z0.d, p0/m, za0v.d[w21, 0]
+mova z0.q, p0/m, za0v.q[s12]
+mova z0.q, p0/m, za0v.q[d12]
+mova z0.q, p0/m, za0v.q[w12,]
+mova z0.q, p0/m, za0v.q[w12.]
+mova z0.q, p0/m, za0v.q[w12, abc]
+mova z0.q, p0/m, za0v.q[w12, #abc]
+mova z0.q, p0/m, za0v.q[w12, 1a]
+mova z0.q, p0/m, za0v.q[w12, #1a]
+mova z0.q, p0/m, za0v.q[w12, 1a2]
+mova z0.q, p0/m, za0v.q[w12, #1a2]
diff --git a/gas/testsuite/gas/aarch64/sme-2.d b/gas/testsuite/gas/aarch64/sme-2.d
new file mode 100644
index 0000000..2764aac
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-2.d
@@ -0,0 +1,43 @@
+#name: SME extension, MOVA (tile to vector)
+#as: -march=armv8-a+sme
+#objdump: -dr
+
+.*: file format .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+ 0: c0028000 mov z0.b, p0/m, za0v.b\[w12, 0\]
+ 4: c0428000 mov z0.h, p0/m, za0v.h\[w12, 0\]
+ 8: c0828000 mov z0.s, p0/m, za0v.s\[w12, 0\]
+ c: c0c28000 mov z0.d, p0/m, za0v.d\[w12, 0\]
+ 10: c0c38000 mov z0.q, p0/m, za0v.q\[w12, 0\]
+ 14: c002fdff mov z31.b, p7/m, za0v.b\[w15, 15\]
+ 18: c042fdff mov z31.h, p7/m, za1v.h\[w15, 7\]
+ 1c: c082fdff mov z31.s, p7/m, za3v.s\[w15, 3\]
+ 20: c0c2fdff mov z31.d, p7/m, za7v.d\[w15, 1\]
+ 24: c0c3fdff mov z31.q, p7/m, za15v.q\[w15, 0\]
+ 28: c0020000 mov z0.b, p0/m, za0h.b\[w12, 0\]
+ 2c: c0420000 mov z0.h, p0/m, za0h.h\[w12, 0\]
+ 30: c0820000 mov z0.s, p0/m, za0h.s\[w12, 0\]
+ 34: c0c20000 mov z0.d, p0/m, za0h.d\[w12, 0\]
+ 38: c0c30000 mov z0.q, p0/m, za0h.q\[w12, 0\]
+ 3c: c0027dff mov z31.b, p7/m, za0h.b\[w15, 15\]
+ 40: c0427dff mov z31.h, p7/m, za1h.h\[w15, 7\]
+ 44: c0827dff mov z31.s, p7/m, za3h.s\[w15, 3\]
+ 48: c0c27dff mov z31.d, p7/m, za7h.d\[w15, 1\]
+ 4c: c0c37dff mov z31.q, p7/m, za15h.q\[w15, 0\]
+ 50: c0027dff mov z31.b, p7/m, za0h.b\[w15, 15\]
+ 54: c0427dff mov z31.h, p7/m, za1h.h\[w15, 7\]
+ 58: c0827dff mov z31.s, p7/m, za3h.s\[w15, 3\]
+ 5c: c0c27dff mov z31.d, p7/m, za7h.d\[w15, 1\]
+ 60: c0c37dff mov z31.q, p7/m, za15h.q\[w15, 0\]
+ 64: c0027dff mov z31.b, p7/m, za0h.b\[w15, 15\]
+ 68: c0427dff mov z31.h, p7/m, za1h.h\[w15, 7\]
+ 6c: c0827dff mov z31.s, p7/m, za3h.s\[w15, 3\]
+ 70: c0c27dff mov z31.d, p7/m, za7h.d\[w15, 1\]
+ 74: c0c37dff mov z31.q, p7/m, za15h.q\[w15, 0\]
+ 78: c0c27dff mov z31.d, p7/m, za7h.d\[w15, 1\]
+ 7c: c0c37dff mov z31.q, p7/m, za15h.q\[w15, 0\]
+ 80: c002a400 mov z0.b, p1/m, za0v.b\[w13, 0\]
+ 84: c002a4e0 mov z0.b, p1/m, za0v.b\[w13, 7\]
diff --git a/gas/testsuite/gas/aarch64/sme-2.s b/gas/testsuite/gas/aarch64/sme-2.s
new file mode 100644
index 0000000..a2d0f0a
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-2.s
@@ -0,0 +1,52 @@
+/* Scalable Matrix Extension (SME). */
+
+/* MOVA (tile to vector) variant. */
+mova z0.b, p0/m, za0v.b[w12, 0]
+mova z0.h, p0/m, za0v.h[w12, 0]
+mova z0.s, p0/m, za0v.s[w12, 0]
+mova z0.d, p0/m, za0v.d[w12, 0]
+mova z0.q, p0/m, za0v.q[w12, 0]
+
+mova z31.b, p7/m, za0v.b[w15, 15]
+mova z31.h, p7/m, za1v.h[w15, 7]
+mova z31.s, p7/m, za3v.s[w15, 3]
+mova z31.d, p7/m, za7v.d[w15, 1]
+mova z31.q, p7/m, za15v.q[w15, 0]
+
+mova z0.b, p0/m, za0h.b[w12, 0]
+mova z0.h, p0/m, za0h.h[w12, 0]
+mova z0.s, p0/m, za0h.s[w12, 0]
+mova z0.d, p0/m, za0h.d[w12, 0]
+mova z0.q, p0/m, za0h.q[w12, 0]
+
+mova z31.b, p7/m, za0h.b[w15, 15]
+mova z31.h, p7/m, za1h.h[w15, 7]
+mova z31.s, p7/m, za3h.s[w15, 3]
+mova z31.d, p7/m, za7h.d[w15, 1]
+mova z31.q, p7/m, za15h.q[w15, 0]
+
+/* Parser checks. */
+mova z31.b , p7/m , za0h.b [ w15 , 15 ]
+mova z31.h , p7/m , za1h.h [ w15 , 7 ]
+mova z31.s , p7/m , za3h.s [ w15 , 3 ]
+mova z31.d , p7/m , za7h.d [ w15 , 1 ]
+mova z31.q , p7/m , za15h.q [ w15 , #0 ]
+mova z31.b , p7/m , za0h.b [ w15 , #15 ]
+mova z31.h , p7/m , za1h.h [ w15 , #7 ]
+mova z31.s , p7/m , za3h.s [ w15 , #3 ]
+mova z31.d , p7/m , za7h.d [ w15 , #1 ]
+mova z31.q , p7/m , za15h.q [ w15, #0 ]
+
+/* Register aliases. */
+foo .req w15
+bar .req za7h
+baz .req z31
+
+mova z31.d , p7/m , bar.d [ foo , #1 ]
+mova baz.q , p7/m , za15h.q [ foo , #0 ]
+
+/* Named immediate. */
+val_zero = 0
+val_seven = 7
+mova z0.b, p1/m, za0v.b[w13, #val_zero]
+mova z0.b, p1/m, za0v.b[w13, #val_seven]
diff --git a/gas/testsuite/gas/aarch64/sme-2a.d b/gas/testsuite/gas/aarch64/sme-2a.d
new file mode 100644
index 0000000..9515e3f
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-2a.d
@@ -0,0 +1,29 @@
+#name: SME extension, MOV (tile to vector)
+#as: -march=armv8-a+sme
+#objdump: -dr
+
+.*: file format .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+ 0: c0028000 mov z0\.b, p0/m, za0v\.b\[w12, 0\]
+ 4: c0428000 mov z0\.h, p0/m, za0v\.h\[w12, 0\]
+ 8: c0828000 mov z0\.s, p0/m, za0v\.s\[w12, 0\]
+ c: c0c28000 mov z0\.d, p0/m, za0v\.d\[w12, 0\]
+ 10: c0c38000 mov z0\.q, p0/m, za0v\.q\[w12, 0\]
+ 14: c002fdff mov z31\.b, p7/m, za0v\.b\[w15, 15\]
+ 18: c042fdff mov z31\.h, p7/m, za1v\.h\[w15, 7\]
+ 1c: c082fdff mov z31\.s, p7/m, za3v\.s\[w15, 3\]
+ 20: c0c2fdff mov z31\.d, p7/m, za7v\.d\[w15, 1\]
+ 24: c0c3fdff mov z31\.q, p7/m, za15v\.q\[w15, 0\]
+ 28: c0020000 mov z0\.b, p0/m, za0h\.b\[w12, 0\]
+ 2c: c0420000 mov z0\.h, p0/m, za0h\.h\[w12, 0\]
+ 30: c0820000 mov z0\.s, p0/m, za0h\.s\[w12, 0\]
+ 34: c0c20000 mov z0\.d, p0/m, za0h\.d\[w12, 0\]
+ 38: c0c30000 mov z0\.q, p0/m, za0h\.q\[w12, 0\]
+ 3c: c0027dff mov z31\.b, p7/m, za0h\.b\[w15, 15\]
+ 40: c0427dff mov z31\.h, p7/m, za1h\.h\[w15, 7\]
+ 44: c0827dff mov z31\.s, p7/m, za3h\.s\[w15, 3\]
+ 48: c0c27dff mov z31\.d, p7/m, za7h\.d\[w15, 1\]
+ 4c: c0c37dff mov z31\.q, p7/m, za15h\.q\[w15, 0\]
diff --git a/gas/testsuite/gas/aarch64/sme-2a.s b/gas/testsuite/gas/aarch64/sme-2a.s
new file mode 100644
index 0000000..4754981
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-2a.s
@@ -0,0 +1,26 @@
+/* Scalable Matrix Extension (SME). */
+
+/* MOV alias (tile to vector) variant. */
+mov z0.b, p0/m, za0v.b[w12, 0]
+mov z0.h, p0/m, za0v.h[w12, 0]
+mov z0.s, p0/m, za0v.s[w12, 0]
+mov z0.d, p0/m, za0v.d[w12, 0]
+mov z0.q, p0/m, za0v.q[w12, 0]
+
+mov z31.b, p7/m, za0v.b[w15, 15]
+mov z31.h, p7/m, za1v.h[w15, 7]
+mov z31.s, p7/m, za3v.s[w15, 3]
+mov z31.d, p7/m, za7v.d[w15, 1]
+mov z31.q, p7/m, za15v.q[w15, 0]
+
+mov z0.b, p0/m, za0h.b[w12, 0]
+mov z0.h, p0/m, za0h.h[w12, 0]
+mov z0.s, p0/m, za0h.s[w12, 0]
+mov z0.d, p0/m, za0h.d[w12, 0]
+mov z0.q, p0/m, za0h.q[w12, 0]
+
+mov z31.b, p7/m, za0h.b[w15, 15]
+mov z31.h, p7/m, za1h.h[w15, 7]
+mov z31.s, p7/m, za3h.s[w15, 3]
+mov z31.d, p7/m, za7h.d[w15, 1]
+mov z31.q, p7/m, za15h.q[w15, 0]
diff --git a/gas/testsuite/gas/aarch64/sme-3-illegal.d b/gas/testsuite/gas/aarch64/sme-3-illegal.d
new file mode 100644
index 0000000..5ee89d3
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-3-illegal.d
@@ -0,0 +1,3 @@
+#as: -march=armv8-a+sme
+#source: sme-3-illegal.s
+#error_output: sme-3-illegal.l
diff --git a/gas/testsuite/gas/aarch64/sme-3-illegal.l b/gas/testsuite/gas/aarch64/sme-3-illegal.l
new file mode 100644
index 0000000..8babf4c
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-3-illegal.l
@@ -0,0 +1,11 @@
+[^:]*: Assembler messages:
+[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 1 -- `mova za1v\.b\[w12,#0\],p0/m,z0.b'
+[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 1 -- `mova za2v\.h\[w12,#0\],p0/m,z0.h'
+[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 1 -- `mova za4v\.s\[w12,#0\],p0/m,z0.s'
+[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 1 -- `mova za8v\.d\[w12,#0\],p0/m,z0.d'
+[^:]*:[0-9]+: Error: operand 1 must be an SME horizontal or vertical vector access register -- `mova za16v\.q\[w12\],p0/m,z0.q'
+[^:]*:[0-9]+: Error: index offset out of range at operand 1 -- `mova za0v\.b\[w15,#16\],p7/m,z31.b'
+[^:]*:[0-9]+: Error: index offset out of range at operand 1 -- `mova za1v\.h\[w15,#8\],p7/m,z31.h'
+[^:]*:[0-9]+: Error: index offset out of range at operand 1 -- `mova za3v\.s\[w15,#4\],p7/m,z31.s'
+[^:]*:[0-9]+: Error: index offset out of range at operand 1 -- `mova za7v\.d\[w15,#2\],p7/m,z31.d'
+[^:]*:[0-9]+: Error: index offset out of range at operand 1 -- `mova za15v\.q\[w15,#1\],p7/m,z31.q'
diff --git a/gas/testsuite/gas/aarch64/sme-3-illegal.s b/gas/testsuite/gas/aarch64/sme-3-illegal.s
new file mode 100644
index 0000000..6ed58ec
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-3-illegal.s
@@ -0,0 +1,14 @@
+/* Scalable Matrix Extension (SME). */
+
+/* MOVA (vector to tile) variant. */
+mova za1v.b[w12, #0], p0/m, z0.b
+mova za2v.h[w12, #0], p0/m, z0.h
+mova za4v.s[w12, #0], p0/m, z0.s
+mova za8v.d[w12, #0], p0/m, z0.d
+mova za16v.q[w12], p0/m, z0.q
+
+mova za0v.b[w15, #16], p7/m, z31.b
+mova za1v.h[w15, #8], p7/m, z31.h
+mova za3v.s[w15, #4], p7/m, z31.s
+mova za7v.d[w15, #2], p7/m, z31.d
+mova za15v.q[w15, #1], p7/m, z31.q
diff --git a/gas/testsuite/gas/aarch64/sme-3.d b/gas/testsuite/gas/aarch64/sme-3.d
new file mode 100644
index 0000000..82f72ac
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-3.d
@@ -0,0 +1,31 @@
+#name: SME extension, MOVA (vector to tile)
+#as: -march=armv8-a+sme
+#objdump: -dr
+
+.*: file format .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+ 0: c0008000 mov za0v\.b\[w12, 0\], p0/m, z0\.b
+ 4: c0408000 mov za0v\.h\[w12, 0\], p0/m, z0\.h
+ 8: c0808000 mov za0v\.s\[w12, 0\], p0/m, z0\.s
+ c: c0c08000 mov za0v\.d\[w12, 0\], p0/m, z0\.d
+ 10: c0c18000 mov za0v\.q\[w12, 0\], p0/m, z0\.q
+ 14: c000ffef mov za0v\.b\[w15, 15\], p7/m, z31\.b
+ 18: c040ffef mov za1v\.h\[w15, 7\], p7/m, z31\.h
+ 1c: c080ffef mov za3v\.s\[w15, 3\], p7/m, z31\.s
+ 20: c0c0ffef mov za7v\.d\[w15, 1\], p7/m, z31\.d
+ 24: c0c1ffef mov za15v\.q\[w15, 0\], p7/m, z31\.q
+ 28: c0000000 mov za0h\.b\[w12, 0\], p0/m, z0\.b
+ 2c: c0400000 mov za0h\.h\[w12, 0\], p0/m, z0\.h
+ 30: c0800000 mov za0h\.s\[w12, 0\], p0/m, z0\.s
+ 34: c0c00000 mov za0h\.d\[w12, 0\], p0/m, z0\.d
+ 38: c0c10000 mov za0h\.q\[w12, 0\], p0/m, z0\.q
+ 3c: c0007fef mov za0h\.b\[w15, 15\], p7/m, z31\.b
+ 40: c0407fef mov za1h\.h\[w15, 7\], p7/m, z31\.h
+ 44: c0807fef mov za3h\.s\[w15, 3\], p7/m, z31\.s
+ 48: c0c07fef mov za7h\.d\[w15, 1\], p7/m, z31\.d
+ 4c: c0c17fef mov za15h\.q\[w15, 0\], p7/m, z31\.q
+ 50: c0008000 mov za0v\.b\[w12, 0\], p0/m, z0\.b
+ 54: c0c17fef mov za15h\.q\[w15, 0\], p7/m, z31\.q
diff --git a/gas/testsuite/gas/aarch64/sme-3.s b/gas/testsuite/gas/aarch64/sme-3.s
new file mode 100644
index 0000000..8efc896
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-3.s
@@ -0,0 +1,31 @@
+/* Scalable Matrix Extension (SME). */
+
+/* MOVA (vector to tile) variant. */
+mova za0v.b[w12, 0], p0/m, z0.b
+mova za0v.h[w12, 0], p0/m, z0.h
+mova za0v.s[w12, 0], p0/m, z0.s
+mova za0v.d[w12, 0], p0/m, z0.d
+mova za0v.q[w12, 0], p0/m, z0.q
+
+mova za0v.b[w15, 15], p7/m, z31.b
+mova za1v.h[w15, 7], p7/m, z31.h
+mova za3v.s[w15, 3], p7/m, z31.s
+mova za7v.d[w15, 1], p7/m, z31.d
+mova za15v.q[w15, 0], p7/m, z31.q
+
+mova za0h.b[w12, 0], p0/m, z0.b
+mova za0h.h[w12, 0], p0/m, z0.h
+mova za0h.s[w12, 0], p0/m, z0.s
+mova za0h.d[w12, 0], p0/m, z0.d
+mova za0h.q[w12, 0], p0/m, z0.q
+
+mova za0h.b[w15, 15], p7/m, z31.b
+mova za1h.h[w15, 7], p7/m, z31.h
+mova za3h.s[w15, 3], p7/m, z31.s
+mova za7h.d[w15, 1], p7/m, z31.d
+mova za15h.q[w15, 0], p7/m, z31.q
+
+foo .req w12
+bar .req w15
+mova za0v.b[foo, 0], p0/m, z0.b
+mova za15h.q[bar, 0], p7/m, z31.q
diff --git a/gas/testsuite/gas/aarch64/sme-3a.d b/gas/testsuite/gas/aarch64/sme-3a.d
new file mode 100644
index 0000000..82835ae
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-3a.d
@@ -0,0 +1,29 @@
+#name: SME extension, MOV (vector to tile)
+#as: -march=armv8-a+sme
+#objdump: -dr
+
+.*: file format .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+ 0: c0008000 mov za0v\.b\[w12, 0\], p0/m, z0\.b
+ 4: c0408000 mov za0v\.h\[w12, 0\], p0/m, z0\.h
+ 8: c0808000 mov za0v\.s\[w12, 0\], p0/m, z0\.s
+ c: c0c08000 mov za0v\.d\[w12, 0\], p0/m, z0\.d
+ 10: c0c18000 mov za0v\.q\[w12, 0\], p0/m, z0\.q
+ 14: c000ffef mov za0v\.b\[w15, 15\], p7/m, z31\.b
+ 18: c040ffef mov za1v\.h\[w15, 7\], p7/m, z31\.h
+ 1c: c080ffef mov za3v\.s\[w15, 3\], p7/m, z31\.s
+ 20: c0c0ffef mov za7v\.d\[w15, 1\], p7/m, z31\.d
+ 24: c0c1ffef mov za15v\.q\[w15, 0\], p7/m, z31\.q
+ 28: c0000000 mov za0h\.b\[w12, 0\], p0/m, z0\.b
+ 2c: c0400000 mov za0h\.h\[w12, 0\], p0/m, z0\.h
+ 30: c0800000 mov za0h\.s\[w12, 0\], p0/m, z0\.s
+ 34: c0c00000 mov za0h\.d\[w12, 0\], p0/m, z0\.d
+ 38: c0c10000 mov za0h\.q\[w12, 0\], p0/m, z0\.q
+ 3c: c0007fef mov za0h\.b\[w15, 15\], p7/m, z31\.b
+ 40: c0407fef mov za1h\.h\[w15, 7\], p7/m, z31\.h
+ 44: c0807fef mov za3h\.s\[w15, 3\], p7/m, z31\.s
+ 48: c0c07fef mov za7h\.d\[w15, 1\], p7/m, z31\.d
+ 4c: c0c17fef mov za15h\.q\[w15, 0\], p7/m, z31\.q
diff --git a/gas/testsuite/gas/aarch64/sme-3a.s b/gas/testsuite/gas/aarch64/sme-3a.s
new file mode 100644
index 0000000..892a30e
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme-3a.s
@@ -0,0 +1,26 @@
+/* Scalable Matrix Extension (SME). */
+
+/* MOV alias (vector to tile) variant. */
+mov za0v.b[w12, 0], p0/m, z0.b
+mov za0v.h[w12, 0], p0/m, z0.h
+mov za0v.s[w12, 0], p0/m, z0.s
+mov za0v.d[w12, 0], p0/m, z0.d
+mov za0v.q[w12, 0], p0/m, z0.q
+
+mov za0v.b[w15, 15], p7/m, z31.b
+mov za1v.h[w15, 7], p7/m, z31.h
+mov za3v.s[w15, 3], p7/m, z31.s
+mov za7v.d[w15, 1], p7/m, z31.d
+mov za15v.q[w15, 0], p7/m, z31.q
+
+mov za0h.b[w12, 0], p0/m, z0.b
+mov za0h.h[w12, 0], p0/m, z0.h
+mov za0h.s[w12, 0], p0/m, z0.s
+mov za0h.d[w12, 0], p0/m, z0.d
+mov za0h.q[w12, 0], p0/m, z0.q
+
+mov za0h.b[w15, 15], p7/m, z31.b
+mov za1h.h[w15, 7], p7/m, z31.h
+mov za3h.s[w15, 3], p7/m, z31.s
+mov za7h.d[w15, 1], p7/m, z31.d
+mov za15h.q[w15, 0], p7/m, z31.q