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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/cmd/dlv/dlv_test.go	2024-08-01 19:32:55.250780610 +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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/Documentation/backend_test_health.md	2024-08-01 19:32:55.251780652 +0800
@@ -29,12 +29,19 @@
 	* 1 broken in linux ppc64le
 * linux/ppc64le/native/pie skipped = 3
 	* 3 broken - pie mode
+* linux/riscv64 skipped = 2
+	* 1 broken - cgo stacktraces
+	* 1 not working on linux/riscv64
 * pie skipped = 2
 	* 2 upstream issue - https://github.com/golang/go/issues/29322
 * ppc64le skipped = 11
 	* 6 broken
 	* 1 broken - global variable symbolication
 	* 4 not implemented
+* riscv64 skipped = 6
+	* 2 broken
+	* 1 broken - global variable symbolication
+	* 3 not implemented
 * windows skipped = 6
 	* 1 broken
 	* 2 not working on windows
diff -Naur delve-1.22.0.old/_fixtures/asmnilptr/main_riscv64.s delve-1.22.0/_fixtures/asmnilptr/main_riscv64.s
--- delve-1.22.0.old/_fixtures/asmnilptr/main_riscv64.s	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/_fixtures/asmnilptr/main_riscv64.s	2024-08-01 19:32:55.251780652 +0800
@@ -0,0 +1,7 @@
+#include "textflag.h"
+
+TEXT ·asmFunc(SB),0,$0-16
+	MOV arg+0(FP), R5
+	MOV (R5), R5
+	MOV 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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/_fixtures/cgostacktest/hello.c	2024-08-01 19:32:55.251780652 +0800
@@ -14,6 +14,8 @@
 #else
 #define BREAKPOINT asm("brk 0;")
 #endif
+#elif __riscv
+#define BREAKPOINT asm("ebreak;")
 #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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/_fixtures/testvariablescgo/test.c	2024-08-01 19:32:55.252780695 +0800
@@ -12,6 +12,8 @@
 #else
 #define BREAKPOINT asm("brk 0;")
 #endif
+#elif __riscv
+#define BREAKPOINT asm("ebreak;")
 #endif
 
 #define N 100
@@ -37,6 +39,6 @@
 	strcpy(s, s0);
 
 	BREAKPOINT;
-	
+
 	printf("%s %s %p %p\n", s, longstring, v, v_align_check);
 }
diff -Naur delve-1.22.0.old/pkg/dwarf/regnum/riscv64.go delve-1.22.0/pkg/dwarf/regnum/riscv64.go
--- delve-1.22.0.old/pkg/dwarf/regnum/riscv64.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/dwarf/regnum/riscv64.go	2024-08-01 19:32:55.252780695 +0800
@@ -0,0 +1,92 @@
+package regnum
+
+import "fmt"
+
+// The mapping between hardware registers and DWARF registers, See
+// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-dwarf.adoc
+
+const (
+	// Integer Registers
+	RISCV64_X0 = 0
+	// Link Register
+	RISCV64_LR = 1
+	// Stack Pointer
+	RISCV64_SP = 2
+	RISCV64_GP = 3
+	RISCV64_TP = 4
+	RISCV64_T0 = 5
+	RISCV64_T1 = 6
+	RISCV64_T2 = 7
+	RISCV64_S0 = 8
+	// Frame Pointer
+	RISCV64_FP  = RISCV64_S0
+	RISCV64_S1  = 9
+	RISCV64_A0  = 10
+	RISCV64_A1  = 11
+	RISCV64_A2  = 12
+	RISCV64_A3  = 13
+	RISCV64_A4  = 14
+	RISCV64_A5  = 15
+	RISCV64_A6  = 16
+	RISCV64_A7  = 17
+	RISCV64_S2  = 18
+	RISCV64_S3  = 19
+	RISCV64_S4  = 20
+	RISCV64_S5  = 21
+	RISCV64_S6  = 22
+	RISCV64_S7  = 23
+	RISCV64_S8  = 24
+	RISCV64_S9  = 25
+	RISCV64_S10 = 26
+	// G Register
+	RISCV64_S11 = 27
+	RISCV64_T3  = 28
+	RISCV64_T4  = 29
+	RISCV64_T5  = 30
+	RISCV64_T6  = 31
+
+	RISCV64_X31 = RISCV64_T6
+
+	// Floating-point Registers
+	RISCV64_F0  = 32
+	RISCV64_F31 = 63
+
+	// Not defined in DWARF specification
+	RISCV64_PC = 65
+
+	_RISC64_MaxRegNum = RISCV64_PC
+)
+
+func RISCV64ToName(num uint64) string {
+	switch {
+	case num <= RISCV64_X31:
+		return fmt.Sprintf("X%d", num)
+
+	case num >= RISCV64_F0 && num <= RISCV64_F31:
+		return fmt.Sprintf("F%d", num)
+
+	case num == RISCV64_PC:
+		return fmt.Sprintf("PC")
+
+	default:
+		return fmt.Sprintf("Unknown%d", num)
+	}
+}
+
+func RISCV64MaxRegNum() uint64 {
+	return _RISC64_MaxRegNum
+}
+
+var RISCV64NameToDwarf = func() map[string]int {
+	r := make(map[string]int)
+	for i := 0; i <= 31; i++ {
+		r[fmt.Sprintf("x%d", i)] = RISCV64_X0 + i
+	}
+	r[fmt.Sprintf("pc")] = RISCV64_PC
+
+	for i := 0; i <= 31; i++ {
+		r[fmt.Sprintf("f%d", i)] = RISCV64_F0 + i
+	}
+
+	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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/gobuild/gobuild.go	2024-08-01 19:32:55.252780695 +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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/bininfo.go	2024-08-01 19:32:55.253780737 +0800
@@ -130,6 +130,7 @@
 		elf.EM_AARCH64: true,
 		elf.EM_386:     true,
 		elf.EM_PPC64:   true,
+		elf.EM_RISCV:   true,
 	}
 
 	supportedWindowsArch = map[_PEMachine]bool{
@@ -690,6 +691,8 @@
 		r.Arch = ARM64Arch(goos)
 	case "ppc64le":
 		r.Arch = PPC64LEArch(goos)
+	case "riscv64":
+		r.Arch = RISCV64Arch(goos)
 	}
 	return r
 }
@@ -1692,6 +1695,9 @@
 	case elf.EM_PPC64:
 		_ = getSymbol(image, bi.logger, exe, "runtime.tls_g")
 
+	case elf.EM_RISCV:
+		_ = getSymbol(image, bi.logger, exe, "runtime.tls_g")
+
 	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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/core/linux_core.go	2024-08-01 19:32:55.255780822 +0800
@@ -39,6 +39,7 @@
 const (
 	_EM_AARCH64          = 183
 	_EM_X86_64           = 62
+	_EM_RISCV            = 243
 	_ARM_FP_HEADER_START = 512
 )
 
@@ -48,6 +49,8 @@
 	var currentThread proc.Thread
 	var lastThreadAMD *linuxAMD64Thread
 	var lastThreadARM *linuxARM64Thread
+	var lastThreadRISCV *linuxRISCV64Thread
+
 	for _, note := range notes {
 		switch note.Type {
 		case elf.NT_PRSTATUS:
@@ -65,12 +68,23 @@
 				if currentThread == nil {
 					currentThread = p.Threads[int(t.Pid)]
 				}
+			} else if machineType == _EM_RISCV {
+				t := note.Desc.(*linuxPrStatusRISCV64)
+				lastThreadRISCV = &linuxRISCV64Thread{linutil.RISCV64Registers{Regs: &t.Reg}, t}
+				p.Threads[int(t.Pid)] = &thread{lastThreadRISCV, 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_RISCV {
+				if lastThreadRISCV != nil {
+					lastThreadRISCV.regs.Fpregs = note.Desc.(*linutil.RISCV64PtraceFpRegs).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_RISCV:
+			bi = proc.NewBinaryInfo("linux", "riscv64")
 		default:
 			return nil, nil, fmt.Errorf("unsupported machine type")
 		}
@@ -180,6 +196,11 @@
 	t    *linuxPrStatusARM64
 }
 
+type linuxRISCV64Thread struct {
+	regs linutil.RISCV64Registers
+	t    *linuxPrStatusRISCV64
+}
+
 func (t *linuxAMD64Thread) registers() (proc.Registers, error) {
 	var r linutil.AMD64Registers
 	r.Regs = t.regs.Regs
@@ -194,6 +215,13 @@
 	return &r, nil
 }
 
+func (t *linuxRISCV64Thread) registers() (proc.Registers, error) {
+	var r linutil.RISCV64Registers
+	r.Regs = t.regs.Regs
+	r.Fpregs = t.regs.Fpregs
+	return &r, nil
+}
+
 func (t *linuxAMD64Thread) pid() int {
 	return int(t.t.Pid)
 }
@@ -202,6 +230,10 @@
 	return int(t.t.Pid)
 }
 
+func (t *linuxRISCV64Thread) pid() int {
+	return int(t.t.Pid)
+}
+
 // Note is a note from the PT_NOTE prog.
 // Relevant types:
 // - NT_FILE: File mapping information, e.g. program text mappings. Desc is a LinuxNTFile.
@@ -285,6 +317,8 @@
 			note.Desc = &linuxPrStatusAMD64{}
 		case _EM_AARCH64:
 			note.Desc = &linuxPrStatusARM64{}
+		case _EM_RISCV:
+			note.Desc = &linuxPrStatusRISCV64{}
 		default:
 			return nil, fmt.Errorf("unsupported machine type")
 		}
@@ -332,6 +366,15 @@
 			}
 			note.Desc = fpregs
 		}
+
+		if machineType == _EM_RISCV {
+			fpregs := &linutil.RISCV64PtraceFpRegs{}
+			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)
@@ -446,6 +489,19 @@
 	Fpvalid                      int32
 }
 
+// LinuxPrStatusRISCV64 is a copy of the prstatus kernel struct.
+type linuxPrStatusRISCV64 struct {
+	Siginfo                      linuxSiginfo
+	Cursig                       uint16
+	_                            [2]uint8
+	Sigpend                      uint64
+	Sighold                      uint64
+	Pid, Ppid, Pgrp, Sid         int32
+	Utime, Stime, CUtime, CStime linuxCoreTimeval
+	Reg                          linutil.RISCV64PtraceRegs
+	Fpvalid                      int32
+}
+
 // LinuxSiginfo is a copy of the
 // siginfo kernel struct.
 type linuxSiginfo 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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/dump.go	2024-08-01 19:32:55.256780865 +0800
@@ -138,6 +138,8 @@
 		fhdr.Machine = elf.EM_AARCH64
 	case "ppc64le":
 		fhdr.Machine = elf.EM_PPC64
+	case "riscv64":
+		fhdr.Machine = elf.EM_RISCV
 	default:
 		panic("not implemented")
 	}
diff -Naur delve-1.22.0.old/pkg/proc/linutil/regs_riscv64_arch.go delve-1.22.0/pkg/proc/linutil/regs_riscv64_arch.go
--- delve-1.22.0.old/pkg/proc/linutil/regs_riscv64_arch.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/proc/linutil/regs_riscv64_arch.go	2024-08-01 19:32:55.256780865 +0800
@@ -0,0 +1,386 @@
+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"
+	"golang.org/x/arch/riscv64/riscv64asm"
+)
+
+// Regs is wrapper for sys.PtraceRegs
+type RISCV64Registers struct {
+	Regs       *RISCV64PtraceRegs // general-purpose registers & pc
+	iscgo      bool
+	tp_tls     uint64
+	Fpregs     []proc.Register // Formatted floating-point registers
+	Fpregset   []byte          // holding all floating-point register values
+	loadFpRegs func(*RISCV64Registers) error
+}
+
+func NewRISCV64Registers(regs *RISCV64PtraceRegs, iscgo bool, tp_tls uint64,
+	loadFpRegs func(*RISCV64Registers) error) *RISCV64Registers {
+	return &RISCV64Registers{
+		Regs:       regs,
+		iscgo:      iscgo,
+		tp_tls:     tp_tls,
+		loadFpRegs: loadFpRegs,
+	}
+}
+
+// RISCV64PtraceRegs is the struct used by the linux kernel to return the
+// general purpose registers for RISC-V CPUs.
+type RISCV64PtraceRegs struct {
+	Pc  uint64
+	Ra  uint64
+	Sp  uint64
+	Gp  uint64
+	Tp  uint64
+	T0  uint64
+	T1  uint64
+	T2  uint64
+	S0  uint64
+	S1  uint64
+	A0  uint64
+	A1  uint64
+	A2  uint64
+	A3  uint64
+	A4  uint64
+	A5  uint64
+	A6  uint64
+	A7  uint64
+	S2  uint64
+	S3  uint64
+	S4  uint64
+	S5  uint64
+	S6  uint64
+	S7  uint64
+	S8  uint64
+	S9  uint64
+	S10 uint64
+	S11 uint64
+	T3  uint64
+	T4  uint64
+	T5  uint64
+	T6  uint64
+}
+
+// Slice returns the registers as a list of (name, value) pairs.
+func (r *RISCV64Registers) Slice(floatingPoint bool) ([]proc.Register, error) {
+	var regs64 = []struct {
+		k string
+		v uint64
+	}{
+		{"X1", r.Regs.Ra},
+		{"X2", r.Regs.Sp},
+		{"X3", r.Regs.Gp},
+		{"X4", r.Regs.Tp},
+		{"X5", r.Regs.T0},
+		{"X6", r.Regs.T1},
+		{"X7", r.Regs.T2},
+		{"X8", r.Regs.S0},
+		{"X9", r.Regs.S1},
+		{"X10", r.Regs.A0},
+		{"X11", r.Regs.A1},
+		{"X12", r.Regs.A2},
+		{"X13", r.Regs.A3},
+		{"X14", r.Regs.A4},
+		{"X15", r.Regs.A5},
+		{"X16", r.Regs.A6},
+		{"X17", r.Regs.A7},
+		{"X18", r.Regs.S2},
+		{"X19", r.Regs.S3},
+		{"X20", r.Regs.S4},
+		{"X21", r.Regs.S5},
+		{"X22", r.Regs.S6},
+		{"X23", r.Regs.S7},
+		{"X24", r.Regs.S8},
+		{"X25", r.Regs.S9},
+		{"X26", r.Regs.S10},
+		{"X27", r.Regs.S11},
+		{"X28", r.Regs.T3},
+		{"X29", r.Regs.T4},
+		{"X30", r.Regs.T5},
+		{"X31", r.Regs.T6},
+		{"PC", r.Regs.Pc},
+	}
+
+	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 *RISCV64Registers) PC() uint64 {
+	// PC Register
+	return r.Regs.Pc
+}
+
+// SP returns the value of SP register.
+func (r *RISCV64Registers) SP() uint64 {
+	// Stack pointer
+	return r.Regs.Sp
+}
+
+// BP returns the value of FP register
+func (r *RISCV64Registers) BP() uint64 {
+	// unused FP register
+	return 0
+}
+
+// TLS returns the address of the thread local storage memory segment.
+func (r *RISCV64Registers) TLS() uint64 {
+	// TODO: calling cgo may overwrite $x27, read it from the kernel
+	if !r.iscgo {
+		return 0
+	}
+
+	return r.tp_tls
+}
+
+// GAddr returns the address of the G variable if it is known, 0 and false otherwise.
+func (r *RISCV64Registers) GAddr() (uint64, bool) {
+	// Defined in $GOROOT/cmd/internal/obj/riscv/cpu.go.
+	return r.Regs.S11, !r.iscgo
+}
+
+// LR returns the link register.
+func (r *RISCV64Registers) LR() uint64 {
+	return r.Regs.Ra
+}
+
+// Copy returns a copy of these registers that is guaranteed not to change.
+func (r *RISCV64Registers) Copy() (proc.Registers, error) {
+	if r.loadFpRegs != nil {
+		err := r.loadFpRegs(r)
+		r.loadFpRegs = nil
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	var rr RISCV64Registers
+	rr.Regs = &RISCV64PtraceRegs{}
+	*(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 *RISCV64Registers) GetReg(regNum uint64) (uint64, error) {
+	reg := riscv64asm.Reg(regNum)
+
+	if reg <= riscv64asm.X31 {
+		switch regNum {
+		case regnum.RISCV64_LR:
+			return uint64(r.Regs.Ra), nil
+		case regnum.RISCV64_SP:
+			return uint64(r.Regs.Sp), nil
+		case regnum.RISCV64_GP:
+			return uint64(r.Regs.Gp), nil
+		case regnum.RISCV64_TP:
+			return uint64(r.Regs.Tp), nil
+		case regnum.RISCV64_T0:
+			return uint64(r.Regs.T0), nil
+		case regnum.RISCV64_T1:
+			return uint64(r.Regs.T1), nil
+		case regnum.RISCV64_T2:
+			return uint64(r.Regs.T2), nil
+		case regnum.RISCV64_S0:
+			return uint64(r.Regs.S0), nil
+		case regnum.RISCV64_S1:
+			return uint64(r.Regs.S1), nil
+		case regnum.RISCV64_A0:
+			return uint64(r.Regs.A0), nil
+		case regnum.RISCV64_A1:
+			return uint64(r.Regs.A1), nil
+		case regnum.RISCV64_A2:
+			return uint64(r.Regs.A2), nil
+		case regnum.RISCV64_A3:
+			return uint64(r.Regs.A3), nil
+		case regnum.RISCV64_A4:
+			return uint64(r.Regs.A4), nil
+		case regnum.RISCV64_A5:
+			return uint64(r.Regs.A5), nil
+		case regnum.RISCV64_A6:
+			return uint64(r.Regs.A6), nil
+		case regnum.RISCV64_A7:
+			return uint64(r.Regs.A7), nil
+		case regnum.RISCV64_S2:
+			return uint64(r.Regs.S2), nil
+		case regnum.RISCV64_S3:
+			return uint64(r.Regs.S3), nil
+		case regnum.RISCV64_S4:
+			return uint64(r.Regs.S4), nil
+		case regnum.RISCV64_S5:
+			return uint64(r.Regs.S5), nil
+		case regnum.RISCV64_S6:
+			return uint64(r.Regs.S6), nil
+		case regnum.RISCV64_S7:
+			return uint64(r.Regs.S7), nil
+		case regnum.RISCV64_S8:
+			return uint64(r.Regs.S8), nil
+		case regnum.RISCV64_S9:
+			return uint64(r.Regs.S9), nil
+		case regnum.RISCV64_S10:
+			return uint64(r.Regs.S10), nil
+		case regnum.RISCV64_S11:
+			return uint64(r.Regs.S11), nil
+		case regnum.RISCV64_T3:
+			return uint64(r.Regs.T3), nil
+		case regnum.RISCV64_T4:
+			return uint64(r.Regs.T4), nil
+		case regnum.RISCV64_T5:
+			return uint64(r.Regs.T5), nil
+		case regnum.RISCV64_T6:
+			return uint64(r.Regs.T6), nil
+		}
+	}
+
+	return 0, proc.ErrUnknownRegister
+}
+
+func (r *RISCV64Registers) SetReg(regNum uint64, reg *op.DwarfRegister) (fpchanged bool, err error) {
+	var p *uint64
+	switch regNum {
+	case regnum.RISCV64_LR:
+		p = &r.Regs.Ra
+	case regnum.RISCV64_SP:
+		p = &r.Regs.Sp
+	case regnum.RISCV64_GP:
+		p = &r.Regs.Gp
+	case regnum.RISCV64_TP:
+		p = &r.Regs.Tp
+	case regnum.RISCV64_T0:
+		p = &r.Regs.T0
+	case regnum.RISCV64_T1:
+		p = &r.Regs.T1
+	case regnum.RISCV64_T2:
+		p = &r.Regs.T2
+	case regnum.RISCV64_S0:
+		p = &r.Regs.S0
+	case regnum.RISCV64_S1:
+		p = &r.Regs.S1
+	case regnum.RISCV64_A0:
+		p = &r.Regs.A0
+	case regnum.RISCV64_A1:
+		p = &r.Regs.A1
+	case regnum.RISCV64_A2:
+		p = &r.Regs.A2
+	case regnum.RISCV64_A3:
+		p = &r.Regs.A3
+	case regnum.RISCV64_A4:
+		p = &r.Regs.A4
+	case regnum.RISCV64_A5:
+		p = &r.Regs.A5
+	case regnum.RISCV64_A6:
+		p = &r.Regs.A6
+	case regnum.RISCV64_A7:
+		p = &r.Regs.A7
+	case regnum.RISCV64_S2:
+		p = &r.Regs.S2
+	case regnum.RISCV64_S3:
+		p = &r.Regs.S3
+	case regnum.RISCV64_S4:
+		p = &r.Regs.S4
+	case regnum.RISCV64_S5:
+		p = &r.Regs.S5
+	case regnum.RISCV64_S6:
+		p = &r.Regs.S6
+	case regnum.RISCV64_S7:
+		p = &r.Regs.S7
+	case regnum.RISCV64_S8:
+		p = &r.Regs.S8
+	case regnum.RISCV64_S9:
+		p = &r.Regs.S9
+	case regnum.RISCV64_S10:
+		p = &r.Regs.S10
+	case regnum.RISCV64_S11:
+		p = &r.Regs.S11
+	case regnum.RISCV64_T3:
+		p = &r.Regs.T3
+	case regnum.RISCV64_T4:
+		p = &r.Regs.T4
+	case regnum.RISCV64_T5:
+		p = &r.Regs.T5
+	case regnum.RISCV64_T6:
+		p = &r.Regs.T6
+	case regnum.RISCV64_PC:
+		p = &r.Regs.Pc
+	}
+
+	if p != nil {
+		*p = reg.Uint64Val
+		return false, nil
+	}
+
+	switch {
+	case regNum >= regnum.RISCV64_F0 && regNum <= regnum.RISCV64_F31:
+		if r.loadFpRegs != nil {
+			err := r.loadFpRegs(r)
+			r.loadFpRegs = nil
+			if err != nil {
+				return false, err
+			}
+		}
+
+		i := regNum - regnum.RISCV64_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 __riscv_d_ext_state in the kernel ptrace.h
+type RISCV64PtraceFpRegs struct {
+	Fregs []byte
+	Fcsr  uint32
+}
+
+const _RISCV64_FPREGSET_LENGTH = (32 * 8)
+
+func (fpregs *RISCV64PtraceFpRegs) 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)
+	}
+
+	fcsrBytes := make([]byte, 4)
+	binary.LittleEndian.PutUint32(fcsrBytes, uint32(fpregs.Fcsr))
+	regs = proc.AppendBytesRegister(regs, "FCSR", fcsrBytes)
+
+	return
+}
+
+func (fpregs *RISCV64PtraceFpRegs) Byte() []byte {
+	fpregs.Fregs = make([]byte, _RISCV64_FPREGSET_LENGTH)
+
+	return fpregs.Fregs[:]
+}
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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/native/hwbreak_other.go	2024-08-01 19:32:55.257780908 +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 && riscv64)
 
 package native
 
diff -Naur delve-1.22.0.old/pkg/proc/native/proc.go delve-1.22.0/pkg/proc/native/proc.go
--- delve-1.22.0.old/pkg/proc/native/proc.go	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/native/proc.go	2024-08-01 19:32:55.257780908 +0800
@@ -368,7 +368,7 @@
 		//	  with gdb once AsyncPreempt was enabled. While implementing the port,
 		//	  few tests failed while it was enabled, but cannot be warrantied that
 		//	  disabling it fixed the issues.
-		DisableAsyncPreempt: runtime.GOOS == "windows" || (runtime.GOOS == "linux" && runtime.GOARCH == "arm64") || (runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le"),
+		DisableAsyncPreempt: runtime.GOOS == "windows" || (runtime.GOOS == "linux" && runtime.GOARCH == "arm64") || (runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le") || (runtime.GOOS == "linux" && runtime.GOARCH == "riscv64"),
 
 		StopReason: stopReason,
 		CanDump:    runtime.GOOS == "linux" || runtime.GOOS == "freebsd" || (runtime.GOOS == "windows" && runtime.GOARCH == "amd64"),
@@ -378,7 +378,7 @@
 	if err != nil {
 		return nil, err
 	}
-	if dbp.bi.Arch.Name == "arm64" || dbp.bi.Arch.Name == "ppc64le" {
+	if dbp.bi.Arch.Name == "arm64" || dbp.bi.Arch.Name == "ppc64le" || dbp.bi.Arch.Name == "riscv64" {
 		dbp.iscgo = tgt.IsCgo()
 	}
 	return grp, nil
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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/native/ptrace_linux_64bit.go	2024-08-01 19:32:55.258780950 +0800
@@ -1,4 +1,4 @@
-//go:build (linux && amd64) || (linux && arm64) || (linux && ppc64le)
+//go:build (linux && amd64) || (linux && arm64) || (linux && ppc64le) || (linux && riscv64)
 
 package native
 
diff -Naur delve-1.22.0.old/pkg/proc/native/registers_linux_riscv64.go delve-1.22.0/pkg/proc/native/registers_linux_riscv64.go
--- delve-1.22.0.old/pkg/proc/native/registers_linux_riscv64.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/proc/native/registers_linux_riscv64.go	2024-08-01 19:32:55.258780950 +0800
@@ -0,0 +1,144 @@
+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"
+)
+
+// Defined in asm/ptrace.h
+const (
+	_RISCV64_GREGS_SIZE  = 32 * 8
+	_RISCV64_FPREGS_SIZE = (32 * 8) + 4 + 4 // Add 4 bytes to align with 8 due to sys.Iovec uses uint64 as len
+)
+
+func ptraceGetGRegs(pid int, regs *linutil.RISCV64PtraceRegs) (err error) {
+	iov := sys.Iovec{Base: (*byte)(unsafe.Pointer(regs)), Len: _RISCV64_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.RISCV64PtraceRegs) (err error) {
+	iov := sys.Iovec{Base: (*byte)(unsafe.Pointer(regs)), Len: _RISCV64_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
+}
+
+func ptraceGetFpRegset(tid int, fpregs *linutil.RISCV64PtraceFpRegs) (err error) {
+	fprBytes := make([]byte, _RISCV64_FPREGS_SIZE)
+	iov := sys.Iovec{Base: &fprBytes[0], Len: uint64(_RISCV64_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-8]
+	fpregs.Fcsr = binary.LittleEndian.Uint32(fprBytes[iov.Len-8 : iov.Len-4])
+
+	return
+}
+
+func (thread *nativeThread) setPC(pc uint64) error {
+	ir, err := registers(thread)
+	if err != nil {
+		return err
+	}
+
+	r := ir.(*linutil.RISCV64Registers)
+	r.Regs.Pc = pc
+	thread.dbp.execPtraceFunc(func() { err = ptraceSetGRegs(thread.ID, r.Regs) })
+
+	return err
+}
+
+func (thread *nativeThread) setSP(sp uint64) (err error) {
+	var ir proc.Registers
+
+	ir, err = registers(thread)
+	if err != nil {
+		return err
+	}
+
+	r := ir.(*linutil.RISCV64Registers)
+	r.Regs.Sp = 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.RISCV64Registers)
+	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.RISCV64PtraceRegs
+		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.Tp
+	}
+	r := linutil.NewRISCV64Registers(&regs, thread.dbp.iscgo, tp_tls,
+		func(r *linutil.RISCV64Registers) 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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/native/support_sentinel_linux.go	2024-08-01 19:32:55.259780993 +0800
@@ -1,4 +1,4 @@
-//go:build linux && !amd64 && !arm64 && !386 && !(ppc64le && exp.linuxppc64le)
+//go:build linux && !amd64 && !arm64 && !386 && !(ppc64le && exp.linuxppc64le) && !riscv64
 
 // This file is used to detect build on unsupported GOOS/GOARCH combinations.
 
diff -Naur delve-1.22.0.old/pkg/proc/native/threads_hardware_singlestep_linux.go delve-1.22.0/pkg/proc/native/threads_hardware_singlestep_linux.go
--- delve-1.22.0.old/pkg/proc/native/threads_hardware_singlestep_linux.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/proc/native/threads_hardware_singlestep_linux.go	2024-08-01 19:32:55.259780993 +0800
@@ -0,0 +1,45 @@
+//go:build !riscv64
+
+package native
+
+import (
+	"github.com/go-delve/delve/pkg/proc"
+	sys "golang.org/x/sys/unix"
+)
+
+func (procgrp *processGroup) singleStep(t *nativeThread) (err error) {
+	sig := 0
+	for {
+		t.dbp.execPtraceFunc(func() { err = ptraceSingleStep(t.ID, sig) })
+		sig = 0
+		if err != nil {
+			return err
+		}
+		wpid, status, err := t.dbp.waitFast(t.ID)
+		if err != nil {
+			return err
+		}
+		if (status == nil || status.Exited()) && wpid == t.dbp.pid {
+			t.dbp.postExit()
+			rs := 0
+			if status != nil {
+				rs = status.ExitStatus()
+			}
+			return proc.ErrProcessExited{Pid: t.dbp.pid, Status: rs}
+		}
+		if wpid == t.ID {
+			switch s := status.StopSignal(); s {
+			case sys.SIGTRAP:
+				return nil
+			case sys.SIGSTOP:
+				// delayed SIGSTOP, ignore it
+			case sys.SIGILL, sys.SIGBUS, sys.SIGFPE, sys.SIGSEGV, sys.SIGSTKFLT:
+				// propagate signals that can have been caused by the current instruction
+				sig = int(s)
+			default:
+				// delay propagation of all other signals
+				t.os.delayedSignal = int(s)
+			}
+		}
+	}
+}
diff -Naur delve-1.22.0.old/pkg/proc/native/threads_linux.go delve-1.22.0/pkg/proc/native/threads_linux.go
--- delve-1.22.0.old/pkg/proc/native/threads_linux.go	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/native/threads_linux.go	2024-08-01 19:32:55.260781035 +0800
@@ -4,8 +4,6 @@
 	"fmt"
 
 	sys "golang.org/x/sys/unix"
-
-	"github.com/go-delve/delve/pkg/proc"
 )
 
 type waitStatus sys.WaitStatus
@@ -50,43 +48,6 @@
 	return
 }
 
-func (procgrp *processGroup) singleStep(t *nativeThread) (err error) {
-	sig := 0
-	for {
-		t.dbp.execPtraceFunc(func() { err = ptraceSingleStep(t.ID, sig) })
-		sig = 0
-		if err != nil {
-			return err
-		}
-		wpid, status, err := t.dbp.waitFast(t.ID)
-		if err != nil {
-			return err
-		}
-		if (status == nil || status.Exited()) && wpid == t.dbp.pid {
-			t.dbp.postExit()
-			rs := 0
-			if status != nil {
-				rs = status.ExitStatus()
-			}
-			return proc.ErrProcessExited{Pid: t.dbp.pid, Status: rs}
-		}
-		if wpid == t.ID {
-			switch s := status.StopSignal(); s {
-			case sys.SIGTRAP:
-				return nil
-			case sys.SIGSTOP:
-				// delayed SIGSTOP, ignore it
-			case sys.SIGILL, sys.SIGBUS, sys.SIGFPE, sys.SIGSEGV, sys.SIGSTKFLT:
-				// propagate signals that can have been caused by the current instruction
-				sig = int(s)
-			default:
-				// delay propagation of all other signals
-				t.os.delayedSignal = int(s)
-			}
-		}
-	}
-}
-
 func (t *nativeThread) WriteMemory(addr uint64, data []byte) (written int, err error) {
 	if ok, err := t.dbp.Valid(); !ok {
 		return 0, err
diff -Naur delve-1.22.0.old/pkg/proc/native/threads_linux_riscv64.go delve-1.22.0/pkg/proc/native/threads_linux_riscv64.go
--- delve-1.22.0.old/pkg/proc/native/threads_linux_riscv64.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/proc/native/threads_linux_riscv64.go	2024-08-01 19:32:55.260781035 +0800
@@ -0,0 +1,294 @@
+package native
+
+import (
+	"bytes"
+	"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"
+	"golang.org/x/arch/riscv64/riscv64asm"
+)
+
+func (thread *nativeThread) fpRegisters() ([]proc.Register, []byte, error) {
+	var err error
+	var riscv64_fpregs linutil.RISCV64PtraceFpRegs
+
+	thread.dbp.execPtraceFunc(func() { err = ptraceGetFpRegset(thread.ID, &riscv64_fpregs) })
+	fpregs := riscv64_fpregs.Decode()
+
+	if err != nil {
+		err = fmt.Errorf("could not get floating point registers: %v", err.Error())
+	}
+
+	return fpregs, riscv64_fpregs.Fregs, err
+}
+
+func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error {
+	var restoreRegistersErr error
+
+	sr := savedRegs.(*linutil.RISCV64Registers)
+	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
+}
+
+// resolvePC is used to resolve next PC for current instruction.
+func (t *nativeThread) resolvePC(savedRegs proc.Registers) ([]uint64, error) {
+	regs := savedRegs.(*linutil.RISCV64Registers)
+	nextInstLen := t.BinInfo().Arch.MaxInstructionLength()
+	nextInstBytes := make([]byte, nextInstLen)
+	var err error
+
+	t.dbp.execPtraceFunc(func() {
+		_, err = sys.PtracePeekData(t.ID, uintptr(regs.PC()), nextInstBytes)
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	nextPCs := []uint64{regs.PC() + uint64(nextInstLen)}
+	if bytes.Equal(nextInstBytes, t.BinInfo().Arch.AltBreakpointInstruction()) {
+		return nextPCs, nil
+	} else if bytes.Equal(nextInstBytes, t.BinInfo().Arch.BreakpointInstruction()) {
+		nextInstLen = 2
+		nextPCs = []uint64{regs.PC() + uint64(nextInstLen)}
+		return nextPCs, nil
+	}
+
+	nextInst, err := riscv64asm.Decode(nextInstBytes)
+	if err != nil {
+		return nil, err
+	}
+
+	if nextInst.Len == 2 {
+		nextInstBytes = nextInstBytes[:2]
+		nextInstLen = 2
+		nextPCs = []uint64{regs.PC() + uint64(nextInstLen)}
+	}
+
+	switch nextInst.Op {
+	case riscv64asm.BEQ, riscv64asm.BNE, riscv64asm.BLT, riscv64asm.BGE, riscv64asm.BLTU, riscv64asm.BGEU:
+		rs1, _ := nextInst.Args[0].(riscv64asm.Reg)
+		rs2, _ := nextInst.Args[1].(riscv64asm.Reg)
+		bimm12, _ := nextInst.Args[2].(riscv64asm.Simm)
+		src1u, _ := regs.GetReg(uint64(rs1))
+		src2u, _ := regs.GetReg(uint64(rs2))
+		src1, src2 := int64(src1u), int64(src2u)
+
+		switch nextInst.Op {
+		case riscv64asm.BEQ:
+			if src1 == src2 && int(bimm12.Imm) != nextInstLen {
+				nextPCs = append(nextPCs, regs.PC()+uint64(bimm12.Imm))
+			}
+		case riscv64asm.BNE:
+			if src1 != src2 && int(bimm12.Imm) != nextInstLen {
+				nextPCs = append(nextPCs, regs.PC()+uint64(bimm12.Imm))
+			}
+		case riscv64asm.BLT:
+			if src1 < src2 && int(bimm12.Imm) != nextInstLen {
+				nextPCs = append(nextPCs, regs.PC()+uint64(bimm12.Imm))
+			}
+		case riscv64asm.BGE:
+			if src1 >= src2 && int(bimm12.Imm) != nextInstLen {
+				nextPCs = append(nextPCs, regs.PC()+uint64(bimm12.Imm))
+			}
+		case riscv64asm.BLTU:
+			if src1u < src2u && int(bimm12.Imm) != nextInstLen {
+				nextPCs = append(nextPCs, regs.PC()+uint64(bimm12.Imm))
+			}
+		case riscv64asm.BGEU:
+			if src1u >= src2u && int(bimm12.Imm) != nextInstLen {
+				nextPCs = append(nextPCs, regs.PC()+uint64(bimm12.Imm))
+			}
+		}
+
+	case riscv64asm.JAL:
+		jimm, _ := nextInst.Args[1].(riscv64asm.Simm)
+		if int(jimm.Imm) != nextInstLen {
+			nextPCs = append(nextPCs, regs.PC()+uint64(jimm.Imm))
+		}
+
+	case riscv64asm.JALR:
+		rd, _ := nextInst.Args[0].(riscv64asm.Reg)
+		rs1_mem := nextInst.Args[1].(riscv64asm.RegOffset)
+		rs1, ofs := rs1_mem.OfsReg, rs1_mem.Ofs
+		src1, _ := regs.GetReg(uint64(rs1))
+		if rd == riscv64asm.X0 && rs1 == riscv64asm.X1 {
+			nextPCs = []uint64{(src1 + uint64(ofs.Imm)) & (^uint64(0x1))}
+		}
+		if (src1+uint64(ofs.Imm))&(^uint64(0x1)) != nextPCs[0] {
+			nextPCs = append(nextPCs, (src1+uint64(ofs.Imm))&(^uint64(0x1)))
+		}
+
+	// We can't put a breakpoint in the middle of a lr/sc atomic sequence, so look for the end of the sequence and put the breakpoint there.
+	// RISC-V Go only use lr.w/d.aq, see comments at the beginning of $GOROOT/src/runtime/internal/atomic/atomic_riscv64.s
+	case riscv64asm.LR_D_AQ, riscv64asm.LR_W_AQ:
+		// Currently, RISC-V Go only use this kind of lr/sc sequence, so only check this pattern.
+		// defined in $GOROOT/src/cmd/compile/internal/riscv64/ssa.go:
+		// LR	(Rarg0), Rtmp
+		// BNE	Rtmp, Rarg1, 3(PC)
+		// SC	Rarg2, (Rarg0), Rtmp
+		// BNE	Rtmp, ZERO, -3(PC)
+		curPC := regs.PC() + uint64(nextInstLen)
+		t.dbp.execPtraceFunc(func() {
+			_, err = sys.PtracePeekData(t.ID, uintptr(curPC), nextInstBytes)
+		})
+		if err != nil {
+			return nil, err
+		}
+		nextInst, err = riscv64asm.Decode(nextInstBytes)
+		if err != nil {
+			return nil, err
+		}
+		if nextInst.Len == 2 {
+			nextInstBytes = nextInstBytes[:2]
+		}
+		if nextInst.Op != riscv64asm.BNE {
+			break
+		}
+
+		curPC += uint64(nextInstLen)
+		t.dbp.execPtraceFunc(func() {
+			_, err = sys.PtracePeekData(t.ID, uintptr(curPC), nextInstBytes)
+		})
+		if err != nil {
+			return nil, err
+		}
+		nextInst, err = riscv64asm.Decode(nextInstBytes)
+		if err != nil {
+			return nil, err
+		}
+		if nextInst.Len == 2 {
+			nextInstBytes = nextInstBytes[:2]
+		}
+		if nextInst.Op != riscv64asm.SC_D_RL && nextInst.Op != riscv64asm.SC_W_RL {
+			break
+		}
+
+		curPC += uint64(nextInstLen)
+		t.dbp.execPtraceFunc(func() {
+			_, err = sys.PtracePeekData(t.ID, uintptr(regs.PC()+uint64(curPC)), nextInstBytes)
+		})
+		if err != nil {
+			return nil, err
+		}
+		nextInst, err = riscv64asm.Decode(nextInstBytes)
+		if err != nil {
+			return nil, err
+		}
+		if nextInst.Len == 2 {
+			nextInstBytes = nextInstBytes[:2]
+		}
+		if nextInst.Op != riscv64asm.BNE {
+			break
+		}
+		nextPCs = []uint64{curPC}
+	}
+
+	return nextPCs, nil
+}
+
+// RISC-V doesn't have ptrace singlestep support, so use breakpoint to emulate it.
+func (procgrp *processGroup) singleStep(t *nativeThread) (err error) {
+	regs, err := t.Registers()
+	if err != nil {
+		return err
+	}
+	nextPCs, err := t.resolvePC(regs)
+	if err != nil {
+		return err
+	}
+	originalDataSet := make(map[uintptr][]byte)
+
+	// Do in batch, first set breakpoint, then continue.
+	t.dbp.execPtraceFunc(func() {
+		breakpointInstr := t.BinInfo().Arch.BreakpointInstruction()
+		readWriteMem := func(i int, addr uintptr, instr []byte) error {
+			originalData := make([]byte, len(breakpointInstr))
+			_, err = sys.PtracePeekData(t.ID, addr, originalData)
+			if err != nil {
+				return err
+			}
+			_, err = sys.PtracePokeData(t.ID, addr, instr)
+			if err != nil {
+				return err
+			}
+			// Everything is ok, store originalData
+			originalDataSet[addr] = originalData
+			return nil
+		}
+		for i, nextPC := range nextPCs {
+			err = readWriteMem(i, uintptr(nextPC), breakpointInstr)
+			if err != nil {
+				return
+			}
+		}
+	})
+	// Make sure we restore before return.
+	defer func() {
+		t.dbp.execPtraceFunc(func() {
+			for addr, originalData := range originalDataSet {
+				if originalData != nil {
+					_, err = sys.PtracePokeData(t.ID, addr, originalData)
+				}
+			}
+		})
+	}()
+	if err != nil {
+		return err
+	}
+	for {
+		sig := 0
+		t.dbp.execPtraceFunc(func() { err = ptraceCont(t.ID, sig) })
+		if err != nil {
+			return err
+		}
+		// To be able to catch process exit, we can only use wait instead of waitFast.
+		wpid, status, err := t.dbp.wait(t.ID, 0)
+		if err != nil {
+			return err
+		}
+		if (status == nil || status.Exited()) && wpid == t.dbp.pid {
+			t.dbp.postExit()
+			rs := 0
+			if status != nil {
+				rs = status.ExitStatus()
+			}
+			return proc.ErrProcessExited{Pid: t.dbp.pid, Status: rs}
+		}
+		if wpid == t.ID {
+			sig = 0
+			switch s := status.StopSignal(); s {
+			case sys.SIGTRAP:
+				return nil
+			case sys.SIGSTOP:
+				// delayed SIGSTOP, ignore it
+			case sys.SIGILL, sys.SIGBUS, sys.SIGFPE, sys.SIGSEGV, sys.SIGSTKFLT:
+				// propagate signals that can have been caused by the current instruction
+				sig = int(s)
+			default:
+				// delay propagation of all other signals
+				t.os.delayedSignal = int(s)
+			}
+		}
+	}
+}
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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/pe.go	2024-08-01 19:32:55.260781035 +0800
@@ -21,6 +21,7 @@
 	_IMAGE_FILE_MACHINE_POWERPC   = 0x1f0
 	_IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1
 	_IMAGE_FILE_MACHINE_R4000     = 0x166
+	_IMAGE_FILE_MACHINE_RISCV64   = 0x5064
 	_IMAGE_FILE_MACHINE_SH3       = 0x1a2
 	_IMAGE_FILE_MACHINE_SH3DSP    = 0x1a3
 	_IMAGE_FILE_MACHINE_SH4       = 0x1a6
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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/proc_test.go	2024-08-01 19:32:55.261781078 +0800
@@ -3192,6 +3192,7 @@
 	skipOn(t, "not working on freebsd", "freebsd")
 	skipOn(t, "not working on linux/386", "linux", "386")
 	skipOn(t, "not working on linux/ppc64le when -gcflags=-N -l is passed", "linux", "ppc64le")
+	skipOn(t, "not working on linux/riscv64", "linux", "riscv64")
 	withTestProcessArgs("testnextprog", t, "", []string{}, protest.LinkStrip, func(p *proc.Target, grp *proc.TargetGroup, f protest.Fixture) {
 		setFunctionBreakpoint(p, t, "main.main")
 		assertNoError(grp.Continue(), t, "Continue")
@@ -3350,6 +3351,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", "linux", "riscv64")
 	if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 21) {
 		skipOn(t, "broken - cgo stacktraces", "windows", "arm64")
 	}
@@ -3738,6 +3740,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", "riscv64")
 	// 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
@@ -4085,6 +4088,7 @@
 
 func TestDWZCompression(t *testing.T) {
 	skipOn(t, "broken", "ppc64le")
+	skipOn(t, "broken", "riscv64")
 	// 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 +4649,7 @@
 	skipOn(t, "broken", "386")
 	skipOn(t, "broken - cgo stacktraces", "darwin", "arm64")
 	skipOn(t, "broken", "ppc64le")
+	skipOn(t, "broken", "riscv64")
 	protest.MustHaveCgo(t)
 	// If a panic happens during cgo execution the stacktrace should show the C
 	// function that caused the problem.
@@ -5380,6 +5385,7 @@
 	skipOn(t, "not implemented", "freebsd")
 	skipOn(t, "not implemented", "386")
 	skipOn(t, "not implemented", "ppc64le")
+	skipOn(t, "not implemented", "riscv64")
 	skipOn(t, "see https://github.com/go-delve/delve/issues/2768", "windows")
 	protest.AllowRecording(t)
 
@@ -5441,6 +5447,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", "riscv64")
 	protest.AllowRecording(t)
 
 	withTestProcess("databpcountstest", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) {
@@ -5556,6 +5563,7 @@
 	skipOn(t, "not implemented", "freebsd")
 	skipOn(t, "not implemented", "386")
 	skipOn(t, "not implemented", "ppc64le")
+	skipOn(t, "not implemented", "riscv64")
 	skipOn(t, "see https://github.com/go-delve/delve/issues/2768", "windows")
 	protest.AllowRecording(t)
 
@@ -5715,6 +5723,8 @@
 		asmfile = "main_386.s"
 	case "ppc64le":
 		asmfile = "main_ppc64le.s"
+	case "riscv64":
+		asmfile = "main_riscv64.s"
 	default:
 		t.Fatalf("assembly file for %s not provided", runtime.GOARCH)
 	}
diff -Naur delve-1.22.0.old/pkg/proc/riscv64_arch.go delve-1.22.0/pkg/proc/riscv64_arch.go
--- delve-1.22.0.old/pkg/proc/riscv64_arch.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/proc/riscv64_arch.go	2024-08-01 19:32:55.263781163 +0800
@@ -0,0 +1,337 @@
+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"
+)
+
+// ebreak instruction: 0x00100073
+var riscv64BreakInstruction = []byte{0x73, 0x00, 0x10, 0x00}
+
+// c.ebreak instruction: 0x9002
+var riscv64CompressedBreakInstruction = []byte{0x02, 0x90}
+
+// RISCV64Arch returns an initialized RISCV64 struct.
+func RISCV64Arch(goos string) *Arch {
+	return &Arch{
+		Name:                             "riscv64",
+		ptrSize:                          8,
+		maxInstructionLength:             4,
+		breakpointInstruction:            riscv64CompressedBreakInstruction,
+		altBreakpointInstruction:         riscv64BreakInstruction,
+		breakInstrMovesPC:                false,
+		derefTLS:                         false,
+		prologues:                        prologuesRISCV64,
+		fixFrameUnwindContext:            riscv64FixFrameUnwindContext,
+		switchStack:                      riscv64SwitchStack,
+		regSize:                          riscv64RegSize,
+		RegistersToDwarfRegisters:        riscv64RegistersToDwarfRegisters,
+		addrAndStackRegsToDwarfRegisters: riscv64AddrAndStackRegsToDwarfRegisters,
+		DwarfRegisterToString:            riscv64DwarfRegisterToString,
+		inhibitStepInto:                  func(*BinaryInfo, uint64) bool { return false },
+		asmDecode:                        riscv64AsmDecode,
+		usesLR:                           true,
+		PCRegNum:                         regnum.RISCV64_PC,
+		SPRegNum:                         regnum.RISCV64_SP,
+		asmRegisters:                     riscv64AsmRegisters,
+		RegisterNameToDwarf:              nameToDwarfFunc(regnum.RISCV64NameToDwarf),
+		RegnumToString:                   regnum.RISCV64ToName,
+		debugCallMinStackSize:            288,         // TODO
+		maxRegArgBytes:                   16*8 + 16*8, // 16 int argument registers plus 16 float argument registers
+	}
+}
+
+func riscv64FixFrameUnwindContext(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.RISCV64_PC,
+			Regs: map[uint64]frame.DWRule{
+				regnum.RISCV64_PC: {
+					Rule:   frame.RuleOffset,
+					Offset: int64(-a.PtrSize()),
+				},
+
+				regnum.RISCV64_FP: {
+					Rule:   frame.RuleOffset,
+					Offset: int64(-2 * a.PtrSize()),
+				},
+
+				regnum.RISCV64_SP: {
+					Rule:   frame.RuleValOffset,
+					Offset: 0,
+				},
+			},
+
+			CFA: frame.DWRule{
+				Rule:   frame.RuleCFA,
+				Reg:    regnum.RISCV64_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.RISCV64_FP].Rule == frame.RuleUndefined {
+		fctxt.Regs[regnum.RISCV64_FP] = frame.DWRule{
+			Rule:   frame.RuleFramePointer,
+			Reg:    regnum.RISCV64_FP,
+			Offset: 0,
+		}
+	}
+
+	if fctxt.Regs[regnum.RISCV64_LR].Rule == frame.RuleUndefined {
+		fctxt.Regs[regnum.RISCV64_LR] = frame.DWRule{
+			Rule:   frame.RuleRegister,
+			Reg:    regnum.RISCV64_LR,
+			Offset: 0,
+		}
+	}
+
+	return fctxt
+}
+
+const riscv64cgocallSPOffsetSaveSlot = 0x8
+const riscv64prevG0schedSPOffsetSaveSlot = 0x10
+
+func riscv64SwitchStack(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":
+		// cgostacktrace is broken on riscv64, so do nothing here.
+
+	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()+riscv64cgocallSPOffsetSaveSlot),
+			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_riscv64.s
+		bpoff := uint64(4)
+		lroff := uint64(18)
+		if producer := it.bi.Producer(); producer != "" && goversion.ProducerAfterOrEqual(producer, 1, 18) {
+			// In Go 1.18 the order registers are saved was changed.
+			bpoff = 4
+			lroff = 16
+		}
+		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()+riscv64cgocallSPOffsetSaveSlot), 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_riscv64.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()+riscv64prevG0schedSPOffsetSaveSlot), int64(it.bi.Arch.PtrSize()))
+		it.systemstack = true
+		return false
+	}
+
+	return false
+}
+
+func riscv64RegSize(regnum uint64) int {
+	// All CPU registers are 64bit
+	return 8
+}
+
+func riscv64RegistersToDwarfRegisters(staticBase uint64, regs Registers) *op.DwarfRegisters {
+	dregs := initDwarfRegistersFromSlice(int(regnum.RISCV64MaxRegNum()), regs, regnum.RISCV64NameToDwarf)
+	dr := op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.RISCV64_PC, regnum.RISCV64_SP, regnum.RISCV64_FP, regnum.RISCV64_LR)
+	dr.SetLoadMoreCallback(loadMoreDwarfRegistersFromSliceFunc(dr, regs, regnum.RISCV64NameToDwarf))
+	return dr
+}
+
+func riscv64AddrAndStackRegsToDwarfRegisters(staticBase, pc, sp, bp, lr uint64) op.DwarfRegisters {
+	dregs := make([]*op.DwarfRegister, int(regnum.RISCV64_PC+1))
+	dregs[regnum.RISCV64_PC] = op.DwarfRegisterFromUint64(pc)
+	dregs[regnum.RISCV64_SP] = op.DwarfRegisterFromUint64(sp)
+	dregs[regnum.RISCV64_FP] = op.DwarfRegisterFromUint64(bp)
+	dregs[regnum.RISCV64_LR] = op.DwarfRegisterFromUint64(lr)
+
+	return *op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.RISCV64_PC, regnum.RISCV64_SP, regnum.RISCV64_FP, regnum.RISCV64_LR)
+}
+
+func riscv64DwarfRegisterToString(i int, reg *op.DwarfRegister) (name string, floatingPoint bool, repr string) {
+	name = regnum.RISCV64ToName(uint64(i))
+
+	if reg == nil {
+		return name, false, ""
+	}
+
+	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/riscv64_disasm.go delve-1.22.0/pkg/proc/riscv64_disasm.go
--- delve-1.22.0.old/pkg/proc/riscv64_disasm.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/pkg/proc/riscv64_disasm.go	2024-08-01 19:32:55.263781163 +0800
@@ -0,0 +1,189 @@
+package proc
+
+import (
+	"fmt"
+
+	"github.com/go-delve/delve/pkg/dwarf/op"
+	"github.com/go-delve/delve/pkg/dwarf/regnum"
+	"golang.org/x/arch/riscv64/riscv64asm"
+)
+
+var (
+	errType = fmt.Errorf("unknown type")
+)
+
+func riscv64AsmDecode(asmInst *AsmInstruction, mem []byte, regs *op.DwarfRegisters, memrw MemoryReadWriter, bi *BinaryInfo) error {
+	inst, err := riscv64asm.Decode(mem)
+	if err != nil {
+		asmInst.Inst = (*riscv64ArchInst)(nil)
+		return err
+	}
+
+	asmInst.Size = inst.Len
+	asmInst.Bytes = mem[:asmInst.Size]
+	asmInst.Inst = (*riscv64ArchInst)(&inst)
+	asmInst.Kind = OtherInstruction
+
+	switch inst.Op {
+	case riscv64asm.JALR:
+		rd, _ := inst.Args[0].(riscv64asm.Reg)
+		rs1 := inst.Args[1].(riscv64asm.RegOffset).OfsReg
+		if rd == riscv64asm.X1 {
+			asmInst.Kind = CallInstruction
+		} else if rd == riscv64asm.X0 && rs1 == riscv64asm.X1 {
+			asmInst.Kind = RetInstruction
+		} else {
+			asmInst.Kind = JmpInstruction
+		}
+
+	case riscv64asm.JAL:
+		rd, _ := inst.Args[0].(riscv64asm.Reg)
+		if rd == riscv64asm.X1 {
+			asmInst.Kind = CallInstruction
+		} else {
+			asmInst.Kind = JmpInstruction
+		}
+
+	case riscv64asm.BEQ,
+		riscv64asm.BNE,
+		riscv64asm.BLT,
+		riscv64asm.BGE,
+		riscv64asm.BLTU,
+		riscv64asm.BGEU:
+		asmInst.Kind = JmpInstruction
+
+	case riscv64asm.EBREAK:
+		asmInst.Kind = HardBreakInstruction
+
+	default:
+		asmInst.Kind = OtherInstruction
+	}
+
+	asmInst.DestLoc = resolveCallArgRISCV64(&inst, asmInst.Loc.PC, asmInst.AtPC, regs, memrw, bi)
+
+	return nil
+}
+
+func resolveCallArgRISCV64(inst *riscv64asm.Inst, instAddr uint64, currentGoroutine bool, regs *op.DwarfRegisters, mem MemoryReadWriter, bininfo *BinaryInfo) *Location {
+	var pc uint64
+	var err error
+
+	switch inst.Op {
+	// Format: op rs1, rs2, bimm12
+	// Target: bimm12
+	case riscv64asm.BEQ,
+		riscv64asm.BNE,
+		riscv64asm.BLT,
+		riscv64asm.BGE,
+		riscv64asm.BLTU,
+		riscv64asm.BGEU:
+
+		switch arg := inst.Args[2].(type) {
+		case riscv64asm.Simm:
+			pc = uint64(int64(instAddr) + int64(arg.Imm))
+		default:
+			return nil
+		}
+
+	// Format: op rd, jimm20
+	// Target: simm20
+	case riscv64asm.JAL:
+		switch arg := inst.Args[1].(type) {
+		case riscv64asm.Simm:
+			pc = uint64(int64(instAddr) + int64(arg.Imm))
+		default:
+			return nil
+		}
+
+	// Format: op rd, rs1, imm12
+	// Target: rj + offs16
+	case riscv64asm.JALR:
+		if !currentGoroutine || regs == nil {
+			return nil
+		}
+		switch arg := inst.Args[1].(type) {
+		case riscv64asm.RegOffset:
+			pc, err = bininfo.Arch.getAsmRegister(regs, int(arg.OfsReg))
+			if err != nil {
+				return nil
+			}
+			pc = uint64(int64(pc) + int64(arg.Ofs.Imm))
+		}
+
+	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/riscv/obj.go.
+var prologuesRISCV64 []opcodeSeq
+
+func init() {
+	var tinyStacksplit = opcodeSeq{uint64(riscv64asm.ADDI)}
+	var smallStacksplit = opcodeSeq{}
+	var bigStacksplit = opcodeSeq{uint64(riscv64asm.LUI),
+		uint64(riscv64asm.ADDIW),
+		uint64(riscv64asm.BLTU),
+		uint64(riscv64asm.LUI),
+		uint64(riscv64asm.ADDIW),
+		uint64(riscv64asm.ADD)}
+
+	var unixGetG = opcodeSeq{uint64(riscv64asm.LD)}
+	var tailPrologues = opcodeSeq{uint64(riscv64asm.BLTU),
+		uint64(riscv64asm.JAL),
+		uint64(riscv64asm.JAL)}
+
+	prologuesRISCV64 = 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...)
+		prologuesRISCV64 = append(prologuesRISCV64, prologue)
+	}
+}
+
+type riscv64ArchInst riscv64asm.Inst
+
+func (inst *riscv64ArchInst) Text(flavour AssemblyFlavour, pc uint64, symLookup func(uint64) (string, uint64)) string {
+	if inst == nil {
+		return "?"
+	}
+
+	var text string
+
+	switch flavour {
+	case GNUFlavour:
+		text = riscv64asm.GNUSyntax(riscv64asm.Inst(*inst))
+	default:
+		text = riscv64asm.GoSyntax(riscv64asm.Inst(*inst), pc, symLookup, nil)
+	}
+
+	return text
+}
+
+func (inst *riscv64ArchInst) OpcodeEquals(op uint64) bool {
+	if inst == nil {
+		return false
+	}
+
+	return uint64(inst.Op) == op
+}
+
+var riscv64AsmRegisters = func() map[int]asmRegister {
+	r := make(map[int]asmRegister)
+
+	for i := riscv64asm.X0; i <= riscv64asm.X31; i++ {
+		r[int(i)] = asmRegister{regnum.RISCV64_X0 + uint64(i), 0, 0}
+	}
+
+	return r
+}()
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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/stack.go	2024-08-01 19:32:55.263781163 +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 == "riscv64" {
 		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 == "riscv64" {
 		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/target_exec.go delve-1.22.0/pkg/proc/target_exec.go
--- delve-1.22.0.old/pkg/proc/target_exec.go	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/target_exec.go	2024-08-01 19:32:55.263781163 +0800
@@ -8,6 +8,7 @@
 	"go/ast"
 	"go/token"
 	"path/filepath"
+	"runtime"
 	"strings"
 
 	"golang.org/x/arch/ppc64/ppc64asm"
@@ -1364,7 +1365,9 @@
 			stepOverBreak(thread, loc.PC)
 			// In linux-arm64, PtraceSingleStep seems cannot step over BRK instruction
 			// (linux-arm64 feature or kernel bug maybe).
-			if !arch.BreakInstrMovesPC() {
+			// RISC-V use ebreak as hardcoded breakpoint in Go, however we use c.ebreak
+			// in delve to support breakpoints in cgo.
+			if !arch.BreakInstrMovesPC() && runtime.GOARCH != "riscv64" {
 				setPC(thread, loc.PC+uint64(arch.BreakpointSize()))
 			}
 			// Single-step current thread until we exit runtime.breakpoint and
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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/pkg/proc/test/support.go	2024-08-01 19:32:55.264781206 +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 == "riscv64" {
+		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")
@@ -382,7 +385,7 @@
 	// Tracks regabiSupported variable in ParseGOEXPERIMENT internal/buildcfg/exp.go
 	switch {
 	case goversion.VersionAfterOrEqual(runtime.Version(), 1, 18):
-		return runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "ppc64"
+		return runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "riscv64"
 	case goversion.VersionAfterOrEqual(runtime.Version(), 1, 17):
 		return runtime.GOARCH == "amd64" && (runtime.GOOS == "android" || runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows")
 	default:
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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/_scripts/make.go	2024-08-01 19:32:55.265781248 +0800
@@ -50,6 +50,8 @@
 				envflags = append(envflags, "GOOS="+OS)
 			}
 			if len(envflags) > 0 {
+				// Add -mod=vendor to envflags due to riscv arch package has not upstream yet.
+				envflags = append(envflags, "-mod=vendor")
 				executeEnv(envflags, "go", "build", "-ldflags", "-extldflags -static", tagFlags(), buildFlags(), DelveMainPackagePath)
 			} else {
 				execute("go", "build", "-ldflags", "-extldflags -static", tagFlags(), buildFlags(), DelveMainPackagePath)
@@ -111,7 +113,7 @@
 	test.PersistentFlags().StringVarP(&TestBuildMode, "test-build-mode", "m", "", `Runs tests compiling with the specified build mode, one of either:
 	normal		normal buildmode (default)
 	pie		PIE buildmode
-	
+
 This option can only be specified if testset is basic or a single package.`)
 	test.PersistentFlags().BoolVarP(&TestIncludePIE, "pie", "", true, "Standard testing should include PIE")
 
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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/service/debugger/debugger_test.go	2024-08-01 19:32:55.265781248 +0800
@@ -49,6 +49,9 @@
 	if runtime.GOARCH == "ppc64le" && runtime.GOOS == "linux" {
 		t.Setenv("GOARCH", "amd64")
 	}
+	if runtime.GOARCH == "riscv64" && runtime.GOOS == "linux" {
+		t.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	2023-12-30 06:48:07.000000000 +0800
+++ delve-1.22.0/service/debugger/debugger_unix_test.go	2024-08-01 19:32:55.266781291 +0800
@@ -34,6 +34,9 @@
 	if runtime.GOARCH == "ppc64le" && runtime.GOOS == "linux" {
 		t.Setenv("GOARCH", "amd64")
 	}
+	if runtime.GOARCH == "riscv64" && runtime.GOOS == "linux" {
+		t.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/vendor/golang.org/x/arch/riscv64/riscv64asm/arg.go delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/arg.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/arg.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/arg.go	2024-08-01 19:32:55.266781291 +0800
@@ -0,0 +1,116 @@
+// 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 riscv64asm
+
+// Naming for Go decoder arguments:
+//
+// - arg_rd: a general purpose register rd encoded in rd[11:7] field
+//
+// - arg_rs1: a general purpose register rs1 encoded in rs1[19:15] field
+//
+// - arg_rs2: a general purpose register rs2 encoded in rs2[24:20] field
+//
+// - arg_rs3: a general purpose register rs3 encoded in rs3[31:27] field
+//
+// - arg_fd: a floating point register rd encoded in rd[11:7] field
+//
+// - arg_fs1: a floating point register rs1 encoded in rs1[19:15] field
+//
+// - arg_fs2: a floating point register rs2 encoded in rs2[24:20] field
+//
+// - arg_fs3: a floating point register rs3 encoded in rs3[31:27] field
+//
+// - arg_csr: a control status register encoded in csr[31:20] field
+//
+// - arg_rs1_mem: source register with offset in load commands
+//
+// - arg_rs1_store: source register with offset in store commands
+//
+// - arg_rs1_amo: source register with offset in atomic commands
+//
+// - arg_pred: predecessor memory ordering information encoded in pred[27:24] field
+//             For details, please refer to chapter 2.7 of ISA manual volume 1
+//
+// - arg_succ: successor memory ordering information encoded in succ[23:20] field
+//             For details, please refer to chapter 2.7 of ISA manual volume 1
+//
+// - arg_zimm: a unsigned immediate encoded in zimm[19:15] field
+//
+// - arg_imm12: an I-type immediate encoded in imm12[31:20] field
+//
+// - arg_simm12: a S-type immediate encoded in simm12[31:25|11:7] field
+//
+// - arg_bimm12: a B-type immediate encoded in bimm12[31:25|11:7] field
+//
+// - arg_imm20: an U-type immediate encoded in imm20[31:12] field
+//
+// - arg_jimm20: a J-type immediate encoded in jimm20[31:12] field
+//
+// - arg_shamt5: a shift amount encoded in shamt5[24:20] field
+//
+// - arg_shamt6: a shift amount encoded in shamt6[25:20] field
+//
+
+type instArg uint16
+
+const (
+	_ instArg = iota
+	arg_rd
+	arg_rs1
+	arg_rs2
+	arg_rs3
+	arg_fd
+	arg_fs1
+	arg_fs2
+	arg_fs3
+	arg_csr
+
+	arg_rs1_amo
+	arg_rs1_mem
+	arg_rs1_store
+
+	arg_pred
+	arg_succ
+
+	arg_zimm
+	arg_imm12
+	arg_simm12
+	arg_bimm12
+	arg_imm20
+	arg_jimm20
+	arg_shamt5
+	arg_shamt6
+
+	// RISC-V Compressed Extension Args
+	arg_rd_p
+	arg_fd_p
+	arg_rs1_p
+	arg_rd_rs1_p
+	arg_fs2_p
+	arg_rs2_p
+	arg_rd_n0
+	arg_rs1_n0
+	arg_rd_rs1_n0
+	arg_c_rs1_n0
+	arg_c_rs2_n0
+	arg_c_fs2
+	arg_c_rs2
+	arg_rd_n2
+
+	arg_c_imm6
+	arg_c_nzimm6
+	arg_c_nzuimm6
+	arg_c_uimm7
+	arg_c_uimm8
+	arg_c_uimm8sp_s
+	arg_c_uimm8sp
+	arg_c_uimm9sp_s
+	arg_c_uimm9sp
+	arg_c_bimm9
+	arg_c_nzimm10
+	arg_c_nzuimm10
+	arg_c_imm12
+	arg_c_nzimm18
+)
diff -Naur delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/csr_string.go delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/csr_string.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/csr_string.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/csr_string.go	2024-08-01 19:32:55.266781291 +0800
@@ -0,0 +1,577 @@
+// Code generated by "stringer -type=Csr"; DO NOT EDIT.
+
+package riscv64asm
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[USTATUS-0]
+	_ = x[FFLAGS-1]
+	_ = x[FRM-2]
+	_ = x[FCSR-3]
+	_ = x[UIE-4]
+	_ = x[UTVEC-5]
+	_ = x[UTVT-7]
+	_ = x[VSTART-8]
+	_ = x[VXSAT-9]
+	_ = x[VXRM-10]
+	_ = x[VCSR-15]
+	_ = x[USCRATCH-64]
+	_ = x[UEPC-65]
+	_ = x[UCAUSE-66]
+	_ = x[UTVAL-67]
+	_ = x[UIP-68]
+	_ = x[UNXTI-69]
+	_ = x[UINTSTATUS-70]
+	_ = x[USCRATCHCSW-72]
+	_ = x[USCRATCHCSWL-73]
+	_ = x[SSTATUS-256]
+	_ = x[SEDELEG-258]
+	_ = x[SIDELEG-259]
+	_ = x[SIE-260]
+	_ = x[STVEC-261]
+	_ = x[SCOUNTEREN-262]
+	_ = x[STVT-263]
+	_ = x[SSCRATCH-320]
+	_ = x[SEPC-321]
+	_ = x[SCAUSE-322]
+	_ = x[STVAL-323]
+	_ = x[SIP-324]
+	_ = x[SNXTI-325]
+	_ = x[SINTSTATUS-326]
+	_ = x[SSCRATCHCSW-328]
+	_ = x[SSCRATCHCSWL-329]
+	_ = x[SATP-384]
+	_ = x[VSSTATUS-512]
+	_ = x[VSIE-516]
+	_ = x[VSTVEC-517]
+	_ = x[VSSCRATCH-576]
+	_ = x[VSEPC-577]
+	_ = x[VSCAUSE-578]
+	_ = x[VSTVAL-579]
+	_ = x[VSIP-580]
+	_ = x[VSATP-640]
+	_ = x[MSTATUS-768]
+	_ = x[MISA-769]
+	_ = x[MEDELEG-770]
+	_ = x[MIDELEG-771]
+	_ = x[MIE-772]
+	_ = x[MTVEC-773]
+	_ = x[MCOUNTEREN-774]
+	_ = x[MTVT-775]
+	_ = x[MSTATUSH-784]
+	_ = x[MCOUNTINHIBIT-800]
+	_ = x[MHPMEVENT3-803]
+	_ = x[MHPMEVENT4-804]
+	_ = x[MHPMEVENT5-805]
+	_ = x[MHPMEVENT6-806]
+	_ = x[MHPMEVENT7-807]
+	_ = x[MHPMEVENT8-808]
+	_ = x[MHPMEVENT9-809]
+	_ = x[MHPMEVENT10-810]
+	_ = x[MHPMEVENT11-811]
+	_ = x[MHPMEVENT12-812]
+	_ = x[MHPMEVENT13-813]
+	_ = x[MHPMEVENT14-814]
+	_ = x[MHPMEVENT15-815]
+	_ = x[MHPMEVENT16-816]
+	_ = x[MHPMEVENT17-817]
+	_ = x[MHPMEVENT18-818]
+	_ = x[MHPMEVENT19-819]
+	_ = x[MHPMEVENT20-820]
+	_ = x[MHPMEVENT21-821]
+	_ = x[MHPMEVENT22-822]
+	_ = x[MHPMEVENT23-823]
+	_ = x[MHPMEVENT24-824]
+	_ = x[MHPMEVENT25-825]
+	_ = x[MHPMEVENT26-826]
+	_ = x[MHPMEVENT27-827]
+	_ = x[MHPMEVENT28-828]
+	_ = x[MHPMEVENT29-829]
+	_ = x[MHPMEVENT30-830]
+	_ = x[MHPMEVENT31-831]
+	_ = x[MSCRATCH-832]
+	_ = x[MEPC-833]
+	_ = x[MCAUSE-834]
+	_ = x[MTVAL-835]
+	_ = x[MIP-836]
+	_ = x[MNXTI-837]
+	_ = x[MINTSTATUS-838]
+	_ = x[MSCRATCHCSW-840]
+	_ = x[MSCRATCHCSWL-841]
+	_ = x[MTINST-842]
+	_ = x[MTVAL2-843]
+	_ = x[PMPCFG0-928]
+	_ = x[PMPCFG1-929]
+	_ = x[PMPCFG2-930]
+	_ = x[PMPCFG3-931]
+	_ = x[PMPADDR0-944]
+	_ = x[PMPADDR1-945]
+	_ = x[PMPADDR2-946]
+	_ = x[PMPADDR3-947]
+	_ = x[PMPADDR4-948]
+	_ = x[PMPADDR5-949]
+	_ = x[PMPADDR6-950]
+	_ = x[PMPADDR7-951]
+	_ = x[PMPADDR8-952]
+	_ = x[PMPADDR9-953]
+	_ = x[PMPADDR10-954]
+	_ = x[PMPADDR11-955]
+	_ = x[PMPADDR12-956]
+	_ = x[PMPADDR13-957]
+	_ = x[PMPADDR14-958]
+	_ = x[PMPADDR15-959]
+	_ = x[HSTATUS-1536]
+	_ = x[HEDELEG-1538]
+	_ = x[HIDELEG-1539]
+	_ = x[HIE-1540]
+	_ = x[HTIMEDELTA-1541]
+	_ = x[HCOUNTEREN-1542]
+	_ = x[HGEIE-1543]
+	_ = x[HTIMEDELTAH-1557]
+	_ = x[HTVAL-1603]
+	_ = x[HIP-1604]
+	_ = x[HVIP-1605]
+	_ = x[HTINST-1610]
+	_ = x[HGATP-1664]
+	_ = x[TSELECT-1952]
+	_ = x[TDATA1-1953]
+	_ = x[TDATA2-1954]
+	_ = x[TDATA3-1955]
+	_ = x[TINFO-1956]
+	_ = x[TCONTROL-1957]
+	_ = x[MCONTEXT-1960]
+	_ = x[MNOISE-1961]
+	_ = x[SCONTEXT-1962]
+	_ = x[DCSR-1968]
+	_ = x[DPC-1969]
+	_ = x[DSCRATCH0-1970]
+	_ = x[DSCRATCH1-1971]
+	_ = x[MCYCLE-2816]
+	_ = x[MINSTRET-2818]
+	_ = x[MHPMCOUNTER3-2819]
+	_ = x[MHPMCOUNTER4-2820]
+	_ = x[MHPMCOUNTER5-2821]
+	_ = x[MHPMCOUNTER6-2822]
+	_ = x[MHPMCOUNTER7-2823]
+	_ = x[MHPMCOUNTER8-2824]
+	_ = x[MHPMCOUNTER9-2825]
+	_ = x[MHPMCOUNTER10-2826]
+	_ = x[MHPMCOUNTER11-2827]
+	_ = x[MHPMCOUNTER12-2828]
+	_ = x[MHPMCOUNTER13-2829]
+	_ = x[MHPMCOUNTER14-2830]
+	_ = x[MHPMCOUNTER15-2831]
+	_ = x[MHPMCOUNTER16-2832]
+	_ = x[MHPMCOUNTER17-2833]
+	_ = x[MHPMCOUNTER18-2834]
+	_ = x[MHPMCOUNTER19-2835]
+	_ = x[MHPMCOUNTER20-2836]
+	_ = x[MHPMCOUNTER21-2837]
+	_ = x[MHPMCOUNTER22-2838]
+	_ = x[MHPMCOUNTER23-2839]
+	_ = x[MHPMCOUNTER24-2840]
+	_ = x[MHPMCOUNTER25-2841]
+	_ = x[MHPMCOUNTER26-2842]
+	_ = x[MHPMCOUNTER27-2843]
+	_ = x[MHPMCOUNTER28-2844]
+	_ = x[MHPMCOUNTER29-2845]
+	_ = x[MHPMCOUNTER30-2846]
+	_ = x[MHPMCOUNTER31-2847]
+	_ = x[MCYCLEH-2944]
+	_ = x[MINSTRETH-2946]
+	_ = x[MHPMCOUNTER3H-2947]
+	_ = x[MHPMCOUNTER4H-2948]
+	_ = x[MHPMCOUNTER5H-2949]
+	_ = x[MHPMCOUNTER6H-2950]
+	_ = x[MHPMCOUNTER7H-2951]
+	_ = x[MHPMCOUNTER8H-2952]
+	_ = x[MHPMCOUNTER9H-2953]
+	_ = x[MHPMCOUNTER10H-2954]
+	_ = x[MHPMCOUNTER11H-2955]
+	_ = x[MHPMCOUNTER12H-2956]
+	_ = x[MHPMCOUNTER13H-2957]
+	_ = x[MHPMCOUNTER14H-2958]
+	_ = x[MHPMCOUNTER15H-2959]
+	_ = x[MHPMCOUNTER16H-2960]
+	_ = x[MHPMCOUNTER17H-2961]
+	_ = x[MHPMCOUNTER18H-2962]
+	_ = x[MHPMCOUNTER19H-2963]
+	_ = x[MHPMCOUNTER20H-2964]
+	_ = x[MHPMCOUNTER21H-2965]
+	_ = x[MHPMCOUNTER22H-2966]
+	_ = x[MHPMCOUNTER23H-2967]
+	_ = x[MHPMCOUNTER24H-2968]
+	_ = x[MHPMCOUNTER25H-2969]
+	_ = x[MHPMCOUNTER26H-2970]
+	_ = x[MHPMCOUNTER27H-2971]
+	_ = x[MHPMCOUNTER28H-2972]
+	_ = x[MHPMCOUNTER29H-2973]
+	_ = x[MHPMCOUNTER30H-2974]
+	_ = x[MHPMCOUNTER31H-2975]
+	_ = x[CYCLE-3072]
+	_ = x[TIME-3073]
+	_ = x[INSTRET-3074]
+	_ = x[HPMCOUNTER3-3075]
+	_ = x[HPMCOUNTER4-3076]
+	_ = x[HPMCOUNTER5-3077]
+	_ = x[HPMCOUNTER6-3078]
+	_ = x[HPMCOUNTER7-3079]
+	_ = x[HPMCOUNTER8-3080]
+	_ = x[HPMCOUNTER9-3081]
+	_ = x[HPMCOUNTER10-3082]
+	_ = x[HPMCOUNTER11-3083]
+	_ = x[HPMCOUNTER12-3084]
+	_ = x[HPMCOUNTER13-3085]
+	_ = x[HPMCOUNTER14-3086]
+	_ = x[HPMCOUNTER15-3087]
+	_ = x[HPMCOUNTER16-3088]
+	_ = x[HPMCOUNTER17-3089]
+	_ = x[HPMCOUNTER18-3090]
+	_ = x[HPMCOUNTER19-3091]
+	_ = x[HPMCOUNTER20-3092]
+	_ = x[HPMCOUNTER21-3093]
+	_ = x[HPMCOUNTER22-3094]
+	_ = x[HPMCOUNTER23-3095]
+	_ = x[HPMCOUNTER24-3096]
+	_ = x[HPMCOUNTER25-3097]
+	_ = x[HPMCOUNTER26-3098]
+	_ = x[HPMCOUNTER27-3099]
+	_ = x[HPMCOUNTER28-3100]
+	_ = x[HPMCOUNTER29-3101]
+	_ = x[HPMCOUNTER30-3102]
+	_ = x[HPMCOUNTER31-3103]
+	_ = x[VL-3104]
+	_ = x[VTYPE-3105]
+	_ = x[VLENB-3106]
+	_ = x[CYCLEH-3200]
+	_ = x[TIMEH-3201]
+	_ = x[INSTRETH-3202]
+	_ = x[HPMCOUNTER3H-3203]
+	_ = x[HPMCOUNTER4H-3204]
+	_ = x[HPMCOUNTER5H-3205]
+	_ = x[HPMCOUNTER6H-3206]
+	_ = x[HPMCOUNTER7H-3207]
+	_ = x[HPMCOUNTER8H-3208]
+	_ = x[HPMCOUNTER9H-3209]
+	_ = x[HPMCOUNTER10H-3210]
+	_ = x[HPMCOUNTER11H-3211]
+	_ = x[HPMCOUNTER12H-3212]
+	_ = x[HPMCOUNTER13H-3213]
+	_ = x[HPMCOUNTER14H-3214]
+	_ = x[HPMCOUNTER15H-3215]
+	_ = x[HPMCOUNTER16H-3216]
+	_ = x[HPMCOUNTER17H-3217]
+	_ = x[HPMCOUNTER18H-3218]
+	_ = x[HPMCOUNTER19H-3219]
+	_ = x[HPMCOUNTER20H-3220]
+	_ = x[HPMCOUNTER21H-3221]
+	_ = x[HPMCOUNTER22H-3222]
+	_ = x[HPMCOUNTER23H-3223]
+	_ = x[HPMCOUNTER24H-3224]
+	_ = x[HPMCOUNTER25H-3225]
+	_ = x[HPMCOUNTER26H-3226]
+	_ = x[HPMCOUNTER27H-3227]
+	_ = x[HPMCOUNTER28H-3228]
+	_ = x[HPMCOUNTER29H-3229]
+	_ = x[HPMCOUNTER30H-3230]
+	_ = x[HPMCOUNTER31H-3231]
+	_ = x[HGEIP-3602]
+	_ = x[MVENDORID-3857]
+	_ = x[MARCHID-3858]
+	_ = x[MIMPID-3859]
+	_ = x[MHARTID-3860]
+	_ = x[MENTROPY-3861]
+}
+
+const _Csr_name = "USTATUSFFLAGSFRMFCSRUIEUTVECUTVTVSTARTVXSATVXRMVCSRUSCRATCHUEPCUCAUSEUTVALUIPUNXTIUINTSTATUSUSCRATCHCSWUSCRATCHCSWLSSTATUSSEDELEGSIDELEGSIESTVECSCOUNTERENSTVTSSCRATCHSEPCSCAUSESTVALSIPSNXTISINTSTATUSSSCRATCHCSWSSCRATCHCSWLSATPVSSTATUSVSIEVSTVECVSSCRATCHVSEPCVSCAUSEVSTVALVSIPVSATPMSTATUSMISAMEDELEGMIDELEGMIEMTVECMCOUNTERENMTVTMSTATUSHMCOUNTINHIBITMHPMEVENT3MHPMEVENT4MHPMEVENT5MHPMEVENT6MHPMEVENT7MHPMEVENT8MHPMEVENT9MHPMEVENT10MHPMEVENT11MHPMEVENT12MHPMEVENT13MHPMEVENT14MHPMEVENT15MHPMEVENT16MHPMEVENT17MHPMEVENT18MHPMEVENT19MHPMEVENT20MHPMEVENT21MHPMEVENT22MHPMEVENT23MHPMEVENT24MHPMEVENT25MHPMEVENT26MHPMEVENT27MHPMEVENT28MHPMEVENT29MHPMEVENT30MHPMEVENT31MSCRATCHMEPCMCAUSEMTVALMIPMNXTIMINTSTATUSMSCRATCHCSWMSCRATCHCSWLMTINSTMTVAL2PMPCFG0PMPCFG1PMPCFG2PMPCFG3PMPADDR0PMPADDR1PMPADDR2PMPADDR3PMPADDR4PMPADDR5PMPADDR6PMPADDR7PMPADDR8PMPADDR9PMPADDR10PMPADDR11PMPADDR12PMPADDR13PMPADDR14PMPADDR15HSTATUSHEDELEGHIDELEGHIEHTIMEDELTAHCOUNTERENHGEIEHTIMEDELTAHHTVALHIPHVIPHTINSTHGATPTSELECTTDATA1TDATA2TDATA3TINFOTCONTROLMCONTEXTMNOISESCONTEXTDCSRDPCDSCRATCH0DSCRATCH1MCYCLEMINSTRETMHPMCOUNTER3MHPMCOUNTER4MHPMCOUNTER5MHPMCOUNTER6MHPMCOUNTER7MHPMCOUNTER8MHPMCOUNTER9MHPMCOUNTER10MHPMCOUNTER11MHPMCOUNTER12MHPMCOUNTER13MHPMCOUNTER14MHPMCOUNTER15MHPMCOUNTER16MHPMCOUNTER17MHPMCOUNTER18MHPMCOUNTER19MHPMCOUNTER20MHPMCOUNTER21MHPMCOUNTER22MHPMCOUNTER23MHPMCOUNTER24MHPMCOUNTER25MHPMCOUNTER26MHPMCOUNTER27MHPMCOUNTER28MHPMCOUNTER29MHPMCOUNTER30MHPMCOUNTER31MCYCLEHMINSTRETHMHPMCOUNTER3HMHPMCOUNTER4HMHPMCOUNTER5HMHPMCOUNTER6HMHPMCOUNTER7HMHPMCOUNTER8HMHPMCOUNTER9HMHPMCOUNTER10HMHPMCOUNTER11HMHPMCOUNTER12HMHPMCOUNTER13HMHPMCOUNTER14HMHPMCOUNTER15HMHPMCOUNTER16HMHPMCOUNTER17HMHPMCOUNTER18HMHPMCOUNTER19HMHPMCOUNTER20HMHPMCOUNTER21HMHPMCOUNTER22HMHPMCOUNTER23HMHPMCOUNTER24HMHPMCOUNTER25HMHPMCOUNTER26HMHPMCOUNTER27HMHPMCOUNTER28HMHPMCOUNTER29HMHPMCOUNTER30HMHPMCOUNTER31HCYCLETIMEINSTRETHPMCOUNTER3HPMCOUNTER4HPMCOUNTER5HPMCOUNTER6HPMCOUNTER7HPMCOUNTER8HPMCOUNTER9HPMCOUNTER10HPMCOUNTER11HPMCOUNTER12HPMCOUNTER13HPMCOUNTER14HPMCOUNTER15HPMCOUNTER16HPMCOUNTER17HPMCOUNTER18HPMCOUNTER19HPMCOUNTER20HPMCOUNTER21HPMCOUNTER22HPMCOUNTER23HPMCOUNTER24HPMCOUNTER25HPMCOUNTER26HPMCOUNTER27HPMCOUNTER28HPMCOUNTER29HPMCOUNTER30HPMCOUNTER31VLVTYPEVLENBCYCLEHTIMEHINSTRETHHPMCOUNTER3HHPMCOUNTER4HHPMCOUNTER5HHPMCOUNTER6HHPMCOUNTER7HHPMCOUNTER8HHPMCOUNTER9HHPMCOUNTER10HHPMCOUNTER11HHPMCOUNTER12HHPMCOUNTER13HHPMCOUNTER14HHPMCOUNTER15HHPMCOUNTER16HHPMCOUNTER17HHPMCOUNTER18HHPMCOUNTER19HHPMCOUNTER20HHPMCOUNTER21HHPMCOUNTER22HHPMCOUNTER23HHPMCOUNTER24HHPMCOUNTER25HHPMCOUNTER26HHPMCOUNTER27HHPMCOUNTER28HHPMCOUNTER29HHPMCOUNTER30HHPMCOUNTER31HHGEIPMVENDORIDMARCHIDMIMPIDMHARTIDMENTROPY"
+
+var _Csr_map = map[Csr]string{
+	0:    _Csr_name[0:7],
+	1:    _Csr_name[7:13],
+	2:    _Csr_name[13:16],
+	3:    _Csr_name[16:20],
+	4:    _Csr_name[20:23],
+	5:    _Csr_name[23:28],
+	7:    _Csr_name[28:32],
+	8:    _Csr_name[32:38],
+	9:    _Csr_name[38:43],
+	10:   _Csr_name[43:47],
+	15:   _Csr_name[47:51],
+	64:   _Csr_name[51:59],
+	65:   _Csr_name[59:63],
+	66:   _Csr_name[63:69],
+	67:   _Csr_name[69:74],
+	68:   _Csr_name[74:77],
+	69:   _Csr_name[77:82],
+	70:   _Csr_name[82:92],
+	72:   _Csr_name[92:103],
+	73:   _Csr_name[103:115],
+	256:  _Csr_name[115:122],
+	258:  _Csr_name[122:129],
+	259:  _Csr_name[129:136],
+	260:  _Csr_name[136:139],
+	261:  _Csr_name[139:144],
+	262:  _Csr_name[144:154],
+	263:  _Csr_name[154:158],
+	320:  _Csr_name[158:166],
+	321:  _Csr_name[166:170],
+	322:  _Csr_name[170:176],
+	323:  _Csr_name[176:181],
+	324:  _Csr_name[181:184],
+	325:  _Csr_name[184:189],
+	326:  _Csr_name[189:199],
+	328:  _Csr_name[199:210],
+	329:  _Csr_name[210:222],
+	384:  _Csr_name[222:226],
+	512:  _Csr_name[226:234],
+	516:  _Csr_name[234:238],
+	517:  _Csr_name[238:244],
+	576:  _Csr_name[244:253],
+	577:  _Csr_name[253:258],
+	578:  _Csr_name[258:265],
+	579:  _Csr_name[265:271],
+	580:  _Csr_name[271:275],
+	640:  _Csr_name[275:280],
+	768:  _Csr_name[280:287],
+	769:  _Csr_name[287:291],
+	770:  _Csr_name[291:298],
+	771:  _Csr_name[298:305],
+	772:  _Csr_name[305:308],
+	773:  _Csr_name[308:313],
+	774:  _Csr_name[313:323],
+	775:  _Csr_name[323:327],
+	784:  _Csr_name[327:335],
+	800:  _Csr_name[335:348],
+	803:  _Csr_name[348:358],
+	804:  _Csr_name[358:368],
+	805:  _Csr_name[368:378],
+	806:  _Csr_name[378:388],
+	807:  _Csr_name[388:398],
+	808:  _Csr_name[398:408],
+	809:  _Csr_name[408:418],
+	810:  _Csr_name[418:429],
+	811:  _Csr_name[429:440],
+	812:  _Csr_name[440:451],
+	813:  _Csr_name[451:462],
+	814:  _Csr_name[462:473],
+	815:  _Csr_name[473:484],
+	816:  _Csr_name[484:495],
+	817:  _Csr_name[495:506],
+	818:  _Csr_name[506:517],
+	819:  _Csr_name[517:528],
+	820:  _Csr_name[528:539],
+	821:  _Csr_name[539:550],
+	822:  _Csr_name[550:561],
+	823:  _Csr_name[561:572],
+	824:  _Csr_name[572:583],
+	825:  _Csr_name[583:594],
+	826:  _Csr_name[594:605],
+	827:  _Csr_name[605:616],
+	828:  _Csr_name[616:627],
+	829:  _Csr_name[627:638],
+	830:  _Csr_name[638:649],
+	831:  _Csr_name[649:660],
+	832:  _Csr_name[660:668],
+	833:  _Csr_name[668:672],
+	834:  _Csr_name[672:678],
+	835:  _Csr_name[678:683],
+	836:  _Csr_name[683:686],
+	837:  _Csr_name[686:691],
+	838:  _Csr_name[691:701],
+	840:  _Csr_name[701:712],
+	841:  _Csr_name[712:724],
+	842:  _Csr_name[724:730],
+	843:  _Csr_name[730:736],
+	928:  _Csr_name[736:743],
+	929:  _Csr_name[743:750],
+	930:  _Csr_name[750:757],
+	931:  _Csr_name[757:764],
+	944:  _Csr_name[764:772],
+	945:  _Csr_name[772:780],
+	946:  _Csr_name[780:788],
+	947:  _Csr_name[788:796],
+	948:  _Csr_name[796:804],
+	949:  _Csr_name[804:812],
+	950:  _Csr_name[812:820],
+	951:  _Csr_name[820:828],
+	952:  _Csr_name[828:836],
+	953:  _Csr_name[836:844],
+	954:  _Csr_name[844:853],
+	955:  _Csr_name[853:862],
+	956:  _Csr_name[862:871],
+	957:  _Csr_name[871:880],
+	958:  _Csr_name[880:889],
+	959:  _Csr_name[889:898],
+	1536: _Csr_name[898:905],
+	1538: _Csr_name[905:912],
+	1539: _Csr_name[912:919],
+	1540: _Csr_name[919:922],
+	1541: _Csr_name[922:932],
+	1542: _Csr_name[932:942],
+	1543: _Csr_name[942:947],
+	1557: _Csr_name[947:958],
+	1603: _Csr_name[958:963],
+	1604: _Csr_name[963:966],
+	1605: _Csr_name[966:970],
+	1610: _Csr_name[970:976],
+	1664: _Csr_name[976:981],
+	1952: _Csr_name[981:988],
+	1953: _Csr_name[988:994],
+	1954: _Csr_name[994:1000],
+	1955: _Csr_name[1000:1006],
+	1956: _Csr_name[1006:1011],
+	1957: _Csr_name[1011:1019],
+	1960: _Csr_name[1019:1027],
+	1961: _Csr_name[1027:1033],
+	1962: _Csr_name[1033:1041],
+	1968: _Csr_name[1041:1045],
+	1969: _Csr_name[1045:1048],
+	1970: _Csr_name[1048:1057],
+	1971: _Csr_name[1057:1066],
+	2816: _Csr_name[1066:1072],
+	2818: _Csr_name[1072:1080],
+	2819: _Csr_name[1080:1092],
+	2820: _Csr_name[1092:1104],
+	2821: _Csr_name[1104:1116],
+	2822: _Csr_name[1116:1128],
+	2823: _Csr_name[1128:1140],
+	2824: _Csr_name[1140:1152],
+	2825: _Csr_name[1152:1164],
+	2826: _Csr_name[1164:1177],
+	2827: _Csr_name[1177:1190],
+	2828: _Csr_name[1190:1203],
+	2829: _Csr_name[1203:1216],
+	2830: _Csr_name[1216:1229],
+	2831: _Csr_name[1229:1242],
+	2832: _Csr_name[1242:1255],
+	2833: _Csr_name[1255:1268],
+	2834: _Csr_name[1268:1281],
+	2835: _Csr_name[1281:1294],
+	2836: _Csr_name[1294:1307],
+	2837: _Csr_name[1307:1320],
+	2838: _Csr_name[1320:1333],
+	2839: _Csr_name[1333:1346],
+	2840: _Csr_name[1346:1359],
+	2841: _Csr_name[1359:1372],
+	2842: _Csr_name[1372:1385],
+	2843: _Csr_name[1385:1398],
+	2844: _Csr_name[1398:1411],
+	2845: _Csr_name[1411:1424],
+	2846: _Csr_name[1424:1437],
+	2847: _Csr_name[1437:1450],
+	2944: _Csr_name[1450:1457],
+	2946: _Csr_name[1457:1466],
+	2947: _Csr_name[1466:1479],
+	2948: _Csr_name[1479:1492],
+	2949: _Csr_name[1492:1505],
+	2950: _Csr_name[1505:1518],
+	2951: _Csr_name[1518:1531],
+	2952: _Csr_name[1531:1544],
+	2953: _Csr_name[1544:1557],
+	2954: _Csr_name[1557:1571],
+	2955: _Csr_name[1571:1585],
+	2956: _Csr_name[1585:1599],
+	2957: _Csr_name[1599:1613],
+	2958: _Csr_name[1613:1627],
+	2959: _Csr_name[1627:1641],
+	2960: _Csr_name[1641:1655],
+	2961: _Csr_name[1655:1669],
+	2962: _Csr_name[1669:1683],
+	2963: _Csr_name[1683:1697],
+	2964: _Csr_name[1697:1711],
+	2965: _Csr_name[1711:1725],
+	2966: _Csr_name[1725:1739],
+	2967: _Csr_name[1739:1753],
+	2968: _Csr_name[1753:1767],
+	2969: _Csr_name[1767:1781],
+	2970: _Csr_name[1781:1795],
+	2971: _Csr_name[1795:1809],
+	2972: _Csr_name[1809:1823],
+	2973: _Csr_name[1823:1837],
+	2974: _Csr_name[1837:1851],
+	2975: _Csr_name[1851:1865],
+	3072: _Csr_name[1865:1870],
+	3073: _Csr_name[1870:1874],
+	3074: _Csr_name[1874:1881],
+	3075: _Csr_name[1881:1892],
+	3076: _Csr_name[1892:1903],
+	3077: _Csr_name[1903:1914],
+	3078: _Csr_name[1914:1925],
+	3079: _Csr_name[1925:1936],
+	3080: _Csr_name[1936:1947],
+	3081: _Csr_name[1947:1958],
+	3082: _Csr_name[1958:1970],
+	3083: _Csr_name[1970:1982],
+	3084: _Csr_name[1982:1994],
+	3085: _Csr_name[1994:2006],
+	3086: _Csr_name[2006:2018],
+	3087: _Csr_name[2018:2030],
+	3088: _Csr_name[2030:2042],
+	3089: _Csr_name[2042:2054],
+	3090: _Csr_name[2054:2066],
+	3091: _Csr_name[2066:2078],
+	3092: _Csr_name[2078:2090],
+	3093: _Csr_name[2090:2102],
+	3094: _Csr_name[2102:2114],
+	3095: _Csr_name[2114:2126],
+	3096: _Csr_name[2126:2138],
+	3097: _Csr_name[2138:2150],
+	3098: _Csr_name[2150:2162],
+	3099: _Csr_name[2162:2174],
+	3100: _Csr_name[2174:2186],
+	3101: _Csr_name[2186:2198],
+	3102: _Csr_name[2198:2210],
+	3103: _Csr_name[2210:2222],
+	3104: _Csr_name[2222:2224],
+	3105: _Csr_name[2224:2229],
+	3106: _Csr_name[2229:2234],
+	3200: _Csr_name[2234:2240],
+	3201: _Csr_name[2240:2245],
+	3202: _Csr_name[2245:2253],
+	3203: _Csr_name[2253:2265],
+	3204: _Csr_name[2265:2277],
+	3205: _Csr_name[2277:2289],
+	3206: _Csr_name[2289:2301],
+	3207: _Csr_name[2301:2313],
+	3208: _Csr_name[2313:2325],
+	3209: _Csr_name[2325:2337],
+	3210: _Csr_name[2337:2350],
+	3211: _Csr_name[2350:2363],
+	3212: _Csr_name[2363:2376],
+	3213: _Csr_name[2376:2389],
+	3214: _Csr_name[2389:2402],
+	3215: _Csr_name[2402:2415],
+	3216: _Csr_name[2415:2428],
+	3217: _Csr_name[2428:2441],
+	3218: _Csr_name[2441:2454],
+	3219: _Csr_name[2454:2467],
+	3220: _Csr_name[2467:2480],
+	3221: _Csr_name[2480:2493],
+	3222: _Csr_name[2493:2506],
+	3223: _Csr_name[2506:2519],
+	3224: _Csr_name[2519:2532],
+	3225: _Csr_name[2532:2545],
+	3226: _Csr_name[2545:2558],
+	3227: _Csr_name[2558:2571],
+	3228: _Csr_name[2571:2584],
+	3229: _Csr_name[2584:2597],
+	3230: _Csr_name[2597:2610],
+	3231: _Csr_name[2610:2623],
+	3602: _Csr_name[2623:2628],
+	3857: _Csr_name[2628:2637],
+	3858: _Csr_name[2637:2644],
+	3859: _Csr_name[2644:2650],
+	3860: _Csr_name[2650:2657],
+	3861: _Csr_name[2657:2665],
+}
+
+func (i Csr) String() string {
+	if str, ok := _Csr_map[i]; ok {
+		return str
+	}
+	return "Csr(" + strconv.FormatInt(int64(i), 10) + ")"
+}
diff -Naur delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/decode.go delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/decode.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/decode.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/decode.go	2024-08-01 19:32:55.266781291 +0800
@@ -0,0 +1,611 @@
+// 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 riscv64asm
+
+import (
+	"encoding/binary"
+	"fmt"
+)
+
+type instArgs [6]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) < 2 {
+		return Inst{}, errShort
+	}
+	var length = len(src)
+	var x uint32
+	// Non-RVC instructions always starts with 0x11
+	// So check whether src[0] & 3 == 3
+	if src[0]&3 == 3 {
+		length = 4
+		x = binary.LittleEndian.Uint32(src)
+	} else {
+		length = 2
+		x = uint32(binary.LittleEndian.Uint16(src))
+	}
+
+Search:
+	for i, f := range instFormats {
+		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 && f.op != C_NOP {
+				// Cannot decode argument.
+				continue Search
+			}
+			args[j] = arg
+		}
+
+		if length == 2 {
+			args = convertCompressedIns(&f, args)
+		}
+
+		decoderCover[i] = true
+		inst = Inst{
+			Op:   f.op,
+			Args: args,
+			Enc:  x,
+			Len:  length,
+		}
+		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_rd:
+		return X0 + Reg((x>>7)&((1<<5)-1))
+
+	case arg_rs1:
+		return X0 + Reg((x>>15)&((1<<5)-1))
+
+	case arg_rs2:
+		return X0 + Reg((x>>20)&((1<<5)-1))
+
+	case arg_rs3:
+		return X0 + Reg((x>>27)&((1<<5)-1))
+
+	case arg_fd:
+		return F0 + Reg((x>>7)&((1<<5)-1))
+
+	case arg_fs1:
+		return F0 + Reg((x>>15)&((1<<5)-1))
+
+	case arg_fs2:
+		return F0 + Reg((x>>20)&((1<<5)-1))
+
+	case arg_fs3:
+		return F0 + Reg((x>>27)&((1<<5)-1))
+
+	case arg_rs1_amo:
+		return AmoReg{X0 + Reg((x>>15)&((1<<5)-1))}
+
+	case arg_rs1_mem:
+		var tmp uint32
+		tmp = x >> 20
+		// Sign-extend
+		if tmp>>uint32(12-1) == 1 {
+			tmp |= 0xfffff << 12
+		}
+		return RegOffset{X0 + Reg((x>>15)&((1<<5)-1)), Simm{int32(tmp), true, 12}}
+
+	case arg_rs1_store:
+		var tmp uint32
+		tmp = (x<<20)>>27 |
+			(x>>25)<<5
+		// Sign-extend
+		if tmp>>uint32(12-1) == 1 {
+			tmp |= 0xfffff << 12
+		}
+		return RegOffset{X0 + Reg((x>>15)&((1<<5)-1)), Simm{int32(tmp), true, 12}}
+
+	case arg_pred:
+		var tmp uint32
+		tmp = x << 4 >> 28
+		return MemOrder(uint8(tmp))
+
+	case arg_succ:
+		var tmp uint32
+		tmp = x << 8 >> 28
+		return MemOrder(uint8(tmp))
+
+	case arg_csr:
+		var tmp uint32
+		tmp = x >> 20
+		return Csr(tmp)
+
+	case arg_zimm:
+		var tmp uint32
+		tmp = x << 12 >> 27
+		return Uimm{tmp, true}
+
+	case arg_shamt5:
+		var tmp uint32
+		tmp = x << 7 >> 27
+		return Uimm{tmp, false}
+
+	case arg_shamt6:
+		var tmp uint32
+		tmp = x << 6 >> 26
+		return Uimm{tmp, false}
+
+	case arg_imm12:
+		var tmp uint32
+		tmp = x >> 20
+		// Sign-extend
+		if tmp>>uint32(12-1) == 1 {
+			tmp |= 0xfffff << 12
+		}
+		return Simm{int32(tmp), true, 12}
+
+	case arg_imm20:
+		var tmp uint32
+		tmp = x >> 12
+		return Uimm{tmp, false}
+
+	case arg_jimm20:
+		var tmp uint32
+		tmp = (x>>31)<<20 |
+			(x<<1)>>22<<1 |
+			(x<<11)>>31<<11 |
+			(x<<12)>>24<<12
+		// Sign-extend
+		if tmp>>uint32(21-1) == 1 {
+			tmp |= 0x7ff << 21
+		}
+		return Simm{int32(tmp), true, 21}
+
+	case arg_simm12:
+		var tmp uint32
+		tmp = (x<<20)>>27 |
+			(x>>25)<<5
+		// Sign-extend
+		if tmp>>uint32(12-1) == 1 {
+			tmp |= 0xfffff << 12
+		}
+		return Simm{int32(tmp), true, 12}
+
+	case arg_bimm12:
+		var tmp uint32
+		tmp = (x<<20)>>28<<1 |
+			(x<<1)>>26<<5 |
+			(x<<24)>>31<<11 |
+			(x>>31)<<12
+		// Sign-extend
+		if tmp>>uint32(13-1) == 1 {
+			tmp |= 0x7ffff << 13
+		}
+		return Simm{int32(tmp), true, 13}
+
+	case arg_rd_p, arg_rs2_p:
+		return X8 + Reg((x>>2)&((1<<3)-1))
+
+	case arg_fd_p, arg_fs2_p:
+		return F8 + Reg((x>>2)&((1<<3)-1))
+
+	case arg_rs1_p, arg_rd_rs1_p:
+		return X8 + Reg((x>>7)&((1<<3)-1))
+
+	case arg_rd_n0, arg_rs1_n0, arg_rd_rs1_n0, arg_c_rs1_n0:
+		if X0+Reg((x>>7)&((1<<5)-1)) == X0 {
+			return nil
+		}
+		return X0 + Reg((x>>7)&((1<<5)-1))
+
+	case arg_c_rs2_n0:
+		if X0+Reg((x>>2)&((1<<5)-1)) == X0 {
+			return nil
+		}
+		return X0 + Reg((x>>2)&((1<<5)-1))
+
+	case arg_c_fs2:
+		return F0 + Reg((x>>2)&((1<<5)-1))
+
+	case arg_c_rs2:
+		return X0 + Reg((x>>2)&((1<<5)-1))
+
+	case arg_rd_n2:
+		if X0+Reg((x>>7)&((1<<5)-1)) == X0 || X0+Reg((x>>7)&((1<<5)-1)) == X2 {
+			return nil
+		}
+		return X0 + Reg((x>>7)&((1<<5)-1))
+
+	case arg_c_imm6:
+		var tmp uint32
+		tmp = (x<<25)>>27 | (x<<19)>>31<<5
+		// Sign-extend
+		if tmp>>uint32(6-1) == 1 {
+			tmp |= 0x3ffffff << 6
+		}
+		return Simm{int32(tmp), true, 6}
+
+	case arg_c_nzimm6:
+		var tmp uint32
+		tmp = (x<<25)>>27 | (x<<19)>>31<<5
+		// Sign-extend
+		if tmp>>uint32(6-1) == 1 {
+			tmp |= 0x3ffffff << 6
+		}
+		if int32(tmp) == 0 {
+			return nil
+		}
+		return Simm{int32(tmp), true, 6}
+
+	case arg_c_nzuimm6:
+		var tmp uint32
+		tmp = (x<<25)>>27 | (x<<19)>>31<<5
+		if int32(tmp) == 0 {
+			return nil
+		}
+		return Uimm{tmp, false}
+
+	case arg_c_uimm7:
+		var tmp uint32
+		tmp = (x<<26)>>31<<6 |
+			(x<<25)>>31<<2 |
+			(x<<19)>>29<<3
+
+		return Uimm{tmp, false}
+
+	case arg_c_uimm8:
+		var tmp uint32
+		tmp = (x<<25)>>30<<6 | (x<<19)>>29<<3
+
+		return Uimm{tmp, false}
+
+	case arg_c_uimm8sp_s:
+		var tmp uint32
+		tmp = (x<<23)>>30<<6 | (x<<19)>>28<<2
+
+		return Uimm{tmp, false}
+
+	case arg_c_uimm8sp:
+		var tmp uint32
+		tmp = (x<<25)>>29<<2 |
+			(x<<19)>>31<<5 |
+			(x<<28)>>30<<6
+
+		return Uimm{tmp, false}
+
+	case arg_c_uimm9sp_s:
+		var tmp uint32
+		tmp = (x<<22)>>29<<6 | (x<<19)>>29<<3
+
+		return Uimm{tmp, false}
+
+	case arg_c_uimm9sp:
+		var tmp uint32
+		tmp = (x<<25)>>30<<3 |
+			(x<<19)>>31<<5 |
+			(x<<27)>>29<<6
+
+		return Uimm{tmp, false}
+
+	case arg_c_bimm9:
+		var tmp uint32
+		tmp = (x<<29)>>31<<5 |
+			(x<<27)>>30<<1 |
+			(x<<25)>>30<<6 |
+			(x<<19)>>31<<8 |
+			(x<<20)>>30<<3
+		// Sign-extend
+		if tmp>>uint32(9-1) == 1 {
+			tmp |= 0x7fffff << 9
+		}
+		return Simm{int32(tmp), true, 9}
+
+	case arg_c_nzimm10:
+		var tmp uint32
+		tmp = (x<<29)>>31<<5 |
+			(x<<27)>>30<<7 |
+			(x<<26)>>31<<6 |
+			(x<<25)>>31<<4 |
+			(x<<19)>>31<<9
+		// Sign-extend
+		if tmp>>uint32(10-1) == 1 {
+			tmp |= 0x3fffff << 10
+		}
+		if int32(tmp) == 0 {
+			return nil
+		}
+		return Simm{int32(tmp), true, 10}
+
+	case arg_c_nzuimm10:
+		var tmp uint32
+		tmp = (x<<26)>>31<<3 |
+			(x<<25)>>31<<2 |
+			(x<<21)>>28<<6 |
+			(x<<19)>>30<<4
+		if int32(tmp) == 0 {
+			return nil
+		}
+		return Uimm{tmp, false}
+
+	case arg_c_imm12:
+		var tmp uint32
+		tmp = (x<<29)>>31<<5 |
+			(x<<26)>>28<<1 |
+			(x<<25)>>31<<7 |
+			(x<<24)>>31<<6 |
+			(x<<23)>>31<<10 |
+			(x<<21)>>30<<8 |
+			(x<<20)>>31<<4 |
+			(x<<19)>>31<<11
+		// Sign-extend
+		if tmp>>uint32(12-1) == 1 {
+			tmp |= 0xfffff << 12
+		}
+		return Simm{int32(tmp), true, 12}
+
+	case arg_c_nzimm18:
+		var tmp uint32
+		tmp = (x<<25)>>27<<12 | (x<<19)>>31<<17
+		// Sign-extend
+		if tmp>>uint32(18-1) == 1 {
+			tmp |= 0x3fff << 18
+		}
+		if int32(tmp) == 0 {
+			return nil
+		}
+		return Simm{int32(tmp), true, 18}
+
+	default:
+		return nil
+	}
+}
+
+// convertCompressedIns rewrites the RVC Instruction to regular Instructions
+func convertCompressedIns(f *instFormat, args Args) Args {
+	var newargs Args
+	switch f.op {
+	case C_ADDI4SPN:
+		f.op = ADDI
+		newargs[0] = args[0]
+		newargs[1] = Reg(X2)
+		newargs[2] = Simm{int32(args[1].(Uimm).Imm), true, 12}
+
+	case C_LW:
+		f.op = LW
+		newargs[0] = args[0]
+		newargs[1] = RegOffset{args[1].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}}
+
+	case C_SW:
+		f.op = SW
+		newargs[0] = args[1]
+		newargs[1] = RegOffset{args[0].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}}
+
+	case C_NOP:
+		f.op = ADDI
+		newargs[0] = X0
+		newargs[1] = X0
+		newargs[2] = Simm{0, true, 12}
+
+	case C_ADDI:
+		f.op = ADDI
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = Simm{args[1].(Simm).Imm, true, 12}
+
+	case C_LI:
+		f.op = ADDI
+		newargs[0] = args[0]
+		newargs[1] = Reg(X0)
+		newargs[2] = Simm{args[1].(Simm).Imm, true, 12}
+
+	case C_ADDI16SP:
+		f.op = ADDI
+		newargs[0] = Reg(X2)
+		newargs[1] = Reg(X2)
+		newargs[2] = Simm{args[0].(Simm).Imm, true, 12}
+
+	case C_LUI:
+		f.op = LUI
+		newargs[0] = args[0]
+		newargs[1] = Uimm{uint32(args[1].(Simm).Imm >> 12), false}
+
+	case C_ANDI:
+		f.op = ANDI
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = Simm{args[1].(Simm).Imm, true, 12}
+
+	case C_SUB:
+		f.op = SUB
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = args[1]
+
+	case C_XOR:
+		f.op = XOR
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = args[1]
+
+	case C_OR:
+		f.op = OR
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = args[1]
+
+	case C_AND:
+		f.op = AND
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = args[1]
+
+	case C_J:
+		f.op = JAL
+		newargs[0] = Reg(X0)
+		newargs[1] = Simm{args[0].(Simm).Imm, true, 21}
+
+	case C_BEQZ:
+		f.op = BEQ
+		newargs[0] = args[0]
+		newargs[1] = Reg(X0)
+		newargs[2] = Simm{args[1].(Simm).Imm, true, 13}
+
+	case C_BNEZ:
+		f.op = BNE
+		newargs[0] = args[0]
+		newargs[1] = Reg(X0)
+		newargs[2] = Simm{args[1].(Simm).Imm, true, 13}
+
+	case C_LWSP:
+		f.op = LW
+		newargs[0] = args[0]
+		newargs[1] = RegOffset{Reg(X2), Simm{int32(args[1].(Uimm).Imm), true, 12}}
+
+	case C_JR:
+		f.op = JALR
+		newargs[0] = Reg(X0)
+		newargs[1] = RegOffset{args[0].(Reg), Simm{0, true, 12}}
+
+	case C_MV:
+		f.op = ADD
+		newargs[0] = args[0]
+		newargs[1] = Reg(X0)
+		newargs[2] = args[1]
+
+	case C_EBREAK:
+		f.op = EBREAK
+
+	case C_JALR:
+		f.op = JALR
+		newargs[0] = Reg(X1)
+		newargs[1] = RegOffset{args[0].(Reg), Simm{0, true, 12}}
+
+	case C_ADD:
+		f.op = ADD
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = args[1]
+
+	case C_SWSP:
+		f.op = SW
+		newargs[0] = args[0]
+		newargs[1] = RegOffset{Reg(X2), Simm{int32(args[1].(Uimm).Imm), true, 12}}
+
+	// riscv64 compressed instructions
+	case C_LD:
+		f.op = LD
+		newargs[0] = args[0]
+		newargs[1] = RegOffset{args[1].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}}
+
+	case C_SD:
+		f.op = SD
+		newargs[0] = args[1]
+		newargs[1] = RegOffset{args[0].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}}
+
+	case C_ADDIW:
+		f.op = ADDIW
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = Simm{args[1].(Simm).Imm, true, 12}
+
+	case C_SRLI:
+		f.op = SRLI
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = args[1]
+
+	case C_SRAI:
+		f.op = SRAI
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = args[1]
+
+	case C_SUBW:
+		f.op = SUBW
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = args[1]
+
+	case C_ADDW:
+		f.op = ADDW
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = args[1]
+
+	case C_SLLI:
+		f.op = SLLI
+		newargs[0] = args[0]
+		newargs[1] = args[0]
+		newargs[2] = args[1]
+
+	case C_LDSP:
+		f.op = LD
+		newargs[0] = args[0]
+		newargs[1] = RegOffset{Reg(X2), Simm{int32(args[1].(Uimm).Imm), true, 12}}
+
+	case C_SDSP:
+		f.op = SD
+		newargs[0] = args[0]
+		newargs[1] = RegOffset{Reg(X2), Simm{int32(args[1].(Uimm).Imm), true, 12}}
+
+	// riscv double persicion floating point compressed instructions
+	case C_FLD:
+		f.op = FLD
+		newargs[0] = args[0]
+		newargs[1] = RegOffset{args[1].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}}
+
+	case C_FSD:
+		f.op = FSD
+		newargs[0] = args[1]
+		newargs[1] = RegOffset{args[0].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}}
+
+	case C_FLDSP:
+		f.op = FLD
+		newargs[0] = args[0]
+		newargs[1] = RegOffset{Reg(X2), Simm{int32(args[1].(Uimm).Imm), true, 12}}
+
+	case C_FSDSP:
+		f.op = FSD
+		newargs[0] = args[0]
+		newargs[1] = RegOffset{Reg(X2), Simm{int32(args[1].(Uimm).Imm), true, 12}}
+
+	case C_UNIMP:
+		f.op = CSRRW
+		newargs[0] = Reg(X0)
+		newargs[1] = Csr(CYCLE)
+		newargs[2] = Reg(X0)
+	}
+	return newargs
+}
diff -Naur delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/gnu.go delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/gnu.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/gnu.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/gnu.go	2024-08-01 19:32:55.266781291 +0800
@@ -0,0 +1,337 @@
+// 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 riscv64asm
+
+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 RISC-V Instruction Set Manual. See
+// https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMAFDQC/riscv-spec-20191213.pdf
+func GNUSyntax(inst Inst) string {
+	op := strings.ToLower(inst.Op.String())
+	var args []string
+	for _, a := range inst.Args {
+		if a == nil {
+			break
+		}
+		args = append(args, strings.ToLower(a.String()))
+	}
+
+	// No need add "I" to opcode suffix.
+	// Binutils version 2.40
+	var immOpcodes = map[Op]Op{
+		ADDI:   ADD,
+		ADDIW:  ADDW,
+		ANDI:   AND,
+		CSRRCI: CSRRC,
+		CSRRSI: CSRRS,
+		CSRRWI: CSRRW,
+		ORI:    OR,
+		SLLI:   SLL,
+		SLLIW:  SLLW,
+		SRAI:   SRA,
+		SRAIW:  SRAW,
+		SRLI:   SRL,
+		SRLIW:  SRLW,
+		XORI:   XOR,
+	}
+
+	switch inst.Op {
+	case ADDI, ADDIW, ANDI, ORI, SLLI, SLLIW, SRAI, SRAIW, SRLI, SRLIW, XORI:
+		// Binutils 2.42 reverts this change
+		// op = immOpcodes[inst.Op].String()
+		if inst.Op == ADDI {
+			if inst.Args[1].(Reg) == X0 && inst.Args[0].(Reg) != X0 {
+				op = "li"
+				args[1] = args[2]
+				args = args[:len(args)-1]
+				break
+			}
+
+			if inst.Args[2].(Simm).Imm == 0 {
+				if inst.Args[0].(Reg) == X0 && inst.Args[1].(Reg) == X0 {
+					op = "nop"
+					args = nil
+				} else {
+					op = "mv"
+					args = args[:len(args)-1]
+				}
+			}
+		}
+
+		if inst.Op == ADDIW && inst.Args[2].(Simm).Imm == 0 {
+			op = "sext.w"
+			args = args[:len(args)-1]
+		}
+
+		if inst.Op == XORI && inst.Args[2].(Simm).String() == "-1" {
+			op = "not"
+			args = args[:len(args)-1]
+		}
+
+	case ADD:
+		if inst.Args[1].(Reg) == X0 {
+			op = "mv"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+
+	case BEQ:
+		if inst.Args[1].(Reg) == X0 {
+			op = "beqz"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+
+	case BGE:
+		if inst.Args[1].(Reg) == X0 {
+			op = "bgez"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		} else if inst.Args[0].(Reg) == X0 {
+			op = "blez"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+
+	case BLT:
+		if inst.Args[1].(Reg) == X0 {
+			op = "bltz"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		} else if inst.Args[0].(Reg) == X0 {
+			op = "bgtz"
+			args[0], args[1] = args[1], args[2]
+			args = args[:len(args)-1]
+		}
+
+	case BNE:
+		if inst.Args[1].(Reg) == X0 {
+			op = "bnez"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+
+	case CSRRC:
+		if inst.Args[0].(Reg) == X0 {
+			op = "csrc"
+			args[0], args[1] = args[1], args[2]
+			args = args[:len(args)-1]
+		}
+
+	case CSRRCI:
+		if inst.Args[0].(Reg) == X0 {
+			op = "csrc"
+			args[0], args[1] = args[1], args[2]
+			args = args[:len(args)-1]
+		} else {
+			op = immOpcodes[inst.Op].String()
+		}
+
+	case CSRRS:
+		if inst.Args[2].(Reg) == X0 {
+			switch inst.Args[1].(Csr) {
+			case FCSR:
+				op = "frcsr"
+				args = args[:len(args)-2]
+
+			case FFLAGS:
+				op = "frflags"
+				args = args[:len(args)-2]
+
+			case FRM:
+				op = "frrm"
+				args = args[:len(args)-2]
+
+			// rdcycleh, rdinstreth and rdtimeh are RV-32 only instructions.
+			// So not included there.
+			case CYCLE:
+				op = "rdcycle"
+				args = args[:len(args)-2]
+
+			case INSTRET:
+				op = "rdinstret"
+				args = args[:len(args)-2]
+
+			case TIME:
+				op = "rdtime"
+				args = args[:len(args)-2]
+
+			default:
+				op = "csrr"
+				args = args[:len(args)-1]
+			}
+		} else if inst.Args[0].(Reg) == X0 {
+			op = "csrs"
+			args[0], args[1] = args[1], args[2]
+			args = args[:len(args)-1]
+		}
+
+	case CSRRSI:
+		if inst.Args[0].(Reg) == X0 {
+			op = "csrs"
+			args[0], args[1] = args[1], args[2]
+			args = args[:len(args)-1]
+		} else {
+			op = immOpcodes[inst.Op].String()
+		}
+
+	case CSRRW:
+		switch inst.Args[1].(Csr) {
+		case FCSR:
+			op = "fscsr"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+
+		case FFLAGS:
+			op = "fsflags"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+
+		case FRM:
+			op = "fsrm"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+
+		case CYCLE:
+			if inst.Args[0].(Reg) == X0 && inst.Args[2].(Reg) == X0 {
+				op = "unimp"
+				args = nil
+			}
+
+		default:
+			if inst.Args[0].(Reg) == X0 {
+				op = "csrw"
+				args[0], args[1] = args[1], args[2]
+				args = args[:len(args)-1]
+			}
+		}
+
+	case CSRRWI:
+		if inst.Args[0].(Reg) == X0 {
+			op = "csrw"
+			args[0], args[1] = args[1], args[2]
+			args = args[:len(args)-1]
+		} else {
+			op = immOpcodes[inst.Op].String()
+		}
+
+	// When both pred and succ equals to iorw, the GNU objdump will omit them.
+	case FENCE:
+		if inst.Args[0].(MemOrder).String() == "iorw" &&
+			inst.Args[1].(MemOrder).String() == "iorw" {
+			args = nil
+		}
+
+	case FSGNJX_D:
+		if inst.Args[1].(Reg) == inst.Args[2].(Reg) {
+			op = "fabs.d"
+			args = args[:len(args)-1]
+		}
+
+	case FSGNJX_S:
+		if inst.Args[1].(Reg) == inst.Args[2].(Reg) {
+			op = "fabs.s"
+			args = args[:len(args)-1]
+		}
+
+	case FSGNJ_D:
+		if inst.Args[1].(Reg) == inst.Args[2].(Reg) {
+			op = "fmv.d"
+			args = args[:len(args)-1]
+		}
+
+	case FSGNJ_S:
+		if inst.Args[1].(Reg) == inst.Args[2].(Reg) {
+			op = "fmv.s"
+			args = args[:len(args)-1]
+		}
+
+	case FSGNJN_D:
+		if inst.Args[1].(Reg) == inst.Args[2].(Reg) {
+			op = "fneg.d"
+			args = args[:len(args)-1]
+		}
+
+	case FSGNJN_S:
+		if inst.Args[1].(Reg) == inst.Args[2].(Reg) {
+			op = "fneg.s"
+			args = args[:len(args)-1]
+		}
+
+	case JAL:
+		if inst.Args[0].(Reg) == X0 {
+			op = "j"
+			args[0] = args[1]
+			args = args[:len(args)-1]
+		} else if inst.Args[0].(Reg) == X1 {
+			op = "jal"
+			args[0] = args[1]
+			args = args[:len(args)-1]
+		}
+
+	case JALR:
+		if inst.Args[0].(Reg) == X1 && inst.Args[1].(RegOffset).Ofs.Imm == 0 {
+			args[0] = inst.Args[1].(RegOffset).OfsReg.String()
+			args = args[:len(args)-1]
+		}
+
+		if inst.Args[0].(Reg) == X0 && inst.Args[1].(RegOffset).Ofs.Imm == 0 {
+			if inst.Args[1].(RegOffset).OfsReg == X1 {
+				op = "ret"
+				args = nil
+			} else {
+				op = "jr"
+				args[0] = inst.Args[1].(RegOffset).OfsReg.String()
+				args = args[:len(args)-1]
+			}
+		}
+
+	case SLTIU:
+		if inst.Args[2].(Simm).String() == "1" {
+			op = "seqz"
+			args = args[:len(args)-1]
+		}
+
+	case SLT:
+		if inst.Args[1].(Reg) == X0 {
+			op = "sgtz"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		} else if inst.Args[2].(Reg) == X0 {
+			op = "sltz"
+			args = args[:len(args)-1]
+		}
+
+	case SLTU:
+		if inst.Args[1].(Reg) == X0 {
+			op = "snez"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+
+	case SUB:
+		if inst.Args[1].(Reg) == X0 {
+			op = "neg"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+
+	case SUBW:
+		if inst.Args[1].(Reg) == X0 {
+			op = "negw"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+	}
+
+	if args != nil {
+		op = strings.ToLower(op)
+		op += " " + strings.Join(args, ",")
+	}
+	return op
+}
diff -Naur delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/inst.go delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/inst.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/inst.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/inst.go	2024-08-01 19:32:55.267781333 +0800
@@ -0,0 +1,532 @@
+// 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 riscv64asm
+
+import (
+	"fmt"
+	"strings"
+)
+
+// An Op is a RISC-V opcode.
+type Op uint16
+
+// NOTE: The actual Op values are defined in tables.go.
+func (op Op) String() string {
+	if (op >= Op(len(opstr))) || (opstr[op] == "") {
+		return fmt.Sprintf("Op(%d)", int(op))
+	}
+
+	return opstr[op]
+}
+
+// An Arg is a single instruction argument.
+type Arg interface {
+	String() string
+}
+
+// An Args holds the instruction arguments.
+// If an instruction has fewer than 6 arguments,
+// the final elements in the array are nil.
+type Args [6]Arg
+
+// An Inst is a single instruction.
+type Inst struct {
+	Op   Op     // Opcode mnemonic.
+	Enc  uint32 // Raw encoding bits.
+	Args Args   // Instruction arguments, in RISC-V mamual order.
+	Len  int    // Length of encoded instruction in bytes
+}
+
+func (i Inst) String() string {
+	var args []string
+	for _, arg := range i.Args {
+		if arg == nil {
+			break
+		}
+		args = append(args, arg.String())
+	}
+
+	if len(args) == 0 {
+		return i.Op.String()
+	} else {
+		return i.Op.String() + " " + strings.Join(args, ",")
+	}
+}
+
+// A Reg is a single register.
+// The zero value denotes X0, not the absence of a register.
+type Reg uint16
+
+const (
+	// General-purpose register
+	X0 Reg = iota
+	X1
+	X2
+	X3
+	X4
+	X5
+	X6
+	X7
+	X8
+	X9
+	X10
+	X11
+	X12
+	X13
+	X14
+	X15
+	X16
+	X17
+	X18
+	X19
+	X20
+	X21
+	X22
+	X23
+	X24
+	X25
+	X26
+	X27
+	X28
+	X29
+	X30
+	X31
+
+	//Float point register
+	F0
+	F1
+	F2
+	F3
+	F4
+	F5
+	F6
+	F7
+	F8
+	F9
+	F10
+	F11
+	F12
+	F13
+	F14
+	F15
+	F16
+	F17
+	F18
+	F19
+	F20
+	F21
+	F22
+	F23
+	F24
+	F25
+	F26
+	F27
+	F28
+	F29
+	F30
+	F31
+)
+
+func (r Reg) String() string {
+	switch {
+	case r == X0:
+		return "zero"
+
+	case r == X1:
+		return "ra"
+
+	case r == X2:
+		return "sp"
+
+	case r == X3:
+		return "gp"
+
+	case r == X4:
+		return "tp"
+
+	case (r >= X5) && (r <= X7):
+		return fmt.Sprintf("t%d", int(r-X5))
+
+	case r == X8:
+		return "s0"
+
+	case r == X9:
+		return "s1"
+
+	case (r >= X10) && (r <= X17):
+		return fmt.Sprintf("a%d", int(r-X10))
+
+	case (r >= X18) && (r <= X27):
+		return fmt.Sprintf("s%d", int(r-X18)+2)
+
+	case (r >= X28) && (r <= X31):
+		return fmt.Sprintf("t%d", int(r-X28)+3)
+
+	case (r >= F0) && (r <= F7):
+		return fmt.Sprintf("ft%d", int(r-F0))
+
+	case (r >= F8) && (r <= F9):
+		return fmt.Sprintf("fs%d", int(r-F8))
+
+	case (r >= F10) && (r <= F17):
+		return fmt.Sprintf("fa%d", int(r-F10))
+
+	case (r >= F18) && (r <= F27):
+		return fmt.Sprintf("fs%d", int(r-F18)+2)
+
+	case (r >= F28) && (r <= F31):
+		return fmt.Sprintf("ft%d", int(r-F28)+8)
+
+	default:
+		return fmt.Sprintf("Unknown(%d)", int(r))
+	}
+}
+
+//go:generate stringer -type=Csr
+type Csr uint16
+
+const (
+	USTATUS        Csr = 0x0000
+	FFLAGS         Csr = 0x0001
+	FRM            Csr = 0x0002
+	FCSR           Csr = 0x0003
+	UIE            Csr = 0x0004
+	UTVEC          Csr = 0x0005
+	UTVT           Csr = 0x0007
+	VSTART         Csr = 0x0008
+	VXSAT          Csr = 0x0009
+	VXRM           Csr = 0x000a
+	VCSR           Csr = 0x000f
+	USCRATCH       Csr = 0x0040
+	UEPC           Csr = 0x0041
+	UCAUSE         Csr = 0x0042
+	UTVAL          Csr = 0x0043
+	UIP            Csr = 0x0044
+	UNXTI          Csr = 0x0045
+	UINTSTATUS     Csr = 0x0046
+	USCRATCHCSW    Csr = 0x0048
+	USCRATCHCSWL   Csr = 0x0049
+	SSTATUS        Csr = 0x0100
+	SEDELEG        Csr = 0x0102
+	SIDELEG        Csr = 0x0103
+	SIE            Csr = 0x0104
+	STVEC          Csr = 0x0105
+	SCOUNTEREN     Csr = 0x0106
+	STVT           Csr = 0x0107
+	SSCRATCH       Csr = 0x0140
+	SEPC           Csr = 0x0141
+	SCAUSE         Csr = 0x0142
+	STVAL          Csr = 0x0143
+	SIP            Csr = 0x0144
+	SNXTI          Csr = 0x0145
+	SINTSTATUS     Csr = 0x0146
+	SSCRATCHCSW    Csr = 0x0148
+	SSCRATCHCSWL   Csr = 0x0149
+	SATP           Csr = 0x0180
+	VSSTATUS       Csr = 0x0200
+	VSIE           Csr = 0x0204
+	VSTVEC         Csr = 0x0205
+	VSSCRATCH      Csr = 0x0240
+	VSEPC          Csr = 0x0241
+	VSCAUSE        Csr = 0x0242
+	VSTVAL         Csr = 0x0243
+	VSIP           Csr = 0x0244
+	VSATP          Csr = 0x0280
+	MSTATUS        Csr = 0x0300
+	MISA           Csr = 0x0301
+	MEDELEG        Csr = 0x0302
+	MIDELEG        Csr = 0x0303
+	MIE            Csr = 0x0304
+	MTVEC          Csr = 0x0305
+	MCOUNTEREN     Csr = 0x0306
+	MTVT           Csr = 0x0307
+	MSTATUSH       Csr = 0x0310
+	MCOUNTINHIBIT  Csr = 0x0320
+	MHPMEVENT3     Csr = 0x0323
+	MHPMEVENT4     Csr = 0x0324
+	MHPMEVENT5     Csr = 0x0325
+	MHPMEVENT6     Csr = 0x0326
+	MHPMEVENT7     Csr = 0x0327
+	MHPMEVENT8     Csr = 0x0328
+	MHPMEVENT9     Csr = 0x0329
+	MHPMEVENT10    Csr = 0x032a
+	MHPMEVENT11    Csr = 0x032b
+	MHPMEVENT12    Csr = 0x032c
+	MHPMEVENT13    Csr = 0x032d
+	MHPMEVENT14    Csr = 0x032e
+	MHPMEVENT15    Csr = 0x032f
+	MHPMEVENT16    Csr = 0x0330
+	MHPMEVENT17    Csr = 0x0331
+	MHPMEVENT18    Csr = 0x0332
+	MHPMEVENT19    Csr = 0x0333
+	MHPMEVENT20    Csr = 0x0334
+	MHPMEVENT21    Csr = 0x0335
+	MHPMEVENT22    Csr = 0x0336
+	MHPMEVENT23    Csr = 0x0337
+	MHPMEVENT24    Csr = 0x0338
+	MHPMEVENT25    Csr = 0x0339
+	MHPMEVENT26    Csr = 0x033a
+	MHPMEVENT27    Csr = 0x033b
+	MHPMEVENT28    Csr = 0x033c
+	MHPMEVENT29    Csr = 0x033d
+	MHPMEVENT30    Csr = 0x033e
+	MHPMEVENT31    Csr = 0x033f
+	MSCRATCH       Csr = 0x0340
+	MEPC           Csr = 0x0341
+	MCAUSE         Csr = 0x0342
+	MTVAL          Csr = 0x0343
+	MIP            Csr = 0x0344
+	MNXTI          Csr = 0x0345
+	MINTSTATUS     Csr = 0x0346
+	MSCRATCHCSW    Csr = 0x0348
+	MSCRATCHCSWL   Csr = 0x0349
+	MTINST         Csr = 0x034a
+	MTVAL2         Csr = 0x034b
+	PMPCFG0        Csr = 0x03a0
+	PMPCFG1        Csr = 0x03a1
+	PMPCFG2        Csr = 0x03a2
+	PMPCFG3        Csr = 0x03a3
+	PMPADDR0       Csr = 0x03b0
+	PMPADDR1       Csr = 0x03b1
+	PMPADDR2       Csr = 0x03b2
+	PMPADDR3       Csr = 0x03b3
+	PMPADDR4       Csr = 0x03b4
+	PMPADDR5       Csr = 0x03b5
+	PMPADDR6       Csr = 0x03b6
+	PMPADDR7       Csr = 0x03b7
+	PMPADDR8       Csr = 0x03b8
+	PMPADDR9       Csr = 0x03b9
+	PMPADDR10      Csr = 0x03ba
+	PMPADDR11      Csr = 0x03bb
+	PMPADDR12      Csr = 0x03bc
+	PMPADDR13      Csr = 0x03bd
+	PMPADDR14      Csr = 0x03be
+	PMPADDR15      Csr = 0x03bf
+	HSTATUS        Csr = 0x0600
+	HEDELEG        Csr = 0x0602
+	HIDELEG        Csr = 0x0603
+	HIE            Csr = 0x0604
+	HTIMEDELTA     Csr = 0x0605
+	HCOUNTEREN     Csr = 0x0606
+	HGEIE          Csr = 0x0607
+	HTIMEDELTAH    Csr = 0x0615
+	HTVAL          Csr = 0x0643
+	HIP            Csr = 0x0644
+	HVIP           Csr = 0x0645
+	HTINST         Csr = 0x064a
+	HGATP          Csr = 0x0680
+	TSELECT        Csr = 0x07a0
+	TDATA1         Csr = 0x07a1
+	TDATA2         Csr = 0x07a2
+	TDATA3         Csr = 0x07a3
+	TINFO          Csr = 0x07a4
+	TCONTROL       Csr = 0x07a5
+	MCONTEXT       Csr = 0x07a8
+	MNOISE         Csr = 0x07a9
+	SCONTEXT       Csr = 0x07aa
+	DCSR           Csr = 0x07b0
+	DPC            Csr = 0x07b1
+	DSCRATCH0      Csr = 0x07b2
+	DSCRATCH1      Csr = 0x07b3
+	MCYCLE         Csr = 0x0b00
+	MINSTRET       Csr = 0x0b02
+	MHPMCOUNTER3   Csr = 0x0b03
+	MHPMCOUNTER4   Csr = 0x0b04
+	MHPMCOUNTER5   Csr = 0x0b05
+	MHPMCOUNTER6   Csr = 0x0b06
+	MHPMCOUNTER7   Csr = 0x0b07
+	MHPMCOUNTER8   Csr = 0x0b08
+	MHPMCOUNTER9   Csr = 0x0b09
+	MHPMCOUNTER10  Csr = 0x0b0a
+	MHPMCOUNTER11  Csr = 0x0b0b
+	MHPMCOUNTER12  Csr = 0x0b0c
+	MHPMCOUNTER13  Csr = 0x0b0d
+	MHPMCOUNTER14  Csr = 0x0b0e
+	MHPMCOUNTER15  Csr = 0x0b0f
+	MHPMCOUNTER16  Csr = 0x0b10
+	MHPMCOUNTER17  Csr = 0x0b11
+	MHPMCOUNTER18  Csr = 0x0b12
+	MHPMCOUNTER19  Csr = 0x0b13
+	MHPMCOUNTER20  Csr = 0x0b14
+	MHPMCOUNTER21  Csr = 0x0b15
+	MHPMCOUNTER22  Csr = 0x0b16
+	MHPMCOUNTER23  Csr = 0x0b17
+	MHPMCOUNTER24  Csr = 0x0b18
+	MHPMCOUNTER25  Csr = 0x0b19
+	MHPMCOUNTER26  Csr = 0x0b1a
+	MHPMCOUNTER27  Csr = 0x0b1b
+	MHPMCOUNTER28  Csr = 0x0b1c
+	MHPMCOUNTER29  Csr = 0x0b1d
+	MHPMCOUNTER30  Csr = 0x0b1e
+	MHPMCOUNTER31  Csr = 0x0b1f
+	MCYCLEH        Csr = 0x0b80
+	MINSTRETH      Csr = 0x0b82
+	MHPMCOUNTER3H  Csr = 0x0b83
+	MHPMCOUNTER4H  Csr = 0x0b84
+	MHPMCOUNTER5H  Csr = 0x0b85
+	MHPMCOUNTER6H  Csr = 0x0b86
+	MHPMCOUNTER7H  Csr = 0x0b87
+	MHPMCOUNTER8H  Csr = 0x0b88
+	MHPMCOUNTER9H  Csr = 0x0b89
+	MHPMCOUNTER10H Csr = 0x0b8a
+	MHPMCOUNTER11H Csr = 0x0b8b
+	MHPMCOUNTER12H Csr = 0x0b8c
+	MHPMCOUNTER13H Csr = 0x0b8d
+	MHPMCOUNTER14H Csr = 0x0b8e
+	MHPMCOUNTER15H Csr = 0x0b8f
+	MHPMCOUNTER16H Csr = 0x0b90
+	MHPMCOUNTER17H Csr = 0x0b91
+	MHPMCOUNTER18H Csr = 0x0b92
+	MHPMCOUNTER19H Csr = 0x0b93
+	MHPMCOUNTER20H Csr = 0x0b94
+	MHPMCOUNTER21H Csr = 0x0b95
+	MHPMCOUNTER22H Csr = 0x0b96
+	MHPMCOUNTER23H Csr = 0x0b97
+	MHPMCOUNTER24H Csr = 0x0b98
+	MHPMCOUNTER25H Csr = 0x0b99
+	MHPMCOUNTER26H Csr = 0x0b9a
+	MHPMCOUNTER27H Csr = 0x0b9b
+	MHPMCOUNTER28H Csr = 0x0b9c
+	MHPMCOUNTER29H Csr = 0x0b9d
+	MHPMCOUNTER30H Csr = 0x0b9e
+	MHPMCOUNTER31H Csr = 0x0b9f
+	CYCLE          Csr = 0x0c00
+	TIME           Csr = 0x0c01
+	INSTRET        Csr = 0x0c02
+	HPMCOUNTER3    Csr = 0x0c03
+	HPMCOUNTER4    Csr = 0x0c04
+	HPMCOUNTER5    Csr = 0x0c05
+	HPMCOUNTER6    Csr = 0x0c06
+	HPMCOUNTER7    Csr = 0x0c07
+	HPMCOUNTER8    Csr = 0x0c08
+	HPMCOUNTER9    Csr = 0x0c09
+	HPMCOUNTER10   Csr = 0x0c0a
+	HPMCOUNTER11   Csr = 0x0c0b
+	HPMCOUNTER12   Csr = 0x0c0c
+	HPMCOUNTER13   Csr = 0x0c0d
+	HPMCOUNTER14   Csr = 0x0c0e
+	HPMCOUNTER15   Csr = 0x0c0f
+	HPMCOUNTER16   Csr = 0x0c10
+	HPMCOUNTER17   Csr = 0x0c11
+	HPMCOUNTER18   Csr = 0x0c12
+	HPMCOUNTER19   Csr = 0x0c13
+	HPMCOUNTER20   Csr = 0x0c14
+	HPMCOUNTER21   Csr = 0x0c15
+	HPMCOUNTER22   Csr = 0x0c16
+	HPMCOUNTER23   Csr = 0x0c17
+	HPMCOUNTER24   Csr = 0x0c18
+	HPMCOUNTER25   Csr = 0x0c19
+	HPMCOUNTER26   Csr = 0x0c1a
+	HPMCOUNTER27   Csr = 0x0c1b
+	HPMCOUNTER28   Csr = 0x0c1c
+	HPMCOUNTER29   Csr = 0x0c1d
+	HPMCOUNTER30   Csr = 0x0c1e
+	HPMCOUNTER31   Csr = 0x0c1f
+	VL             Csr = 0x0c20
+	VTYPE          Csr = 0x0c21
+	VLENB          Csr = 0x0c22
+	CYCLEH         Csr = 0x0c80
+	TIMEH          Csr = 0x0c81
+	INSTRETH       Csr = 0x0c82
+	HPMCOUNTER3H   Csr = 0x0c83
+	HPMCOUNTER4H   Csr = 0x0c84
+	HPMCOUNTER5H   Csr = 0x0c85
+	HPMCOUNTER6H   Csr = 0x0c86
+	HPMCOUNTER7H   Csr = 0x0c87
+	HPMCOUNTER8H   Csr = 0x0c88
+	HPMCOUNTER9H   Csr = 0x0c89
+	HPMCOUNTER10H  Csr = 0x0c8a
+	HPMCOUNTER11H  Csr = 0x0c8b
+	HPMCOUNTER12H  Csr = 0x0c8c
+	HPMCOUNTER13H  Csr = 0x0c8d
+	HPMCOUNTER14H  Csr = 0x0c8e
+	HPMCOUNTER15H  Csr = 0x0c8f
+	HPMCOUNTER16H  Csr = 0x0c90
+	HPMCOUNTER17H  Csr = 0x0c91
+	HPMCOUNTER18H  Csr = 0x0c92
+	HPMCOUNTER19H  Csr = 0x0c93
+	HPMCOUNTER20H  Csr = 0x0c94
+	HPMCOUNTER21H  Csr = 0x0c95
+	HPMCOUNTER22H  Csr = 0x0c96
+	HPMCOUNTER23H  Csr = 0x0c97
+	HPMCOUNTER24H  Csr = 0x0c98
+	HPMCOUNTER25H  Csr = 0x0c99
+	HPMCOUNTER26H  Csr = 0x0c9a
+	HPMCOUNTER27H  Csr = 0x0c9b
+	HPMCOUNTER28H  Csr = 0x0c9c
+	HPMCOUNTER29H  Csr = 0x0c9d
+	HPMCOUNTER30H  Csr = 0x0c9e
+	HPMCOUNTER31H  Csr = 0x0c9f
+	HGEIP          Csr = 0x0e12
+	MVENDORID      Csr = 0x0f11
+	MARCHID        Csr = 0x0f12
+	MIMPID         Csr = 0x0f13
+	MHARTID        Csr = 0x0f14
+	MENTROPY       Csr = 0x0f15
+)
+
+type Uimm struct {
+	Imm     uint32
+	Decimal bool
+}
+
+func (ui Uimm) String() string {
+	if ui.Decimal == true {
+		return fmt.Sprintf("%d", ui.Imm)
+	} else {
+		return fmt.Sprintf("%#x", ui.Imm)
+	}
+}
+
+type Simm struct {
+	Imm     int32
+	Decimal bool
+	Width   uint8
+}
+
+func (si Simm) String() string {
+	if si.Decimal {
+		return fmt.Sprintf("%d", si.Imm)
+	} else {
+		return fmt.Sprintf("%#x", si.Imm)
+	}
+}
+
+// Avoid recursive of String() method.
+type AmoReg struct {
+	reg Reg
+}
+
+func (amoReg AmoReg) String() string {
+	return fmt.Sprintf("(%s)", amoReg.reg)
+}
+
+type RegOffset struct {
+	OfsReg Reg
+	Ofs    Simm
+}
+
+func (regofs RegOffset) String() string {
+	return fmt.Sprintf("%s(%s)", regofs.Ofs, regofs.OfsReg)
+}
+
+type MemOrder uint8
+
+func (memOrder MemOrder) String() string {
+	var str string
+	if memOrder<<7>>7 == 1 {
+		str += "i"
+	}
+	if memOrder>>1<<7>>7 == 1 {
+		str += "o"
+	}
+	if memOrder>>2<<7>>7 == 1 {
+		str += "r"
+	}
+	if memOrder>>3<<7>>7 == 1 {
+		str += "w"
+	}
+	return str
+}
diff -Naur delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/plan9x.go delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/plan9x.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/plan9x.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/plan9x.go	2024-08-01 19:32:55.267781333 +0800
@@ -0,0 +1,361 @@
+// 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 riscv64asm
+
+import (
+	"fmt"
+	"io"
+	"strconv"
+	"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.
+// The reader text should read from the text segment using text addresses
+// as offsets; it is used to display pc-relative loads as constant loads.
+func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text io.ReaderAt) string {
+	if symname == nil {
+		symname = func(uint64) (string, uint64) { return "", 0 }
+	}
+
+	var args []string
+	for _, a := range inst.Args {
+		if a == nil {
+			break
+		}
+		args = append(args, plan9Arg(&inst, pc, symname, a))
+	}
+
+	op := inst.Op.String()
+
+	switch inst.Op {
+
+	case AMOADD_D, AMOADD_D_AQ, AMOADD_D_RL, AMOADD_D_AQRL, AMOADD_W, AMOADD_W_AQ,
+		AMOADD_W_RL, AMOADD_W_AQRL, AMOAND_D, AMOAND_D_AQ, AMOAND_D_RL, AMOAND_D_AQRL,
+		AMOAND_W, AMOAND_W_AQ, AMOAND_W_RL, AMOAND_W_AQRL, AMOMAXU_D, AMOMAXU_D_AQ,
+		AMOMAXU_D_RL, AMOMAXU_D_AQRL, AMOMAXU_W, AMOMAXU_W_AQ, AMOMAXU_W_RL, AMOMAXU_W_AQRL,
+		AMOMAX_D, AMOMAX_D_AQ, AMOMAX_D_RL, AMOMAX_D_AQRL, AMOMAX_W, AMOMAX_W_AQ, AMOMAX_W_RL,
+		AMOMAX_W_AQRL, AMOMINU_D, AMOMINU_D_AQ, AMOMINU_D_RL, AMOMINU_D_AQRL, AMOMINU_W,
+		AMOMINU_W_AQ, AMOMINU_W_RL, AMOMINU_W_AQRL, AMOMIN_D, AMOMIN_D_AQ, AMOMIN_D_RL,
+		AMOMIN_D_AQRL, AMOMIN_W, AMOMIN_W_AQ, AMOMIN_W_RL, AMOMIN_W_AQRL, AMOOR_D, AMOOR_D_AQ,
+		AMOOR_D_RL, AMOOR_D_AQRL, AMOOR_W, AMOOR_W_AQ, AMOOR_W_RL, AMOOR_W_AQRL, AMOSWAP_D,
+		AMOSWAP_D_AQ, AMOSWAP_D_RL, AMOSWAP_D_AQRL, AMOSWAP_W, AMOSWAP_W_AQ, AMOSWAP_W_RL,
+		AMOSWAP_W_AQRL, AMOXOR_D, AMOXOR_D_AQ, AMOXOR_D_RL, AMOXOR_D_AQRL, AMOXOR_W,
+		AMOXOR_W_AQ, AMOXOR_W_RL, AMOXOR_W_AQRL, SC_D, SC_D_AQ, SC_D_RL, SC_D_AQRL,
+		SC_W, SC_W_AQ, SC_W_RL, SC_W_AQRL:
+		// Atomic instructions have special oprand order.
+		args[2], args[1] = args[1], args[2]
+
+	case ADDI:
+		if inst.Args[2].(Simm).Imm == 0 {
+			op = "MOV"
+			args = args[:len(args)-1]
+		}
+
+	case ADDIW:
+		if inst.Args[2].(Simm).Imm == 0 {
+			op = "MOVW"
+			args = args[:len(args)-1]
+		}
+
+	case ANDI:
+		if inst.Args[2].(Simm).Imm == 255 {
+			op = "MOVBU"
+			args = args[:len(args)-1]
+		}
+
+	case BEQ:
+		if inst.Args[1].(Reg) == X0 {
+			op = "BEQZ"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+		for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
+			args[i], args[j] = args[j], args[i]
+		}
+
+	case BGE:
+		if inst.Args[1].(Reg) == X0 {
+			op = "BGEZ"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+		for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
+			args[i], args[j] = args[j], args[i]
+		}
+
+	case BLT:
+		if inst.Args[1].(Reg) == X0 {
+			op = "BLTZ"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+		for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
+			args[i], args[j] = args[j], args[i]
+		}
+
+	case BNE:
+		if inst.Args[1].(Reg) == X0 {
+			op = "BNEZ"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+		for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
+			args[i], args[j] = args[j], args[i]
+		}
+
+	case BLTU, BGEU:
+		for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
+			args[i], args[j] = args[j], args[i]
+		}
+
+	case CSRRW:
+		switch inst.Args[1].(Csr) {
+		case CYCLE:
+			if inst.Args[0].(Reg) == X0 && inst.Args[2].(Reg) == X0 {
+				op = "UNIMP"
+				args = nil
+			}
+		}
+
+	case CSRRS:
+		if inst.Args[2].(Reg) == X0 {
+			switch inst.Args[1].(Csr) {
+			case CYCLE:
+				op = "RDCYCLE"
+				args = args[:len(args)-2]
+			case CYCLEH:
+				op = "RDCYCLEH"
+				args = args[:len(args)-2]
+			case INSTRET:
+				op = "RDINSTRET"
+				args = args[:len(args)-2]
+			case INSTRETH:
+				op = "RDINSTRETH"
+				args = args[:len(args)-2]
+			case TIME:
+				op = "RDTIME"
+				args = args[:len(args)-2]
+			case TIMEH:
+				op = "RDTIMEH"
+				args = args[:len(args)-2]
+			}
+		}
+
+	// Fence instruction in plan9 doesn't have any oprands.
+	case FENCE:
+		args = nil
+
+	case FMADD_D, FMADD_H, FMADD_Q, FMADD_S, FMSUB_D, FMSUB_H,
+		FMSUB_Q, FMSUB_S, FNMADD_D, FNMADD_H, FNMADD_Q, FNMADD_S,
+		FNMSUB_D, FNMSUB_H, FNMSUB_Q, FNMSUB_S:
+		args[1], args[3] = args[3], args[1]
+
+	case FSGNJ_S:
+		if inst.Args[2] == inst.Args[1] {
+			op = "MOVF"
+			args = args[:len(args)-1]
+		}
+
+	case FSGNJ_D:
+		if inst.Args[2] == inst.Args[1] {
+			op = "MOVD"
+			args = args[:len(args)-1]
+		}
+
+	case FSGNJX_S:
+		if inst.Args[2] == inst.Args[1] {
+			op = "FABSS"
+			args = args[:len(args)-1]
+		}
+
+	case FSGNJX_D:
+		if inst.Args[2] == inst.Args[1] {
+			op = "FABSD"
+			args = args[:len(args)-1]
+		}
+
+	case FSGNJN_S:
+		if inst.Args[2] == inst.Args[1] {
+			op = "FNEGS"
+			args = args[:len(args)-1]
+		}
+
+	case FSGNJN_D:
+		if inst.Args[2] == inst.Args[1] {
+			op = "FNESD"
+			args = args[:len(args)-1]
+		}
+
+	case LD, SD:
+		op = "MOV"
+		if inst.Op == SD {
+			args[0], args[1] = args[1], args[0]
+		}
+
+	case LB, SB:
+		op = "MOVB"
+		if inst.Op == SB {
+			args[0], args[1] = args[1], args[0]
+		}
+
+	case LH, SH:
+		op = "MOVH"
+		if inst.Op == SH {
+			args[0], args[1] = args[1], args[0]
+		}
+
+	case LW, SW:
+		op = "MOVW"
+		if inst.Op == SW {
+			args[0], args[1] = args[1], args[0]
+		}
+
+	case LBU:
+		op = "MOVBU"
+
+	case LHU:
+		op = "MOVHU"
+
+	case LWU:
+		op = "MOVWU"
+
+	case FLW, FSW:
+		op = "MOVF"
+		if inst.Op == FLW {
+			args[0], args[1] = args[1], args[0]
+		}
+
+	case FLD, FSD:
+		op = "MOVD"
+		if inst.Op == FLD {
+			args[0], args[1] = args[1], args[0]
+		}
+
+	case SUB:
+		if inst.Args[1].(Reg) == X0 {
+			op = "NEG"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+
+	case XORI:
+		if inst.Args[2].(Simm).String() == "-1" {
+			op = "NOT"
+			args = args[:len(args)-1]
+		}
+
+	case SLTIU:
+		if inst.Args[2].(Simm).Imm == 1 {
+			op = "SEQZ"
+			args = args[:len(args)-1]
+		}
+
+	case SLTU:
+		if inst.Args[1].(Reg) == X0 {
+			op = "SNEZ"
+			args[1] = args[2]
+			args = args[:len(args)-1]
+		}
+
+	case JAL:
+		if inst.Args[0].(Reg) == X0 {
+			op = "JMP"
+			args[0] = args[1]
+			args = args[:len(args)-1]
+		} else if inst.Args[0].(Reg) == X1 {
+			op = "CALL"
+			args[0] = args[1]
+			args = args[:len(args)-1]
+		} else {
+			args[0], args[1] = args[1], args[0]
+		}
+
+	case JALR:
+		if inst.Args[0].(Reg) == X0 {
+			if inst.Args[1].(RegOffset).OfsReg == X1 && inst.Args[1].(RegOffset).Ofs.Imm == 0 {
+				op = "RET"
+				args = args[:0]
+				break
+			}
+			op = "JMP"
+			args[0] = args[1]
+			args = args[:len(args)-1]
+		} else if inst.Args[0].(Reg) == X1 {
+			op = "CALL"
+			args[0] = args[1]
+			args = args[:len(args)-1]
+		} else {
+			args[0], args[1] = args[1], args[0]
+		}
+	}
+
+	// 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]
+	}
+
+	// Change to plan9 opcode format
+	// Atomic instructions do not have reorder suffix, so remove them
+	op = strings.Replace(op, ".AQRL", "", -1)
+	op = strings.Replace(op, ".AQ", "", -1)
+	op = strings.Replace(op, ".RL", "", -1)
+	op = strings.Replace(op, ".", "", -1)
+
+	if args != nil {
+		op += " " + strings.Join(args, ", ")
+	}
+
+	return op
+}
+
+func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
+	switch a := arg.(type) {
+	case Uimm:
+		return fmt.Sprintf("$%d", uint32(a.Imm))
+
+	case Simm:
+		imm, _ := strconv.Atoi(a.String())
+		if a.Width == 13 || a.Width == 21 {
+			addr := int64(pc) + int64(imm)
+			if s, base := symname(uint64(addr)); s != "" && uint64(addr) == base {
+				return fmt.Sprintf("%s(SB)", s)
+			}
+			return fmt.Sprintf("%d(PC)", imm/4)
+		}
+		return fmt.Sprintf("$%d", int32(imm))
+
+	case Reg:
+		if a <= 31 {
+			switch a {
+			case 2:
+				return "SP"
+			default:
+				return fmt.Sprintf("X%d", a)
+			}
+		} else {
+			return fmt.Sprintf("F%d", a-32)
+		}
+
+	case RegOffset:
+		if a.Ofs.Imm == 0 {
+			return fmt.Sprintf("(X%d)", a.OfsReg)
+		} else {
+			return fmt.Sprintf("%s(X%d)", a.Ofs.String(), a.OfsReg)
+		}
+
+	case AmoReg:
+		return fmt.Sprintf("(X%d)", a.reg)
+
+	default:
+		return strings.ToUpper(arg.String())
+	}
+}
diff -Naur delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/tables.go delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/tables.go
--- delve-1.22.0.old/vendor/golang.org/x/arch/riscv64/riscv64asm/tables.go	1970-01-01 08:00:00.000000000 +0800
+++ delve-1.22.0/vendor/golang.org/x/arch/riscv64/riscv64asm/tables.go	2024-08-01 19:32:55.267781333 +0800
@@ -0,0 +1,1314 @@
+// Generated by riscv64spec riscv-opcodes
+// 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 riscv64asm
+
+const (
+	_ Op = iota
+	ADD
+	ADDI
+	ADDIW
+	ADDW
+	AMOADD_D
+	AMOADD_D_AQ
+	AMOADD_D_AQRL
+	AMOADD_D_RL
+	AMOADD_W
+	AMOADD_W_AQ
+	AMOADD_W_AQRL
+	AMOADD_W_RL
+	AMOAND_D
+	AMOAND_D_AQ
+	AMOAND_D_AQRL
+	AMOAND_D_RL
+	AMOAND_W
+	AMOAND_W_AQ
+	AMOAND_W_AQRL
+	AMOAND_W_RL
+	AMOMAXU_D
+	AMOMAXU_D_AQ
+	AMOMAXU_D_AQRL
+	AMOMAXU_D_RL
+	AMOMAXU_W
+	AMOMAXU_W_AQ
+	AMOMAXU_W_AQRL
+	AMOMAXU_W_RL
+	AMOMAX_D
+	AMOMAX_D_AQ
+	AMOMAX_D_AQRL
+	AMOMAX_D_RL
+	AMOMAX_W
+	AMOMAX_W_AQ
+	AMOMAX_W_AQRL
+	AMOMAX_W_RL
+	AMOMINU_D
+	AMOMINU_D_AQ
+	AMOMINU_D_AQRL
+	AMOMINU_D_RL
+	AMOMINU_W
+	AMOMINU_W_AQ
+	AMOMINU_W_AQRL
+	AMOMINU_W_RL
+	AMOMIN_D
+	AMOMIN_D_AQ
+	AMOMIN_D_AQRL
+	AMOMIN_D_RL
+	AMOMIN_W
+	AMOMIN_W_AQ
+	AMOMIN_W_AQRL
+	AMOMIN_W_RL
+	AMOOR_D
+	AMOOR_D_AQ
+	AMOOR_D_AQRL
+	AMOOR_D_RL
+	AMOOR_W
+	AMOOR_W_AQ
+	AMOOR_W_AQRL
+	AMOOR_W_RL
+	AMOSWAP_D
+	AMOSWAP_D_AQ
+	AMOSWAP_D_AQRL
+	AMOSWAP_D_RL
+	AMOSWAP_W
+	AMOSWAP_W_AQ
+	AMOSWAP_W_AQRL
+	AMOSWAP_W_RL
+	AMOXOR_D
+	AMOXOR_D_AQ
+	AMOXOR_D_AQRL
+	AMOXOR_D_RL
+	AMOXOR_W
+	AMOXOR_W_AQ
+	AMOXOR_W_AQRL
+	AMOXOR_W_RL
+	AND
+	ANDI
+	AUIPC
+	BEQ
+	BGE
+	BGEU
+	BLT
+	BLTU
+	BNE
+	CSRRC
+	CSRRCI
+	CSRRS
+	CSRRSI
+	CSRRW
+	CSRRWI
+	C_ADD
+	C_ADDI
+	C_ADDI16SP
+	C_ADDI4SPN
+	C_ADDIW
+	C_ADDW
+	C_AND
+	C_ANDI
+	C_BEQZ
+	C_BNEZ
+	C_EBREAK
+	C_FLD
+	C_FLDSP
+	C_FSD
+	C_FSDSP
+	C_J
+	C_JALR
+	C_JR
+	C_LD
+	C_LDSP
+	C_LI
+	C_LUI
+	C_LW
+	C_LWSP
+	C_MV
+	C_NOP
+	C_OR
+	C_SD
+	C_SDSP
+	C_SLLI
+	C_SRAI
+	C_SRLI
+	C_SUB
+	C_SUBW
+	C_SW
+	C_SWSP
+	C_UNIMP
+	C_XOR
+	DIV
+	DIVU
+	DIVUW
+	DIVW
+	EBREAK
+	ECALL
+	FADD_D
+	FADD_H
+	FADD_Q
+	FADD_S
+	FCLASS_D
+	FCLASS_H
+	FCLASS_Q
+	FCLASS_S
+	FCVT_D_L
+	FCVT_D_LU
+	FCVT_D_Q
+	FCVT_D_S
+	FCVT_D_W
+	FCVT_D_WU
+	FCVT_H_L
+	FCVT_H_LU
+	FCVT_H_S
+	FCVT_H_W
+	FCVT_H_WU
+	FCVT_LU_D
+	FCVT_LU_H
+	FCVT_LU_Q
+	FCVT_LU_S
+	FCVT_L_D
+	FCVT_L_H
+	FCVT_L_Q
+	FCVT_L_S
+	FCVT_Q_D
+	FCVT_Q_L
+	FCVT_Q_LU
+	FCVT_Q_S
+	FCVT_Q_W
+	FCVT_Q_WU
+	FCVT_S_D
+	FCVT_S_H
+	FCVT_S_L
+	FCVT_S_LU
+	FCVT_S_Q
+	FCVT_S_W
+	FCVT_S_WU
+	FCVT_WU_D
+	FCVT_WU_H
+	FCVT_WU_Q
+	FCVT_WU_S
+	FCVT_W_D
+	FCVT_W_H
+	FCVT_W_Q
+	FCVT_W_S
+	FDIV_D
+	FDIV_H
+	FDIV_Q
+	FDIV_S
+	FENCE
+	FENCE_I
+	FEQ_D
+	FEQ_H
+	FEQ_Q
+	FEQ_S
+	FLD
+	FLE_D
+	FLE_H
+	FLE_Q
+	FLE_S
+	FLH
+	FLQ
+	FLT_D
+	FLT_H
+	FLT_Q
+	FLT_S
+	FLW
+	FMADD_D
+	FMADD_H
+	FMADD_Q
+	FMADD_S
+	FMAX_D
+	FMAX_H
+	FMAX_Q
+	FMAX_S
+	FMIN_D
+	FMIN_H
+	FMIN_Q
+	FMIN_S
+	FMSUB_D
+	FMSUB_H
+	FMSUB_Q
+	FMSUB_S
+	FMUL_D
+	FMUL_H
+	FMUL_Q
+	FMUL_S
+	FMV_D_X
+	FMV_H_X
+	FMV_W_X
+	FMV_X_D
+	FMV_X_H
+	FMV_X_W
+	FNMADD_D
+	FNMADD_H
+	FNMADD_Q
+	FNMADD_S
+	FNMSUB_D
+	FNMSUB_H
+	FNMSUB_Q
+	FNMSUB_S
+	FSD
+	FSGNJN_D
+	FSGNJN_H
+	FSGNJN_Q
+	FSGNJN_S
+	FSGNJX_D
+	FSGNJX_H
+	FSGNJX_Q
+	FSGNJX_S
+	FSGNJ_D
+	FSGNJ_H
+	FSGNJ_Q
+	FSGNJ_S
+	FSH
+	FSQ
+	FSQRT_D
+	FSQRT_H
+	FSQRT_Q
+	FSQRT_S
+	FSUB_D
+	FSUB_H
+	FSUB_Q
+	FSUB_S
+	FSW
+	JAL
+	JALR
+	LB
+	LBU
+	LD
+	LH
+	LHU
+	LR_D
+	LR_D_AQ
+	LR_D_AQRL
+	LR_D_RL
+	LR_W
+	LR_W_AQ
+	LR_W_AQRL
+	LR_W_RL
+	LUI
+	LW
+	LWU
+	MUL
+	MULH
+	MULHSU
+	MULHU
+	MULW
+	OR
+	ORI
+	REM
+	REMU
+	REMUW
+	REMW
+	SB
+	SC_D
+	SC_D_AQ
+	SC_D_AQRL
+	SC_D_RL
+	SC_W
+	SC_W_AQ
+	SC_W_AQRL
+	SC_W_RL
+	SD
+	SH
+	SLL
+	SLLI
+	SLLIW
+	SLLW
+	SLT
+	SLTI
+	SLTIU
+	SLTU
+	SRA
+	SRAI
+	SRAIW
+	SRAW
+	SRL
+	SRLI
+	SRLIW
+	SRLW
+	SUB
+	SUBW
+	SW
+	XOR
+	XORI
+)
+
+var opstr = [...]string{
+	ADD:	"ADD",
+	ADDI:	"ADDI",
+	ADDIW:	"ADDIW",
+	ADDW:	"ADDW",
+	AMOADD_D:	"AMOADD.D",
+	AMOADD_D_AQ:	"AMOADD.D.AQ",
+	AMOADD_D_AQRL:	"AMOADD.D.AQRL",
+	AMOADD_D_RL:	"AMOADD.D.RL",
+	AMOADD_W:	"AMOADD.W",
+	AMOADD_W_AQ:	"AMOADD.W.AQ",
+	AMOADD_W_AQRL:	"AMOADD.W.AQRL",
+	AMOADD_W_RL:	"AMOADD.W.RL",
+	AMOAND_D:	"AMOAND.D",
+	AMOAND_D_AQ:	"AMOAND.D.AQ",
+	AMOAND_D_AQRL:	"AMOAND.D.AQRL",
+	AMOAND_D_RL:	"AMOAND.D.RL",
+	AMOAND_W:	"AMOAND.W",
+	AMOAND_W_AQ:	"AMOAND.W.AQ",
+	AMOAND_W_AQRL:	"AMOAND.W.AQRL",
+	AMOAND_W_RL:	"AMOAND.W.RL",
+	AMOMAXU_D:	"AMOMAXU.D",
+	AMOMAXU_D_AQ:	"AMOMAXU.D.AQ",
+	AMOMAXU_D_AQRL:	"AMOMAXU.D.AQRL",
+	AMOMAXU_D_RL:	"AMOMAXU.D.RL",
+	AMOMAXU_W:	"AMOMAXU.W",
+	AMOMAXU_W_AQ:	"AMOMAXU.W.AQ",
+	AMOMAXU_W_AQRL:	"AMOMAXU.W.AQRL",
+	AMOMAXU_W_RL:	"AMOMAXU.W.RL",
+	AMOMAX_D:	"AMOMAX.D",
+	AMOMAX_D_AQ:	"AMOMAX.D.AQ",
+	AMOMAX_D_AQRL:	"AMOMAX.D.AQRL",
+	AMOMAX_D_RL:	"AMOMAX.D.RL",
+	AMOMAX_W:	"AMOMAX.W",
+	AMOMAX_W_AQ:	"AMOMAX.W.AQ",
+	AMOMAX_W_AQRL:	"AMOMAX.W.AQRL",
+	AMOMAX_W_RL:	"AMOMAX.W.RL",
+	AMOMINU_D:	"AMOMINU.D",
+	AMOMINU_D_AQ:	"AMOMINU.D.AQ",
+	AMOMINU_D_AQRL:	"AMOMINU.D.AQRL",
+	AMOMINU_D_RL:	"AMOMINU.D.RL",
+	AMOMINU_W:	"AMOMINU.W",
+	AMOMINU_W_AQ:	"AMOMINU.W.AQ",
+	AMOMINU_W_AQRL:	"AMOMINU.W.AQRL",
+	AMOMINU_W_RL:	"AMOMINU.W.RL",
+	AMOMIN_D:	"AMOMIN.D",
+	AMOMIN_D_AQ:	"AMOMIN.D.AQ",
+	AMOMIN_D_AQRL:	"AMOMIN.D.AQRL",
+	AMOMIN_D_RL:	"AMOMIN.D.RL",
+	AMOMIN_W:	"AMOMIN.W",
+	AMOMIN_W_AQ:	"AMOMIN.W.AQ",
+	AMOMIN_W_AQRL:	"AMOMIN.W.AQRL",
+	AMOMIN_W_RL:	"AMOMIN.W.RL",
+	AMOOR_D:	"AMOOR.D",
+	AMOOR_D_AQ:	"AMOOR.D.AQ",
+	AMOOR_D_AQRL:	"AMOOR.D.AQRL",
+	AMOOR_D_RL:	"AMOOR.D.RL",
+	AMOOR_W:	"AMOOR.W",
+	AMOOR_W_AQ:	"AMOOR.W.AQ",
+	AMOOR_W_AQRL:	"AMOOR.W.AQRL",
+	AMOOR_W_RL:	"AMOOR.W.RL",
+	AMOSWAP_D:	"AMOSWAP.D",
+	AMOSWAP_D_AQ:	"AMOSWAP.D.AQ",
+	AMOSWAP_D_AQRL:	"AMOSWAP.D.AQRL",
+	AMOSWAP_D_RL:	"AMOSWAP.D.RL",
+	AMOSWAP_W:	"AMOSWAP.W",
+	AMOSWAP_W_AQ:	"AMOSWAP.W.AQ",
+	AMOSWAP_W_AQRL:	"AMOSWAP.W.AQRL",
+	AMOSWAP_W_RL:	"AMOSWAP.W.RL",
+	AMOXOR_D:	"AMOXOR.D",
+	AMOXOR_D_AQ:	"AMOXOR.D.AQ",
+	AMOXOR_D_AQRL:	"AMOXOR.D.AQRL",
+	AMOXOR_D_RL:	"AMOXOR.D.RL",
+	AMOXOR_W:	"AMOXOR.W",
+	AMOXOR_W_AQ:	"AMOXOR.W.AQ",
+	AMOXOR_W_AQRL:	"AMOXOR.W.AQRL",
+	AMOXOR_W_RL:	"AMOXOR.W.RL",
+	AND:	"AND",
+	ANDI:	"ANDI",
+	AUIPC:	"AUIPC",
+	BEQ:	"BEQ",
+	BGE:	"BGE",
+	BGEU:	"BGEU",
+	BLT:	"BLT",
+	BLTU:	"BLTU",
+	BNE:	"BNE",
+	CSRRC:	"CSRRC",
+	CSRRCI:	"CSRRCI",
+	CSRRS:	"CSRRS",
+	CSRRSI:	"CSRRSI",
+	CSRRW:	"CSRRW",
+	CSRRWI:	"CSRRWI",
+	C_ADD:	"C.ADD",
+	C_ADDI:	"C.ADDI",
+	C_ADDI16SP:	"C.ADDI16SP",
+	C_ADDI4SPN:	"C.ADDI4SPN",
+	C_ADDIW:	"C.ADDIW",
+	C_ADDW:	"C.ADDW",
+	C_AND:	"C.AND",
+	C_ANDI:	"C.ANDI",
+	C_BEQZ:	"C.BEQZ",
+	C_BNEZ:	"C.BNEZ",
+	C_EBREAK:	"C.EBREAK",
+	C_FLD:	"C.FLD",
+	C_FLDSP:	"C.FLDSP",
+	C_FSD:	"C.FSD",
+	C_FSDSP:	"C.FSDSP",
+	C_J:	"C.J",
+	C_JALR:	"C.JALR",
+	C_JR:	"C.JR",
+	C_LD:	"C.LD",
+	C_LDSP:	"C.LDSP",
+	C_LI:	"C.LI",
+	C_LUI:	"C.LUI",
+	C_LW:	"C.LW",
+	C_LWSP:	"C.LWSP",
+	C_MV:	"C.MV",
+	C_NOP:	"C.NOP",
+	C_OR:	"C.OR",
+	C_SD:	"C.SD",
+	C_SDSP:	"C.SDSP",
+	C_SLLI:	"C.SLLI",
+	C_SRAI:	"C.SRAI",
+	C_SRLI:	"C.SRLI",
+	C_SUB:	"C.SUB",
+	C_SUBW:	"C.SUBW",
+	C_SW:	"C.SW",
+	C_SWSP:	"C.SWSP",
+	C_UNIMP:	"C.UNIMP",
+	C_XOR:	"C.XOR",
+	DIV:	"DIV",
+	DIVU:	"DIVU",
+	DIVUW:	"DIVUW",
+	DIVW:	"DIVW",
+	EBREAK:	"EBREAK",
+	ECALL:	"ECALL",
+	FADD_D:	"FADD.D",
+	FADD_H:	"FADD.H",
+	FADD_Q:	"FADD.Q",
+	FADD_S:	"FADD.S",
+	FCLASS_D:	"FCLASS.D",
+	FCLASS_H:	"FCLASS.H",
+	FCLASS_Q:	"FCLASS.Q",
+	FCLASS_S:	"FCLASS.S",
+	FCVT_D_L:	"FCVT.D.L",
+	FCVT_D_LU:	"FCVT.D.LU",
+	FCVT_D_Q:	"FCVT.D.Q",
+	FCVT_D_S:	"FCVT.D.S",
+	FCVT_D_W:	"FCVT.D.W",
+	FCVT_D_WU:	"FCVT.D.WU",
+	FCVT_H_L:	"FCVT.H.L",
+	FCVT_H_LU:	"FCVT.H.LU",
+	FCVT_H_S:	"FCVT.H.S",
+	FCVT_H_W:	"FCVT.H.W",
+	FCVT_H_WU:	"FCVT.H.WU",
+	FCVT_LU_D:	"FCVT.LU.D",
+	FCVT_LU_H:	"FCVT.LU.H",
+	FCVT_LU_Q:	"FCVT.LU.Q",
+	FCVT_LU_S:	"FCVT.LU.S",
+	FCVT_L_D:	"FCVT.L.D",
+	FCVT_L_H:	"FCVT.L.H",
+	FCVT_L_Q:	"FCVT.L.Q",
+	FCVT_L_S:	"FCVT.L.S",
+	FCVT_Q_D:	"FCVT.Q.D",
+	FCVT_Q_L:	"FCVT.Q.L",
+	FCVT_Q_LU:	"FCVT.Q.LU",
+	FCVT_Q_S:	"FCVT.Q.S",
+	FCVT_Q_W:	"FCVT.Q.W",
+	FCVT_Q_WU:	"FCVT.Q.WU",
+	FCVT_S_D:	"FCVT.S.D",
+	FCVT_S_H:	"FCVT.S.H",
+	FCVT_S_L:	"FCVT.S.L",
+	FCVT_S_LU:	"FCVT.S.LU",
+	FCVT_S_Q:	"FCVT.S.Q",
+	FCVT_S_W:	"FCVT.S.W",
+	FCVT_S_WU:	"FCVT.S.WU",
+	FCVT_WU_D:	"FCVT.WU.D",
+	FCVT_WU_H:	"FCVT.WU.H",
+	FCVT_WU_Q:	"FCVT.WU.Q",
+	FCVT_WU_S:	"FCVT.WU.S",
+	FCVT_W_D:	"FCVT.W.D",
+	FCVT_W_H:	"FCVT.W.H",
+	FCVT_W_Q:	"FCVT.W.Q",
+	FCVT_W_S:	"FCVT.W.S",
+	FDIV_D:	"FDIV.D",
+	FDIV_H:	"FDIV.H",
+	FDIV_Q:	"FDIV.Q",
+	FDIV_S:	"FDIV.S",
+	FENCE:	"FENCE",
+	FENCE_I:	"FENCE.I",
+	FEQ_D:	"FEQ.D",
+	FEQ_H:	"FEQ.H",
+	FEQ_Q:	"FEQ.Q",
+	FEQ_S:	"FEQ.S",
+	FLD:	"FLD",
+	FLE_D:	"FLE.D",
+	FLE_H:	"FLE.H",
+	FLE_Q:	"FLE.Q",
+	FLE_S:	"FLE.S",
+	FLH:	"FLH",
+	FLQ:	"FLQ",
+	FLT_D:	"FLT.D",
+	FLT_H:	"FLT.H",
+	FLT_Q:	"FLT.Q",
+	FLT_S:	"FLT.S",
+	FLW:	"FLW",
+	FMADD_D:	"FMADD.D",
+	FMADD_H:	"FMADD.H",
+	FMADD_Q:	"FMADD.Q",
+	FMADD_S:	"FMADD.S",
+	FMAX_D:	"FMAX.D",
+	FMAX_H:	"FMAX.H",
+	FMAX_Q:	"FMAX.Q",
+	FMAX_S:	"FMAX.S",
+	FMIN_D:	"FMIN.D",
+	FMIN_H:	"FMIN.H",
+	FMIN_Q:	"FMIN.Q",
+	FMIN_S:	"FMIN.S",
+	FMSUB_D:	"FMSUB.D",
+	FMSUB_H:	"FMSUB.H",
+	FMSUB_Q:	"FMSUB.Q",
+	FMSUB_S:	"FMSUB.S",
+	FMUL_D:	"FMUL.D",
+	FMUL_H:	"FMUL.H",
+	FMUL_Q:	"FMUL.Q",
+	FMUL_S:	"FMUL.S",
+	FMV_D_X:	"FMV.D.X",
+	FMV_H_X:	"FMV.H.X",
+	FMV_W_X:	"FMV.W.X",
+	FMV_X_D:	"FMV.X.D",
+	FMV_X_H:	"FMV.X.H",
+	FMV_X_W:	"FMV.X.W",
+	FNMADD_D:	"FNMADD.D",
+	FNMADD_H:	"FNMADD.H",
+	FNMADD_Q:	"FNMADD.Q",
+	FNMADD_S:	"FNMADD.S",
+	FNMSUB_D:	"FNMSUB.D",
+	FNMSUB_H:	"FNMSUB.H",
+	FNMSUB_Q:	"FNMSUB.Q",
+	FNMSUB_S:	"FNMSUB.S",
+	FSD:	"FSD",
+	FSGNJN_D:	"FSGNJN.D",
+	FSGNJN_H:	"FSGNJN.H",
+	FSGNJN_Q:	"FSGNJN.Q",
+	FSGNJN_S:	"FSGNJN.S",
+	FSGNJX_D:	"FSGNJX.D",
+	FSGNJX_H:	"FSGNJX.H",
+	FSGNJX_Q:	"FSGNJX.Q",
+	FSGNJX_S:	"FSGNJX.S",
+	FSGNJ_D:	"FSGNJ.D",
+	FSGNJ_H:	"FSGNJ.H",
+	FSGNJ_Q:	"FSGNJ.Q",
+	FSGNJ_S:	"FSGNJ.S",
+	FSH:	"FSH",
+	FSQ:	"FSQ",
+	FSQRT_D:	"FSQRT.D",
+	FSQRT_H:	"FSQRT.H",
+	FSQRT_Q:	"FSQRT.Q",
+	FSQRT_S:	"FSQRT.S",
+	FSUB_D:	"FSUB.D",
+	FSUB_H:	"FSUB.H",
+	FSUB_Q:	"FSUB.Q",
+	FSUB_S:	"FSUB.S",
+	FSW:	"FSW",
+	JAL:	"JAL",
+	JALR:	"JALR",
+	LB:	"LB",
+	LBU:	"LBU",
+	LD:	"LD",
+	LH:	"LH",
+	LHU:	"LHU",
+	LR_D:	"LR.D",
+	LR_D_AQ:	"LR.D.AQ",
+	LR_D_AQRL:	"LR.D.AQRL",
+	LR_D_RL:	"LR.D.RL",
+	LR_W:	"LR.W",
+	LR_W_AQ:	"LR.W.AQ",
+	LR_W_AQRL:	"LR.W.AQRL",
+	LR_W_RL:	"LR.W.RL",
+	LUI:	"LUI",
+	LW:	"LW",
+	LWU:	"LWU",
+	MUL:	"MUL",
+	MULH:	"MULH",
+	MULHSU:	"MULHSU",
+	MULHU:	"MULHU",
+	MULW:	"MULW",
+	OR:	"OR",
+	ORI:	"ORI",
+	REM:	"REM",
+	REMU:	"REMU",
+	REMUW:	"REMUW",
+	REMW:	"REMW",
+	SB:	"SB",
+	SC_D:	"SC.D",
+	SC_D_AQ:	"SC.D.AQ",
+	SC_D_AQRL:	"SC.D.AQRL",
+	SC_D_RL:	"SC.D.RL",
+	SC_W:	"SC.W",
+	SC_W_AQ:	"SC.W.AQ",
+	SC_W_AQRL:	"SC.W.AQRL",
+	SC_W_RL:	"SC.W.RL",
+	SD:	"SD",
+	SH:	"SH",
+	SLL:	"SLL",
+	SLLI:	"SLLI",
+	SLLIW:	"SLLIW",
+	SLLW:	"SLLW",
+	SLT:	"SLT",
+	SLTI:	"SLTI",
+	SLTIU:	"SLTIU",
+	SLTU:	"SLTU",
+	SRA:	"SRA",
+	SRAI:	"SRAI",
+	SRAIW:	"SRAIW",
+	SRAW:	"SRAW",
+	SRL:	"SRL",
+	SRLI:	"SRLI",
+	SRLIW:	"SRLIW",
+	SRLW:	"SRLW",
+	SUB:	"SUB",
+	SUBW:	"SUBW",
+	SW:	"SW",
+	XOR:	"XOR",
+	XORI:	"XORI",
+}
+
+var instFormats = [...]instFormat{
+	// ADD rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x00000033, op: ADD, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// ADDI rd, rs1, imm12
+	{mask: 0x0000707f, value: 0x00000013, op: ADDI, args: instArgs{arg_rd, arg_rs1, arg_imm12}},
+	// ADDIW rd, rs1, imm12
+	{mask: 0x0000707f, value: 0x0000001b, op: ADDIW, args: instArgs{arg_rd, arg_rs1, arg_imm12}},
+	// ADDW rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x0000003b, op: ADDW, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// AMOADD.D rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0000302f, op: AMOADD_D, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOADD.D.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0400302f, op: AMOADD_D_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOADD.D.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0600302f, op: AMOADD_D_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOADD.D.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0200302f, op: AMOADD_D_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOADD.W rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0000202f, op: AMOADD_W, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOADD.W.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0400202f, op: AMOADD_W_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOADD.W.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0600202f, op: AMOADD_W_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOADD.W.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0200202f, op: AMOADD_W_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOAND.D rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x6000302f, op: AMOAND_D, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOAND.D.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x6400302f, op: AMOAND_D_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOAND.D.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x6600302f, op: AMOAND_D_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOAND.D.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x6200302f, op: AMOAND_D_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOAND.W rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x6000202f, op: AMOAND_W, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOAND.W.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x6400202f, op: AMOAND_W_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOAND.W.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x6600202f, op: AMOAND_W_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOAND.W.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x6200202f, op: AMOAND_W_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAXU.D rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xe000302f, op: AMOMAXU_D, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAXU.D.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xe400302f, op: AMOMAXU_D_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAXU.D.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xe600302f, op: AMOMAXU_D_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAXU.D.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xe200302f, op: AMOMAXU_D_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAXU.W rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xe000202f, op: AMOMAXU_W, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAXU.W.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xe400202f, op: AMOMAXU_W_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAXU.W.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xe600202f, op: AMOMAXU_W_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAXU.W.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xe200202f, op: AMOMAXU_W_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAX.D rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xa000302f, op: AMOMAX_D, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAX.D.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xa400302f, op: AMOMAX_D_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAX.D.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xa600302f, op: AMOMAX_D_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAX.D.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xa200302f, op: AMOMAX_D_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAX.W rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xa000202f, op: AMOMAX_W, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAX.W.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xa400202f, op: AMOMAX_W_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAX.W.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xa600202f, op: AMOMAX_W_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMAX.W.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xa200202f, op: AMOMAX_W_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMINU.D rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xc000302f, op: AMOMINU_D, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMINU.D.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xc400302f, op: AMOMINU_D_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMINU.D.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xc600302f, op: AMOMINU_D_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMINU.D.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xc200302f, op: AMOMINU_D_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMINU.W rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xc000202f, op: AMOMINU_W, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMINU.W.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xc400202f, op: AMOMINU_W_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMINU.W.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xc600202f, op: AMOMINU_W_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMINU.W.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0xc200202f, op: AMOMINU_W_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMIN.D rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x8000302f, op: AMOMIN_D, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMIN.D.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x8400302f, op: AMOMIN_D_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMIN.D.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x8600302f, op: AMOMIN_D_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMIN.D.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x8200302f, op: AMOMIN_D_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMIN.W rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x8000202f, op: AMOMIN_W, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMIN.W.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x8400202f, op: AMOMIN_W_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMIN.W.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x8600202f, op: AMOMIN_W_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOMIN.W.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x8200202f, op: AMOMIN_W_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOOR.D rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x4000302f, op: AMOOR_D, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOOR.D.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x4400302f, op: AMOOR_D_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOOR.D.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x4600302f, op: AMOOR_D_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOOR.D.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x4200302f, op: AMOOR_D_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOOR.W rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x4000202f, op: AMOOR_W, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOOR.W.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x4400202f, op: AMOOR_W_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOOR.W.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x4600202f, op: AMOOR_W_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOOR.W.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x4200202f, op: AMOOR_W_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOSWAP.D rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0800302f, op: AMOSWAP_D, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOSWAP.D.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0c00302f, op: AMOSWAP_D_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOSWAP.D.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0e00302f, op: AMOSWAP_D_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOSWAP.D.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0a00302f, op: AMOSWAP_D_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOSWAP.W rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0800202f, op: AMOSWAP_W, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOSWAP.W.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0c00202f, op: AMOSWAP_W_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOSWAP.W.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0e00202f, op: AMOSWAP_W_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOSWAP.W.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x0a00202f, op: AMOSWAP_W_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOXOR.D rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x2000302f, op: AMOXOR_D, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOXOR.D.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x2400302f, op: AMOXOR_D_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOXOR.D.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x2600302f, op: AMOXOR_D_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOXOR.D.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x2200302f, op: AMOXOR_D_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOXOR.W rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x2000202f, op: AMOXOR_W, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOXOR.W.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x2400202f, op: AMOXOR_W_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOXOR.W.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x2600202f, op: AMOXOR_W_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AMOXOR.W.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x2200202f, op: AMOXOR_W_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// AND rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x00007033, op: AND, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// ANDI rd, rs1, imm12
+	{mask: 0x0000707f, value: 0x00007013, op: ANDI, args: instArgs{arg_rd, arg_rs1, arg_imm12}},
+	// AUIPC rd, imm20
+	{mask: 0x0000007f, value: 0x00000017, op: AUIPC, args: instArgs{arg_rd, arg_imm20}},
+	// BEQ rs1, rs2, bimm12
+	{mask: 0x0000707f, value: 0x00000063, op: BEQ, args: instArgs{arg_rs1, arg_rs2, arg_bimm12}},
+	// BGE rs1, rs2, bimm12
+	{mask: 0x0000707f, value: 0x00005063, op: BGE, args: instArgs{arg_rs1, arg_rs2, arg_bimm12}},
+	// BGEU rs1, rs2, bimm12
+	{mask: 0x0000707f, value: 0x00007063, op: BGEU, args: instArgs{arg_rs1, arg_rs2, arg_bimm12}},
+	// BLT rs1, rs2, bimm12
+	{mask: 0x0000707f, value: 0x00004063, op: BLT, args: instArgs{arg_rs1, arg_rs2, arg_bimm12}},
+	// BLTU rs1, rs2, bimm12
+	{mask: 0x0000707f, value: 0x00006063, op: BLTU, args: instArgs{arg_rs1, arg_rs2, arg_bimm12}},
+	// BNE rs1, rs2, bimm12
+	{mask: 0x0000707f, value: 0x00001063, op: BNE, args: instArgs{arg_rs1, arg_rs2, arg_bimm12}},
+	// CSRRC rd, csr, rs1
+	{mask: 0x0000707f, value: 0x00003073, op: CSRRC, args: instArgs{arg_rd, arg_csr, arg_rs1}},
+	// CSRRCI rd, csr, zimm
+	{mask: 0x0000707f, value: 0x00007073, op: CSRRCI, args: instArgs{arg_rd, arg_csr, arg_zimm}},
+	// CSRRS rd, csr, rs1
+	{mask: 0x0000707f, value: 0x00002073, op: CSRRS, args: instArgs{arg_rd, arg_csr, arg_rs1}},
+	// CSRRSI rd, csr, zimm
+	{mask: 0x0000707f, value: 0x00006073, op: CSRRSI, args: instArgs{arg_rd, arg_csr, arg_zimm}},
+	// CSRRW rd, csr, rs1
+	{mask: 0x0000707f, value: 0x00001073, op: CSRRW, args: instArgs{arg_rd, arg_csr, arg_rs1}},
+	// CSRRWI rd, csr, zimm
+	{mask: 0x0000707f, value: 0x00005073, op: CSRRWI, args: instArgs{arg_rd, arg_csr, arg_zimm}},
+	// C.ADD rd_rs1_n0, c_rs2_n0
+	{mask: 0x0000f003, value: 0x00009002, op: C_ADD, args: instArgs{arg_rd_rs1_n0, arg_c_rs2_n0}},
+	// C.ADDI rd_rs1_n0, c_nzimm6
+	{mask: 0x0000e003, value: 0x00000001, op: C_ADDI, args: instArgs{arg_rd_rs1_n0, arg_c_nzimm6}},
+	// C.ADDI16SP c_nzimm10
+	{mask: 0x0000ef83, value: 0x00006101, op: C_ADDI16SP, args: instArgs{arg_c_nzimm10}},
+	// C.ADDI4SPN rd_p, c_nzuimm10
+	{mask: 0x0000e003, value: 0x00000000, op: C_ADDI4SPN, args: instArgs{arg_rd_p, arg_c_nzuimm10}},
+	// C.ADDIW rd_rs1_n0, c_imm6
+	{mask: 0x0000e003, value: 0x00002001, op: C_ADDIW, args: instArgs{arg_rd_rs1_n0, arg_c_imm6}},
+	// C.ADDW rd_rs1_p, rs2_p
+	{mask: 0x0000fc63, value: 0x00009c21, op: C_ADDW, args: instArgs{arg_rd_rs1_p, arg_rs2_p}},
+	// C.AND rd_rs1_p, rs2_p
+	{mask: 0x0000fc63, value: 0x00008c61, op: C_AND, args: instArgs{arg_rd_rs1_p, arg_rs2_p}},
+	// C.ANDI rd_rs1_p, c_imm6
+	{mask: 0x0000ec03, value: 0x00008801, op: C_ANDI, args: instArgs{arg_rd_rs1_p, arg_c_imm6}},
+	// C.BEQZ rs1_p, c_bimm9
+	{mask: 0x0000e003, value: 0x0000c001, op: C_BEQZ, args: instArgs{arg_rs1_p, arg_c_bimm9}},
+	// C.BNEZ rs1_p, c_bimm9
+	{mask: 0x0000e003, value: 0x0000e001, op: C_BNEZ, args: instArgs{arg_rs1_p, arg_c_bimm9}},
+	// C.EBREAK
+	{mask: 0x0000ffff, value: 0x00009002, op: C_EBREAK, args: instArgs{}},
+	// C.FLD fd_p, rs1_p, c_uimm8
+	{mask: 0x0000e003, value: 0x00002000, op: C_FLD, args: instArgs{arg_fd_p, arg_rs1_p, arg_c_uimm8}},
+	// C.FLDSP fd, c_uimm9sp
+	{mask: 0x0000e003, value: 0x00002002, op: C_FLDSP, args: instArgs{arg_fd, arg_c_uimm9sp}},
+	// C.FSD rs1_p, fs2_p, c_uimm8
+	{mask: 0x0000e003, value: 0x0000a000, op: C_FSD, args: instArgs{arg_rs1_p, arg_fs2_p, arg_c_uimm8}},
+	// C.FSDSP c_fs2, c_uimm9sp_s
+	{mask: 0x0000e003, value: 0x0000a002, op: C_FSDSP, args: instArgs{arg_c_fs2, arg_c_uimm9sp_s}},
+	// C.J c_imm12
+	{mask: 0x0000e003, value: 0x0000a001, op: C_J, args: instArgs{arg_c_imm12}},
+	// C.JALR c_rs1_n0
+	{mask: 0x0000f07f, value: 0x00009002, op: C_JALR, args: instArgs{arg_c_rs1_n0}},
+	// C.JR rs1_n0
+	{mask: 0x0000f07f, value: 0x00008002, op: C_JR, args: instArgs{arg_rs1_n0}},
+	// C.LD rd_p, rs1_p, c_uimm8
+	{mask: 0x0000e003, value: 0x00006000, op: C_LD, args: instArgs{arg_rd_p, arg_rs1_p, arg_c_uimm8}},
+	// C.LDSP rd_n0, c_uimm9sp
+	{mask: 0x0000e003, value: 0x00006002, op: C_LDSP, args: instArgs{arg_rd_n0, arg_c_uimm9sp}},
+	// C.LI rd_n0, c_imm6
+	{mask: 0x0000e003, value: 0x00004001, op: C_LI, args: instArgs{arg_rd_n0, arg_c_imm6}},
+	// C.LUI rd_n2, c_nzimm18
+	{mask: 0x0000e003, value: 0x00006001, op: C_LUI, args: instArgs{arg_rd_n2, arg_c_nzimm18}},
+	// C.LW rd_p, rs1_p, c_uimm7
+	{mask: 0x0000e003, value: 0x00004000, op: C_LW, args: instArgs{arg_rd_p, arg_rs1_p, arg_c_uimm7}},
+	// C.LWSP rd_n0, c_uimm8sp
+	{mask: 0x0000e003, value: 0x00004002, op: C_LWSP, args: instArgs{arg_rd_n0, arg_c_uimm8sp}},
+	// C.MV rd_n0, c_rs2_n0
+	{mask: 0x0000f003, value: 0x00008002, op: C_MV, args: instArgs{arg_rd_n0, arg_c_rs2_n0}},
+	// C.NOP c_nzimm6
+	{mask: 0x0000ef83, value: 0x00000001, op: C_NOP, args: instArgs{arg_c_nzimm6}},
+	// C.OR rd_rs1_p, rs2_p
+	{mask: 0x0000fc63, value: 0x00008c41, op: C_OR, args: instArgs{arg_rd_rs1_p, arg_rs2_p}},
+	// C.SD rs1_p, rs2_p, c_uimm8
+	{mask: 0x0000e003, value: 0x0000e000, op: C_SD, args: instArgs{arg_rs1_p, arg_rs2_p, arg_c_uimm8}},
+	// C.SDSP c_rs2, c_uimm9sp_s
+	{mask: 0x0000e003, value: 0x0000e002, op: C_SDSP, args: instArgs{arg_c_rs2, arg_c_uimm9sp_s}},
+	// C.SLLI rd_rs1_n0, c_nzuimm6
+	{mask: 0x0000e003, value: 0x00000002, op: C_SLLI, args: instArgs{arg_rd_rs1_n0, arg_c_nzuimm6}},
+	// C.SRAI rd_rs1_p, c_nzuimm6
+	{mask: 0x0000ec03, value: 0x00008401, op: C_SRAI, args: instArgs{arg_rd_rs1_p, arg_c_nzuimm6}},
+	// C.SRLI rd_rs1_p, c_nzuimm6
+	{mask: 0x0000ec03, value: 0x00008001, op: C_SRLI, args: instArgs{arg_rd_rs1_p, arg_c_nzuimm6}},
+	// C.SUB rd_rs1_p, rs2_p
+	{mask: 0x0000fc63, value: 0x00008c01, op: C_SUB, args: instArgs{arg_rd_rs1_p, arg_rs2_p}},
+	// C.SUBW rd_rs1_p, rs2_p
+	{mask: 0x0000fc63, value: 0x00009c01, op: C_SUBW, args: instArgs{arg_rd_rs1_p, arg_rs2_p}},
+	// C.SW rs1_p, rs2_p, c_uimm7
+	{mask: 0x0000e003, value: 0x0000c000, op: C_SW, args: instArgs{arg_rs1_p, arg_rs2_p, arg_c_uimm7}},
+	// C.SWSP c_rs2, c_uimm8sp_s
+	{mask: 0x0000e003, value: 0x0000c002, op: C_SWSP, args: instArgs{arg_c_rs2, arg_c_uimm8sp_s}},
+	// C.UNIMP
+	{mask: 0x0000ffff, value: 0x00000000, op: C_UNIMP, args: instArgs{}},
+	// C.XOR rd_rs1_p, rs2_p
+	{mask: 0x0000fc63, value: 0x00008c21, op: C_XOR, args: instArgs{arg_rd_rs1_p, arg_rs2_p}},
+	// DIV rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x02004033, op: DIV, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// DIVU rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x02005033, op: DIVU, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// DIVUW rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x0200503b, op: DIVUW, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// DIVW rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x0200403b, op: DIVW, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// EBREAK
+	{mask: 0xffffffff, value: 0x00100073, op: EBREAK, args: instArgs{}},
+	// ECALL
+	{mask: 0xffffffff, value: 0x00000073, op: ECALL, args: instArgs{}},
+	// FADD.D fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x02000053, op: FADD_D, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FADD.H fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x04000053, op: FADD_H, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FADD.Q fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x06000053, op: FADD_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FADD.S fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x00000053, op: FADD_S, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FCLASS.D rd, fs1
+	{mask: 0xfff0707f, value: 0xe2001053, op: FCLASS_D, args: instArgs{arg_rd, arg_fs1}},
+	// FCLASS.H rd, fs1
+	{mask: 0xfff0707f, value: 0xe4001053, op: FCLASS_H, args: instArgs{arg_rd, arg_fs1}},
+	// FCLASS.Q rd, fs1
+	{mask: 0xfff0707f, value: 0xe6001053, op: FCLASS_Q, args: instArgs{arg_rd, arg_fs1}},
+	// FCLASS.S rd, fs1
+	{mask: 0xfff0707f, value: 0xe0001053, op: FCLASS_S, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.D.L fd, rs1
+	{mask: 0xfff0007f, value: 0xd2200053, op: FCVT_D_L, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.D.LU fd, rs1
+	{mask: 0xfff0007f, value: 0xd2300053, op: FCVT_D_LU, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.D.Q fd, fs1
+	{mask: 0xfff0007f, value: 0x42300053, op: FCVT_D_Q, args: instArgs{arg_fd, arg_fs1}},
+	// FCVT.D.S fd, fs1
+	{mask: 0xfff0007f, value: 0x42000053, op: FCVT_D_S, args: instArgs{arg_fd, arg_fs1}},
+	// FCVT.D.W fd, rs1
+	{mask: 0xfff0007f, value: 0xd2000053, op: FCVT_D_W, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.D.WU fd, rs1
+	{mask: 0xfff0007f, value: 0xd2100053, op: FCVT_D_WU, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.H.L fd, rs1
+	{mask: 0xfff0007f, value: 0xd4200053, op: FCVT_H_L, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.H.LU fd, rs1
+	{mask: 0xfff0007f, value: 0xd4300053, op: FCVT_H_LU, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.H.S fd, fs1
+	{mask: 0xfff0007f, value: 0x44000053, op: FCVT_H_S, args: instArgs{arg_fd, arg_fs1}},
+	// FCVT.H.W fd, rs1
+	{mask: 0xfff0007f, value: 0xd4000053, op: FCVT_H_W, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.H.WU fd, rs1
+	{mask: 0xfff0007f, value: 0xd4100053, op: FCVT_H_WU, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.LU.D rd, fs1
+	{mask: 0xfff0007f, value: 0xc2300053, op: FCVT_LU_D, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.LU.H rd, fs1
+	{mask: 0xfff0007f, value: 0xc4300053, op: FCVT_LU_H, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.LU.Q rd, fs1
+	{mask: 0xfff0007f, value: 0xc6300053, op: FCVT_LU_Q, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.LU.S rd, fs1
+	{mask: 0xfff0007f, value: 0xc0300053, op: FCVT_LU_S, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.L.D rd, fs1
+	{mask: 0xfff0007f, value: 0xc2200053, op: FCVT_L_D, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.L.H rd, fs1
+	{mask: 0xfff0007f, value: 0xc4200053, op: FCVT_L_H, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.L.Q rd, fs1
+	{mask: 0xfff0007f, value: 0xc6200053, op: FCVT_L_Q, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.L.S rd, fs1
+	{mask: 0xfff0007f, value: 0xc0200053, op: FCVT_L_S, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.Q.D fd, fs1
+	{mask: 0xfff0007f, value: 0x46100053, op: FCVT_Q_D, args: instArgs{arg_fd, arg_fs1}},
+	// FCVT.Q.L fd, rs1
+	{mask: 0xfff0007f, value: 0xd6200053, op: FCVT_Q_L, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.Q.LU fd, rs1
+	{mask: 0xfff0007f, value: 0xd6300053, op: FCVT_Q_LU, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.Q.S fd, fs1
+	{mask: 0xfff0007f, value: 0x46000053, op: FCVT_Q_S, args: instArgs{arg_fd, arg_fs1}},
+	// FCVT.Q.W fd, rs1
+	{mask: 0xfff0007f, value: 0xd6000053, op: FCVT_Q_W, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.Q.WU fd, rs1
+	{mask: 0xfff0007f, value: 0xd6100053, op: FCVT_Q_WU, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.S.D fd, fs1
+	{mask: 0xfff0007f, value: 0x40100053, op: FCVT_S_D, args: instArgs{arg_fd, arg_fs1}},
+	// FCVT.S.H fd, fs1
+	{mask: 0xfff0007f, value: 0x40200053, op: FCVT_S_H, args: instArgs{arg_fd, arg_fs1}},
+	// FCVT.S.L fd, rs1
+	{mask: 0xfff0007f, value: 0xd0200053, op: FCVT_S_L, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.S.LU fd, rs1
+	{mask: 0xfff0007f, value: 0xd0300053, op: FCVT_S_LU, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.S.Q fd, fs1
+	{mask: 0xfff0007f, value: 0x40300053, op: FCVT_S_Q, args: instArgs{arg_fd, arg_fs1}},
+	// FCVT.S.W fd, rs1
+	{mask: 0xfff0007f, value: 0xd0000053, op: FCVT_S_W, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.S.WU fd, rs1
+	{mask: 0xfff0007f, value: 0xd0100053, op: FCVT_S_WU, args: instArgs{arg_fd, arg_rs1}},
+	// FCVT.WU.D rd, fs1
+	{mask: 0xfff0007f, value: 0xc2100053, op: FCVT_WU_D, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.WU.H rd, fs1
+	{mask: 0xfff0007f, value: 0xc4100053, op: FCVT_WU_H, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.WU.Q rd, fs1
+	{mask: 0xfff0007f, value: 0xc6100053, op: FCVT_WU_Q, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.WU.S rd, fs1
+	{mask: 0xfff0007f, value: 0xc0100053, op: FCVT_WU_S, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.W.D rd, fs1
+	{mask: 0xfff0007f, value: 0xc2000053, op: FCVT_W_D, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.W.H rd, fs1
+	{mask: 0xfff0007f, value: 0xc4000053, op: FCVT_W_H, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.W.Q rd, fs1
+	{mask: 0xfff0007f, value: 0xc6000053, op: FCVT_W_Q, args: instArgs{arg_rd, arg_fs1}},
+	// FCVT.W.S rd, fs1
+	{mask: 0xfff0007f, value: 0xc0000053, op: FCVT_W_S, args: instArgs{arg_rd, arg_fs1}},
+	// FDIV.D fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x1a000053, op: FDIV_D, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FDIV.H fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x1c000053, op: FDIV_H, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FDIV.Q fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x1e000053, op: FDIV_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FDIV.S fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x18000053, op: FDIV_S, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FENCE pred, succ
+	{mask: 0x0000707f, value: 0x0000000f, op: FENCE, args: instArgs{arg_pred, arg_succ}},
+	// FENCE.I
+	{mask: 0x0000707f, value: 0x0000100f, op: FENCE_I, args: instArgs{}},
+	// FEQ.D rd, fs1, fs2
+	{mask: 0xfe00707f, value: 0xa2002053, op: FEQ_D, args: instArgs{arg_rd, arg_fs1, arg_fs2}},
+	// FEQ.H rd, fs1, fs2
+	{mask: 0xfe00707f, value: 0xa4002053, op: FEQ_H, args: instArgs{arg_rd, arg_fs1, arg_fs2}},
+	// FEQ.Q rd, fs1, fs2
+	{mask: 0xfe00707f, value: 0xa6002053, op: FEQ_Q, args: instArgs{arg_rd, arg_fs1, arg_fs2}},
+	// FEQ.S rd, fs1, fs2
+	{mask: 0xfe00707f, value: 0xa0002053, op: FEQ_S, args: instArgs{arg_rd, arg_fs1, arg_fs2}},
+	// FLD fd, rs1_mem
+	{mask: 0x0000707f, value: 0x00003007, op: FLD, args: instArgs{arg_fd, arg_rs1_mem}},
+	// FLE.D rd, fs1, fs2
+	{mask: 0xfe00707f, value: 0xa2000053, op: FLE_D, args: instArgs{arg_rd, arg_fs1, arg_fs2}},
+	// FLE.H rd, fs1, fs2
+	{mask: 0xfe00707f, value: 0xa4000053, op: FLE_H, args: instArgs{arg_rd, arg_fs1, arg_fs2}},
+	// FLE.Q rd, fs1, fs2
+	{mask: 0xfe00707f, value: 0xa6000053, op: FLE_Q, args: instArgs{arg_rd, arg_fs1, arg_fs2}},
+	// FLE.S rd, fs1, fs2
+	{mask: 0xfe00707f, value: 0xa0000053, op: FLE_S, args: instArgs{arg_rd, arg_fs1, arg_fs2}},
+	// FLH fd, rs1_mem
+	{mask: 0x0000707f, value: 0x00001007, op: FLH, args: instArgs{arg_fd, arg_rs1_mem}},
+	// FLQ fd, rs1_mem
+	{mask: 0x0000707f, value: 0x00004007, op: FLQ, args: instArgs{arg_fd, arg_rs1_mem}},
+	// FLT.D rd, fs1, fs2
+	{mask: 0xfe00707f, value: 0xa2001053, op: FLT_D, args: instArgs{arg_rd, arg_fs1, arg_fs2}},
+	// FLT.H rd, fs1, fs2
+	{mask: 0xfe00707f, value: 0xa4001053, op: FLT_H, args: instArgs{arg_rd, arg_fs1, arg_fs2}},
+	// FLT.Q rd, fs1, fs2
+	{mask: 0xfe00707f, value: 0xa6001053, op: FLT_Q, args: instArgs{arg_rd, arg_fs1, arg_fs2}},
+	// FLT.S rd, fs1, fs2
+	{mask: 0xfe00707f, value: 0xa0001053, op: FLT_S, args: instArgs{arg_rd, arg_fs1, arg_fs2}},
+	// FLW fd, rs1_mem
+	{mask: 0x0000707f, value: 0x00002007, op: FLW, args: instArgs{arg_fd, arg_rs1_mem}},
+	// FMADD.D fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x02000043, op: FMADD_D, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FMADD.H fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x04000043, op: FMADD_H, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FMADD.Q fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x06000043, op: FMADD_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FMADD.S fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x00000043, op: FMADD_S, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FMAX.D fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x2a001053, op: FMAX_D, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FMAX.H fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x2c001053, op: FMAX_H, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FMAX.Q fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x2e001053, op: FMAX_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FMAX.S fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x28001053, op: FMAX_S, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FMIN.D fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x2a000053, op: FMIN_D, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FMIN.H fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x2c000053, op: FMIN_H, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FMIN.Q fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x2e000053, op: FMIN_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FMIN.S fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x28000053, op: FMIN_S, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FMSUB.D fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x02000047, op: FMSUB_D, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FMSUB.H fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x04000047, op: FMSUB_H, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FMSUB.Q fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x06000047, op: FMSUB_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FMSUB.S fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x00000047, op: FMSUB_S, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FMUL.D fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x12000053, op: FMUL_D, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FMUL.H fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x14000053, op: FMUL_H, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FMUL.Q fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x16000053, op: FMUL_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FMUL.S fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x10000053, op: FMUL_S, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FMV.D.X fd, rs1
+	{mask: 0xfff0707f, value: 0xf2000053, op: FMV_D_X, args: instArgs{arg_fd, arg_rs1}},
+	// FMV.H.X fd, rs1
+	{mask: 0xfff0707f, value: 0xf4000053, op: FMV_H_X, args: instArgs{arg_fd, arg_rs1}},
+	// FMV.W.X fd, rs1
+	{mask: 0xfff0707f, value: 0xf0000053, op: FMV_W_X, args: instArgs{arg_fd, arg_rs1}},
+	// FMV.X.D rd, fs1
+	{mask: 0xfff0707f, value: 0xe2000053, op: FMV_X_D, args: instArgs{arg_rd, arg_fs1}},
+	// FMV.X.H rd, fs1
+	{mask: 0xfff0707f, value: 0xe4000053, op: FMV_X_H, args: instArgs{arg_rd, arg_fs1}},
+	// FMV.X.W rd, fs1
+	{mask: 0xfff0707f, value: 0xe0000053, op: FMV_X_W, args: instArgs{arg_rd, arg_fs1}},
+	// FNMADD.D fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x0200004f, op: FNMADD_D, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FNMADD.H fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x0400004f, op: FNMADD_H, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FNMADD.Q fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x0600004f, op: FNMADD_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FNMADD.S fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x0000004f, op: FNMADD_S, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FNMSUB.D fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x0200004b, op: FNMSUB_D, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FNMSUB.H fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x0400004b, op: FNMSUB_H, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FNMSUB.Q fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x0600004b, op: FNMSUB_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FNMSUB.S fd, fs1, fs2, fs3
+	{mask: 0x0600007f, value: 0x0000004b, op: FNMSUB_S, args: instArgs{arg_fd, arg_fs1, arg_fs2, arg_fs3}},
+	// FSD fs2, rs1_store
+	{mask: 0x0000707f, value: 0x00003027, op: FSD, args: instArgs{arg_fs2, arg_rs1_store}},
+	// FSGNJN.D fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x22001053, op: FSGNJN_D, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSGNJN.H fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x24001053, op: FSGNJN_H, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSGNJN.Q fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x26001053, op: FSGNJN_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSGNJN.S fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x20001053, op: FSGNJN_S, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSGNJX.D fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x22002053, op: FSGNJX_D, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSGNJX.H fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x24002053, op: FSGNJX_H, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSGNJX.Q fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x26002053, op: FSGNJX_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSGNJX.S fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x20002053, op: FSGNJX_S, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSGNJ.D fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x22000053, op: FSGNJ_D, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSGNJ.H fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x24000053, op: FSGNJ_H, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSGNJ.Q fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x26000053, op: FSGNJ_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSGNJ.S fd, fs1, fs2
+	{mask: 0xfe00707f, value: 0x20000053, op: FSGNJ_S, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSH fs2, rs1_store
+	{mask: 0x0000707f, value: 0x00001027, op: FSH, args: instArgs{arg_fs2, arg_rs1_store}},
+	// FSQ fs2, rs1_store
+	{mask: 0x0000707f, value: 0x00004027, op: FSQ, args: instArgs{arg_fs2, arg_rs1_store}},
+	// FSQRT.D fd, fs1
+	{mask: 0xfff0007f, value: 0x5a000053, op: FSQRT_D, args: instArgs{arg_fd, arg_fs1}},
+	// FSQRT.H fd, fs1
+	{mask: 0xfff0007f, value: 0x5c000053, op: FSQRT_H, args: instArgs{arg_fd, arg_fs1}},
+	// FSQRT.Q fd, fs1
+	{mask: 0xfff0007f, value: 0x5e000053, op: FSQRT_Q, args: instArgs{arg_fd, arg_fs1}},
+	// FSQRT.S fd, fs1
+	{mask: 0xfff0007f, value: 0x58000053, op: FSQRT_S, args: instArgs{arg_fd, arg_fs1}},
+	// FSUB.D fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x0a000053, op: FSUB_D, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSUB.H fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x0c000053, op: FSUB_H, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSUB.Q fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x0e000053, op: FSUB_Q, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSUB.S fd, fs1, fs2
+	{mask: 0xfe00007f, value: 0x08000053, op: FSUB_S, args: instArgs{arg_fd, arg_fs1, arg_fs2}},
+	// FSW fs2, rs1_store
+	{mask: 0x0000707f, value: 0x00002027, op: FSW, args: instArgs{arg_fs2, arg_rs1_store}},
+	// JAL rd, jimm20
+	{mask: 0x0000007f, value: 0x0000006f, op: JAL, args: instArgs{arg_rd, arg_jimm20}},
+	// JALR rd, rs1_mem
+	{mask: 0x0000707f, value: 0x00000067, op: JALR, args: instArgs{arg_rd, arg_rs1_mem}},
+	// LB rd, rs1_mem
+	{mask: 0x0000707f, value: 0x00000003, op: LB, args: instArgs{arg_rd, arg_rs1_mem}},
+	// LBU rd, rs1_mem
+	{mask: 0x0000707f, value: 0x00004003, op: LBU, args: instArgs{arg_rd, arg_rs1_mem}},
+	// LD rd, rs1_mem
+	{mask: 0x0000707f, value: 0x00003003, op: LD, args: instArgs{arg_rd, arg_rs1_mem}},
+	// LH rd, rs1_mem
+	{mask: 0x0000707f, value: 0x00001003, op: LH, args: instArgs{arg_rd, arg_rs1_mem}},
+	// LHU rd, rs1_mem
+	{mask: 0x0000707f, value: 0x00005003, op: LHU, args: instArgs{arg_rd, arg_rs1_mem}},
+	// LR.D rd, rs1_amo
+	{mask: 0xfff0707f, value: 0x1000302f, op: LR_D, args: instArgs{arg_rd, arg_rs1_amo}},
+	// LR.D.AQ rd, rs1_amo
+	{mask: 0xfff0707f, value: 0x1400302f, op: LR_D_AQ, args: instArgs{arg_rd, arg_rs1_amo}},
+	// LR.D.AQRL rd, rs1_amo
+	{mask: 0xfff0707f, value: 0x1600302f, op: LR_D_AQRL, args: instArgs{arg_rd, arg_rs1_amo}},
+	// LR.D.RL rd, rs1_amo
+	{mask: 0xfff0707f, value: 0x1200302f, op: LR_D_RL, args: instArgs{arg_rd, arg_rs1_amo}},
+	// LR.W rd, rs1_amo
+	{mask: 0xfff0707f, value: 0x1000202f, op: LR_W, args: instArgs{arg_rd, arg_rs1_amo}},
+	// LR.W.AQ rd, rs1_amo
+	{mask: 0xfff0707f, value: 0x1400202f, op: LR_W_AQ, args: instArgs{arg_rd, arg_rs1_amo}},
+	// LR.W.AQRL rd, rs1_amo
+	{mask: 0xfff0707f, value: 0x1600202f, op: LR_W_AQRL, args: instArgs{arg_rd, arg_rs1_amo}},
+	// LR.W.RL rd, rs1_amo
+	{mask: 0xfff0707f, value: 0x1200202f, op: LR_W_RL, args: instArgs{arg_rd, arg_rs1_amo}},
+	// LUI rd, imm20
+	{mask: 0x0000007f, value: 0x00000037, op: LUI, args: instArgs{arg_rd, arg_imm20}},
+	// LW rd, rs1_mem
+	{mask: 0x0000707f, value: 0x00002003, op: LW, args: instArgs{arg_rd, arg_rs1_mem}},
+	// LWU rd, rs1_mem
+	{mask: 0x0000707f, value: 0x00006003, op: LWU, args: instArgs{arg_rd, arg_rs1_mem}},
+	// MUL rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x02000033, op: MUL, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// MULH rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x02001033, op: MULH, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// MULHSU rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x02002033, op: MULHSU, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// MULHU rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x02003033, op: MULHU, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// MULW rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x0200003b, op: MULW, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// OR rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x00006033, op: OR, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// ORI rd, rs1, imm12
+	{mask: 0x0000707f, value: 0x00006013, op: ORI, args: instArgs{arg_rd, arg_rs1, arg_imm12}},
+	// REM rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x02006033, op: REM, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// REMU rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x02007033, op: REMU, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// REMUW rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x0200703b, op: REMUW, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// REMW rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x0200603b, op: REMW, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// SB rs2, rs1_store
+	{mask: 0x0000707f, value: 0x00000023, op: SB, args: instArgs{arg_rs2, arg_rs1_store}},
+	// SC.D rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x1800302f, op: SC_D, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// SC.D.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x1c00302f, op: SC_D_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// SC.D.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x1e00302f, op: SC_D_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// SC.D.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x1a00302f, op: SC_D_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// SC.W rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x1800202f, op: SC_W, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// SC.W.AQ rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x1c00202f, op: SC_W_AQ, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// SC.W.AQRL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x1e00202f, op: SC_W_AQRL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// SC.W.RL rd, rs2, rs1_amo
+	{mask: 0xfe00707f, value: 0x1a00202f, op: SC_W_RL, args: instArgs{arg_rd, arg_rs2, arg_rs1_amo}},
+	// SD rs2, rs1_store
+	{mask: 0x0000707f, value: 0x00003023, op: SD, args: instArgs{arg_rs2, arg_rs1_store}},
+	// SH rs2, rs1_store
+	{mask: 0x0000707f, value: 0x00001023, op: SH, args: instArgs{arg_rs2, arg_rs1_store}},
+	// SLL rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x00001033, op: SLL, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// SLLI rd, rs1, shamt6
+	{mask: 0xfc00707f, value: 0x00001013, op: SLLI, args: instArgs{arg_rd, arg_rs1, arg_shamt6}},
+	// SLLIW rd, rs1, shamt5
+	{mask: 0xfe00707f, value: 0x0000101b, op: SLLIW, args: instArgs{arg_rd, arg_rs1, arg_shamt5}},
+	// SLLW rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x0000103b, op: SLLW, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// SLT rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x00002033, op: SLT, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// SLTI rd, rs1, imm12
+	{mask: 0x0000707f, value: 0x00002013, op: SLTI, args: instArgs{arg_rd, arg_rs1, arg_imm12}},
+	// SLTIU rd, rs1, imm12
+	{mask: 0x0000707f, value: 0x00003013, op: SLTIU, args: instArgs{arg_rd, arg_rs1, arg_imm12}},
+	// SLTU rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x00003033, op: SLTU, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// SRA rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x40005033, op: SRA, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// SRAI rd, rs1, shamt6
+	{mask: 0xfc00707f, value: 0x40005013, op: SRAI, args: instArgs{arg_rd, arg_rs1, arg_shamt6}},
+	// SRAIW rd, rs1, shamt5
+	{mask: 0xfe00707f, value: 0x4000501b, op: SRAIW, args: instArgs{arg_rd, arg_rs1, arg_shamt5}},
+	// SRAW rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x4000503b, op: SRAW, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// SRL rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x00005033, op: SRL, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// SRLI rd, rs1, shamt6
+	{mask: 0xfc00707f, value: 0x00005013, op: SRLI, args: instArgs{arg_rd, arg_rs1, arg_shamt6}},
+	// SRLIW rd, rs1, shamt5
+	{mask: 0xfe00707f, value: 0x0000501b, op: SRLIW, args: instArgs{arg_rd, arg_rs1, arg_shamt5}},
+	// SRLW rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x0000503b, op: SRLW, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// SUB rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x40000033, op: SUB, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// SUBW rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x4000003b, op: SUBW, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// SW rs2, rs1_store
+	{mask: 0x0000707f, value: 0x00002023, op: SW, args: instArgs{arg_rs2, arg_rs1_store}},
+	// XOR rd, rs1, rs2
+	{mask: 0xfe00707f, value: 0x00004033, op: XOR, args: instArgs{arg_rd, arg_rs1, arg_rs2}},
+	// XORI rd, rs1, imm12
+	{mask: 0x0000707f, value: 0x00004013, op: XORI, args: instArgs{arg_rd, arg_rs1, arg_imm12}},
+}
