arm64/instgen: support register with index in SVE

This CL generates CL 759780.

Change-Id: I430b74f92be3e6c5dc9c0f57fc8081612f16f874
Reviewed-on: https://go-review.googlesource.com/c/arch/+/759800
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/arm64/instgen/encodings.go b/arm64/instgen/encodings.go
index dd932cf..fc099be 100644
--- a/arm64/instgen/encodings.go
+++ b/arm64/instgen/encodings.go
@@ -692,4 +692,290 @@
 	`Is the number [0-31] of the source and destination SIMD&FP register, encoded in the "Vdn" field.
 bit range mappings:
 Vdn: [0:5)`: {"encodeVdn05", `return v & 31, true`, "enc_Vdn"},
+	`For the "16-bit to 32-bit" variant: is the immediate index of a pair of 16-bit elements within each 128-bit vector segment, in the range 0 to 3, encoded in the "i2" field.
+bit range mappings:
+i2: [19:21)
+`: {"encodeI2_1921_16To32Bit", `if v > 3 {
+		return 0, false
+	}
+	return v << 19, true`, "enc_i2"},
+	`For the "16-bit to 64-bit" variant: is the immediate index of a 64-bit group of four 16-bit values within each 128-bit vector segment, in the range 0 to 1, encoded in the "i1" field.
+bit range mappings:
+i1: [20:21)
+`: {"encodeI1_2021_16To64Bit", `if v > 1 {
+		return 0, false
+	}
+	return v << 20, true`, "enc_i1"},
+	`For the "16-bit to 64-bit" variant: is the name of the second source scalable vector register Z0-Z15, encoded in the "Zm" field.
+bit range mappings:
+Zm: [16:20)
+`: {"encodeZm1620_16To64Bit", `if v > 15 {
+		return 0, false
+	}
+	return v << 16, true`, "enc_Zm"},
+	`For the "16-bit" and "32-bit" variants: is the name of the second source scalable vector register Z0-Z7, encoded in the "Zm" field.
+bit range mappings:
+Zm: [16:19)
+`: {"encodeZm1619_16Bit32Bit", `if v > 7 {
+		return 0, false
+	}
+	return v << 16, true`, "enc_Zm"},
+	`For the "16-bit" variant: is the element index, in the range 0 to 7, encoded in the "i3h:i3l" fields.
+bit range mappings:
+i3h: [22:23)
+i3l: [19:21)
+`: {"encodeI3hI3l_1923_16Bit", `if v > 7 {
+		return 0, false
+	}
+	return (v&3)<<19 | (v>>2)<<22, true`, "enc_i3h_i3l"},
+	`For the "32-bit" variant: is the element index, in the range 0 to 3, encoded in the "i2" field.
+bit range mappings:
+i2: [19:21)
+`: {"encodeI2_1921_32Bit", `if v > 3 {
+		return 0, false
+	}
+	return v << 19, true`, "enc_i2"},
+	`For the "32-bit" variant: is the element index, in the range 0 to 7, encoded in the "i3h:i3l" fields.
+bit range mappings:
+i3h: [19:21)
+i3l: [11:12)
+`: {"encodeI3hI3l_1119_32Bit", `if v > 7 {
+		return 0, false
+	}
+	return (v&1)<<11 | (v>>1)<<19, true`, "enc_i3h_i3l"},
+	`For the "32-bit" variant: is the name of the second source scalable vector register Z0-Z7, encoded in the "Zm" field.
+bit range mappings:
+Zm: [16:19)
+`: {"encodeZm1619_32Bit", `if v > 7 {
+		return 0, false
+	}
+	return v << 16, true`, "enc_Zm"},
+	`For the "64-bit" variant: is the element index, in the range 0 to 1, encoded in the "i1" field.
+bit range mappings:
+i1: [20:21)
+`: {"encodeI1_2021_64Bit", `if v > 1 {
+		return 0, false
+	}
+	return v << 20, true`, "enc_i1"},
+	`For the "64-bit" variant: is the element index, in the range 0 to 3, encoded in the "i2h:i2l" fields.
+bit range mappings:
+i2h: [20:21)
+i2l: [11:12)
+`: {"encodeI2hI2l_1120_64Bit", `if v > 3 {
+		return 0, false
+	}
+	return (v&1)<<11 | (v>>1)<<20, true`, "enc_i2h_i2l"},
+	`For the "64-bit" variant: is the name of the second source scalable vector register Z0-Z15, encoded in the "Zm" field.
+bit range mappings:
+Zm: [16:20)
+`: {"encodeZm1620_64Bit", `if v > 15 {
+		return 0, false
+	}
+	return v << 16, true`, "enc_Zm"},
+	`For the "8-bit to 16-bit" variant: is the immediate index of a pair of 8-bit elements within each 128-bit vector segment, in the range 0 to 7, encoded in the "i3h:i3l" fields.
+bit range mappings:
+i3h: [22:23)
+i3l: [19:21)
+`: {"encodeI3hI3l_1923_8To16Bit", `if v > 7 {
+		return 0, false
+	}
+	return (v&3)<<19 | (v>>2)<<22, true`, "enc_i3h_i3l"},
+	`For the "8-bit to 32-bit" variant: is the immediate index of a 32-bit group of four 8-bit values within each 128-bit vector segment, in the range 0 to 3, encoded in the "i2" field.
+bit range mappings:
+i2: [19:21)
+`: {"encodeI2_1921_8To32Bit", `if v > 3 {
+		return 0, false
+	}
+	return v << 19, true`, "enc_i2"},
+	`For the "8-bit to 32-bit" variant: is the name of the second source scalable vector register Z0-Z7, encoded in the "Zm" field.
+bit range mappings:
+Zm: [16:19)
+`: {"encodeZm1619_8To32Bit", `if v > 7 {
+		return 0, false
+	}
+	return v << 16, true`, "enc_Zm"},
+	`For the "Double-precision" variant: is the immediate index, in the range 0 to 1, encoded in the "i1" field.
+bit range mappings:
+i1: [20:21)
+`: {"encodeI1_2021_DoublePrecision", `if v > 1 {
+		return 0, false
+	}
+	return v << 20, true`, "enc_i1"},
+	`For the "Double-precision" variant: is the name of the second source scalable vector register Z0-Z15, encoded in the "Zm" field.
+bit range mappings:
+Zm: [16:20)
+`: {"encodeZm1620_DoublePrecision", `if v > 15 {
+		return 0, false
+	}
+	return v << 16, true`, "enc_Zm"},
+	`For the "Doubleword" variant: is the optional portion index, in the range 0 to 7, defaulting to 0, encoded in the "i3h:i3l" fields.
+bit range mappings:
+i3h: [22:23)
+i3l: [17:19)
+`: {"encodeI3hI3l_1722_Doubleword", `if v > 7 {
+		return 0, false
+	}
+	return (v&3)<<17 | (v>>2)<<22, true`, "enc_i3h_i3l"},
+	`For the "Half-precision" and "Single-precision" variants: is the name of the second source scalable vector register Z0-Z7, encoded in the "Zm" field.
+bit range mappings:
+Zm: [16:19)
+`: {"encodeZm1619_HalfSinglePrecision", `if v > 7 {
+		return 0, false
+	}
+	return v << 16, true`, "enc_Zm"},
+	`For the "Half-precision" variant: is the immediate index, in the range 0 to 7, encoded in the "i3h:i3l" fields.
+bit range mappings:
+i3h: [22:23)
+i3l: [19:21)
+`: {"encodeI3hI3l_1923_HalfPrecision", `if v > 7 {
+		return 0, false
+	}
+	return (v&3)<<19 | (v>>2)<<22, true`, "enc_i3h_i3l"},
+	`For the "Halfword" variant: is the optional portion index, in the range 0 to 1, defaulting to 0, encoded in the "i1" field.
+bit range mappings:
+i1: [17:18)
+`: {"encodeI1_1718_Halfword", `if v > 1 {
+		return 0, false
+	}
+	return v << 17, true`, "enc_i1"},
+	`For the "Single-precision" variant: is the immediate index, in the range 0 to 3, encoded in the "i2" field.
+bit range mappings:
+i2: [19:21)
+`: {"encodeI2_1921_SinglePrecision", `if v > 3 {
+		return 0, false
+	}
+	return v << 19, true`, "enc_i2"},
+	`For the "Word" variant: is the optional portion index, in the range 0 to 3, defaulting to 0, encoded in the "i2" field.
+bit range mappings:
+i2: [17:19)
+`: {"encodeI2_1719_Word", `if v > 3 {
+		return 0, false
+	}
+	return v << 17, true`, "enc_i2"},
+	`Is the immediate index of a 32-bit group of four 8-bit values within each 128-bit vector segment, in the range 0 to 3, encoded in the "i2" field.
+bit range mappings:
+i2: [19:21)
+`: {"encodeI2_1921_8BitGroup", `if v > 3 {
+		return 0, false
+	}
+	return v << 19, true`, "enc_i2"},
+	`Is the immediate index of a pair of 16-bit elements within each 128-bit vector segment, in the range 0 to 3, encoded in the "i2" field.
+bit range mappings:
+i2: [19:21)
+`: {"encodeI2_1921_Pair16Bit", `if v > 3 {
+		return 0, false
+	}
+	return v << 19, true`, "enc_i2"},
+	`Is the immediate index of a pair of 8-bit elements within each 128-bit vector segment, in the range 0 to 7, encoded in the "i3h:i3l" fields.
+bit range mappings:
+i3h: [19:21)
+i3l: [11:12)
+`: {"encodeI3hI3l_1119_Pair8Bit", `if v > 7 {
+		return 0, false
+	}
+	return (v&1)<<11 | (v>>1)<<19, true`, "enc_i3h_i3l"},
+	`Is the immediate index, in the range 0 to 15, encoded in the "i4h:i4l" fields.
+bit range mappings:
+i4h: [19:21)
+i4l: [10:12)
+`: {"encodeI4hI4l_1019", `if v > 15 {
+		return 0, false
+	}
+	return (v&3)<<10 | (v>>2)<<19, true`, "enc_i4h_i4l"},
+	`Is the immediate index, in the range 0 to 7, encoded in the "i3h:i3l" fields.
+bit range mappings:
+i3h: [19:21)
+i3l: [11:12)
+`: {"encodeI3hI3l_1119", `if v > 7 {
+		return 0, false
+	}
+	return (v&1)<<11 | (v>>1)<<19, true`, "enc_i3h_i3l"},
+	`Is the immediate index, in the range 0 to 7, encoded in the "i3h:i3l" fields.
+bit range mappings:
+i3h: [22:23)
+i3l: [19:21)
+`: {"encodeI3hI3l_1922", `if v > 7 {
+		return 0, false
+	}
+	return (v&3)<<19 | (v>>2)<<22, true`, "enc_i3h_i3l"},
+	`Is the immediate index, in the range 0 to one less than the number of elements in 128 bits, encoded in "i1:tsz".
+bit range mappings:
+i1: [20:21)
+tsz: [16:20)
+`: {"encodeI1Tsz_Delegate", `// The statement "range 0 to one less than the number of elements in 128 bits"
+	// is not possible to handle here, we delegate this to the caller.
+	return codeI1Tsz, false`, "enc_i1_tsz"},
+	`Is the immediate index, in the range 0 to one less than the number of elements in 512 bits, encoded in "imm2:tsz".
+bit range mappings:
+imm2: [22:24)
+tsz: [16:21)
+`: {"encodeImm2Tsz_Delegate", `// The statement "range 0 to one less than the number of elements in 512 bits"
+	// is not possible to handle here, we delegate this to the caller.
+	return codeImm2Tsz, false`, "enc_imm2_tsz"},
+	`Is the name of the first source scalable predicate register PN8-PN15, with predicate-as-counter encoding, encoded in the "PNn" field.
+bit range mappings:
+PNn: [5:8)
+`: {"encodePnN_58", `if v >= 24 && v <= 31 {
+		// PN registers starts from 16.
+		return (v - 24) << 5, true
+	}
+	return 0, false`, "enc_PNn"},
+	`Is the name of the second source scalable vector register Z0-Z7, encoded in the "Zm" field.
+bit range mappings:
+Zm: [16:19)
+`: {"encodeZm_1619_Range0_7", `if v <= 7 {
+		return v << 16, true
+	}
+	return 0, false`, "enc_Zm"},
+	`Is the portion index, in the range 0 to 3, encoded in the "imm2" field.
+bit range mappings:
+imm2: [8:10)
+`: {"encodeImm2_810", `if v > 3 {
+		return 0, false
+	}
+	return v << 8, true`, "enc_imm2"},
+	`Is the size specifier,
+tsz	<T>
+0000	RESERVED
+xxx1	B
+xx10	H
+x100	S
+1000	D
+bit range mappings:
+tsz: [16:20)
+`: {"encodeTsz_1620_SizeSpecifier4", `switch v {
+	case ARNG_B:
+		return 1 << 16, true
+	case ARNG_H:
+		return 2 << 16, true
+	case ARNG_S:
+		return 4 << 16, true
+	case ARNG_D:
+		return 8 << 16, true
+	}
+	return 0, false`, "enc_tsz"},
+
+	`Is the size specifier,
+tsz	<T>
+00000	RESERVED
+xxxx1	B
+xxx10	H
+xx100	S
+x1000	D
+10000	Q
+bit range mappings:
+tsz: [16:21)
+`: {"encodeTsz_1621_SizeSpecifier5", `switch v {
+	case ARNG_B:
+		return 1 << 16, true
+	case ARNG_H:
+		return 2 << 16, true
+	case ARNG_S:
+		return 4 << 16, true
+	case ARNG_D:
+		return 8 << 16, true
+	case ARNG_Q:
+		return 16 << 16, true
+	}
+	return 0, false`, "enc_tsz"},
 }
diff --git a/arm64/instgen/generator.go b/arm64/instgen/generator.go
index 9f615b4..f9511e4 100644
--- a/arm64/instgen/generator.go
+++ b/arm64/instgen/generator.go
@@ -202,6 +202,9 @@
 	"AC_ZREG":    0,
 	"AC_SPZGREG": 1,
 	"AC_VREG":    1,
+	"AC_ARNGIDX": 2,
+	"AC_ZREGIDX": 2,
+	"AC_PREGIDX": 2,
 }
 
 func readExistingGoOps(aoutPath string) map[string]bool {
@@ -556,6 +559,10 @@
 		s = strings.Replace(s, ".", "_", -1)
 		s = strings.Replace(s, " ", "_", -1)
 		s = strings.Replace(s, "|", "", -1)
+		s = strings.Replace(s, "[", "_", -1)
+		s = strings.Replace(s, "]", "_", -1)
+		s = strings.Replace(s, "{", "", -1)
+		s = strings.Replace(s, "}", "", -1)
 		return s
 	}
 
@@ -712,6 +719,7 @@
 	"Pm":  "P",
 	"Pg":  "P",
 	"PNd": "PN",
+	"PNn": "PN",
 	"Pv":  "P",
 
 	"Vd": "V",
@@ -914,6 +922,64 @@
 						log.Fatalf("Unexpected V with fixed arrangement: %s", opName)
 					}
 				}
+			} else if op.Typ == "AC_ARNGIDX" || op.Typ == "AC_ZREGIDX" || op.Typ == "AC_PREGIDX" {
+				// Operands that takes SVE/SIMD registers and arrangement with index.
+				// reg.T[index]
+				var regPrefix string
+				var regName string
+				var arrangement string
+				index := rng.IntN(4)
+
+				if op.Typ == "AC_ARNGIDX" {
+					parts := strings.Split(opName, ".")
+					regName = strings.TrimSuffix(strings.TrimPrefix(parts[0], "<"), ">")
+					regPrefix = regMap[regName]
+					if regPrefix == "" {
+						log.Fatalf("Unknown register prefix: %s", regName)
+					}
+
+					parts2 := strings.Split(parts[1], "[")
+					arrangement = strings.TrimSuffix(strings.TrimPrefix(parts2[0], "<"), ">")
+				} else if op.Typ == "AC_ZREGIDX" || op.Typ == "AC_PREGIDX" {
+					re := regexp.MustCompile(`<([A-Z][A-Za-z0-9]*)>`)
+					matches := re.FindStringSubmatch(opName)
+					if len(matches) > 1 {
+						regName = matches[1]
+						regPrefix = regMap[regName]
+						if regPrefix == "" {
+							log.Fatalf("Unknown register: %s", regName)
+						}
+					} else {
+						log.Fatalf("Unknown AC_[PZ]REGIDX: %s", opName)
+					}
+				}
+
+				var goAsmOp, gnuAsmOp string
+				limit := 32
+				if regPrefix == "P" || regPrefix == "PN" {
+					limit = 16
+				}
+				regIdx := cachedOrNew(regCache, regName, limit)
+				if regPrefix == "V" {
+					log.Fatalf("Unexpected V with index: %s", opName)
+				}
+
+				if arrangement != "" {
+					if arrMap[arrangement] {
+						arrIdx := cachedOrNew(arrCache, arrangement, len(sveArr))
+						goAsmOp = fmt.Sprintf("%s%d.%s[%d]", regPrefix, regIdx, sveArr[arrIdx], index)
+						gnuAsmOp = goAsmOp
+					} else {
+						// Fixed arrangement
+						goAsmOp = fmt.Sprintf("%s%d.%s[%d]", regPrefix, regIdx, arrangement, index)
+						gnuAsmOp = goAsmOp
+					}
+				} else {
+					goAsmOp = fmt.Sprintf("%s%d[%d]", regPrefix, regIdx, index)
+					gnuAsmOp = goAsmOp
+				}
+				gnuAsmOps = append([]string{gnuAsmOp}, gnuAsmOps...)
+				goAsmOps = append(goAsmOps, goAsmOp)
 			} else if op.Typ == "AC_SPZGREG" || op.Typ == "AC_VREG" {
 				// Operands that takes scalar or NEON vector registers.
 				// There arn't that much of shapes, just enumerate them...
@@ -1043,7 +1109,9 @@
 		enc.Asm == "SUBP  <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>" ||
 		enc.Asm == "UABAL  <Zda>.<T>, <Zn>.<Tb>, <Zm>.<Tb>" ||
 		enc.Asm == "UCVTF  <Zd>.<T>, <Zn>.<Tb>" ||
-		enc.Asm == "UDOT  <Zda>.H, <Zn>.B, <Zm>.B" {
+		enc.Asm == "UDOT  <Zda>.H, <Zn>.B, <Zm>.B" ||
+		enc.Asm == "SDOT  <Zda>.H, <Zn>.B, <Zm>.B[<imm>]" ||
+		enc.Asm == "UDOT  <Zda>.H, <Zn>.B, <Zm>.B[<imm>]" {
 		// Very new instruction encodings
 		// GNU toolchain 2.45 doesn't know about these specific encodings yet.
 		todoCase := e2eData{GoOp: enc.GoOp[1:], Asm: fmt.Sprintf("// TODO: %s", enc.Asm), highFeat: highFeat}
diff --git a/arm64/instgen/xmlspec/parser.go b/arm64/instgen/xmlspec/parser.go
index b8b73ff..fc61da7 100644
--- a/arm64/instgen/xmlspec/parser.go
+++ b/arm64/instgen/xmlspec/parser.go
@@ -80,10 +80,10 @@
 }
 
 var operandRules = []operandRule{
-	// AC_SPZGREG: Standard scalar registers (W, X, R).
-	{regexp.MustCompile(`^(<[WX][a-z]+>!?|<R><[a-z]+>|X[0-9]+|{<[WX][a-z]+>})$`), "AC_SPZGREG"},
-	// AC_SPZGREG: Scalar registers or stack pointer (SP).
-	{regexp.MustCompile(`^<([WX][a-z]{1}|R><n)\|[W]?SP>$`), "AC_SPZGREG"},
+	// AC_ARNG: Registers with arrangement (e.g. .B, .D, .S) or type variable (<T>).
+	{regexp.MustCompile(`^<[PVZ][a-zA-Z]+>\.([1-9]*[BDHQS]|<T[a-z]*>)$`), "AC_ARNG"},
+	// AC_ZREG: Scalable vector registers (Z).
+	{regexp.MustCompile(`^<Z[a-z]+>$`), "AC_ZREG"},
 	// AC_PREG: Predicate registers (P).
 	{regexp.MustCompile(`^<P[a-z]{1}>$`), "AC_PREG"},
 	// AC_PREG: Predicate-as-counter registers (PN).
@@ -92,15 +92,19 @@
 	{regexp.MustCompile(`^<P[N]?[a-z]{1}>\/M$`), "AC_PREGZM"},
 	// AC_PREGZM: Predicate registers with zeroing predication (/Z).
 	{regexp.MustCompile(`^<P[N]?[a-z]{1}>\/(Z|<ZM>)$`), "AC_PREGZM"},
-	// AC_REGIDX: Registers with immediate index.
-	{regexp.MustCompile(`^(<[PZ][N]?[a-z]{1}>|ZT0)\[<[a-z]+>\]$`), "AC_REGIDX"},
-	// AC_ZREG: Scalable vector registers (Z).
-	{regexp.MustCompile(`^<Z[a-z]+>$`), "AC_ZREG"},
-	// AC_ARNG: Registers with arrangement (e.g. .B, .D, .S) or type variable (<T>).
-	{regexp.MustCompile(`^<[PVZ][a-zA-Z]+>\.([1-9]*[BDHQS]|<T[a-z]*>)$`), "AC_ARNG"},
+	// AC_SPZGREG: Standard scalar registers (W, X, R).
+	{regexp.MustCompile(`^(<[WX][a-z]+>!?|<R><[a-z]+>|X[0-9]+|{<[WX][a-z]+>})$`), "AC_SPZGREG"},
+	// AC_SPZGREG: Scalar registers or stack pointer (SP).
+	{regexp.MustCompile(`^<([WX][a-z]{1}|R><n)\|[W]?SP>$`), "AC_SPZGREG"},
+	// AC_VREG: V registers (SIMD).
+	{regexp.MustCompile(`(^<Dd>|^<V>.*)$`), "AC_VREG"},
 	// AC_ARNGIDX: Register arrangement with index.
 	{regexp.MustCompile(`^<[VZ][a-zA-Z]*>\.([1-9]*[BDHQS]|<T[a-z]*>)\[(<(index|imm)[1-9]*>|[0-9]+)\]$`), "AC_ARNGIDX"},
 	{regexp.MustCompile(`^{[\s]+<[PVZ][a-z]+[1-4]*>\.[BDHQS],*[\s]*}\[<index>\]$`), "AC_ARNGIDX"},
+	// AC_PREGIDX: P Registers with immediate index.
+	{regexp.MustCompile(`^(<P[N]?[a-z]{1}>)\[<[a-z]+>\]$`), "AC_PREGIDX"},
+	// AC_ZREGIDX: Z Registers with (optional) immediate index.
+	{regexp.MustCompile(`^(<Z[a-z]{1}>)\{?\[<[a-z]+>\]\}?$`), "AC_ZREGIDX"},
 	// AC_REGLIST1: List of 1 register with arrangement.
 	{regexp.MustCompile(`^{[\s]+<[PVZ][a-z]+>\.([1-9]*[BDHQS]|<T[a-z]*>)[\s]+}$`), "AC_REGLIST1"},
 	// AC_REGLIST2: List of 2 registers with arrangement.
@@ -131,16 +135,12 @@
 	{regexp.MustCompile(`^<[WX][dn]+>(\{\s*,\s*<pattern>(\{\s*,\s*MUL\s+#<imm>\s*\})?\s*\})?$`), "AC_REG_PATTERN"},
 	// AC_ZREG_PATTERN: Z register with rotate/replication pattern.
 	{regexp.MustCompile(`^<Z[dn]+>\.(<T>|[BDHQS])(\{\s*,\s*<pattern>(\{\s*,\s*MUL\s+#<imm>\s*\})?\s*\})?$`), "AC_ZREG_PATTERN"},
-	// AC_PREGIDX: Predicate register with index.
-	{regexp.MustCompile(`^<P[nm]>\.<T>\[\s*<Wv>\s*,\s*<imm>\s*\]$`), "AC_PREGIDX"},
+	// AC_PREGSEL: Predicate register with selector register and immediate index.
+	{regexp.MustCompile(`^<P[nm]>\.<T>\[\s*<Wv>\s*,\s*<imm>\s*\]$`), "AC_PREGSEL"},
 	// AC_PREG_PATTERN: Predicate register with pattern.
 	{regexp.MustCompile(`^<P[dn]>\.<T>(\{\s*,\s*<pattern>\s*\})?$`), "AC_PREG_PATTERN"},
-	// AC_ZREGIDX: Z register with optional index.
-	{regexp.MustCompile(`^<Z[dn]>(\{\s*\[<imm>\]\s*\})?$`), "AC_ZREGIDX"},
 	// AC_IMM: Immediate value.
 	{regexp.MustCompile(`(^#.*)|(<const>)$`), "AC_IMM"},
-	// AC_VREG: V registers (SIMD).
-	{regexp.MustCompile(`(^<Dd>|^<V>.*)$`), "AC_VREG"},
 }
 
 // warmUpCache initializes the XML decoding cache for the Instruction type.
@@ -1014,7 +1014,7 @@
 	// <reg>.<T>[<index>]
 	"AC_ARNGIDX": 3,
 	"AC_ZREGIDX": 3,
-	"AC_REGIDX":  3,
+	"AC_PREGIDX": 3,
 	// #<imm>, <shift>
 	"AC_IMM": 2,
 	// [<reg1>.<T1>, <reg2>.<T2>, <mod> <amount>]
@@ -1026,7 +1026,7 @@
 	"AC_MEMOFFMULVL": 3,
 	// <preg>.<T>[<selreg>, <imm>]
 	// selreg must be a W reg, so one additional encoding func to check.
-	"AC_PREGIDX": 5,
+	"AC_PREGSEL": 5,
 	// <width><reg>
 	"AC_SPZGREG": 2,
 	"AC_VREG":    2,