| // Copyright 2024 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 riscv64asm |
| |
| import ( |
| "fmt" |
| "strings" |
| ) |
| |
| // An Op is a RISC-V opcode. |
| type Op uint16 |
| |
| // NOTE: The actual Op values are defined in tables.go. |
| func (op Op) String() string { |
| if op >= Op(len(opstr)) || opstr[op] == "" { |
| return fmt.Sprintf("Op(%d)", op) |
| } |
| |
| return opstr[op] |
| } |
| |
| // An Arg is a single instruction argument. |
| type Arg interface { |
| String() string |
| } |
| |
| // An Args holds the instruction arguments. |
| // If an instruction has fewer than 6 arguments, |
| // the final elements in the array are nil. |
| type Args [6]Arg |
| |
| // An Inst is a single instruction. |
| type Inst struct { |
| Op Op // Opcode mnemonic. |
| Enc uint32 // Raw encoding bits. |
| Args Args // Instruction arguments, in RISC-V mamual order. |
| Len int // Length of encoded instruction in bytes |
| } |
| |
| func (i Inst) String() string { |
| var args []string |
| for _, arg := range i.Args { |
| if arg == nil { |
| break |
| } |
| args = append(args, arg.String()) |
| } |
| |
| if len(args) == 0 { |
| return i.Op.String() |
| } |
| return i.Op.String() + " " + strings.Join(args, ",") |
| } |
| |
| // A Reg is a single register. |
| // The zero value denotes X0, not the absence of a register. |
| type Reg uint16 |
| |
| const ( |
| // General-purpose register |
| X0 Reg = iota |
| 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 |
| X31 |
| |
| //Float point register |
| F0 |
| F1 |
| F2 |
| F3 |
| F4 |
| F5 |
| F6 |
| F7 |
| F8 |
| F9 |
| F10 |
| F11 |
| F12 |
| F13 |
| F14 |
| F15 |
| F16 |
| F17 |
| F18 |
| F19 |
| F20 |
| F21 |
| F22 |
| F23 |
| F24 |
| F25 |
| F26 |
| F27 |
| F28 |
| F29 |
| F30 |
| F31 |
| ) |
| |
| func (r Reg) String() string { |
| switch { |
| case r >= X0 && r <= X31: |
| return fmt.Sprintf("x%d", r) |
| |
| case r >= F0 && r <= F31: |
| return fmt.Sprintf("f%d", r-F0) |
| |
| default: |
| return fmt.Sprintf("Unknown(%d)", r) |
| } |
| } |
| |
| // A CSR is a single control and status register. |
| // Use stringer to generate CSR match table. |
| // |
| //go:generate stringer -type=CSR |
| type CSR uint16 |
| |
| const ( |
| // Control status register |
| USTATUS CSR = 0x0000 |
| FFLAGS CSR = 0x0001 |
| FRM CSR = 0x0002 |
| FCSR CSR = 0x0003 |
| UIE CSR = 0x0004 |
| UTVEC CSR = 0x0005 |
| UTVT CSR = 0x0007 |
| VSTART CSR = 0x0008 |
| VXSAT CSR = 0x0009 |
| VXRM CSR = 0x000a |
| VCSR CSR = 0x000f |
| USCRATCH CSR = 0x0040 |
| UEPC CSR = 0x0041 |
| UCAUSE CSR = 0x0042 |
| UTVAL CSR = 0x0043 |
| UIP CSR = 0x0044 |
| UNXTI CSR = 0x0045 |
| UINTSTATUS CSR = 0x0046 |
| USCRATCHCSW CSR = 0x0048 |
| USCRATCHCSWL CSR = 0x0049 |
| SSTATUS CSR = 0x0100 |
| SEDELEG CSR = 0x0102 |
| SIDELEG CSR = 0x0103 |
| SIE CSR = 0x0104 |
| STVEC CSR = 0x0105 |
| SCOUNTEREN CSR = 0x0106 |
| STVT CSR = 0x0107 |
| SSCRATCH CSR = 0x0140 |
| SEPC CSR = 0x0141 |
| SCAUSE CSR = 0x0142 |
| STVAL CSR = 0x0143 |
| SIP CSR = 0x0144 |
| SNXTI CSR = 0x0145 |
| SINTSTATUS CSR = 0x0146 |
| SSCRATCHCSW CSR = 0x0148 |
| SSCRATCHCSWL CSR = 0x0149 |
| SATP CSR = 0x0180 |
| VSSTATUS CSR = 0x0200 |
| VSIE CSR = 0x0204 |
| VSTVEC CSR = 0x0205 |
| VSSCRATCH CSR = 0x0240 |
| VSEPC CSR = 0x0241 |
| VSCAUSE CSR = 0x0242 |
| VSTVAL CSR = 0x0243 |
| VSIP CSR = 0x0244 |
| VSATP CSR = 0x0280 |
| MSTATUS CSR = 0x0300 |
| MISA CSR = 0x0301 |
| MEDELEG CSR = 0x0302 |
| MIDELEG CSR = 0x0303 |
| MIE CSR = 0x0304 |
| MTVEC CSR = 0x0305 |
| MCOUNTEREN CSR = 0x0306 |
| MTVT CSR = 0x0307 |
| MSTATUSH CSR = 0x0310 |
| MCOUNTINHIBIT CSR = 0x0320 |
| MHPMEVENT3 CSR = 0x0323 |
| MHPMEVENT4 CSR = 0x0324 |
| MHPMEVENT5 CSR = 0x0325 |
| MHPMEVENT6 CSR = 0x0326 |
| MHPMEVENT7 CSR = 0x0327 |
| MHPMEVENT8 CSR = 0x0328 |
| MHPMEVENT9 CSR = 0x0329 |
| MHPMEVENT10 CSR = 0x032a |
| MHPMEVENT11 CSR = 0x032b |
| MHPMEVENT12 CSR = 0x032c |
| MHPMEVENT13 CSR = 0x032d |
| MHPMEVENT14 CSR = 0x032e |
| MHPMEVENT15 CSR = 0x032f |
| MHPMEVENT16 CSR = 0x0330 |
| MHPMEVENT17 CSR = 0x0331 |
| MHPMEVENT18 CSR = 0x0332 |
| MHPMEVENT19 CSR = 0x0333 |
| MHPMEVENT20 CSR = 0x0334 |
| MHPMEVENT21 CSR = 0x0335 |
| MHPMEVENT22 CSR = 0x0336 |
| MHPMEVENT23 CSR = 0x0337 |
| MHPMEVENT24 CSR = 0x0338 |
| MHPMEVENT25 CSR = 0x0339 |
| MHPMEVENT26 CSR = 0x033a |
| MHPMEVENT27 CSR = 0x033b |
| MHPMEVENT28 CSR = 0x033c |
| MHPMEVENT29 CSR = 0x033d |
| MHPMEVENT30 CSR = 0x033e |
| MHPMEVENT31 CSR = 0x033f |
| MSCRATCH CSR = 0x0340 |
| MEPC CSR = 0x0341 |
| MCAUSE CSR = 0x0342 |
| MTVAL CSR = 0x0343 |
| MIP CSR = 0x0344 |
| MNXTI CSR = 0x0345 |
| MINTSTATUS CSR = 0x0346 |
| MSCRATCHCSW CSR = 0x0348 |
| MSCRATCHCSWL CSR = 0x0349 |
| MTINST CSR = 0x034a |
| MTVAL2 CSR = 0x034b |
| PMPCFG0 CSR = 0x03a0 |
| PMPCFG1 CSR = 0x03a1 |
| PMPCFG2 CSR = 0x03a2 |
| PMPCFG3 CSR = 0x03a3 |
| PMPADDR0 CSR = 0x03b0 |
| PMPADDR1 CSR = 0x03b1 |
| PMPADDR2 CSR = 0x03b2 |
| PMPADDR3 CSR = 0x03b3 |
| PMPADDR4 CSR = 0x03b4 |
| PMPADDR5 CSR = 0x03b5 |
| PMPADDR6 CSR = 0x03b6 |
| PMPADDR7 CSR = 0x03b7 |
| PMPADDR8 CSR = 0x03b8 |
| PMPADDR9 CSR = 0x03b9 |
| PMPADDR10 CSR = 0x03ba |
| PMPADDR11 CSR = 0x03bb |
| PMPADDR12 CSR = 0x03bc |
| PMPADDR13 CSR = 0x03bd |
| PMPADDR14 CSR = 0x03be |
| PMPADDR15 CSR = 0x03bf |
| HSTATUS CSR = 0x0600 |
| HEDELEG CSR = 0x0602 |
| HIDELEG CSR = 0x0603 |
| HIE CSR = 0x0604 |
| HTIMEDELTA CSR = 0x0605 |
| HCOUNTEREN CSR = 0x0606 |
| HGEIE CSR = 0x0607 |
| HTIMEDELTAH CSR = 0x0615 |
| HTVAL CSR = 0x0643 |
| HIP CSR = 0x0644 |
| HVIP CSR = 0x0645 |
| HTINST CSR = 0x064a |
| HGATP CSR = 0x0680 |
| TSELECT CSR = 0x07a0 |
| TDATA1 CSR = 0x07a1 |
| TDATA2 CSR = 0x07a2 |
| TDATA3 CSR = 0x07a3 |
| TINFO CSR = 0x07a4 |
| TCONTROL CSR = 0x07a5 |
| MCONTEXT CSR = 0x07a8 |
| MNOISE CSR = 0x07a9 |
| SCONTEXT CSR = 0x07aa |
| DCSR CSR = 0x07b0 |
| DPC CSR = 0x07b1 |
| DSCRATCH0 CSR = 0x07b2 |
| DSCRATCH1 CSR = 0x07b3 |
| MCYCLE CSR = 0x0b00 |
| MINSTRET CSR = 0x0b02 |
| MHPMCOUNTER3 CSR = 0x0b03 |
| MHPMCOUNTER4 CSR = 0x0b04 |
| MHPMCOUNTER5 CSR = 0x0b05 |
| MHPMCOUNTER6 CSR = 0x0b06 |
| MHPMCOUNTER7 CSR = 0x0b07 |
| MHPMCOUNTER8 CSR = 0x0b08 |
| MHPMCOUNTER9 CSR = 0x0b09 |
| MHPMCOUNTER10 CSR = 0x0b0a |
| MHPMCOUNTER11 CSR = 0x0b0b |
| MHPMCOUNTER12 CSR = 0x0b0c |
| MHPMCOUNTER13 CSR = 0x0b0d |
| MHPMCOUNTER14 CSR = 0x0b0e |
| MHPMCOUNTER15 CSR = 0x0b0f |
| MHPMCOUNTER16 CSR = 0x0b10 |
| MHPMCOUNTER17 CSR = 0x0b11 |
| MHPMCOUNTER18 CSR = 0x0b12 |
| MHPMCOUNTER19 CSR = 0x0b13 |
| MHPMCOUNTER20 CSR = 0x0b14 |
| MHPMCOUNTER21 CSR = 0x0b15 |
| MHPMCOUNTER22 CSR = 0x0b16 |
| MHPMCOUNTER23 CSR = 0x0b17 |
| MHPMCOUNTER24 CSR = 0x0b18 |
| MHPMCOUNTER25 CSR = 0x0b19 |
| MHPMCOUNTER26 CSR = 0x0b1a |
| MHPMCOUNTER27 CSR = 0x0b1b |
| MHPMCOUNTER28 CSR = 0x0b1c |
| MHPMCOUNTER29 CSR = 0x0b1d |
| MHPMCOUNTER30 CSR = 0x0b1e |
| MHPMCOUNTER31 CSR = 0x0b1f |
| MCYCLEH CSR = 0x0b80 |
| MINSTRETH CSR = 0x0b82 |
| MHPMCOUNTER3H CSR = 0x0b83 |
| MHPMCOUNTER4H CSR = 0x0b84 |
| MHPMCOUNTER5H CSR = 0x0b85 |
| MHPMCOUNTER6H CSR = 0x0b86 |
| MHPMCOUNTER7H CSR = 0x0b87 |
| MHPMCOUNTER8H CSR = 0x0b88 |
| MHPMCOUNTER9H CSR = 0x0b89 |
| MHPMCOUNTER10H CSR = 0x0b8a |
| MHPMCOUNTER11H CSR = 0x0b8b |
| MHPMCOUNTER12H CSR = 0x0b8c |
| MHPMCOUNTER13H CSR = 0x0b8d |
| MHPMCOUNTER14H CSR = 0x0b8e |
| MHPMCOUNTER15H CSR = 0x0b8f |
| MHPMCOUNTER16H CSR = 0x0b90 |
| MHPMCOUNTER17H CSR = 0x0b91 |
| MHPMCOUNTER18H CSR = 0x0b92 |
| MHPMCOUNTER19H CSR = 0x0b93 |
| MHPMCOUNTER20H CSR = 0x0b94 |
| MHPMCOUNTER21H CSR = 0x0b95 |
| MHPMCOUNTER22H CSR = 0x0b96 |
| MHPMCOUNTER23H CSR = 0x0b97 |
| MHPMCOUNTER24H CSR = 0x0b98 |
| MHPMCOUNTER25H CSR = 0x0b99 |
| MHPMCOUNTER26H CSR = 0x0b9a |
| MHPMCOUNTER27H CSR = 0x0b9b |
| MHPMCOUNTER28H CSR = 0x0b9c |
| MHPMCOUNTER29H CSR = 0x0b9d |
| MHPMCOUNTER30H CSR = 0x0b9e |
| MHPMCOUNTER31H CSR = 0x0b9f |
| CYCLE CSR = 0x0c00 |
| TIME CSR = 0x0c01 |
| INSTRET CSR = 0x0c02 |
| HPMCOUNTER3 CSR = 0x0c03 |
| HPMCOUNTER4 CSR = 0x0c04 |
| HPMCOUNTER5 CSR = 0x0c05 |
| HPMCOUNTER6 CSR = 0x0c06 |
| HPMCOUNTER7 CSR = 0x0c07 |
| HPMCOUNTER8 CSR = 0x0c08 |
| HPMCOUNTER9 CSR = 0x0c09 |
| HPMCOUNTER10 CSR = 0x0c0a |
| HPMCOUNTER11 CSR = 0x0c0b |
| HPMCOUNTER12 CSR = 0x0c0c |
| HPMCOUNTER13 CSR = 0x0c0d |
| HPMCOUNTER14 CSR = 0x0c0e |
| HPMCOUNTER15 CSR = 0x0c0f |
| HPMCOUNTER16 CSR = 0x0c10 |
| HPMCOUNTER17 CSR = 0x0c11 |
| HPMCOUNTER18 CSR = 0x0c12 |
| HPMCOUNTER19 CSR = 0x0c13 |
| HPMCOUNTER20 CSR = 0x0c14 |
| HPMCOUNTER21 CSR = 0x0c15 |
| HPMCOUNTER22 CSR = 0x0c16 |
| HPMCOUNTER23 CSR = 0x0c17 |
| HPMCOUNTER24 CSR = 0x0c18 |
| HPMCOUNTER25 CSR = 0x0c19 |
| HPMCOUNTER26 CSR = 0x0c1a |
| HPMCOUNTER27 CSR = 0x0c1b |
| HPMCOUNTER28 CSR = 0x0c1c |
| HPMCOUNTER29 CSR = 0x0c1d |
| HPMCOUNTER30 CSR = 0x0c1e |
| HPMCOUNTER31 CSR = 0x0c1f |
| VL CSR = 0x0c20 |
| VTYPE CSR = 0x0c21 |
| VLENB CSR = 0x0c22 |
| CYCLEH CSR = 0x0c80 |
| TIMEH CSR = 0x0c81 |
| INSTRETH CSR = 0x0c82 |
| HPMCOUNTER3H CSR = 0x0c83 |
| HPMCOUNTER4H CSR = 0x0c84 |
| HPMCOUNTER5H CSR = 0x0c85 |
| HPMCOUNTER6H CSR = 0x0c86 |
| HPMCOUNTER7H CSR = 0x0c87 |
| HPMCOUNTER8H CSR = 0x0c88 |
| HPMCOUNTER9H CSR = 0x0c89 |
| HPMCOUNTER10H CSR = 0x0c8a |
| HPMCOUNTER11H CSR = 0x0c8b |
| HPMCOUNTER12H CSR = 0x0c8c |
| HPMCOUNTER13H CSR = 0x0c8d |
| HPMCOUNTER14H CSR = 0x0c8e |
| HPMCOUNTER15H CSR = 0x0c8f |
| HPMCOUNTER16H CSR = 0x0c90 |
| HPMCOUNTER17H CSR = 0x0c91 |
| HPMCOUNTER18H CSR = 0x0c92 |
| HPMCOUNTER19H CSR = 0x0c93 |
| HPMCOUNTER20H CSR = 0x0c94 |
| HPMCOUNTER21H CSR = 0x0c95 |
| HPMCOUNTER22H CSR = 0x0c96 |
| HPMCOUNTER23H CSR = 0x0c97 |
| HPMCOUNTER24H CSR = 0x0c98 |
| HPMCOUNTER25H CSR = 0x0c99 |
| HPMCOUNTER26H CSR = 0x0c9a |
| HPMCOUNTER27H CSR = 0x0c9b |
| HPMCOUNTER28H CSR = 0x0c9c |
| HPMCOUNTER29H CSR = 0x0c9d |
| HPMCOUNTER30H CSR = 0x0c9e |
| HPMCOUNTER31H CSR = 0x0c9f |
| HGEIP CSR = 0x0e12 |
| MVENDORID CSR = 0x0f11 |
| MARCHID CSR = 0x0f12 |
| MIMPID CSR = 0x0f13 |
| MHARTID CSR = 0x0f14 |
| MENTROPY CSR = 0x0f15 |
| ) |
| |
| // An Uimm is an unsigned immediate number |
| type Uimm struct { |
| Imm uint32 // 32-bit unsigned integer |
| Decimal bool // Print format of the immediate, either decimal or hexadecimal |
| } |
| |
| func (ui Uimm) String() string { |
| if ui.Decimal { |
| return fmt.Sprintf("%d", ui.Imm) |
| } |
| return fmt.Sprintf("%#x", ui.Imm) |
| } |
| |
| // A Simm is a signed immediate number |
| type Simm struct { |
| Imm int32 // 32-bit signed integer |
| Decimal bool // Print format of the immediate, either decimal or hexadecimal |
| Width uint8 // Actual width of the Simm |
| } |
| |
| func (si Simm) String() string { |
| if si.Decimal { |
| return fmt.Sprintf("%d", si.Imm) |
| } |
| return fmt.Sprintf("%#x", si.Imm) |
| } |
| |
| // An AmoReg is an atomic address register used in AMO instructions |
| type AmoReg struct { |
| reg Reg // Avoid promoted String method |
| } |
| |
| func (amoReg AmoReg) String() string { |
| return fmt.Sprintf("(%s)", amoReg.reg) |
| } |
| |
| // A RegOffset is a register with offset value |
| type RegOffset struct { |
| OfsReg Reg |
| Ofs Simm |
| } |
| |
| func (regofs RegOffset) String() string { |
| return fmt.Sprintf("%s(%s)", regofs.Ofs, regofs.OfsReg) |
| } |
| |
| // A MemOrder is a memory order hint in fence instruction |
| type MemOrder uint8 |
| |
| func (memOrder MemOrder) String() string { |
| var str string |
| if memOrder<<7>>7 == 1 { |
| str += "i" |
| } |
| if memOrder>>1<<7>>7 == 1 { |
| str += "o" |
| } |
| if memOrder>>2<<7>>7 == 1 { |
| str += "r" |
| } |
| if memOrder>>3<<7>>7 == 1 { |
| str += "w" |
| } |
| return str |
| } |