aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2023-03-30 11:09:16 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2023-03-30 11:09:16 +0100
commit6efa660124f481a5ba415cedd195764ea6ac09fd (patch)
tree5ceb8e36ccb0439e3256688ff9cfb98abb06673d /gas
parentce623e7aa486d1330c9a4529c77a302d2fdcb801 (diff)
downloadbinutils-6efa660124f481a5ba415cedd195764ea6ac09fd.zip
binutils-6efa660124f481a5ba415cedd195764ea6ac09fd.tar.gz
binutils-6efa660124f481a5ba415cedd195764ea6ac09fd.tar.bz2
aarch64: Add the SME2 shift instructions
There are two instruction formats here: - SQRSHR, SQRSHRU and UQRSHR, which operate on lists of two or four registers. - SQRSHRN, SQRSHRUN and UQRSHRN, which operate on lists of four registers. These are the first SME2 instructions to have immediate operands. The patch makes sure that, when parsing SME2 instructions with immediate operands, the new predicate-as-counter registers are parsed as registers rather than as #-less immediates.
Diffstat (limited to 'gas')
-rw-r--r--gas/config/tc-aarch64.c17
-rw-r--r--gas/testsuite/gas/aarch64/sme2-27-invalid.d3
-rw-r--r--gas/testsuite/gas/aarch64/sme2-27-invalid.l31
-rw-r--r--gas/testsuite/gas/aarch64/sme2-27-invalid.s25
-rw-r--r--gas/testsuite/gas/aarch64/sme2-27-noarch.d3
-rw-r--r--gas/testsuite/gas/aarch64/sme2-27-noarch.l50
-rw-r--r--gas/testsuite/gas/aarch64/sme2-27.d62
-rw-r--r--gas/testsuite/gas/aarch64/sme2-27.s71
-rw-r--r--gas/testsuite/gas/aarch64/sme2-28-invalid.d3
-rw-r--r--gas/testsuite/gas/aarch64/sme2-28-invalid.l19
-rw-r--r--gas/testsuite/gas/aarch64/sme2-28-invalid.s11
-rw-r--r--gas/testsuite/gas/aarch64/sme2-28-noarch.d3
-rw-r--r--gas/testsuite/gas/aarch64/sme2-28-noarch.l26
-rw-r--r--gas/testsuite/gas/aarch64/sme2-28.d34
-rw-r--r--gas/testsuite/gas/aarch64/sme2-28.s29
15 files changed, 384 insertions, 3 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 2c8d591..781c87b 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -349,6 +349,13 @@ struct reloc_entry
| REG_TYPE(FP_B) | REG_TYPE(FP_H) \
| REG_TYPE(FP_S) | REG_TYPE(FP_D) | REG_TYPE(FP_Q) \
| REG_TYPE(Z) | REG_TYPE(P)) \
+ /* Likewise, but with predicate-as-counter registers added. */ \
+ MULTI_REG_TYPE(R_ZR_SP_BHSDQ_VZP_PN, REG_TYPE(R_32) | REG_TYPE(R_64) \
+ | REG_TYPE(SP_32) | REG_TYPE(SP_64) \
+ | REG_TYPE(ZR_32) | REG_TYPE(ZR_64) | REG_TYPE(V) \
+ | REG_TYPE(FP_B) | REG_TYPE(FP_H) \
+ | REG_TYPE(FP_S) | REG_TYPE(FP_D) | REG_TYPE(FP_Q) \
+ | REG_TYPE(Z) | REG_TYPE(P) | REG_TYPE(PN)) \
/* Any integer register; used for error messages only. */ \
MULTI_REG_TYPE(R_N, REG_TYPE(R_32) | REG_TYPE(R_64) \
| REG_TYPE(SP_32) | REG_TYPE(SP_64) \
@@ -6527,9 +6534,11 @@ parse_operands (char *str, const aarch64_opcode *opcode)
clear_error ();
skip_whitespace (str);
- if (AARCH64_CPU_HAS_ANY_FEATURES (*opcode->avariant,
- AARCH64_FEATURE_SVE
- | AARCH64_FEATURE_SVE2))
+ if (AARCH64_CPU_HAS_FEATURE (*opcode->avariant, AARCH64_FEATURE_SME2))
+ imm_reg_type = REG_TYPE_R_ZR_SP_BHSDQ_VZP_PN;
+ else if (AARCH64_CPU_HAS_ANY_FEATURES (*opcode->avariant,
+ AARCH64_FEATURE_SVE
+ | AARCH64_FEATURE_SVE2))
imm_reg_type = REG_TYPE_R_ZR_SP_BHSDQ_VZP;
else
imm_reg_type = REG_TYPE_R_ZR_BHSDQ_V;
@@ -6892,6 +6901,8 @@ parse_operands (char *str, const aarch64_opcode *opcode)
case AARCH64_OPND_SVE_SHLIMM_PRED:
case AARCH64_OPND_SVE_SHLIMM_UNPRED:
case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
+ case AARCH64_OPND_SME_SHRIMM4:
+ case AARCH64_OPND_SME_SHRIMM5:
case AARCH64_OPND_SVE_SHRIMM_PRED:
case AARCH64_OPND_SVE_SHRIMM_UNPRED:
case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
diff --git a/gas/testsuite/gas/aarch64/sme2-27-invalid.d b/gas/testsuite/gas/aarch64/sme2-27-invalid.d
new file mode 100644
index 0000000..7b34ec4
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-27-invalid.d
@@ -0,0 +1,3 @@
+#as: -march=armv8-a
+#source: sme2-27-invalid.s
+#error_output: sme2-27-invalid.l
diff --git a/gas/testsuite/gas/aarch64/sme2-27-invalid.l b/gas/testsuite/gas/aarch64/sme2-27-invalid.l
new file mode 100644
index 0000000..9efaa04
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-27-invalid.l
@@ -0,0 +1,31 @@
+[^ :]+: Assembler messages:
+[^ :]+:[0-9]+: Error: expected an SVE vector register at operand 1 -- `sqrshr 0,{z0\.s-z1\.s},#1'
+[^ :]+:[0-9]+: Error: expected '{' at operand 2 -- `sqrshr z0\.h,0,#1'
+[^ :]+:[0-9]+: Error: start register out of range at operand 2 -- `sqrshr z0\.h,{z1\.s-z2\.s},#1'
+[^ :]+:[0-9]+: Error: immediate value out of range 1 to 16 at operand 3 -- `sqrshr z0\.h,{z0\.s-z1\.s},#0'
+[^ :]+:[0-9]+: Error: immediate value out of range 1 to 16 at operand 3 -- `sqrshr z0\.h,{z0\.s-z1\.s},#17'
+[^ :]+:[0-9]+: Error: operand mismatch -- `sqrshr z0\.s,{z0\.d-z1\.d},#1'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: sqrshr z0\.h, {z0\.d-z1\.d}, #1
+[^ :]+:[0-9]+: Info: other valid variant\(s\):
+[^ :]+:[0-9]+: Info: sqrshr z0\.b, {z0\.s-z1\.s}, #1
+[^ :]+:[0-9]+: Error: immediate operand required at operand 3 -- `sqrshr z0\.h,{z0\.s-z1\.s},x0'
+[^ :]+:[0-9]+: Error: immediate operand required at operand 3 -- `sqrshr z0\.h,{z0\.s-z1\.s},z0\.s'
+[^ :]+:[0-9]+: Error: immediate operand required at operand 3 -- `sqrshr z0\.h,{z0\.s-z1\.s},p0'
+[^ :]+:[0-9]+: Error: immediate operand required at operand 3 -- `sqrshr z0\.h,{z0\.s-z1\.s},pn0'
+[^ :]+:[0-9]+: Error: start register out of range at operand 2 -- `sqrshr z0\.b,{z1\.s-z4\.s},#1'
+[^ :]+:[0-9]+: Error: start register out of range at operand 2 -- `sqrshr z0\.b,{z2\.s-z5\.s},#1'
+[^ :]+:[0-9]+: Error: start register out of range at operand 2 -- `sqrshr z0\.b,{z3\.s-z6\.s},#1'
+[^ :]+:[0-9]+: Error: immediate value out of range 1 to 32 at operand 3 -- `sqrshr z0\.b,{z0\.s-z3\.s},#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range 1 to 32 at operand 3 -- `sqrshr z0\.b,{z0\.s-z3\.s},#0'
+[^ :]+:[0-9]+: Error: immediate value out of range 1 to 32 at operand 3 -- `sqrshr z0\.b,{z0\.s-z3\.s},#33'
+[^ :]+:[0-9]+: Error: operand mismatch -- `sqrshr z0\.b,{z0\.d-z3\.d},#1'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: sqrshr z0\.b, {z0\.s-z3\.s}, #1
+[^ :]+:[0-9]+: Info: other valid variant\(s\):
+[^ :]+:[0-9]+: Info: sqrshr z0\.h, {z0\.d-z3\.d}, #1
+[^ :]+:[0-9]+: Error: operand mismatch -- `sqrshr z0\.b,{z0\.d-z3\.d},#65'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: sqrshr z0\.b, {z0\.s-z3\.s}, #65
+[^ :]+:[0-9]+: Info: other valid variant\(s\):
+[^ :]+:[0-9]+: Info: sqrshr z0\.h, {z0\.d-z3\.d}, #65
diff --git a/gas/testsuite/gas/aarch64/sme2-27-invalid.s b/gas/testsuite/gas/aarch64/sme2-27-invalid.s
new file mode 100644
index 0000000..3a613af
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-27-invalid.s
@@ -0,0 +1,25 @@
+ .equ x0, 1
+ .equ z0.s, 2
+ .equ p0, 3
+ .equ pn0, 4
+
+ sqrshr 0, { z0.s - z1.s }, #1
+ sqrshr z0.h, 0, #1
+
+ sqrshr z0.h, { z1.s - z2.s }, #1
+ sqrshr z0.h, { z0.s - z1.s }, #0
+ sqrshr z0.h, { z0.s - z1.s }, #17
+ sqrshr z0.s, { z0.d - z1.d }, #1
+ sqrshr z0.h, { z0.s - z1.s }, x0
+ sqrshr z0.h, { z0.s - z1.s }, z0.s
+ sqrshr z0.h, { z0.s - z1.s }, p0
+ sqrshr z0.h, { z0.s - z1.s }, pn0
+
+ sqrshr z0.b, { z1.s - z4.s }, #1
+ sqrshr z0.b, { z2.s - z5.s }, #1
+ sqrshr z0.b, { z3.s - z6.s }, #1
+ sqrshr z0.b, { z0.s - z3.s }, #-1
+ sqrshr z0.b, { z0.s - z3.s }, #0
+ sqrshr z0.b, { z0.s - z3.s }, #33
+ sqrshr z0.b, { z0.d - z3.d }, #1
+ sqrshr z0.b, { z0.d - z3.d }, #65 // Double error
diff --git a/gas/testsuite/gas/aarch64/sme2-27-noarch.d b/gas/testsuite/gas/aarch64/sme2-27-noarch.d
new file mode 100644
index 0000000..f0e735d
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-27-noarch.d
@@ -0,0 +1,3 @@
+#as: -march=armv8-a+sme
+#source: sme2-27.s
+#error_output: sme2-27-noarch.l
diff --git a/gas/testsuite/gas/aarch64/sme2-27-noarch.l b/gas/testsuite/gas/aarch64/sme2-27-noarch.l
new file mode 100644
index 0000000..72213e0
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-27-noarch.l
@@ -0,0 +1,50 @@
+[^ :]+: Assembler messages:
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.h,{z0\.s-z1\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z31\.h,{z0\.s-z1\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.h,{z30\.s-z31\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.h,{z0\.s-z1\.s},#16'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z14\.h,{z22\.s-z23\.s},#7'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.h,{z0\.s-z1\.s},#x0'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.h,{z0\.s-z1\.s},#z0\.s'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.h,{z0\.s-z1\.s},#p0'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.h,{z0\.s-z1\.s},#pn0'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.b,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z31\.b,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.b,{z28\.s-z31\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.b,{z0\.s-z3\.s},#32'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z6\.b,{z12\.s-z15\.s},#25'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.h,{z0\.d-z3\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z31\.h,{z0\.d-z3\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.h,{z28\.d-z31\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z0\.h,{z0\.d-z3\.d},#64'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshr z25\.h,{z20\.d-z23\.d},#50'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z0\.h,{z0\.s-z1\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z31\.h,{z0\.s-z1\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z0\.h,{z30\.s-z31\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z0\.h,{z0\.s-z1\.s},#16'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z14\.h,{z22\.s-z23\.s},#7'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z0\.b,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z31\.b,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z0\.b,{z28\.s-z31\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z0\.b,{z0\.s-z3\.s},#32'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z6\.b,{z12\.s-z15\.s},#25'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z0\.h,{z0\.d-z3\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z31\.h,{z0\.d-z3\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z0\.h,{z28\.d-z31\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z0\.h,{z0\.d-z3\.d},#64'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshru z25\.h,{z20\.d-z23\.d},#50'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z0\.h,{z0\.s-z1\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z31\.h,{z0\.s-z1\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z0\.h,{z30\.s-z31\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z0\.h,{z0\.s-z1\.s},#16'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z14\.h,{z22\.s-z23\.s},#7'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z0\.b,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z31\.b,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z0\.b,{z28\.s-z31\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z0\.b,{z0\.s-z3\.s},#32'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z6\.b,{z12\.s-z15\.s},#25'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z0\.h,{z0\.d-z3\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z31\.h,{z0\.d-z3\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z0\.h,{z28\.d-z31\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z0\.h,{z0\.d-z3\.d},#64'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshr z25\.h,{z20\.d-z23\.d},#50'
diff --git a/gas/testsuite/gas/aarch64/sme2-27.d b/gas/testsuite/gas/aarch64/sme2-27.d
new file mode 100644
index 0000000..e217715
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-27.d
@@ -0,0 +1,62 @@
+#as: -march=armv8-a+sme2
+#objdump: -dr
+
+[^:]+: file format .*
+
+
+[^:]+:
+
+[^:]+:
+[^:]+: c1efd400 sqrshr z0\.h, {z0\.s-z1\.s}, #1
+[^:]+: c1efd41f sqrshr z31\.h, {z0\.s-z1\.s}, #1
+[^:]+: c1efd7c0 sqrshr z0\.h, {z30\.s-z31\.s}, #1
+[^:]+: c1e0d400 sqrshr z0\.h, {z0\.s-z1\.s}, #16
+[^:]+: c1e9d6ce sqrshr z14\.h, {z22\.s-z23\.s}, #7
+[^:]+: c1efd400 sqrshr z0\.h, {z0\.s-z1\.s}, #1
+[^:]+: c1eed400 sqrshr z0\.h, {z0\.s-z1\.s}, #2
+[^:]+: c1edd400 sqrshr z0\.h, {z0\.s-z1\.s}, #3
+[^:]+: c1ecd400 sqrshr z0\.h, {z0\.s-z1\.s}, #4
+[^:]+: c17fd800 sqrshr z0\.b, {z0\.s-z3\.s}, #1
+[^:]+: c17fd81f sqrshr z31\.b, {z0\.s-z3\.s}, #1
+[^:]+: c17fdb80 sqrshr z0\.b, {z28\.s-z31\.s}, #1
+[^:]+: c160d800 sqrshr z0\.b, {z0\.s-z3\.s}, #32
+[^:]+: c167d986 sqrshr z6\.b, {z12\.s-z15\.s}, #25
+[^:]+: c1ffd800 sqrshr z0\.h, {z0\.d-z3\.d}, #1
+[^:]+: c1ffd81f sqrshr z31\.h, {z0\.d-z3\.d}, #1
+[^:]+: c1ffdb80 sqrshr z0\.h, {z28\.d-z31\.d}, #1
+[^:]+: c1a0d800 sqrshr z0\.h, {z0\.d-z3\.d}, #64
+[^:]+: c1aeda99 sqrshr z25\.h, {z20\.d-z23\.d}, #50
+[^:]+: c13fd800 \.inst 0xc13fd800 ; undefined
+[^:]+: c120d800 \.inst 0xc120d800 ; undefined
+[^:]+: c1ffd400 sqrshru z0\.h, {z0\.s-z1\.s}, #1
+[^:]+: c1ffd41f sqrshru z31\.h, {z0\.s-z1\.s}, #1
+[^:]+: c1ffd7c0 sqrshru z0\.h, {z30\.s-z31\.s}, #1
+[^:]+: c1f0d400 sqrshru z0\.h, {z0\.s-z1\.s}, #16
+[^:]+: c1f9d6ce sqrshru z14\.h, {z22\.s-z23\.s}, #7
+[^:]+: c17fd840 sqrshru z0\.b, {z0\.s-z3\.s}, #1
+[^:]+: c17fd85f sqrshru z31\.b, {z0\.s-z3\.s}, #1
+[^:]+: c17fdbc0 sqrshru z0\.b, {z28\.s-z31\.s}, #1
+[^:]+: c160d840 sqrshru z0\.b, {z0\.s-z3\.s}, #32
+[^:]+: c167d9c6 sqrshru z6\.b, {z12\.s-z15\.s}, #25
+[^:]+: c1ffd840 sqrshru z0\.h, {z0\.d-z3\.d}, #1
+[^:]+: c1ffd85f sqrshru z31\.h, {z0\.d-z3\.d}, #1
+[^:]+: c1ffdbc0 sqrshru z0\.h, {z28\.d-z31\.d}, #1
+[^:]+: c1a0d840 sqrshru z0\.h, {z0\.d-z3\.d}, #64
+[^:]+: c1aedad9 sqrshru z25\.h, {z20\.d-z23\.d}, #50
+[^:]+: c1efd420 uqrshr z0\.h, {z0\.s-z1\.s}, #1
+[^:]+: c1efd43f uqrshr z31\.h, {z0\.s-z1\.s}, #1
+[^:]+: c1efd7e0 uqrshr z0\.h, {z30\.s-z31\.s}, #1
+[^:]+: c1e0d420 uqrshr z0\.h, {z0\.s-z1\.s}, #16
+[^:]+: c1e9d6ee uqrshr z14\.h, {z22\.s-z23\.s}, #7
+[^:]+: c17fd820 uqrshr z0\.b, {z0\.s-z3\.s}, #1
+[^:]+: c17fd83f uqrshr z31\.b, {z0\.s-z3\.s}, #1
+[^:]+: c17fdba0 uqrshr z0\.b, {z28\.s-z31\.s}, #1
+[^:]+: c160d820 uqrshr z0\.b, {z0\.s-z3\.s}, #32
+[^:]+: c167d9a6 uqrshr z6\.b, {z12\.s-z15\.s}, #25
+[^:]+: c1ffd820 uqrshr z0\.h, {z0\.d-z3\.d}, #1
+[^:]+: c1ffd83f uqrshr z31\.h, {z0\.d-z3\.d}, #1
+[^:]+: c1ffdba0 uqrshr z0\.h, {z28\.d-z31\.d}, #1
+[^:]+: c1a0d820 uqrshr z0\.h, {z0\.d-z3\.d}, #64
+[^:]+: c1aedab9 uqrshr z25\.h, {z20\.d-z23\.d}, #50
+[^:]+: c13fd820 \.inst 0xc13fd820 ; undefined
+[^:]+: c120d820 \.inst 0xc120d820 ; undefined
diff --git a/gas/testsuite/gas/aarch64/sme2-27.s b/gas/testsuite/gas/aarch64/sme2-27.s
new file mode 100644
index 0000000..e7e04ba
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-27.s
@@ -0,0 +1,71 @@
+ .equ x0, 1
+ .equ z0.s, 2
+ .equ p0, 3
+ .equ pn0, 4
+
+ sqrshr z0.h, { z0.s - z1.s }, #1
+ sqrshr z31.h, { z0.s - z1.s }, #1
+ sqrshr z0.h, { z30.s - z31.s }, #1
+ sqrshr z0.h, { z0.s - z1.s }, #16
+ sqrshr z14.h, { z22.s - z23.s }, #7
+
+ sqrshr z0.h, { z0.s - z1.s }, #x0
+ sqrshr z0.h, { z0.s - z1.s }, #z0.s
+ sqrshr z0.h, { z0.s - z1.s }, #p0
+ sqrshr z0.h, { z0.s - z1.s }, #pn0
+
+ sqrshr z0.b, { z0.s - z3.s }, #1
+ sqrshr z31.b, { z0.s - z3.s }, #1
+ sqrshr z0.b, { z28.s - z31.s }, #1
+ sqrshr z0.b, { z0.s - z3.s }, #32
+ sqrshr z6.b, { z12.s - z15.s }, #25
+
+ sqrshr z0.h, { z0.d - z3.d }, #1
+ sqrshr z31.h, { z0.d - z3.d }, #1
+ sqrshr z0.h, { z28.d - z31.d }, #1
+ sqrshr z0.h, { z0.d - z3.d }, #64
+ sqrshr z25.h, { z20.d - z23.d }, #50
+
+ // Invalid SQRSHR
+ .inst 0xc13fd800
+ .inst 0xc120d800
+
+ sqrshru z0.h, { z0.s - z1.s }, #1
+ sqrshru z31.h, { z0.s - z1.s }, #1
+ sqrshru z0.h, { z30.s - z31.s }, #1
+ sqrshru z0.h, { z0.s - z1.s }, #16
+ sqrshru z14.h, { z22.s - z23.s }, #7
+
+ sqrshru z0.b, { z0.s - z3.s }, #1
+ sqrshru z31.b, { z0.s - z3.s }, #1
+ sqrshru z0.b, { z28.s - z31.s }, #1
+ sqrshru z0.b, { z0.s - z3.s }, #32
+ sqrshru z6.b, { z12.s - z15.s }, #25
+
+ sqrshru z0.h, { z0.d - z3.d }, #1
+ sqrshru z31.h, { z0.d - z3.d }, #1
+ sqrshru z0.h, { z28.d - z31.d }, #1
+ sqrshru z0.h, { z0.d - z3.d }, #64
+ sqrshru z25.h, { z20.d - z23.d }, #50
+
+ uqrshr z0.h, { z0.s - z1.s }, #1
+ uqrshr z31.h, { z0.s - z1.s }, #1
+ uqrshr z0.h, { z30.s - z31.s }, #1
+ uqrshr z0.h, { z0.s - z1.s }, #16
+ uqrshr z14.h, { z22.s - z23.s }, #7
+
+ uqrshr z0.b, { z0.s - z3.s }, #1
+ uqrshr z31.b, { z0.s - z3.s }, #1
+ uqrshr z0.b, { z28.s - z31.s }, #1
+ uqrshr z0.b, { z0.s - z3.s }, #32
+ uqrshr z6.b, { z12.s - z15.s }, #25
+
+ uqrshr z0.h, { z0.d - z3.d }, #1
+ uqrshr z31.h, { z0.d - z3.d }, #1
+ uqrshr z0.h, { z28.d - z31.d }, #1
+ uqrshr z0.h, { z0.d - z3.d }, #64
+ uqrshr z25.h, { z20.d - z23.d }, #50
+
+ // Invalid UQRSHR
+ .inst 0xc13fd820
+ .inst 0xc120d820
diff --git a/gas/testsuite/gas/aarch64/sme2-28-invalid.d b/gas/testsuite/gas/aarch64/sme2-28-invalid.d
new file mode 100644
index 0000000..dbe03ce
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-28-invalid.d
@@ -0,0 +1,3 @@
+#as: -march=armv8-a
+#source: sme2-28-invalid.s
+#error_output: sme2-28-invalid.l
diff --git a/gas/testsuite/gas/aarch64/sme2-28-invalid.l b/gas/testsuite/gas/aarch64/sme2-28-invalid.l
new file mode 100644
index 0000000..615f8c35
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-28-invalid.l
@@ -0,0 +1,19 @@
+[^ :]+: Assembler messages:
+[^ :]+:[0-9]+: Error: expected a register at operand 1 -- `sqrshrn 0,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: expected '{' at operand 2 -- `sqrshrn z0\.b,0,#1'
+[^ :]+:[0-9]+: Error: start register out of range at operand 2 -- `sqrshrn z0\.b,{z1\.s-z4\.s},#1'
+[^ :]+:[0-9]+: Error: start register out of range at operand 2 -- `sqrshrn z0\.b,{z2\.s-z5\.s},#1'
+[^ :]+:[0-9]+: Error: start register out of range at operand 2 -- `sqrshrn z0\.b,{z3\.s-z6\.s},#1'
+[^ :]+:[0-9]+: Error: immediate value out of range 1 to 32 at operand 3 -- `sqrshrn z0\.b,{z0\.s-z3\.s},#-1'
+[^ :]+:[0-9]+: Error: immediate value out of range 1 to 32 at operand 3 -- `sqrshrn z0\.b,{z0\.s-z3\.s},#0'
+[^ :]+:[0-9]+: Error: immediate value out of range 1 to 32 at operand 3 -- `sqrshrn z0\.b,{z0\.s-z3\.s},#33'
+[^ :]+:[0-9]+: Error: operand mismatch -- `sqrshrn z0\.b,{z0\.d-z3\.d},#1'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: sqrshrn z0\.b, {z0\.s-z3\.s}, #1
+[^ :]+:[0-9]+: Info: other valid variant\(s\):
+[^ :]+:[0-9]+: Info: sqrshrn z0\.h, {z0\.d-z3\.d}, #1
+[^ :]+:[0-9]+: Error: operand mismatch -- `sqrshrn z0\.b,{z0\.d-z3\.d},#65'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: sqrshrn z0\.b, {z0\.s-z3\.s}, #65
+[^ :]+:[0-9]+: Info: other valid variant\(s\):
+[^ :]+:[0-9]+: Info: sqrshrn z0\.h, {z0\.d-z3\.d}, #65
diff --git a/gas/testsuite/gas/aarch64/sme2-28-invalid.s b/gas/testsuite/gas/aarch64/sme2-28-invalid.s
new file mode 100644
index 0000000..f587049
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-28-invalid.s
@@ -0,0 +1,11 @@
+ sqrshrn 0, { z0.s - z3.s }, #1
+ sqrshrn z0.b, 0, #1
+
+ sqrshrn z0.b, { z1.s - z4.s }, #1
+ sqrshrn z0.b, { z2.s - z5.s }, #1
+ sqrshrn z0.b, { z3.s - z6.s }, #1
+ sqrshrn z0.b, { z0.s - z3.s }, #-1
+ sqrshrn z0.b, { z0.s - z3.s }, #0
+ sqrshrn z0.b, { z0.s - z3.s }, #33
+ sqrshrn z0.b, { z0.d - z3.d }, #1
+ sqrshrn z0.b, { z0.d - z3.d }, #65 // Double error
diff --git a/gas/testsuite/gas/aarch64/sme2-28-noarch.d b/gas/testsuite/gas/aarch64/sme2-28-noarch.d
new file mode 100644
index 0000000..de378eb
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-28-noarch.d
@@ -0,0 +1,3 @@
+#as: -march=armv8-a+sme
+#source: sme2-28.s
+#error_output: sme2-28-noarch.l
diff --git a/gas/testsuite/gas/aarch64/sme2-28-noarch.l b/gas/testsuite/gas/aarch64/sme2-28-noarch.l
new file mode 100644
index 0000000..a3762f1
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-28-noarch.l
@@ -0,0 +1,26 @@
+[^ :]+: Assembler messages:
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrn z0\.b,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrn z31\.b,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrn z0\.b,{z28\.s-z31\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrn z0\.b,{z0\.s-z3\.s},#32'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrn z6\.b,{z12\.s-z15\.s},#25'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrn z0\.h,{z0\.d-z3\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrn z31\.h,{z0\.d-z3\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrn z0\.h,{z28\.d-z31\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrn z0\.h,{z0\.d-z3\.d},#64'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrn z25\.h,{z20\.d-z23\.d},#50'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrun z0\.b,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrun z31\.b,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrun z0\.b,{z28\.s-z31\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrun z0\.b,{z0\.s-z3\.s},#32'
+[^ :]+:[0-9]+: Error: selected processor does not support `sqrshrun z6\.b,{z12\.s-z15\.s},#25'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshrn z0\.b,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshrn z31\.b,{z0\.s-z3\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshrn z0\.b,{z28\.s-z31\.s},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshrn z0\.b,{z0\.s-z3\.s},#32'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshrn z6\.b,{z12\.s-z15\.s},#25'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshrn z0\.h,{z0\.d-z3\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshrn z31\.h,{z0\.d-z3\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshrn z0\.h,{z28\.d-z31\.d},#1'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshrn z0\.h,{z0\.d-z3\.d},#64'
+[^ :]+:[0-9]+: Error: selected processor does not support `uqrshrn z25\.h,{z20\.d-z23\.d},#50'
diff --git a/gas/testsuite/gas/aarch64/sme2-28.d b/gas/testsuite/gas/aarch64/sme2-28.d
new file mode 100644
index 0000000..b72273d
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-28.d
@@ -0,0 +1,34 @@
+#as: -march=armv8-a+sme2
+#objdump: -dr
+
+[^:]+: file format .*
+
+
+[^:]+:
+
+[^:]+:
+[^:]+: c17fdc00 sqrshrn z0\.b, {z0\.s-z3\.s}, #1
+[^:]+: c17fdc1f sqrshrn z31\.b, {z0\.s-z3\.s}, #1
+[^:]+: c17fdf80 sqrshrn z0\.b, {z28\.s-z31\.s}, #1
+[^:]+: c160dc00 sqrshrn z0\.b, {z0\.s-z3\.s}, #32
+[^:]+: c167dd86 sqrshrn z6\.b, {z12\.s-z15\.s}, #25
+[^:]+: c1ffdc00 sqrshrn z0\.h, {z0\.d-z3\.d}, #1
+[^:]+: c1ffdc1f sqrshrn z31\.h, {z0\.d-z3\.d}, #1
+[^:]+: c1ffdf80 sqrshrn z0\.h, {z28\.d-z31\.d}, #1
+[^:]+: c1a0dc00 sqrshrn z0\.h, {z0\.d-z3\.d}, #64
+[^:]+: c1aede99 sqrshrn z25\.h, {z20\.d-z23\.d}, #50
+[^:]+: c17fdc40 sqrshrun z0\.b, {z0\.s-z3\.s}, #1
+[^:]+: c17fdc5f sqrshrun z31\.b, {z0\.s-z3\.s}, #1
+[^:]+: c17fdfc0 sqrshrun z0\.b, {z28\.s-z31\.s}, #1
+[^:]+: c160dc40 sqrshrun z0\.b, {z0\.s-z3\.s}, #32
+[^:]+: c167ddc6 sqrshrun z6\.b, {z12\.s-z15\.s}, #25
+[^:]+: c17fdc20 uqrshrn z0\.b, {z0\.s-z3\.s}, #1
+[^:]+: c17fdc3f uqrshrn z31\.b, {z0\.s-z3\.s}, #1
+[^:]+: c17fdfa0 uqrshrn z0\.b, {z28\.s-z31\.s}, #1
+[^:]+: c160dc20 uqrshrn z0\.b, {z0\.s-z3\.s}, #32
+[^:]+: c167dda6 uqrshrn z6\.b, {z12\.s-z15\.s}, #25
+[^:]+: c1ffdc20 uqrshrn z0\.h, {z0\.d-z3\.d}, #1
+[^:]+: c1ffdc3f uqrshrn z31\.h, {z0\.d-z3\.d}, #1
+[^:]+: c1ffdfa0 uqrshrn z0\.h, {z28\.d-z31\.d}, #1
+[^:]+: c1a0dc20 uqrshrn z0\.h, {z0\.d-z3\.d}, #64
+[^:]+: c1aedeb9 uqrshrn z25\.h, {z20\.d-z23\.d}, #50
diff --git a/gas/testsuite/gas/aarch64/sme2-28.s b/gas/testsuite/gas/aarch64/sme2-28.s
new file mode 100644
index 0000000..3b51448
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sme2-28.s
@@ -0,0 +1,29 @@
+ sqrshrn z0.b, { z0.s - z3.s }, #1
+ sqrshrn z31.b, { z0.s - z3.s }, #1
+ sqrshrn z0.b, { z28.s - z31.s }, #1
+ sqrshrn z0.b, { z0.s - z3.s }, #32
+ sqrshrn z6.b, { z12.s - z15.s }, #25
+
+ sqrshrn z0.h, { z0.d - z3.d }, #1
+ sqrshrn z31.h, { z0.d - z3.d }, #1
+ sqrshrn z0.h, { z28.d - z31.d }, #1
+ sqrshrn z0.h, { z0.d - z3.d }, #64
+ sqrshrn z25.h, { z20.d - z23.d }, #50
+
+ sqrshrun z0.b, { z0.s - z3.s }, #1
+ sqrshrun z31.b, { z0.s - z3.s }, #1
+ sqrshrun z0.b, { z28.s - z31.s }, #1
+ sqrshrun z0.b, { z0.s - z3.s }, #32
+ sqrshrun z6.b, { z12.s - z15.s }, #25
+
+ uqrshrn z0.b, { z0.s - z3.s }, #1
+ uqrshrn z31.b, { z0.s - z3.s }, #1
+ uqrshrn z0.b, { z28.s - z31.s }, #1
+ uqrshrn z0.b, { z0.s - z3.s }, #32
+ uqrshrn z6.b, { z12.s - z15.s }, #25
+
+ uqrshrn z0.h, { z0.d - z3.d }, #1
+ uqrshrn z31.h, { z0.d - z3.d }, #1
+ uqrshrn z0.h, { z28.d - z31.d }, #1
+ uqrshrn z0.h, { z0.d - z3.d }, #64
+ uqrshrn z25.h, { z20.d - z23.d }, #50