arm64/arm64asm: add support for TLBI and DC

The format of TLBI is TLBI <tlbi_op> {<Xt>}, where <Xt> is an optional
field. But there is no field for <Xt> in the instruction format table.
This CL adds a new Arg type sysOp to handle this case.

This patch is a copy of CL 256197. Co-authored-by: JunchenLi
<junchen.li@arm.com>

Change-Id: I6e12f49a8614ca80fd60eef5b63755323824f5fa
Reviewed-on: https://go-review.googlesource.com/c/arch/+/302889
Trust: Fannie Zhang <Fannie.Zhang@arm.com>
Run-TryBot: Fannie Zhang <Fannie.Zhang@arm.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
diff --git a/arm64/arm64asm/condition.go b/arm64/arm64asm/condition.go
index d673857..37ad8ee 100644
--- a/arm64/arm64asm/condition.go
+++ b/arm64/arm64asm/condition.go
@@ -11,7 +11,7 @@
 // Refer to instFormat inside decode.go for more details
 
 func at_sys_cr_system_cond(instr uint32) bool {
-	return sys_op_4((instr>>16)&0x7, 0x7, 0x8, (instr>>5)&0x7) == Sys_AT
+	return sys_op_4((instr>>16)&0x7, 0x7, 0x8, (instr>>5)&0x7) == sys_AT
 }
 
 func bfi_bfm_32m_bitfield_cond(instr uint32) bool {
@@ -61,11 +61,11 @@
 	return instr&0xe000 != 0xe000
 }
 func dc_sys_cr_system_cond(instr uint32) bool {
-	return sys_op_4((instr>>16)&0x7, 0x7, (instr>>8)&0xf, (instr>>5)&0x7) == Sys_DC
+	return sys_op_4((instr>>16)&0x7, 0x7, (instr>>8)&0xf, (instr>>5)&0x7) == sys_DC
 }
 
 func ic_sys_cr_system_cond(instr uint32) bool {
-	return sys_op_4((instr>>16)&0x7, 0x7, (instr>>8)&0xf, (instr>>5)&0x7) == Sys_IC
+	return sys_op_4((instr>>16)&0x7, 0x7, (instr>>8)&0xf, (instr>>5)&0x7) == sys_IC
 }
 
 func lsl_ubfm_32m_bitfield_cond(instr uint32) bool {
@@ -133,7 +133,7 @@
 }
 
 func tlbi_sys_cr_system_cond(instr uint32) bool {
-	return sys_op_4((instr>>16)&0x7, 0x8, (instr>>8)&0xf, (instr>>5)&0x7) == Sys_TLBI
+	return sys_op_4((instr>>16)&0x7, 0x8, (instr>>8)&0xf, (instr>>5)&0x7) == sys_TLBI
 }
 
 func ubfiz_ubfm_32m_bitfield_cond(instr uint32) bool {
diff --git a/arm64/arm64asm/condition_util.go b/arm64/arm64asm/condition_util.go
index 62c0c3b..f2fa11b 100644
--- a/arm64/arm64asm/condition_util.go
+++ b/arm64/arm64asm/condition_util.go
@@ -47,19 +47,19 @@
 	return false
 }
 
-type Sys uint8
+type sys uint8
 
 const (
-	Sys_AT Sys = iota
-	Sys_DC
-	Sys_IC
-	Sys_TLBI
-	Sys_SYS
+	sys_AT sys = iota
+	sys_DC
+	sys_IC
+	sys_TLBI
+	sys_SYS
 )
 
-func sys_op_4(op1, crn, crm, op2 uint32) Sys {
-	// TODO: system instruction
-	return Sys_SYS
+func sys_op_4(op1, crn, crm, op2 uint32) sys {
+	sysInst := sysInstFields{uint8(op1), uint8(crn), uint8(crm), uint8(op2)}
+	return sysInst.getType()
 }
 
 func is_zero(x uint32) bool {
diff --git a/arm64/arm64asm/decode.go b/arm64/arm64asm/decode.go
index 5e29c47..b1c4f5e 100644
--- a/arm64/arm64asm/decode.go
+++ b/arm64/arm64asm/decode.go
@@ -684,17 +684,26 @@
 		//TODO: system instruction
 		return nil
 
-	case arg_sysop_DC_SYS_CR_system:
-		//TODO: system instruction
-		return nil
-
 	case arg_sysop_SYS_CR_system:
 		//TODO: system instruction
 		return nil
 
-	case arg_sysop_TLBI_SYS_CR_system:
-		//TODO: system instruction
-		return nil
+	case arg_sysop_DC_SYS_CR_system, arg_sysop_TLBI_SYS_CR_system:
+		op1 := (x >> 16) & 7
+		cn := (x >> 12) & 15
+		cm := (x >> 8) & 15
+		op2 := (x >> 5) & 7
+		sysInst := sysInstFields{uint8(op1), uint8(cn), uint8(cm), uint8(op2)}
+		attrs := sysInst.getAttrs()
+		reg := int(x & 31)
+		if !attrs.hasOperand2 {
+			if reg == 31 {
+				return sysOp{sysInst, 0, false}
+			}
+			// This instruction is undefined if the Rt field is not set to 31.
+			return nil
+		}
+		return sysOp{sysInst, X0 + Reg(reg), true}
 
 	case arg_Bt:
 		return B0 + Reg(x&(1<<5-1))
diff --git a/arm64/arm64asm/decode_test.go b/arm64/arm64asm/decode_test.go
index 9c7d2b6..26eb6ae 100644
--- a/arm64/arm64asm/decode_test.go
+++ b/arm64/arm64asm/decode_test.go
@@ -63,9 +63,7 @@
 		// TODO: system instruction.
 		var Todo = strings.Fields(`
 			sys
-			dc
 			at
-			tlbi
 			ic
 			hvc
 			smc
diff --git a/arm64/arm64asm/inst.go b/arm64/arm64asm/inst.go
index afeb9a3..8c633fe 100644
--- a/arm64/arm64asm/inst.go
+++ b/arm64/arm64asm/inst.go
@@ -968,3 +968,161 @@
 	}
 	return fmt.Sprintf("%s[%d]", result, r.index)
 }
+
+type sysOp struct {
+	op          sysInstFields
+	r           Reg
+	hasOperand2 bool
+}
+
+func (s sysOp) isArg() {}
+
+func (s sysOp) String() string {
+	result := s.op.String()
+	// If s.hasOperand2 is false, the value in the register
+	// specified by s.r is ignored.
+	if s.hasOperand2 {
+		result += ", " + s.r.String()
+	}
+	return result
+}
+
+type sysInstFields struct {
+	op1 uint8
+	cn  uint8
+	cm  uint8
+	op2 uint8
+}
+
+type sysInstAttrs struct {
+	typ         sys
+	name        string
+	hasOperand2 bool
+}
+
+func (s sysInstFields) isArg() {}
+
+func (s sysInstFields) getAttrs() sysInstAttrs {
+	attrs, ok := sysInstsAttrs[sysInstFields{s.op1, s.cn, s.cm, s.op2}]
+	if !ok {
+		return sysInstAttrs{typ: sys_SYS}
+	}
+	return attrs
+}
+
+func (s sysInstFields) String() string {
+	return s.getAttrs().name
+}
+
+func (s sysInstFields) getType() sys {
+	return s.getAttrs().typ
+}
+
+var sysInstsAttrs = map[sysInstFields]sysInstAttrs{
+	sysInstFields{0, 8, 3, 0}:  {sys_TLBI, "VMALLE1IS", false},
+	sysInstFields{0, 8, 3, 1}:  {sys_TLBI, "VAE1IS", true},
+	sysInstFields{0, 8, 3, 2}:  {sys_TLBI, "ASIDE1IS", true},
+	sysInstFields{0, 8, 3, 3}:  {sys_TLBI, "VAAE1IS", true},
+	sysInstFields{0, 8, 3, 5}:  {sys_TLBI, "VALE1IS", true},
+	sysInstFields{0, 8, 3, 7}:  {sys_TLBI, "VAALE1IS", true},
+	sysInstFields{0, 8, 7, 0}:  {sys_TLBI, "VMALLE1", false},
+	sysInstFields{0, 8, 7, 1}:  {sys_TLBI, "VAE1", true},
+	sysInstFields{0, 8, 7, 2}:  {sys_TLBI, "ASIDE1", true},
+	sysInstFields{0, 8, 7, 3}:  {sys_TLBI, "VAAE1", true},
+	sysInstFields{0, 8, 7, 5}:  {sys_TLBI, "VALE1", true},
+	sysInstFields{0, 8, 7, 7}:  {sys_TLBI, "VAALE1", true},
+	sysInstFields{4, 8, 0, 1}:  {sys_TLBI, "IPAS2E1IS", true},
+	sysInstFields{4, 8, 0, 5}:  {sys_TLBI, "IPAS2LE1IS", true},
+	sysInstFields{4, 8, 3, 0}:  {sys_TLBI, "ALLE2IS", false},
+	sysInstFields{4, 8, 3, 1}:  {sys_TLBI, "VAE2IS", true},
+	sysInstFields{4, 8, 3, 4}:  {sys_TLBI, "ALLE1IS", false},
+	sysInstFields{4, 8, 3, 5}:  {sys_TLBI, "VALE2IS", true},
+	sysInstFields{4, 8, 3, 6}:  {sys_TLBI, "VMALLS12E1IS", false},
+	sysInstFields{4, 8, 4, 1}:  {sys_TLBI, "IPAS2E1", true},
+	sysInstFields{4, 8, 4, 5}:  {sys_TLBI, "IPAS2LE1", true},
+	sysInstFields{4, 8, 7, 0}:  {sys_TLBI, "ALLE2", false},
+	sysInstFields{4, 8, 7, 1}:  {sys_TLBI, "VAE2", true},
+	sysInstFields{4, 8, 7, 4}:  {sys_TLBI, "ALLE1", false},
+	sysInstFields{4, 8, 7, 5}:  {sys_TLBI, "VALE2", true},
+	sysInstFields{4, 8, 7, 6}:  {sys_TLBI, "VMALLS12E1", false},
+	sysInstFields{6, 8, 3, 0}:  {sys_TLBI, "ALLE3IS", false},
+	sysInstFields{6, 8, 3, 1}:  {sys_TLBI, "VAE3IS", true},
+	sysInstFields{6, 8, 3, 5}:  {sys_TLBI, "VALE3IS", true},
+	sysInstFields{6, 8, 7, 0}:  {sys_TLBI, "ALLE3", false},
+	sysInstFields{6, 8, 7, 1}:  {sys_TLBI, "VAE3", true},
+	sysInstFields{6, 8, 7, 5}:  {sys_TLBI, "VALE3", true},
+	sysInstFields{0, 8, 1, 0}:  {sys_TLBI, "VMALLE1OS", false},
+	sysInstFields{0, 8, 1, 1}:  {sys_TLBI, "VAE1OS", true},
+	sysInstFields{0, 8, 1, 2}:  {sys_TLBI, "ASIDE1OS", true},
+	sysInstFields{0, 8, 1, 3}:  {sys_TLBI, "VAAE1OS", true},
+	sysInstFields{0, 8, 1, 5}:  {sys_TLBI, "VALE1OS", true},
+	sysInstFields{0, 8, 1, 7}:  {sys_TLBI, "VAALE1OS", true},
+	sysInstFields{0, 8, 2, 1}:  {sys_TLBI, "RVAE1IS", true},
+	sysInstFields{0, 8, 2, 3}:  {sys_TLBI, "RVAAE1IS", true},
+	sysInstFields{0, 8, 2, 5}:  {sys_TLBI, "RVALE1IS", true},
+	sysInstFields{0, 8, 2, 7}:  {sys_TLBI, "RVAALE1IS", true},
+	sysInstFields{0, 8, 5, 1}:  {sys_TLBI, "RVAE1OS", true},
+	sysInstFields{0, 8, 5, 3}:  {sys_TLBI, "RVAAE1OS", true},
+	sysInstFields{0, 8, 5, 5}:  {sys_TLBI, "RVALE1OS", true},
+	sysInstFields{0, 8, 5, 7}:  {sys_TLBI, "RVAALE1OS", true},
+	sysInstFields{0, 8, 6, 1}:  {sys_TLBI, "RVAE1", true},
+	sysInstFields{0, 8, 6, 3}:  {sys_TLBI, "RVAAE1", true},
+	sysInstFields{0, 8, 6, 5}:  {sys_TLBI, "RVALE1", true},
+	sysInstFields{0, 8, 6, 7}:  {sys_TLBI, "RVAALE1", true},
+	sysInstFields{4, 8, 0, 2}:  {sys_TLBI, "RIPAS2E1IS", true},
+	sysInstFields{4, 8, 0, 6}:  {sys_TLBI, "RIPAS2LE1IS", true},
+	sysInstFields{4, 8, 1, 0}:  {sys_TLBI, "ALLE2OS", false},
+	sysInstFields{4, 8, 1, 1}:  {sys_TLBI, "VAE2OS", true},
+	sysInstFields{4, 8, 1, 4}:  {sys_TLBI, "ALLE1OS", false},
+	sysInstFields{4, 8, 1, 5}:  {sys_TLBI, "VALE2OS", true},
+	sysInstFields{4, 8, 1, 6}:  {sys_TLBI, "VMALLS12E1OS", false},
+	sysInstFields{4, 8, 2, 1}:  {sys_TLBI, "RVAE2IS", true},
+	sysInstFields{4, 8, 2, 5}:  {sys_TLBI, "RVALE2IS", true},
+	sysInstFields{4, 8, 4, 0}:  {sys_TLBI, "IPAS2E1OS", true},
+	sysInstFields{4, 8, 4, 2}:  {sys_TLBI, "RIPAS2E1", true},
+	sysInstFields{4, 8, 4, 3}:  {sys_TLBI, "RIPAS2E1OS", true},
+	sysInstFields{4, 8, 4, 4}:  {sys_TLBI, "IPAS2LE1OS", true},
+	sysInstFields{4, 8, 4, 6}:  {sys_TLBI, "RIPAS2LE1", true},
+	sysInstFields{4, 8, 4, 7}:  {sys_TLBI, "RIPAS2LE1OS", true},
+	sysInstFields{4, 8, 5, 1}:  {sys_TLBI, "RVAE2OS", true},
+	sysInstFields{4, 8, 5, 5}:  {sys_TLBI, "RVALE2OS", true},
+	sysInstFields{4, 8, 6, 1}:  {sys_TLBI, "RVAE2", true},
+	sysInstFields{4, 8, 6, 5}:  {sys_TLBI, "RVALE2", true},
+	sysInstFields{6, 8, 1, 0}:  {sys_TLBI, "ALLE3OS", false},
+	sysInstFields{6, 8, 1, 1}:  {sys_TLBI, "VAE3OS", true},
+	sysInstFields{6, 8, 1, 5}:  {sys_TLBI, "VALE3OS", true},
+	sysInstFields{6, 8, 2, 1}:  {sys_TLBI, "RVAE3IS", true},
+	sysInstFields{6, 8, 2, 5}:  {sys_TLBI, "RVALE3IS", true},
+	sysInstFields{6, 8, 5, 1}:  {sys_TLBI, "RVAE3OS", true},
+	sysInstFields{6, 8, 5, 5}:  {sys_TLBI, "RVALE3OS", true},
+	sysInstFields{6, 8, 6, 1}:  {sys_TLBI, "RVAE3", true},
+	sysInstFields{6, 8, 6, 5}:  {sys_TLBI, "RVALE3", true},
+	sysInstFields{0, 7, 6, 1}:  {sys_DC, "IVAC", true},
+	sysInstFields{0, 7, 6, 2}:  {sys_DC, "ISW", true},
+	sysInstFields{0, 7, 10, 2}: {sys_DC, "CSW", true},
+	sysInstFields{0, 7, 14, 2}: {sys_DC, "CISW", true},
+	sysInstFields{3, 7, 4, 1}:  {sys_DC, "ZVA", true},
+	sysInstFields{3, 7, 10, 1}: {sys_DC, "CVAC", true},
+	sysInstFields{3, 7, 11, 1}: {sys_DC, "CVAU", true},
+	sysInstFields{3, 7, 14, 1}: {sys_DC, "CIVAC", true},
+	sysInstFields{0, 7, 6, 3}:  {sys_DC, "IGVAC", true},
+	sysInstFields{0, 7, 6, 4}:  {sys_DC, "IGSW", true},
+	sysInstFields{0, 7, 6, 5}:  {sys_DC, "IGDVAC", true},
+	sysInstFields{0, 7, 6, 6}:  {sys_DC, "IGDSW", true},
+	sysInstFields{0, 7, 10, 4}: {sys_DC, "CGSW", true},
+	sysInstFields{0, 7, 10, 6}: {sys_DC, "CGDSW", true},
+	sysInstFields{0, 7, 14, 4}: {sys_DC, "CIGSW", true},
+	sysInstFields{0, 7, 14, 6}: {sys_DC, "CIGDSW", true},
+	sysInstFields{3, 7, 4, 3}:  {sys_DC, "GVA", true},
+	sysInstFields{3, 7, 4, 4}:  {sys_DC, "GZVA", true},
+	sysInstFields{3, 7, 10, 3}: {sys_DC, "CGVAC", true},
+	sysInstFields{3, 7, 10, 5}: {sys_DC, "CGDVAC", true},
+	sysInstFields{3, 7, 12, 3}: {sys_DC, "CGVAP", true},
+	sysInstFields{3, 7, 12, 5}: {sys_DC, "CGDVAP", true},
+	sysInstFields{3, 7, 13, 3}: {sys_DC, "CGVADP", true},
+	sysInstFields{3, 7, 13, 5}: {sys_DC, "CGDVADP", true},
+	sysInstFields{3, 7, 14, 3}: {sys_DC, "CIGVAC", true},
+	sysInstFields{3, 7, 14, 5}: {sys_DC, "CIGDVAC", true},
+	sysInstFields{3, 7, 12, 1}: {sys_DC, "CVAP", true},
+	sysInstFields{3, 7, 13, 1}: {sys_DC, "CVADP", true},
+}
diff --git a/arm64/arm64asm/objdump_test.go b/arm64/arm64asm/objdump_test.go
index 3baf8a1..a096dce 100644
--- a/arm64/arm64asm/objdump_test.go
+++ b/arm64/arm64asm/objdump_test.go
@@ -120,9 +120,7 @@
 // TODO: system instruction.
 var todo = strings.Fields(`
 	sys
-	dc
 	at
-	tlbi
 	ic
 	hvc
 	smc
diff --git a/arm64/arm64asm/plan9x.go b/arm64/arm64asm/plan9x.go
index f4eef8c..ea5139c 100644
--- a/arm64/arm64asm/plan9x.go
+++ b/arm64/arm64asm/plan9x.go
@@ -542,10 +542,7 @@
 			}
 
 		}
-		if regno == 31 {
-			return "ZR"
-		}
-		return fmt.Sprintf("R%d", regno)
+		return plan9gpr(a)
 
 	case RegSP:
 		regno := uint16(a) & 31
@@ -555,13 +552,7 @@
 		return fmt.Sprintf("R%d", regno)
 
 	case RegExtshiftAmount:
-		reg := ""
-		regno := uint16(a.reg) & 31
-		if regno == 31 {
-			reg = "ZR"
-		} else {
-			reg = fmt.Sprintf("R%d", uint16(a.reg)&31)
-		}
+		reg := plan9gpr(a.reg)
 		extshift := ""
 		amount := ""
 		if a.extShift != ExtShift(0) {
@@ -614,19 +605,13 @@
 	case MemExtend:
 		base := ""
 		index := ""
-		indexreg := ""
 		regno := uint16(a.Base) & 31
 		if regno == 31 {
 			base = "(RSP)"
 		} else {
 			base = fmt.Sprintf("(R%d)", regno)
 		}
-		regno = uint16(a.Index) & 31
-		if regno == 31 {
-			indexreg = "ZR"
-		} else {
-			indexreg = fmt.Sprintf("R%d", regno)
-		}
+		indexreg := plan9gpr(a.Index)
 
 		if a.Extend == lsl {
 			// Refer to ARM reference manual, for byte load/store(register), the index
@@ -736,7 +721,22 @@
 		if strings.Contains(a.String(), "#") {
 			return fmt.Sprintf("$%d", a)
 		}
+	case sysOp:
+		result := a.op.String()
+		if a.r != 0 {
+			result += ", " + plan9gpr(a.r)
+		}
+		return result
 	}
 
 	return strings.ToUpper(arg.String())
 }
+
+// Convert a general-purpose register to plan9 assembly format.
+func plan9gpr(r Reg) string {
+	regno := uint16(r) & 31
+	if regno == 31 {
+		return "ZR"
+	}
+	return fmt.Sprintf("R%d", regno)
+}
diff --git a/arm64/arm64asm/testdata/gnucases.txt b/arm64/arm64asm/testdata/gnucases.txt
index 2154209..3ea6941 100644
--- a/arm64/arm64asm/testdata/gnucases.txt
+++ b/arm64/arm64asm/testdata/gnucases.txt
@@ -4649,3 +4649,109 @@
 743d0a0e|	umov w20, v11.h[2]
 743d0c0e|	mov w20, v11.s[1]
 743d084e|	mov x20, v11.d[0]
+1f8308d5|	tlbi vmalle1is
+1f8708d5|	tlbi vmalle1
+1f830cd5|	tlbi alle2is
+9f830cd5|	tlbi alle1is
+df830cd5|	tlbi vmalls12e1is
+1f870cd5|	tlbi alle2
+9f870cd5|	tlbi alle1
+df870cd5|	tlbi vmalls12e1
+1f830ed5|	tlbi alle3is
+1f870ed5|	tlbi alle3
+1f8108d5|	tlbi vmalle1os
+1f810cd5|	tlbi alle2os
+9f810cd5|	tlbi alle1os
+df810cd5|	tlbi vmalls12e1os
+1f810ed5|	tlbi alle3os
+208308d5|	tlbi vae1is, x0
+418308d5|	tlbi aside1is, x1
+628308d5|	tlbi vaae1is, x2
+a38308d5|	tlbi vale1is, x3
+e48308d5|	tlbi vaale1is, x4
+258708d5|	tlbi vae1, x5
+468708d5|	tlbi aside1, x6
+678708d5|	tlbi vaae1, x7
+a88708d5|	tlbi vale1, x8
+e98708d5|	tlbi vaale1, x9
+2a800cd5|	tlbi ipas2e1is, x10
+ab800cd5|	tlbi ipas2le1is, x11
+2c830cd5|	tlbi vae2is, x12
+ad830cd5|	tlbi vale2is, x13
+2e840cd5|	tlbi ipas2e1, x14
+af840cd5|	tlbi ipas2le1, x15
+30870cd5|	tlbi vae2, x16
+b1870cd5|	tlbi vale2, x17
+3f830ed5|	tlbi vae3is, xzr
+b3830ed5|	tlbi vale3is, x19
+34870ed5|	tlbi vae3, x20
+b5870ed5|	tlbi vale3, x21
+368108d5|	tlbi vae1os, x22
+578108d5|	tlbi aside1os, x23
+788108d5|	tlbi vaae1os, x24
+b98108d5|	tlbi vale1os, x25
+fa8108d5|	tlbi vaale1os, x26
+3b8208d5|	tlbi rvae1is, x27
+7f8208d5|	tlbi rvaae1is, xzr
+bd8208d5|	tlbi rvale1is, x29
+fe8208d5|	tlbi rvaale1is, x30
+3f8508d5|	tlbi rvae1os, xzr
+608508d5|	tlbi rvaae1os, x0
+a18508d5|	tlbi rvale1os, x1
+e28508d5|	tlbi rvaale1os, x2
+238608d5|	tlbi rvae1, x3
+648608d5|	tlbi rvaae1, x4
+a58608d5|	tlbi rvale1, x5
+e68608d5|	tlbi rvaale1, x6
+47800cd5|	tlbi ripas2e1is, x7
+c8800cd5|	tlbi ripas2le1is, x8
+29810cd5|	tlbi vae2os, x9
+aa810cd5|	tlbi vale2os, x10
+2b820cd5|	tlbi rvae2is, x11
+ac820cd5|	tlbi rvale2is, x12
+0d840cd5|	tlbi ipas2e1os, x13
+4e840cd5|	tlbi ripas2e1, x14
+6f840cd5|	tlbi ripas2e1os, x15
+90840cd5|	tlbi ipas2le1os, x16
+d1840cd5|	tlbi ripas2le1, x17
+ff840cd5|	tlbi ripas2le1os, xzr
+33850cd5|	tlbi rvae2os, x19
+b4850cd5|	tlbi rvale2os, x20
+35860cd5|	tlbi rvae2, x21
+b6860cd5|	tlbi rvale2, x22
+37810ed5|	tlbi vae3os, x23
+b8810ed5|	tlbi vale3os, x24
+39820ed5|	tlbi rvae3is, x25
+ba820ed5|	tlbi rvale3is, x26
+3b850ed5|	tlbi rvae3os, x27
+bf850ed5|	tlbi rvale3os, xzr
+3d860ed5|	tlbi rvae3, x29
+be860ed5|	tlbi rvale3, x30
+207608d5|	dc ivac, x0
+417608d5|	dc isw, x1
+427a08d5|	dc csw, x2
+437e08d5|	dc cisw, x3
+24740bd5|	dc zva, x4
+257a0bd5|	dc cvac, x5
+267b0bd5|	dc cvau, x6
+277e0bd5|	dc civac, x7
+687608d5|	dc igvac, x8
+897608d5|	dc igsw, x9
+aa7608d5|	dc igdvac, x10
+cb7608d5|	dc igdsw, x11
+8c7a08d5|	dc cgsw, x12
+cd7a08d5|	dc cgdsw, x13
+8e7e08d5|	dc cigsw, x14
+cf7e08d5|	dc cigdsw, x15
+70740bd5|	dc gva, x16
+91740bd5|	dc gzva, x17
+7f7a0bd5|	dc cgvac, xzr
+b37a0bd5|	dc cgdvac, x19
+747c0bd5|	dc cgvap, x20
+b57c0bd5|	dc cgdvap, x21
+767d0bd5|	dc cgvadp, x22
+b77d0bd5|	dc cgdvadp, x23
+787e0bd5|	dc cigvac, x24
+b97e0bd5|	dc cigdvac, x25
+3a7c0bd5|	dc cvap, x26
+3b7d0bd5|	dc cvadp, x27
diff --git a/arm64/arm64asm/testdata/plan9cases.txt b/arm64/arm64asm/testdata/plan9cases.txt
index 1bbb238..a1da4f8 100644
--- a/arm64/arm64asm/testdata/plan9cases.txt
+++ b/arm64/arm64asm/testdata/plan9cases.txt
@@ -4576,3 +4576,109 @@
 44786638|	MOVBU (R2)(R6<<0), R4
 ae7bbe38|	MOVB (R29)(R30<<0), R14
 ae6bbe38|	MOVB (R29)(R30), R14
+1f8308d5|	TLBI VMALLE1IS
+1f8708d5|	TLBI VMALLE1
+1f830cd5|	TLBI ALLE2IS
+9f830cd5|	TLBI ALLE1IS
+df830cd5|	TLBI VMALLS12E1IS
+1f870cd5|	TLBI ALLE2
+9f870cd5|	TLBI ALLE1
+df870cd5|	TLBI VMALLS12E1
+1f830ed5|	TLBI ALLE3IS
+1f870ed5|	TLBI ALLE3
+1f8108d5|	TLBI VMALLE1OS
+1f810cd5|	TLBI ALLE2OS
+9f810cd5|	TLBI ALLE1OS
+df810cd5|	TLBI VMALLS12E1OS
+1f810ed5|	TLBI ALLE3OS
+208308d5|	TLBI VAE1IS, R0
+418308d5|	TLBI ASIDE1IS, R1
+628308d5|	TLBI VAAE1IS, R2
+a38308d5|	TLBI VALE1IS, R3
+e48308d5|	TLBI VAALE1IS, R4
+258708d5|	TLBI VAE1, R5
+468708d5|	TLBI ASIDE1, R6
+678708d5|	TLBI VAAE1, R7
+a88708d5|	TLBI VALE1, R8
+e98708d5|	TLBI VAALE1, R9
+2a800cd5|	TLBI IPAS2E1IS, R10
+ab800cd5|	TLBI IPAS2LE1IS, R11
+2c830cd5|	TLBI VAE2IS, R12
+ad830cd5|	TLBI VALE2IS, R13
+2e840cd5|	TLBI IPAS2E1, R14
+af840cd5|	TLBI IPAS2LE1, R15
+30870cd5|	TLBI VAE2, R16
+b1870cd5|	TLBI VALE2, R17
+3f830ed5|	TLBI VAE3IS, ZR
+b3830ed5|	TLBI VALE3IS, R19
+34870ed5|	TLBI VAE3, R20
+b5870ed5|	TLBI VALE3, R21
+368108d5|	TLBI VAE1OS, R22
+578108d5|	TLBI ASIDE1OS, R23
+788108d5|	TLBI VAAE1OS, R24
+b98108d5|	TLBI VALE1OS, R25
+fa8108d5|	TLBI VAALE1OS, R26
+3b8208d5|	TLBI RVAE1IS, R27
+7f8208d5|	TLBI RVAAE1IS, ZR
+bd8208d5|	TLBI RVALE1IS, R29
+fe8208d5|	TLBI RVAALE1IS, R30
+3f8508d5|	TLBI RVAE1OS, ZR
+608508d5|	TLBI RVAAE1OS, R0
+a18508d5|	TLBI RVALE1OS, R1
+e28508d5|	TLBI RVAALE1OS, R2
+238608d5|	TLBI RVAE1, R3
+648608d5|	TLBI RVAAE1, R4
+a58608d5|	TLBI RVALE1, R5
+e68608d5|	TLBI RVAALE1, R6
+47800cd5|	TLBI RIPAS2E1IS, R7
+c8800cd5|	TLBI RIPAS2LE1IS, R8
+29810cd5|	TLBI VAE2OS, R9
+aa810cd5|	TLBI VALE2OS, R10
+2b820cd5|	TLBI RVAE2IS, R11
+ac820cd5|	TLBI RVALE2IS, R12
+0d840cd5|	TLBI IPAS2E1OS, R13
+4e840cd5|	TLBI RIPAS2E1, R14
+6f840cd5|	TLBI RIPAS2E1OS, R15
+90840cd5|	TLBI IPAS2LE1OS, R16
+d1840cd5|	TLBI RIPAS2LE1, R17
+ff840cd5|	TLBI RIPAS2LE1OS, ZR
+33850cd5|	TLBI RVAE2OS, R19
+b4850cd5|	TLBI RVALE2OS, R20
+35860cd5|	TLBI RVAE2, R21
+b6860cd5|	TLBI RVALE2, R22
+37810ed5|	TLBI VAE3OS, R23
+b8810ed5|	TLBI VALE3OS, R24
+39820ed5|	TLBI RVAE3IS, R25
+ba820ed5|	TLBI RVALE3IS, R26
+3b850ed5|	TLBI RVAE3OS, R27
+bf850ed5|	TLBI RVALE3OS, ZR
+3d860ed5|	TLBI RVAE3, R29
+be860ed5|	TLBI RVALE3, R30
+207608d5|	DC IVAC, R0
+417608d5|	DC ISW, R1
+427a08d5|	DC CSW, R2
+437e08d5|	DC CISW, R3
+24740bd5|	DC ZVA, R4
+257a0bd5|	DC CVAC, R5
+267b0bd5|	DC CVAU, R6
+277e0bd5|	DC CIVAC, R7
+687608d5|	DC IGVAC, R8
+897608d5|	DC IGSW, R9
+aa7608d5|	DC IGDVAC, R10
+cb7608d5|	DC IGDSW, R11
+8c7a08d5|	DC CGSW, R12
+cd7a08d5|	DC CGDSW, R13
+8e7e08d5|	DC CIGSW, R14
+cf7e08d5|	DC CIGDSW, R15
+70740bd5|	DC GVA, R16
+91740bd5|	DC GZVA, R17
+7f7a0bd5|	DC CGVAC, ZR
+b37a0bd5|	DC CGDVAC, R19
+747c0bd5|	DC CGVAP, R20
+b57c0bd5|	DC CGDVAP, R21
+767d0bd5|	DC CGVADP, R22
+b77d0bd5|	DC CGDVADP, R23
+787e0bd5|	DC CIGVAC, R24
+b97e0bd5|	DC CIGDVAC, R25
+3a7c0bd5|	DC CVAP, R26
+3b7d0bd5|	DC CVADP, R27