// Copyright 2017 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package arm64asm import ( "fmt" "strings" ) // An Op is an ARM64 opcode. type Op uint16 // NOTE: The actual Op values are defined in tables.go. // They are chosen to simplify instruction decoding and // are not a dense packing from 0 to N, although the // density is high, probably at least 90%. func (op Op) String() string { if op >= Op(len(opstr)) || opstr[op] == "" { return fmt.Sprintf("Op(%d)", int(op)) } return opstr[op] } // An Inst is a single instruction. type Inst struct { Op Op // Opcode mnemonic Enc uint32 // Raw encoding bits. Args Args // Instruction arguments, in ARM manual order. } func (i Inst) String() string { var args []string for _, arg := range i.Args { if arg == nil { break } args = append(args, arg.String()) } return i.Op.String() + " " + strings.Join(args, ", ") } // An Args holds the instruction arguments. // If an instruction has fewer than 5 arguments, // the final elements in the array are nil. type Args [5]Arg // An Arg is a single instruction argument, one of these types: // Reg, RegSP, ImmShift, RegExtshiftAmount, PCRel, MemImmediate, // MemExtend, Imm, Imm64, Imm_hint, Imm_clrex, Imm_dcps, Cond, // Imm_c, Imm_option, Imm_prfop, Pstatefield, Systemreg, Imm_fp // RegisterWithArrangement, RegisterWithArrangementAndIndex. type Arg interface { isArg() String() string } // A Reg is a single register. // The zero value denotes W0, not the absence of a register. type Reg uint16 const ( W0 Reg = iota W1 W2 W3 W4 W5 W6 W7 W8 W9 W10 W11 W12 W13 W14 W15 W16 W17 W18 W19 W20 W21 W22 W23 W24 W25 W26 W27 W28 W29 W30 WZR X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 XZR B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B30 B31 H0 H1 H2 H3 H4 H5 H6 H7 H8 H9 H10 H11 H12 H13 H14 H15 H16 H17 H18 H19 H20 H21 H22 H23 H24 H25 H26 H27 H28 H29 H30 H31 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 S14 S15 S16 S17 S18 S19 S20 S21 S22 S23 S24 S25 S26 S27 S28 S29 S30 S31 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 D25 D26 D27 D28 D29 D30 D31 Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 Q10 Q11 Q12 Q13 Q14 Q15 Q16 Q17 Q18 Q19 Q20 Q21 Q22 Q23 Q24 Q25 Q26 Q27 Q28 Q29 Q30 Q31 V0 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 WSP = WZR // These are different registers with the same encoding. SP = XZR // These are different registers with the same encoding. ) func (Reg) isArg() {} func (r Reg) String() string { switch { case r == WZR: return "WZR" case r == XZR: return "XZR" case W0 <= r && r <= W30: return fmt.Sprintf("W%d", int(r-W0)) case X0 <= r && r <= X30: return fmt.Sprintf("X%d", int(r-X0)) case B0 <= r && r <= B31: return fmt.Sprintf("B%d", int(r-B0)) case H0 <= r && r <= H31: return fmt.Sprintf("H%d", int(r-H0)) case S0 <= r && r <= S31: return fmt.Sprintf("S%d", int(r-S0)) case D0 <= r && r <= D31: return fmt.Sprintf("D%d", int(r-D0)) case Q0 <= r && r <= Q31: return fmt.Sprintf("Q%d", int(r-Q0)) case V0 <= r && r <= V31: return fmt.Sprintf("V%d", int(r-V0)) default: return fmt.Sprintf("Reg(%d)", int(r)) } } // A RegSP represent a register and X31/W31 is regarded as SP/WSP. type RegSP Reg func (RegSP) isArg() {} func (r RegSP) String() string { switch Reg(r) { case WSP: return "WSP" case SP: return "SP" default: return Reg(r).String() } } type ImmShift struct { imm uint16 shift uint8 } func (ImmShift) isArg() {} func (is ImmShift) String() string { if is.shift == 0 { return fmt.Sprintf("#%#x", is.imm) } if is.shift < 128 { return fmt.Sprintf("#%#x, LSL #%d", is.imm, is.shift) } return fmt.Sprintf("#%#x, MSL #%d", is.imm, is.shift-128) } type ExtShift uint8 const ( _ ExtShift = iota uxtb uxth uxtw uxtx sxtb sxth sxtw sxtx lsl lsr asr ror ) func (extShift ExtShift) String() string { switch extShift { case uxtb: return "UXTB" case uxth: return "UXTH" case uxtw: return "UXTW" case uxtx: return "UXTX" case sxtb: return "SXTB" case sxth: return "SXTH" case sxtw: return "SXTW" case sxtx: return "SXTX" case lsl: return "LSL" case lsr: return "LSR" case asr: return "ASR" case ror: return "ROR" } return "" } type RegExtshiftAmount struct { reg Reg extShift ExtShift amount uint8 show_zero bool } func (RegExtshiftAmount) isArg() {} func (rea RegExtshiftAmount) String() string { buf := rea.reg.String() if rea.extShift != ExtShift(0) { buf += ", " + rea.extShift.String() if rea.amount != 0 { buf += fmt.Sprintf(" #%d", rea.amount) } else { if rea.show_zero == true { buf += fmt.Sprintf(" #%d", rea.amount) } } } return buf } // A PCRel describes a memory address (usually a code label) // as a distance relative to the program counter. type PCRel int64 func (PCRel) isArg() {} func (r PCRel) String() string { return fmt.Sprintf(".%+#x", uint64(r)) } // An AddrMode is an ARM addressing mode. type AddrMode uint8 const ( _ AddrMode = iota AddrPostIndex // [R], X - use address R, set R = R + X AddrPreIndex // [R, X]! - use address R + X, set R = R + X AddrOffset // [R, X] - use address R + X AddrPostReg // [Rn], Rm - - use address Rn, set Rn = Rn + Rm ) // A MemImmediate is a memory reference made up of a base R and immediate X. // The effective memory address is R or R+X depending on AddrMode. type MemImmediate struct { Base RegSP Mode AddrMode imm int32 } func (MemImmediate) isArg() {} func (m MemImmediate) String() string { R := m.Base.String() X := fmt.Sprintf("#%d", m.imm) switch m.Mode { case AddrOffset: if X == "#0" { return fmt.Sprintf("[%s]", R) } return fmt.Sprintf("[%s,%s]", R, X) case AddrPreIndex: return fmt.Sprintf("[%s,%s]!", R, X) case AddrPostIndex: return fmt.Sprintf("[%s],%s", R, X) case AddrPostReg: post := Reg(X0) + Reg(m.imm) postR := post.String() return fmt.Sprintf("[%s], %s", R, postR) } return fmt.Sprintf("unimplemented!") } // A MemExtend is a memory reference made up of a base R and index expression X. // The effective memory address is R or R+X depending on Index, Extend and Amount. type MemExtend struct { Base RegSP Index Reg Extend ExtShift // Amount indicates the index shift amount (but also see ShiftMustBeZero field below). Amount uint8 // Refer to ARM reference manual, for byte load/store(register), the index // shift amount must be 0, encoded in "S" as 0 if omitted, or as 1 if present. // a.ShiftMustBeZero is set true indicates the index shift amount must be 0. // In GNU syntax, a #0 shift amount is printed if Amount is 1 but ShiftMustBeZero // is true; #0 is not printed if Amount is 0 and ShiftMustBeZero is true. // Both cases represent shift by 0 bit. ShiftMustBeZero bool } func (MemExtend) isArg() {} func (m MemExtend) String() string { Rbase := m.Base.String() RIndex := m.Index.String() if m.ShiftMustBeZero { if m.Amount != 0 { return fmt.Sprintf("[%s,%s,%s #0]", Rbase, RIndex, m.Extend.String()) } else { if m.Extend != lsl { return fmt.Sprintf("[%s,%s,%s]", Rbase, RIndex, m.Extend.String()) } else { return fmt.Sprintf("[%s,%s]", Rbase, RIndex) } } } else { if m.Amount != 0 { return fmt.Sprintf("[%s,%s,%s #%d]", Rbase, RIndex, m.Extend.String(), m.Amount) } else { if m.Extend != lsl { return fmt.Sprintf("[%s,%s,%s]", Rbase, RIndex, m.Extend.String()) } else { return fmt.Sprintf("[%s,%s]", Rbase, RIndex) } } } } // An Imm is an integer constant. type Imm struct { Imm uint32 Decimal bool } func (Imm) isArg() {} func (i Imm) String() string { if !i.Decimal { return fmt.Sprintf("#%#x", i.Imm) } else { return fmt.Sprintf("#%d", i.Imm) } } type Imm64 struct { Imm uint64 Decimal bool } func (Imm64) isArg() {} func (i Imm64) String() string { if !i.Decimal { return fmt.Sprintf("#%#x", i.Imm) } else { return fmt.Sprintf("#%d", i.Imm) } } // An Imm_hint is an integer constant for HINT instruction. type Imm_hint uint8 func (Imm_hint) isArg() {} func (i Imm_hint) String() string { return fmt.Sprintf("#%#x", uint32(i)) } // An Imm_clrex is an integer constant for CLREX instruction. type Imm_clrex uint8 func (Imm_clrex) isArg() {} func (i Imm_clrex) String() string { if i == 15 { return "" } return fmt.Sprintf("#%#x", uint32(i)) } // An Imm_dcps is an integer constant for DCPS[123] instruction. type Imm_dcps uint16 func (Imm_dcps) isArg() {} func (i Imm_dcps) String() string { if i == 0 { return "" } return fmt.Sprintf("#%#x", uint32(i)) } // Standard conditions. type Cond struct { Value uint8 Invert bool } func (Cond) isArg() {} func (c Cond) String() string { cond31 := c.Value >> 1 invert := bool((c.Value & 1) == 1) invert = (invert != c.Invert) switch cond31 { case 0: if invert { return "NE" } else { return "EQ" } case 1: if invert { return "CC" } else { return "CS" } case 2: if invert { return "PL" } else { return "MI" } case 3: if invert { return "VC" } else { return "VS" } case 4: if invert { return "LS" } else { return "HI" } case 5: if invert { return "LT" } else { return "GE" } case 6: if invert { return "LE" } else { return "GT" } case 7: return "AL" } return "" } // An Imm_c is an integer constant for SYS/SYSL/TLBI instruction. type Imm_c uint8 func (Imm_c) isArg() {} func (i Imm_c) String() string { return fmt.Sprintf("C%d", uint8(i)) } // An Imm_option is an integer constant for DMB/DSB/ISB instruction. type Imm_option uint8 func (Imm_option) isArg() {} func (i Imm_option) String() string { switch uint8(i) { case 15: return "SY" case 14: return "ST" case 13: return "LD" case 11: return "ISH" case 10: return "ISHST" case 9: return "ISHLD" case 7: return "NSH" case 6: return "NSHST" case 5: return "NSHLD" case 3: return "OSH" case 2: return "OSHST" case 1: return "OSHLD" } return fmt.Sprintf("#%#02x", uint8(i)) } // An Imm_prfop is an integer constant for PRFM instruction. type Imm_prfop uint8 func (Imm_prfop) isArg() {} func (i Imm_prfop) String() string { prf_type := (i >> 3) & (1<<2 - 1) prf_target := (i >> 1) & (1<<2 - 1) prf_policy := i & 1 var result string switch prf_type { case 0: result = "PLD" case 1: result = "PLI" case 2: result = "PST" case 3: return fmt.Sprintf("#%#02x", uint8(i)) } switch prf_target { case 0: result += "L1" case 1: result += "L2" case 2: result += "L3" case 3: return fmt.Sprintf("#%#02x", uint8(i)) } if prf_policy == 0 { result += "KEEP" } else { result += "STRM" } return result } type Pstatefield uint8 const ( SPSel Pstatefield = iota DAIFSet DAIFClr ) func (Pstatefield) isArg() {} func (p Pstatefield) String() string { switch p { case SPSel: return "SPSel" case DAIFSet: return "DAIFSet" case DAIFClr: return "DAIFClr" default: return "unimplemented" } } type Systemreg struct { op0 uint8 op1 uint8 cn uint8 cm uint8 op2 uint8 } func (Systemreg) isArg() {} func (s Systemreg) String() string { return fmt.Sprintf("S%d_%d_C%d_C%d_%d", s.op0, s.op1, s.cn, s.cm, s.op2) } // An Imm_fp is a signed floating-point constant. type Imm_fp struct { s uint8 exp int8 pre uint8 } func (Imm_fp) isArg() {} func (i Imm_fp) String() string { var s, pre, numerator, denominator int16 var result float64 if i.s == 0 { s = 1 } else { s = -1 } pre = s * int16(16+i.pre) if i.exp > 0 { numerator = (pre << uint8(i.exp)) denominator = 16 } else { numerator = pre denominator = (16 << uint8(-1*i.exp)) } result = float64(numerator) / float64(denominator) return fmt.Sprintf("#%.18e", result) } type Arrangement uint8 const ( _ Arrangement = iota ArrangementB Arrangement8B Arrangement16B ArrangementH Arrangement4H Arrangement8H ArrangementS Arrangement2S Arrangement4S ArrangementD Arrangement1D Arrangement2D Arrangement1Q ) func (a Arrangement) String() (result string) { switch a { case ArrangementB: result = ".B" case Arrangement8B: result = ".8B" case Arrangement16B: result = ".16B" case ArrangementH: result = ".H" case Arrangement4H: result = ".4H" case Arrangement8H: result = ".8H" case ArrangementS: result = ".S" case Arrangement2S: result = ".2S" case Arrangement4S: result = ".4S" case ArrangementD: result = ".D" case Arrangement1D: result = ".1D" case Arrangement2D: result = ".2D" case Arrangement1Q: result = ".1Q" } return } // Register with arrangement: ., { .8B, .8B}, type RegisterWithArrangement struct { r Reg a Arrangement cnt uint8 } func (RegisterWithArrangement) isArg() {} func (r RegisterWithArrangement) String() string { result := r.r.String() result += r.a.String() if r.cnt > 0 { result = "{" + result if r.cnt == 2 { r1 := V0 + Reg((uint16(r.r)-uint16(V0)+1)&31) result += ", " + r1.String() + r.a.String() } else if r.cnt > 2 { if (uint16(r.cnt) + ((uint16(r.r) - uint16(V0)) & 31)) > 32 { for i := 1; i < int(r.cnt); i++ { cur := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(i))&31) result += ", " + cur.String() + r.a.String() } } else { r1 := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(r.cnt)-1)&31) result += "-" + r1.String() + r.a.String() } } result += "}" } return result } // Register with arrangement and index: // // .[], // { .B, .B }[]. type RegisterWithArrangementAndIndex struct { r Reg a Arrangement index uint8 cnt uint8 } func (RegisterWithArrangementAndIndex) isArg() {} func (r RegisterWithArrangementAndIndex) String() string { result := r.r.String() result += r.a.String() if r.cnt > 0 { result = "{" + result if r.cnt == 2 { r1 := V0 + Reg((uint16(r.r)-uint16(V0)+1)&31) result += ", " + r1.String() + r.a.String() } else if r.cnt > 2 { if (uint16(r.cnt) + ((uint16(r.r) - uint16(V0)) & 31)) > 32 { for i := 1; i < int(r.cnt); i++ { cur := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(i))&31) result += ", " + cur.String() + r.a.String() } } else { r1 := V0 + Reg((uint16(r.r)-uint16(V0)+uint16(r.cnt)-1)&31) result += "-" + r1.String() + r.a.String() } } result += "}" } 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}, }