| // 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: <Vd>.<T>, { <Vt>.8B, <Vt2>.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: <Vm>.<Ts>[<index>], |
| // { <Vt>.B, <Vt2>.B }[<index>]. |
| 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}, |
| } |