diff -Naur delve-1.22.0.old/cmd/dlv/dlv_test.go delve-1.22.0/cmd/dlv/dlv_test.go
--- delve-1.22.0.old/cmd/dlv/dlv_test.go	2024-06-08 17:27:28.679331240 +0800
+++ delve-1.22.0/cmd/dlv/dlv_test.go	2024-06-08 17:36:06.367331240 +0800
@@ -224,7 +224,7 @@
 
 func getDlvBinInternal(t *testing.T, goflags ...string) string {
 	dlvbin := filepath.Join(t.TempDir(), "dlv.exe")
-	args := append([]string{"build", "-o", dlvbin}, goflags...)
+	args := append([]string{"build", "-mod=vendor", "-o", dlvbin}, goflags...)
 	args = append(args, "github.com/go-delve/delve/cmd/dlv")
 
 	out, err := exec.Command("go", args...).CombinedOutput()
@@ -382,7 +382,7 @@
 
 	// Checks gen-usage-docs.go
 	tempDir := t.TempDir()
-	cmd := exec.Command("go", "run", "_scripts/gen-usage-docs.go", tempDir)
+	cmd := exec.Command("go", "run", "-mod=vendor", "_scripts/gen-usage-docs.go", tempDir)
 	cmd.Dir = projectRoot()
 	err := cmd.Run()
 	assertNoError(err, t, "go run _scripts/gen-usage-docs.go")
diff -Naur delve-1.22.0.old/Documentation/backend_test_health.md delve-1.22.0/Documentation/backend_test_health.md
--- delve-1.22.0.old/Documentation/backend_test_health.md	2024-06-08 17:27:28.659331240 +0800
+++ delve-1.22.0/Documentation/backend_test_health.md	2024-06-08 17:28:41.227331240 +0800
@@ -29,6 +29,11 @@
 	* 1 broken in linux ppc64le
 * linux/ppc64le/native/pie skipped = 3
 	* 3 broken - pie mode
+* loong64 skipped = 8
+	* 1 broken
+	* 3 broken - cgo stacktraces
+	* 1 broken - global variable symbolication
+	* 3 not implemented
 * pie skipped = 2
 	* 2 upstream issue - https://github.com/golang/go/issues/29322
 * ppc64le skipped = 11
diff -Naur delve-1.22.0.old/_fixtures/asmnilptr/main_loong64.s delve-1.22.0/_fixtures/asmnilptr/main_loong64.s
--- delve-1.22.0.old/_fixtures/asmnilptr/main_loong64.s	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/_fixtures/asmnilptr/main_loong64.s	2024-06-08 17:29:39.103331240 +0800
@@ -0,0 +1,7 @@
+#include "textflag.h"
+
+TEXT ·asmFunc(SB),0,$0-16
+	MOVV arg+0(FP), R5
+	MOVV (R5), R5
+	MOVV R5, ret+8(FP)
+	RET
diff -Naur delve-1.22.0.old/_fixtures/cgostacktest/hello.c delve-1.22.0/_fixtures/cgostacktest/hello.c
--- delve-1.22.0.old/_fixtures/cgostacktest/hello.c	2024-06-08 17:27:28.663331240 +0800
+++ delve-1.22.0/_fixtures/cgostacktest/hello.c	2024-06-08 17:30:27.831331240 +0800
@@ -14,6 +14,8 @@
 #else
 #define BREAKPOINT asm("brk 0;")
 #endif
+#elif __loongarch__
+#define BREAKPOINT asm("break 0;")
 #endif
 
 void helloworld_pt2(int x) {
diff -Naur delve-1.22.0.old/_fixtures/testvariablescgo/test.c delve-1.22.0/_fixtures/testvariablescgo/test.c
--- delve-1.22.0.old/_fixtures/testvariablescgo/test.c	2024-06-08 17:27:28.675331240 +0800
+++ delve-1.22.0/_fixtures/testvariablescgo/test.c	2024-06-08 17:31:43.667331240 +0800
@@ -12,6 +12,8 @@
 #else
 #define BREAKPOINT asm("brk 0;")
 #endif
+#elif __loongarch__
+#define BREAKPOINT asm("break 0;")
 #endif
 
 #define N 100
diff -Naur delve-1.22.0.old/pkg/dwarf/regnum/loong64.go delve-1.22.0/pkg/dwarf/regnum/loong64.go
--- delve-1.22.0.old/pkg/dwarf/regnum/loong64.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/dwarf/regnum/loong64.go	2024-06-08 17:36:40.963331240 +0800
@@ -0,0 +1,87 @@
+package regnum
+
+import (
+	"fmt"
+)
+
+// The mapping between hardware registers and DWARF registers, See
+// https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html
+// https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html
+
+const (
+	// General-purpose Register
+	LOONG64_R0  = 0
+	LOONG64_LR  = 1 // ra: address for subroutine
+	LOONG64_SP  = 3 // sp: stack pointer
+	LOONG64_R22 = 22
+	LOONG64_FP  = LOONG64_R22 // fp: frame pointer
+	LOONG64_R31 = 31
+
+	// Floating-point Register
+	LOONG64_F0  = 32
+	LOONG64_F31 = 63
+
+	// Floating condition flag register
+	LOONG64_FCC0 = 64
+	LOONG64_FCC7 = 71
+
+	LOONG64_FCSR = 72
+
+	// Extra, not defined in ELF-ABI specification
+	LOONG64_ERA  = 73
+	LOONG64_BADV = 74
+
+	// See golang src/cmd/link/internal/loong64/l.go
+	LOONG64_PC = LOONG64_ERA // era : exception program counter
+
+	_LOONG64_MaxRegNum = LOONG64_BADV
+)
+
+func LOONG64ToName(num uint64) string {
+	switch {
+	case num <= LOONG64_R31:
+		return fmt.Sprintf("R%d", num)
+
+	case num >= LOONG64_F0 && num <= LOONG64_F31:
+		return fmt.Sprintf("F%d", num-32)
+
+	case num >= LOONG64_FCC0 && num <= LOONG64_FCC7:
+		return fmt.Sprintf("FCC%d", num-64)
+
+	case num == LOONG64_FCSR:
+		return fmt.Sprintf("FCSR")
+
+	case num == LOONG64_ERA:
+		return fmt.Sprintf("ERA")
+
+	case num == LOONG64_BADV:
+		return fmt.Sprintf("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 <= 31; i++ {
+		r[fmt.Sprintf("r%d", i)] = LOONG64_R0 + i
+	}
+	r[fmt.Sprintf("era")] = LOONG64_ERA
+	r[fmt.Sprintf("badv")] = LOONG64_BADV
+
+	for i := 0; i <= 31; i++ {
+		r[fmt.Sprintf("f%d", i)] = LOONG64_F0 + i
+	}
+
+	for i := 0; i <= 7; i++ {
+		r[fmt.Sprintf("fcc%d", i)] = LOONG64_FCC0 + i
+	}
+	r["fcsr"] = LOONG64_FCSR
+
+	return r
+}()
diff -Naur delve-1.22.0.old/pkg/gobuild/gobuild.go delve-1.22.0/pkg/gobuild/gobuild.go
--- delve-1.22.0.old/pkg/gobuild/gobuild.go	2024-06-08 17:27:28.687331240 +0800
+++ delve-1.22.0/pkg/gobuild/gobuild.go	2024-06-08 17:37:48.659331240 +0800
@@ -80,7 +80,7 @@
 
 	args = append(args, "-o", debugname)
 	if isTest {
-		args = append([]string{"-c"}, args...)
+		args = append([]string{"-c", "-mod=vendor"}, args...)
 	}
 	args = append(args, "-gcflags", "all=-N -l")
 	if buildflags != "" {
diff -Naur delve-1.22.0.old/pkg/proc/bininfo.go delve-1.22.0/pkg/proc/bininfo.go
--- delve-1.22.0.old/pkg/proc/bininfo.go	2024-06-08 17:27:28.687331240 +0800
+++ delve-1.22.0/pkg/proc/bininfo.go	2024-06-08 17:43:46.399331240 +0800
@@ -130,6 +130,7 @@
 		elf.EM_AARCH64: true,
 		elf.EM_386:     true,
 		elf.EM_PPC64:   true,
+		elf.EM_LOONGARCH: true,
 	}
 
 	supportedWindowsArch = map[_PEMachine]bool{
@@ -690,6 +691,8 @@
 		r.Arch = ARM64Arch(goos)
 	case "ppc64le":
 		r.Arch = PPC64LEArch(goos)
+	case "loong64":
+		r.Arch = LOONG64Arch(goos)
 	}
 	return r
 }
@@ -1692,6 +1695,13 @@
 	case elf.EM_PPC64:
 		_ = getSymbol(image, bi.logger, exe, "runtime.tls_g")
 
+	case elf.EM_LOONGARCH:
+		tlsg := getSymbol(image, bi.logger, exe, "runtime.tls_g")
+		if tlsg == nil || tls == nil {
+			bi.gStructOffset = 6 * uint64(bi.Arch.PtrSize())
+			return
+		}
+		bi.gStructOffset = tlsg.Value + (tls.Vaddr & (tls.Align - 1))
 	default:
 		// we should never get here
 		panic("architecture not supported")
diff -Naur delve-1.22.0.old/pkg/proc/core/linux_core.go delve-1.22.0/pkg/proc/core/linux_core.go
--- delve-1.22.0.old/pkg/proc/core/linux_core.go	2024-06-08 17:27:28.687331240 +0800
+++ delve-1.22.0/pkg/proc/core/linux_core.go	2024-06-08 17:50:38.103331240 +0800
@@ -39,6 +39,7 @@
 const (
 	_EM_AARCH64          = 183
 	_EM_X86_64           = 62
+	_EM_LOONGARCH        = 258
 	_ARM_FP_HEADER_START = 512
 )
 
@@ -48,6 +49,7 @@
 	var currentThread proc.Thread
 	var lastThreadAMD *linuxAMD64Thread
 	var lastThreadARM *linuxARM64Thread
+	var lastThreadLOONG *linuxLOONG64Thread
 	for _, note := range notes {
 		switch note.Type {
 		case elf.NT_PRSTATUS:
@@ -65,12 +67,24 @@
 				if currentThread == nil {
 					currentThread = p.Threads[int(t.Pid)]
 				}
+
+			} else if machineType == _EM_LOONGARCH {
+				t := note.Desc.(*linuxPrStatusLOONG64)
+				lastThreadLOONG = &linuxLOONG64Thread{linutil.LOONG64Registers{Regs: &t.Reg}, t}
+				p.Threads[int(t.Pid)] = &thread{lastThreadLOONG, p, proc.CommonThread{}}
+				if currentThread == nil {
+					currentThread = p.Threads[int(t.Pid)]
+				}
 			}
 		case _NT_FPREGSET:
 			if machineType == _EM_AARCH64 {
 				if lastThreadARM != nil {
 					lastThreadARM.regs.Fpregs = note.Desc.(*linutil.ARM64PtraceFpRegs).Decode()
 				}
+			} else if machineType == _EM_LOONGARCH {
+				if lastThreadLOONG != nil {
+					lastThreadLOONG.regs.Fpregs = note.Desc.(*linutil.LOONG64PtraceFpRegs).Decode()
+				}
 			}
 		case _NT_X86_XSTATE:
 			if machineType == _EM_X86_64 {
@@ -146,6 +160,8 @@
 			bi = proc.NewBinaryInfo("linux", "amd64")
 		case _EM_AARCH64:
 			bi = proc.NewBinaryInfo("linux", "arm64")
+		case _EM_LOONGARCH:
+			bi = proc.NewBinaryInfo("linux", "loong64")			
 		default:
 			return nil, nil, fmt.Errorf("unsupported machine type")
 		}
@@ -201,6 +217,21 @@
 func (t *linuxARM64Thread) pid() int {
 	return int(t.t.Pid)
 }
+type linuxLOONG64Thread struct {
+	regs linutil.LOONG64Registers
+	t    *linuxPrStatusLOONG64
+}
+
+func (t *linuxLOONG64Thread) registers() (proc.Registers, error) {
+	var r linutil.LOONG64Registers
+	r.Regs = t.regs.Regs
+	r.Fpregs = t.regs.Fpregs
+	return &r, nil
+}
+
+func (t *linuxLOONG64Thread) pid() int {
+	return int(t.t.Pid)
+}
 
 // Note is a note from the PT_NOTE prog.
 // Relevant types:
@@ -285,6 +316,8 @@
 			note.Desc = &linuxPrStatusAMD64{}
 		case _EM_AARCH64:
 			note.Desc = &linuxPrStatusARM64{}
+		case _EM_LOONGARCH:
+			note.Desc = &linuxPrStatusLOONG64{}			
 		default:
 			return nil, fmt.Errorf("unsupported machine type")
 		}
@@ -332,6 +365,15 @@
 			}
 			note.Desc = fpregs
 		}
+
+		if machineType == _EM_LOONGARCH {
+			fpregs := &linutil.LOONG64PtraceFpRegs{}
+			rdr := bytes.NewReader(desc)
+			if err := binary.Read(rdr, binary.LittleEndian, fpregs.Byte()); err != nil {
+				return nil, err
+			}
+			note.Desc = fpregs
+		}
 	}
 	if err := skipPadding(r, 4); err != nil {
 		return nil, fmt.Errorf("aligning after desc: %v", err)
@@ -445,6 +487,18 @@
 	Reg                          linutil.ARM64PtraceRegs
 	Fpvalid                      int32
 }
+// LinuxPrStatusLOONG64 is a copy of the prstatus kernel struct.
+type linuxPrStatusLOONG64 struct {
+	Siginfo                      linuxSiginfo
+	Cursig                       uint16
+	_                            [2]uint8
+	Sigpend                      uint64
+	Sighold                      uint64
+	Pid, Ppid, Pgrp, Sid         int32
+	Utime, Stime, CUtime, CStime linuxCoreTimeval
+	Reg                          linutil.LOONG64PtraceRegs
+	Fpvalid                      int32
+}
 
 // LinuxSiginfo is a copy of the
 // siginfo kernel struct.
diff -Naur delve-1.22.0.old/pkg/proc/dump.go delve-1.22.0/pkg/proc/dump.go
--- delve-1.22.0.old/pkg/proc/dump.go	2024-06-08 17:27:28.687331240 +0800
+++ delve-1.22.0/pkg/proc/dump.go	2024-06-08 17:51:23.899331240 +0800
@@ -138,6 +138,8 @@
 		fhdr.Machine = elf.EM_AARCH64
 	case "ppc64le":
 		fhdr.Machine = elf.EM_PPC64
+	case "loong64":
+		fhdr.Machine = elf.EM_LOONGARCH
 	default:
 		panic("not implemented")
 	}
diff -Naur delve-1.22.0.old/pkg/proc/linutil/regs_loong64_arch.go delve-1.22.0/pkg/proc/linutil/regs_loong64_arch.go
--- delve-1.22.0.old/pkg/proc/linutil/regs_loong64_arch.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/proc/linutil/regs_loong64_arch.go	2024-06-08 17:52:00.863331240 +0800
@@ -0,0 +1,233 @@
+package linutil
+
+import (
+	"encoding/binary"
+	"fmt"
+	"github.com/go-delve/delve/pkg/dwarf/op"
+	"github.com/go-delve/delve/pkg/dwarf/regnum"
+	"github.com/go-delve/delve/pkg/proc"
+)
+
+// Regs is a wrapper for sys.PtraceRegs.
+type LOONG64Registers struct {
+	Regs       *LOONG64PtraceRegs // general-purpose registers
+	iscgo      bool
+	tp_tls     uint64
+	Fpregs     []proc.Register // Formatted floating point registers
+	Fpregset   []byte          // holding all floating point register values
+	loadFpRegs func(*LOONG64Registers) error
+}
+
+func NewLOONG64Registers(regs *LOONG64PtraceRegs, iscgo bool, tp_tls uint64,
+	loadFpRegs func(*LOONG64Registers) error) *LOONG64Registers {
+	return &LOONG64Registers{
+		Regs:       regs,
+		iscgo:      iscgo,
+		tp_tls:     tp_tls,
+		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
+	Orig_a0  uint64
+	Era      uint64
+	Badv     uint64
+	Reserved [10]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[0]},
+		{"R1", r.Regs.Regs[1]},
+		{"R2", r.Regs.Regs[2]},
+		{"R3", r.Regs.Regs[3]},
+		{"R4", r.Regs.Regs[4]},
+		{"R5", r.Regs.Regs[5]},
+		{"R6", r.Regs.Regs[6]},
+		{"R7", r.Regs.Regs[7]},
+		{"R8", r.Regs.Regs[8]},
+		{"R9", r.Regs.Regs[9]},
+		{"R10", r.Regs.Regs[10]},
+		{"R11", r.Regs.Regs[11]},
+		{"R12", r.Regs.Regs[12]},
+		{"R13", r.Regs.Regs[13]},
+		{"R14", r.Regs.Regs[14]},
+		{"R15", r.Regs.Regs[15]},
+		{"R16", r.Regs.Regs[16]},
+		{"R17", r.Regs.Regs[17]},
+		{"R18", r.Regs.Regs[18]},
+		{"R19", r.Regs.Regs[19]},
+		{"R20", r.Regs.Regs[20]},
+		{"R21", r.Regs.Regs[21]},
+		{"R22", r.Regs.Regs[22]},
+		{"R23", r.Regs.Regs[23]},
+		{"R24", r.Regs.Regs[24]},
+		{"R25", r.Regs.Regs[25]},
+		{"R26", r.Regs.Regs[26]},
+		{"R27", r.Regs.Regs[27]},
+		{"R28", r.Regs.Regs[28]},
+		{"R29", r.Regs.Regs[29]},
+		{"R30", r.Regs.Regs[30]},
+		{"R31", r.Regs.Regs[31]},
+		{"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 {
+	// unused FP register
+	return 0
+}
+
+// TLS returns the address of the thread local storage memory segment.
+func (r *LOONG64Registers) TLS() uint64 {
+	// TODO: calling cgo may overwrite $r22,read it from the kernel
+	if !r.iscgo {
+		return 0
+	}
+
+	// refer to golang defined REGG: loong64/a.out.go
+	return r.tp_tls
+}
+
+// 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_R22], !r.iscgo
+}
+
+// LR returns the link register.
+func (r *LOONG64Registers) LR() uint64 {
+	return r.Regs.Regs[regnum.LOONG64_LR]
+}
+
+// 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
+}
+
+func (r *LOONG64Registers) SetReg(regNum uint64, reg *op.DwarfRegister) (fpchanged bool, err error) {
+	switch regNum {
+	case regnum.LOONG64_SP:
+		r.Regs.Regs[regnum.LOONG64_SP] = reg.Uint64Val
+		return false, nil
+
+	case regnum.LOONG64_PC:
+		r.Regs.Era = reg.Uint64Val
+		return false, nil
+	}
+
+	switch {
+	case regNum >= regnum.LOONG64_R0 && regNum <= regnum.LOONG64_R31:
+		r.Regs.Regs[regNum] = reg.Uint64Val
+		return false, nil
+
+	case regNum >= regnum.LOONG64_F0 && regNum <= regnum.LOONG64_F31:
+		if r.loadFpRegs != nil {
+			err := r.loadFpRegs(r)
+			r.loadFpRegs = nil
+			if err != nil {
+				return false, err
+			}
+		}
+
+		i := regNum - regnum.LOONG64_F0
+		reg.FillBytes()
+		copy(r.Fpregset[8*i:], reg.Bytes)
+		return true, nil
+
+	default:
+		return false, fmt.Errorf("changing register %d not implemented", regNum)
+	}
+}
+
+// Refer to the definition of struct user_fp_state in the kernel ptrace.h
+type LOONG64PtraceFpRegs struct {
+	Fregs []byte
+	Fcc   uint64
+	Fcsr  uint32
+}
+
+const _LOONG64_FPREGSET_LENGTH = (32 * 8)
+
+func (fpregs *LOONG64PtraceFpRegs) Decode() (regs []proc.Register) {
+	for i := 0; i < len(fpregs.Fregs); i += 8 {
+		name := fmt.Sprintf("F%d", (i / 8))
+		value := fpregs.Fregs[i : i+8]
+		regs = proc.AppendBytesRegister(regs, name, value)
+	}
+
+	fccBytes := make([]byte, 8)
+	binary.LittleEndian.PutUint64(fccBytes, uint64(fpregs.Fcc))
+	regs = proc.AppendBytesRegister(regs, "FCC0", fccBytes)
+
+	fcsrBytes := make([]byte, 4)
+	binary.LittleEndian.PutUint32(fccBytes, uint32(fpregs.Fcsr))
+	regs = proc.AppendBytesRegister(regs, "FCSR", fcsrBytes)
+
+	return
+}
+
+func (fpregs *LOONG64PtraceFpRegs) Byte() []byte {
+	fpregs.Fregs = make([]byte, _LOONG64_FPREGSET_LENGTH)
+
+	return fpregs.Fregs[:]
+}
diff -Naur delve-1.22.0.old/pkg/proc/loong64_arch.go delve-1.22.0/pkg/proc/loong64_arch.go
--- delve-1.22.0.old/pkg/proc/loong64_arch.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/proc/loong64_arch.go	2024-06-08 17:52:34.151331240 +0800
@@ -0,0 +1,368 @@
+package proc
+
+import (
+	"encoding/binary"
+	"fmt"
+	"strings"
+
+	"github.com/go-delve/delve/pkg/dwarf/frame"
+	"github.com/go-delve/delve/pkg/dwarf/op"
+	"github.com/go-delve/delve/pkg/dwarf/regnum"
+        "github.com/go-delve/delve/pkg/goversion"
+)
+
+// 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:                false,
+		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),
+		RegnumToString:                   regnum.LOONG64ToName,
+		debugCallMinStackSize:            288,	// TODO
+		maxRegArgBytes:                   16*8 + 16*8, // 16 int argument registers plus 16 float argument registers, TODO
+	}
+}
+
+func loong64FixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *BinaryInfo) *frame.FrameContext {
+	a := bi.Arch
+
+	if a.sigreturnfn == nil {
+		a.sigreturnfn = bi.lookupOneFunc("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: {
+					Rule:   frame.RuleOffset,
+					Offset: int64(-a.PtrSize()),
+				},
+
+				regnum.LOONG64_FP: {
+					Rule:   frame.RuleOffset,
+					Offset: int64(-2 * a.PtrSize()),
+				},
+
+				regnum.LOONG64_SP: {
+					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.lookupOneFunc("crosscall2")
+	}
+
+	if a.crosscall2fn != nil && pc >= a.crosscall2fn.Entry && pc < a.crosscall2fn.End {
+		rule := fctxt.CFA
+
+		if rule.Offset == crosscall2SPOffsetBad {
+			rule.Offset += crosscall2SPOffset
+		}
+		fctxt.CFA = rule
+	}
+
+	// We assume that FP 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.RuleRegister,
+			Reg:    regnum.LOONG64_LR,
+			Offset: 0,
+		}
+	}
+
+	return fctxt
+}
+
+const loong64cgocallSPOffsetSaveSlot = 0x8
+const loong64PrevG0schedSPOffsetSaveSlot = 0x10
+
+func loong64SwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) bool {
+	if it.frame.Current.Fn == nil {
+		if it.systemstack && it.g != nil && it.top {
+			it.switchToGoroutineStack()
+			return true
+		}
+		return false
+	}
+	switch it.frame.Current.Fn.Name {
+	case "runtime.cgocallback_gofunc", "runtime.cgocallback":
+		// 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 function 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.top || it.systemstack {
+			return false
+		}
+
+		it.loadG0SchedSP()
+		if it.g0_sched_sp <= 0 {
+			return false
+		}
+		// Entering the system stack.
+		it.regs.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(it.regs.SP()+loong64PrevG0schedSPOffsetSaveSlot), int64(it.bi.Arch.PtrSize()))
+		it.top = false
+		callFrameRegs, ret, retaddr := it.advanceRegs()
+		frameOnSystemStack := it.newStackframe(ret, retaddr)
+		it.pc = frameOnSystemStack.Ret
+		it.regs = callFrameRegs
+		it.systemstack = true
+
+		return true
+
+	case "runtime.asmcgocall":
+		if it.top || !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(it.regs.SP()+loong64cgocallSPOffsetSaveSlot),
+			int64(it.bi.Arch.PtrSize()))
+		oldsp := it.regs.SP()
+		it.regs.Reg(it.regs.SPRegNum).Uint64Val = 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 it.regs.SP() == oldsp {
+			return false
+		}
+
+		it.top = false
+		it.systemstack = false
+		// The return value is stored in the LR register which is saved at 24(SP).
+		addrret := uint64(int64(it.regs.SP()) + int64(it.bi.Arch.PtrSize()*3)) // TODO
+		it.frame.Ret, _ = readUintRaw(it.mem, addrret, int64(it.bi.Arch.PtrSize()))
+		it.pc = it.frame.Ret
+
+		return true
+
+	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
+		bpoff := uint64(14)
+		lroff := uint64(15)
+		if producer := it.bi.Producer(); producer != "" && goversion.ProducerAfterOrEqual(producer, 1, 19) {
+			// In Go 1.19 (specifically eee6f9f82) the order registers are saved was changed.
+			bpoff = 22
+			lroff = 23
+		}
+		newbp, _ := readUintRaw(it.mem, uint64(it.regs.SP()+8*bpoff), int64(it.bi.Arch.PtrSize()))
+		newlr, _ := readUintRaw(it.mem, uint64(it.regs.SP()+8*lroff), 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*bpoff)
+			it.regs.AddReg(it.regs.BPRegNum, reg)
+		}
+		it.regs.Reg(it.regs.LRRegNum).Uint64Val = uint64(newlr)
+		it.regs.Reg(it.regs.SPRegNum).Uint64Val = uint64(newbp)
+		it.pc = newlr
+		return true
+	case "runtime.mstart":
+		// Calls to runtime.systemstack will switch to the systemstack then:
+		// 1. alter the goroutine stack so that it looks like systemstack_switch
+		//    was called
+		// 2. alter the system stack so that it looks like the bottom-most frame
+		//    belongs to runtime.mstart
+		// If we find a runtime.mstart frame on the system stack of a goroutine
+		// parked on runtime.systemstack_switch we assume runtime.systemstack was
+		// called and continue tracing from the parked position.
+
+		if it.top || !it.systemstack || it.g == nil {
+			return false
+		}
+		if fn := it.bi.PCToFunc(it.g.PC); fn == nil || fn.Name != "runtime.systemstack_switch" {
+			return false
+		}
+
+		it.switchToGoroutineStack()
+		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.throw" && 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()+loong64PrevG0schedSPOffsetSaveSlot),
+			int64(it.bi.Arch.PtrSize()))
+		it.systemstack = true
+
+		return false
+	}
+
+	return false
+}
+
+func loong64RegSize(regnum uint64) int {
+	// All CPU registers are 64bit
+	return 8
+}
+
+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, regnum.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, ""
+	}
+
+	if strings.HasPrefix(name, "FCC") {
+		return name, true, fmt.Sprintf("%#x", reg.Uint64Val)
+	} else if strings.HasPrefix(name, "F") {
+		return name, true, fmt.Sprintf("%#016x", reg.Uint64Val)
+	} else {
+		return name, false, fmt.Sprintf("%#016x", reg.Uint64Val)
+	}
+}
diff -Naur delve-1.22.0.old/pkg/proc/loong64_disasm.go delve-1.22.0/pkg/proc/loong64_disasm.go
--- delve-1.22.0.old/pkg/proc/loong64_disasm.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/proc/loong64_disasm.go	2024-06-08 17:53:11.283331240 +0800
@@ -0,0 +1,217 @@
+// 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 *op.DwarfRegisters, 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)
+	asmInst.Kind = OtherInstruction
+
+	switch inst.Op {
+	case loong64asm.JIRL:
+		rd, _ := inst.Args[0].(loong64asm.Reg)
+		rj, _ := inst.Args[1].(loong64asm.Reg)
+		if rd == loong64asm.R1 {
+			asmInst.Kind = CallInstruction
+		} else if rd == loong64asm.R0 && rj == loong64asm.R1 {
+			asmInst.Kind = RetInstruction
+		} else {
+			asmInst.Kind = JmpInstruction
+		}
+
+	case loong64asm.BL:
+		asmInst.Kind = CallInstruction
+
+	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 *op.DwarfRegisters, mem MemoryReadWriter, bininfo *BinaryInfo) *Location {
+	var pc uint64
+	var err error
+
+	switch inst.Op {
+	// Format: op offs26
+	// Target: offs26
+	case loong64asm.B, loong64asm.BL:
+		switch arg := inst.Args[0].(type) {
+		case loong64asm.OffsetSimm:
+			pc = uint64(int64(instAddr) + int64(arg.Imm))
+		default:
+			return nil
+		}
+
+	// Format: op rd,rj,offs16
+	// Target: offs16
+	case loong64asm.BEQ,
+		loong64asm.BNE,
+		loong64asm.BLT,
+		loong64asm.BGE,
+		loong64asm.BLTU,
+		loong64asm.BGEU:
+
+		switch arg := inst.Args[2].(type) {
+		case loong64asm.OffsetSimm:
+			pc = uint64(int64(instAddr) + int64(arg.Imm))
+		default:
+			return nil
+		}
+
+	// Format: op rd,rj,offs16
+	// Target: rj + offs16
+	case loong64asm.JIRL:
+		if !currentGoroutine || regs == nil {
+			return nil
+		}
+		switch arg1 := inst.Args[1].(type) {
+		case loong64asm.Reg:
+			switch arg2 := inst.Args[2].(type) {
+			case loong64asm.OffsetSimm:
+				pc, err = bininfo.Arch.getAsmRegister(regs, int(arg1))
+				if err != nil {
+					return nil
+				}
+				pc = uint64(int64(pc) + int64(arg2.Imm))
+			}
+		}
+
+	// Format: op rj,offs21
+	// Target: offs21
+	case loong64asm.BEQZ,
+		loong64asm.BNEZ,
+		loong64asm.BCEQZ,
+		loong64asm.BCNEZ:
+
+		if (!currentGoroutine) || (regs == nil) {
+			return nil
+		}
+
+		switch arg := inst.Args[1].(type) {
+		case loong64asm.OffsetSimm:
+			pc = uint64(int64(instAddr) + int64(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/obj.go.
+var prologuesLOONG64 []opcodeSeq
+
+func init() {
+	var tinyStacksplit = opcodeSeq{uint64(loong64asm.ADDI_D)}
+	var smallStacksplit = opcodeSeq{}
+	var bigStacksplit = opcodeSeq{uint64(loong64asm.LU12I_W),
+		uint64(loong64asm.ORI),
+		uint64(loong64asm.SLTU),
+		uint64(loong64asm.BNE),
+		uint64(loong64asm.LU12I_W),
+		uint64(loong64asm.ORI),
+		uint64(loong64asm.ADD_D)}
+
+	var unixGetG = opcodeSeq{uint64(loong64asm.LD_D)}
+	var tailPrologues = opcodeSeq{uint64(loong64asm.SLTU),
+		uint64(loong64asm.BNE),
+		uint64(loong64asm.OR),
+		uint64(loong64asm.BL),
+		uint64(loong64asm.BEQ)}
+
+	prologuesLOONG64 = make([]opcodeSeq, 0, 3)
+	for _, stacksplit := range []opcodeSeq{tinyStacksplit, smallStacksplit, bigStacksplit} {
+		prologue := make(opcodeSeq, 0, len(unixGetG)+len(stacksplit)+len(tailPrologues))
+		prologue = append(prologue, unixGetG...)
+		prologue = append(prologue, stacksplit...)
+		prologue = append(prologue, tailPrologues...)
+		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 GNUFlavour:
+		text = loong64asm.GNUSyntax(loong64asm.Inst(*inst))
+	default:
+		text = loong64asm.GoSyntax(loong64asm.Inst(*inst), pc, symLookup)
+	}
+
+	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
+}()
diff -Naur delve-1.22.0.old/pkg/proc/native/hwbreak_other.go delve-1.22.0/pkg/proc/native/hwbreak_other.go
--- delve-1.22.0.old/pkg/proc/native/hwbreak_other.go	2024-06-08 17:27:28.695331240 +0800
+++ delve-1.22.0/pkg/proc/native/hwbreak_other.go	2024-06-08 17:53:44.007331240 +0800
@@ -1,4 +1,4 @@
-//go:build (linux && 386) || (darwin && arm64) || (windows && arm64) || (linux && ppc64le)
+//go:build (linux && 386) || (darwin && arm64) || (windows && arm64) || (linux && ppc64le) || (linux && loong64)
 
 package native
 
diff -Naur delve-1.22.0.old/pkg/proc/native/ptrace_linux_64bit.go delve-1.22.0/pkg/proc/native/ptrace_linux_64bit.go
--- delve-1.22.0.old/pkg/proc/native/ptrace_linux_64bit.go	2024-06-08 17:27:28.695331240 +0800
+++ delve-1.22.0/pkg/proc/native/ptrace_linux_64bit.go	2024-06-08 17:54:15.767331240 +0800
@@ -1,4 +1,4 @@
-//go:build (linux && amd64) || (linux && arm64) || (linux && ppc64le)
+//go:build (linux && amd64) || (linux && arm64) || (linux && ppc64le) || (linux && loong64)
 
 package native
 
diff -Naur delve-1.22.0.old/pkg/proc/native/registers_linux_loong64.go delve-1.22.0/pkg/proc/native/registers_linux_loong64.go
--- delve-1.22.0.old/pkg/proc/native/registers_linux_loong64.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/proc/native/registers_linux_loong64.go	2024-06-08 17:54:46.735331240 +0800
@@ -0,0 +1,158 @@
+//go:build linux && loong64
+// +build linux,loong64
+
+package native
+
+import (
+	"debug/elf"
+	"encoding/binary"
+	"syscall"
+	"unsafe"
+
+	sys "golang.org/x/sys/unix"
+
+	"github.com/go-delve/delve/pkg/dwarf/op"
+	"github.com/go-delve/delve/pkg/proc"
+	"github.com/go-delve/delve/pkg/proc/linutil"
+)
+
+const (
+	// Refer to the definition of struct user_pt_regs in the kernel file ptrace.h
+	_LOONG64_GREGS_SIZE = (32 * 8) + 8 + 8 + 8 + (10 * 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, fpregs *linutil.LOONG64PtraceFpRegs) (err error) {
+	fprBytes := make([]byte, _LOONG64_FPREGS_SIZE)
+	iov := sys.Iovec{Base: &fprBytes[0], Len: uint64(_LOONG64_FPREGS_SIZE)}
+
+	_, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_GETREGSET, 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
+	}
+
+	fpregs.Fregs = fprBytes[:iov.Len-16]
+	fpregs.Fcc = binary.LittleEndian.Uint64(fprBytes[iov.Len-16 : iov.Len-8])
+	fpregs.Fcsr = binary.LittleEndian.Uint32(fprBytes[iov.Len-8 : iov.Len-4])
+
+	return
+}
+
+// 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)
+	fpchanged, err := r.SetReg(regNum, reg)
+	if err != nil {
+		return err
+	}
+
+	thread.dbp.execPtraceFunc(func() {
+		err = ptraceSetGRegs(thread.ID, r.Regs)
+		if err != syscall.Errno(0) && err != nil {
+			return
+		}
+		if fpchanged && r.Fpregset != nil {
+			iov := sys.Iovec{Base: &r.Fpregset[0], Len: uint64(len(r.Fpregset))}
+			_, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_SETREGSET, uintptr(thread.ID), uintptr(elf.NT_FPREGSET), uintptr(unsafe.Pointer(&iov)), 0, 0)
+		}
+	})
+	if err == syscall.Errno(0) {
+		err = nil
+	}
+
+	return err
+}
+
+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
+	}
+
+	var tp_tls uint64
+	if thread.dbp.iscgo {
+		tp_tls = regs.Regs[2]
+	}
+	r := linutil.NewLOONG64Registers(&regs, thread.dbp.iscgo, tp_tls,
+		func(r *linutil.LOONG64Registers) error {
+			var floatLoadError error
+			r.Fpregs, r.Fpregset, floatLoadError = thread.fpRegisters()
+			return floatLoadError
+		})
+
+	return r, nil
+}
diff -Naur delve-1.22.0.old/pkg/proc/native/support_sentinel_linux.go delve-1.22.0/pkg/proc/native/support_sentinel_linux.go
--- delve-1.22.0.old/pkg/proc/native/support_sentinel_linux.go	2024-06-08 17:27:28.695331240 +0800
+++ delve-1.22.0/pkg/proc/native/support_sentinel_linux.go	2024-06-08 17:55:51.815331240 +0800
@@ -1,4 +1,4 @@
-//go:build linux && !amd64 && !arm64 && !386 && !(ppc64le && exp.linuxppc64le)
+//go:build linux && !amd64 && !arm64 && !386 && !(ppc64le && exp.linuxppc64le) && !loong64
 
 // This file is used to detect build on unsupported GOOS/GOARCH combinations.
 
diff -Naur delve-1.22.0.old/pkg/proc/native/threads_linux_loong64.go delve-1.22.0/pkg/proc/native/threads_linux_loong64.go
--- delve-1.22.0.old/pkg/proc/native/threads_linux_loong64.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/proc/native/threads_linux_loong64.go	2024-06-08 17:56:28.115331240 +0800
@@ -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() { err = ptraceGetFpRegset(thread.ID, &loong64_fpregs) })
+	fpregs := loong64_fpregs.Decode()
+
+	if err != nil {
+		err = fmt.Errorf("could not get floating point registers: %v", err.Error())
+	}
+
+	return fpregs, loong64_fpregs.Fregs, 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
+}
diff -Naur delve-1.22.0.old/pkg/proc/pe.go delve-1.22.0/pkg/proc/pe.go
--- delve-1.22.0.old/pkg/proc/pe.go	2024-06-08 17:27:28.695331240 +0800
+++ delve-1.22.0/pkg/proc/pe.go	2024-06-08 17:58:21.479331240 +0800
@@ -5,58 +5,61 @@
 )
 
 const (
-	_IMAGE_FILE_MACHINE_UNKNOWN   = 0x0
-	_IMAGE_FILE_MACHINE_AM33      = 0x1d3
-	_IMAGE_FILE_MACHINE_AMD64     = 0x8664
-	_IMAGE_FILE_MACHINE_ARM       = 0x1c0
-	_IMAGE_FILE_MACHINE_ARMNT     = 0x1c4
-	_IMAGE_FILE_MACHINE_ARM64     = 0xaa64
-	_IMAGE_FILE_MACHINE_EBC       = 0xebc
-	_IMAGE_FILE_MACHINE_I386      = 0x14c
-	_IMAGE_FILE_MACHINE_IA64      = 0x200
-	_IMAGE_FILE_MACHINE_M32R      = 0x9041
-	_IMAGE_FILE_MACHINE_MIPS16    = 0x266
-	_IMAGE_FILE_MACHINE_MIPSFPU   = 0x366
-	_IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466
-	_IMAGE_FILE_MACHINE_POWERPC   = 0x1f0
-	_IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1
-	_IMAGE_FILE_MACHINE_R4000     = 0x166
-	_IMAGE_FILE_MACHINE_SH3       = 0x1a2
-	_IMAGE_FILE_MACHINE_SH3DSP    = 0x1a3
-	_IMAGE_FILE_MACHINE_SH4       = 0x1a6
-	_IMAGE_FILE_MACHINE_SH5       = 0x1a8
-	_IMAGE_FILE_MACHINE_THUMB     = 0x1c2
-	_IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
+	_IMAGE_FILE_MACHINE_UNKNOWN     = 0x0
+	_IMAGE_FILE_MACHINE_AM33        = 0x1d3
+	_IMAGE_FILE_MACHINE_AMD64       = 0x8664
+	_IMAGE_FILE_MACHINE_ARM         = 0x1c0
+	_IMAGE_FILE_MACHINE_ARMNT       = 0x1c4
+	_IMAGE_FILE_MACHINE_ARM64       = 0xaa64
+	_IMAGE_FILE_MACHINE_EBC         = 0xebc
+	_IMAGE_FILE_MACHINE_I386        = 0x14c
+	_IMAGE_FILE_MACHINE_IA64        = 0x200
+	_IMAGE_FILE_MACHINE_LOONGARCH64 = 0x6264
+	_IMAGE_FILE_MACHINE_M32R        = 0x9041
+	_IMAGE_FILE_MACHINE_MIPS16      = 0x266
+	_IMAGE_FILE_MACHINE_MIPSFPU     = 0x366
+	_IMAGE_FILE_MACHINE_MIPSFPU16   = 0x466
+	_IMAGE_FILE_MACHINE_POWERPC     = 0x1f0
+	_IMAGE_FILE_MACHINE_POWERPCFP   = 0x1f1
+	_IMAGE_FILE_MACHINE_R4000       = 0x166
+	_IMAGE_FILE_MACHINE_SH3         = 0x1a2
+	_IMAGE_FILE_MACHINE_SH3DSP      = 0x1a3
+	_IMAGE_FILE_MACHINE_SH4         = 0x1a6
+	_IMAGE_FILE_MACHINE_SH5         = 0x1a8
+	_IMAGE_FILE_MACHINE_THUMB       = 0x1c2
+	_IMAGE_FILE_MACHINE_WCEMIPSV2   = 0x169
 )
 
 type _PEMachine uint16
 
 // PEMachineString map pe machine to name, See $GOROOT/src/debug/pe/pe.go for detail
 var _PEMachineString = map[_PEMachine]string{
-	_IMAGE_FILE_MACHINE_UNKNOWN:   "unknown",
-	_IMAGE_FILE_MACHINE_AM33:      "am33",
-	_IMAGE_FILE_MACHINE_AMD64:     "amd64",
-	_IMAGE_FILE_MACHINE_ARM:       "arm",
-	_IMAGE_FILE_MACHINE_ARMNT:     "armnt",
-	_IMAGE_FILE_MACHINE_ARM64:     "arm64",
-	_IMAGE_FILE_MACHINE_EBC:       "ebc",
-	_IMAGE_FILE_MACHINE_I386:      "i386",
-	_IMAGE_FILE_MACHINE_IA64:      "ia64",
-	_IMAGE_FILE_MACHINE_M32R:      "m32r",
-	_IMAGE_FILE_MACHINE_MIPS16:    "mips16",
-	_IMAGE_FILE_MACHINE_MIPSFPU:   "mipsfpu",
-	_IMAGE_FILE_MACHINE_MIPSFPU16: "mipsfpu16",
-	_IMAGE_FILE_MACHINE_POWERPC:   "powerpc",
-	_IMAGE_FILE_MACHINE_POWERPCFP: "powerpcfp",
-	_IMAGE_FILE_MACHINE_R4000:     "r4000",
-	_IMAGE_FILE_MACHINE_SH3:       "sh3",
-	_IMAGE_FILE_MACHINE_SH3DSP:    "sh3dsp",
-	_IMAGE_FILE_MACHINE_SH4:       "sh4",
-	_IMAGE_FILE_MACHINE_SH5:       "sh5",
-	_IMAGE_FILE_MACHINE_THUMB:     "thumb",
-	_IMAGE_FILE_MACHINE_WCEMIPSV2: "wcemipsv2",
+	_IMAGE_FILE_MACHINE_UNKNOWN:     "unknown",
+	_IMAGE_FILE_MACHINE_AM33:        "am33",
+	_IMAGE_FILE_MACHINE_AMD64:       "amd64",
+	_IMAGE_FILE_MACHINE_ARM:         "arm",
+	_IMAGE_FILE_MACHINE_ARMNT:       "armnt",
+	_IMAGE_FILE_MACHINE_ARM64:       "arm64",
+	_IMAGE_FILE_MACHINE_EBC:         "ebc",
+	_IMAGE_FILE_MACHINE_I386:        "i386",
+	_IMAGE_FILE_MACHINE_IA64:        "ia64",
+	_IMAGE_FILE_MACHINE_LOONGARCH64: "loong64",
+	_IMAGE_FILE_MACHINE_M32R:        "m32r",
+	_IMAGE_FILE_MACHINE_MIPS16:      "mips16",
+	_IMAGE_FILE_MACHINE_MIPSFPU:     "mipsfpu",
+	_IMAGE_FILE_MACHINE_MIPSFPU16:   "mipsfpu16",
+	_IMAGE_FILE_MACHINE_POWERPC:     "powerpc",
+	_IMAGE_FILE_MACHINE_POWERPCFP:   "powerpcfp",
+	_IMAGE_FILE_MACHINE_R4000:       "r4000",
+	_IMAGE_FILE_MACHINE_SH3:         "sh3",
+	_IMAGE_FILE_MACHINE_SH3DSP:      "sh3dsp",
+	_IMAGE_FILE_MACHINE_SH4:         "sh4",
+	_IMAGE_FILE_MACHINE_SH5:         "sh5",
+	_IMAGE_FILE_MACHINE_THUMB:       "thumb",
+	_IMAGE_FILE_MACHINE_WCEMIPSV2:   "wcemipsv2",
 }
 
+
 func (m _PEMachine) String() string {
 	str, ok := _PEMachineString[m]
 	if ok {
diff -Naur delve-1.22.0.old/pkg/proc/proc_test.go delve-1.22.0/pkg/proc/proc_test.go
--- delve-1.22.0.old/pkg/proc/proc_test.go	2024-06-08 17:27:28.699331240 +0800
+++ delve-1.22.0/pkg/proc/proc_test.go	2024-06-08 19:07:41.939331240 +0800
@@ -3350,6 +3350,7 @@
 	skipOn(t, "broken - cgo stacktraces", "386")
 	skipOn(t, "broken - cgo stacktraces", "windows", "arm64")
 	skipOn(t, "broken - cgo stacktraces", "linux", "ppc64le")
+	skipOn(t, "broken - cgo stacktraces", "loong64")
 	if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 21) {
 		skipOn(t, "broken - cgo stacktraces", "windows", "arm64")
 	}
@@ -3459,6 +3460,11 @@
 		t.Skip("cgo stacktraces not supported on i386 for now")
 	}
 
+	if runtime.GOARCH == "loong64"{
+		t.Skip("cgo stacktraces not supported on loong64 for now")
+	}
+
+
 	protest.MustHaveCgo(t)
 
 	withTestProcess("cgostacktest/", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) {
@@ -3533,6 +3539,7 @@
 
 func TestIssue1034(t *testing.T) {
 	skipOn(t, "broken - cgo stacktraces", "386")
+	skipOn(t, "broken - cgo stacktraces", "loong64")
 	protest.MustHaveCgo(t)
 
 	// The external linker on macOS produces an abbrev for DW_TAG_subprogram
@@ -3553,6 +3560,7 @@
 
 func TestIssue1008(t *testing.T) {
 	skipOn(t, "broken - cgo stacktraces", "386")
+	skipOn(t, "broken - cgo stacktraces", "loong64")
 	protest.MustHaveCgo(t)
 
 	// The external linker on macOS inserts "end of sequence" extended opcodes
@@ -3738,6 +3746,7 @@
 func TestDisassembleGlobalVars(t *testing.T) {
 	skipOn(t, "broken - global variable symbolication", "arm64")   // On ARM64 symLookup can't look up variables due to how they are loaded, see issue #1778
 	skipOn(t, "broken - global variable symbolication", "ppc64le") // See comment on ARM64 above.
+	skipOn(t, "broken - global variable symbolication", "loong64")
 	// On 386 linux when pie, the generated code use __x86.get_pc_thunk to ensure position-independent.
 	// Locate global variable by
 	//    `CALL __x86.get_pc_thunk.ax(SB) 0xb0f7f
@@ -3924,6 +3933,7 @@
 
 func TestInlineStep(t *testing.T) {
 	skipOn(t, "broken", "ppc64le")
+
 	if ver, _ := goversion.Parse(runtime.Version()); ver.Major >= 0 && !ver.AfterOrEqual(goversion.GoVersion{Major: 1, Minor: 10, Rev: -1}) {
 		// Versions of go before 1.10 do not have DWARF information for inlined calls
 		t.Skip("inlining not supported")
@@ -4085,6 +4095,7 @@
 
 func TestDWZCompression(t *testing.T) {
 	skipOn(t, "broken", "ppc64le")
+	skipOn(t, "broken - global variable symbolication", "loong64")
 	// If dwz is not available in the system, skip this test
 	if _, err := exec.LookPath("dwz"); err != nil {
 		t.Skip("dwz not installed")
@@ -4645,6 +4656,7 @@
 	skipOn(t, "broken", "386")
 	skipOn(t, "broken - cgo stacktraces", "darwin", "arm64")
 	skipOn(t, "broken", "ppc64le")
+	skipOn(t, "broken", "loong64")
 	protest.MustHaveCgo(t)
 	// If a panic happens during cgo execution the stacktrace should show the C
 	// function that caused the problem.
@@ -5380,6 +5392,7 @@
 	skipOn(t, "not implemented", "freebsd")
 	skipOn(t, "not implemented", "386")
 	skipOn(t, "not implemented", "ppc64le")
+	skipOn(t, "not implemented", "loong64")
 	skipOn(t, "see https://github.com/go-delve/delve/issues/2768", "windows")
 	protest.AllowRecording(t)
 
@@ -5441,6 +5454,7 @@
 	skipOn(t, "not implemented", "386")
 	skipOn(t, "see https://github.com/go-delve/delve/issues/2768", "windows")
 	skipOn(t, "not implemented", "ppc64le")
+	skipOn(t, "not implemented", "loong64")
 	protest.AllowRecording(t)
 
 	withTestProcess("databpcountstest", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) {
@@ -5715,6 +5729,8 @@
 		asmfile = "main_386.s"
 	case "ppc64le":
 		asmfile = "main_ppc64le.s"
+	case "loong64":
+		asmfile = "main_loong64.s"
 	default:
 		t.Fatalf("assembly file for %s not provided", runtime.GOARCH)
 	}
diff -Naur delve-1.22.0.old/pkg/proc/stack.go delve-1.22.0/pkg/proc/stack.go
--- delve-1.22.0.old/pkg/proc/stack.go	2024-06-08 17:27:28.699331240 +0800
+++ delve-1.22.0/pkg/proc/stack.go	2024-06-08 19:09:11.039331240 +0800
@@ -282,7 +282,7 @@
 	it.pc = it.g.PC
 	it.regs.Reg(it.regs.SPRegNum).Uint64Val = it.g.SP
 	it.regs.AddReg(it.regs.BPRegNum, op.DwarfRegisterFromUint64(it.g.BP))
-	if it.bi.Arch.Name == "arm64" || it.bi.Arch.Name == "ppc64le" {
+	if it.bi.Arch.Name == "arm64" || it.bi.Arch.Name == "ppc64le" || it.bi.Arch.Name == "loong64"{
 		it.regs.Reg(it.regs.LRRegNum).Uint64Val = it.g.LR
 	}
 }
@@ -521,7 +521,7 @@
 		}
 	}
 
-	if it.bi.Arch.Name == "arm64" || it.bi.Arch.Name == "ppc64le" {
+	if it.bi.Arch.Name == "arm64" || it.bi.Arch.Name == "ppc64le" || it.bi.Arch.Name == "loong64"{
 		if ret == 0 && it.regs.Reg(it.regs.LRRegNum) != nil {
 			ret = it.regs.Reg(it.regs.LRRegNum).Uint64Val
 		}
diff -Naur delve-1.22.0.old/pkg/proc/test/support.go delve-1.22.0/pkg/proc/test/support.go
--- delve-1.22.0.old/pkg/proc/test/support.go	2024-06-08 17:27:28.699331240 +0800
+++ delve-1.22.0/pkg/proc/test/support.go	2024-06-08 19:09:48.479331240 +0800
@@ -310,6 +310,9 @@
 	if runtime.GOARCH == "386" {
 		t.Skip(fmt.Errorf("%s does not support FunctionCall for now", runtime.GOARCH))
 	}
+	if runtime.GOARCH == "loong64" {
+		t.Skip(fmt.Errorf("%s does not support FunctionCall for now", runtime.GOARCH))
+	}
 	if runtime.GOARCH == "arm64" {
 		if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 19) || runtime.GOOS == "windows" {
 			t.Skip("this version of Go does not support function calls")
diff -Naur delve-1.22.0.old/_scripts/make.go delve-1.22.0/_scripts/make.go
--- delve-1.22.0.old/_scripts/make.go	2024-06-08 17:27:28.675331240 +0800
+++ delve-1.22.0/_scripts/make.go	2024-06-08 17:33:46.295331240 +0800
@@ -50,7 +50,10 @@
 				envflags = append(envflags, "GOOS="+OS)
 			}
 			if len(envflags) > 0 {
-				executeEnv(envflags, "go", "build", "-ldflags", "-extldflags -static", tagFlags(), buildFlags(), DelveMainPackagePath)
+				envflags = append(envflags, "-mod=vendor")
+			}
+			if len(envflags) > 0 {
+				executeEnv(envflags, "go", "build", "-mod=vendor", "-ldflags", "-extldflags -static", tagFlags(), buildFlags(), DelveMainPackagePath)
 			} else {
 				execute("go", "build", "-ldflags", "-extldflags -static", tagFlags(), buildFlags(), DelveMainPackagePath)
 			}
diff -Naur delve-1.22.0.old/service/dap/server_test.go delve-1.22.0/service/dap/server_test.go
--- delve-1.22.0.old/service/dap/server_test.go	2024-06-08 17:27:28.703331240 +0800
+++ delve-1.22.0/service/dap/server_test.go	2024-06-08 19:13:04.111331240 +0800
@@ -2542,7 +2542,7 @@
 			[]onBreakpoint{{
 				// Stop at line 36
 				execute: func() {
-					if runtime.GOARCH == "386" && goversion.VersionAfterOrEqual(runtime.Version(), 1, 18) && !goversion.VersionAfterOrEqual(runtime.Version(), 1, 21) {
+					if (runtime.GOARCH == "386" && goversion.VersionAfterOrEqual(runtime.Version(), 1, 18) && !goversion.VersionAfterOrEqual(runtime.Version(), 1, 21)) || runtime.GOARCH == "loong64" {
 						client.StepInRequest(1)
 						client.ExpectStepInResponse(t)
 						client.ExpectStoppedEvent(t)
@@ -2617,7 +2617,7 @@
 			[]onBreakpoint{{
 				// Stop at line 36
 				execute: func() {
-					if runtime.GOARCH == "386" && goversion.VersionAfterOrEqual(runtime.Version(), 1, 18) && !goversion.VersionAfterOrEqual(runtime.Version(), 1, 21) {
+					if (runtime.GOARCH == "386" && goversion.VersionAfterOrEqual(runtime.Version(), 1, 18) && !goversion.VersionAfterOrEqual(runtime.Version(), 1, 21)) || runtime.GOARCH == "loong64" {
 						client.StepInRequest(1)
 						client.ExpectStepInResponse(t)
 						client.ExpectStoppedEvent(t)
@@ -2717,7 +2717,7 @@
 }
 
 func isPcReg(reg dap.Variable) bool {
-	pcRegNames := []string{"rip", "pc", "eip"}
+	pcRegNames := []string{"rip", "pc", "eip", "era"}
 	for _, name := range pcRegNames {
 		if name == strings.TrimSpace(reg.Name) {
 			return true
diff -Naur delve-1.22.0.old/service/debugger/debugger_test.go delve-1.22.0/service/debugger/debugger_test.go
--- delve-1.22.0.old/service/debugger/debugger_test.go	2024-06-08 17:27:28.703331240 +0800
+++ delve-1.22.0/service/debugger/debugger_test.go	2024-06-08 19:13:56.767331240 +0800
@@ -49,6 +49,9 @@
 	if runtime.GOARCH == "ppc64le" && runtime.GOOS == "linux" {
 		t.Setenv("GOARCH", "amd64")
 	}
+	if runtime.GOARCH == "loong64" && runtime.GOOS == "linux" {
+		os.Setenv("GOARCH", "amd64")
+	}
 	t.Setenv("GOOS", switchOS[runtime.GOOS])
 	exepath := filepath.Join(buildtestdir, debugname)
 	if err := gobuild.GoBuild(debugname, []string{buildtestdir}, fmt.Sprintf("-o %s", exepath)); err != nil {
diff -Naur delve-1.22.0.old/service/debugger/debugger_unix_test.go delve-1.22.0/service/debugger/debugger_unix_test.go
--- delve-1.22.0.old/service/debugger/debugger_unix_test.go	2024-06-08 17:27:28.703331240 +0800
+++ delve-1.22.0/service/debugger/debugger_unix_test.go	2024-06-08 19:14:37.551331240 +0800
@@ -34,6 +34,9 @@
 	if runtime.GOARCH == "ppc64le" && runtime.GOOS == "linux" {
 		t.Setenv("GOARCH", "amd64")
 	}
+	if runtime.GOARCH == "loong64" && runtime.GOOS == "linux" {
+		os.Setenv("GOARCH", "amd64")
+	}
 	t.Setenv("GOOS", switchOS[runtime.GOOS])
 	exepath := filepath.Join(buildtestdir, debugname)
 	defer os.Remove(exepath)
diff -Naur delve-1.22.0.old/service/test/integration1_test.go delve-1.22.0/service/test/integration1_test.go
--- delve-1.22.0.old/service/test/integration1_test.go	2024-06-08 17:27:28.703331240 +0800
+++ delve-1.22.0/service/test/integration1_test.go	2024-06-08 19:16:33.043331240 +0800
@@ -910,7 +910,7 @@
 		// look for static call to afunction() on line 29
 		found := false
 		for i := range d3 {
-			if d3[i].Loc.Line == 29 && (strings.HasPrefix(d3[i].Text, "call") || strings.HasPrefix(d3[i].Text, "CALL")) && d3[i].DestLoc != nil && d3[i].DestLoc.Function != nil && d3[i].DestLoc.Function.Name() == "main.afunction" {
+			if d3[i].Loc.Line == 29 && (strings.HasPrefix(d3[i].Text, "call") || strings.HasPrefix(d3[i].Text, "CALL") || strings.HasPrefix(d3[i].Text, "bl")) && d3[i].DestLoc != nil && d3[i].DestLoc.Function != nil && d3[i].DestLoc.Function.Name() == "main.afunction" {
 				found = true
 				break
 			}
@@ -960,7 +960,7 @@
 				t.Fatal("Calling StepInstruction() repeatedly did not find the call instruction")
 			}
 
-			if strings.HasPrefix(curinstr.Text, "call") || strings.HasPrefix(curinstr.Text, "CALL") {
+			if strings.HasPrefix(curinstr.Text, "call") || strings.HasPrefix(curinstr.Text, "CALL")  || strings.HasPrefix(curinstr.Text, "jirl") || strings.HasPrefix(curinstr.Text, "bl"){
 				t.Logf("call: %v", curinstr)
 				if curinstr.DestLoc == nil || curinstr.DestLoc.Function == nil {
 					t.Fatalf("Call instruction does not have destination: %v", curinstr)
diff -Naur delve-1.22.0.old/service/test/integration2_test.go delve-1.22.0/service/test/integration2_test.go
--- delve-1.22.0.old/service/test/integration2_test.go	2024-06-08 17:27:28.703331240 +0800
+++ delve-1.22.0/service/test/integration2_test.go	2024-06-08 19:17:49.975331240 +0800
@@ -1418,7 +1418,7 @@
 		// look for static call to afunction() on line 29
 		found := false
 		for i := range d3 {
-			if d3[i].Loc.Line == 29 && (strings.HasPrefix(d3[i].Text, "call") || strings.HasPrefix(d3[i].Text, "CALL")) && d3[i].DestLoc != nil && d3[i].DestLoc.Function != nil && d3[i].DestLoc.Function.Name() == "main.afunction" {
+			if d3[i].Loc.Line == 29 && (strings.HasPrefix(d3[i].Text, "bl") || strings.HasPrefix(d3[i].Text, "jirl") || strings.HasPrefix(d3[i].Text, "call") || strings.HasPrefix(d3[i].Text, "CALL")) && d3[i].DestLoc != nil && d3[i].DestLoc.Function != nil && d3[i].DestLoc.Function.Name() == "main.afunction" {
 				found = true
 				break
 			}
@@ -1468,7 +1468,7 @@
 				t.Fatal("Calling StepInstruction() repeatedly did not find the call instruction")
 			}
 
-			if strings.HasPrefix(curinstr.Text, "call") || strings.HasPrefix(curinstr.Text, "CALL") {
+			if strings.HasPrefix(curinstr.Text, "call") || strings.HasPrefix(curinstr.Text, "CALL") || strings.HasPrefix(curinstr.Text, "bl") || strings.HasPrefix(curinstr.Text, "jirl") {
 				t.Logf("call: %v", curinstr)
 				if curinstr.DestLoc == nil || curinstr.DestLoc.Function == nil {
 					t.Fatalf("Call instruction does not have destination: %v", curinstr)
diff -Naur delve-1.22.0.old/vendor/golang.org/x/arch/loong64/loong64asm/arg.go delve-1.22.0/vendor/golang.org/x/arch/loong64/loong64asm/arg.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/loong64/loong64asm/arg.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/loong64/loong64asm/arg.go	2024-06-08 19:28:12.463331240 +0800
@@ -0,0 +1,93 @@
+// Copyright 2023 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_lsbw: For details, please refer to chapter 2.2.3.8 of instruction manual
+//
+// - arg_msbw: For details, please refer to chapter 2.2.3.9 of instruction manual
+//
+// - arg_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
+	//6-10
+	arg_rj
+	arg_rk
+	arg_op_4_0
+	arg_fcsr_4_0
+	arg_fcsr_9_5
+	//11-15
+	arg_csr_23_10
+	arg_cd
+	arg_cj
+	arg_ca
+	arg_sa2_16_15
+	//16-20
+	arg_sa3_17_15
+	arg_code_4_0
+	arg_code_14_0
+	arg_ui5_14_10
+	arg_ui6_15_10
+	//21-25
+	arg_ui12_21_10
+	arg_lsbw
+	arg_msbw
+	arg_lsbd
+	arg_msbd
+	//26-30
+	arg_hint_4_0
+	arg_hint_14_0
+	arg_level_14_0
+	arg_level_17_10
+	arg_seq_17_10
+	//31-35
+	arg_si12_21_10
+	arg_si14_23_10
+	arg_si16_25_10
+	arg_si20_24_5
+	arg_offset_20_0
+	//36~
+	arg_offset_25_0
+	arg_offset_15_0
+)
diff -Naur delve-1.22.0.old/vendor/golang.org/x/arch/loong64/loong64asm/decode.go delve-1.22.0/vendor/golang.org/x/arch/loong64/loong64asm/decode.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/loong64/loong64asm/decode.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/loong64/loong64asm/decode.go	2024-06-08 19:28:33.979331240 +0800
@@ -0,0 +1,269 @@
+// Copyright 2023 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, i)
+			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, index int) 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_op_4_0:
+		tmp := x & ((1 << 5) - 1)
+		return Uimm{tmp, false}
+
+	case arg_csr_23_10:
+		tmp := (x >> 10) & ((1 << 14) - 1)
+		return Uimm{tmp, false}
+
+	case arg_sa2_16_15:
+		f := &instFormats[index]
+		tmp := SaSimm((x >> 15) & ((1 << 2) - 1))
+		if (f.op == ALSL_D) || (f.op == ALSL_W) || (f.op == ALSL_WU) {
+			return tmp + 1
+		} else {
+			return tmp + 0
+		}
+
+	case arg_sa3_17_15:
+		return SaSimm((x >> 15) & ((1 << 3) - 1))
+
+	case arg_code_4_0:
+		return CodeSimm(x & ((1 << 5) - 1))
+
+	case arg_code_14_0:
+		return CodeSimm(x & ((1 << 15) - 1))
+
+	case arg_ui5_14_10:
+		tmp := (x >> 10) & ((1 << 5) - 1)
+		return Uimm{tmp, false}
+
+	case arg_ui6_15_10:
+		tmp := (x >> 10) & ((1 << 6) - 1)
+		return Uimm{tmp, false}
+
+	case arg_ui12_21_10:
+		tmp := ((x >> 10) & ((1 << 12) - 1) & 0xfff)
+		return Uimm{tmp, false}
+
+	case arg_lsbw:
+		tmp := (x >> 10) & ((1 << 5) - 1)
+		return Uimm{tmp, false}
+
+	case arg_msbw:
+		tmp := (x >> 16) & ((1 << 5) - 1)
+		return Uimm{tmp, false}
+
+	case arg_lsbd:
+		tmp := (x >> 10) & ((1 << 6) - 1)
+		return Uimm{tmp, false}
+
+	case arg_msbd:
+		tmp := (x >> 16) & ((1 << 6) - 1)
+		return Uimm{tmp, false}
+
+	case arg_hint_4_0:
+		tmp := x & ((1 << 5) - 1)
+		return Uimm{tmp, false}
+
+	case arg_hint_14_0:
+		tmp := x & ((1 << 15) - 1)
+		return Uimm{tmp, false}
+
+	case arg_level_14_0:
+		tmp := x & ((1 << 15) - 1)
+		return Uimm{tmp, false}
+
+	case arg_level_17_10:
+		tmp := (x >> 10) & ((1 << 8) - 1)
+		return Uimm{tmp, false}
+
+	case arg_seq_17_10:
+		tmp := (x >> 10) & ((1 << 8) - 1)
+		return Uimm{tmp, false}
+
+	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 Simm16{tmp, 12}
+
+	case arg_si14_23_10:
+		var tmp int32
+		if (x & 0x800000) == 0x800000 {
+			tmp = int32((((x >> 10) & ((1 << 14) - 1)) << 2) | 0xffff0000)
+		} else {
+			tmp = int32((((x >> 10) & ((1 << 14) - 1)) << 2) | 0x00000000)
+		}
+		return Simm32{tmp, 14}
+
+	case arg_si16_25_10:
+		var tmp int32
+
+		if (x & 0x2000000) == 0x2000000 {
+			tmp = int32(((x >> 10) & ((1 << 16) - 1)) | 0xffff0000)
+		} else {
+			tmp = int32(((x >> 10) & ((1 << 16) - 1)) | 0x00000000)
+		}
+
+		return Simm32{tmp, 16}
+
+	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 Simm32{tmp, 20}
+
+	case arg_offset_20_0:
+		var tmp int32
+
+		if (x & 0x10) == 0x10 {
+			tmp = int32(((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 21) - 1)) << 2) | 0xff800000)
+		} else {
+			tmp = int32((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 21) - 1)) << 2)
+		}
+
+		return OffsetSimm{tmp, 21}
+
+	case arg_offset_15_0:
+		var tmp int32
+		if (x & 0x2000000) == 0x2000000 {
+			tmp = int32((((x >> 10) & ((1 << 16) - 1)) << 2) | 0xfffc0000)
+		} else {
+			tmp = int32((((x >> 10) & ((1 << 16) - 1)) << 2) | 0x00000000)
+		}
+
+		return OffsetSimm{tmp, 16}
+
+	case arg_offset_25_0:
+		var tmp int32
+
+		if (x & 0x200) == 0x200 {
+			tmp = int32(((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 26) - 1)) << 2) | 0xf0000000)
+		} else {
+			tmp = int32(((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 26) - 1)) << 2) | 0x00000000)
+		}
+
+		return OffsetSimm{tmp, 26}
+	default:
+		return nil
+	}
+}
diff -Naur delve-1.22.0.old/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go delve-1.22.0/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go	2024-06-08 19:28:50.963331240 +0800
@@ -0,0 +1,16 @@
+// Copyright 2023 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())
+}
diff -Naur delve-1.22.0.old/vendor/golang.org/x/arch/loong64/loong64asm/inst.go delve-1.22.0/vendor/golang.org/x/arch/loong64/loong64asm/inst.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/loong64/loong64asm/inst.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/loong64/loong64asm/inst.go	2024-06-08 19:29:29.299331240 +0800
@@ -0,0 +1,302 @@
+// Copyright 2023 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 op string = i.Op.String()
+	var args []string
+
+	for _, arg := range i.Args {
+		if arg == nil {
+			break
+		}
+		args = append(args, arg.String())
+	}
+
+	switch i.Op {
+	case OR:
+		if i.Args[2].(Reg) == R0 {
+			op = "move"
+			args = args[0:2]
+		}
+
+	case ANDI:
+		if i.Args[0].(Reg) == R0 && i.Args[1].(Reg) == R0 {
+			return "nop"
+		}
+
+	case JIRL:
+		if i.Args[0].(Reg) == R0 && i.Args[2].(OffsetSimm).Imm == 0 {
+			return "jr " + args[1]
+		}
+
+	case BLT:
+		if i.Args[0].(Reg) == R0 {
+			op = "bgtz"
+			args = args[1:]
+		} else if i.Args[1].(Reg) == R0 {
+			op = "bltz"
+			args = append(args[:1], args[2:]...)
+		}
+
+	case BGE:
+		if i.Args[0].(Reg) == R0 {
+			op = "blez"
+			args = args[1:]
+		} else if i.Args[1].(Reg) == R0 {
+			op = "bgez"
+			args = append(args[:1], args[2:]...)
+		}
+	}
+
+	if len(args) == 0 {
+		return op
+	} else {
+		return op + " " + strings.Join(args, ", ")
+	}
+}
+
+// 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 {
+	String() string
+}
+
+// A Reg is a single register.
+// The zero value denotes R0, not the absence of a 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 (r Reg) String() string {
+	switch {
+	case r == R0:
+		return "$zero"
+
+	case r == R1:
+		return "$ra"
+
+	case r == R2:
+		return "$tp"
+
+	case r == R3:
+		return "$sp"
+
+	case (r >= R4) && (r <= R11):
+		return fmt.Sprintf("$a%d", int(r-R4))
+
+	case (r >= R12) && (r <= R20):
+		return fmt.Sprintf("$t%d", int(r-R12))
+
+	case r == R21:
+		return "$r21"
+
+	case r == R22:
+		return "$fp"
+
+	case (r >= R23) && (r <= R31):
+		return fmt.Sprintf("$s%d", int(r-R23))
+
+	case (r >= F0) && (r <= F7):
+		return fmt.Sprintf("$fa%d", int(r-F0))
+
+	case (r >= F8) && (r <= F23):
+		return fmt.Sprintf("$ft%d", int(r-F8))
+
+	case (r >= F24) && (r <= F31):
+		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 (f Fcsr) String() string {
+	return fmt.Sprintf("$fcsr%d", uint8(f))
+}
+
+// float condition flags register
+type Fcc uint8
+
+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 Uimm struct {
+	Imm     uint32
+	Decimal bool
+}
+
+func (i Uimm) String() string {
+	if i.Decimal == true {
+		return fmt.Sprintf("%d", i.Imm)
+	} else {
+		return fmt.Sprintf("%#x", i.Imm)
+	}
+}
+
+type Simm16 struct {
+	Imm   int16
+	Width uint8
+}
+
+func (si Simm16) String() string {
+	return fmt.Sprintf("%d", int32(si.Imm))
+}
+
+type Simm32 struct {
+	Imm   int32
+	Width uint8
+}
+
+func (si Simm32) String() string {
+	return fmt.Sprintf("%d", int32(si.Imm))
+}
+
+type OffsetSimm struct {
+	Imm   int32
+	Width uint8
+}
+
+func (o OffsetSimm) String() string {
+	return fmt.Sprintf("%d", int32(o.Imm))
+}
+
+type SaSimm int16
+
+func (s SaSimm) String() string {
+	return fmt.Sprintf("%#x", int(s))
+}
+
+type CodeSimm int16
+
+func (c CodeSimm) String() string {
+	return fmt.Sprintf("%#x", int(c))
+}
diff -Naur delve-1.22.0.old/vendor/golang.org/x/arch/loong64/loong64asm/plan9x.go delve-1.22.0/vendor/golang.org/x/arch/loong64/loong64asm/plan9x.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/loong64/loong64asm/plan9x.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/loong64/loong64asm/plan9x.go	2024-06-08 19:30:22.707331240 +0800
@@ -0,0 +1,437 @@
+// Copyright 2020 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"
+)
+
+// GoSyntax returns the Go assembler syntax for the instruction.
+// The syntax was originally defined by Plan 9.
+// The pc is the program counter of the instruction, used for
+// expanding PC-relative addresses into absolute ones.
+// The symname function queries the symbol table for the program
+// being disassembled. Given a target address it returns the name
+// and base address of the symbol containing the target, if any;
+// otherwise it returns "", 0.
+func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) string {
+	if symname == nil {
+		symname = func(uint64) (string, uint64) { return "", 0 }
+	}
+	if inst.Op == 0 && inst.Enc == 0 {
+		return "WORD $0"
+	} else if inst.Op == 0 {
+		return "?"
+	}
+
+	var args []string
+	for _, a := range inst.Args {
+		if a == nil {
+			break
+		}
+		args = append(args, plan9Arg(&inst, pc, symname, a))
+	}
+
+	var op string = plan9OpMap[inst.Op]
+	if op == "" {
+		op = "Unknown " + inst.Op.String()
+	}
+
+	switch inst.Op {
+	case BSTRPICK_D:
+		msbw, lsbw := inst.Args[2].(Uimm), inst.Args[3].(Uimm)
+		if msbw.Imm == 15 && lsbw.Imm == 0 {
+			op = "MOVHU"
+		} else if msbw.Imm == 31 && lsbw.Imm == 0 {
+			op = "MOVWU"
+		}
+		args = append(args[1:2], args[0:1]...)
+
+	case BCNEZ, BCEQZ:
+		args = args[1:2]
+
+	case BEQ, BNE:
+		rj := inst.Args[0].(Reg)
+		rd := inst.Args[1].(Reg)
+		if rj == rd && inst.Op == BEQ {
+			op = "JMP"
+			args = args[2:]
+		} else if rj == R0 {
+			args = args[1:]
+		} else if rd == R0 {
+			args = append(args[:1], args[2:]...)
+		}
+
+	case BEQZ, BNEZ:
+		if inst.Args[0].(Reg) == R0 && inst.Op == BEQ {
+			op = "JMP"
+			args = args[1:]
+		}
+
+	case BLT, BLTU, BGE, BGEU:
+		rj := inst.Args[0].(Reg)
+		rd := inst.Args[1].(Reg)
+		if rj == rd && (inst.Op == BGE || inst.Op == BGEU) {
+			op = "JMP"
+			args = args[2:]
+		} else if rj == R0 {
+			switch inst.Op {
+			case BGE:
+				op = "BLEZ"
+			case BLT:
+				op = "BGTZ"
+			}
+			args = args[1:]
+		} else if rd == R0 {
+			if !strings.HasSuffix(op, "U") {
+				op += "Z"
+			}
+			args = append(args[:1], args[2:]...)
+		}
+
+	case JIRL:
+		rd := inst.Args[0].(Reg)
+		rj := inst.Args[1].(Reg)
+		regno := uint16(rj) & 31
+		if rd == R0 {
+			return fmt.Sprintf("JMP (R%d)", regno)
+		}
+		return fmt.Sprintf("CALL (R%d)", regno)
+
+	case LD_B, LD_H, LD_W, LD_D, LD_BU, LD_HU, LD_WU, LL_W, LL_D,
+		ST_B, ST_H, ST_W, ST_D, SC_W, SC_D, FLD_S, FLD_D, FST_S, FST_D:
+		var off int32
+		switch a := inst.Args[2].(type) {
+		case Simm16:
+			off = signumConvInt32(int32(a.Imm), a.Width)
+		case Simm32:
+			off = signumConvInt32(int32(a.Imm), a.Width) >> 2
+		}
+		Iop := strings.ToUpper(inst.Op.String())
+		if strings.HasPrefix(Iop, "L") || strings.HasPrefix(Iop, "FL") {
+			return fmt.Sprintf("%s %d(%s), %s", op, off, args[1], args[0])
+		}
+		return fmt.Sprintf("%s %s, %d(%s)", op, args[0], off, args[1])
+
+	case CACOP:
+		code := inst.Args[0].(CodeSimm)
+		si12 := inst.Args[2].(Simm16)
+		off := signumConvInt32(int32(si12.Imm), si12.Width)
+		return fmt.Sprintf("%s R%d, %d(%s)", op, code, off, args[1])
+
+	default:
+		// Reverse args, placing dest last
+		for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
+			args[i], args[j] = args[j], args[i]
+		}
+		switch len(args) {
+		case 0, 1:
+			if inst.Op != B && inst.Op != BL {
+				return op
+			}
+
+		case 3:
+			switch a0 := inst.Args[0].(type) {
+			case Reg:
+				rj := inst.Args[1].(Reg)
+				if a0 == rj && a0 != R0 {
+					args = args[0:2]
+				}
+			case Fcc:
+				args = args[0:2]
+			}
+			switch inst.Op {
+			case SUB_W, SUB_D, ADDI_W, ADDI_D, ORI:
+				rj := inst.Args[1].(Reg)
+				if rj == R0 {
+					args = append(args[0:1], args[2:]...)
+					if inst.Op == SUB_W {
+						op = "NEGW"
+					} else if inst.Op == SUB_D {
+						op = "NEGV"
+					} else {
+						op = "MOVW"
+					}
+				}
+
+			case ANDI:
+				ui12 := inst.Args[2].(Uimm)
+				if ui12.Imm == uint32(0xff) {
+					op = "MOVBU"
+					args = args[1:]
+				} else if ui12.Imm == 0 && inst.Args[0].(Reg) == R0 && inst.Args[1].(Reg) == R0 {
+					return "NOOP"
+				}
+
+			case SLL_W, OR:
+				rk := inst.Args[2].(Reg)
+				if rk == R0 {
+					args = args[1:]
+					if inst.Op == SLL_W {
+						op = "MOVW"
+					} else {
+						op = "MOVV"
+					}
+				}
+			}
+		}
+	}
+
+	if args != nil {
+		op += " " + strings.Join(args, ", ")
+	}
+	return op
+}
+
+func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
+	// Reg:			gpr[0, 31] and fpr[0, 31]
+	// Fcsr:		fcsr[0, 3]
+	// Fcc:			fcc[0, 7]
+	// Uimm:		unsigned integer constant
+	// Simm16:		si16
+	// Simm32:		si32
+	// OffsetSimm:	si32
+	switch a := arg.(type) {
+	case Reg:
+		regenum := uint16(a)
+		regno := uint16(a) & 0x1f
+		// General-purpose register
+		if regenum >= uint16(R0) && regenum <= uint16(R31) {
+			return fmt.Sprintf("R%d", regno)
+		} else { // Float point register
+			return fmt.Sprintf("F%d", regno)
+		}
+
+	case Fcsr:
+		regno := uint8(a) & 0x1f
+		return fmt.Sprintf("FCSR%d", regno)
+
+	case Fcc:
+		regno := uint8(a) & 0x1f
+		return fmt.Sprintf("FCC%d", regno)
+
+	case Uimm:
+		return fmt.Sprintf("$%d", a.Imm)
+
+	case Simm16:
+		si16 := signumConvInt32(int32(a.Imm), a.Width)
+		return fmt.Sprintf("$%d", si16)
+
+	case Simm32:
+		si32 := signumConvInt32(a.Imm, a.Width)
+		return fmt.Sprintf("$%d", si32)
+
+	case OffsetSimm:
+		offs := offsConvInt32(a.Imm, a.Width)
+		if inst.Op == B || inst.Op == BL {
+			addr := int64(pc) + int64(a.Imm)
+			if s, base := symname(uint64(addr)); s != "" && uint64(addr) == base {
+				return fmt.Sprintf("%s(SB)", s)
+			}
+		}
+		return fmt.Sprintf("%d(PC)", offs>>2)
+
+	case SaSimm:
+		return fmt.Sprintf("$%d", a)
+
+	case CodeSimm:
+		return fmt.Sprintf("$%d", a)
+
+	}
+	return strings.ToUpper(arg.String())
+}
+
+func signumConvInt32(imm int32, width uint8) int32 {
+	active := uint32(1<<width) - 1
+	signum := uint32(imm) & active
+	if ((signum >> (width - 1)) & 0x1) == 1 {
+		signum |= ^active
+	}
+	return int32(signum)
+}
+
+func offsConvInt32(imm int32, width uint8) int32 {
+	relWidth := width + 2
+	return signumConvInt32(imm, relWidth)
+}
+
+var plan9OpMap = map[Op]string{
+	ADD_W:       "ADD",
+	ADD_D:       "ADDV",
+	SUB_W:       "SUB",
+	SUB_D:       "SUBV",
+	ADDI_W:      "ADD",
+	ADDI_D:      "ADDV",
+	LU12I_W:     "LU12IW",
+	LU32I_D:     "LU32ID",
+	LU52I_D:     "LU52ID",
+	SLT:         "SGT",
+	SLTU:        "SGTU",
+	SLTI:        "SGT",
+	SLTUI:       "SGTU",
+	PCADDU12I:   "PCADDU12I",
+	PCALAU12I:   "PCALAU12I",
+	AND:         "AND",
+	OR:          "OR",
+	NOR:         "NOR",
+	XOR:         "XOR",
+	ANDI:        "AND",
+	ORI:         "OR",
+	XORI:        "XOR",
+	MUL_W:       "MUL",
+	MULH_W:      "MULH",
+	MULH_WU:     "MULHU",
+	MUL_D:       "MULV",
+	MULH_D:      "MULHV",
+	MULH_DU:     "MULHVU",
+	DIV_W:       "DIV",
+	DIV_WU:      "DIVU",
+	DIV_D:       "DIVV",
+	DIV_DU:      "DIVVU",
+	MOD_W:       "REM",
+	MOD_WU:      "REMU",
+	MOD_D:       "REMV",
+	MOD_DU:      "REMVU",
+	SLL_W:       "SLL",
+	SRL_W:       "SRL",
+	SRA_W:       "SRA",
+	ROTR_W:      "ROTR",
+	SLL_D:       "SLLV",
+	SRL_D:       "SRLV",
+	SRA_D:       "SRAV",
+	ROTR_D:      "ROTRV",
+	SLLI_W:      "SLL",
+	SRLI_W:      "SRL",
+	SRAI_W:      "SRA",
+	ROTRI_W:     "ROTR",
+	SLLI_D:      "SLLV",
+	SRLI_D:      "SRLV",
+	SRAI_D:      "SRAV",
+	ROTRI_D:     "ROTRV",
+	EXT_W_B:     "",
+	EXT_W_H:     "",
+	CLO_W:       "CLO",
+	CLZ_W:       "CLZ",
+	BSTRPICK_D:  "",
+	MASKEQZ:     "MASKEQZ",
+	MASKNEZ:     "MASKNEZ",
+	BCNEZ:       "BFPT",
+	BCEQZ:       "BFPF",
+	BEQ:         "BEQ",
+	BNE:         "BNE",
+	BEQZ:        "BEQ",
+	BNEZ:        "BNE",
+	BLT:         "BLT",
+	BLTU:        "BLTU",
+	BGE:         "BGE",
+	BGEU:        "BGEU",
+	B:           "JMP",
+	BL:          "CALL",
+	LD_B:        "MOVB",
+	LD_H:        "MOVH",
+	LD_W:        "MOVW",
+	LD_D:        "MOVV",
+	LD_BU:       "MOVBU",
+	LD_HU:       "MOVHU",
+	LD_WU:       "MOVWU",
+	ST_B:        "MOVB",
+	ST_H:        "MOVH",
+	ST_W:        "MOVW",
+	ST_D:        "MOVV",
+	AMSWAP_W:    "AMSWAPW",
+	AMSWAP_D:    "AMSWAPD",
+	AMADD_W:     "AMADDW",
+	AMADD_D:     "AMADDV",
+	AMAND_W:     "AMANDW",
+	AMAND_D:     "AMANDV",
+	AMOR_W:      "AMORW",
+	AMOR_D:      "AMORV",
+	AMXOR_W:     "AMXORW",
+	AMXOR_D:     "AMXORV",
+	AMMAX_W:     "AMMAXW",
+	AMMAX_D:     "AMMAXV",
+	AMMIN_W:     "AMMINW",
+	AMMIN_D:     "AMMINV",
+	AMMAX_WU:    "AMMAXWU",
+	AMMAX_DU:    "AMMAXVU",
+	AMMIN_WU:    "AMMINWU",
+	AMMIN_DU:    "AMMINVU",
+	AMSWAP_DB_W: "AMSWAPDBW",
+	AMSWAP_DB_D: "AMSWAPDBV",
+	AMADD_DB_W:  "AMADDDBW",
+	AMADD_DB_D:  "AMADDDBV",
+	AMAND_DB_W:  "AMANDDBW",
+	AMAND_DB_D:  "AMANDDBV",
+	AMOR_DB_W:   "AMORDBW",
+	AMOR_DB_D:   "AMORDBV",
+	AMXOR_DB_W:  "AMXORDBW",
+	AMXOR_DB_D:  "AMXORDBV",
+	AMMAX_DB_W:  "AMMAXDBW",
+	AMMAX_DB_D:  "AMMAXDBV",
+	AMMIN_DB_W:  "AMMINDBW",
+	AMMIN_DB_D:  "AMMINDBV",
+	AMMAX_DB_WU: "AMMAXDBWU",
+	AMMAX_DB_DU: "AMMAXDBVU",
+	AMMIN_DB_WU: "AMMINDBWU",
+	AMMIN_DB_DU: "AMMINDBVU",
+	LL_W:        "LL",
+	LL_D:        "LLV",
+	SC_W:        "SC",
+	SC_D:        "SCV",
+	DBAR:        "DBAR",
+	SYSCALL:     "SYSCALL",
+	BREAK:       "BREAK",
+	CACOP:       "BREAK",
+	RDTIMEL_W:   "RDTIMELW",
+	RDTIMEH_W:   "RDTIMEHW",
+	RDTIME_D:    "RDTIMED",
+	FADD_S:      "ADDF",
+	FADD_D:      "ADDD",
+	FSUB_S:      "SUBF",
+	FSUB_D:      "SUBD",
+	FMUL_S:      "MULF",
+	FMUL_D:      "MULD",
+	FDIV_S:      "DIVF",
+	FDIV_D:      "DIVD",
+	FABS_S:      "ABSF",
+	FABS_D:      "ABSD",
+	FNEG_S:      "NEGF",
+	FNEG_D:      "NEGD",
+	FSQRT_S:     "SQRTF",
+	FSQRT_D:     "SQRTD",
+	FCMP_CEQ_S:  "CMPEQF",
+	FCMP_CEQ_D:  "CMPEQD",
+	FCMP_SLE_S:  "CMPGEF",
+	FCMP_SLE_D:  "CMPGED",
+	FCMP_SLT_S:  "CMPGTF",
+	FCMP_SLT_D:  "CMPGTD",
+	FCVT_D_S:    "MOVFD",
+	FCVT_S_D:    "MOVDF",
+	FFINT_S_W:   "MOVWF",
+	FFINT_S_L:   "MOVVF",
+	FFINT_D_W:   "MOVWD",
+	FFINT_D_L:   "MOVVD",
+	FTINT_W_S:   "MOVFW",
+	FTINT_L_S:   "MOVFV",
+	FTINT_W_D:   "MOVDW",
+	FTINT_L_D:   "MOVDV",
+	FTINTRZ_W_S: "TRUNCFW",
+	FTINTRZ_W_D: "TRUNCDW",
+	FTINTRZ_L_S: "TRUNCFV",
+	FTINTRZ_L_D: "TRUNCDV",
+	FMOV_S:      "MOVF",
+	FMOV_D:      "MOVD",
+	MOVGR2FR_W:  "MOVW",
+	MOVGR2FR_D:  "MOVV",
+	MOVFR2GR_S:  "MOVW",
+	MOVFR2GR_D:  "MOVV",
+	MOVGR2CF:    "MOVV",
+	MOVCF2GR:    "MOVV",
+	FLD_S:       "MOVF",
+	FLD_D:       "MOVD",
+	FST_S:       "MOVF",
+	FST_D:       "MOVD",
+}
diff -Naur delve-1.22.0.old/vendor/golang.org/x/arch/loong64/loong64asm/tables.go delve-1.22.0/vendor/golang.org/x/arch/loong64/loong64asm/tables.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/loong64/loong64asm/tables.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/loong64/loong64asm/tables.go	2024-06-08 19:31:17.327331240 +0800
@@ -0,0 +1,1514 @@
+// Generated by loong64spec LoongArch-Vol1-EN.pdf
+// DO NOT EDIT
+
+// Copyright 2023 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
+	CACOP
+	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
+	CSRRD
+	CSRWR
+	CSRXCHG
+	CTO_D
+	CTO_W
+	CTZ_D
+	CTZ_W
+	DBAR
+	DBCL
+	DIV_D
+	DIV_DU
+	DIV_W
+	DIV_WU
+	ERTN
+	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
+	IDLE
+	INVTLB
+	IOCSRRD_B
+	IOCSRRD_D
+	IOCSRRD_H
+	IOCSRRD_W
+	IOCSRWR_B
+	IOCSRWR_D
+	IOCSRWR_H
+	IOCSRWR_W
+	JIRL
+	LDDIR
+	LDGT_B
+	LDGT_D
+	LDGT_H
+	LDGT_W
+	LDLE_B
+	LDLE_D
+	LDLE_H
+	LDLE_W
+	LDPTE
+	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
+	TLBCLR
+	TLBFILL
+	TLBFLUSH
+	TLBRD
+	TLBSRCH
+	TLBWR
+	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",
+	CACOP:        "CACOP",
+	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",
+	CSRRD:        "CSRRD",
+	CSRWR:        "CSRWR",
+	CSRXCHG:      "CSRXCHG",
+	CTO_D:        "CTO.D",
+	CTO_W:        "CTO.W",
+	CTZ_D:        "CTZ.D",
+	CTZ_W:        "CTZ.W",
+	DBAR:         "DBAR",
+	DBCL:         "DBCL",
+	DIV_D:        "DIV.D",
+	DIV_DU:       "DIV.DU",
+	DIV_W:        "DIV.W",
+	DIV_WU:       "DIV.WU",
+	ERTN:         "ERTN",
+	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",
+	IDLE:         "IDLE",
+	INVTLB:       "INVTLB",
+	IOCSRRD_B:    "IOCSRRD.B",
+	IOCSRRD_D:    "IOCSRRD.D",
+	IOCSRRD_H:    "IOCSRRD.H",
+	IOCSRRD_W:    "IOCSRRD.W",
+	IOCSRWR_B:    "IOCSRWR.B",
+	IOCSRWR_D:    "IOCSRWR.D",
+	IOCSRWR_H:    "IOCSRWR.H",
+	IOCSRWR_W:    "IOCSRWR.W",
+	JIRL:         "JIRL",
+	LDDIR:        "LDDIR",
+	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",
+	LDPTE:        "LDPTE",
+	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",
+	TLBCLR:       "TLBCLR",
+	TLBFILL:      "TLBFILL",
+	TLBFLUSH:     "TLBFLUSH",
+	TLBRD:        "TLBRD",
+	TLBSRCH:      "TLBSRCH",
+	TLBWR:        "TLBWR",
+	XOR:          "XOR",
+	XORI:         "XORI",
+}
+
+var instFormats = [...]instFormat{
+	// ADDI.D rd, rj, si12
+	{mask: 0xffc00000, value: 0x02c00000, op: ADDI_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+	// ADDI.W rd, rj, si12
+	{mask: 0xffc00000, value: 0x02800000, 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}},
+	// ADD.D rd, rj, rk
+	{mask: 0xffff8000, value: 0x00108000, op: ADD_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// ADD.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00100000, op: ADD_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// ALSL.D rd, rj, rk, sa2
+	{mask: 0xfffe0000, value: 0x002c0000, op: ALSL_D, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}},
+	// ALSL.W rd, rj, rk, sa2
+	{mask: 0xfffe0000, value: 0x00040000, op: ALSL_W, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}},
+	// ALSL.WU rd, rj, rk, sa2
+	{mask: 0xfffe0000, value: 0x00060000, 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_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}},
+	// AMADD.W rd, rk, rj
+	{mask: 0xffff8000, value: 0x38610000, op: AMADD_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_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}},
+	// AMAND.W rd, rk, rj
+	{mask: 0xffff8000, value: 0x38620000, op: AMAND_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_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}},
+	// 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}},
+	// AMMIN.D rd, rk, rj
+	{mask: 0xffff8000, value: 0x38668000, op: AMMIN_D, 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}},
+	// 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}},
+	// AMOR.D rd, rk, rj
+	{mask: 0xffff8000, value: 0x38638000, op: AMOR_D, 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}},
+	// AMOR.W rd, rk, rj
+	{mask: 0xffff8000, value: 0x38630000, op: AMOR_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_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}},
+	// AMSWAP.W rd, rk, rj
+	{mask: 0xffff8000, value: 0x38600000, op: AMSWAP_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_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}},
+	// AMXOR.W rd, rk, rj
+	{mask: 0xffff8000, value: 0x38640000, op: AMXOR_W, args: instArgs{arg_rd, arg_rk, arg_rj}},
+	// AND rd, rj, rk
+	{mask: 0xffff8000, value: 0x00148000, op: AND, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// ANDI rd, rj, ui12
+	{mask: 0xffc00000, value: 0x03400000, op: ANDI, args: instArgs{arg_rd, arg_rj, arg_ui12_21_10}},
+	// ANDN rd, rj, rk
+	{mask: 0xffff8000, value: 0x00168000, op: ANDN, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// ASRTGT.D rj, rk
+	{mask: 0xffff801f, value: 0x00018000, op: ASRTGT_D, args: instArgs{arg_rj, arg_rk}},
+	// ASRTLE.D rj, rk
+	{mask: 0xffff801f, value: 0x00010000, 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: 0x00004800, op: BITREV_4B, args: instArgs{arg_rd, arg_rj}},
+	// BITREV.8B rd, rj
+	{mask: 0xfffffc00, value: 0x00004c00, op: BITREV_8B, args: instArgs{arg_rd, arg_rj}},
+	// BITREV.D rd, rj
+	{mask: 0xfffffc00, value: 0x00005400, op: BITREV_D, args: instArgs{arg_rd, arg_rj}},
+	// BITREV.W rd, rj
+	{mask: 0xfffffc00, value: 0x00005000, 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: 0x002a0000, op: BREAK, args: instArgs{arg_code_14_0}},
+	// BSTRINS.D rd, rj, msbd, lsbd
+	{mask: 0xffc00000, value: 0x00800000, op: BSTRINS_D, args: instArgs{arg_rd, arg_rj, arg_msbd, arg_lsbd}},
+	// BSTRINS.W rd, rj, msbw, lsbw
+	{mask: 0xffe08000, value: 0x00600000, op: BSTRINS_W, args: instArgs{arg_rd, arg_rj, arg_msbw, arg_lsbw}},
+	// BSTRPICK.D rd, rj, msbd, lsbd
+	{mask: 0xffc00000, value: 0x00c00000, op: BSTRPICK_D, args: instArgs{arg_rd, arg_rj, arg_msbd, arg_lsbd}},
+	// BSTRPICK.W rd, rj, msbw, lsbw
+	{mask: 0xffe08000, value: 0x00608000, op: BSTRPICK_W, args: instArgs{arg_rd, arg_rj, arg_msbw, arg_lsbw}},
+	// BYTEPICK.D rd, rj, rk, sa3
+	{mask: 0xfffc0000, value: 0x000c0000, op: BYTEPICK_D, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa3_17_15}},
+	// BYTEPICK.W rd, rj, rk, sa2
+	{mask: 0xfffe0000, value: 0x00080000, op: BYTEPICK_W, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}},
+	// CACOP code, rj, si12
+	{mask: 0xffc00000, value: 0x06000000, op: CACOP, args: instArgs{arg_code_4_0, arg_rj, arg_si12_21_10}},
+	// CLO.D rd, rj
+	{mask: 0xfffffc00, value: 0x00002000, op: CLO_D, args: instArgs{arg_rd, arg_rj}},
+	// CLO.W rd, rj
+	{mask: 0xfffffc00, value: 0x00001000, op: CLO_W, args: instArgs{arg_rd, arg_rj}},
+	// CLZ.D rd, rj
+	{mask: 0xfffffc00, value: 0x00002400, op: CLZ_D, args: instArgs{arg_rd, arg_rj}},
+	// CLZ.W rd, rj
+	{mask: 0xfffffc00, value: 0x00001400, op: CLZ_W, args: instArgs{arg_rd, arg_rj}},
+	// CPUCFG rd, rj
+	{mask: 0xfffffc00, value: 0x00006c00, op: CPUCFG, args: instArgs{arg_rd, arg_rj}},
+	// CRCC.W.B.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00260000, op: CRCC_W_B_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// CRCC.W.D.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00278000, op: CRCC_W_D_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// CRCC.W.H.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00268000, op: CRCC_W_H_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// CRCC.W.W.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00270000, op: CRCC_W_W_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// CRC.W.B.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00240000, op: CRC_W_B_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// CRC.W.D.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00258000, op: CRC_W_D_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// CRC.W.H.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00248000, op: CRC_W_H_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// CRC.W.W.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00250000, op: CRC_W_W_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// CSRRD rd, csr
+	{mask: 0xff0003e0, value: 0x04000000, op: CSRRD, args: instArgs{arg_rd, arg_csr_23_10}},
+	// CSRWR rd, csr
+	{mask: 0xff0003e0, value: 0x04000020, op: CSRWR, args: instArgs{arg_rd, arg_csr_23_10}},
+	// CSRXCHG rd, rj, csr
+	{mask: 0xff000000, value: 0x04000000, op: CSRXCHG, args: instArgs{arg_rd, arg_rj, arg_csr_23_10}},
+	// CTO.D rd, rj
+	{mask: 0xfffffc00, value: 0x00002800, op: CTO_D, args: instArgs{arg_rd, arg_rj}},
+	// CTO.W rd, rj
+	{mask: 0xfffffc00, value: 0x00001800, op: CTO_W, args: instArgs{arg_rd, arg_rj}},
+	// CTZ.D rd, rj
+	{mask: 0xfffffc00, value: 0x00002c00, op: CTZ_D, args: instArgs{arg_rd, arg_rj}},
+	// CTZ.W rd, rj
+	{mask: 0xfffffc00, value: 0x00001c00, op: CTZ_W, args: instArgs{arg_rd, arg_rj}},
+	// DBAR hint
+	{mask: 0xffff8000, value: 0x38720000, op: DBAR, args: instArgs{arg_hint_14_0}},
+	// DBCL code
+	{mask: 0xffff8000, value: 0x002a8000, op: DBCL, args: instArgs{arg_code_14_0}},
+	// DIV.D rd, rj, rk
+	{mask: 0xffff8000, value: 0x00220000, op: DIV_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// DIV.DU rd, rj, rk
+	{mask: 0xffff8000, value: 0x00230000, op: DIV_DU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// DIV.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00200000, op: DIV_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// DIV.WU rd, rj, rk
+	{mask: 0xffff8000, value: 0x00210000, op: DIV_WU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// ERTN
+	{mask: 0xffffffff, value: 0x06483800, op: ERTN, args: instArgs{}},
+	// EXT.W.B rd, rj
+	{mask: 0xfffffc00, value: 0x00005c00, op: EXT_W_B, args: instArgs{arg_rd, arg_rj}},
+	// EXT.W.H rd, rj
+	{mask: 0xfffffc00, value: 0x00005800, op: EXT_W_H, args: instArgs{arg_rd, arg_rj}},
+	// FABS.D fd, fj
+	{mask: 0xfffffc00, value: 0x01140800, op: FABS_D, args: instArgs{arg_fd, arg_fj}},
+	// FABS.S fd, fj
+	{mask: 0xfffffc00, value: 0x01140400, op: FABS_S, args: instArgs{arg_fd, arg_fj}},
+	// FADD.D fd, fj, fk
+	{mask: 0xffff8000, value: 0x01010000, op: FADD_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FADD.S fd, fj, fk
+	{mask: 0xffff8000, value: 0x01008000, op: FADD_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FCLASS.D fd, fj
+	{mask: 0xfffffc00, value: 0x01143800, op: FCLASS_D, args: instArgs{arg_fd, arg_fj}},
+	// FCLASS.S fd, fj
+	{mask: 0xfffffc00, value: 0x01143400, op: FCLASS_S, args: instArgs{arg_fd, arg_fj}},
+	// FCMP.CAF.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c200000, op: FCMP_CAF_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CAF.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c100000, op: FCMP_CAF_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CEQ.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c220000, op: FCMP_CEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CEQ.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c120000, op: FCMP_CEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CLE.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c230000, op: FCMP_CLE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CLE.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c130000, op: FCMP_CLE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CLT.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c210000, op: FCMP_CLT_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CLT.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c110000, op: FCMP_CLT_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CNE.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c280000, op: FCMP_CNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CNE.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c180000, op: FCMP_CNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.COR.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c2a0000, op: FCMP_COR_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.COR.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c1a0000, op: FCMP_COR_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CUEQ.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c260000, op: FCMP_CUEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CUEQ.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c160000, op: FCMP_CUEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CULE.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c270000, op: FCMP_CULE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CULE.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c170000, op: FCMP_CULE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CULT.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c250000, op: FCMP_CULT_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CULT.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c150000, op: FCMP_CULT_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CUNE.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c2c0000, op: FCMP_CUNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CUNE.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c1c0000, op: FCMP_CUNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CUN.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c240000, op: FCMP_CUN_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.CUN.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c140000, op: FCMP_CUN_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SAF.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c208000, op: FCMP_SAF_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SAF.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c108000, op: FCMP_SAF_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SEQ.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c228000, op: FCMP_SEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SEQ.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c128000, op: FCMP_SEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SLE.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c238000, op: FCMP_SLE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SLE.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c138000, op: FCMP_SLE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SLT.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c218000, op: FCMP_SLT_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SLT.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c118000, op: FCMP_SLT_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SNE.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c288000, op: FCMP_SNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SNE.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c188000, op: FCMP_SNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SOR.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c2a8000, op: FCMP_SOR_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SOR.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c1a8000, op: FCMP_SOR_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SUEQ.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c268000, op: FCMP_SUEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SUEQ.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c168000, op: FCMP_SUEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SULE.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c278000, op: FCMP_SULE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SULE.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c178000, op: FCMP_SULE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SULT.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c258000, op: FCMP_SULT_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SULT.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c158000, op: FCMP_SULT_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SUNE.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c2c8000, op: FCMP_SUNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SUNE.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c1c8000, op: FCMP_SUNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SUN.D cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c248000, op: FCMP_SUN_D, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCMP.SUN.S cd, fj, fk
+	{mask: 0xffff8018, value: 0x0c148000, op: FCMP_SUN_S, args: instArgs{arg_cd, arg_fj, arg_fk}},
+	// FCOPYSIGN.D fd, fj, fk
+	{mask: 0xffff8000, value: 0x01130000, op: FCOPYSIGN_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FCOPYSIGN.S fd, fj, fk
+	{mask: 0xffff8000, value: 0x01128000, op: FCOPYSIGN_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FCVT.D.S fd, fj
+	{mask: 0xfffffc00, value: 0x01192400, op: FCVT_D_S, args: instArgs{arg_fd, arg_fj}},
+	// FCVT.S.D fd, fj
+	{mask: 0xfffffc00, value: 0x01191800, op: FCVT_S_D, args: instArgs{arg_fd, arg_fj}},
+	// FDIV.D fd, fj, fk
+	{mask: 0xffff8000, value: 0x01070000, op: FDIV_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FDIV.S fd, fj, fk
+	{mask: 0xffff8000, value: 0x01068000, op: FDIV_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FFINT.D.L fd, fj
+	{mask: 0xfffffc00, value: 0x011d2800, op: FFINT_D_L, args: instArgs{arg_fd, arg_fj}},
+	// FFINT.D.W fd, fj
+	{mask: 0xfffffc00, value: 0x011d2000, op: FFINT_D_W, args: instArgs{arg_fd, arg_fj}},
+	// FFINT.S.L fd, fj
+	{mask: 0xfffffc00, value: 0x011d1800, op: FFINT_S_L, args: instArgs{arg_fd, arg_fj}},
+	// FFINT.S.W fd, fj
+	{mask: 0xfffffc00, value: 0x011d1000, op: FFINT_S_W, args: instArgs{arg_fd, arg_fj}},
+	// 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}},
+	// 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}},
+	// FLOGB.D fd, fj
+	{mask: 0xfffffc00, value: 0x01142800, op: FLOGB_D, args: instArgs{arg_fd, arg_fj}},
+	// FLOGB.S fd, fj
+	{mask: 0xfffffc00, value: 0x01142400, op: FLOGB_S, args: instArgs{arg_fd, arg_fj}},
+	// FMADD.D fd, fj, fk, fa
+	{mask: 0xfff00000, value: 0x08200000, op: FMADD_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+	// FMADD.S fd, fj, fk, fa
+	{mask: 0xfff00000, value: 0x08100000, op: FMADD_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+	// FMAXA.D fd, fj, fk
+	{mask: 0xffff8000, value: 0x010d0000, op: FMAXA_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FMAXA.S fd, fj, fk
+	{mask: 0xffff8000, value: 0x010c8000, op: FMAXA_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FMAX.D fd, fj, fk
+	{mask: 0xffff8000, value: 0x01090000, op: FMAX_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FMAX.S fd, fj, fk
+	{mask: 0xffff8000, value: 0x01088000, op: FMAX_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FMINA.D fd, fj, fk
+	{mask: 0xffff8000, value: 0x010f0000, op: FMINA_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FMINA.S fd, fj, fk
+	{mask: 0xffff8000, value: 0x010e8000, op: FMINA_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FMIN.D fd, fj, fk
+	{mask: 0xffff8000, value: 0x010b0000, op: FMIN_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FMIN.S fd, fj, fk
+	{mask: 0xffff8000, value: 0x010a8000, op: FMIN_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FMOV.D fd, fj
+	{mask: 0xfffffc00, value: 0x01149800, op: FMOV_D, args: instArgs{arg_fd, arg_fj}},
+	// FMOV.S fd, fj
+	{mask: 0xfffffc00, value: 0x01149400, op: FMOV_S, args: instArgs{arg_fd, arg_fj}},
+	// FMSUB.D fd, fj, fk, fa
+	{mask: 0xfff00000, value: 0x08600000, op: FMSUB_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+	// FMSUB.S fd, fj, fk, fa
+	{mask: 0xfff00000, value: 0x08500000, op: FMSUB_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+	// FMUL.D fd, fj, fk
+	{mask: 0xffff8000, value: 0x01050000, op: FMUL_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FMUL.S fd, fj, fk
+	{mask: 0xffff8000, value: 0x01048000, op: FMUL_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FNEG.D fd, fj
+	{mask: 0xfffffc00, value: 0x01141800, op: FNEG_D, args: instArgs{arg_fd, arg_fj}},
+	// FNEG.S fd, fj
+	{mask: 0xfffffc00, value: 0x01141400, op: FNEG_S, args: instArgs{arg_fd, arg_fj}},
+	// FNMADD.D fd, fj, fk, fa
+	{mask: 0xfff00000, value: 0x08a00000, op: FNMADD_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+	// FNMADD.S fd, fj, fk, fa
+	{mask: 0xfff00000, value: 0x08900000, op: FNMADD_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+	// FNMSUB.D fd, fj, fk, fa
+	{mask: 0xfff00000, value: 0x08e00000, op: FNMSUB_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+	// FNMSUB.S fd, fj, fk, fa
+	{mask: 0xfff00000, value: 0x08d00000, op: FNMSUB_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}},
+	// FRECIP.D fd, fj
+	{mask: 0xfffffc00, value: 0x01145800, op: FRECIP_D, args: instArgs{arg_fd, arg_fj}},
+	// FRECIP.S fd, fj
+	{mask: 0xfffffc00, value: 0x01145400, op: FRECIP_S, args: instArgs{arg_fd, arg_fj}},
+	// FRINT.D fd, fj
+	{mask: 0xfffffc00, value: 0x011e4800, op: FRINT_D, args: instArgs{arg_fd, arg_fj}},
+	// FRINT.S fd, fj
+	{mask: 0xfffffc00, value: 0x011e4400, op: FRINT_S, args: instArgs{arg_fd, arg_fj}},
+	// FRSQRT.D fd, fj
+	{mask: 0xfffffc00, value: 0x01146800, op: FRSQRT_D, args: instArgs{arg_fd, arg_fj}},
+	// FRSQRT.S fd, fj
+	{mask: 0xfffffc00, value: 0x01146400, op: FRSQRT_S, args: instArgs{arg_fd, arg_fj}},
+	// FSCALEB.D fd, fj, fk
+	{mask: 0xffff8000, value: 0x01110000, op: FSCALEB_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FSCALEB.S fd, fj, fk
+	{mask: 0xffff8000, value: 0x01108000, op: FSCALEB_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FSEL fd, fj, fk, ca
+	{mask: 0xfffc0000, value: 0x0d000000, op: FSEL, args: instArgs{arg_fd, arg_fj, arg_fk, arg_ca}},
+	// FSQRT.D fd, fj
+	{mask: 0xfffffc00, value: 0x01144800, op: FSQRT_D, args: instArgs{arg_fd, arg_fj}},
+	// FSQRT.S fd, fj
+	{mask: 0xfffffc00, value: 0x01144400, op: FSQRT_S, args: instArgs{arg_fd, arg_fj}},
+	// 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}},
+	// 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}},
+	// FSUB.D fd, fj, fk
+	{mask: 0xffff8000, value: 0x01030000, op: FSUB_D, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FSUB.S fd, fj, fk
+	{mask: 0xffff8000, value: 0x01028000, op: FSUB_S, args: instArgs{arg_fd, arg_fj, arg_fk}},
+	// FTINTRM.L.D fd, fj
+	{mask: 0xfffffc00, value: 0x011a2800, op: FTINTRM_L_D, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRM.L.S fd, fj
+	{mask: 0xfffffc00, value: 0x011a2400, op: FTINTRM_L_S, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRM.W.D fd, fj
+	{mask: 0xfffffc00, value: 0x011a0800, op: FTINTRM_W_D, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRM.W.S fd, fj
+	{mask: 0xfffffc00, value: 0x011a0400, op: FTINTRM_W_S, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRNE.L.D fd, fj
+	{mask: 0xfffffc00, value: 0x011ae800, op: FTINTRNE_L_D, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRNE.L.S fd, fj
+	{mask: 0xfffffc00, value: 0x011ae400, op: FTINTRNE_L_S, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRNE.W.D fd, fj
+	{mask: 0xfffffc00, value: 0x011ac800, op: FTINTRNE_W_D, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRNE.W.S fd, fj
+	{mask: 0xfffffc00, value: 0x011ac400, op: FTINTRNE_W_S, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRP.L.D fd, fj
+	{mask: 0xfffffc00, value: 0x011a6800, op: FTINTRP_L_D, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRP.L.S fd, fj
+	{mask: 0xfffffc00, value: 0x011a6400, op: FTINTRP_L_S, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRP.W.D fd, fj
+	{mask: 0xfffffc00, value: 0x011a4800, op: FTINTRP_W_D, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRP.W.S fd, fj
+	{mask: 0xfffffc00, value: 0x011a4400, op: FTINTRP_W_S, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRZ.L.D fd, fj
+	{mask: 0xfffffc00, value: 0x011aa800, op: FTINTRZ_L_D, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRZ.L.S fd, fj
+	{mask: 0xfffffc00, value: 0x011aa400, op: FTINTRZ_L_S, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRZ.W.D fd, fj
+	{mask: 0xfffffc00, value: 0x011a8800, op: FTINTRZ_W_D, args: instArgs{arg_fd, arg_fj}},
+	// FTINTRZ.W.S fd, fj
+	{mask: 0xfffffc00, value: 0x011a8400, op: FTINTRZ_W_S, args: instArgs{arg_fd, arg_fj}},
+	// FTINT.L.D fd, fj
+	{mask: 0xfffffc00, value: 0x011b2800, op: FTINT_L_D, args: instArgs{arg_fd, arg_fj}},
+	// FTINT.L.S fd, fj
+	{mask: 0xfffffc00, value: 0x011b2400, op: FTINT_L_S, args: instArgs{arg_fd, arg_fj}},
+	// FTINT.W.D fd, fj
+	{mask: 0xfffffc00, value: 0x011b0800, op: FTINT_W_D, args: instArgs{arg_fd, arg_fj}},
+	// FTINT.W.S fd, fj
+	{mask: 0xfffffc00, value: 0x011b0400, op: FTINT_W_S, args: instArgs{arg_fd, arg_fj}},
+	// IBAR hint
+	{mask: 0xffff8000, value: 0x38728000, op: IBAR, args: instArgs{arg_hint_14_0}},
+	// IDLE level
+	{mask: 0xffff8000, value: 0x06488000, op: IDLE, args: instArgs{arg_level_14_0}},
+	// INVTLB op, rj, rk
+	{mask: 0xffff8000, value: 0x06498000, op: INVTLB, args: instArgs{arg_op_4_0, arg_rj, arg_rk}},
+	// IOCSRRD.B rd, rj
+	{mask: 0xfffffc00, value: 0x06480000, op: IOCSRRD_B, args: instArgs{arg_rd, arg_rj}},
+	// IOCSRRD.D rd, rj
+	{mask: 0xfffffc00, value: 0x06480c00, op: IOCSRRD_D, args: instArgs{arg_rd, arg_rj}},
+	// IOCSRRD.H rd, rj
+	{mask: 0xfffffc00, value: 0x06480400, op: IOCSRRD_H, args: instArgs{arg_rd, arg_rj}},
+	// IOCSRRD.W rd, rj
+	{mask: 0xfffffc00, value: 0x06480800, op: IOCSRRD_W, args: instArgs{arg_rd, arg_rj}},
+	// IOCSRWR.B rd, rj
+	{mask: 0xfffffc00, value: 0x06481000, op: IOCSRWR_B, args: instArgs{arg_rd, arg_rj}},
+	// IOCSRWR.D rd, rj
+	{mask: 0xfffffc00, value: 0x06481c00, op: IOCSRWR_D, args: instArgs{arg_rd, arg_rj}},
+	// IOCSRWR.H rd, rj
+	{mask: 0xfffffc00, value: 0x06481400, op: IOCSRWR_H, args: instArgs{arg_rd, arg_rj}},
+	// IOCSRWR.W rd, rj
+	{mask: 0xfffffc00, value: 0x06481800, op: IOCSRWR_W, args: instArgs{arg_rd, arg_rj}},
+	// JIRL rd, rj, offs
+	{mask: 0xfc000000, value: 0x4c000000, op: JIRL, args: instArgs{arg_rd, arg_rj, arg_offset_15_0}},
+	// LDDIR rd, rj, level
+	{mask: 0xfffc0000, value: 0x06400000, op: LDDIR, args: instArgs{arg_rd, arg_rj, arg_level_17_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}},
+	// LDPTE rj, seq
+	{mask: 0xfffc001f, value: 0x06440000, op: LDPTE, args: instArgs{arg_rj, arg_seq_17_10}},
+	// 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}},
+	// 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}},
+	// 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: 0x03000000, op: LU52I_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+	// MASKEQZ rd, rj, rk
+	{mask: 0xffff8000, value: 0x00130000, op: MASKEQZ, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MASKNEZ rd, rj, rk
+	{mask: 0xffff8000, value: 0x00138000, op: MASKNEZ, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MOD.D rd, rj, rk
+	{mask: 0xffff8000, value: 0x00228000, op: MOD_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MOD.DU rd, rj, rk
+	{mask: 0xffff8000, value: 0x00238000, op: MOD_DU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MOD.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00208000, op: MOD_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MOD.WU rd, rj, rk
+	{mask: 0xffff8000, value: 0x00218000, op: MOD_WU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MOVCF2FR fd, cj
+	{mask: 0xffffff00, value: 0x0114d400, op: MOVCF2FR, args: instArgs{arg_fd, arg_cj}},
+	// MOVCF2GR rd, cj
+	{mask: 0xffffff00, value: 0x0114dc00, op: MOVCF2GR, args: instArgs{arg_rd, arg_cj}},
+	// MOVFCSR2GR rd, fcsr
+	{mask: 0xfffffc00, value: 0x0114c800, op: MOVFCSR2GR, args: instArgs{arg_rd, arg_fcsr_9_5}},
+	// MOVFR2CF cd, fj
+	{mask: 0xfffffc18, value: 0x0114d000, op: MOVFR2CF, args: instArgs{arg_cd, arg_fj}},
+	// MOVFR2GR.D rd, fj
+	{mask: 0xfffffc00, value: 0x0114b800, op: MOVFR2GR_D, args: instArgs{arg_rd, arg_fj}},
+	// MOVFR2GR.S rd, fj
+	{mask: 0xfffffc00, value: 0x0114b400, op: MOVFR2GR_S, args: instArgs{arg_rd, arg_fj}},
+	// MOVFRH2GR.S rd, fj
+	{mask: 0xfffffc00, value: 0x0114bc00, op: MOVFRH2GR_S, args: instArgs{arg_rd, arg_fj}},
+	// MOVGR2CF cd, rj
+	{mask: 0xfffffc18, value: 0x0114d800, op: MOVGR2CF, args: instArgs{arg_cd, arg_rj}},
+	// MOVGR2FCSR fcsr, rj
+	{mask: 0xfffffc00, value: 0x0114c000, op: MOVGR2FCSR, args: instArgs{arg_fcsr_4_0, arg_rj}},
+	// MOVGR2FRH.W fd, rj
+	{mask: 0xfffffc00, value: 0x0114ac00, op: MOVGR2FRH_W, args: instArgs{arg_fd, arg_rj}},
+	// MOVGR2FR.D fd, rj
+	{mask: 0xfffffc00, value: 0x0114a800, op: MOVGR2FR_D, args: instArgs{arg_fd, arg_rj}},
+	// MOVGR2FR.W fd, rj
+	{mask: 0xfffffc00, value: 0x0114a400, op: MOVGR2FR_W, args: instArgs{arg_fd, arg_rj}},
+	// MULH.D rd, rj, rk
+	{mask: 0xffff8000, value: 0x001e0000, op: MULH_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MULH.DU rd, rj, rk
+	{mask: 0xffff8000, value: 0x001e8000, op: MULH_DU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MULH.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x001c8000, op: MULH_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MULH.WU rd, rj, rk
+	{mask: 0xffff8000, value: 0x001d0000, op: MULH_WU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MULW.D.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x001f0000, op: MULW_D_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MULW.D.WU rd, rj, rk
+	{mask: 0xffff8000, value: 0x001f8000, op: MULW_D_WU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MUL.D rd, rj, rk
+	{mask: 0xffff8000, value: 0x001d8000, op: MUL_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// MUL.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x001c0000, op: MUL_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// NOR rd, rj, rk
+	{mask: 0xffff8000, value: 0x00140000, op: NOR, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// OR rd, rj, rk
+	{mask: 0xffff8000, value: 0x00150000, op: OR, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// ORI rd, rj, ui12
+	{mask: 0xffc00000, value: 0x03800000, op: ORI, args: instArgs{arg_rd, arg_rj, arg_ui12_21_10}},
+	// ORN rd, rj, rk
+	{mask: 0xffff8000, value: 0x00160000, 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_hint_4_0, arg_rj, arg_si12_21_10}},
+	// PRELDX hint, rj, rk
+	{mask: 0xffff8000, value: 0x382c0000, op: PRELDX, args: instArgs{arg_hint_4_0, arg_rj, arg_rk}},
+	// RDTIMEH.W rd, rj
+	{mask: 0xfffffc00, value: 0x00006400, op: RDTIMEH_W, args: instArgs{arg_rd, arg_rj}},
+	// RDTIMEL.W rd, rj
+	{mask: 0xfffffc00, value: 0x00006000, op: RDTIMEL_W, args: instArgs{arg_rd, arg_rj}},
+	// RDTIME.D rd, rj
+	{mask: 0xfffffc00, value: 0x00006800, op: RDTIME_D, args: instArgs{arg_rd, arg_rj}},
+	// REVB.2H rd, rj
+	{mask: 0xfffffc00, value: 0x00003000, op: REVB_2H, args: instArgs{arg_rd, arg_rj}},
+	// REVB.2W rd, rj
+	{mask: 0xfffffc00, value: 0x00003800, op: REVB_2W, args: instArgs{arg_rd, arg_rj}},
+	// REVB.4H rd, rj
+	{mask: 0xfffffc00, value: 0x00003400, op: REVB_4H, args: instArgs{arg_rd, arg_rj}},
+	// REVB.D rd, rj
+	{mask: 0xfffffc00, value: 0x00003c00, op: REVB_D, args: instArgs{arg_rd, arg_rj}},
+	// REVH.2W rd, rj
+	{mask: 0xfffffc00, value: 0x00004000, op: REVH_2W, args: instArgs{arg_rd, arg_rj}},
+	// REVH.D rd, rj
+	{mask: 0xfffffc00, value: 0x00004400, op: REVH_D, args: instArgs{arg_rd, arg_rj}},
+	// ROTRI.D rd, rj, ui6
+	{mask: 0xffff0000, value: 0x004d0000, op: ROTRI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}},
+	// ROTRI.W rd, rj, ui5
+	{mask: 0xffff8000, value: 0x004c8000, op: ROTRI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}},
+	// ROTR.D rd, rj, rk
+	{mask: 0xffff8000, value: 0x001b8000, op: ROTR_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// ROTR.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x001b0000, op: ROTR_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// 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}},
+	// SLLI.D rd, rj, ui6
+	{mask: 0xffff0000, value: 0x00410000, op: SLLI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}},
+	// SLLI.W rd, rj, ui5
+	{mask: 0xffff8000, value: 0x00408000, op: SLLI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}},
+	// SLL.D rd, rj, rk
+	{mask: 0xffff8000, value: 0x00188000, op: SLL_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// SLL.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00170000, op: SLL_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// SLT rd, rj, rk
+	{mask: 0xffff8000, value: 0x00120000, op: SLT, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// SLTI rd, rj, si12
+	{mask: 0xffc00000, value: 0x02000000, op: SLTI, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+	// SLTU rd, rj, rk
+	{mask: 0xffff8000, value: 0x00128000, op: SLTU, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// SLTUI rd, rj, si12
+	{mask: 0xffc00000, value: 0x02400000, op: SLTUI, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}},
+	// SRAI.D rd, rj, ui6
+	{mask: 0xffff0000, value: 0x00490000, op: SRAI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}},
+	// SRAI.W rd, rj, ui5
+	{mask: 0xffff8000, value: 0x00488000, op: SRAI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}},
+	// SRA.D rd, rj, rk
+	{mask: 0xffff8000, value: 0x00198000, op: SRA_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// SRA.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00180000, op: SRA_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// SRLI.D rd, rj, ui6
+	{mask: 0xffff0000, value: 0x00450000, op: SRLI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}},
+	// SRLI.W rd, rj, ui5
+	{mask: 0xffff8000, value: 0x00448000, op: SRLI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}},
+	// SRL.D rd, rj, rk
+	{mask: 0xffff8000, value: 0x00190000, op: SRL_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// SRL.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00178000, op: SRL_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// 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}},
+	// 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}},
+	// SUB.D rd, rj, rk
+	{mask: 0xffff8000, value: 0x00118000, op: SUB_D, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// SUB.W rd, rj, rk
+	{mask: 0xffff8000, value: 0x00110000, op: SUB_W, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// SYSCALL code
+	{mask: 0xffff8000, value: 0x002b0000, op: SYSCALL, args: instArgs{arg_code_14_0}},
+	// TLBCLR
+	{mask: 0xffffffff, value: 0x06482000, op: TLBCLR, args: instArgs{}},
+	// TLBFILL
+	{mask: 0xffffffff, value: 0x06483400, op: TLBFILL, args: instArgs{}},
+	// TLBFLUSH
+	{mask: 0xffffffff, value: 0x06482400, op: TLBFLUSH, args: instArgs{}},
+	// TLBRD
+	{mask: 0xffffffff, value: 0x06482c00, op: TLBRD, args: instArgs{}},
+	// TLBSRCH
+	{mask: 0xffffffff, value: 0x06482800, op: TLBSRCH, args: instArgs{}},
+	// TLBWR
+	{mask: 0xffffffff, value: 0x06483000, op: TLBWR, args: instArgs{}},
+	// XOR rd, rj, rk
+	{mask: 0xffff8000, value: 0x00158000, op: XOR, args: instArgs{arg_rd, arg_rj, arg_rk}},
+	// XORI rd, rj, ui12
+	{mask: 0xffc00000, value: 0x03c00000, op: XORI, args: instArgs{arg_rd, arg_rj, arg_ui12_21_10}},
+}
