[v1,11/12] aarch64: Add support for sve2p1 pmov instruction.

Message ID 20240704124045.306577-12-srinath.parvathaneni@arm.com
State New
Headers
Series aarch64: Add support for remaining sve2p1 instructions. |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 fail Test failed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Srinath Parvathaneni July 4, 2024, 12:40 p.m. UTC
  This patch adds support for followign SVE2p1 instruction, spec is available here [1].

1. PMOV (to vector)
2. PMOV (to predicate)

Both pmov (to vector) and pmov (to predicate) have destination scalable vector
register and source scalable vector register respectively as an operand with no
suffix and optional index. To handle this case we have added 8 new operands in
this patch.

AARCH64_OPND_SVE_Zn0_INDEX,      /* Zn[index], bits [9:5].  */
AARCH64_OPND_SVE_Zn1_17_INDEX,    /* Zn[index], bits [9:5,17].  */
AARCH64_OPND_SVE_Zn2_18_INDEX,    /* Zn[index], bits [9:5,18:17].  */
AARCH64_OPND_SVE_Zn3_22_INDEX,    /* Zn[index], bits [9:5,18:17,22].  */
AARCH64_OPND_SVE_Zd0_INDEX,      /* Zn[index], bits [4:0].  */
AARCH64_OPND_SVE_Zd1_17_INDEX,    /* Zn[index], bits [4:0,17].  */
AARCH64_OPND_SVE_Zd2_18_INDEX,    /* Zn[index], bits [4:0,18:17].  */
AARCH64_OPND_SVE_Zd3_22_INDEX,    /* Zn[index], bits [4:0,18:17,22].  */

Since the index of the <Zd> operand is optional, the index part is
dropped in disassembly in both the cases of "no index" or "zero index".

As per spec: PMOV <Zd>{[<imm>]}, <Pn>.D
             PMOV <Pn>.D, <Zd>{[<imm>]}

Example1:
	Assembly: pmov z5[0], p6.d
	Disassembly: pmov z5, p6.d

        Assembly: pmov z5, p6.d
        Disassembly: pmov z5, p6.d

Example2:
	Assembly: pmov p4.b, z5[0]
	Disassembly: pmov p4.b, z5

        Assembly: pmov p4.b, z5
        Disassembly: pmov p4.b, z5
[1]: https://developer.arm.com/documentation/ddi0602/2024-03/SVE-Instructions?lang=en
---
 gas/config/tc-aarch64.c                      |  28 ++++-
 gas/testsuite/gas/aarch64/sve2p1-7-invalid.d |   3 +
 gas/testsuite/gas/aarch64/sve2p1-7-invalid.l | 118 +++++++++++++++++++
 gas/testsuite/gas/aarch64/sve2p1-7-invalid.s |  76 ++++++++++++
 gas/testsuite/gas/aarch64/sve2p1-7.d         |  64 ++++++++++
 gas/testsuite/gas/aarch64/sve2p1-7.s         |  63 ++++++++++
 include/opcode/aarch64.h                     |   8 ++
 opcodes/aarch64-opc.c                        |  34 +++++-
 opcodes/aarch64-opc.h                        |   2 +
 opcodes/aarch64-tbl.h                        |  54 ++++++++-
 10 files changed, 440 insertions(+), 10 deletions(-)
 create mode 100644 gas/testsuite/gas/aarch64/sve2p1-7-invalid.d
 create mode 100644 gas/testsuite/gas/aarch64/sve2p1-7-invalid.l
 create mode 100644 gas/testsuite/gas/aarch64/sve2p1-7-invalid.s
 create mode 100644 gas/testsuite/gas/aarch64/sve2p1-7.d
 create mode 100644 gas/testsuite/gas/aarch64/sve2p1-7.s
  

Comments

Richard Earnshaw (lists) July 8, 2024, 4:15 p.m. UTC | #1
On 04/07/2024 13:40, Srinath Parvathaneni wrote:
> 
> This patch adds support for followign SVE2p1 instruction, spec is available here [1].
> 
> 1. PMOV (to vector)
> 2. PMOV (to predicate)
> 
> Both pmov (to vector) and pmov (to predicate) have destination scalable vector
> register and source scalable vector register respectively as an operand with no
> suffix and optional index. To handle this case we have added 8 new operands in
> this patch.
> 
> AARCH64_OPND_SVE_Zn0_INDEX,      /* Zn[index], bits [9:5].  */
> AARCH64_OPND_SVE_Zn1_17_INDEX,    /* Zn[index], bits [9:5,17].  */
> AARCH64_OPND_SVE_Zn2_18_INDEX,    /* Zn[index], bits [9:5,18:17].  */
> AARCH64_OPND_SVE_Zn3_22_INDEX,    /* Zn[index], bits [9:5,18:17,22].  */
> AARCH64_OPND_SVE_Zd0_INDEX,      /* Zn[index], bits [4:0].  */
> AARCH64_OPND_SVE_Zd1_17_INDEX,    /* Zn[index], bits [4:0,17].  */
> AARCH64_OPND_SVE_Zd2_18_INDEX,    /* Zn[index], bits [4:0,18:17].  */
> AARCH64_OPND_SVE_Zd3_22_INDEX,    /* Zn[index], bits [4:0,18:17,22].  */
> 
> Since the index of the <Zd> operand is optional, the index part is
> dropped in disassembly in both the cases of "no index" or "zero index".
> 
> As per spec: PMOV <Zd>{[<imm>]}, <Pn>.D
>              PMOV <Pn>.D, <Zd>{[<imm>]}
> 
> Example1:
> 	Assembly: pmov z5[0], p6.d
> 	Disassembly: pmov z5, p6.d
> 
>         Assembly: pmov z5, p6.d
>         Disassembly: pmov z5, p6.d
> 
> Example2:
> 	Assembly: pmov p4.b, z5[0]
> 	Disassembly: pmov p4.b, z5
> 
>         Assembly: pmov p4.b, z5
>         Disassembly: pmov p4.b, z5
> [1]: https://developer.arm.com/documentation/ddi0602/2024-03/SVE-Instructions?lang=en
> ---
>  gas/config/tc-aarch64.c                      |  28 ++++-
>  gas/testsuite/gas/aarch64/sve2p1-7-invalid.d |   3 +
>  gas/testsuite/gas/aarch64/sve2p1-7-invalid.l | 118 +++++++++++++++++++
>  gas/testsuite/gas/aarch64/sve2p1-7-invalid.s |  76 ++++++++++++
>  gas/testsuite/gas/aarch64/sve2p1-7.d         |  64 ++++++++++
>  gas/testsuite/gas/aarch64/sve2p1-7.s         |  63 ++++++++++
>  include/opcode/aarch64.h                     |   8 ++
>  opcodes/aarch64-opc.c                        |  34 +++++-
>  opcodes/aarch64-opc.h                        |   2 +
>  opcodes/aarch64-tbl.h                        |  54 ++++++++-
>  10 files changed, 440 insertions(+), 10 deletions(-)
>  create mode 100644 gas/testsuite/gas/aarch64/sve2p1-7-invalid.d
>  create mode 100644 gas/testsuite/gas/aarch64/sve2p1-7-invalid.l
>  create mode 100644 gas/testsuite/gas/aarch64/sve2p1-7-invalid.s
>  create mode 100644 gas/testsuite/gas/aarch64/sve2p1-7.d
>  create mode 100644 gas/testsuite/gas/aarch64/sve2p1-7.s
> 

+   FLAGS includes PTR_OPTIONAL_INDEX, which has been introduced to parse
+   instructions with optional index operands.  */

This will read strangely ten years from now.  Just say:

   FLAGS includes PTR_OPTIONAL_INDEX to handle instructions with optional index operands.

R.
  

Patch

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 42c03bd199e..50f00515521 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -113,6 +113,7 @@  enum vector_el_type
 #define NTA_HASTYPE     1
 #define NTA_HASINDEX    2
 #define NTA_HASVARWIDTH 4
+#define NTA_NOINDEX    8
 
 struct vector_type_el
 {
@@ -1185,11 +1186,15 @@  parse_index_expression (char **str, int64_t *imm)
    register index.
 
    FLAGS includes PTR_GOOD_MATCH if we are sufficiently far into parsing
-   an operand that we can be confident that it is a good match.  */
+   an operand that we can be confident that it is a good match.
+
+   FLAGS includes PTR_OPTIONAL_INDEX, which has been introduced to parse
+   instructions with optional index operands.  */
 
 #define PTR_IN_REGLIST (1U << 0)
 #define PTR_FULL_REG (1U << 1)
 #define PTR_GOOD_MATCH (1U << 2)
+#define PTR_OPTIONAL_INDEX (1U << 3)
 
 static const reg_entry *
 parse_typed_reg (char **ccp, aarch64_reg_type type,
@@ -1277,7 +1282,10 @@  parse_typed_reg (char **ccp, aarch64_reg_type type,
       atype.width = parsetype.width;
     }
 
-  if (!(flags & PTR_FULL_REG) && skip_past_char (&str, '['))
+  if ((flags & PTR_OPTIONAL_INDEX) && (*str == '\0' || *str == ','))
+    atype.defined |= NTA_NOINDEX;
+  else if ((!(flags & PTR_FULL_REG) || (flags & PTR_OPTIONAL_INDEX))
+	    && skip_past_char (&str, '['))
     {
       /* Reject Sn[index] syntax.  */
       if (reg->type != REG_TYPE_Z
@@ -6886,6 +6894,20 @@  parse_operands (char *str, const aarch64_opcode *opcode)
 	  reg_type = REG_TYPE_Z;
 	  goto vector_reg_index;
 
+	case AARCH64_OPND_SVE_Zn0_INDEX:
+	case AARCH64_OPND_SVE_Zn1_17_INDEX:
+	case AARCH64_OPND_SVE_Zn2_18_INDEX:
+	case AARCH64_OPND_SVE_Zn3_22_INDEX:
+	case AARCH64_OPND_SVE_Zd0_INDEX:
+	case AARCH64_OPND_SVE_Zd1_17_INDEX:
+	case AARCH64_OPND_SVE_Zd2_18_INDEX:
+	case AARCH64_OPND_SVE_Zd3_22_INDEX:
+	  reg_type = REG_TYPE_Z;
+	  reg = parse_typed_reg (&str, reg_type, &vectype, PTR_OPTIONAL_INDEX);
+	  if (!reg || !(vectype.defined & (NTA_HASINDEX | NTA_NOINDEX)))
+	    goto failure;
+	  goto vector_reg_optional_index;
+
 	case AARCH64_OPND_Ed:
 	case AARCH64_OPND_En:
 	case AARCH64_OPND_Em:
@@ -6899,7 +6921,7 @@  parse_operands (char *str, const aarch64_opcode *opcode)
 	    goto failure;
 	  if (!(vectype.defined & NTA_HASINDEX))
 	    goto failure;
-
+	vector_reg_optional_index:
 	  if (reg->type == REG_TYPE_Z && vectype.type == NT_invtype)
 	    /* Unqualified Zn[index] is allowed in LUTI2 instructions.  */
 	    info->qualifier = AARCH64_OPND_QLF_NIL;
diff --git a/gas/testsuite/gas/aarch64/sve2p1-7-invalid.d b/gas/testsuite/gas/aarch64/sve2p1-7-invalid.d
new file mode 100644
index 00000000000..ddf2ccb0deb
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve2p1-7-invalid.d
@@ -0,0 +1,3 @@ 
+#name: Test of illegal pmov instruction.
+#as: -march=armv9.4-a
+#error_output: sve2p1-7-invalid.l
diff --git a/gas/testsuite/gas/aarch64/sve2p1-7-invalid.l b/gas/testsuite/gas/aarch64/sve2p1-7-invalid.l
new file mode 100644
index 00000000000..4559f6f8d36
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve2p1-7-invalid.l
@@ -0,0 +1,118 @@ 
+.*: Assembler messages:
+.*: Error: operand mismatch -- `pmov p0,z0'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov p0.h, z0
+.*: Error: expected an SVE vector or predicate register at operand 1 -- `pmov p16.b,z0'
+.*: Error: register element index must be 0 at operand 2 -- `pmov p0.b,z31\[1\]'
+.*: Error: comma expected between operands at operand 2 -- `pmov p15.b'
+.*: Error: operand mismatch -- `pmov p15,z31.b\[4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov p15.h, z31\[4\]
+.*: Error: operand mismatch -- `pmov p7,z15.b'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov p7.h, z15
+.*: Error: expected an SVE predicate register at operand 2 -- `mov p7,w15.b'
+.*: Error: expected an SVE predicate register at operand 2 -- `mov p7.b,x15'
+.*: Error: operand mismatch -- `pmov p0,z0\[3\]'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov p0.h, z0\[3\]
+.*: Error: expected an SVE vector or predicate register at operand 1 -- `pmov p16.h,z0'
+.*: Error: register element index out of range 0 to 1 at operand 2 -- `pmov p0.h,z31\[2\]'
+.*: Error: comma expected between operands at operand 2 -- `pmov p15.h'
+.*: Error: operand mismatch -- `pmov p15,z31.h\[4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov p15.h, z31\[4\]
+.*: Error: operand mismatch -- `pmov p7.h,z15.h'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov p7.h, z15
+.*: Error: expected an SVE vector register at operand 2 -- `pmov p7.h,x15.h'
+.*: Error: expected an SVE vector register at operand 2 -- `pmov p7.h,w15'
+.*: Error: operand mismatch -- `pmov p0,z0\[4\]'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov p0.h, z0\[4\]
+.*: Error: expected an SVE vector or predicate register at operand 1 -- `pmov p16.s,z0'
+.*: Error: register element index out of range 0 to 3 at operand 2 -- `pmov p0.s,z31\[5\]'
+.*: Error: comma expected between operands at operand 2 -- `pmov p15.s'
+.*: Error: operand mismatch -- `pmov p15,z31.s\[6\]'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov p15.h, z31\[6\]
+.*: Error: operand mismatch -- `pmov p7.s,z15.s'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov p7.s, z15
+.*: Error: expected an SVE vector register at operand 2 -- `pmov p7.s,w15.s'
+.*: Error: expected an SVE vector register at operand 2 -- `pmov p7.s,x15'
+.*: Error: operand mismatch -- `pmov p0,z0\[8\]'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov p0.h, z0\[8\]
+.*: Error: expected an SVE vector or predicate register at operand 1 -- `pmov p16.d,z0'
+.*: Error: register element index out of range 0 to 7 at operand 2 -- `pmov p0.d,z31\[10\]'
+.*: Error: comma expected between operands at operand 2 -- `pmov p15.d'
+.*: Error: operand mismatch -- `pmov p15,z31.d\[12\]'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov p15.h, z31\[12\]
+.*: Error: operand mismatch -- `pmov p7.d,z15.d'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov p7.d, z15
+.*: Error: expected an SVE vector register at operand 2 -- `pmov p7.d,x15.d'
+.*: Error: expected an SVE vector register at operand 2 -- `pmov p7.d,w15'
+.*: Error: operand mismatch -- `pmov z0,p0'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z0, p0.b
+.*: Error: expected an SVE predicate register at operand 2 -- `pmov z0,p16.b'
+.*: Error: register element index must be 0 at operand 1 -- `pmov z31\[1\],p0.b'
+.*: Error: comma expected between operands at operand 2 -- `pmov p15.b'
+.*: Error: operand mismatch -- `pmov z31.b\[4\],p15'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z31\[4\], p15.b
+.*: Error: operand mismatch -- `pmov z15.b,p7.b'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z15, p7.b
+.*: Error: expected an SVE vector or predicate register at operand 1 -- `pmov x15.b,p7.b'
+.*: Error: expected an SVE vector or predicate register at operand 1 -- `pmov w15.b,p7'
+.*: Error: operand mismatch -- `pmov z0\[3\],p0'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z0\[3\], p0.b
+.*: Error: expected an SVE predicate register at operand 2 -- `pmov z0,p16.h'
+.*: Error: register element index out of range 0 to 1 at operand 1 -- `pmov z31\[2\],p0.h'
+.*: Error: comma expected between operands at operand 2 -- `pmov p15.h'
+.*: Error: operand mismatch -- `pmov z31.h\[5\],p15'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z31\[5\], p15.b
+.*: Error: operand mismatch -- `pmov z15,p7'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z15, p7.b
+.*: Error: operand mismatch -- `pmov z8.h,p7.h'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z8, p7.h
+.*: Error: expected an SVE vector or predicate register at operand 1 -- `pmov x8.h,p7.h'
+.*: Error: expected an SVE vector or predicate register at operand 1 -- `pmov w8.h,p7'
+.*: Error: register element index out of range 0 to 3 at operand 1 -- `pmov z0\[5\],p0.s'
+.*: Error: expected an SVE predicate register at operand 2 -- `pmov z0,p16.s'
+.*: Error: register element index out of range 0 to 3 at operand 1 -- `pmov z31\[6\],p0.s'
+.*: Error: comma expected between operands at operand 2 -- `pmov p15.s'
+.*: Error: operand mismatch -- `pmov z31.s\[7\],p15'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z31\[7\], p15.b
+.*: Error: operand mismatch -- `pmov z15,p7'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z15, p7.b
+.*: Error: operand mismatch -- `pmov z8.s,p7.s'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z8, p7.s
+.*: Error: expected an SVE vector or predicate register at operand 1 -- `pmov x8.s,p7.s'
+.*: Error: expected an SVE vector or predicate register at operand 1 -- `pmov w8.s,p7'
+.*: Error: register element index out of range 0 to 7 at operand 1 -- `pmov z0\[8\],p0.d'
+.*: Error: expected an SVE predicate register at operand 2 -- `pmov z0,p16.d'
+.*: Error: register element index out of range 0 to 7 at operand 1 -- `pmov z31\[9\],p0.d'
+.*: Error: comma expected between operands at operand 2 -- `pmov p15.d'
+.*: Error: operand mismatch -- `pmov z31.d\[10\],p15'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z31\[10\], p15.b
+.*: Error: operand mismatch -- `pmov z15,p7'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z15, p7.b
+.*: Error: operand mismatch -- `pmov z8.d,p7.d'
+.*: Info:    did you mean this\?
+.*: Info:    	pmov z8, p7.d
+.*: Error: expected an SVE vector or predicate register at operand 1 -- `pmov w8.d,p7.d'
+.*: Error: expected an SVE vector or predicate register at operand 1 -- `pmov x8.d,p7'
diff --git a/gas/testsuite/gas/aarch64/sve2p1-7-invalid.s b/gas/testsuite/gas/aarch64/sve2p1-7-invalid.s
new file mode 100644
index 00000000000..b83ef36ba8c
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve2p1-7-invalid.s
@@ -0,0 +1,76 @@ 
+/* PMOV (to predicate).  */
+pmov	p0, z0
+pmov	p16.b, z0
+pmov	p0.b, z31[1]
+pmov	p15.b
+pmov	p15, z31.b[4]
+pmov	p7, z15.b
+mov	p7, w15.b
+mov	p7.b, x15
+
+pmov	p0, z0[3]
+pmov	p16.h, z0
+pmov	p0.h, z31[2]
+pmov	p15.h
+pmov	p15, z31.h[4]
+pmov	p7.h, z15.h
+pmov	p7.h, x15.h
+pmov	p7.h, w15
+
+pmov	p0, z0[4]
+pmov	p16.s, z0
+pmov	p0.s, z31[5]
+pmov	p15.s
+pmov	p15, z31.s[6]
+pmov	p7.s, z15.s
+pmov	p7.s, w15.s
+pmov	p7.s, x15
+
+pmov	p0, z0[8]
+pmov	p16.d, z0
+pmov	p0.d, z31[10]
+pmov	p15.d
+pmov	p15, z31.d[12]
+pmov	p7.d, z15.d
+pmov	p7.d, x15.d
+pmov	p7.d, w15
+
+/* PMOV (to vector).  */
+pmov	z0, p0
+pmov	z0, p16.b
+pmov	z31[1], p0.b
+pmov	p15.b
+pmov	z31.b[4], p15
+pmov	z15.b, p7.b
+pmov	x15.b, p7.b
+pmov	w15.b, p7
+
+pmov	z0[3], p0
+pmov	z0, p16.h
+pmov	z31[2], p0.h
+pmov	p15.h
+pmov	z31.h[5], p15
+pmov	z15, p7
+pmov	z8.h, p7.h
+pmov	x8.h, p7.h
+pmov	w8.h, p7
+
+pmov	z0[5], p0.s
+pmov	z0, p16.s
+pmov	z31[6], p0.s
+pmov	p15.s
+pmov	z31.s[7], p15
+pmov	z15, p7
+pmov	z8.s, p7.s
+pmov	x8.s, p7.s
+pmov	w8.s, p7
+
+pmov	z0[8], p0.d
+pmov	z0, p16.d
+pmov	z31[9], p0.d
+pmov	p15.d
+pmov	z31.d[10], p15
+pmov	z15, p7
+pmov	z8.d, p7.d
+pmov	w8.d, p7.d
+pmov	x8.d, p7
diff --git a/gas/testsuite/gas/aarch64/sve2p1-7.d b/gas/testsuite/gas/aarch64/sve2p1-7.d
new file mode 100644
index 00000000000..6bd1a22aaf4
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve2p1-7.d
@@ -0,0 +1,64 @@ 
+#name: Test of SVE2.1 pmov instruction.
+#as: -march=armv9.4-a
+#objdump: -dr
+
+[^:]+:     file format .*
+
+
+[^:]+:
+
+[^:]+:
+.*:	052a3800 	pmov	p0.b, z0
+.*:	052a380f 	pmov	p15.b, z0
+.*:	052a3be0 	pmov	p0.b, z31
+.*:	052a3bef 	pmov	p15.b, z31
+.*:	052a3bef 	pmov	p15.b, z31
+.*:	052a39e7 	pmov	p7.b, z15
+.*:	052c3800 	pmov	p0.h, z0
+.*:	052c380f 	pmov	p15.h, z0
+.*:	052c3be0 	pmov	p0.h, z31
+.*:	052e3800 	pmov	p0.h, z0\[1\]
+.*:	052e3bef 	pmov	p15.h, z31\[1\]
+.*:	052c39e7 	pmov	p7.h, z15
+.*:	052c3903 	pmov	p3.h, z8
+.*:	05683800 	pmov	p0.s, z0
+.*:	0568380f 	pmov	p15.s, z0
+.*:	05683be0 	pmov	p0.s, z31
+.*:	056e3800 	pmov	p0.s, z0\[3\]
+.*:	056e3bef 	pmov	p15.s, z31\[3\]
+.*:	056a39e7 	pmov	p7.s, z15\[1\]
+.*:	05683903 	pmov	p3.s, z8
+.*:	05a83800 	pmov	p0.d, z0
+.*:	05a8380f 	pmov	p15.d, z0
+.*:	05a83be0 	pmov	p0.d, z31
+.*:	05ee3800 	pmov	p0.d, z0\[7\]
+.*:	05ee3bef 	pmov	p15.d, z31\[7\]
+.*:	05ae39e7 	pmov	p7.d, z15\[3\]
+.*:	05a83903 	pmov	p3.d, z8
+.*:	052b3800 	pmov	z0, p0.b
+.*:	052b381f 	pmov	z31, p0.b
+.*:	052b39e0 	pmov	z0, p15.b
+.*:	052b39ff 	pmov	z31, p15.b
+.*:	052b38e0 	pmov	z0, p7.b
+.*:	052b38ef 	pmov	z15, p7.b
+.*:	052d3800 	pmov	z0, p0.h
+.*:	052d381f 	pmov	z31, p0.h
+.*:	052f3800 	pmov	z0\[1\], p0.h
+.*:	052d39e0 	pmov	z0, p15.h
+.*:	052f39ff 	pmov	z31\[1\], p15.h
+.*:	052d39ef 	pmov	z15, p15.h
+.*:	052d38e8 	pmov	z8, p7.h
+.*:	05693800 	pmov	z0, p0.s
+.*:	0569381f 	pmov	z31, p0.s
+.*:	056f3800 	pmov	z0\[3\], p0.s
+.*:	056939e0 	pmov	z0, p15.s
+.*:	056f39ff 	pmov	z31\[3\], p15.s
+.*:	056d39ef 	pmov	z15\[2\], p15.s
+.*:	056938e8 	pmov	z8, p7.s
+.*:	05a93800 	pmov	z0, p0.d
+.*:	05a9381f 	pmov	z31, p0.d
+.*:	05ef3800 	pmov	z0\[7\], p0.d
+.*:	05a939e0 	pmov	z0, p15.d
+.*:	05ef39ff 	pmov	z31\[7\], p15.d
+.*:	05af39ef 	pmov	z15\[3\], p15.d
+.*:	05a938e8 	pmov	z8, p7.d
diff --git a/gas/testsuite/gas/aarch64/sve2p1-7.s b/gas/testsuite/gas/aarch64/sve2p1-7.s
new file mode 100644
index 00000000000..3d16548460a
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve2p1-7.s
@@ -0,0 +1,63 @@ 
+/* PMOV (to predicate).  */
+pmov	p0.b, z0
+pmov	p15.b, z0
+pmov	p0.b, z31
+pmov	p15.b, z31
+pmov	p15.b, z31[0]
+pmov	p7.b, z15
+
+pmov	p0.h, z0[0]
+pmov	p15.h, z0[0]
+pmov	p0.h, z31[0]
+pmov	p0.h, z0[1]
+pmov	p15.h, z31[1]
+pmov	p7.h, z15[0]
+pmov	p3.h, z8
+
+pmov	p0.s, z0[0]
+pmov	p15.s, z0[0]
+pmov	p0.s, z31[0]
+pmov	p0.s, z0[3]
+pmov	p15.s, z31[3]
+pmov	p7.s, z15[1]
+pmov	p3.s, z8
+
+pmov	p0.d, z0[0]
+pmov	p15.d, z0[0]
+pmov	p0.d, z31[0]
+pmov	p0.d, z0[7]
+pmov	p15.d, z31[7]
+pmov	p7.d, z15[3]
+pmov	p3.d, z8
+
+/* PMOV (to vector).  */
+pmov	z0, p0.b
+pmov	z31, p0.b
+pmov	z0, p15.b
+pmov	z31, p15.b
+pmov	z0[0], p7.b
+pmov	z15[0], p7.b
+
+pmov	z0[0], p0.h
+pmov	z31[0], p0.h
+pmov	z0[1], p0.h
+pmov	z0[0], p15.h
+pmov	z31[1], p15.h
+pmov	z15[0], p15.h
+pmov	z8, p7.h
+
+pmov	z0[0], p0.s
+pmov	z31[0], p0.s
+pmov	z0[3], p0.s
+pmov	z0[0], p15.s
+pmov	z31[3], p15.s
+pmov	z15[2], p15.s
+pmov	z8, p7.s
+
+pmov	z0[0], p0.d
+pmov	z31[0], p0.d
+pmov	z0[7], p0.d
+pmov	z0[0], p15.d
+pmov	z31[7], p15.d
+pmov	z15[3], p15.d
+pmov	z8, p7.d
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 9daa911394f..5baa8edb0b5 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -857,6 +857,14 @@  enum aarch64_opnd
   AARCH64_OPND_SME_Zn_INDEX3_14,    /* Zn[index], bits [9:5] and [16:14].  */
   AARCH64_OPND_SME_Zn_INDEX3_15,    /* Zn[index], bits [9:5] and [17:15].  */
   AARCH64_OPND_SME_Zn_INDEX4_14,    /* Zn[index], bits [9:5] and [17:14].  */
+  AARCH64_OPND_SVE_Zn0_INDEX,	    /* Zn[index], bits [9:5].  */
+  AARCH64_OPND_SVE_Zn1_17_INDEX,    /* Zn[index], bits [9:5,17].  */
+  AARCH64_OPND_SVE_Zn2_18_INDEX,    /* Zn[index], bits [9:5,18:17].  */
+  AARCH64_OPND_SVE_Zn3_22_INDEX,    /* Zn[index], bits [9:5,18:17,22].  */
+  AARCH64_OPND_SVE_Zd0_INDEX,	    /* Zn[index], bits [4:0].  */
+  AARCH64_OPND_SVE_Zd1_17_INDEX,    /* Zn[index], bits [4:0,17].  */
+  AARCH64_OPND_SVE_Zd2_18_INDEX,    /* Zn[index], bits [4:0,18:17].  */
+  AARCH64_OPND_SVE_Zd3_22_INDEX,    /* Zn[index], bits [4:0,18:17,22].  */
   AARCH64_OPND_SME_VLxN_10,	/* VLx2 or VLx4, in bit 10.  */
   AARCH64_OPND_SME_VLxN_13,	/* VLx2 or VLx4, in bit 13.  */
   AARCH64_OPND_SME_ZT0,		/* The fixed token zt0/ZT0 (not encoded).  */
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 0b090557808..0e726102693 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -387,6 +387,8 @@  const aarch64_field fields[] =
     {  5, 14 },	/* imm14: in test bit and branch instructions.  */
     {  0, 16 },	/* imm16_0: in udf instruction. */
     {  5, 16 },	/* imm16_5: in exception instructions.  */
+    { 17,  1 }, /* imm17_1: in 1 bit element index.  */
+    { 17,  2 }, /* imm17_2: in 2 bits element index.  */
     {  5, 19 },	/* imm19: e.g. in CBZ.  */
     {  0, 26 },	/* imm26: in unconditional branch instructions.  */
     { 16,  3 },	/* immb: in advsimd shift by immediate instructions.  */
@@ -1874,6 +1876,14 @@  operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 	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_Zn0_INDEX:
+	case AARCH64_OPND_SVE_Zn1_17_INDEX:
+	case AARCH64_OPND_SVE_Zn2_18_INDEX:
+	case AARCH64_OPND_SVE_Zn3_22_INDEX:
+	case AARCH64_OPND_SVE_Zd0_INDEX:
+	case AARCH64_OPND_SVE_Zd1_17_INDEX:
+	case AARCH64_OPND_SVE_Zd2_18_INDEX:
+	case AARCH64_OPND_SVE_Zd3_22_INDEX:
 	  size = get_operand_fields_width (get_operand_from_code (type)) - 5;
 	  if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
 			      0, (1 << size) - 1))
@@ -4248,11 +4258,11 @@  aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_SVE_Zt:
     case AARCH64_OPND_SME_Zm:
       if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
-	snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
+       snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
       else
-	snprintf (buf, size, "%s",
-		  style_reg (styler, "z%d.%s", opnd->reg.regno,
-			     aarch64_get_qualifier_name (opnd->qualifier)));
+       snprintf (buf, size, "%s",
+		 style_reg (styler, "z%d.%s", opnd->reg.regno,
+			    aarch64_get_qualifier_name (opnd->qualifier)));
       break;
 
     case AARCH64_OPND_SVE_ZnxN:
@@ -4307,6 +4317,22 @@  aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 		style_imm (styler, "%" PRIi64, opnd->reglane.index));
       break;
 
+    case AARCH64_OPND_SVE_Zn0_INDEX:
+    case AARCH64_OPND_SVE_Zn1_17_INDEX:
+    case AARCH64_OPND_SVE_Zn2_18_INDEX:
+    case AARCH64_OPND_SVE_Zn3_22_INDEX:
+    case AARCH64_OPND_SVE_Zd0_INDEX:
+    case AARCH64_OPND_SVE_Zd1_17_INDEX:
+    case AARCH64_OPND_SVE_Zd2_18_INDEX:
+    case AARCH64_OPND_SVE_Zd3_22_INDEX:
+      if (opnd->reglane.index == 0)
+	snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
+      else
+	snprintf (buf, size, "%s[%s]",
+		  style_reg (styler, "z%d", opnd->reglane.regno),
+		  style_imm (styler, "%" PRIi64, opnd->reglane.index));
+      break;
+
     case AARCH64_OPND_SME_ZAda_1b:
     case AARCH64_OPND_SME_ZAda_2b:
     case AARCH64_OPND_SME_ZAda_3b:
diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h
index e97ea5d27f2..49310960305 100644
--- a/opcodes/aarch64-opc.h
+++ b/opcodes/aarch64-opc.h
@@ -191,6 +191,8 @@  enum aarch64_field_kind
   FLD_imm14,
   FLD_imm16_0,
   FLD_imm16_5,
+  FLD_imm17_1,
+  FLD_imm17_2,
   FLD_imm19,
   FLD_imm26,
   FLD_immb,
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 0bd2cc0c34b..ad0d8ae7be6 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -1567,6 +1567,10 @@ 
   QLF3(S_B,P_Z,S_B),                                    \
   QLF3(S_B,P_M,S_B),                                    \
 }
+#define OP_SVE_BU                                       \
+{                                                       \
+  QLF2(S_B,NIL),					\
+}
 #define OP_SVE_BUB                                      \
 {                                                       \
   QLF3(S_B,NIL,S_B),                                    \
@@ -1869,9 +1873,21 @@ 
 {                                                       \
   QLF3(S_S,P_Z,NIL),                                    \
 }
-#define OP_SVE_UB                                       \
-{                                                       \
-  QLF2(NIL,S_B),                                        \
+#define OP_SVE_UB				       \
+{						       \
+  QLF2(NIL,S_B),					\
+}
+#define OP_SVE_UD				       \
+{						       \
+  QLF2(NIL,S_D),					\
+}
+#define OP_SVE_UH				       \
+{						       \
+  QLF2(NIL,S_H),					\
+}
+#define OP_SVE_US				       \
+{						       \
+  QLF2(NIL,S_S),					\
 }
 #define OP_SVE_UUD                                      \
 {                                                       \
@@ -6649,6 +6665,16 @@  const struct aarch64_opcode aarch64_opcode_table[] =
   SVE2p1_INSN("zipq1",0x4400e000, 0xff20fc00, sve_size_bhsd, 0, OP3 (SVE_Zd, SVE_Zn, SVE_Zm_16), OP_SVE_VVV_BHSD, 0, 0),
   SVE2p1_INSN("zipq2",0x4400e400, 0xff20fc00, sve_size_bhsd, 0, OP3 (SVE_Zd, SVE_Zn, SVE_Zm_16), OP_SVE_VVV_BHSD, 0, 0),
 
+  SVE2p1_INSN("pmov",0x052a3800, 0xfffffc10, sve_misc, 0, OP2 (SVE_Pd, SVE_Zn0_INDEX), OP_SVE_BU, 0, 0),
+  SVE2p1_INSN("pmov",0x052c3800, 0xfffdfc10, sve_misc, 0, OP2 (SVE_Pd, SVE_Zn1_17_INDEX), OP_SVE_HU, 0, 0),
+  SVE2p1_INSN("pmov",0x05683800, 0xfff9fc10, sve_misc, 0, OP2 (SVE_Pd, SVE_Zn2_18_INDEX), OP_SVE_SU, 0, 0),
+  SVE2p1_INSN("pmov",0x05a83800, 0xffb9fc10, sve_misc, 0, OP2 (SVE_Pd, SVE_Zn3_22_INDEX), OP_SVE_DU, 0, 0),
+
+  SVE2p1_INSN("pmov",0x052b3800, 0xfffffe00, sve_misc, 0, OP2 (SVE_Zd0_INDEX, SVE_Pg4_5), OP_SVE_UB, 0, 0),
+  SVE2p1_INSN("pmov",0x052d3800, 0xfffdfe00, sve_misc, 0, OP2 (SVE_Zd1_17_INDEX, SVE_Pg4_5), OP_SVE_UH, 0, 0),
+  SVE2p1_INSN("pmov",0x05693800, 0xfff9fe00, sve_misc, 0, OP2 (SVE_Zd2_18_INDEX, SVE_Pg4_5), OP_SVE_US, 0, 0),
+  SVE2p1_INSN("pmov",0x05a93800, 0xffb9fe00, sve_misc, 0, OP2 (SVE_Zd3_22_INDEX, SVE_Pg4_5), OP_SVE_UD, 0, 0),
+
   SVE2p1_INSN("ld1q",0xc400a000, 0xffe0e000, sve_misc, 0, OP3 (SVE_ZtxN, SVE_Pg3, SVE_ADDR_ZX), OP_SVE_QZD, F_OD (1), 0),
   SVE2p1_INSN("ld2q",0xa490e000, 0xfff0e000, sve_misc, 0, OP3 (SVE_ZtxN, SVE_Pg3, SVE_ADDR_RI_S4x2xVL), OP_SVE_QZU, F_OD (2), 0),
   SVE2p1_INSN("ld3q",0xa510e000, 0xfff0e000, sve_misc, 0, OP3 (SVE_ZtxN, SVE_Pg3, SVE_ADDR_RI_S4x3xVL), OP_SVE_QZU, F_OD (3), 0),
@@ -7478,6 +7504,28 @@  const struct aarch64_opcode aarch64_opcode_table[] =
       F(FLD_SVE_Zn, FLD_imm3_15), "an indexed SVE vector register")	\
     Y(SVE_REG, simple_index, "SME_Zn_INDEX4_14", 0,			\
       F(FLD_SVE_Zn, FLD_imm4_14), "an indexed SVE vector register")	\
+    Y(SVE_REG, regno, "SVE_Zn0_INDEX", 0, F(FLD_SVE_Zn),		\
+      "an SVE vector register with option zero index")			\
+    Y(SVE_REG, simple_index, "SVE_Zn1_17_INDEX", 0,			\
+      F(FLD_SVE_Zn, FLD_imm17_1),					\
+      "an SVE vector register with optional one bit index")		\
+    Y(SVE_REG, simple_index, "SVE_Zn2_18_INDEX", 0,			\
+      F(FLD_SVE_Zn, FLD_imm17_2),					\
+      "an SVE vector register with optional two bit index")		\
+    Y(SVE_REG, simple_index, "SVE_Zn3_22_INDEX", 0,			\
+      F(FLD_SVE_Zn, FLD_SVE_i3h, FLD_imm17_2),				\
+      "an SVE vector register with optional three bit index")		\
+    Y(SVE_REG, regno, "SVE_Zd0_INDEX", 0, F(FLD_SVE_Zd),		\
+      "an SVE vector register with option zero index")			\
+    Y(SVE_REG, simple_index, "SVE_Zd1_17_INDEX", 0,			\
+      F(FLD_SVE_Zd, FLD_imm17_1),					\
+      "an SVE vector register with optional one bit index")		\
+    Y(SVE_REG, simple_index, "SVE_Zd2_18_INDEX", 0,			\
+      F(FLD_SVE_Zd, FLD_imm17_2),					\
+      "an SVE vector register with optional two bit index")		\
+    Y(SVE_REG, simple_index, "SVE_Zd3_22_INDEX", 0,			\
+      F(FLD_SVE_Zd, FLD_SVE_i3h, FLD_imm17_2),				\
+      "an SVE vector register with optional three bit index")		\
     Y(IMMEDIATE, imm, "SME_VLxN_10", 0, F(FLD_SME_VL_10),		\
       "VLx2 or VLx4")							\
     Y(IMMEDIATE, imm, "SME_VLxN_13", 0, F(FLD_SME_VL_13),		\