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