delve/1001-add-loongarch64-support-not-upstream-new.patch
herengui 15e4060dbf 添加龙芯架构支持
Signed-off-by: herengui <herengui@kylinsec.com.cn>
(cherry picked from commit 91b4abdf69d62640a91ec0a081579f4648dc555b)
2023-09-13 18:30:42 +08:00

3183 lines
97 KiB
Diff

From 4f40e314c15265038af687b02e4694d0e4030798 Mon Sep 17 00:00:00 2001
From: herengui <herengui@kylinsec.com.cn>
Date: Thu, 31 Aug 2023 11:14:31 +0800
Subject: [PATCH 1001/1001] add loongarch64 support not upstream new
Signed-off-by: herengui <herengui@kylinsec.com.cn>
---
pkg/dwarf/regnum/loong64.go | 88 +
pkg/proc/gdbserial/gdbserver_conn_loong64.go | 16 +
pkg/proc/linutil/regs_loong64_arch.go | 182 +++
pkg/proc/loong64_arch.go | 304 ++++
pkg/proc/loong64_disasm.go | 215 +++
pkg/proc/native/registers_linux_loong64.go | 160 ++
pkg/proc/native/threads_linux_loong64.go | 54 +
.../x/arch/loong64/loong64asm/arg.go | 88 +
.../x/arch/loong64/loong64asm/decode.go | 216 +++
.../x/arch/loong64/loong64asm/gnu.go | 16 +
.../x/arch/loong64/loong64asm/inst.go | 307 ++++
.../x/arch/loong64/loong64asm/tables.go | 1417 +++++++++++++++++
12 files changed, 3063 insertions(+)
create mode 100644 pkg/dwarf/regnum/loong64.go
create mode 100644 pkg/proc/gdbserial/gdbserver_conn_loong64.go
create mode 100644 pkg/proc/linutil/regs_loong64_arch.go
create mode 100644 pkg/proc/loong64_arch.go
create mode 100644 pkg/proc/loong64_disasm.go
create mode 100644 pkg/proc/native/registers_linux_loong64.go
create mode 100644 pkg/proc/native/threads_linux_loong64.go
create mode 100644 vendor/golang.org/x/arch/loong64/loong64asm/arg.go
create mode 100644 vendor/golang.org/x/arch/loong64/loong64asm/decode.go
create mode 100644 vendor/golang.org/x/arch/loong64/loong64asm/gnu.go
create mode 100644 vendor/golang.org/x/arch/loong64/loong64asm/inst.go
create mode 100644 vendor/golang.org/x/arch/loong64/loong64asm/tables.go
diff --git a/pkg/dwarf/regnum/loong64.go b/pkg/dwarf/regnum/loong64.go
new file mode 100644
index 0000000..ab14ef4
--- /dev/null
+++ b/pkg/dwarf/regnum/loong64.go
@@ -0,0 +1,88 @@
+package regnum
+
+import (
+ "fmt"
+)
+
+// The mapping between hardware registers and DWARF registers, See
+// https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html
+
+const (
+ // General CPU Registers
+ LOONG64_R0 = 0
+ LOONG64_R1 = 1
+ LOONG64_R2 = 2
+ LOONG64_R3 = 3
+ LOONG64_R4 = 4
+ LOONG64_R5 = 5
+ LOONG64_R6 = 6
+ LOONG64_R7 = 7
+ LOONG64_R8 = 8
+ LOONG64_R9 = 9
+ LOONG64_R10 = 10
+ LOONG64_R11 = 11
+ LOONG64_R12 = 12
+ LOONG64_R13 = 13
+ LOONG64_R14 = 14
+ LOONG64_R15 = 15
+ LOONG64_R16 = 16
+ LOONG64_R17 = 17
+ LOONG64_R18 = 18
+ LOONG64_R19 = 19
+ LOONG64_R20 = 20
+ LOONG64_R21 = 21
+ LOONG64_R22 = 22
+ LOONG64_R23 = 23
+ LOONG64_R24 = 24
+ LOONG64_R25 = 25
+ LOONG64_R26 = 26
+ LOONG64_R27 = 27
+ LOONG64_R28 = 28
+ LOONG64_R29 = 29
+ LOONG64_R30 = 30
+ LOONG64_R31 = 31
+
+ // Control and Status Registers
+ LOONG64_ERA = 32
+ LOONG64_BADV = 33
+
+ // See golang src/cmd/link/internal/loong64/l.go
+ LOONG64_SP = LOONG64_R3 // sp : stack pointer
+ LOONG64_FP = LOONG64_R22 // fp : frame pointer
+ LOONG64_LR = LOONG64_R1 // ra : address fro subroutine
+ LOONG64_PC = LOONG64_ERA // rea : exception program counter
+
+ _LOONG64_MaxRegNum = LOONG64_BADV + 1
+)
+
+func LOONG64ToName(num uint64) string {
+ switch {
+ case num <= LOONG64_R31:
+ return fmt.Sprintf("r%d", num)
+
+ case num == LOONG64_ERA:
+ return "era"
+
+ case num == LOONG64_BADV:
+ return "badv"
+
+ default:
+ return fmt.Sprintf("unknown%d", num)
+ }
+}
+
+func LOONG64MaxRegNum() uint64 {
+ return _LOONG64_MaxRegNum
+}
+
+var LOONG64NameToDwarf = func() map[string]int {
+ r := make(map[string]int)
+ for i := 0; i <= LOONG64_R31; i++ {
+ r[fmt.Sprintf("r%d", i)] = LOONG64_R0 + i
+ }
+
+ r["era"] = 32
+ r["badv"] = 33
+
+ return r
+}()
\ No newline at end of file
diff --git a/pkg/proc/gdbserial/gdbserver_conn_loong64.go b/pkg/proc/gdbserial/gdbserver_conn_loong64.go
new file mode 100644
index 0000000..d25ffbe
--- /dev/null
+++ b/pkg/proc/gdbserial/gdbserver_conn_loong64.go
@@ -0,0 +1,16 @@
+//+build loong64
+
+package gdbserial
+
+const (
+ regnamePC = "rea"
+ regnameCX = "ra"
+ regnameSP = "sp"
+ regnameBP = "fp"
+
+ // not needed but needs to be declared
+ regnameFsBase = ""
+ regnameDX = ""
+
+ breakpointKind = 4
+)
diff --git a/pkg/proc/linutil/regs_loong64_arch.go b/pkg/proc/linutil/regs_loong64_arch.go
new file mode 100644
index 0000000..1c9350a
--- /dev/null
+++ b/pkg/proc/linutil/regs_loong64_arch.go
@@ -0,0 +1,182 @@
+package linutil
+
+import (
+ "fmt"
+ "github.com/go-delve/delve/pkg/dwarf/regnum"
+ "github.com/go-delve/delve/pkg/proc"
+ "golang.org/x/arch/loong64/loong64asm"
+)
+
+// Regs is a wrapper for sys.PtraceRegs.
+type LOONG64Registers struct {
+ Regs *LOONG64PtraceRegs // general-purpose registers
+ Fpregs []proc.Register // Formatted floating point registers
+ Fpregset []byte // holding all floating point register values
+ loadFpRegs func(*LOONG64Registers) error
+}
+
+func NewLOONG64Registers(regs *LOONG64PtraceRegs, loadFpRegs func(*LOONG64Registers) error) *LOONG64Registers {
+ return &LOONG64Registers{
+ Regs: regs,
+ loadFpRegs: loadFpRegs,
+ }
+}
+
+// LOONG64PtraceRegs is the struct used by the linux kernel to return the GPR
+// for loongarch64 CPUs. refer to sys/unix/zptrace_linux_loong64.go
+type LOONG64PtraceRegs struct {
+ Regs [32]uint64
+ Era uint64
+ BadV uint64
+}
+
+// Slice returns the registers as a list of (name, value) pairs.
+func (r *LOONG64Registers) Slice(floatingPoint bool) ([]proc.Register, error) {
+ var regs64 = []struct {
+ k string
+ v uint64
+ }{
+ {"R0", r.Regs.Regs[regnum.LOONG64_R0]},
+ {"R1", r.Regs.Regs[regnum.LOONG64_R1]},
+ {"R2", r.Regs.Regs[regnum.LOONG64_R2]},
+ {"R3", r.Regs.Regs[regnum.LOONG64_R3]},
+ {"R4", r.Regs.Regs[regnum.LOONG64_R4]},
+ {"R5", r.Regs.Regs[regnum.LOONG64_R5]},
+ {"R6", r.Regs.Regs[regnum.LOONG64_R6]},
+ {"R7", r.Regs.Regs[regnum.LOONG64_R7]},
+ {"R8", r.Regs.Regs[regnum.LOONG64_R8]},
+ {"R9", r.Regs.Regs[regnum.LOONG64_R9]},
+ {"R10", r.Regs.Regs[regnum.LOONG64_R10]},
+ {"R11", r.Regs.Regs[regnum.LOONG64_R11]},
+ {"R12", r.Regs.Regs[regnum.LOONG64_R12]},
+ {"R13", r.Regs.Regs[regnum.LOONG64_R13]},
+ {"R14", r.Regs.Regs[regnum.LOONG64_R14]},
+ {"R15", r.Regs.Regs[regnum.LOONG64_R15]},
+ {"R16", r.Regs.Regs[regnum.LOONG64_R16]},
+ {"R17", r.Regs.Regs[regnum.LOONG64_R17]},
+ {"R18", r.Regs.Regs[regnum.LOONG64_R18]},
+ {"R19", r.Regs.Regs[regnum.LOONG64_R19]},
+ {"R20", r.Regs.Regs[regnum.LOONG64_R20]},
+ {"R21", r.Regs.Regs[regnum.LOONG64_R21]},
+ {"R22", r.Regs.Regs[regnum.LOONG64_R22]},
+ {"R23", r.Regs.Regs[regnum.LOONG64_R23]},
+ {"R24", r.Regs.Regs[regnum.LOONG64_R24]},
+ {"R25", r.Regs.Regs[regnum.LOONG64_R25]},
+ {"R26", r.Regs.Regs[regnum.LOONG64_R26]},
+ {"R27", r.Regs.Regs[regnum.LOONG64_R27]},
+ {"R28", r.Regs.Regs[regnum.LOONG64_R28]},
+ {"R29", r.Regs.Regs[regnum.LOONG64_R29]},
+ {"R30", r.Regs.Regs[regnum.LOONG64_R30]},
+ {"R31", r.Regs.Regs[regnum.LOONG64_R31]},
+ {"ERA", r.Regs.Era},
+ {"BADV", r.Regs.BadV},
+ }
+
+ out := make([]proc.Register, 0, (len(regs64) + len(r.Fpregs)))
+ for _, reg := range regs64 {
+ out = proc.AppendUint64Register(out, reg.k, reg.v)
+ }
+
+ var floatLoadError error
+ if floatingPoint {
+ if r.loadFpRegs != nil {
+ floatLoadError = r.loadFpRegs(r)
+ r.loadFpRegs = nil
+ }
+
+ out = append(out, r.Fpregs...)
+ }
+
+ return out, floatLoadError
+}
+
+// PC returns the value of PC register.
+func (r *LOONG64Registers) PC() uint64 {
+ // PC Register
+ return r.Regs.Era
+}
+
+// SP returns the value of SP register.
+func (r *LOONG64Registers) SP() uint64 {
+ // Stack pointer
+ return r.Regs.Regs[regnum.LOONG64_SP]
+}
+
+// BP returns the value of FP register
+func (r *LOONG64Registers) BP() uint64 {
+ // Frame pointer
+ return r.Regs.Regs[regnum.LOONG64_FP]
+}
+
+// TLS returns the address of the thread local storage memory segment.
+func (r *LOONG64Registers) TLS() uint64 {
+ return 0;
+}
+
+// GAddr returns the address of the G variable if it is known, 0 and false otherwise.
+func (r *LOONG64Registers) GAddr() (uint64, bool) {
+ // REGG is $r22,store the address of g
+ return r.Regs.Regs[regnum.LOONG64_FP], true
+}
+
+// Get returns the value of the n-th register (in loong64asm order).
+func (r *LOONG64Registers) Get(n int) (uint64, error) {
+ reg := loong64asm.Reg(n)
+
+ if reg >= regnum.LOONG64_R0 && reg <= regnum.LOONG64_R31 {
+ return r.Regs.Regs[reg-regnum.LOONG64_R0], nil
+ }
+
+ return 0, proc.ErrUnknownRegister
+}
+
+// Copy returns a copy of these registers that is guaranteed not to change.
+func (r *LOONG64Registers) Copy() (proc.Registers, error) {
+ if r.loadFpRegs != nil {
+ err := r.loadFpRegs(r)
+ r.loadFpRegs = nil
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ var rr LOONG64Registers
+ rr.Regs = &LOONG64PtraceRegs{}
+ *(rr.Regs) = *(r.Regs)
+ if r.Fpregs != nil {
+ rr.Fpregs = make([]proc.Register, len(r.Fpregs))
+ copy(rr.Fpregs, r.Fpregs)
+ }
+
+ if r.Fpregset != nil {
+ rr.Fpregset = make([]byte, len(r.Fpregset))
+ copy(rr.Fpregset, r.Fpregset)
+ }
+
+ return &rr, nil
+}
+
+type LOONG64PtraceFpRegs struct {
+ Vregs []byte
+ Fcc uint64
+ Fcsr uint32
+}
+
+const _LOONG64_FP_VREGS_LENGTH = (32 * 8)
+
+func (fpregs *LOONG64PtraceFpRegs) Decode() (regs []proc.Register) {
+ // floating-pointer register : $f0 - $f32, 64-bit
+ for i := 0; i < _LOONG64_FP_VREGS_LENGTH; i += 8 {
+ name := fmt.Sprintf("$f%d", (i / 8))
+ value := fpregs.Vregs[i : i+8]
+ regs = proc.AppendBytesRegister(regs, name, value)
+ }
+
+ return
+}
+
+func (fpregs *LOONG64PtraceFpRegs) Byte() []byte {
+ fpregs.Vregs = make([]byte, _LOONG64_FP_VREGS_LENGTH)
+
+ return fpregs.Vregs[:]
+}
\ No newline at end of file
diff --git a/pkg/proc/loong64_arch.go b/pkg/proc/loong64_arch.go
new file mode 100644
index 0000000..08d5a39
--- /dev/null
+++ b/pkg/proc/loong64_arch.go
@@ -0,0 +1,304 @@
+package proc
+
+import (
+ "encoding/binary"
+ "fmt"
+ "github.com/go-delve/delve/pkg/dwarf/frame"
+ "github.com/go-delve/delve/pkg/dwarf/op"
+ "github.com/go-delve/delve/pkg/dwarf/regnum"
+ "strings"
+)
+
+// Break Instruction : 0x002a0000
+var loong64BreakInstruction = []byte{0x00, 0x00, 0x2a, 0x00}
+
+// LOONG64Arch returns an initialized LOONG64 struct.
+func LOONG64Arch(goos string) *Arch {
+ return &Arch{
+ Name: "loong64",
+ ptrSize: 8,
+ maxInstructionLength: 4,
+ breakpointInstruction: loong64BreakInstruction,
+ breakInstrMovesPC: true,
+ derefTLS: false,
+ prologues: prologuesLOONG64,
+ fixFrameUnwindContext: loong64FixFrameUnwindContext,
+ switchStack: loong64SwitchStack,
+ regSize: loong64RegSize,
+ RegistersToDwarfRegisters: loong64RegistersToDwarfRegisters,
+ addrAndStackRegsToDwarfRegisters: loong64AddrAndStackRegsToDwarfRegisters,
+ DwarfRegisterToString: loong64DwarfRegisterToString,
+ inhibitStepInto: func(*BinaryInfo, uint64) bool { return false },
+ asmDecode: loong64AsmDecode,
+ usesLR: true,
+ // PCRegNum: regnum.LOONG64_PC,
+ // SPRegNum: regnum.LOONG64_SP,
+ // asmRegisters: loong64AsmRegisters,
+ // RegisterNameToDwarf: nameToDwarfFunc(regnum.LOONG64NameToDwarf),
+ }
+}
+
+func loong64FixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *BinaryInfo) *frame.FrameContext {
+ a := bi.Arch
+
+ if a.sigreturnfn == nil {
+ a.sigreturnfn = bi.LookupFunc["runtime.sigreturn"]
+ }
+
+ if (fctxt == nil) || ((a.sigreturnfn != nil) && (pc >= a.sigreturnfn.Entry) && (pc < a.sigreturnfn.End)) {
+ // When there's no frame descriptor entry use BP (the frame pointer) instead
+ // - return register is [bp + a.PtrSize()] (i.e. [cfa-a.PtrSize()])
+ // - cfa is bp + a.PtrSize()*2
+ // - bp is [bp] (i.e. [cfa-a.PtrSize()*2])
+ // - sp is cfa
+
+ // When the signal handler runs it will move the execution to the signal
+ // handling stack (installed using the sigaltstack system call).
+ // This isn't a proper stack switch: the pointer to g in TLS will still
+ // refer to whatever g was executing on that thread before the signal was
+ // received.
+ // Since go did not execute a stack switch the previous value of sp, pc
+ // and bp is not saved inside g.sched, as it normally would.
+ // The only way to recover is to either read sp/pc from the signal context
+ // parameter (the ucontext_t* parameter) or to unconditionally follow the
+ // frame pointer when we get to runtime.sigreturn (which is what we do
+ // here).
+
+ return &frame.FrameContext{
+ RetAddrReg: regnum.LOONG64_PC,
+ Regs: map[uint64]frame.DWRule{
+ regnum.LOONG64_PC: frame.DWRule{
+ Rule: frame.RuleOffset,
+ Offset: int64(-a.PtrSize()),
+ },
+
+ regnum.LOONG64_FP: frame.DWRule{
+ Rule: frame.RuleOffset,
+ Offset: int64(-2 * a.PtrSize()),
+ },
+
+ regnum.LOONG64_SP: frame.DWRule{
+ Rule: frame.RuleValOffset,
+ Offset: 0,
+ },
+ },
+
+ CFA: frame.DWRule{
+ Rule: frame.RuleCFA,
+ Reg: regnum.LOONG64_FP,
+ Offset: int64(2 * a.PtrSize()),
+ },
+ }
+ }
+
+ if a.crosscall2fn == nil {
+ a.crosscall2fn = bi.LookupFunc["crosscall2"]
+ }
+
+ if a.crosscall2fn != nil && pc >= a.crosscall2fn.Entry && pc < a.crosscall2fn.End {
+ rule := fctxt.CFA
+
+ if rule.Offset == crosscall2SPOffsetBad {
+ switch bi.GOOS {
+ case "windows":
+ rule.Offset += crosscall2SPOffsetWindows
+ default:
+ rule.Offset += crosscall2SPOffsetNonWindows
+ }
+ }
+
+ fctxt.CFA = rule
+ }
+
+ // We assume that RBP is the frame pointer and we want to keep it updated,
+ // so that we can use it to unwind the stack even when we encounter frames
+ // without descriptor entries.
+ // If there isn't a rule already we emit one.
+ if fctxt.Regs[regnum.LOONG64_FP].Rule == frame.RuleUndefined {
+ fctxt.Regs[regnum.LOONG64_FP] = frame.DWRule{
+ Rule: frame.RuleFramePointer,
+ Reg: regnum.LOONG64_FP,
+ Offset: 0,
+ }
+ }
+
+ if fctxt.Regs[regnum.LOONG64_LR].Rule == frame.RuleUndefined {
+ fctxt.Regs[regnum.LOONG64_LR] = frame.DWRule{
+ Rule: frame.RuleFramePointer,
+ Reg: regnum.LOONG64_LR,
+ Offset: 0,
+ }
+ }
+
+ return fctxt
+}
+
+const loong64cgocallSPOffsetSaveSlot = 0x8
+
+func loong64SwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) bool {
+ if it.frame.Current.Fn != nil {
+ switch it.frame.Current.Fn.Name {
+ case "runtime.asmcgocall", "runtime.cgocallback_gofunc", "runtime.sigpanic":
+ //do nothing
+
+ case "runtime.goexit", "runtime.rt0_go", "runtime.mcall":
+ // Look for "top of stack" functions.
+ it.atend = true
+ return true
+
+ case "crosscall2":
+ //The offsets get from runtime/cgo/asm_loong64.s:10
+ newsp, _ := readUintRaw(it.mem, uint64(it.regs.SP()+8*24), int64(it.bi.Arch.PtrSize()))
+ newbp, _ := readUintRaw(it.mem, uint64(it.regs.SP()+8*14), int64(it.bi.Arch.PtrSize()))
+ newlr, _ := readUintRaw(it.mem, uint64(it.regs.SP()+8*15), int64(it.bi.Arch.PtrSize()))
+
+ if it.regs.Reg(it.regs.BPRegNum) != nil {
+ it.regs.Reg(it.regs.BPRegNum).Uint64Val = uint64(newbp)
+ } else {
+ reg, _ := it.readRegisterAt(it.regs.BPRegNum, it.regs.SP()+8*14)
+ it.regs.AddReg(it.regs.BPRegNum, reg)
+ }
+
+ it.regs.Reg(it.regs.LRRegNum).Uint64Val = uint64(newlr)
+ it.regs.Reg(it.regs.SPRegNum).Uint64Val = uint64(newsp)
+ it.pc = newlr
+ return true
+
+ default:
+ if (it.systemstack && it.top && it.g != nil) &&
+ (strings.HasPrefix(it.frame.Current.Fn.Name, "runtime.")) &&
+ (it.frame.Current.Fn.Name != "runtime.fatalthrow") {
+ // The runtime switches to the system stack in multiple places.
+ // This usually happens through a call to runtime.systemstack but there
+ // are functions that switch to the system stack manually (for example
+ // runtime.morestack).
+ // Since we are only interested in printing the system stack for cgo
+ // calls we switch directly to the goroutine stack if we detect that the
+ // function at the top of the stack is a runtime function.
+ it.switchToGoroutineStack()
+
+ return true
+ }
+ }
+ }
+
+ fn := it.bi.PCToFunc(it.frame.Ret)
+ if fn == nil {
+ return false
+ }
+
+ switch fn.Name {
+ case "runtime.asmcgocall":
+ if !it.systemstack {
+ return false
+ }
+
+ // This function is called by a goroutine to execute a C function and
+ // switches from the goroutine stack to the system stack.
+ // Since we are unwinding the stack from callee to caller we have to switch
+ // from the system stack to the goroutine stack.
+ off, _ := readIntRaw(it.mem,
+ uint64(callFrameRegs.SP()+loong64cgocallSPOffsetSaveSlot),
+ int64(it.bi.Arch.PtrSize()))
+ oldsp := callFrameRegs.SP()
+ newsp := uint64(int64(it.stackhi) - off)
+
+ // runtime.asmcgocall can also be called from inside the system stack,
+ // in that case no stack switch actually happens
+ if newsp == oldsp {
+ return false
+ }
+
+ it.systemstack = false
+ callFrameRegs.Reg(callFrameRegs.SPRegNum).Uint64Val = uint64(int64(newsp))
+
+ return false
+
+ case "runtime.cgocallback_gofunc":
+ // For a detailed description of how this works read the long comment at
+ // the start of $GOROOT/src/runtime/cgocall.go and the source code of
+ // runtime.cgocallback_gofunc in $GOROOT/src/runtime/asm_loong64.s
+ //
+ // When a C functions calls back into go it will eventually call into
+ // runtime.cgocallback_gofunc which is the function that does the stack
+ // switch from the system stack back into the goroutine stack
+ // Since we are going backwards on the stack here we see the transition
+ // as goroutine stack -> system stack.
+ if it.systemstack {
+ return false
+ }
+
+ it.loadG0SchedSP()
+ if it.g0_sched_sp <= 0 {
+ return false
+ }
+
+ // entering the system stack
+ callFrameRegs.Reg(callFrameRegs.SPRegNum).Uint64Val = it.g0_sched_sp
+
+ // reads the previous value of g0.sched.sp that runtime.cgocallback_gofunc saved on the stack
+ it.g0_sched_sp, _ = readUintRaw(it.mem,
+ uint64(callFrameRegs.SP()+prevG0schedSPOffsetSaveSlot),
+ int64(it.bi.Arch.PtrSize()))
+ it.systemstack = true
+
+ return false
+ }
+
+ return false
+}
+
+func loong64RegSize(regnum uint64) int {
+ // All CPU registers are 64bit
+ return 8
+}
+
+var loong64NameToDwarf = func() map[string]int {
+ r := make(map[string]int)
+ for i := 0; i <= 31; i++ {
+ r[fmt.Sprintf("r%d", i)] = i
+ }
+
+ r["era"] = int(regnum.LOONG64_ERA)
+ r["badv"] = int(regnum.LOONG64_BADV)
+
+ return r
+}()
+
+func loong64RegistersToDwarfRegisters(staticBase uint64, regs Registers) op.DwarfRegisters {
+ dregs := initDwarfRegistersFromSlice(int(regnum.LOONG64MaxRegNum()),
+ regs, regnum.LOONG64NameToDwarf)
+
+ dr := op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.LOONG64_PC,
+ regnum.LOONG64_SP, regnum.LOONG64_FP, regnum.LOONG64_LR)
+
+ dr.SetLoadMoreCallback(loadMoreDwarfRegistersFromSliceFunc(dr, regs, loong64NameToDwarf))
+
+ return *dr
+}
+
+func loong64AddrAndStackRegsToDwarfRegisters(staticBase, pc, sp, bp, lr uint64) op.DwarfRegisters {
+ dregs := make([]*op.DwarfRegister, int(regnum.LOONG64MaxRegNum()))
+
+ dregs[regnum.LOONG64_PC] = op.DwarfRegisterFromUint64(pc)
+ dregs[regnum.LOONG64_SP] = op.DwarfRegisterFromUint64(sp)
+ dregs[regnum.LOONG64_FP] = op.DwarfRegisterFromUint64(bp)
+ dregs[regnum.LOONG64_LR] = op.DwarfRegisterFromUint64(lr)
+
+ return *op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.LOONG64_PC,
+ regnum.LOONG64_SP, regnum.LOONG64_FP, regnum.LOONG64_LR)
+}
+
+func loong64DwarfRegisterToString(i int, reg *op.DwarfRegister) (name string, floatingPoint bool, repr string) {
+ name = regnum.LOONG64ToName(uint64(i))
+
+ if reg == nil {
+ return name, false, ""
+ }
+
+ // Only support general-purpose registers
+ floatingPoint = false
+ repr = fmt.Sprintf("%#016x", reg.Uint64Val)
+
+ return name, floatingPoint, repr
+}
\ No newline at end of file
diff --git a/pkg/proc/loong64_disasm.go b/pkg/proc/loong64_disasm.go
new file mode 100644
index 0000000..b28bdc0
--- /dev/null
+++ b/pkg/proc/loong64_disasm.go
@@ -0,0 +1,215 @@
+// TODO: disassembler support should be compiled in unconditionally,
+// instead of being decided by the build-target architecture, and be
+// part of the Arch object instead.
+
+package proc
+
+import (
+ "fmt"
+ // "github.com/go-delve/delve/pkg/dwarf/op"
+ // "github.com/go-delve/delve/pkg/dwarf/regnum"
+ "golang.org/x/arch/loong64/loong64asm"
+)
+
+var (
+ errType = fmt.Errorf("unknown type")
+)
+
+func loong64AsmDecode(asmInst *AsmInstruction, mem []byte, regs Registers,
+ memrw MemoryReadWriter, bi *BinaryInfo) error {
+
+ asmInst.Size = 4
+ asmInst.Bytes = mem[:asmInst.Size]
+
+ inst, err := loong64asm.Decode(mem)
+ if err != nil {
+ asmInst.Inst = (*loong64ArchInst)(nil)
+ return err
+ }
+
+ asmInst.Inst = (*loong64ArchInst)(&inst)
+
+ switch inst.Op {
+ case loong64asm.BL:
+ //write return addr to ra
+ asmInst.Kind = CallInstruction
+
+ case loong64asm.JIRL:
+ asmInst.Kind = RetInstruction
+
+ case loong64asm.BEQZ,
+ loong64asm.BNEZ,
+ loong64asm.BCEQZ,
+ loong64asm.BCNEZ,
+ loong64asm.B,
+ loong64asm.BEQ,
+ loong64asm.BNE,
+ loong64asm.BLT,
+ loong64asm.BGE,
+ loong64asm.BLTU,
+ loong64asm.BGEU:
+ asmInst.Kind = JmpInstruction
+
+ case loong64asm.BREAK:
+ asmInst.Kind = HardBreakInstruction
+
+ default:
+ asmInst.Kind = OtherInstruction
+ }
+
+ asmInst.DestLoc = resolveCallArgLOONG64(&inst, asmInst.Loc.PC, asmInst.AtPC, regs, memrw, bi)
+
+ return nil
+}
+
+func resolveCallArgLOONG64(inst *loong64asm.Inst, instAddr uint64, currentGoroutine bool,
+ regs Registers, mem MemoryReadWriter, bininfo *BinaryInfo) *Location {
+ var pc uint64
+
+ switch inst.Op {
+ // Format : INST offs
+ case loong64asm.B,
+ loong64asm.BL:
+
+ switch arg := inst.Args[0].(type) {
+ case loong64asm.Imm32:
+ if arg.Imm < 0 {
+ pc = instAddr - uint64(arg.Imm*(-1))
+ } else {
+ pc = instAddr + uint64(arg.Imm)
+ }
+ default:
+ return nil
+ }
+
+ //Format: inst rj,rd,offs16
+ case loong64asm.BEQ,
+ loong64asm.BNE,
+ loong64asm.BLT,
+ loong64asm.BGE,
+ loong64asm.BLTU,
+ loong64asm.BGEU,
+ loong64asm.JIRL:
+
+ switch arg := inst.Args[2].(type) {
+ case loong64asm.Imm32:
+ if arg.Imm < 0 {
+ pc = instAddr - uint64(arg.Imm*(-1))
+ } else {
+ pc = instAddr + uint64(arg.Imm)
+ }
+ default:
+ return nil
+ }
+
+ //Format: inst rj,offs21
+ case loong64asm.BEQZ,
+ loong64asm.BNEZ,
+ loong64asm.BCEQZ,
+ loong64asm.BCNEZ:
+
+ if (!currentGoroutine) || (regs == nil) {
+ return nil
+ }
+
+ switch arg := inst.Args[1].(type) {
+ case loong64asm.Imm32:
+ if arg.Imm < 0 {
+ pc = instAddr - uint64(arg.Imm*(-1))
+ } else {
+ pc = instAddr + uint64(arg.Imm)
+ }
+ default:
+ return nil
+ }
+
+ default:
+ return nil
+ }
+
+ file, line, fn := bininfo.PCToLine(pc)
+ if fn == nil {
+ return &Location{PC: pc}
+ }
+
+ return &Location{PC: pc, File: file, Line: line, Fn: fn}
+}
+
+// Possible stacksplit prologues are inserted by stacksplit in
+// $GOROOT/src/cmd/internal/obj/loong64/obj0.go.
+var prologuesLOONG64 []opcodeSeq
+
+func init() {
+ var tinyStacksplit = opcodeSeq{
+ uint64(loong64asm.SLTU),
+ uint64(loong64asm.JIRL),
+ }
+
+ var smallStacksplit = opcodeSeq{
+ uint64(loong64asm.ADD_W),
+ uint64(loong64asm.SLTU),
+ uint64(loong64asm.JIRL),
+ }
+
+ var bigStacksplit = opcodeSeq{
+ uint64(loong64asm.OR),
+ uint64(loong64asm.BEQ),
+ uint64(loong64asm.ADD_W),
+ uint64(loong64asm.SUB_W),
+ uint64(loong64asm.SLTU),
+ uint64(loong64asm.JIRL),
+ }
+
+ var unixGetG = opcodeSeq{uint64(loong64asm.LD_W)}
+
+ prologuesLOONG64 = make([]opcodeSeq, 0, 3)
+ for _, getG := range []opcodeSeq{unixGetG} {
+ for _, stacksplit := range []opcodeSeq{tinyStacksplit, smallStacksplit, bigStacksplit} {
+ prologue := make(opcodeSeq, 0, len(getG)+len(stacksplit))
+ prologue = append(prologue, getG...)
+ prologue = append(prologue, stacksplit...)
+ prologuesLOONG64 = append(prologuesLOONG64, prologue)
+ }
+ }
+}
+
+type loong64ArchInst loong64asm.Inst
+
+func (inst *loong64ArchInst) Text(flavour AssemblyFlavour, pc uint64,
+ symLookup func(uint64) (string, uint64)) string {
+
+ if inst == nil {
+ return "?"
+ }
+
+ var text string
+
+ switch flavour {
+ case GoFlavour:
+ // Unsupport Goflavour: GoSyntax
+ text = "??"
+
+ default:
+ text = loong64asm.GNUSyntax(loong64asm.Inst(*inst))
+ }
+
+ return text
+}
+
+func (inst *loong64ArchInst) OpcodeEquals(op uint64) bool {
+ if inst == nil {
+ return false
+ }
+
+ return uint64(inst.Op) == op
+}
+
+// var loong64AsmRegisters = func() map[int]asmRegister {
+// r := make(map[int]asmRegister)
+
+// for i := loong64asm.R0; i <= loong64asm.R31; i++ {
+// r[int(i)] = asmRegister{regnum.LOONG64_R0 + uint64(i), 0, 0}
+// }
+
+// return r
+// }()
\ No newline at end of file
diff --git a/pkg/proc/native/registers_linux_loong64.go b/pkg/proc/native/registers_linux_loong64.go
new file mode 100644
index 0000000..0970072
--- /dev/null
+++ b/pkg/proc/native/registers_linux_loong64.go
@@ -0,0 +1,160 @@
+//go:build linux && loong64
+// +build linux,loong64
+
+package native
+
+import (
+ "debug/elf"
+ "fmt"
+ "syscall"
+ "unsafe"
+
+ sys "golang.org/x/sys/unix"
+
+ "github.com/go-delve/delve/pkg/dwarf/op"
+ "github.com/go-delve/delve/pkg/dwarf/regnum"
+ "github.com/go-delve/delve/pkg/proc"
+ "github.com/go-delve/delve/pkg/proc/linutil"
+)
+
+const (
+ // golang/sys : unix/ztypes_linux_loong64.go
+ // 32 GPR * 8 + ERA * 8, refer to definition of kernel
+ _LOONG64_GREGS_SIZE = (32 * 8) + (1 * 8)
+
+ // In fact, the total number of bytes is 268(32 Fpr * 8 + 1 Fcc * 8 + 1 Fcsr +4),
+ // but since the Len defined in sys.Iovec is uint64,the total numbel of bytes must
+ // be an integral multiple of 8,so add 4 bytes
+ _LOONG64_FPREGS_SIZE = (32 * 8) + (1 * 8) + (1 * 4) + 4
+)
+
+func ptraceGetGRegs(pid int, regs *linutil.LOONG64PtraceRegs) (err error) {
+ iov := sys.Iovec{Base: (*byte)(unsafe.Pointer(regs)), Len: _LOONG64_GREGS_SIZE}
+
+ _, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_GETREGSET, uintptr(pid),
+ uintptr(elf.NT_PRSTATUS), uintptr(unsafe.Pointer(&iov)), 0, 0)
+ if err == syscall.Errno(0) {
+ err = nil
+ }
+
+ return
+}
+
+func ptraceSetGRegs(pid int, regs *linutil.LOONG64PtraceRegs) (err error) {
+ iov := sys.Iovec{Base: (*byte)(unsafe.Pointer(regs)), Len: _LOONG64_GREGS_SIZE}
+
+ _, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_SETREGSET, uintptr(pid),
+ uintptr(elf.NT_PRSTATUS), uintptr(unsafe.Pointer(&iov)), 0, 0)
+ if err == syscall.Errno(0) {
+ err = nil
+ }
+
+ return
+}
+
+// ptraceGetFpRegset returns floating point registers of
+// the specified thread using PTRACE.
+func ptraceGetFpRegset(tid int) (fpregset []byte, err error) {
+ fpregs := make([]byte, _LOONG64_FPREGS_SIZE)
+ iov := sys.Iovec{Base: &fpregs[0], Len: uint64(_LOONG64_FPREGS_SIZE)}
+
+ _, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_SETREGSET, uintptr(tid),
+ uintptr(elf.NT_FPREGSET), uintptr(unsafe.Pointer(&iov)), 0, 0)
+ if err != syscall.Errno(0) {
+ if err == syscall.ENODEV {
+ err = nil
+ }
+ return
+ } else {
+ err = nil
+ }
+
+ fpregset = fpregs[:iov.Len-16]
+
+ return fpregset, err
+}
+
+// SetPC sets PC to the value specified by 'pc'.
+func (thread *nativeThread) SetPC(pc uint64) error {
+ ir, err := registers(thread)
+ if err != nil {
+ return err
+ }
+
+ r := ir.(*linutil.LOONG64Registers)
+ r.Regs.Era = pc
+ thread.dbp.execPtraceFunc(func() { err = ptraceSetGRegs(thread.ID, r.Regs) })
+
+ return err
+}
+
+// SetSP sets SP to the value specified by 'sp'
+func (thread *nativeThread) SetSP(sp uint64) (err error) {
+ var ir proc.Registers
+
+ ir, err = registers(thread)
+ if err != nil {
+ return err
+ }
+
+ r := ir.(*linutil.LOONG64Registers)
+ r.Regs.Regs[3] = sp
+ thread.dbp.execPtraceFunc(func() { err = ptraceSetGRegs(thread.ID, r.Regs) })
+
+ return nil
+}
+
+func (thread *nativeThread) SetReg(regNum uint64, reg *op.DwarfRegister) error {
+ ir, err := registers(thread)
+ if err != nil {
+ return err
+ }
+ r := ir.(*linutil.LOONG64Registers)
+
+ switch regNum {
+ case regnum.LOONG64_FP:
+ r.Regs.Regs[regnum.LOONG64_FP] = reg.Uint64Val
+
+ case regnum.LOONG64_LR:
+ r.Regs.Regs[regnum.LOONG64_LR] = reg.Uint64Val
+
+ case regnum.LOONG64_SP:
+ r.Regs.Regs[regnum.LOONG64_SP] = reg.Uint64Val
+
+ case regnum.LOONG64_PC:
+ r.Regs.Era = reg.Uint64Val
+
+ default:
+ //TODO: when the register calling convention is adopted by
+ // Go on loong64 this should be implemented.
+ return fmt.Errorf("changing register %d not implemented", regNum)
+ }
+
+ thread.dbp.execPtraceFunc(func() { err = ptraceSetGRegs(thread.ID, r.Regs) })
+
+ return err
+}
+
+func (thread *nativeThread) SetDX(dx uint64) (err error) {
+ return fmt.Errorf("not supported")
+}
+
+func registers(thread *nativeThread) (proc.Registers, error) {
+ var (
+ regs linutil.LOONG64PtraceRegs
+ err error
+ )
+
+ thread.dbp.execPtraceFunc(func() { err = ptraceGetGRegs(thread.ID, &regs) })
+ if err != nil {
+ return nil, err
+ }
+
+ r := linutil.NewLOONG64Registers(&regs, func(r *linutil.LOONG64Registers) error {
+ var floatLoadError error
+ r.Fpregs, r.Fpregset, floatLoadError = thread.fpRegisters()
+ return floatLoadError
+ })
+
+ return r, nil
+}
\ No newline at end of file
diff --git a/pkg/proc/native/threads_linux_loong64.go b/pkg/proc/native/threads_linux_loong64.go
new file mode 100644
index 0000000..4c9087a
--- /dev/null
+++ b/pkg/proc/native/threads_linux_loong64.go
@@ -0,0 +1,54 @@
+//go:build linux && loong64
+// +build linux,loong64
+
+package native
+
+import (
+ "debug/elf"
+ "fmt"
+ "syscall"
+ "unsafe"
+
+ sys "golang.org/x/sys/unix"
+
+ "github.com/go-delve/delve/pkg/proc"
+ "github.com/go-delve/delve/pkg/proc/linutil"
+)
+
+func (thread *nativeThread) fpRegisters() ([]proc.Register, []byte, error) {
+ var err error
+ var loong64_fpregs linutil.LOONG64PtraceFpRegs
+
+ thread.dbp.execPtraceFunc(func() { loong64_fpregs.Vregs, err = ptraceGetFpRegset(thread.ID) })
+ fpregs := loong64_fpregs.Decode()
+
+ if err != nil {
+ err = fmt.Errorf("could not get floating point registers: %v", err.Error())
+ }
+
+ return fpregs, loong64_fpregs.Vregs, err
+}
+
+func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error {
+ var restoreRegistersErr error
+
+ sr := savedRegs.(*linutil.LOONG64Registers)
+ t.dbp.execPtraceFunc(func() {
+ restoreRegistersErr = ptraceSetGRegs(t.ID, sr.Regs)
+ if restoreRegistersErr != syscall.Errno(0) {
+ return
+ }
+
+ if sr.Fpregset != nil {
+ iov := sys.Iovec{Base: &sr.Fpregset[0], Len: uint64(len(sr.Fpregset))}
+ _, _, restoreRegistersErr = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_SETREGSET,
+ uintptr(t.ID), uintptr(elf.NT_FPREGSET), uintptr(unsafe.Pointer(&iov)), 0, 0)
+ }
+ })
+
+ if restoreRegistersErr == syscall.Errno(0) {
+ restoreRegistersErr = nil
+ }
+
+ return restoreRegistersErr
+}
\ No newline at end of file
diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/arg.go b/vendor/golang.org/x/arch/loong64/loong64asm/arg.go
new file mode 100644
index 0000000..5cb31e3
--- /dev/null
+++ b/vendor/golang.org/x/arch/loong64/loong64asm/arg.go
@@ -0,0 +1,88 @@
+// Copyright 2021 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 loong64asm
+
+// Naming for Go decoder arguments:
+//
+// - arg_fd: a Floating Point operand register fd encoded in the fd[4:0] field
+//
+// - arg_fj: a Floating Point operand register fj encoded in the fj[9:5] field
+//
+// - arg_fk: a Floating Point operand register fk encoded in the fk[14:10] field
+//
+// - arg_fa: a Floating Point operand register fa encoded in the fa[19:15] field
+//
+// - arg_rd: a general-purpose register rd encoded in the rd[4:0] field
+//
+// - arg_rj: a general-purpose register rj encoded in the rj[9:5] field
+//
+// - arg_rk: a general-purpose register rk encoded in the rk[14:10] field
+//
+// - arg_fcsr_4_0: float control status register encoded in [4:0] field
+//
+// - arg_cd_2_0: condition flag register encoded in [2:0] field
+//
+// - arg_sa2_16_15: shift bits constant encoded in [16:15] field
+//
+// - arg_code_14_0: arg for exception process routine encoded in [14:0] field
+//
+// - arg_ui5_14_10: 5bits unsigned immediate
+//
+// - arg_bstrins_lsbw: For details, please refer to chapter 2.2.3.8 of instruction manual
+//
+// - arg_bstrpick_msbw: For details, please refer to chapter 2.2.3.9 of instruction manual
+//
+// - arg_preld_hint_4_0: hint field implied the prefetch type and the data should fetch to cache's level
+// 0: load to data cache level 1
+// 8: store to data cache level 1
+// other: no define
+//
+// - arg_si12_21_10: 12bits signed immediate
+
+type instArg uint16
+
+const (
+ _ instArg = iota
+ //1-5
+ arg_fd
+ arg_fj
+ arg_fk
+ arg_fa
+ arg_rd
+ arg_rd_
+ //6-10
+ arg_rj
+ arg_rk
+ arg_fcsr_4_0
+ arg_fcsr_9_5
+ arg_cd
+ //11-15
+ arg_cj
+ arg_ca
+ arg_sa2_16_15
+ arg_sa2_16_15_bytepickw
+ arg_sa3_17_15
+ //16-20
+ arg_code_14_0
+ arg_ui5_14_10
+ arg_ui6_15_10
+ arg_ui12_21_10
+ arg_bstrins_lsbw
+ //21-25
+ arg_bstrpick_msbw
+ arg_bstrins_lsbd
+ arg_bstrpick_msbd
+ arg_preld_hint_4_0
+ arg_hint_14_0
+ //26-30
+ arg_si12_21_10
+ arg_si14_23_10
+ arg_si16_25_10
+ arg_si20_24_5
+ arg_offset_20_0
+ //31~
+ arg_offset_25_0
+ arg_offset_15_0
+)
\ No newline at end of file
diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/decode.go b/vendor/golang.org/x/arch/loong64/loong64asm/decode.go
new file mode 100644
index 0000000..bcbc702
--- /dev/null
+++ b/vendor/golang.org/x/arch/loong64/loong64asm/decode.go
@@ -0,0 +1,216 @@
+// Copyright 2021 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 loong64asm
+
+import (
+ "encoding/binary"
+ "fmt"
+)
+
+type instArgs [5]instArg
+
+// An instFormat describes the format of an instruction encoding.
+type instFormat struct {
+ mask uint32
+ value uint32
+ op Op
+ // args describe how to decode the instruction arguments.
+ // args is stored as a fixed-size array.
+ // if there are fewer than len(args) arguments, args[i] == 0 marks
+ // the end of the argument list.
+ args instArgs
+}
+
+var (
+ errShort = fmt.Errorf("truncated instruction")
+ errUnknown = fmt.Errorf("unknown instruction")
+)
+
+var decoderCover []bool
+
+func init() {
+ decoderCover = make([]bool, len(instFormats))
+}
+
+// Decode decodes the 4 bytes in src as a single instruction.
+func Decode(src []byte) (inst Inst, err error) {
+ if len(src) < 4 {
+ return Inst{}, errShort
+ }
+
+ x := binary.LittleEndian.Uint32(src)
+
+Search:
+ for i := range instFormats {
+ f := &instFormats[i]
+
+ if (x & f.mask) != f.value {
+ continue
+ }
+
+ // Decode args.
+ var args Args
+ for j, aop := range f.args {
+ if aop == 0 {
+ break
+ }
+
+ arg := decodeArg(aop, x)
+ if arg == nil {
+ // Cannot decode argument
+ continue Search
+ }
+
+ args[j] = arg
+ }
+
+ decoderCover[i] = true
+ inst = Inst{
+ Op: f.op,
+ Args: args,
+ Enc: x,
+ }
+ return inst, nil
+ }
+
+ return Inst{}, errUnknown
+}
+
+// decodeArg decodes the arg described by aop from the instruction bits x.
+// It returns nil if x cannot be decoded according to aop.
+func decodeArg(aop instArg, x uint32) Arg {
+ switch aop {
+ case arg_fd:
+ return F0 + Reg(x&((1<<5)-1))
+
+ case arg_fj:
+ return F0 + Reg((x>>5)&((1<<5)-1))
+
+ case arg_fk:
+ return F0 + Reg((x>>10)&((1<<5)-1))
+
+ case arg_fa:
+ return F0 + Reg((x>>15)&((1<<5)-1))
+
+ case arg_rd:
+ return R0 + Reg(x&((1<<5)-1))
+
+ case arg_rj:
+ return R0 + Reg((x>>5)&((1<<5)-1))
+
+ case arg_rk:
+ return R0 + Reg((x>>10)&((1<<5)-1))
+
+ case arg_fcsr_4_0:
+ return FCSR0 + Fcsr(x&((1<<5)-1))
+
+ case arg_fcsr_9_5:
+ return FCSR0 + Fcsr((x>>5)&((1<<5)-1))
+
+ case arg_cd:
+ return FCC0 + Fcc(x&((1<<3)-1))
+
+ case arg_cj:
+ return FCC0 + Fcc((x>>5)&((1<<3)-1))
+
+ case arg_ca:
+ return FCC0 + Fcc((x>>15)&((1<<3)-1))
+
+ case arg_sa2_16_15:
+ return Sa((x>>15)&((1<<2)-1)) + 1
+
+ case arg_sa2_16_15_bytepickw:
+ return Sa((x >> 15) & ((1 << 2) - 1))
+
+ case arg_sa3_17_15:
+ return Sa((x >> 15) & ((1 << 3) - 1))
+
+ case arg_code_14_0:
+ return Code(x & ((1 << 15) - 1))
+
+ case arg_ui5_14_10:
+ tmp := ((x >> 10) & ((1 << 5) - 1))
+ return Imm{tmp, true}
+
+ case arg_ui6_15_10:
+ tmp := ((x >> 10) & ((1 << 6) - 1))
+ return Imm{tmp, true}
+
+ case arg_ui12_21_10:
+ tmp := ((x >> 10) & ((1 << 12) - 1))
+ return Imm{tmp, true}
+
+ case arg_bstrins_lsbw:
+ tmp := ((x >> 10) & ((1 << 5) - 1))
+ return Imm{tmp, true}
+
+ case arg_bstrpick_msbw:
+ tmp := ((x >> 16) & ((1 << 5) - 1))
+ return Imm{tmp, true}
+
+ case arg_bstrins_lsbd:
+ tmp := ((x >> 10) & ((1 << 6) - 1))
+ return Imm{tmp, true}
+
+ case arg_bstrpick_msbd:
+ tmp := ((x >> 16) & ((1 << 6) - 1))
+ return Imm{tmp, true}
+
+ case arg_preld_hint_4_0:
+ tmp := (x & ((1 << 5) - 1))
+ return Imm{tmp, true}
+
+ case arg_hint_14_0:
+ tmp := (x & ((1 << 15) - 1))
+ return Imm{tmp, true}
+
+ case arg_si12_21_10:
+ var tmp int16
+ //no int12, so sign-extend a 12-bit signed to 16-bit signed
+ if (x & 0x200000) == 0x200000 {
+ tmp = int16(((x >> 10) & ((1 << 12) - 1)) | 0xf000)
+ } else {
+ tmp = int16(((x >> 10) & ((1 << 12) - 1)) | 0x0000)
+ }
+ return Imm16{tmp, true}
+
+ case arg_si14_23_10:
+ var tmp int16
+ if (x & 0x800000) == 0x800000 {
+ tmp = int16(((x>>10)&((1<<14)-1))|0xC000) << 2
+ } else {
+ tmp = int16(((x>>10)&((1<<14)-1))|0x0000) << 2
+ }
+ return Imm16{tmp, true}
+
+ case arg_si16_25_10:
+ tmp := int16((x >> 10) & ((1 << 16) - 1))
+ return Imm16{tmp, true}
+
+ case arg_si20_24_5:
+ var tmp int32
+ if (x & 0x1000000) == 0x1000000 {
+ tmp = int32(((x >> 5) & ((1 << 20) - 1)) | 0xfff00000)
+ } else {
+ tmp = int32(((x >> 5) & ((1 << 20) - 1)) | 0x00000000)
+ }
+ return Imm32{tmp, true}
+
+ case arg_offset_20_0:
+ tmp := (((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 21) - 1)) << 2
+ return Imm{tmp, true}
+
+ case arg_offset_15_0:
+ tmp := ((x >> 10) & ((1 << 16) - 1)) << 2
+ return Imm{tmp, true}
+
+ case arg_offset_25_0:
+ tmp := (((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 26) - 1)) << 2
+ return Imm{tmp, true}
+
+ default:
+ return nil
+ }
+}
\ No newline at end of file
diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go b/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go
new file mode 100644
index 0000000..f914a35
--- /dev/null
+++ b/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go
@@ -0,0 +1,16 @@
+// Copyright 2021 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 loong64asm
+
+import (
+ "strings"
+)
+
+// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
+// This form typically matches the syntax defined in the LOONG64 Reference Manual. See
+// https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html
+func GNUSyntax(inst Inst) string {
+ return strings.ToLower(inst.String())
+}
\ No newline at end of file
diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/inst.go b/vendor/golang.org/x/arch/loong64/loong64asm/inst.go
new file mode 100644
index 0000000..5a4ebf1
--- /dev/null
+++ b/vendor/golang.org/x/arch/loong64/loong64asm/inst.go
@@ -0,0 +1,307 @@
+// Copyright 2021 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 loong64asm
+
+import (
+ "fmt"
+ "strings"
+)
+
+// An Inst is a single instruction.
+type Inst struct {
+ Op Op // Opcode mnemonic
+ Enc uint32 // Raw encoding bits.
+ Args Args // Instruction arguments, in LOONG64 manual order.
+}
+
+func (i Inst) String() string {
+ var args []string
+
+ for _, arg := range i.Args {
+ if arg == nil {
+ break
+ }
+
+ args = append(args, arg.String())
+ }
+
+ str2 := strings.Join(args, ", ")
+ if str2 == "" {
+ str := i.Op.String()
+ return strings.Replace(str, ", (", "(", -1)
+ } else {
+ str := i.Op.String() + " " + strings.Join(args, ", ")
+ return strings.Replace(str, ", (", "(", -1)
+ }
+}
+
+// An Op is an LOONG64 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 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
+type Arg interface {
+ isArg()
+ String() string
+}
+
+// A Reg is a single register.
+// The zero value denotes R0, not the absence of a register.
+// General-purpose register an float register
+type Reg uint16
+
+const (
+ //_ Reg = iota
+
+ // General-purpose register
+ R0 Reg = iota
+ R1
+ R2
+ R3
+ R4
+ R5
+ R6
+ R7
+ R8
+ R9
+ R10
+ R11
+ R12
+ R13
+ R14
+ R15
+ R16
+ R17
+ R18
+ R19
+ R20
+ R21
+ R22
+ R23
+ R24
+ R25
+ R26
+ R27
+ R28
+ R29
+ R30
+ R31
+
+ // 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 (Reg) isArg() {}
+
+// LOONG64 LP64
+func (r Reg) String() string {
+ switch {
+ case r == R0:
+ // zero
+ return "zero"
+
+ case r == R1:
+ // at
+ return "ra"
+
+ case r == R2:
+ // tp
+ return "tp"
+
+ case r == R3:
+ // sp
+ return "sp"
+
+ case (r >= R4) && (r <= R11):
+ // a0 - a7/v0 - v1
+ return fmt.Sprintf("a%d", int(r-R4))
+
+ case (r >= R12) && (r <= R20):
+ // t0 - t8
+ return fmt.Sprintf("t%d", int(r-R12))
+
+ case r == R21:
+ // x
+ return "x"
+
+ case r == R22:
+ // fp
+ return "fp"
+
+ case (r >= R23) && (r <= R31):
+ // s0 - s8
+ return fmt.Sprintf("s%d", int(r-R23))
+
+ case (r >= F0) && (r <= F7):
+ // fa0 - fa7
+ return fmt.Sprintf("fa%d", int(r-F0))
+
+ case (r >= F8) && (r <= F23):
+ // ft0 - ft15
+ return fmt.Sprintf("ft%d", int(r-F8))
+
+ case (r >= F24) && (r <= F31):
+ // fs0 - fs7
+ return fmt.Sprintf("fs%d", int(r-F24))
+
+ default:
+ return fmt.Sprintf("Unknown(%d)", int(r))
+ }
+}
+
+// float control status register
+type Fcsr uint8
+
+const (
+ //_ Fcsr = iota
+ FCSR0 Fcsr = iota
+ FCSR1
+ FCSR2
+ FCSR3
+)
+
+func (Fcsr) isArg() {}
+
+func (f Fcsr) String() string {
+ return fmt.Sprintf("r%d", uint8(f))
+}
+
+// float condition flags register
+type Fcc uint8
+
+func (Fcc) isArg() {}
+
+const (
+ //_ Fcc = iota
+ FCC0 Fcc = iota
+ FCC1
+ FCC2
+ FCC3
+ FCC4
+ FCC5
+ FCC6
+ FCC7
+)
+
+func (f Fcc) String() string {
+ return fmt.Sprintf("fcc%d", uint8(f))
+}
+
+// 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 Imm16 struct {
+ Imm int16
+ Decimal bool
+}
+
+func (Imm16) isArg() {}
+
+func (i Imm16) String() string {
+ if !i.Decimal {
+ return fmt.Sprintf("%#x", i.Imm)
+ } else {
+ return fmt.Sprintf("%d", i.Imm)
+ }
+}
+
+type Imm32 struct {
+ Imm int32
+ Decimal bool
+}
+
+func (Imm32) isArg() {}
+
+func (i Imm32) String() string {
+ if !i.Decimal {
+ return fmt.Sprintf("%#x", i.Imm)
+ } else {
+ return fmt.Sprintf("%d", i.Imm)
+ }
+}
+
+type Offset int32
+
+func (Offset) isArg() {}
+
+func (i Offset) String() string {
+ return fmt.Sprintf("%d", int32(i))
+}
+
+type Sa int16
+
+func (Sa) isArg() {}
+
+func (i Sa) String() string {
+ return fmt.Sprintf("%d", int16(i))
+}
+
+type Code int16
+
+func (Code) isArg() {}
+
+func (c Code) String() string {
+ return fmt.Sprintf("%d", int16(c))
+}
\ No newline at end of file
diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/tables.go b/vendor/golang.org/x/arch/loong64/loong64asm/tables.go
new file mode 100644
index 0000000..2b3ba1f
--- /dev/null
+++ b/vendor/golang.org/x/arch/loong64/loong64asm/tables.go
@@ -0,0 +1,1417 @@
+// Generated by LOONG64 internal tool
+// DO NOT EDIT
+// Copyright 2021 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 loong64asm
+
+const (
+ _ Op = iota
+ ADDI_D
+ ADDI_W
+ ADDU16I_D
+ ADD_D
+ ADD_W
+ ALSL_D
+ ALSL_W
+ ALSL_WU
+ AMADD_D
+ AMADD_DB_D
+ AMADD_DB_W
+ AMADD_W
+ AMAND_D
+ AMAND_DB_D
+ AMAND_DB_W
+ AMAND_W
+ AMMAX_D
+ AMMAX_DB_D
+ AMMAX_DB_DU
+ AMMAX_DB_W
+ AMMAX_DB_WU
+ AMMAX_DU
+ AMMAX_W
+ AMMAX_WU
+ AMMIN_D
+ AMMIN_DB_D
+ AMMIN_DB_DU
+ AMMIN_DB_W
+ AMMIN_DB_WU
+ AMMIN_DU
+ AMMIN_W
+ AMMIN_WU
+ AMOR_D
+ AMOR_DB_D
+ AMOR_DB_W
+ AMOR_W
+ AMSWAP_D
+ AMSWAP_DB_D
+ AMSWAP_DB_W
+ AMSWAP_W
+ AMXOR_D
+ AMXOR_DB_D
+ AMXOR_DB_W
+ AMXOR_W
+ AND
+ ANDI
+ ANDN
+ ASRTGT_D
+ ASRTLE_D
+ B
+ BCEQZ
+ BCNEZ
+ BEQ
+ BEQZ
+ BGE
+ BGEU
+ BITREV_4B
+ BITREV_8B
+ BITREV_D
+ BITREV_W
+ BL
+ BLT
+ BLTU
+ BNE
+ BNEZ
+ BREAK
+ BSTRINS_D
+ BSTRINS_W
+ BSTRPICK_D
+ BSTRPICK_W
+ BYTEPICK_D
+ BYTEPICK_W
+ CLO_D
+ CLO_W
+ CLZ_D
+ CLZ_W
+ CPUCFG
+ CRCC_W_B_W
+ CRCC_W_D_W
+ CRCC_W_H_W
+ CRCC_W_W_W
+ CRC_W_B_W
+ CRC_W_D_W
+ CRC_W_H_W
+ CRC_W_W_W
+ CTO_D
+ CTO_W
+ CTZ_D
+ CTZ_W
+ DBAR
+ DIV_D
+ DIV_DU
+ DIV_W
+ DIV_WU
+ EXT_W_B
+ EXT_W_H
+ FABS_D
+ FABS_S
+ FADD_D
+ FADD_S
+ FCLASS_D
+ FCLASS_S
+ FCMP_CAF_D
+ FCMP_CAF_S
+ FCMP_CEQ_D
+ FCMP_CEQ_S
+ FCMP_CLE_D
+ FCMP_CLE_S
+ FCMP_CLT_D
+ FCMP_CLT_S
+ FCMP_CNE_D
+ FCMP_CNE_S
+ FCMP_COR_D
+ FCMP_COR_S
+ FCMP_CUEQ_D
+ FCMP_CUEQ_S
+ FCMP_CULE_D
+ FCMP_CULE_S
+ FCMP_CULT_D
+ FCMP_CULT_S
+ FCMP_CUNE_D
+ FCMP_CUNE_S
+ FCMP_CUN_D
+ FCMP_CUN_S
+ FCMP_SAF_D
+ FCMP_SAF_S
+ FCMP_SEQ_D
+ FCMP_SEQ_S
+ FCMP_SLE_D
+ FCMP_SLE_S
+ FCMP_SLT_D
+ FCMP_SLT_S
+ FCMP_SNE_D
+ FCMP_SNE_S
+ FCMP_SOR_D
+ FCMP_SOR_S
+ FCMP_SUEQ_D
+ FCMP_SUEQ_S
+ FCMP_SULE_D
+ FCMP_SULE_S
+ FCMP_SULT_D
+ FCMP_SULT_S
+ FCMP_SUNE_D
+ FCMP_SUNE_S
+ FCMP_SUN_D
+ FCMP_SUN_S
+ FCOPYSIGN_D
+ FCOPYSIGN_S
+ FCVT_D_S
+ FCVT_S_D
+ FDIV_D
+ FDIV_S
+ FFINT_D_L
+ FFINT_D_W
+ FFINT_S_L
+ FFINT_S_W
+ FLDGT_D
+ FLDGT_S
+ FLDLE_D
+ FLDLE_S
+ FLDX_D
+ FLDX_S
+ FLD_D
+ FLD_S
+ FLOGB_D
+ FLOGB_S
+ FMADD_D
+ FMADD_S
+ FMAXA_D
+ FMAXA_S
+ FMAX_D
+ FMAX_S
+ FMINA_D
+ FMINA_S
+ FMIN_D
+ FMIN_S
+ FMOV_D
+ FMOV_S
+ FMSUB_D
+ FMSUB_S
+ FMUL_D
+ FMUL_S
+ FNEG_D
+ FNEG_S
+ FNMADD_D
+ FNMADD_S
+ FNMSUB_D
+ FNMSUB_S
+ FRECIP_D
+ FRECIP_S
+ FRINT_D
+ FRINT_S
+ FRSQRT_D
+ FRSQRT_S
+ FSCALEB_D
+ FSCALEB_S
+ FSEL
+ FSQRT_D
+ FSQRT_S
+ FSTGT_D
+ FSTGT_S
+ FSTLE_D
+ FSTLE_S
+ FSTX_D
+ FSTX_S
+ FST_D
+ FST_S
+ FSUB_D
+ FSUB_S
+ FTINTRM_L_D
+ FTINTRM_L_S
+ FTINTRM_W_D
+ FTINTRM_W_S
+ FTINTRNE_L_D
+ FTINTRNE_L_S
+ FTINTRNE_W_D
+ FTINTRNE_W_S
+ FTINTRP_L_D
+ FTINTRP_L_S
+ FTINTRP_W_D
+ FTINTRP_W_S
+ FTINTRZ_L_D
+ FTINTRZ_L_S
+ FTINTRZ_W_D
+ FTINTRZ_W_S
+ FTINT_L_D
+ FTINT_L_S
+ FTINT_W_D
+ FTINT_W_S
+ IBAR
+ JIRL
+ LDGT_B
+ LDGT_D
+ LDGT_H
+ LDGT_W
+ LDLE_B
+ LDLE_D
+ LDLE_H
+ LDLE_W
+ LDPTR_D
+ LDPTR_W
+ LDX_B
+ LDX_BU
+ LDX_D
+ LDX_H
+ LDX_HU
+ LDX_W
+ LDX_WU
+ LD_B
+ LD_BU
+ LD_D
+ LD_H
+ LD_HU
+ LD_W
+ LD_WU
+ LL_D
+ LL_W
+ LU12I_W
+ LU32I_D
+ LU52I_D
+ MASKEQZ
+ MASKNEZ
+ MOD_D
+ MOD_DU
+ MOD_W
+ MOD_WU
+ MOVCF2FR
+ MOVCF2GR
+ MOVFCSR2GR
+ MOVFR2CF
+ MOVFR2GR_D
+ MOVFR2GR_S
+ MOVFRH2GR_S
+ MOVGR2CF
+ MOVGR2FCSR
+ MOVGR2FRH_W
+ MOVGR2FR_D
+ MOVGR2FR_W
+ MULH_D
+ MULH_DU
+ MULH_W
+ MULH_WU
+ MULW_D_W
+ MULW_D_WU
+ MUL_D
+ MUL_W
+ NOR
+ OR
+ ORI
+ ORN
+ PCADDI
+ PCADDU12I
+ PCADDU18I
+ PCALAU12I
+ PRELD
+ PRELDX
+ RDTIMEH_W
+ RDTIMEL_W
+ RDTIME_D
+ REVB_2H
+ REVB_2W
+ REVB_4H
+ REVB_D
+ REVH_2W
+ REVH_D
+ ROTRI_D
+ ROTRI_W
+ ROTR_D
+ ROTR_W
+ SC_D
+ SC_W
+ SLLI_D
+ SLLI_W
+ SLL_D
+ SLL_W
+ SLT
+ SLTI
+ SLTU
+ SLTUI
+ SRAI_D
+ SRAI_W
+ SRA_D
+ SRA_W
+ SRLI_D
+ SRLI_W
+ SRL_D
+ SRL_W
+ STGT_B
+ STGT_D
+ STGT_H
+ STGT_W
+ STLE_B
+ STLE_D
+ STLE_H
+ STLE_W
+ STPTR_D
+ STPTR_W
+ STX_B
+ STX_D
+ STX_H
+ STX_W
+ ST_B
+ ST_D
+ ST_H
+ ST_W
+ SUB_D
+ SUB_W
+ SYSCALL
+ XOR
+ XORI
+)
+
+var opstr = [...]string{
+ ADDI_D: "ADDI.D",
+ ADDI_W: "ADDI.W",
+ ADDU16I_D: "ADDU16I.D",
+ ADD_D: "ADD.D",
+ ADD_W: "ADD.W",
+ ALSL_D: "ALSL.D",
+ ALSL_W: "ALSL.W",
+ ALSL_WU: "ALSL.WU",
+ AMADD_D: "AMADD.D",
+ AMADD_DB_D: "AMADD_DB.D",
+ AMADD_DB_W: "AMADD_DB.W",
+ AMADD_W: "AMADD.W",
+ AMAND_D: "AMAND.D",
+ AMAND_DB_D: "AMAND_DB.D",
+ AMAND_DB_W: "AMAND_DB.W",
+ AMAND_W: "AMAND.W",
+ AMMAX_D: "AMMAX.D",
+ AMMAX_DB_D: "AMMAX_DB.D",
+ AMMAX_DB_DU: "AMMAX_DB.DU",
+ AMMAX_DB_W: "AMMAX_DB.W",
+ AMMAX_DB_WU: "AMMAX_DB.WU",
+ AMMAX_DU: "AMMAX.DU",
+ AMMAX_W: "AMMAX.W",
+ AMMAX_WU: "AMMAX.WU",
+ AMMIN_D: "AMMIN.D",
+ AMMIN_DB_D: "AMMIN_DB.D",
+ AMMIN_DB_DU: "AMMIN_DB.DU",
+ AMMIN_DB_W: "AMMIN_DB.W",
+ AMMIN_DB_WU: "AMMIN_DB.WU",
+ AMMIN_DU: "AMMIN.DU",
+ AMMIN_W: "AMMIN.W",
+ AMMIN_WU: "AMMIN.WU",
+ AMOR_D: "AMOR.D",
+ AMOR_DB_D: "AMOR_DB.D",
+ AMOR_DB_W: "AMOR_DB.W",
+ AMOR_W: "AMOR.W",
+ AMSWAP_D: "AMSWAP.D",
+ AMSWAP_DB_D: "AMSWAP_DB.D",
+ AMSWAP_DB_W: "AMSWAP_DB.W",
+ AMSWAP_W: "AMSWAP.W",
+ AMXOR_D: "AMXOR.D",
+ AMXOR_DB_D: "AMXOR_DB.D",
+ AMXOR_DB_W: "AMXOR_DB.W",
+ AMXOR_W: "AMXOR.W",
+ AND: "AND",
+ ANDI: "ANDI",
+ ANDN: "ANDN",
+ ASRTGT_D: "ASRTGT.D",
+ ASRTLE_D: "ASRTLE.D",
+ B: "B",
+ BCEQZ: "BCEQZ",
+ BCNEZ: "BCNEZ",
+ BEQ: "BEQ",
+ BEQZ: "BEQZ",
+ BGE: "BGE",
+ BGEU: "BGEU",
+ BITREV_4B: "BITREV.4B",
+ BITREV_8B: "BITREV.8B",
+ BITREV_D: "BITREV.D",
+ BITREV_W: "BITREV.W",
+ BL: "BL",
+ BLT: "BLT",
+ BLTU: "BLTU",
+ BNE: "BNE",
+ BNEZ: "BNEZ",
+ BREAK: "BREAK",
+ BSTRINS_D: "BSTRINS.D",
+ BSTRINS_W: "BSTRINS.W",
+ BSTRPICK_D: "BSTRPICK.D",
+ BSTRPICK_W: "BSTRPICK.W",
+ BYTEPICK_D: "BYTEPICK.D",
+ BYTEPICK_W: "BYTEPICK.W",
+ CLO_D: "CLO.D",
+ CLO_W: "CLO.W",
+ CLZ_D: "CLZ.D",
+ CLZ_W: "CLZ.W",
+ CPUCFG: "CPUCFG",
+ CRCC_W_B_W: "CRCC.W.B.W",
+ CRCC_W_D_W: "CRCC.W.D.W",
+ CRCC_W_H_W: "CRCC.W.H.W",
+ CRCC_W_W_W: "CRCC.W.W.W",
+ CRC_W_B_W: "CRC.W.B.W",
+ CRC_W_D_W: "CRC.W.D.W",
+ CRC_W_H_W: "CRC.W.H.W",
+ CRC_W_W_W: "CRC.W.W.W",
+ CTO_D: "CTO.D",
+ CTO_W: "CTO.W",
+ CTZ_D: "CTZ.D",
+ CTZ_W: "CTZ.W",
+ DBAR: "DBAR",
+ DIV_D: "DIV.D",
+ DIV_DU: "DIV.DU",
+ DIV_W: "DIV.W",
+ DIV_WU: "DIV.WU",
+ EXT_W_B: "EXT.W.B",
+ EXT_W_H: "EXT.W.H",
+ FABS_D: "FABS.D",
+ FABS_S: "FABS.S",
+ FADD_D: "FADD.D",
+ FADD_S: "FADD.S",
+ FCLASS_D: "FCLASS.D",
+ FCLASS_S: "FCLASS.S",
+ FCMP_CAF_D: "FCMP.CAF.D",
+ FCMP_CAF_S: "FCMP.CAF.S",
+ FCMP_CEQ_D: "FCMP.CEQ.D",
+ FCMP_CEQ_S: "FCMP.CEQ.S",
+ FCMP_CLE_D: "FCMP.CLE.D",
+ FCMP_CLE_S: "FCMP.CLE.S",
+ FCMP_CLT_D: "FCMP.CLT.D",
+ FCMP_CLT_S: "FCMP.CLT.S",
+ FCMP_CNE_D: "FCMP.CNE.D",
+ FCMP_CNE_S: "FCMP.CNE.S",
+ FCMP_COR_D: "FCMP.COR.D",
+ FCMP_COR_S: "FCMP.COR.S",
+ FCMP_CUEQ_D: "FCMP.CUEQ.D",
+ FCMP_CUEQ_S: "FCMP.CUEQ.S",
+ FCMP_CULE_D: "FCMP.CULE.D",
+ FCMP_CULE_S: "FCMP.CULE.S",
+ FCMP_CULT_D: "FCMP.CULT.D",
+ FCMP_CULT_S: "FCMP.CULT.S",
+ FCMP_CUNE_D: "FCMP.CUNE.D",
+ FCMP_CUNE_S: "FCMP.CUNE.S",
+ FCMP_CUN_D: "FCMP.CUN.D",
+ FCMP_CUN_S: "FCMP.CUN.S",
+ FCMP_SAF_D: "FCMP.SAF.D",
+ FCMP_SAF_S: "FCMP.SAF.S",
+ FCMP_SEQ_D: "FCMP.SEQ.D",
+ FCMP_SEQ_S: "FCMP.SEQ.S",
+ FCMP_SLE_D: "FCMP.SLE.D",
+ FCMP_SLE_S: "FCMP.SLE.S",
+ FCMP_SLT_D: "FCMP.SLT.D",
+ FCMP_SLT_S: "FCMP.SLT.S",
+ FCMP_SNE_D: "FCMP.SNE.D",
+ FCMP_SNE_S: "FCMP.SNE.S",
+ FCMP_SOR_D: "FCMP.SOR.D",
+ FCMP_SOR_S: "FCMP.SOR.S",
+ FCMP_SUEQ_D: "FCMP.SUEQ.D",
+ FCMP_SUEQ_S: "FCMP.SUEQ.S",
+ FCMP_SULE_D: "FCMP.SULE.D",
+ FCMP_SULE_S: "FCMP.SULE.S",
+ FCMP_SULT_D: "FCMP.SULT.D",
+ FCMP_SULT_S: "FCMP.SULT.S",
+ FCMP_SUNE_D: "FCMP.SUNE.D",
+ FCMP_SUNE_S: "FCMP.SUNE.S",
+ FCMP_SUN_D: "FCMP.SUN.D",
+ FCMP_SUN_S: "FCMP.SUN.S",
+ FCOPYSIGN_D: "FCOPYSIGN.D",
+ FCOPYSIGN_S: "FCOPYSIGN.S",
+ FCVT_D_S: "FCVT.D.S",
+ FCVT_S_D: "FCVT.S.D",
+ FDIV_D: "FDIV.D",
+ FDIV_S: "FDIV.S",
+ FFINT_D_L: "FFINT.D.L",
+ FFINT_D_W: "FFINT.D.W",
+ FFINT_S_L: "FFINT.S.L",
+ FFINT_S_W: "FFINT.S.W",
+ FLDGT_D: "FLDGT.D",
+ FLDGT_S: "FLDGT.S",
+ FLDLE_D: "FLDLE.D",
+ FLDLE_S: "FLDLE.S",
+ FLDX_D: "FLDX.D",
+ FLDX_S: "FLDX.S",
+ FLD_D: "FLD.D",
+ FLD_S: "FLD.S",
+ FLOGB_D: "FLOGB.D",
+ FLOGB_S: "FLOGB.S",
+ FMADD_D: "FMADD.D",
+ FMADD_S: "FMADD.S",
+ FMAXA_D: "FMAXA.D",
+ FMAXA_S: "FMAXA.S",
+ FMAX_D: "FMAX.D",
+ FMAX_S: "FMAX.S",
+ FMINA_D: "FMINA.D",
+ FMINA_S: "FMINA.S",
+ FMIN_D: "FMIN.D",
+ FMIN_S: "FMIN.S",
+ FMOV_D: "FMOV.D",
+ FMOV_S: "FMOV.S",
+ FMSUB_D: "FMSUB.D",
+ FMSUB_S: "FMSUB.S",
+ FMUL_D: "FMUL.D",
+ FMUL_S: "FMUL.S",
+ FNEG_D: "FNEG.D",
+ FNEG_S: "FNEG.S",
+ FNMADD_D: "FNMADD.D",
+ FNMADD_S: "FNMADD.S",
+ FNMSUB_D: "FNMSUB.D",
+ FNMSUB_S: "FNMSUB.S",
+ FRECIP_D: "FRECIP.D",
+ FRECIP_S: "FRECIP.S",
+ FRINT_D: "FRINT.D",
+ FRINT_S: "FRINT.S",
+ FRSQRT_D: "FRSQRT.D",
+ FRSQRT_S: "FRSQRT.S",
+ FSCALEB_D: "FSCALEB.D",
+ FSCALEB_S: "FSCALEB.S",
+ FSEL: "FSEL",
+ FSQRT_D: "FSQRT.D",
+ FSQRT_S: "FSQRT.S",
+ FSTGT_D: "FSTGT.D",
+ FSTGT_S: "FSTGT.S",
+ FSTLE_D: "FSTLE.D",
+ FSTLE_S: "FSTLE.S",
+ FSTX_D: "FSTX.D",
+ FSTX_S: "FSTX.S",
+ FST_D: "FST.D",
+ FST_S: "FST.S",
+ FSUB_D: "FSUB.D",
+ FSUB_S: "FSUB.S",
+ FTINTRM_L_D: "FTINTRM.L.D",
+ FTINTRM_L_S: "FTINTRM.L.S",
+ FTINTRM_W_D: "FTINTRM.W.D",
+ FTINTRM_W_S: "FTINTRM.W.S",
+ FTINTRNE_L_D: "FTINTRNE.L.D",
+ FTINTRNE_L_S: "FTINTRNE.L.S",
+ FTINTRNE_W_D: "FTINTRNE.W.D",
+ FTINTRNE_W_S: "FTINTRNE.W.S",
+ FTINTRP_L_D: "FTINTRP.L.D",
+ FTINTRP_L_S: "FTINTRP.L.S",
+ FTINTRP_W_D: "FTINTRP.W.D",
+ FTINTRP_W_S: "FTINTRP.W.S",
+ FTINTRZ_L_D: "FTINTRZ.L.D",
+ FTINTRZ_L_S: "FTINTRZ.L.S",
+ FTINTRZ_W_D: "FTINTRZ.W.D",
+ FTINTRZ_W_S: "FTINTRZ.W.S",
+ FTINT_L_D: "FTINT.L.D",
+ FTINT_L_S: "FTINT.L.S",
+ FTINT_W_D: "FTINT.W.D",
+ FTINT_W_S: "FTINT.W.S",
+ IBAR: "IBAR",
+ JIRL: "JIRL",
+ LDGT_B: "LDGT.B",
+ LDGT_D: "LDGT.D",
+ LDGT_H: "LDGT.H",
+ LDGT_W: "LDGT.W",
+ LDLE_B: "LDLE.B",
+ LDLE_D: "LDLE.D",
+ LDLE_H: "LDLE.H",
+ LDLE_W: "LDLE.W",
+ LDPTR_D: "LDPTR.D",
+ LDPTR_W: "LDPTR.W",
+ LDX_B: "LDX.B",
+ LDX_BU: "LDX.BU",
+ LDX_D: "LDX.D",
+ LDX_H: "LDX.H",
+ LDX_HU: "LDX.HU",
+ LDX_W: "LDX.W",
+ LDX_WU: "LDX.WU",
+ LD_B: "LD.B",
+ LD_BU: "LD.BU",
+ LD_D: "LD.D",
+ LD_H: "LD.H",
+ LD_HU: "LD.HU",
+ LD_W: "LD.W",
+ LD_WU: "LD.WU",
+ LL_D: "LL.D",
+ LL_W: "LL.W",
+ LU12I_W: "LU12I.W",
+ LU32I_D: "LU32I.D",
+ LU52I_D: "LU52I.D",
+ MASKEQZ: "MASKEQZ",
+ MASKNEZ: "MASKNEZ",
+ MOD_D: "MOD.D",
+ MOD_DU: "MOD.DU",
+ MOD_W: "MOD.W",
+ MOD_WU: "MOD.WU",
+ MOVCF2FR: "MOVCF2FR",
+ MOVCF2GR: "MOVCF2GR",
+ MOVFCSR2GR: "MOVFCSR2GR",
+ MOVFR2CF: "MOVFR2CF",
+ MOVFR2GR_D: "MOVFR2GR.D",
+ MOVFR2GR_S: "MOVFR2GR.S",
+ MOVFRH2GR_S: "MOVFRH2GR.S",
+ MOVGR2CF: "MOVGR2CF",
+ MOVGR2FCSR: "MOVGR2FCSR",
+ MOVGR2FRH_W: "MOVGR2FRH.W",
+ MOVGR2FR_D: "MOVGR2FR.D",
+ MOVGR2FR_W: "MOVGR2FR.W",
+ MULH_D: "MULH.D",
+ MULH_DU: "MULH.DU",
+ MULH_W: "MULH.W",
+ MULH_WU: "MULH.WU",
+ MULW_D_W: "MULW.D.W",
+ MULW_D_WU: "MULW.D.WU",
+ MUL_D: "MUL.D",
+ MUL_W: "MUL.W",
+ NOR: "NOR",
+ OR: "OR",
+ ORI: "ORI",
+ ORN: "ORN",
+ PCADDI: "PCADDI",
+ PCADDU12I: "PCADDU12I",
+ PCADDU18I: "PCADDU18I",
+ PCALAU12I: "PCALAU12I",
+ PRELD: "PRELD",
+ PRELDX: "PRELDX",
+ RDTIMEH_W: "RDTIMEH.W",
+ RDTIMEL_W: "RDTIMEL.W",
+ RDTIME_D: "RDTIME.D",
+ REVB_2H: "REVB.2H",
+ REVB_2W: "REVB.2W",
+ REVB_4H: "REVB.4H",
+ REVB_D: "REVB.D",
+ REVH_2W: "REVH.2W",
+ REVH_D: "REVH.D",
+ ROTRI_D: "ROTRI.D",
+ ROTRI_W: "ROTRI.W",
+ ROTR_D: "ROTR.D",
+ ROTR_W: "ROTR.W",
+ SC_D: "SC.D",
+ SC_W: "SC.W",
+ SLLI_D: "SLLI.D",
+ SLLI_W: "SLLI.W",
+ SLL_D: "SLL.D",
+ SLL_W: "SLL.W",
+ SLT: "SLT",
+ SLTI: "SLTI",
+ SLTU: "SLTU",
+ SLTUI: "SLTUI",
+ SRAI_D: "SRAI.D",
+ SRAI_W: "SRAI.W",
+ SRA_D: "SRA.D",
+ SRA_W: "SRA.W",
+ SRLI_D: "SRLI.D",
+ SRLI_W: "SRLI.W",
+ SRL_D: "SRL.D",
+ SRL_W: "SRL.W",
+ STGT_B: "STGT.B",
+ STGT_D: "STGT.D",
+ STGT_H: "STGT.H",
+ STGT_W: "STGT.W",
+ STLE_B: "STLE.B",
+ STLE_D: "STLE.D",
+ STLE_H: "STLE.H",
+ STLE_W: "STLE.W",
+ STPTR_D: "STPTR.D",
+ STPTR_W: "STPTR.W",
+ STX_B: "STX.B",
+ STX_D: "STX.D",
+ STX_H: "STX.H",
+ STX_W: "STX.W",
+ ST_B: "ST.B",
+ ST_D: "ST.D",
+ ST_H: "ST.H",
+ ST_W: "ST.W",
+ SUB_D: "SUB.D",
+ SUB_W: "SUB.W",
+ SYSCALL: "SYSCALL",
+ XOR: "XOR",
+ XORI: "XORI",
+}
+
+var instFormats = [...]instFormat{
+ // ADD.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x108000, op: ADD_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // ADD.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x100000, op: ADD_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // ADDI.D rd, rj, si12
+ {mask: 0xffc00000, value: 0x2c00000, op: ADDI_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // ADDI.W rd, rj, si12
+ {mask: 0xffc00000, value: 0x2800000, op: ADDI_W, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // ADDU16I.D rd, rj, si16
+ {mask: 0xfc000000, value: 0x10000000, op: ADDU16I_D, args: instArgs{arg_rd, arg_rj, arg_si16_25_10}},
+ // ALSL.D rd, rj, rk, sa2
+ {mask: 0xfffe0000, value: 0x2c0000, op: ALSL_D, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}},
+ // ALSL.W rd, rj, rk, sa2
+ {mask: 0xfffe0000, value: 0x40000, op: ALSL_W, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}},
+ // ALSL.WU rd, rj, rk, sa2
+ {mask: 0xfffe0000, value: 0x60000, op: ALSL_WU, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}},
+ // AMADD.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x38618000, op: AMADD_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMADD.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x38610000, op: AMADD_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMADD_DB.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x386a8000, op: AMADD_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMADD_DB.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x386a0000, op: AMADD_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMAND.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x38628000, op: AMAND_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMAND.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x38620000, op: AMAND_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMAND_DB.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x386b8000, op: AMAND_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMAND_DB.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x386b0000, op: AMAND_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMAX.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x38658000, op: AMMAX_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMAX.DU rd, rk, rj
+ {mask: 0xffff8000, value: 0x38678000, op: AMMAX_DU, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMAX.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x38650000, op: AMMAX_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMAX.WU rd, rk, rj
+ {mask: 0xffff8000, value: 0x38670000, op: AMMAX_WU, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMAX_DB.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x386e8000, op: AMMAX_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMAX_DB.DU rd, rk, rj
+ {mask: 0xffff8000, value: 0x38708000, op: AMMAX_DB_DU, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMAX_DB.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x386e0000, op: AMMAX_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMAX_DB.WU rd, rk, rj
+ {mask: 0xffff8000, value: 0x38700000, op: AMMAX_DB_WU, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMIN.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x38668000, op: AMMIN_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMIN.DU rd, rk, rj
+ {mask: 0xffff8000, value: 0x38688000, op: AMMIN_DU, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMIN.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x38660000, op: AMMIN_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMIN.WU rd, rk, rj
+ {mask: 0xffff8000, value: 0x38680000, op: AMMIN_WU, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMIN_DB.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x386f8000, op: AMMIN_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMIN_DB.DU rd, rk, rj
+ {mask: 0xffff8000, value: 0x38718000, op: AMMIN_DB_DU, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMIN_DB.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x386f0000, op: AMMIN_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMMIN_DB.WU rd, rk, rj
+ {mask: 0xffff8000, value: 0x38710000, op: AMMIN_DB_WU, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMOR.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x38638000, op: AMOR_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMOR.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x38630000, op: AMOR_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMOR_DB.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x386c8000, op: AMOR_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMOR_DB.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x386c0000, op: AMOR_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMSWAP.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x38608000, op: AMSWAP_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMSWAP.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x38600000, op: AMSWAP_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMSWAP_DB.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x38698000, op: AMSWAP_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMSWAP_DB.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x38690000, op: AMSWAP_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMXOR.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x38648000, op: AMXOR_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMXOR.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x38640000, op: AMXOR_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMXOR_DB.D rd, rk, rj
+ {mask: 0xffff8000, value: 0x386d8000, op: AMXOR_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AMXOR_DB.W rd, rk, rj
+ {mask: 0xffff8000, value: 0x386d0000, op: AMXOR_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+ // AND rd, rj, rk
+ {mask: 0xffff8000, value: 0x148000, op: AND, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // ANDI rd, rj, ui12
+ {mask: 0xffc00000, value: 0x3400000, op: ANDI, args: instArgs{arg_rd, arg_rj, arg_ui12_21_10}},
+ // ANDN rd, rj, rk
+ {mask: 0xffff8000, value: 0x168000, op: ANDN, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // ASRTGT.D rj, rk
+ {mask: 0xffff801f, value: 0x18000, op: ASRTGT_D, args: instArgs{arg_rj, arg_rk}},
+ // ASRTLE.D rj, rk
+ {mask: 0xffff801f, value: 0x10000, op: ASRTLE_D, args: instArgs{arg_rj, arg_rk}},
+ // B offs
+ {mask: 0xfc000000, value: 0x50000000, op: B, args: instArgs{arg_offset_25_0}},
+ // BCEQZ cj, offs
+ {mask: 0xfc000300, value: 0x48000000, op: BCEQZ, args: instArgs{arg_cj, arg_offset_20_0}},
+ // BCNEZ cj, offs
+ {mask: 0xfc000300, value: 0x48000100, op: BCNEZ, args: instArgs{arg_cj, arg_offset_20_0}},
+ // BEQ rj, rd, offs
+ {mask: 0xfc000000, value: 0x58000000, op: BEQ, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}},
+ // BEQZ rj, offs
+ {mask: 0xfc000000, value: 0x40000000, op: BEQZ, args: instArgs{arg_rj, arg_offset_20_0}},
+ // BGE rj, rd, offs
+ {mask: 0xfc000000, value: 0x64000000, op: BGE, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}},
+ // BGEU rj, rd, offs
+ {mask: 0xfc000000, value: 0x6c000000, op: BGEU, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}},
+ // BITREV.4B rd, rj
+ {mask: 0xfffffc00, value: 0x4800, op: BITREV_4B, args: instArgs{arg_rd, arg_rj}},
+ // BITREV.8B rd, rj
+ {mask: 0xfffffc00, value: 0x4c00, op: BITREV_8B, args: instArgs{arg_rd, arg_rj}},
+ // BITREV.D rd, rj
+ {mask: 0xfffffc00, value: 0x5400, op: BITREV_D, args: instArgs{arg_rd, arg_rj}},
+ // BITREV.W rd, rj
+ {mask: 0xfffffc00, value: 0x5000, op: BITREV_W, args: instArgs{arg_rd, arg_rj}},
+ // BL offs
+ {mask: 0xfc000000, value: 0x54000000, op: BL, args: instArgs{arg_offset_25_0}},
+ // BLT rj, rd, offs
+ {mask: 0xfc000000, value: 0x60000000, op: BLT, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}},
+ // BLTU rj, rd, offs
+ {mask: 0xfc000000, value: 0x68000000, op: BLTU, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}},
+ // BNE rj, rd, offs
+ {mask: 0xfc000000, value: 0x5c000000, op: BNE, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}},
+ // BNEZ rj, offs
+ {mask: 0xfc000000, value: 0x44000000, op: BNEZ, args: instArgs{arg_rj, arg_offset_20_0}},
+ // BREAK code
+ {mask: 0xffff8000, value: 0x2a0000, op: BREAK, args: instArgs{arg_code_14_0}},
+ // BSTRINS.D rd, rj, msbd, lsbd
+ {mask: 0xffc00000, value: 0x800000, op: BSTRINS_D, args: instArgs{arg_rd, arg_rj, arg_bstrpick_msbd, arg_bstrins_lsbd}},
+ // BSTRINS.W rd, rj, msbw, lsbw
+ {mask: 0xffe08000, value: 0x600000, op: BSTRINS_W, args: instArgs{arg_rd, arg_rj, arg_bstrpick_msbw, arg_bstrins_lsbw}},
+ // BSTRPICK.D rd, rj, msbd, lsbd
+ {mask: 0xffc00000, value: 0xc00000, op: BSTRPICK_D, args: instArgs{arg_rd, arg_rj, arg_bstrpick_msbd, arg_bstrins_lsbd}},
+ // BSTRPICK.W rd, rj, msbw, lsbw
+ {mask: 0xffe08000, value: 0x608000, op: BSTRPICK_W, args: instArgs{arg_rd, arg_rj, arg_bstrpick_msbw, arg_bstrins_lsbw}},
+ // BYTEPICK.D rd, rj, rk, sa3
+ {mask: 0xfffc0000, value: 0xc0000, op: BYTEPICK_D, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa3_17_15}},
+ // BYTEPICK.W arg_rd, arg_rj, arg_rk, arg_sa2_16_15_bytepickw
+ {mask: 0xfffe0000, value: 0x80000, op: BYTEPICK_W, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15_bytepickw}},
+ // CLO.D rd, rj
+ {mask: 0xfffffc00, value: 0x2000, op: CLO_D, args: instArgs{arg_rd, arg_rj}},
+ // CLO.W rd, rj
+ {mask: 0xfffffc00, value: 0x1000, op: CLO_W, args: instArgs{arg_rd, arg_rj}},
+ // CLZ.D rd, rj
+ {mask: 0xfffffc00, value: 0x2400, op: CLZ_D, args: instArgs{arg_rd, arg_rj}},
+ // CLZ.W rd, rj
+ {mask: 0xfffffc00, value: 0x1400, op: CLZ_W, args: instArgs{arg_rd, arg_rj}},
+ // CPUCFG rd, rj
+ {mask: 0xfffffc00, value: 0x6c00, op: CPUCFG, args: instArgs{arg_rd, arg_rj}},
+ // CRC.W.B.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x240000, op: CRC_W_B_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // CRC.W.D.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x258000, op: CRC_W_D_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // CRC.W.H.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x248000, op: CRC_W_H_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // CRC.W.W.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x250000, op: CRC_W_W_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // CRCC.W.B.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x260000, op: CRCC_W_B_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // CRCC.W.D.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x278000, op: CRCC_W_D_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // CRCC.W.H.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x268000, op: CRCC_W_H_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // CRCC.W.W.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x270000, op: CRCC_W_W_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // CTO.D rd, rj
+ {mask: 0xfffffc00, value: 0x2800, op: CTO_D, args: instArgs{arg_rd, arg_rj}},
+ // CTO.W rd, rj
+ {mask: 0xfffffc00, value: 0x1800, op: CTO_W, args: instArgs{arg_rd, arg_rj}},
+ // CTZ.D rd, rj
+ {mask: 0xfffffc00, value: 0x2c00, op: CTZ_D, args: instArgs{arg_rd, arg_rj}},
+ // CTZ.W rd, rj
+ {mask: 0xfffffc00, value: 0x1c00, op: CTZ_W, args: instArgs{arg_rd, arg_rj}},
+ // DBAR hint
+ {mask: 0xffff8000, value: 0x38720000, op: DBAR, args: instArgs{arg_hint_14_0}},
+ // DIV.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x220000, op: DIV_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // DIV.DU rd, rj, rk
+ {mask: 0xffff8000, value: 0x230000, op: DIV_DU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // DIV.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x200000, op: DIV_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // DIV.WU rd, rj, rk
+ {mask: 0xffff8000, value: 0x210000, op: DIV_WU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // EXT.W.B rd, rj
+ {mask: 0xfffffc00, value: 0x5c00, op: EXT_W_B, args: instArgs{arg_rd, arg_rj}},
+ // EXT.W.H rd, rj
+ {mask: 0xfffffc00, value: 0x5800, op: EXT_W_H, args: instArgs{arg_rd, arg_rj}},
+ // FABS.D fd, fj
+ {mask: 0xfffffc00, value: 0x1140800, op: FABS_D, args: instArgs{arg_fd, arg_fj}},
+ // FABS.S fd, fj
+ {mask: 0xfffffc00, value: 0x1140400, op: FABS_S, args: instArgs{arg_fd, arg_fj}},
+ // FADD.D fd, fj, fk
+ {mask: 0xffff8000, value: 0x1010000, op: FADD_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FADD.S fd, fj, fk
+ {mask: 0xffff8000, value: 0x1008000, op: FADD_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FCLASS.D fd, fj
+ {mask: 0xfffffc00, value: 0x1143800, op: FCLASS_D, args: instArgs{arg_fd, arg_fj}},
+ // FCLASS.S fd, fj
+ {mask: 0xfffffc00, value: 0x1143400, op: FCLASS_S, args: instArgs{arg_fd, arg_fj}},
+ // FCMP.CAF.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc200000, op: FCMP_CAF_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CAF.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc100000, op: FCMP_CAF_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CEQ.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc220000, op: FCMP_CEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CEQ.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc120000, op: FCMP_CEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CLE.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc230000, op: FCMP_CLE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CLE.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc130000, op: FCMP_CLE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CLT.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc210000, op: FCMP_CLT_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CLT.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc110000, op: FCMP_CLT_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CNE.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc280000, op: FCMP_CNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CNE.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc180000, op: FCMP_CNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.COR.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc2a0000, op: FCMP_COR_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.COR.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc1a0000, op: FCMP_COR_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CUEQ.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc260000, op: FCMP_CUEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CUEQ.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc160000, op: FCMP_CUEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CULE.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc270000, op: FCMP_CULE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CULE.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc170000, op: FCMP_CULE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CULT.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc250000, op: FCMP_CULT_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CULT.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc150000, op: FCMP_CULT_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CUN.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc240000, op: FCMP_CUN_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CUN.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc140000, op: FCMP_CUN_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CUNE.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc2c0000, op: FCMP_CUNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.CUNE.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc1c0000, op: FCMP_CUNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SAF.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc208000, op: FCMP_SAF_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SAF.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc108000, op: FCMP_SAF_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SEQ.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc228000, op: FCMP_SEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SEQ.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc128000, op: FCMP_SEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SLE.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc238000, op: FCMP_SLE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SLE.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc138000, op: FCMP_SLE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SLT.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc218000, op: FCMP_SLT_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SLT.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc118000, op: FCMP_SLT_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SNE.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc288000, op: FCMP_SNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SNE.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc188000, op: FCMP_SNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SOR.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc2a8000, op: FCMP_SOR_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SOR.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc1a8000, op: FCMP_SOR_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SUEQ.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc268000, op: FCMP_SUEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SUEQ.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc168000, op: FCMP_SUEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SULE.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc278000, op: FCMP_SULE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SULE.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc178000, op: FCMP_SULE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SULT.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc258000, op: FCMP_SULT_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SULT.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc158000, op: FCMP_SULT_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SUN.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc248000, op: FCMP_SUN_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SUN.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc148000, op: FCMP_SUN_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SUNE.D cd, fj, fk
+ {mask: 0xffff8018, value: 0xc2c8000, op: FCMP_SUNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCMP.SUNE.S cd, fj, fk
+ {mask: 0xffff8018, value: 0xc1c8000, op: FCMP_SUNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+ // FCOPYSIGN.D fd, fj, fk
+ {mask: 0xffff8000, value: 0x1130000, op: FCOPYSIGN_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FCOPYSIGN.S fd, fj, fk
+ {mask: 0xffff8000, value: 0x1128000, op: FCOPYSIGN_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FCVT.D.S fd, fj
+ {mask: 0xfffffc00, value: 0x1192400, op: FCVT_D_S, args: instArgs{arg_fd, arg_fj}},
+ // FCVT.S.D fd, fj
+ {mask: 0xfffffc00, value: 0x1191800, op: FCVT_S_D, args: instArgs{arg_fd, arg_fj}},
+ // FDIV.D fd, fj, fk
+ {mask: 0xffff8000, value: 0x1070000, op: FDIV_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FDIV.S fd, fj, fk
+ {mask: 0xffff8000, value: 0x1068000, op: FDIV_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FFINT.D.L fd, fj
+ {mask: 0xfffffc00, value: 0x11d2800, op: FFINT_D_L, args: instArgs{arg_fd, arg_fj}},
+ // FFINT.D.W fd, fj
+ {mask: 0xfffffc00, value: 0x11d2000, op: FFINT_D_W, args: instArgs{arg_fd, arg_fj}},
+ // FFINT.S.L fd, fj
+ {mask: 0xfffffc00, value: 0x11d1800, op: FFINT_S_L, args: instArgs{arg_fd, arg_fj}},
+ // FFINT.S.W fd, fj
+ {mask: 0xfffffc00, value: 0x11d1000, op: FFINT_S_W, args: instArgs{arg_fd, arg_fj}},
+ // FLD.D fd, rj, si12
+ {mask: 0xffc00000, value: 0x2b800000, op: FLD_D, args: instArgs{arg_fd, arg_rj, arg_si12_21_10}},
+ // FLD.S fd, rj, si12
+ {mask: 0xffc00000, value: 0x2b000000, op: FLD_S, args: instArgs{arg_fd, arg_rj, arg_si12_21_10}},
+ // FLDGT.D fd, rj, rk
+ {mask: 0xffff8000, value: 0x38748000, op: FLDGT_D, args: instArgs{arg_fd, arg_rj, arg_rk}},
+ // FLDGT.S fd, rj, rk
+ {mask: 0xffff8000, value: 0x38740000, op: FLDGT_S, args: instArgs{arg_fd, arg_rj, arg_rk}},
+ // FLDLE.D fd, rj, rk
+ {mask: 0xffff8000, value: 0x38758000, op: FLDLE_D, args: instArgs{arg_fd, arg_rj, arg_rk}},
+ // FLDLE.S fd, rj, rk
+ {mask: 0xffff8000, value: 0x38750000, op: FLDLE_S, args: instArgs{arg_fd, arg_rj, arg_rk}},
+ // FLDX.D fd, rj, rk
+ {mask: 0xffff8000, value: 0x38340000, op: FLDX_D, args: instArgs{arg_fd, arg_rj, arg_rk}},
+ // FLDX.S fd, rj, rk
+ {mask: 0xffff8000, value: 0x38300000, op: FLDX_S, args: instArgs{arg_fd, arg_rj, arg_rk}},
+ // FLOGB.D fd, fj
+ {mask: 0xfffffc00, value: 0x1142800, op: FLOGB_D, args: instArgs{arg_fd, arg_fj}},
+ // FLOGB.S fd, fj
+ {mask: 0xfffffc00, value: 0x1142400, op: FLOGB_S, args: instArgs{arg_fd, arg_fj}},
+ // FMADD.D fd, fj, fk, fa
+ {mask: 0xfff00000, value: 0x8200000, op: FMADD_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+ // FMADD.S fd, fj, fk, fa
+ {mask: 0xfff00000, value: 0x8100000, op: FMADD_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+ // FMAX.D fd, fj, fk
+ {mask: 0xffff8000, value: 0x1090000, op: FMAX_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FMAX.S fd, fj, fk
+ {mask: 0xffff8000, value: 0x1088000, op: FMAX_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FMAXA.D fd, fj, fk
+ {mask: 0xffff8000, value: 0x10d0000, op: FMAXA_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FMAXA.S fd, fj, fk
+ {mask: 0xffff8000, value: 0x10c8000, op: FMAXA_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FMIN.D fd, fj, fk
+ {mask: 0xffff8000, value: 0x10b0000, op: FMIN_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FMIN.S fd, fj, fk
+ {mask: 0xffff8000, value: 0x10a8000, op: FMIN_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FMINA.D fd, fj, fk
+ {mask: 0xffff8000, value: 0x10f0000, op: FMINA_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FMINA.S fd, fj, fk
+ {mask: 0xffff8000, value: 0x10e8000, op: FMINA_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FMOV.D fd, fj
+ {mask: 0xfffffc00, value: 0x1149800, op: FMOV_D, args: instArgs{arg_fd, arg_fj}},
+ // FMOV.S fd, fj
+ {mask: 0xfffffc00, value: 0x1149400, op: FMOV_S, args: instArgs{arg_fd, arg_fj}},
+ // FMSUB.D fd, fj, fk, fa
+ {mask: 0xfff00000, value: 0x8600000, op: FMSUB_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+ // FMSUB.S fd, fj, fk, fa
+ {mask: 0xfff00000, value: 0x8500000, op: FMSUB_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+ // FMUL.D fd, fj, fk
+ {mask: 0xffff8000, value: 0x1050000, op: FMUL_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FMUL.S fd, fj, fk
+ {mask: 0xffff8000, value: 0x1048000, op: FMUL_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FNEG.D fd, fj
+ {mask: 0xfffffc00, value: 0x1141800, op: FNEG_D, args: instArgs{arg_fd, arg_fj}},
+ // FNEG.S fd, fj
+ {mask: 0xfffffc00, value: 0x1141400, op: FNEG_S, args: instArgs{arg_fd, arg_fj}},
+ // FNMADD.D fd, fj, fk, fa
+ {mask: 0xfff00000, value: 0x8a00000, op: FNMADD_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+ // FNMADD.S fd, fj, fk, fa
+ {mask: 0xfff00000, value: 0x8900000, op: FNMADD_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+ // FNMSUB.D fd, fj, fk, fa
+ {mask: 0xfff00000, value: 0x8e00000, op: FNMSUB_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+ // FNMSUB.S fd, fj, fk, fa
+ {mask: 0xfff00000, value: 0x8d00000, op: FNMSUB_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+ // FRECIP.D fd, fj
+ {mask: 0xfffffc00, value: 0x1145800, op: FRECIP_D, args: instArgs{arg_fd, arg_fj}},
+ // FRECIP.S fd, fj
+ {mask: 0xfffffc00, value: 0x1145400, op: FRECIP_S, args: instArgs{arg_fd, arg_fj}},
+ // FRINT.D fd, fj
+ {mask: 0xfffffc00, value: 0x11e4800, op: FRINT_D, args: instArgs{arg_fd, arg_fj}},
+ // FRINT.S fd, fj
+ {mask: 0xfffffc00, value: 0x11e4400, op: FRINT_S, args: instArgs{arg_fd, arg_fj}},
+ // FRSQRT.D fd, fj
+ {mask: 0xfffffc00, value: 0x1146800, op: FRSQRT_D, args: instArgs{arg_fd, arg_fj}},
+ // FRSQRT.S fd, fj
+ {mask: 0xfffffc00, value: 0x1146400, op: FRSQRT_S, args: instArgs{arg_fd, arg_fj}},
+ // FSCALEB.D fd, fj, fk
+ {mask: 0xffff8000, value: 0x1110000, op: FSCALEB_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FSCALEB.S fd, fj, fk
+ {mask: 0xffff8000, value: 0x1108000, op: FSCALEB_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FSEL fd, fj, fk, ca
+ {mask: 0xfffc0000, value: 0xd000000, op: FSEL, args: instArgs{arg_fd, arg_fj, arg_fk, arg_ca}},
+ // FSQRT.D fd, fj
+ {mask: 0xfffffc00, value: 0x1144800, op: FSQRT_D, args: instArgs{arg_fd, arg_fj}},
+ // FSQRT.S fd, fj
+ {mask: 0xfffffc00, value: 0x1144400, op: FSQRT_S, args: instArgs{arg_fd, arg_fj}},
+ // FST.D fd, rj, si12
+ {mask: 0xffc00000, value: 0x2bc00000, op: FST_D, args: instArgs{arg_fd, arg_rj, arg_si12_21_10}},
+ // FST.S fd, rj, si12
+ {mask: 0xffc00000, value: 0x2b400000, op: FST_S, args: instArgs{arg_fd, arg_rj, arg_si12_21_10}},
+ // FSTGT.D fd, rj, rk
+ {mask: 0xffff8000, value: 0x38768000, op: FSTGT_D, args: instArgs{arg_fd, arg_rj, arg_rk}},
+ // FSTGT.S fd, rj, rk
+ {mask: 0xffff8000, value: 0x38760000, op: FSTGT_S, args: instArgs{arg_fd, arg_rj, arg_rk}},
+ // FSTLE.D fd, rj, rk
+ {mask: 0xffff8000, value: 0x38778000, op: FSTLE_D, args: instArgs{arg_fd, arg_rj, arg_rk}},
+ // FSTLE.S fd, rj, rk
+ {mask: 0xffff8000, value: 0x38770000, op: FSTLE_S, args: instArgs{arg_fd, arg_rj, arg_rk}},
+ // FSTX.D fd, rj, rk
+ {mask: 0xffff8000, value: 0x383c0000, op: FSTX_D, args: instArgs{arg_fd, arg_rj, arg_rk}},
+ // FSTX.S fd, rj, rk
+ {mask: 0xffff8000, value: 0x38380000, op: FSTX_S, args: instArgs{arg_fd, arg_rj, arg_rk}},
+ // FSUB.D fd, fj, fk
+ {mask: 0xffff8000, value: 0x1030000, op: FSUB_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FSUB.S fd, fj, fk
+ {mask: 0xffff8000, value: 0x1028000, op: FSUB_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+ // FTINT.L.D fd, fj
+ {mask: 0xfffffc00, value: 0x11b2800, op: FTINT_L_D, args: instArgs{arg_fd, arg_fj}},
+ // FTINT.L.S fd, fj
+ {mask: 0xfffffc00, value: 0x11b2400, op: FTINT_L_S, args: instArgs{arg_fd, arg_fj}},
+ // FTINT.W.D fd, fj
+ {mask: 0xfffffc00, value: 0x11b0800, op: FTINT_W_D, args: instArgs{arg_fd, arg_fj}},
+ // FTINT.W.S fd, fj
+ {mask: 0xfffffc00, value: 0x11b0400, op: FTINT_W_S, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRM.L.D fd, fj
+ {mask: 0xfffffc00, value: 0x11a2800, op: FTINTRM_L_D, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRM.L.S fd, fj
+ {mask: 0xfffffc00, value: 0x11a2400, op: FTINTRM_L_S, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRM.W.D fd, fj
+ {mask: 0xfffffc00, value: 0x11a0800, op: FTINTRM_W_D, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRM.W.S fd, fj
+ {mask: 0xfffffc00, value: 0x11a0400, op: FTINTRM_W_S, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRNE.L.D fd, fj
+ {mask: 0xfffffc00, value: 0x11ae800, op: FTINTRNE_L_D, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRNE.L.S fd, fj
+ {mask: 0xfffffc00, value: 0x11ae400, op: FTINTRNE_L_S, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRNE.W.D fd, fj
+ {mask: 0xfffffc00, value: 0x11ac800, op: FTINTRNE_W_D, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRNE.W.S fd, fj
+ {mask: 0xfffffc00, value: 0x11ac400, op: FTINTRNE_W_S, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRP.L.D fd, fj
+ {mask: 0xfffffc00, value: 0x11a6800, op: FTINTRP_L_D, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRP.L.S fd, fj
+ {mask: 0xfffffc00, value: 0x11a6400, op: FTINTRP_L_S, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRP.W.D fd, fj
+ {mask: 0xfffffc00, value: 0x11a4800, op: FTINTRP_W_D, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRP.W.S fd, fj
+ {mask: 0xfffffc00, value: 0x11a4400, op: FTINTRP_W_S, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRZ.L.D fd, fj
+ {mask: 0xfffffc00, value: 0x11aa800, op: FTINTRZ_L_D, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRZ.L.S fd, fj
+ {mask: 0xfffffc00, value: 0x11aa400, op: FTINTRZ_L_S, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRZ.W.D fd, fj
+ {mask: 0xfffffc00, value: 0x11a8800, op: FTINTRZ_W_D, args: instArgs{arg_fd, arg_fj}},
+ // FTINTRZ.W.S fd, fj
+ {mask: 0xfffffc00, value: 0x11a8400, op: FTINTRZ_W_S, args: instArgs{arg_fd, arg_fj}},
+ // IBAR hint
+ {mask: 0xffff8000, value: 0x38728000, op: IBAR, args: instArgs{arg_hint_14_0}},
+ // JIRL rd, rj, offs
+ {mask: 0xfc000000, value: 0x4c000000, op: JIRL, args: instArgs{arg_rd, arg_rj, arg_offset_15_0}},
+ // LD.B rd, rj, si12
+ {mask: 0xffc00000, value: 0x28000000, op: LD_B, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // LD.BU rd, rj, si12
+ {mask: 0xffc00000, value: 0x2a000000, op: LD_BU, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // LD.D rd, rj, si12
+ {mask: 0xffc00000, value: 0x28c00000, op: LD_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // LD.H rd, rj, si12
+ {mask: 0xffc00000, value: 0x28400000, op: LD_H, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // LD.HU rd, rj, si12
+ {mask: 0xffc00000, value: 0x2a400000, op: LD_HU, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // LD.W rd, rj, si12
+ {mask: 0xffc00000, value: 0x28800000, op: LD_W, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // LD.WU rd, rj, si12
+ {mask: 0xffc00000, value: 0x2a800000, op: LD_WU, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // LDGT.B rd, rj, rk
+ {mask: 0xffff8000, value: 0x38780000, op: LDGT_B, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDGT.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x38798000, op: LDGT_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDGT.H rd, rj, rk
+ {mask: 0xffff8000, value: 0x38788000, op: LDGT_H, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDGT.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x38790000, op: LDGT_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDLE.B rd, rj, rk
+ {mask: 0xffff8000, value: 0x387a0000, op: LDLE_B, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDLE.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x387b8000, op: LDLE_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDLE.H rd, rj, rk
+ {mask: 0xffff8000, value: 0x387a8000, op: LDLE_H, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDLE.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x387b0000, op: LDLE_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDPTR.D rd, rj, si14
+ {mask: 0xff000000, value: 0x26000000, op: LDPTR_D, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}},
+ // LDPTR.W rd, rj, si14
+ {mask: 0xff000000, value: 0x24000000, op: LDPTR_W, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}},
+ // LDX.B rd, rj, rk
+ {mask: 0xffff8000, value: 0x38000000, op: LDX_B, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDX.BU rd, rj, rk
+ {mask: 0xffff8000, value: 0x38200000, op: LDX_BU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDX.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x380c0000, op: LDX_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDX.H rd, rj, rk
+ {mask: 0xffff8000, value: 0x38040000, op: LDX_H, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDX.HU rd, rj, rk
+ {mask: 0xffff8000, value: 0x38240000, op: LDX_HU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDX.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x38080000, op: LDX_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LDX.WU rd, rj, rk
+ {mask: 0xffff8000, value: 0x38280000, op: LDX_WU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // LL.D rd, rj, si14
+ {mask: 0xff000000, value: 0x22000000, op: LL_D, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}},
+ // LL.W rd, rj, si14
+ {mask: 0xff000000, value: 0x20000000, op: LL_W, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}},
+ // LU12I.W rd, si20
+ {mask: 0xfe000000, value: 0x14000000, op: LU12I_W, args: instArgs{arg_rd, arg_si20_24_5}},
+ // LU32I.D rd, si20
+ {mask: 0xfe000000, value: 0x16000000, op: LU32I_D, args: instArgs{arg_rd, arg_si20_24_5}},
+ // LU52I.D rd, rj, si12
+ {mask: 0xffc00000, value: 0x3000000, op: LU52I_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // MASKEQZ rd, rj, rk
+ {mask: 0xffff8000, value: 0x130000, op: MASKEQZ, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MASKNEZ rd, rj, rk
+ {mask: 0xffff8000, value: 0x138000, op: MASKNEZ, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MOD.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x228000, op: MOD_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MOD.DU rd, rj, rk
+ {mask: 0xffff8000, value: 0x238000, op: MOD_DU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MOD.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x208000, op: MOD_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MOD.WU rd, rj, rk
+ {mask: 0xffff8000, value: 0x218000, op: MOD_WU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MOVCF2FR fd, cj
+ {mask: 0xffffff00, value: 0x114d400, op: MOVCF2FR, args: instArgs{arg_fd, arg_cj}},
+ // MOVCF2GR rd, cj
+ {mask: 0xffffff00, value: 0x114dc00, op: MOVCF2GR, args: instArgs{arg_rd, arg_cj}},
+ // MOVFCSR2GR rd, fcsr
+ {mask: 0xfffffc00, value: 0x114c800, op: MOVFCSR2GR, args: instArgs{arg_rd, arg_fcsr_9_5}},
+ // MOVFR2CF cd, fj
+ {mask: 0xfffffc18, value: 0x114d000, op: MOVFR2CF, args: instArgs{arg_cd, arg_fj}},
+ // MOVFR2GR.D rd, fj
+ {mask: 0xfffffc00, value: 0x114b800, op: MOVFR2GR_D, args: instArgs{arg_rd, arg_fj}},
+ // MOVFR2GR.S rd, fj
+ {mask: 0xfffffc00, value: 0x114b400, op: MOVFR2GR_S, args: instArgs{arg_rd, arg_fj}},
+ // MOVFRH2GR.S rd, fj
+ {mask: 0xfffffc00, value: 0x114bc00, op: MOVFRH2GR_S, args: instArgs{arg_rd, arg_fj}},
+ // MOVGR2CF cd, rj
+ {mask: 0xfffffc18, value: 0x114d800, op: MOVGR2CF, args: instArgs{arg_cd, arg_rj}},
+ // MOVGR2FCSR fcsr, rj
+ {mask: 0xfffffc00, value: 0x114c000, op: MOVGR2FCSR, args: instArgs{arg_fcsr_4_0, arg_rj}},
+ // MOVGR2FR.D fd, rj
+ {mask: 0xfffffc00, value: 0x114a800, op: MOVGR2FR_D, args: instArgs{arg_fd, arg_rj}},
+ // MOVGR2FR.W fd, rj
+ {mask: 0xfffffc00, value: 0x114a400, op: MOVGR2FR_W, args: instArgs{arg_fd, arg_rj}},
+ // MOVGR2FRH.W fd, rj
+ {mask: 0xfffffc00, value: 0x114ac00, op: MOVGR2FRH_W, args: instArgs{arg_fd, arg_rj}},
+ // MUL.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x1d8000, op: MUL_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MUL.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x1c0000, op: MUL_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MULH.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x1e0000, op: MULH_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MULH.DU rd, rj, rk
+ {mask: 0xffff8000, value: 0x1e8000, op: MULH_DU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MULH.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x1c8000, op: MULH_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MULH.WU rd, rj, rk
+ {mask: 0xffff8000, value: 0x1d0000, op: MULH_WU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MULW.D.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x1f0000, op: MULW_D_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // MULW.D.WU rd, rj, rk
+ {mask: 0xffff8000, value: 0x1f8000, op: MULW_D_WU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // NOR rd, rj, rk
+ {mask: 0xffff8000, value: 0x140000, op: NOR, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // OR rd, rj, rk
+ {mask: 0xffff8000, value: 0x150000, op: OR, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // ORI rd, rj, ui12
+ {mask: 0xffc00000, value: 0x3800000, op: ORI, args: instArgs{arg_rd, arg_rj, arg_ui12_21_10}},
+ // ORN rd, rj, rk
+ {mask: 0xffff8000, value: 0x160000, op: ORN, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // PCADDI rd, si20
+ {mask: 0xfe000000, value: 0x18000000, op: PCADDI, args: instArgs{arg_rd, arg_si20_24_5}},
+ // PCADDU12I rd, si20
+ {mask: 0xfe000000, value: 0x1c000000, op: PCADDU12I, args: instArgs{arg_rd, arg_si20_24_5}},
+ // PCADDU18I rd, si20
+ {mask: 0xfe000000, value: 0x1e000000, op: PCADDU18I, args: instArgs{arg_rd, arg_si20_24_5}},
+ // PCALAU12I rd, si20
+ {mask: 0xfe000000, value: 0x1a000000, op: PCALAU12I, args: instArgs{arg_rd, arg_si20_24_5}},
+ // PRELD hint, rj, si12
+ {mask: 0xffc00000, value: 0x2ac00000, op: PRELD, args: instArgs{arg_preld_hint_4_0, arg_rj, arg_si12_21_10}},
+ // PRELDX hint, rj, rk
+ {mask: 0xffff8000, value: 0x382c0000, op: PRELDX, args: instArgs{arg_preld_hint_4_0, arg_rj, arg_rk}},
+ // RDTIME.D rd, rj
+ {mask: 0xfffffc00, value: 0x6800, op: RDTIME_D, args: instArgs{arg_rd, arg_rj}},
+ // RDTIMEH.W rd, rj
+ {mask: 0xfffffc00, value: 0x6400, op: RDTIMEH_W, args: instArgs{arg_rd, arg_rj}},
+ // RDTIMEL.W rd, rj
+ {mask: 0xfffffc00, value: 0x6000, op: RDTIMEL_W, args: instArgs{arg_rd, arg_rj}},
+ // REVB.2H rd, rj
+ {mask: 0xfffffc00, value: 0x3000, op: REVB_2H, args: instArgs{arg_rd, arg_rj}},
+ // REVB.2W rd, rj
+ {mask: 0xfffffc00, value: 0x3800, op: REVB_2W, args: instArgs{arg_rd, arg_rj}},
+ // REVB.4H rd, rj
+ {mask: 0xfffffc00, value: 0x3400, op: REVB_4H, args: instArgs{arg_rd, arg_rj}},
+ // REVB.D rd, rj
+ {mask: 0xfffffc00, value: 0x3c00, op: REVB_D, args: instArgs{arg_rd, arg_rj}},
+ // REVH.2W rd, rj
+ {mask: 0xfffffc00, value: 0x4000, op: REVH_2W, args: instArgs{arg_rd, arg_rj}},
+ // REVH.D rd, rj
+ {mask: 0xfffffc00, value: 0x4400, op: REVH_D, args: instArgs{arg_rd, arg_rj}},
+ // ROTR.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x1b8000, op: ROTR_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // ROTR.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x1b0000, op: ROTR_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // ROTRI.D rd, rj, ui6
+ {mask: 0xffff0000, value: 0x4d0000, op: ROTRI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}},
+ // ROTRI.W rd, rj, ui5
+ {mask: 0xffff8000, value: 0x4c8000, op: ROTRI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}},
+ // SC.D rd, rj, si14
+ {mask: 0xff000000, value: 0x23000000, op: SC_D, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}},
+ // SC.W rd, rj, si14
+ {mask: 0xff000000, value: 0x21000000, op: SC_W, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}},
+ // SLL.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x188000, op: SLL_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // SLL.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x170000, op: SLL_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // SLLI.D rd, rj, ui6
+ {mask: 0xffff0000, value: 0x410000, op: SLLI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}},
+ // SLLI.W rd, rj, ui5
+ {mask: 0xffff8000, value: 0x408000, op: SLLI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}},
+ // SLT rd, rj, rk
+ {mask: 0xffff8000, value: 0x120000, op: SLT, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // SLTI rd, rj, si12
+ {mask: 0xffc00000, value: 0x2000000, op: SLTI, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // SLTU rd, rj, rk
+ {mask: 0xffff8000, value: 0x128000, op: SLTU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // SLTUI rd, rj, si12
+ {mask: 0xffc00000, value: 0x2400000, op: SLTUI, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // SRA.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x198000, op: SRA_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // SRA.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x180000, op: SRA_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // SRAI.D rd, rj, ui6
+ {mask: 0xffff0000, value: 0x490000, op: SRAI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}},
+ // SRAI.W rd, rj, ui5
+ {mask: 0xffff8000, value: 0x488000, op: SRAI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}},
+ // SRL.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x190000, op: SRL_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // SRL.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x178000, op: SRL_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // SRLI.D rd, rj, ui6
+ {mask: 0xffff0000, value: 0x450000, op: SRLI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}},
+ // SRLI.W rd, rj, ui5
+ {mask: 0xffff8000, value: 0x448000, op: SRLI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}},
+ // ST.B rd, rj, si12
+ {mask: 0xffc00000, value: 0x29000000, op: ST_B, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // ST.D rd, rj, si12
+ {mask: 0xffc00000, value: 0x29c00000, op: ST_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // ST.H rd, rj, si12
+ {mask: 0xffc00000, value: 0x29400000, op: ST_H, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // ST.W rd, rj, si12
+ {mask: 0xffc00000, value: 0x29800000, op: ST_W, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+ // STGT.B rd, rj, rk
+ {mask: 0xffff8000, value: 0x387c0000, op: STGT_B, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // STGT.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x387d8000, op: STGT_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // STGT.H rd, rj, rk
+ {mask: 0xffff8000, value: 0x387c8000, op: STGT_H, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // STGT.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x387d0000, op: STGT_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // STLE.B rd, rj, rk
+ {mask: 0xffff8000, value: 0x387e0000, op: STLE_B, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // STLE.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x387f8000, op: STLE_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // STLE.H rd, rj, rk
+ {mask: 0xffff8000, value: 0x387e8000, op: STLE_H, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // STLE.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x387f0000, op: STLE_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // STPTR.D rd, rj, si14
+ {mask: 0xff000000, value: 0x27000000, op: STPTR_D, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}},
+ // STPTR.W rd, rj, si14
+ {mask: 0xff000000, value: 0x25000000, op: STPTR_W, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}},
+ // STX.B rd, rj, rk
+ {mask: 0xffff8000, value: 0x38100000, op: STX_B, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // STX.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x381c0000, op: STX_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // STX.H rd, rj, rk
+ {mask: 0xffff8000, value: 0x38140000, op: STX_H, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // STX.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x38180000, op: STX_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // SUB.D rd, rj, rk
+ {mask: 0xffff8000, value: 0x118000, op: SUB_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // SUB.W rd, rj, rk
+ {mask: 0xffff8000, value: 0x110000, op: SUB_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // SYSCALL code
+ {mask: 0xffff8000, value: 0x2b0000, op: SYSCALL, args: instArgs{arg_code_14_0}},
+ // XOR rd, rj, rk
+ {mask: 0xffff8000, value: 0x158000, op: XOR, args: instArgs{arg_rd, arg_rj, arg_rk}},
+ // XORI rd, rj, ui12
+ {mask: 0xffc00000, value: 0x3c00000, op: XORI, args: instArgs{arg_rd, arg_rj, arg_ui12_21_10}},
+}
\ No newline at end of file
--
2.41.0