diff --git a/delve.spec b/delve.spec index 9e3ba0c..1e115ff 100644 --- a/delve.spec +++ b/delve.spec @@ -4,12 +4,13 @@ Name: delve Version: 1.22.0 -Release: 2 +Release: 3 Summary: A debugger for the Go programming language License: MIT URL: https://github.com/go-delve/delve Source0: https://github.com/go-delve/delve/archive/v%{version}/%{name}-%{version}.tar.gz Patch1: support-for-loongarch.patch +Patch2: support-for-riscv.patch BuildRequires: gcc glibc BuildRequires: golang >= 1.16 @@ -26,6 +27,9 @@ delve is a debugger for the Go programming language %ifarch loongarch64 %patch1 -p1 %endif +%ifarch riscv64 +%patch -P2 -p1 +%endif %build %gobuild -o _bin/dlv %{goipath}/cmd/dlv @@ -46,6 +50,9 @@ rm -rf %{buildroot} %doc Documentation/* %changelog +* Thu Aug 01 2024 Lin Runze - 1.22.0-3 +- add riscv64 support + * Sat Jun 8 2024 zhangxianjun - 1.22.0-2 - add loongarch64 support diff --git a/support-for-riscv.patch b/support-for-riscv.patch new file mode 100644 index 0000000..33c451f --- /dev/null +++ b/support-for-riscv.patch @@ -0,0 +1,5971 @@ +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, ®s) }) ++ if err != nil { ++ return nil, err ++ } ++ ++ var tp_tls uint64 ++ if thread.dbp.iscgo { ++ tp_tls = regs.Tp ++ } ++ r := linutil.NewRISCV64Registers(®s, 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}}, ++}