diff --git a/0001-ABI1.0-support-for-ptrace-struct-on-loong64.patch b/0001-ABI1.0-support-for-ptrace-struct-on-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..74ca46da59f3db36778be28b8eb40097184786e0 --- /dev/null +++ b/0001-ABI1.0-support-for-ptrace-struct-on-loong64.patch @@ -0,0 +1,59 @@ +From 3a38a1746759845da8ef30c1cfe6e7492afa453b Mon Sep 17 00:00:00 2001 +From: chenguoqi +Date: Tue, 20 May 2025 19:08:07 +0800 +Subject: [PATCH] ABI1.0: support for ptrace struct on loong64 + +--- + Documentation/backend_test_health.md | 4 ++-- + pkg/proc/linutil/regs_loong64_arch.go | 3 +-- + pkg/proc/native/registers_linux_loong64.go | 3 +-- + 3 files changed, 4 insertions(+), 6 deletions(-) + +diff --git a/Documentation/backend_test_health.md b/Documentation/backend_test_health.md +index d20f75e..4089e1b 100644 +--- a/Documentation/backend_test_health.md ++++ b/Documentation/backend_test_health.md +@@ -36,8 +36,8 @@ Tests skipped by each supported backend: + * linux/riscv64 skipped = 2 + * 1 broken - cgo stacktraces + * 1 not working on linux/riscv64 +-* loong64 skipped = 9 +- * 2 broken ++* loong64 skipped = 8 ++ * 1 broken + * 1 broken - global variable symbolication + * 6 not implemented + * pie skipped = 2 +diff --git a/pkg/proc/linutil/regs_loong64_arch.go b/pkg/proc/linutil/regs_loong64_arch.go +index 9b6d1cb..e31102c 100644 +--- a/pkg/proc/linutil/regs_loong64_arch.go ++++ b/pkg/proc/linutil/regs_loong64_arch.go +@@ -32,10 +32,9 @@ func NewLOONG64Registers(regs *LOONG64PtraceRegs, iscgo bool, tp_tls uint64, + // LoongArch64 CPUs. refer to sys/unix/ztype_linux_loong64.go + type LOONG64PtraceRegs struct { + Regs [32]uint64 +- Orig_a0 uint64 + Era uint64 + Badv uint64 +- Reserved [10]uint64 ++ Reserved [11]uint64 + } + + // Slice returns the registers as a list of (name, value) pairs. +diff --git a/pkg/proc/native/registers_linux_loong64.go b/pkg/proc/native/registers_linux_loong64.go +index c32cb63..268335f 100644 +--- a/pkg/proc/native/registers_linux_loong64.go ++++ b/pkg/proc/native/registers_linux_loong64.go +@@ -18,8 +18,7 @@ import ( + + const ( + // Refer to the definition of struct user_pt_regs in the kernel file ptrace.h +- _LOONG64_GREGS_SIZE = (32 * 8) + 8 + 8 + 8 + (10 * 8) +- ++ _LOONG64_GREGS_SIZE = (32 * 8) + 8 + 8 + (11 * 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 +-- +2.43.5 + diff --git a/0001-all-add-build-mode-vendor-support.patch b/0001-all-add-build-mode-vendor-support.patch deleted file mode 100644 index c393c0cfa0e72cc7d0fc1e229045035b9ccc8961..0000000000000000000000000000000000000000 --- a/0001-all-add-build-mode-vendor-support.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 766094d04fff7c321c9c6249203a887e973d6a7f Mon Sep 17 00:00:00 2001 -From: Huang Qiqi -Date: Wed, 11 Oct 2023 17:01:25 +0800 -Subject: [PATCH 1/7] all: add build mode vendor support. - -Change-Id: Ib71adc6e8a8208cb922371f5d1e00431db26d91b ---- - _scripts/make.go | 5 ++++- - cmd/dlv/dlv_test.go | 4 ++-- - pkg/gobuild/gobuild.go | 2 +- - 3 files changed, 7 insertions(+), 4 deletions(-) - -diff --git a/_scripts/make.go b/_scripts/make.go -index 2a7442f..d70f11f 100644 ---- a/_scripts/make.go -+++ b/_scripts/make.go -@@ -51,7 +51,10 @@ func NewMakeCommands() *cobra.Command { - envflags = append(envflags, "GOOS="+OS) - } - if len(envflags) > 0 { -- executeEnv(envflags, "go", "build", "-ldflags", "-extldflags -static", tagFlags(), buildFlags(), DelveMainPackagePath) -+ envflags = append(envflags, "-mod=vendor") -+ } -+ if len(envflags) > 0 { -+ executeEnv(envflags, "go", "build", "-mod=vendor", "-ldflags", "-extldflags -static", tagFlags(), buildFlags(), DelveMainPackagePath) - } else { - execute("go", "build", "-ldflags", "-extldflags -static", tagFlags(), buildFlags(), DelveMainPackagePath) - } -diff --git a/cmd/dlv/dlv_test.go b/cmd/dlv/dlv_test.go -index c4e903c..3de6635 100644 ---- a/cmd/dlv/dlv_test.go -+++ b/cmd/dlv/dlv_test.go -@@ -224,7 +224,7 @@ func getDlvBinEBPF(t *testing.T) string { - - func getDlvBinInternal(t *testing.T, goflags ...string) string { - dlvbin := filepath.Join(t.TempDir(), "dlv.exe") -- args := append([]string{"build", "-o", dlvbin}, goflags...) -+ args := append([]string{"build", "-mod=vendor", "-o", dlvbin}, goflags...) - args = append(args, "github.com/go-delve/delve/cmd/dlv") - - out, err := exec.Command("go", args...).CombinedOutput() -@@ -382,7 +382,7 @@ func TestGeneratedDoc(t *testing.T) { - - // Checks gen-usage-docs.go - tempDir := t.TempDir() -- cmd := exec.Command("go", "run", "_scripts/gen-usage-docs.go", tempDir) -+ cmd := exec.Command("go", "run", "-mod=vendor", "_scripts/gen-usage-docs.go", tempDir) - cmd.Dir = projectRoot() - err := cmd.Run() - assertNoError(err, t, "go run _scripts/gen-usage-docs.go") -diff --git a/pkg/gobuild/gobuild.go b/pkg/gobuild/gobuild.go -index 9799336..fbd28cc 100644 ---- a/pkg/gobuild/gobuild.go -+++ b/pkg/gobuild/gobuild.go -@@ -80,7 +80,7 @@ func goBuildArgs(debugname string, pkgs []string, buildflags string, isTest bool - - args = append(args, "-o", debugname) - if isTest { -- args = append([]string{"-c"}, args...) -+ args = append([]string{"-c", "-mod=vendor"}, args...) - } - args = append(args, "-gcflags", "all=-N -l") - if buildflags != "" { --- -2.20.1 - diff --git a/0002-all-update-golang.org-x-arch-to-b835ee2a400a6a72a771.patch b/0002-all-update-golang.org-x-arch-to-b835ee2a400a6a72a771.patch deleted file mode 100644 index 6bcd97f801bdf539d71fa7fe8c14f374451902ac..0000000000000000000000000000000000000000 --- a/0002-all-update-golang.org-x-arch-to-b835ee2a400a6a72a771.patch +++ /dev/null @@ -1,2676 +0,0 @@ -From 4079d629728ebf672d6f7fda7d479afe38abf6b5 Mon Sep 17 00:00:00 2001 -From: Huang Qiqi -Date: Wed, 11 Oct 2023 17:12:57 +0800 -Subject: [PATCH 2/7] all: update golang.org/x/arch to - b835ee2a400a6a72a77122d96f778f75944bc30a - -go get -d golang.org/x/arch@b835ee2a400a6a72a77122d96f778f75944bc30a -go mod tidy -go mod vendor - -Change-Id: If277538df57ec39da7bd16e399131da24f2617a1 ---- - .../x/arch/loong64/loong64asm/arg.go | 93 + - .../x/arch/loong64/loong64asm/decode.go | 269 +++ - .../x/arch/loong64/loong64asm/ext_test.go | 402 +++++ - .../x/arch/loong64/loong64asm/gnu.go | 16 + - .../x/arch/loong64/loong64asm/inst.go | 296 ++++ - .../golang.org/x/arch/loong64/loong64asm/log | 14 + - .../x/arch/loong64/loong64asm/tables.go | 1513 +++++++++++++++++ - 7 files changed, 2603 insertions(+) - 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/ext_test.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/log - create mode 100644 vendor/golang.org/x/arch/loong64/loong64asm/tables.go - -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..9496e8c ---- /dev/null -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/arg.go -@@ -0,0 +1,93 @@ -+// Copyright 2022 The Go Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style -+// license that can be found in the LICENSE file. -+ -+package loong64asm -+ -+// Naming for Go decoder arguments: -+// -+// - arg_fd: a Floating Point operand register fd encoded in the fd[4:0] field -+// -+// - arg_fj: a Floating Point operand register fj encoded in the fj[9:5] field -+// -+// - arg_fk: a Floating Point operand register fk encoded in the fk[14:10] field -+// -+// - arg_fa: a Floating Point operand register fa encoded in the fa[19:15] field -+// -+// - arg_rd: a general-purpose register rd encoded in the rd[4:0] field -+// -+// - arg_rj: a general-purpose register rj encoded in the rj[9:5] field -+// -+// - arg_rk: a general-purpose register rk encoded in the rk[14:10] field -+// -+// - arg_fcsr_4_0: float control status register encoded in [4:0] field -+// -+// - arg_cd_2_0: condition flag register encoded in [2:0] field -+// -+// - arg_sa2_16_15: shift bits constant encoded in [16:15] field -+// -+// - arg_code_14_0: arg for exception process routine encoded in [14:0] field -+// -+// - arg_ui5_14_10: 5bits unsigned immediate -+// -+// - arg_lsbw: For details, please refer to chapter 2.2.3.8 of instruction manual -+// -+// - arg_msbw: For details, please refer to chapter 2.2.3.9 of instruction manual -+// -+// - arg_hint_4_0: hint field implied the prefetch type and the data should fetch to cache's level -+// 0: load to data cache level 1 -+// 8: store to data cache level 1 -+// other: no define -+// -+// - arg_si12_21_10: 12bits signed immediate -+ -+type instArg uint16 -+ -+const ( -+ _ instArg = iota -+ //1-5 -+ arg_fd -+ arg_fj -+ arg_fk -+ arg_fa -+ arg_rd -+ //6-10 -+ arg_rj -+ arg_rk -+ arg_op_4_0 -+ arg_fcsr_4_0 -+ arg_fcsr_9_5 -+ //11-15 -+ arg_csr_23_10 -+ arg_cd -+ arg_cj -+ arg_ca -+ arg_sa2_16_15 -+ //16-20 -+ arg_sa3_17_15 -+ arg_code_4_0 -+ arg_code_14_0 -+ arg_ui5_14_10 -+ arg_ui6_15_10 -+ //21-25 -+ arg_ui12_21_10 -+ arg_lsbw -+ arg_msbw -+ arg_lsbd -+ arg_msbd -+ //26-30 -+ arg_hint_4_0 -+ arg_hint_14_0 -+ arg_level_14_0 -+ arg_level_17_10 -+ arg_seq_17_10 -+ //31-35 -+ arg_si12_21_10 -+ arg_si14_23_10 -+ arg_si16_25_10 -+ arg_si20_24_5 -+ arg_offset_20_0 -+ //36~ -+ arg_offset_25_0 -+ arg_offset_15_0 -+) -diff --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..ac3448f ---- /dev/null -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/decode.go -@@ -0,0 +1,269 @@ -+// Copyright 2022 The Go Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style -+// license that can be found in the LICENSE file. -+ -+package loong64asm -+ -+import ( -+ "encoding/binary" -+ "fmt" -+) -+ -+type instArgs [5]instArg -+ -+// An instFormat describes the format of an instruction encoding. -+type instFormat struct { -+ mask uint32 -+ value uint32 -+ op Op -+ // args describe how to decode the instruction arguments. -+ // args is stored as a fixed-size array. -+ // if there are fewer than len(args) arguments, args[i] == 0 marks -+ // the end of the argument list. -+ args instArgs -+} -+ -+var ( -+ errShort = fmt.Errorf("truncated instruction") -+ errUnknown = fmt.Errorf("unknown instruction") -+) -+ -+var decoderCover []bool -+ -+func init() { -+ decoderCover = make([]bool, len(instFormats)) -+} -+ -+// Decode decodes the 4 bytes in src as a single instruction. -+func Decode(src []byte) (inst Inst, err error) { -+ if len(src) < 4 { -+ return Inst{}, errShort -+ } -+ -+ x := binary.LittleEndian.Uint32(src) -+ -+Search: -+ for i := range instFormats { -+ f := &instFormats[i] -+ -+ if (x & f.mask) != f.value { -+ continue -+ } -+ -+ // Decode args. -+ var args Args -+ for j, aop := range f.args { -+ if aop == 0 { -+ break -+ } -+ -+ arg := decodeArg(aop, x, i) -+ if arg == nil { -+ // Cannot decode argument -+ continue Search -+ } -+ -+ args[j] = arg -+ } -+ -+ decoderCover[i] = true -+ inst = Inst{ -+ Op: f.op, -+ Args: args, -+ Enc: x, -+ } -+ return inst, nil -+ } -+ -+ return Inst{}, errUnknown -+} -+ -+// decodeArg decodes the arg described by aop from the instruction bits x. -+// It returns nil if x cannot be decoded according to aop. -+func decodeArg(aop instArg, x uint32, index int) Arg { -+ switch aop { -+ case arg_fd: -+ return F0 + Reg(x&((1<<5)-1)) -+ -+ case arg_fj: -+ return F0 + Reg((x>>5)&((1<<5)-1)) -+ -+ case arg_fk: -+ return F0 + Reg((x>>10)&((1<<5)-1)) -+ -+ case arg_fa: -+ return F0 + Reg((x>>15)&((1<<5)-1)) -+ -+ case arg_rd: -+ return R0 + Reg(x&((1<<5)-1)) -+ -+ case arg_rj: -+ return R0 + Reg((x>>5)&((1<<5)-1)) -+ -+ case arg_rk: -+ return R0 + Reg((x>>10)&((1<<5)-1)) -+ -+ case arg_fcsr_4_0: -+ return FCSR0 + Fcsr(x&((1<<5)-1)) -+ -+ case arg_fcsr_9_5: -+ return FCSR0 + Fcsr((x>>5)&((1<<5)-1)) -+ -+ case arg_cd: -+ return FCC0 + Fcc(x&((1<<3)-1)) -+ -+ case arg_cj: -+ return FCC0 + Fcc((x>>5)&((1<<3)-1)) -+ -+ case arg_ca: -+ return FCC0 + Fcc((x>>15)&((1<<3)-1)) -+ -+ case arg_op_4_0: -+ tmp := x & ((1 << 5) - 1) -+ return Uimm{tmp, false} -+ -+ case arg_csr_23_10: -+ tmp := (x >> 10) & ((1 << 14) - 1) -+ return Uimm{tmp, false} -+ -+ case arg_sa2_16_15: -+ f := &instFormats[index] -+ tmp := SaSimm((x >> 15) & ((1 << 2) - 1)) -+ if (f.op == ALSL_D) || (f.op == ALSL_W) || (f.op == ALSL_WU) { -+ return tmp + 1 -+ } else { -+ return tmp + 0 -+ } -+ -+ case arg_sa3_17_15: -+ return SaSimm((x >> 15) & ((1 << 3) - 1)) -+ -+ case arg_code_4_0: -+ return CodeSimm(x & ((1 << 5) - 1)) -+ -+ case arg_code_14_0: -+ return CodeSimm(x & ((1 << 15) - 1)) -+ -+ case arg_ui5_14_10: -+ tmp := (x >> 10) & ((1 << 5) - 1) -+ return Uimm{tmp, false} -+ -+ case arg_ui6_15_10: -+ tmp := (x >> 10) & ((1 << 6) - 1) -+ return Uimm{tmp, false} -+ -+ case arg_ui12_21_10: -+ tmp := ((x >> 10) & ((1 << 12) - 1) & 0xfff) -+ return Uimm{tmp, false} -+ -+ case arg_lsbw: -+ tmp := (x >> 10) & ((1 << 5) - 1) -+ return Uimm{tmp, false} -+ -+ case arg_msbw: -+ tmp := (x >> 16) & ((1 << 5) - 1) -+ return Uimm{tmp, false} -+ -+ case arg_lsbd: -+ tmp := (x >> 10) & ((1 << 6) - 1) -+ return Uimm{tmp, false} -+ -+ case arg_msbd: -+ tmp := (x >> 16) & ((1 << 6) - 1) -+ return Uimm{tmp, false} -+ -+ case arg_hint_4_0: -+ tmp := int16(x & ((1 << 5) - 1)) -+ return Simm16{tmp, 4} -+ -+ case arg_hint_14_0: -+ tmp := int16(x & ((1 << 15) - 1)) -+ return Simm16{tmp, 15} -+ -+ case arg_level_14_0: -+ tmp := x & ((1 << 15) - 1) -+ return Uimm{tmp, false} -+ -+ case arg_level_17_10: -+ tmp := (x >> 10) & ((1 << 8) - 1) -+ return Uimm{tmp, false} -+ -+ case arg_seq_17_10: -+ tmp := (x >> 10) & ((1 << 8) - 1) -+ return Uimm{tmp, false} -+ -+ case arg_si12_21_10: -+ var tmp int16 -+ -+ //no int12, so sign-extend a 12-bit signed to 16-bit signed -+ if (x & 0x200000) == 0x200000 { -+ tmp = int16(((x >> 10) & ((1 << 12) - 1)) | 0xf000) -+ } else { -+ tmp = int16(((x >> 10) & ((1 << 12) - 1)) | 0x0000) -+ } -+ return Simm16{tmp, 12} -+ -+ case arg_si14_23_10: -+ var tmp int32 -+ if (x & 0x800000) == 0x800000 { -+ tmp = int32((((x >> 10) & ((1 << 14) - 1)) << 2) | 0xffff0000) -+ } else { -+ tmp = int32((((x >> 10) & ((1 << 14) - 1)) << 2) | 0x00000000) -+ } -+ return Simm32{tmp, 16} -+ -+ case arg_si16_25_10: -+ var tmp int32 -+ -+ if (x & 0x2000000) == 0x2000000 { -+ tmp = int32(((x >> 10) & ((1 << 16) - 1)) | 0xffff0000) -+ } else { -+ tmp = int32(((x >> 10) & ((1 << 16) - 1)) | 0x00000000) -+ } -+ -+ return Simm32{tmp, 16} -+ -+ case arg_si20_24_5: -+ var tmp int32 -+ if (x & 0x1000000) == 0x1000000 { -+ tmp = int32(((x >> 5) & ((1 << 20) - 1)) | 0xfff00000) -+ } else { -+ tmp = int32(((x >> 5) & ((1 << 20) - 1)) | 0x00000000) -+ } -+ return Simm32{tmp, 20} -+ -+ case arg_offset_20_0: -+ var tmp int32 -+ -+ if (x & 0x1000000) == 0x1000000 { -+ tmp = int32((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 21) - 1)) << 2) -+ } else { -+ tmp = int32((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 21) - 1)) << 2) -+ } -+ -+ return OffsetSimm{tmp, 28} -+ -+ case arg_offset_15_0: -+ var tmp int32 -+ if (x & 0x2000000) == 0x2000000 { -+ tmp = int32((((x >> 10) & ((1 << 16) - 1)) << 2) | 0xfffc0000) -+ } else { -+ tmp = int32((((x >> 10) & ((1 << 16) - 1)) << 2) | 0x00000000) -+ } -+ -+ return OffsetSimm{tmp, 18} -+ -+ case arg_offset_25_0: -+ var tmp int32 -+ -+ if (x & 0x200) == 0x200 { -+ tmp = int32(((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 26) - 1)) << 2) | 0xf0000000) -+ } else { -+ tmp = int32(((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 26) - 1)) << 2) | 0x00000000) -+ } -+ -+ return OffsetSimm{tmp, 28} -+ default: -+ return nil -+ } -+} -diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/ext_test.go b/vendor/golang.org/x/arch/loong64/loong64asm/ext_test.go -new file mode 100644 -index 0000000..c79552c ---- /dev/null -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/ext_test.go -@@ -0,0 +1,402 @@ -+// Copyright 2022 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. -+ -+// Support for testing against external disassembler program. -+ -+package loong64asm -+ -+import ( -+ "bufio" -+ "bytes" -+ "encoding/hex" -+ "flag" -+ "fmt" -+ "io" -+ "io/ioutil" -+ "log" -+ "math/rand" -+ "os" -+ "os/exec" -+ "path/filepath" -+ "strings" -+ "testing" -+ "time" -+) -+ -+var ( -+ dumpTest = flag.Bool("dump", false, "dump all encodings") -+ mismatch = flag.Bool("mismatch", false, "log allowed mismatches") -+ keep = flag.Bool("keep", false, "keep object files around") -+ debug = false -+) -+ -+// An ExtInst represents a single decoded instruction parsed -+// from an external disassembler's output. -+type ExtInst struct { -+ addr uint64 -+ enc [4]byte -+ nenc int -+ text string -+} -+ -+func (r ExtInst) String() string { -+ return fmt.Sprintf("%#x: % x: %s", r.addr, r.enc, r.text) -+} -+ -+// An ExtDis is a connection between an external disassembler and a test. -+type ExtDis struct { -+ Dec chan ExtInst -+ File *os.File -+ Size int -+ Cmd *exec.Cmd -+} -+ -+// Run runs the given command - the external disassembler - and returns -+// a buffered reader of its standard output. -+func (ext *ExtDis) Run(cmd ...string) (*bufio.Reader, error) { -+ if *keep { -+ log.Printf("%s\n", strings.Join(cmd, " ")) -+ } -+ ext.Cmd = exec.Command(cmd[0], cmd[1:]...) -+ out, err := ext.Cmd.StdoutPipe() -+ if err != nil { -+ return nil, fmt.Errorf("stdoutpipe: %v", err) -+ } -+ if err := ext.Cmd.Start(); err != nil { -+ return nil, fmt.Errorf("exec: %v", err) -+ } -+ -+ b := bufio.NewReaderSize(out, 1<<20) -+ return b, nil -+} -+ -+// Wait waits for the command started with Run to exit. -+func (ext *ExtDis) Wait() error { -+ return ext.Cmd.Wait() -+} -+ -+// testExtDis tests a set of byte sequences against an external disassembler. -+// The disassembler is expected to produce the given syntax and run -+// in the given architecture mode (16, 32, or 64-bit). -+// The extdis function must start the external disassembler -+// and then parse its output, sending the parsed instructions on ext.Dec. -+// The generate function calls its argument f once for each byte sequence -+// to be tested. The generate function itself will be called twice, and it must -+// make the same sequence of calls to f each time. -+// When a disassembly does not match the internal decoding, -+// allowedMismatch determines whether this mismatch should be -+// allowed, or else considered an error. -+func testExtDis( -+ t *testing.T, -+ syntax string, -+ extdis func(ext *ExtDis) error, -+ generate func(f func([]byte)), -+ allowedMismatch func(text string, inst *Inst, dec ExtInst) bool, -+) { -+ start := time.Now() -+ ext := &ExtDis{ -+ Dec: make(chan ExtInst), -+ } -+ errc := make(chan error) -+ -+ // First pass: write instructions to input file for external disassembler. -+ file, f, size, err := writeInst(generate) -+ if err != nil { -+ t.Fatal(err) -+ } -+ ext.Size = size -+ ext.File = f -+ defer func() { -+ f.Close() -+ if !*keep { -+ os.Remove(file) -+ } -+ }() -+ -+ // Second pass: compare disassembly against our decodings. -+ var ( -+ totalTests = 0 -+ totalSkips = 0 -+ totalErrors = 0 -+ -+ errors = make([]string, 0, 100) // Sampled errors, at most cap -+ ) -+ go func() { -+ errc <- extdis(ext) -+ }() -+ -+ generate(func(enc []byte) { -+ dec, ok := <-ext.Dec -+ if !ok { -+ t.Errorf("decoding stream ended early") -+ return -+ } -+ inst, text := disasm(syntax, pad(enc)) -+ -+ totalTests++ -+ if *dumpTest { -+ fmt.Printf("%x -> %s [%d]\n", enc[:len(enc)], dec.text, dec.nenc) -+ } -+ -+ if text != dec.text && !strings.Contains(dec.text, "unknown") && syntax == "gnu" { -+ suffix := "" -+ if allowedMismatch(text, &inst, dec) { -+ totalSkips++ -+ if !*mismatch { -+ return -+ } -+ suffix += " (allowed mismatch)" -+ } -+ totalErrors++ -+ cmp := fmt.Sprintf("decode(%x) = %q, %d, want %q, %d%s\n", enc, text, len(enc), dec.text, dec.nenc, suffix) -+ -+ if len(errors) >= cap(errors) { -+ j := rand.Intn(totalErrors) -+ if j >= cap(errors) { -+ return -+ } -+ errors = append(errors[:j], errors[j+1:]...) -+ } -+ errors = append(errors, cmp) -+ } -+ }) -+ -+ if *mismatch { -+ totalErrors -= totalSkips -+ } -+ -+ fmt.Printf("totalTest: %d total skip: %d total error: %d\n", totalTests, totalSkips, totalErrors) -+ // Here are some errors about mismatches(44) -+ // for _, b := range errors { -+ // t.Log(b) -+ // } -+ -+ if totalErrors > 0 { -+ t.Fail() -+ } -+ t.Logf("%d test cases, %d expected mismatches, %d failures; %.0f cases/second", totalTests, totalSkips, totalErrors, float64(totalTests)/time.Since(start).Seconds()) -+ t.Logf("decoder coverage: %.1f%%;\n", decodeCoverage()) -+} -+ -+// Start address of text. -+const start = 0x8000 -+ -+// writeInst writes the generated byte sequences to a new file -+// starting at offset start. That file is intended to be the input to -+// the external disassembler. -+func writeInst(generate func(func([]byte))) (file string, f *os.File, size int, err error) { -+ f, err = ioutil.TempFile("", "loong64asm") -+ if err != nil { -+ return -+ } -+ -+ file = f.Name() -+ -+ f.Seek(start, io.SeekStart) -+ w := bufio.NewWriter(f) -+ defer w.Flush() -+ size = 0 -+ generate(func(x []byte) { -+ if debug { -+ fmt.Printf("%#x: %x%x\n", start+size, x, zeros[len(x):]) -+ } -+ w.Write(x) -+ w.Write(zeros[len(x):]) -+ size += len(zeros) -+ }) -+ return file, f, size, nil -+} -+ -+var zeros = []byte{0, 0, 0, 0} -+ -+// pad pads the code sequence with pops. -+func pad(enc []byte) []byte { -+ if len(enc) < 4 { -+ enc = append(enc[:len(enc):len(enc)], zeros[:4-len(enc)]...) -+ } -+ return enc -+} -+ -+// disasm returns the decoded instruction and text -+// for the given source bytes, using the given syntax and mode. -+func disasm(syntax string, src []byte) (inst Inst, text string) { -+ var err error -+ inst, err = Decode(src) -+ if err != nil { -+ text = "error: " + err.Error() -+ return -+ } -+ text = inst.String() -+ switch syntax { -+ case "gnu": -+ text = GNUSyntax(inst) -+ default: -+ text = "error: unknown syntax " + syntax -+ } -+ return -+} -+ -+// decodecoverage returns a floating point number denoting the -+// decoder coverage. -+func decodeCoverage() float64 { -+ n := 0 -+ for _, t := range decoderCover { -+ if t { -+ n++ -+ } -+ } -+ return 100 * float64(1+n) / float64(1+len(decoderCover)) -+} -+ -+// Helpers for writing disassembler output parsers. -+ -+// isHex reports whether b is a hexadecimal character (0-9a-fA-F). -+func isHex(b byte) bool { -+ return ('0' <= b && b <= '9') || ('a' <= b && b <= 'f') || ('A' <= b && b <= 'F') -+} -+ -+// parseHex parses the hexadecimal byte dump in hex, -+// appending the parsed bytes to raw and returning the updated slice. -+// The returned bool reports whether any invalid hex was found. -+// Spaces and tabs between bytes are okay but any other non-hex is not. -+func parseHex(hex []byte, raw []byte) ([]byte, bool) { -+ hex = bytes.TrimSpace(hex) -+ for j := 0; j < len(hex); { -+ for hex[j] == ' ' || hex[j] == '\t' { -+ j++ -+ } -+ if j >= len(hex) { -+ break -+ } -+ if j+2 > len(hex) || !isHex(hex[j]) || !isHex(hex[j+1]) { -+ return nil, false -+ } -+ raw = append(raw, unhex(hex[j])<<4|unhex(hex[j+1])) -+ j += 2 -+ } -+ return raw, true -+} -+ -+func unhex(b byte) byte { -+ if '0' <= b && b <= '9' { -+ return b - '0' -+ } else if 'A' <= b && b <= 'F' { -+ return b - 'A' + 10 -+ } else if 'a' <= b && b <= 'f' { -+ return b - 'a' + 10 -+ } -+ return 0 -+} -+ -+// index is like bytes.Index(s, []byte(t)) but avoids the allocation. -+func index(s []byte, t string) int { -+ i := 0 -+ for { -+ j := bytes.IndexByte(s[i:], t[0]) -+ if j < 0 { -+ return -1 -+ } -+ i = i + j -+ if i+len(t) > len(s) { -+ return -1 -+ } -+ for k := 1; k < len(t); k++ { -+ if s[i+k] != t[k] { -+ goto nomatch -+ } -+ } -+ return i -+ nomatch: -+ i++ -+ } -+} -+ -+// fixSpace rewrites runs of spaces, tabs, and newline characters into single spaces in s. -+// If s must be rewritten, it is rewritten in place. -+func fixSpace(s []byte) []byte { -+ s = bytes.TrimSpace(s) -+ for i := 0; i < len(s); i++ { -+ if s[i] == '\t' || s[i] == '\n' || i > 0 && s[i] == ' ' && s[i-1] == ' ' { -+ goto Fix -+ } -+ } -+ return s -+ -+Fix: -+ b := s -+ w := 0 -+ for i := 0; i < len(s); i++ { -+ c := s[i] -+ if c == '\t' || c == '\n' { -+ c = ' ' -+ } -+ if c == ' ' && w > 0 && b[w-1] == ' ' { -+ continue -+ } -+ b[w] = c -+ w++ -+ } -+ if w > 0 && b[w-1] == ' ' { -+ w-- -+ } -+ return b[:w] -+} -+ -+// Generators. -+// -+// The test cases are described as functions that invoke a callback repeatedly, -+// with a new input sequence each time. These helpers make writing those -+// a little easier. -+ -+// hexCases generates the cases written in hexadecimal in the encoded string. -+// Spaces in 'encoded' separate entire test cases, not individual bytes. -+func hexCases(t *testing.T, encoded string) func(func([]byte)) { -+ return func(try func([]byte)) { -+ for _, x := range strings.Fields(encoded) { -+ src, err := hex.DecodeString(x) -+ if err != nil { -+ t.Errorf("parsing %q: %v", x, err) -+ } -+ try(src) -+ } -+ } -+} -+ -+// testdataCases generates the test cases recorded in testdata/cases.txt. -+// It only uses the inputs; it ignores the answers recorded in that file. -+func testdataCases(t *testing.T, syntax string) func(func([]byte)) { -+ var codes [][]byte -+ input := filepath.Join("testdata", syntax+"cases.txt") -+ data, err := ioutil.ReadFile(input) -+ if err != nil { -+ t.Fatal(err) -+ } -+ for _, line := range strings.Split(string(data), "\n") { -+ line = strings.TrimSpace(line) -+ if line == "" || strings.HasPrefix(line, "#") { -+ continue -+ } -+ f := strings.Fields(line)[0] -+ i := strings.Index(f, "|") -+ if i < 0 { -+ t.Errorf("parsing %q: missing | separator", f) -+ continue -+ } -+ if i%2 != 0 { -+ t.Errorf("parsing %q: misaligned | separator", f) -+ } -+ code, err := hex.DecodeString(f[:i] + f[i+1:]) -+ if err != nil { -+ t.Errorf("parsing %q: %v", f, err) -+ continue -+ } -+ codes = append(codes, code) -+ } -+ -+ return func(try func([]byte)) { -+ for _, code := range codes { -+ try(code) -+ } -+ } -+} -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..fd6bcff ---- /dev/null -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go -@@ -0,0 +1,16 @@ -+// Copyright 2022 The Go Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style -+// license that can be found in the LICENSE file. -+ -+package loong64asm -+ -+import ( -+ "strings" -+) -+ -+// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils. -+// This form typically matches the syntax defined in the Loong64 Reference Manual. See -+// https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html -+func GNUSyntax(inst Inst) string { -+ return strings.ToLower(inst.String()) -+} -diff --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..187a46f ---- /dev/null -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/inst.go -@@ -0,0 +1,296 @@ -+// Copyright 2022 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" -+ "strconv" -+ "strings" -+ "unsafe" -+) -+ -+// 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 { -+ String() string -+} -+ -+// A Reg is a single register. -+// The zero value denotes R0, not the absence of a register. -+type Reg uint16 -+ -+const ( -+ //_ Reg = iota -+ -+ // General-purpose register -+ R0 Reg = iota -+ R1 -+ R2 -+ R3 -+ R4 -+ R5 -+ R6 -+ R7 -+ R8 -+ R9 -+ R10 -+ R11 -+ R12 -+ R13 -+ R14 -+ R15 -+ R16 -+ R17 -+ R18 -+ R19 -+ R20 -+ R21 -+ R22 -+ R23 -+ R24 -+ R25 -+ R26 -+ R27 -+ R28 -+ R29 -+ R30 -+ R31 -+ -+ // Float point register -+ F0 -+ F1 -+ F2 -+ F3 -+ F4 -+ F5 -+ F6 -+ F7 -+ F8 -+ F9 -+ F10 -+ F11 -+ F12 -+ F13 -+ F14 -+ F15 -+ F16 -+ F17 -+ F18 -+ F19 -+ F20 -+ F21 -+ F22 -+ F23 -+ F24 -+ F25 -+ F26 -+ F27 -+ F28 -+ F29 -+ F30 -+ F31 -+) -+ -+func (r Reg) String() string { -+ switch { -+ case r == R0: -+ return "$zero" -+ -+ case r == R1: -+ return "$ra" -+ -+ case r == R2: -+ return "$tp" -+ -+ case r == R3: -+ return "$sp" -+ -+ case (r >= R4) && (r <= R11): -+ return fmt.Sprintf("$a%d", int(r-R4)) -+ -+ case (r >= R12) && (r <= R20): -+ return fmt.Sprintf("$t%d", int(r-R12)) -+ -+ case r == R21: -+ return "$r21" -+ -+ case r == R22: -+ return "$fp" -+ -+ case (r >= R23) && (r <= R31): -+ return fmt.Sprintf("$s%d", int(r-R23)) -+ -+ case (r >= F0) && (r <= F7): -+ return fmt.Sprintf("$fa%d", int(r-F0)) -+ -+ case (r >= F8) && (r <= F23): -+ return fmt.Sprintf("$ft%d", int(r-F8)) -+ -+ case (r >= F24) && (r <= F31): -+ return fmt.Sprintf("$fs%d", int(r-F24)) -+ -+ default: -+ return fmt.Sprintf("Unknown(%d)", int(r)) -+ } -+} -+ -+// float control status register -+type Fcsr uint8 -+ -+const ( -+ //_ Fcsr = iota -+ FCSR0 Fcsr = iota -+ FCSR1 -+ FCSR2 -+ FCSR3 -+) -+ -+func (f Fcsr) String() string { -+ switch f { -+ case FCSR0: -+ return fmt.Sprintf("$zero") -+ case FCSR1, FCSR2, FCSR3: -+ return fmt.Sprintf("$r%d", uint8(f)) -+ } -+ -+ return fmt.Sprintf("$unknow%d", uint8(f)) -+} -+ -+// float condition flags register -+type Fcc uint8 -+ -+const ( -+ //_ Fcc = iota -+ FCC0 Fcc = iota -+ FCC1 -+ FCC2 -+ FCC3 -+ FCC4 -+ FCC5 -+ FCC6 -+ FCC7 -+) -+ -+func (f Fcc) String() string { -+ return fmt.Sprintf("$fcc%d", uint8(f)) -+} -+ -+// An Imm is an integer constant. -+type Uimm struct { -+ Imm uint32 -+ Decimal bool -+} -+ -+func (i Uimm) String() string { -+ if i.Decimal == true { -+ return fmt.Sprintf("%d", i.Imm) -+ } else { -+ return fmt.Sprintf("%#x", i.Imm) -+ } -+} -+ -+type Simm16 struct { -+ Imm int16 -+ Width uint8 -+} -+ -+func (si Simm16) String() string { -+ if si.Imm == 0 { -+ return fmt.Sprintf("%#x", int(si.Imm)) -+ } else { -+ hex := int16(si.Imm & ((1 << si.Width) - 1)) -+ str := strconv.FormatUint(uint64(*(*int16)(unsafe.Pointer(&hex))), 16) -+ return fmt.Sprintf("%d(0x%s)", int16(si.Imm), str) -+ } -+} -+ -+type Simm32 struct { -+ Imm int32 -+ Width uint8 -+} -+ -+func (si Simm32) String() string { -+ if si.Imm == 0 { -+ return fmt.Sprintf("%#x", int(si.Imm)) -+ } else { -+ hex := int32(si.Imm & ((1 << si.Width) - 1)) -+ str := strconv.FormatUint(uint64(*(*int32)(unsafe.Pointer(&hex))), 16) -+ return fmt.Sprintf("%d(0x%s)", int32(si.Imm), str) -+ } -+} -+ -+type OffsetSimm struct { -+ Imm int32 -+ Width uint8 -+} -+ -+func (o OffsetSimm) String() string { -+ if o.Imm == 0 { -+ return fmt.Sprintf("%#x", int(o.Imm)) -+ } else { -+ hex := int32(o.Imm & ((1 << o.Width) - 1)) -+ str := strconv.FormatUint(uint64(*(*int32)(unsafe.Pointer(&hex))), 16) -+ return fmt.Sprintf("%d(0x%s)", int32(o.Imm), str) -+ } -+} -+ -+type SaSimm int16 -+ -+func (s SaSimm) String() string { -+ return fmt.Sprintf("%#x", int(s)) -+} -+ -+type CodeSimm int16 -+ -+func (c CodeSimm) String() string { -+ return fmt.Sprintf("%#x", int(c)) -+} -diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/log b/vendor/golang.org/x/arch/loong64/loong64asm/log -new file mode 100644 -index 0000000..85bb80f ---- /dev/null -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/log -@@ -0,0 +1,14 @@ -+=== RUN TestObjdumpLoong64TestDecodeGNUSyntaxdata -+totalTest: 388 total skip: 0 total error: 0 -+ ext_test.go:178: 388 test cases, 0 expected mismatches, 0 failures; 51516 cases/second -+ ext_test.go:179: decoder coverage: 100.0%; -+--- PASS: TestObjdumpLoong64TestDecodeGNUSyntaxdata (0.01s) -+PASS -+ok golang.org/x/arch/loong64/loong64asm 0.014s -+=== RUN TestObjdumpLoong64Manual -+totalTest: 32 total skip: 0 total error: 0 -+ ext_test.go:178: 32 test cases, 0 expected mismatches, 0 failures; 7703 cases/second -+ ext_test.go:179: decoder coverage: 8.8%; -+--- PASS: TestObjdumpLoong64Manual (0.01s) -+PASS -+ok golang.org/x/arch/loong64/loong64asm 0.011s -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..f90e929 ---- /dev/null -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/tables.go -@@ -0,0 +1,1513 @@ -+// Generated by Loong64 internal tool -+// DO NOT EDIT -+// Copyright 2022 The Go Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style -+// license that can be found in the LICENSE file. -+ -+package loong64asm -+ -+const ( -+ _ Op = iota -+ ADDI_D -+ ADDI_W -+ ADDU16I_D -+ ADD_D -+ ADD_W -+ ALSL_D -+ ALSL_W -+ ALSL_WU -+ AMADD_D -+ AMADD_DB_D -+ AMADD_DB_W -+ AMADD_W -+ AMAND_D -+ AMAND_DB_D -+ AMAND_DB_W -+ AMAND_W -+ AMMAX_D -+ AMMAX_DB_D -+ AMMAX_DB_DU -+ AMMAX_DB_W -+ AMMAX_DB_WU -+ AMMAX_DU -+ AMMAX_W -+ AMMAX_WU -+ AMMIN_D -+ AMMIN_DB_D -+ AMMIN_DB_DU -+ AMMIN_DB_W -+ AMMIN_DB_WU -+ AMMIN_DU -+ AMMIN_W -+ AMMIN_WU -+ AMOR_D -+ AMOR_DB_D -+ AMOR_DB_W -+ AMOR_W -+ AMSWAP_D -+ AMSWAP_DB_D -+ AMSWAP_DB_W -+ AMSWAP_W -+ AMXOR_D -+ AMXOR_DB_D -+ AMXOR_DB_W -+ AMXOR_W -+ AND -+ ANDI -+ ANDN -+ ASRTGT_D -+ ASRTLE_D -+ B -+ BCEQZ -+ BCNEZ -+ BEQ -+ BEQZ -+ BGE -+ BGEU -+ BITREV_4B -+ BITREV_8B -+ BITREV_D -+ BITREV_W -+ BL -+ BLT -+ BLTU -+ BNE -+ BNEZ -+ BREAK -+ BSTRINS_D -+ BSTRINS_W -+ BSTRPICK_D -+ BSTRPICK_W -+ BYTEPICK_D -+ BYTEPICK_W -+ CACOP -+ CLO_D -+ CLO_W -+ CLZ_D -+ CLZ_W -+ CPUCFG -+ CRCC_W_B_W -+ CRCC_W_D_W -+ CRCC_W_H_W -+ CRCC_W_W_W -+ CRC_W_B_W -+ CRC_W_D_W -+ CRC_W_H_W -+ CRC_W_W_W -+ CSRRD -+ CSRWR -+ CSRXCHG -+ CTO_D -+ CTO_W -+ CTZ_D -+ CTZ_W -+ DBAR -+ DBCL -+ DIV_D -+ DIV_DU -+ DIV_W -+ DIV_WU -+ ERTN -+ EXT_W_B -+ EXT_W_H -+ FABS_D -+ FABS_S -+ FADD_D -+ FADD_S -+ FCLASS_D -+ FCLASS_S -+ FCMP_CAF_D -+ FCMP_CAF_S -+ FCMP_CEQ_D -+ FCMP_CEQ_S -+ FCMP_CLE_D -+ FCMP_CLE_S -+ FCMP_CLT_D -+ FCMP_CLT_S -+ FCMP_CNE_D -+ FCMP_CNE_S -+ FCMP_COR_D -+ FCMP_COR_S -+ FCMP_CUEQ_D -+ FCMP_CUEQ_S -+ FCMP_CULE_D -+ FCMP_CULE_S -+ FCMP_CULT_D -+ FCMP_CULT_S -+ FCMP_CUNE_D -+ FCMP_CUNE_S -+ FCMP_CUN_D -+ FCMP_CUN_S -+ FCMP_SAF_D -+ FCMP_SAF_S -+ FCMP_SEQ_D -+ FCMP_SEQ_S -+ FCMP_SLE_D -+ FCMP_SLE_S -+ FCMP_SLT_D -+ FCMP_SLT_S -+ FCMP_SNE_D -+ FCMP_SNE_S -+ FCMP_SOR_D -+ FCMP_SOR_S -+ FCMP_SUEQ_D -+ FCMP_SUEQ_S -+ FCMP_SULE_D -+ FCMP_SULE_S -+ FCMP_SULT_D -+ FCMP_SULT_S -+ FCMP_SUNE_D -+ FCMP_SUNE_S -+ FCMP_SUN_D -+ FCMP_SUN_S -+ FCOPYSIGN_D -+ FCOPYSIGN_S -+ FCVT_D_S -+ FCVT_S_D -+ FDIV_D -+ FDIV_S -+ FFINT_D_L -+ FFINT_D_W -+ FFINT_S_L -+ FFINT_S_W -+ FLDGT_D -+ FLDGT_S -+ FLDLE_D -+ FLDLE_S -+ FLDX_D -+ FLDX_S -+ FLD_D -+ FLD_S -+ FLOGB_D -+ FLOGB_S -+ FMADD_D -+ FMADD_S -+ FMAXA_D -+ FMAXA_S -+ FMAX_D -+ FMAX_S -+ FMINA_D -+ FMINA_S -+ FMIN_D -+ FMIN_S -+ FMOV_D -+ FMOV_S -+ FMSUB_D -+ FMSUB_S -+ FMUL_D -+ FMUL_S -+ FNEG_D -+ FNEG_S -+ FNMADD_D -+ FNMADD_S -+ FNMSUB_D -+ FNMSUB_S -+ FRECIP_D -+ FRECIP_S -+ FRINT_D -+ FRINT_S -+ FRSQRT_D -+ FRSQRT_S -+ FSCALEB_D -+ FSCALEB_S -+ FSEL -+ FSQRT_D -+ FSQRT_S -+ FSTGT_D -+ FSTGT_S -+ FSTLE_D -+ FSTLE_S -+ FSTX_D -+ FSTX_S -+ FST_D -+ FST_S -+ FSUB_D -+ FSUB_S -+ FTINTRM_L_D -+ FTINTRM_L_S -+ FTINTRM_W_D -+ FTINTRM_W_S -+ FTINTRNE_L_D -+ FTINTRNE_L_S -+ FTINTRNE_W_D -+ FTINTRNE_W_S -+ FTINTRP_L_D -+ FTINTRP_L_S -+ FTINTRP_W_D -+ FTINTRP_W_S -+ FTINTRZ_L_D -+ FTINTRZ_L_S -+ FTINTRZ_W_D -+ FTINTRZ_W_S -+ FTINT_L_D -+ FTINT_L_S -+ FTINT_W_D -+ FTINT_W_S -+ IBAR -+ IDLE -+ INVTLB -+ IOCSRRD_B -+ IOCSRRD_D -+ IOCSRRD_H -+ IOCSRRD_W -+ IOCSRWR_B -+ IOCSRWR_D -+ IOCSRWR_H -+ IOCSRWR_W -+ JIRL -+ LDDIR -+ LDGT_B -+ LDGT_D -+ LDGT_H -+ LDGT_W -+ LDLE_B -+ LDLE_D -+ LDLE_H -+ LDLE_W -+ LDPTE -+ LDPTR_D -+ LDPTR_W -+ LDX_B -+ LDX_BU -+ LDX_D -+ LDX_H -+ LDX_HU -+ LDX_W -+ LDX_WU -+ LD_B -+ LD_BU -+ LD_D -+ LD_H -+ LD_HU -+ LD_W -+ LD_WU -+ LL_D -+ LL_W -+ LU12I_W -+ LU32I_D -+ LU52I_D -+ MASKEQZ -+ MASKNEZ -+ MOD_D -+ MOD_DU -+ MOD_W -+ MOD_WU -+ MOVCF2FR -+ MOVCF2GR -+ MOVFCSR2GR -+ MOVFR2CF -+ MOVFR2GR_D -+ MOVFR2GR_S -+ MOVFRH2GR_S -+ MOVGR2CF -+ MOVGR2FCSR -+ MOVGR2FRH_W -+ MOVGR2FR_D -+ MOVGR2FR_W -+ MULH_D -+ MULH_DU -+ MULH_W -+ MULH_WU -+ MULW_D_W -+ MULW_D_WU -+ MUL_D -+ MUL_W -+ NOR -+ OR -+ ORI -+ ORN -+ PCADDI -+ PCADDU12I -+ PCADDU18I -+ PCALAU12I -+ PRELD -+ PRELDX -+ RDTIMEH_W -+ RDTIMEL_W -+ RDTIME_D -+ REVB_2H -+ REVB_2W -+ REVB_4H -+ REVB_D -+ REVH_2W -+ REVH_D -+ ROTRI_D -+ ROTRI_W -+ ROTR_D -+ ROTR_W -+ SC_D -+ SC_W -+ SLLI_D -+ SLLI_W -+ SLL_D -+ SLL_W -+ SLT -+ SLTI -+ SLTU -+ SLTUI -+ SRAI_D -+ SRAI_W -+ SRA_D -+ SRA_W -+ SRLI_D -+ SRLI_W -+ SRL_D -+ SRL_W -+ STGT_B -+ STGT_D -+ STGT_H -+ STGT_W -+ STLE_B -+ STLE_D -+ STLE_H -+ STLE_W -+ STPTR_D -+ STPTR_W -+ STX_B -+ STX_D -+ STX_H -+ STX_W -+ ST_B -+ ST_D -+ ST_H -+ ST_W -+ SUB_D -+ SUB_W -+ SYSCALL -+ TLBCLR -+ TLBFILL -+ TLBFLUSH -+ TLBRD -+ TLBSRCH -+ TLBWR -+ XOR -+ XORI -+) -+ -+var opstr = [...]string{ -+ ADDI_D: "ADDI.D", -+ ADDI_W: "ADDI.W", -+ ADDU16I_D: "ADDU16I.D", -+ ADD_D: "ADD.D", -+ ADD_W: "ADD.W", -+ ALSL_D: "ALSL.D", -+ ALSL_W: "ALSL.W", -+ ALSL_WU: "ALSL.WU", -+ AMADD_D: "AMADD.D", -+ AMADD_DB_D: "AMADD_DB.D", -+ AMADD_DB_W: "AMADD_DB.W", -+ AMADD_W: "AMADD.W", -+ AMAND_D: "AMAND.D", -+ AMAND_DB_D: "AMAND_DB.D", -+ AMAND_DB_W: "AMAND_DB.W", -+ AMAND_W: "AMAND.W", -+ AMMAX_D: "AMMAX.D", -+ AMMAX_DB_D: "AMMAX_DB.D", -+ AMMAX_DB_DU: "AMMAX_DB.DU", -+ AMMAX_DB_W: "AMMAX_DB.W", -+ AMMAX_DB_WU: "AMMAX_DB.WU", -+ AMMAX_DU: "AMMAX.DU", -+ AMMAX_W: "AMMAX.W", -+ AMMAX_WU: "AMMAX.WU", -+ AMMIN_D: "AMMIN.D", -+ AMMIN_DB_D: "AMMIN_DB.D", -+ AMMIN_DB_DU: "AMMIN_DB.DU", -+ AMMIN_DB_W: "AMMIN_DB.W", -+ AMMIN_DB_WU: "AMMIN_DB.WU", -+ AMMIN_DU: "AMMIN.DU", -+ AMMIN_W: "AMMIN.W", -+ AMMIN_WU: "AMMIN.WU", -+ AMOR_D: "AMOR.D", -+ AMOR_DB_D: "AMOR_DB.D", -+ AMOR_DB_W: "AMOR_DB.W", -+ AMOR_W: "AMOR.W", -+ AMSWAP_D: "AMSWAP.D", -+ AMSWAP_DB_D: "AMSWAP_DB.D", -+ AMSWAP_DB_W: "AMSWAP_DB.W", -+ AMSWAP_W: "AMSWAP.W", -+ AMXOR_D: "AMXOR.D", -+ AMXOR_DB_D: "AMXOR_DB.D", -+ AMXOR_DB_W: "AMXOR_DB.W", -+ AMXOR_W: "AMXOR.W", -+ AND: "AND", -+ ANDI: "ANDI", -+ ANDN: "ANDN", -+ ASRTGT_D: "ASRTGT.D", -+ ASRTLE_D: "ASRTLE.D", -+ B: "B", -+ BCEQZ: "BCEQZ", -+ BCNEZ: "BCNEZ", -+ BEQ: "BEQ", -+ BEQZ: "BEQZ", -+ BGE: "BGE", -+ BGEU: "BGEU", -+ BITREV_4B: "BITREV.4B", -+ BITREV_8B: "BITREV.8B", -+ BITREV_D: "BITREV.D", -+ BITREV_W: "BITREV.W", -+ BL: "BL", -+ BLT: "BLT", -+ BLTU: "BLTU", -+ BNE: "BNE", -+ BNEZ: "BNEZ", -+ BREAK: "BREAK", -+ BSTRINS_D: "BSTRINS.D", -+ BSTRINS_W: "BSTRINS.W", -+ BSTRPICK_D: "BSTRPICK.D", -+ BSTRPICK_W: "BSTRPICK.W", -+ BYTEPICK_D: "BYTEPICK.D", -+ BYTEPICK_W: "BYTEPICK.W", -+ CACOP: "CACOP", -+ CLO_D: "CLO.D", -+ CLO_W: "CLO.W", -+ CLZ_D: "CLZ.D", -+ CLZ_W: "CLZ.W", -+ CPUCFG: "CPUCFG", -+ CRCC_W_B_W: "CRCC.W.B.W", -+ CRCC_W_D_W: "CRCC.W.D.W", -+ CRCC_W_H_W: "CRCC.W.H.W", -+ CRCC_W_W_W: "CRCC.W.W.W", -+ CRC_W_B_W: "CRC.W.B.W", -+ CRC_W_D_W: "CRC.W.D.W", -+ CRC_W_H_W: "CRC.W.H.W", -+ CRC_W_W_W: "CRC.W.W.W", -+ CSRRD: "CSRRD", -+ CSRWR: "CSRWR", -+ CSRXCHG: "CSRXCHG", -+ CTO_D: "CTO.D", -+ CTO_W: "CTO.W", -+ CTZ_D: "CTZ.D", -+ CTZ_W: "CTZ.W", -+ DBAR: "DBAR", -+ DBCL: "DBCL", -+ DIV_D: "DIV.D", -+ DIV_DU: "DIV.DU", -+ DIV_W: "DIV.W", -+ DIV_WU: "DIV.WU", -+ ERTN: "ERTN", -+ EXT_W_B: "EXT.W.B", -+ EXT_W_H: "EXT.W.H", -+ FABS_D: "FABS.D", -+ FABS_S: "FABS.S", -+ FADD_D: "FADD.D", -+ FADD_S: "FADD.S", -+ FCLASS_D: "FCLASS.D", -+ FCLASS_S: "FCLASS.S", -+ FCMP_CAF_D: "FCMP.CAF.D", -+ FCMP_CAF_S: "FCMP.CAF.S", -+ FCMP_CEQ_D: "FCMP.CEQ.D", -+ FCMP_CEQ_S: "FCMP.CEQ.S", -+ FCMP_CLE_D: "FCMP.CLE.D", -+ FCMP_CLE_S: "FCMP.CLE.S", -+ FCMP_CLT_D: "FCMP.CLT.D", -+ FCMP_CLT_S: "FCMP.CLT.S", -+ FCMP_CNE_D: "FCMP.CNE.D", -+ FCMP_CNE_S: "FCMP.CNE.S", -+ FCMP_COR_D: "FCMP.COR.D", -+ FCMP_COR_S: "FCMP.COR.S", -+ FCMP_CUEQ_D: "FCMP.CUEQ.D", -+ FCMP_CUEQ_S: "FCMP.CUEQ.S", -+ FCMP_CULE_D: "FCMP.CULE.D", -+ FCMP_CULE_S: "FCMP.CULE.S", -+ FCMP_CULT_D: "FCMP.CULT.D", -+ FCMP_CULT_S: "FCMP.CULT.S", -+ FCMP_CUNE_D: "FCMP.CUNE.D", -+ FCMP_CUNE_S: "FCMP.CUNE.S", -+ FCMP_CUN_D: "FCMP.CUN.D", -+ FCMP_CUN_S: "FCMP.CUN.S", -+ FCMP_SAF_D: "FCMP.SAF.D", -+ FCMP_SAF_S: "FCMP.SAF.S", -+ FCMP_SEQ_D: "FCMP.SEQ.D", -+ FCMP_SEQ_S: "FCMP.SEQ.S", -+ FCMP_SLE_D: "FCMP.SLE.D", -+ FCMP_SLE_S: "FCMP.SLE.S", -+ FCMP_SLT_D: "FCMP.SLT.D", -+ FCMP_SLT_S: "FCMP.SLT.S", -+ FCMP_SNE_D: "FCMP.SNE.D", -+ FCMP_SNE_S: "FCMP.SNE.S", -+ FCMP_SOR_D: "FCMP.SOR.D", -+ FCMP_SOR_S: "FCMP.SOR.S", -+ FCMP_SUEQ_D: "FCMP.SUEQ.D", -+ FCMP_SUEQ_S: "FCMP.SUEQ.S", -+ FCMP_SULE_D: "FCMP.SULE.D", -+ FCMP_SULE_S: "FCMP.SULE.S", -+ FCMP_SULT_D: "FCMP.SULT.D", -+ FCMP_SULT_S: "FCMP.SULT.S", -+ FCMP_SUNE_D: "FCMP.SUNE.D", -+ FCMP_SUNE_S: "FCMP.SUNE.S", -+ FCMP_SUN_D: "FCMP.SUN.D", -+ FCMP_SUN_S: "FCMP.SUN.S", -+ FCOPYSIGN_D: "FCOPYSIGN.D", -+ FCOPYSIGN_S: "FCOPYSIGN.S", -+ FCVT_D_S: "FCVT.D.S", -+ FCVT_S_D: "FCVT.S.D", -+ FDIV_D: "FDIV.D", -+ FDIV_S: "FDIV.S", -+ FFINT_D_L: "FFINT.D.L", -+ FFINT_D_W: "FFINT.D.W", -+ FFINT_S_L: "FFINT.S.L", -+ FFINT_S_W: "FFINT.S.W", -+ FLDGT_D: "FLDGT.D", -+ FLDGT_S: "FLDGT.S", -+ FLDLE_D: "FLDLE.D", -+ FLDLE_S: "FLDLE.S", -+ FLDX_D: "FLDX.D", -+ FLDX_S: "FLDX.S", -+ FLD_D: "FLD.D", -+ FLD_S: "FLD.S", -+ FLOGB_D: "FLOGB.D", -+ FLOGB_S: "FLOGB.S", -+ FMADD_D: "FMADD.D", -+ FMADD_S: "FMADD.S", -+ FMAXA_D: "FMAXA.D", -+ FMAXA_S: "FMAXA.S", -+ FMAX_D: "FMAX.D", -+ FMAX_S: "FMAX.S", -+ FMINA_D: "FMINA.D", -+ FMINA_S: "FMINA.S", -+ FMIN_D: "FMIN.D", -+ FMIN_S: "FMIN.S", -+ FMOV_D: "FMOV.D", -+ FMOV_S: "FMOV.S", -+ FMSUB_D: "FMSUB.D", -+ FMSUB_S: "FMSUB.S", -+ FMUL_D: "FMUL.D", -+ FMUL_S: "FMUL.S", -+ FNEG_D: "FNEG.D", -+ FNEG_S: "FNEG.S", -+ FNMADD_D: "FNMADD.D", -+ FNMADD_S: "FNMADD.S", -+ FNMSUB_D: "FNMSUB.D", -+ FNMSUB_S: "FNMSUB.S", -+ FRECIP_D: "FRECIP.D", -+ FRECIP_S: "FRECIP.S", -+ FRINT_D: "FRINT.D", -+ FRINT_S: "FRINT.S", -+ FRSQRT_D: "FRSQRT.D", -+ FRSQRT_S: "FRSQRT.S", -+ FSCALEB_D: "FSCALEB.D", -+ FSCALEB_S: "FSCALEB.S", -+ FSEL: "FSEL", -+ FSQRT_D: "FSQRT.D", -+ FSQRT_S: "FSQRT.S", -+ FSTGT_D: "FSTGT.D", -+ FSTGT_S: "FSTGT.S", -+ FSTLE_D: "FSTLE.D", -+ FSTLE_S: "FSTLE.S", -+ FSTX_D: "FSTX.D", -+ FSTX_S: "FSTX.S", -+ FST_D: "FST.D", -+ FST_S: "FST.S", -+ FSUB_D: "FSUB.D", -+ FSUB_S: "FSUB.S", -+ FTINTRM_L_D: "FTINTRM.L.D", -+ FTINTRM_L_S: "FTINTRM.L.S", -+ FTINTRM_W_D: "FTINTRM.W.D", -+ FTINTRM_W_S: "FTINTRM.W.S", -+ FTINTRNE_L_D: "FTINTRNE.L.D", -+ FTINTRNE_L_S: "FTINTRNE.L.S", -+ FTINTRNE_W_D: "FTINTRNE.W.D", -+ FTINTRNE_W_S: "FTINTRNE.W.S", -+ FTINTRP_L_D: "FTINTRP.L.D", -+ FTINTRP_L_S: "FTINTRP.L.S", -+ FTINTRP_W_D: "FTINTRP.W.D", -+ FTINTRP_W_S: "FTINTRP.W.S", -+ FTINTRZ_L_D: "FTINTRZ.L.D", -+ FTINTRZ_L_S: "FTINTRZ.L.S", -+ FTINTRZ_W_D: "FTINTRZ.W.D", -+ FTINTRZ_W_S: "FTINTRZ.W.S", -+ FTINT_L_D: "FTINT.L.D", -+ FTINT_L_S: "FTINT.L.S", -+ FTINT_W_D: "FTINT.W.D", -+ FTINT_W_S: "FTINT.W.S", -+ IBAR: "IBAR", -+ IDLE: "IDLE", -+ INVTLB: "INVTLB", -+ IOCSRRD_B: "IOCSRRD.B", -+ IOCSRRD_D: "IOCSRRD.D", -+ IOCSRRD_H: "IOCSRRD.H", -+ IOCSRRD_W: "IOCSRRD.W", -+ IOCSRWR_B: "IOCSRWR.B", -+ IOCSRWR_D: "IOCSRWR.D", -+ IOCSRWR_H: "IOCSRWR.H", -+ IOCSRWR_W: "IOCSRWR.W", -+ JIRL: "JIRL", -+ LDDIR: "LDDIR", -+ LDGT_B: "LDGT.B", -+ LDGT_D: "LDGT.D", -+ LDGT_H: "LDGT.H", -+ LDGT_W: "LDGT.W", -+ LDLE_B: "LDLE.B", -+ LDLE_D: "LDLE.D", -+ LDLE_H: "LDLE.H", -+ LDLE_W: "LDLE.W", -+ LDPTE: "LDPTE", -+ LDPTR_D: "LDPTR.D", -+ LDPTR_W: "LDPTR.W", -+ LDX_B: "LDX.B", -+ LDX_BU: "LDX.BU", -+ LDX_D: "LDX.D", -+ LDX_H: "LDX.H", -+ LDX_HU: "LDX.HU", -+ LDX_W: "LDX.W", -+ LDX_WU: "LDX.WU", -+ LD_B: "LD.B", -+ LD_BU: "LD.BU", -+ LD_D: "LD.D", -+ LD_H: "LD.H", -+ LD_HU: "LD.HU", -+ LD_W: "LD.W", -+ LD_WU: "LD.WU", -+ LL_D: "LL.D", -+ LL_W: "LL.W", -+ LU12I_W: "LU12I.W", -+ LU32I_D: "LU32I.D", -+ LU52I_D: "LU52I.D", -+ MASKEQZ: "MASKEQZ", -+ MASKNEZ: "MASKNEZ", -+ MOD_D: "MOD.D", -+ MOD_DU: "MOD.DU", -+ MOD_W: "MOD.W", -+ MOD_WU: "MOD.WU", -+ MOVCF2FR: "MOVCF2FR", -+ MOVCF2GR: "MOVCF2GR", -+ MOVFCSR2GR: "MOVFCSR2GR", -+ MOVFR2CF: "MOVFR2CF", -+ MOVFR2GR_D: "MOVFR2GR.D", -+ MOVFR2GR_S: "MOVFR2GR.S", -+ MOVFRH2GR_S: "MOVFRH2GR.S", -+ MOVGR2CF: "MOVGR2CF", -+ MOVGR2FCSR: "MOVGR2FCSR", -+ MOVGR2FRH_W: "MOVGR2FRH.W", -+ MOVGR2FR_D: "MOVGR2FR.D", -+ MOVGR2FR_W: "MOVGR2FR.W", -+ MULH_D: "MULH.D", -+ MULH_DU: "MULH.DU", -+ MULH_W: "MULH.W", -+ MULH_WU: "MULH.WU", -+ MULW_D_W: "MULW.D.W", -+ MULW_D_WU: "MULW.D.WU", -+ MUL_D: "MUL.D", -+ MUL_W: "MUL.W", -+ NOR: "NOR", -+ OR: "OR", -+ ORI: "ORI", -+ ORN: "ORN", -+ PCADDI: "PCADDI", -+ PCADDU12I: "PCADDU12I", -+ PCADDU18I: "PCADDU18I", -+ PCALAU12I: "PCALAU12I", -+ PRELD: "PRELD", -+ PRELDX: "PRELDX", -+ RDTIMEH_W: "RDTIMEH.W", -+ RDTIMEL_W: "RDTIMEL.W", -+ RDTIME_D: "RDTIME.D", -+ REVB_2H: "REVB.2H", -+ REVB_2W: "REVB.2W", -+ REVB_4H: "REVB.4H", -+ REVB_D: "REVB.D", -+ REVH_2W: "REVH.2W", -+ REVH_D: "REVH.D", -+ ROTRI_D: "ROTRI.D", -+ ROTRI_W: "ROTRI.W", -+ ROTR_D: "ROTR.D", -+ ROTR_W: "ROTR.W", -+ SC_D: "SC.D", -+ SC_W: "SC.W", -+ SLLI_D: "SLLI.D", -+ SLLI_W: "SLLI.W", -+ SLL_D: "SLL.D", -+ SLL_W: "SLL.W", -+ SLT: "SLT", -+ SLTI: "SLTI", -+ SLTU: "SLTU", -+ SLTUI: "SLTUI", -+ SRAI_D: "SRAI.D", -+ SRAI_W: "SRAI.W", -+ SRA_D: "SRA.D", -+ SRA_W: "SRA.W", -+ SRLI_D: "SRLI.D", -+ SRLI_W: "SRLI.W", -+ SRL_D: "SRL.D", -+ SRL_W: "SRL.W", -+ STGT_B: "STGT.B", -+ STGT_D: "STGT.D", -+ STGT_H: "STGT.H", -+ STGT_W: "STGT.W", -+ STLE_B: "STLE.B", -+ STLE_D: "STLE.D", -+ STLE_H: "STLE.H", -+ STLE_W: "STLE.W", -+ STPTR_D: "STPTR.D", -+ STPTR_W: "STPTR.W", -+ STX_B: "STX.B", -+ STX_D: "STX.D", -+ STX_H: "STX.H", -+ STX_W: "STX.W", -+ ST_B: "ST.B", -+ ST_D: "ST.D", -+ ST_H: "ST.H", -+ ST_W: "ST.W", -+ SUB_D: "SUB.D", -+ SUB_W: "SUB.W", -+ SYSCALL: "SYSCALL", -+ TLBCLR: "TLBCLR", -+ TLBFILL: "TLBFILL", -+ TLBFLUSH: "TLBFLUSH", -+ TLBRD: "TLBRD", -+ TLBSRCH: "TLBSRCH", -+ TLBWR: "TLBWR", -+ XOR: "XOR", -+ XORI: "XORI", -+} -+ -+var instFormats = [...]instFormat{ -+ // ADDI.D rd, rj, si12 -+ {mask: 0xffc00000, value: 0x02c00000, op: ADDI_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // ADDI.W rd, rj, si12 -+ {mask: 0xffc00000, value: 0x02800000, op: ADDI_W, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // ADDU16I.D rd, rj, si16 -+ {mask: 0xfc000000, value: 0x10000000, op: ADDU16I_D, args: instArgs{arg_rd, arg_rj, arg_si16_25_10}}, -+ // ADD.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x00108000, op: ADD_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // ADD.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00100000, op: ADD_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // ALSL.D rd, rj, rk, sa2 -+ {mask: 0xfffe0000, value: 0x002c0000, op: ALSL_D, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}}, -+ // ALSL.W rd, rj, rk, sa2 -+ {mask: 0xfffe0000, value: 0x00040000, op: ALSL_W, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}}, -+ // ALSL.WU rd, rj, rk, sa2 -+ {mask: 0xfffe0000, value: 0x00060000, op: ALSL_WU, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}}, -+ // AMADD.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x38618000, op: AMADD_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMADD_DB.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x386a8000, op: AMADD_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMADD_DB.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x386a0000, op: AMADD_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMADD.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x38610000, op: AMADD_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMAND.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x38628000, op: AMAND_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMAND_DB.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x386b8000, op: AMAND_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMAND_DB.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x386b0000, op: AMAND_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMAND.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x38620000, op: AMAND_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMAX.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x38658000, op: AMMAX_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMAX_DB.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x386e8000, op: AMMAX_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMAX_DB.DU rd, rk, rj -+ {mask: 0xffff8000, value: 0x38708000, op: AMMAX_DB_DU, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMAX_DB.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x386e0000, op: AMMAX_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMAX_DB.WU rd, rk, rj -+ {mask: 0xffff8000, value: 0x38700000, op: AMMAX_DB_WU, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMAX.DU rd, rk, rj -+ {mask: 0xffff8000, value: 0x38678000, op: AMMAX_DU, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMAX.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x38650000, op: AMMAX_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMAX.WU rd, rk, rj -+ {mask: 0xffff8000, value: 0x38670000, op: AMMAX_WU, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMIN.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x38668000, op: AMMIN_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMIN_DB.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x386f8000, op: AMMIN_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMIN_DB.DU rd, rk, rj -+ {mask: 0xffff8000, value: 0x38718000, op: AMMIN_DB_DU, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMIN_DB.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x386f0000, op: AMMIN_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMIN_DB.WU rd, rk, rj -+ {mask: 0xffff8000, value: 0x38710000, op: AMMIN_DB_WU, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMIN.DU rd, rk, rj -+ {mask: 0xffff8000, value: 0x38688000, op: AMMIN_DU, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMIN.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x38660000, op: AMMIN_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMMIN.WU rd, rk, rj -+ {mask: 0xffff8000, value: 0x38680000, op: AMMIN_WU, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMOR.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x38638000, op: AMOR_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMOR_DB.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x386c8000, op: AMOR_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMOR_DB.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x386c0000, op: AMOR_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMOR.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x38630000, op: AMOR_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMSWAP.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x38608000, op: AMSWAP_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMSWAP_DB.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x38698000, op: AMSWAP_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMSWAP_DB.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x38690000, op: AMSWAP_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMSWAP.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x38600000, op: AMSWAP_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMXOR.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x38648000, op: AMXOR_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMXOR_DB.D rd, rk, rj -+ {mask: 0xffff8000, value: 0x386d8000, op: AMXOR_DB_D, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMXOR_DB.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x386d0000, op: AMXOR_DB_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AMXOR.W rd, rk, rj -+ {mask: 0xffff8000, value: 0x38640000, op: AMXOR_W, args: instArgs{arg_rd, arg_rk, arg_rj}}, -+ // AND rd, rj, rk -+ {mask: 0xffff8000, value: 0x00148000, op: AND, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // ANDI rd, rj, ui12 -+ {mask: 0xffc00000, value: 0x03400000, op: ANDI, args: instArgs{arg_rd, arg_rj, arg_ui12_21_10}}, -+ // ANDN rd, rj, rk -+ {mask: 0xffff8000, value: 0x00168000, op: ANDN, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // ASRTGT.D rj, rk -+ {mask: 0xffff801f, value: 0x00018000, op: ASRTGT_D, args: instArgs{arg_rj, arg_rk}}, -+ // ASRTLE.D rj, rk -+ {mask: 0xffff801f, value: 0x00010000, op: ASRTLE_D, args: instArgs{arg_rj, arg_rk}}, -+ // B offs -+ {mask: 0xfc000000, value: 0x50000000, op: B, args: instArgs{arg_offset_25_0}}, -+ // BCEQZ cj, offs -+ {mask: 0xfc000300, value: 0x48000000, op: BCEQZ, args: instArgs{arg_cj, arg_offset_20_0}}, -+ // BCNEZ cj, offs -+ {mask: 0xfc000300, value: 0x48000100, op: BCNEZ, args: instArgs{arg_cj, arg_offset_20_0}}, -+ // BEQ rj, rd, offs -+ {mask: 0xfc000000, value: 0x58000000, op: BEQ, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}}, -+ // BEQZ rj, offs -+ {mask: 0xfc000000, value: 0x40000000, op: BEQZ, args: instArgs{arg_rj, arg_offset_20_0}}, -+ // BGE rj, rd, offs -+ {mask: 0xfc000000, value: 0x64000000, op: BGE, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}}, -+ // BGEU rj, rd, offs -+ {mask: 0xfc000000, value: 0x6c000000, op: BGEU, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}}, -+ // BITREV.4B rd, rj -+ {mask: 0xfffffc00, value: 0x00004800, op: BITREV_4B, args: instArgs{arg_rd, arg_rj}}, -+ // BITREV.8B rd, rj -+ {mask: 0xfffffc00, value: 0x00004c00, op: BITREV_8B, args: instArgs{arg_rd, arg_rj}}, -+ // BITREV.D rd, rj -+ {mask: 0xfffffc00, value: 0x00005400, op: BITREV_D, args: instArgs{arg_rd, arg_rj}}, -+ // BITREV.W rd, rj -+ {mask: 0xfffffc00, value: 0x00005000, op: BITREV_W, args: instArgs{arg_rd, arg_rj}}, -+ // BL offs -+ {mask: 0xfc000000, value: 0x54000000, op: BL, args: instArgs{arg_offset_25_0}}, -+ // BLT rj, rd, offs -+ {mask: 0xfc000000, value: 0x60000000, op: BLT, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}}, -+ // BLTU rj, rd, offs -+ {mask: 0xfc000000, value: 0x68000000, op: BLTU, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}}, -+ // BNE rj, rd, offs -+ {mask: 0xfc000000, value: 0x5c000000, op: BNE, args: instArgs{arg_rj, arg_rd, arg_offset_15_0}}, -+ // BNEZ rj, offs -+ {mask: 0xfc000000, value: 0x44000000, op: BNEZ, args: instArgs{arg_rj, arg_offset_20_0}}, -+ // BREAK code -+ {mask: 0xffff8000, value: 0x002a0000, op: BREAK, args: instArgs{arg_code_14_0}}, -+ // BSTRINS.D rd, rj, msbd, lsbd -+ {mask: 0xffc00000, value: 0x00800000, op: BSTRINS_D, args: instArgs{arg_rd, arg_rj, arg_msbd, arg_lsbd}}, -+ // BSTRINS.W rd, rj, msbw, lsbw -+ {mask: 0xffe08000, value: 0x00600000, op: BSTRINS_W, args: instArgs{arg_rd, arg_rj, arg_msbw, arg_lsbw}}, -+ // BSTRPICK.D rd, rj, msbd, lsbd -+ {mask: 0xffc00000, value: 0x00c00000, op: BSTRPICK_D, args: instArgs{arg_rd, arg_rj, arg_msbd, arg_lsbd}}, -+ // BSTRPICK.W rd, rj, msbw, lsbw -+ {mask: 0xffe08000, value: 0x00608000, op: BSTRPICK_W, args: instArgs{arg_rd, arg_rj, arg_msbw, arg_lsbw}}, -+ // BYTEPICK.D rd, rj, rk, sa3 -+ {mask: 0xfffc0000, value: 0x000c0000, op: BYTEPICK_D, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa3_17_15}}, -+ // BYTEPICK.W rd, rj, rk, sa2 -+ {mask: 0xfffe0000, value: 0x00080000, op: BYTEPICK_W, args: instArgs{arg_rd, arg_rj, arg_rk, arg_sa2_16_15}}, -+ // CACOP code, rj, si12 -+ {mask: 0xffc00000, value: 0x06000000, op: CACOP, args: instArgs{arg_code_4_0, arg_rj, arg_si12_21_10}}, -+ // CLO.D rd, rj -+ {mask: 0xfffffc00, value: 0x00002000, op: CLO_D, args: instArgs{arg_rd, arg_rj}}, -+ // CLO.W rd, rj -+ {mask: 0xfffffc00, value: 0x00001000, op: CLO_W, args: instArgs{arg_rd, arg_rj}}, -+ // CLZ.D rd, rj -+ {mask: 0xfffffc00, value: 0x00002400, op: CLZ_D, args: instArgs{arg_rd, arg_rj}}, -+ // CLZ.W rd, rj -+ {mask: 0xfffffc00, value: 0x00001400, op: CLZ_W, args: instArgs{arg_rd, arg_rj}}, -+ // CPUCFG rd, rj -+ {mask: 0xfffffc00, value: 0x00006c00, op: CPUCFG, args: instArgs{arg_rd, arg_rj}}, -+ // CRCC.W.B.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00260000, op: CRCC_W_B_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // CRCC.W.D.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00278000, op: CRCC_W_D_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // CRCC.W.H.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00268000, op: CRCC_W_H_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // CRCC.W.W.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00270000, op: CRCC_W_W_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // CRC.W.B.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00240000, op: CRC_W_B_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // CRC.W.D.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00258000, op: CRC_W_D_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // CRC.W.H.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00248000, op: CRC_W_H_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // CRC.W.W.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00250000, op: CRC_W_W_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // CSRRD rd, csr -+ {mask: 0xff0003e0, value: 0x04000000, op: CSRRD, args: instArgs{arg_rd, arg_csr_23_10}}, -+ // CSRWR rd, csr -+ {mask: 0xff0003e0, value: 0x04000020, op: CSRWR, args: instArgs{arg_rd, arg_csr_23_10}}, -+ // CSRXCHG rd, rj, csr -+ {mask: 0xff000000, value: 0x04000000, op: CSRXCHG, args: instArgs{arg_rd, arg_rj, arg_csr_23_10}}, -+ // CTO.D rd, rj -+ {mask: 0xfffffc00, value: 0x00002800, op: CTO_D, args: instArgs{arg_rd, arg_rj}}, -+ // CTO.W rd, rj -+ {mask: 0xfffffc00, value: 0x00001800, op: CTO_W, args: instArgs{arg_rd, arg_rj}}, -+ // CTZ.D rd, rj -+ {mask: 0xfffffc00, value: 0x00002c00, op: CTZ_D, args: instArgs{arg_rd, arg_rj}}, -+ // CTZ.W rd, rj -+ {mask: 0xfffffc00, value: 0x00001c00, op: CTZ_W, args: instArgs{arg_rd, arg_rj}}, -+ // DBAR hint -+ {mask: 0xffff8000, value: 0x38720000, op: DBAR, args: instArgs{arg_hint_14_0}}, -+ // DBCL code -+ {mask: 0xffff8000, value: 0x002a8000, op: DBCL, args: instArgs{arg_code_14_0}}, -+ // DIV.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x00220000, op: DIV_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // DIV.DU rd, rj, rk -+ {mask: 0xffff8000, value: 0x00230000, op: DIV_DU, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // DIV.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00200000, op: DIV_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // DIV.WU rd, rj, rk -+ {mask: 0xffff8000, value: 0x00210000, op: DIV_WU, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // ERTN -+ {mask: 0xffffffff, value: 0x06483800, op: ERTN, args: instArgs{}}, -+ // EXT.W.B rd, rj -+ {mask: 0xfffffc00, value: 0x00005c00, op: EXT_W_B, args: instArgs{arg_rd, arg_rj}}, -+ // EXT.W.H rd, rj -+ {mask: 0xfffffc00, value: 0x00005800, op: EXT_W_H, args: instArgs{arg_rd, arg_rj}}, -+ // FABS.D fd, fj -+ {mask: 0xfffffc00, value: 0x01140800, op: FABS_D, args: instArgs{arg_fd, arg_fj}}, -+ // FABS.S fd, fj -+ {mask: 0xfffffc00, value: 0x01140400, op: FABS_S, args: instArgs{arg_fd, arg_fj}}, -+ // FADD.D fd, fj, fk -+ {mask: 0xffff8000, value: 0x01010000, op: FADD_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FADD.S fd, fj, fk -+ {mask: 0xffff8000, value: 0x01008000, op: FADD_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FCLASS.D fd, fj -+ {mask: 0xfffffc00, value: 0x01143800, op: FCLASS_D, args: instArgs{arg_fd, arg_fj}}, -+ // FCLASS.S fd, fj -+ {mask: 0xfffffc00, value: 0x01143400, op: FCLASS_S, args: instArgs{arg_fd, arg_fj}}, -+ // FCMP.CAF.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c200000, op: FCMP_CAF_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CAF.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c100000, op: FCMP_CAF_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CEQ.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c220000, op: FCMP_CEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CEQ.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c120000, op: FCMP_CEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CLE.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c230000, op: FCMP_CLE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CLE.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c130000, op: FCMP_CLE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CLT.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c210000, op: FCMP_CLT_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CLT.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c110000, op: FCMP_CLT_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CNE.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c280000, op: FCMP_CNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CNE.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c180000, op: FCMP_CNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.COR.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c2a0000, op: FCMP_COR_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.COR.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c1a0000, op: FCMP_COR_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CUEQ.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c260000, op: FCMP_CUEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CUEQ.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c160000, op: FCMP_CUEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CULE.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c270000, op: FCMP_CULE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CULE.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c170000, op: FCMP_CULE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CULT.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c250000, op: FCMP_CULT_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CULT.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c150000, op: FCMP_CULT_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CUNE.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c2c0000, op: FCMP_CUNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CUNE.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c1c0000, op: FCMP_CUNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CUN.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c240000, op: FCMP_CUN_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.CUN.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c140000, op: FCMP_CUN_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SAF.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c208000, op: FCMP_SAF_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SAF.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c108000, op: FCMP_SAF_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SEQ.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c228000, op: FCMP_SEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SEQ.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c128000, op: FCMP_SEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SLE.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c238000, op: FCMP_SLE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SLE.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c138000, op: FCMP_SLE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SLT.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c218000, op: FCMP_SLT_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SLT.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c118000, op: FCMP_SLT_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SNE.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c288000, op: FCMP_SNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SNE.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c188000, op: FCMP_SNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SOR.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c2a8000, op: FCMP_SOR_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SOR.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c1a8000, op: FCMP_SOR_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SUEQ.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c268000, op: FCMP_SUEQ_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SUEQ.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c168000, op: FCMP_SUEQ_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SULE.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c278000, op: FCMP_SULE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SULE.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c178000, op: FCMP_SULE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SULT.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c258000, op: FCMP_SULT_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SULT.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c158000, op: FCMP_SULT_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SUNE.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c2c8000, op: FCMP_SUNE_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SUNE.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c1c8000, op: FCMP_SUNE_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SUN.D cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c248000, op: FCMP_SUN_D, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCMP.SUN.S cd, fj, fk -+ {mask: 0xffff8018, value: 0x0c148000, op: FCMP_SUN_S, args: instArgs{arg_cd, arg_fj, arg_fk}}, -+ // FCOPYSIGN.D fd, fj, fk -+ {mask: 0xffff8000, value: 0x01130000, op: FCOPYSIGN_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FCOPYSIGN.S fd, fj, fk -+ {mask: 0xffff8000, value: 0x01128000, op: FCOPYSIGN_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FCVT.D.S fd, fj -+ {mask: 0xfffffc00, value: 0x01192400, op: FCVT_D_S, args: instArgs{arg_fd, arg_fj}}, -+ // FCVT.S.D fd, fj -+ {mask: 0xfffffc00, value: 0x01191800, op: FCVT_S_D, args: instArgs{arg_fd, arg_fj}}, -+ // FDIV.D fd, fj, fk -+ {mask: 0xffff8000, value: 0x01070000, op: FDIV_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FDIV.S fd, fj, fk -+ {mask: 0xffff8000, value: 0x01068000, op: FDIV_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FFINT.D.L fd, fj -+ {mask: 0xfffffc00, value: 0x011d2800, op: FFINT_D_L, args: instArgs{arg_fd, arg_fj}}, -+ // FFINT.D.W fd, fj -+ {mask: 0xfffffc00, value: 0x011d2000, op: FFINT_D_W, args: instArgs{arg_fd, arg_fj}}, -+ // FFINT.S.L fd, fj -+ {mask: 0xfffffc00, value: 0x011d1800, op: FFINT_S_L, args: instArgs{arg_fd, arg_fj}}, -+ // FFINT.S.W fd, fj -+ {mask: 0xfffffc00, value: 0x011d1000, op: FFINT_S_W, args: instArgs{arg_fd, arg_fj}}, -+ // FLDGT.D fd, rj, rk -+ {mask: 0xffff8000, value: 0x38748000, op: FLDGT_D, args: instArgs{arg_fd, arg_rj, arg_rk}}, -+ // FLDGT.S fd, rj, rk -+ {mask: 0xffff8000, value: 0x38740000, op: FLDGT_S, args: instArgs{arg_fd, arg_rj, arg_rk}}, -+ // FLDLE.D fd, rj, rk -+ {mask: 0xffff8000, value: 0x38758000, op: FLDLE_D, args: instArgs{arg_fd, arg_rj, arg_rk}}, -+ // FLDLE.S fd, rj, rk -+ {mask: 0xffff8000, value: 0x38750000, op: FLDLE_S, args: instArgs{arg_fd, arg_rj, arg_rk}}, -+ // FLDX.D fd, rj, rk -+ {mask: 0xffff8000, value: 0x38340000, op: FLDX_D, args: instArgs{arg_fd, arg_rj, arg_rk}}, -+ // FLDX.S fd, rj, rk -+ {mask: 0xffff8000, value: 0x38300000, op: FLDX_S, args: instArgs{arg_fd, arg_rj, arg_rk}}, -+ // FLD.D fd, rj, si12 -+ {mask: 0xffc00000, value: 0x2b800000, op: FLD_D, args: instArgs{arg_fd, arg_rj, arg_si12_21_10}}, -+ // FLD.S fd, rj, si12 -+ {mask: 0xffc00000, value: 0x2b000000, op: FLD_S, args: instArgs{arg_fd, arg_rj, arg_si12_21_10}}, -+ // FLOGB.D fd, fj -+ {mask: 0xfffffc00, value: 0x01142800, op: FLOGB_D, args: instArgs{arg_fd, arg_fj}}, -+ // FLOGB.S fd, fj -+ {mask: 0xfffffc00, value: 0x01142400, op: FLOGB_S, args: instArgs{arg_fd, arg_fj}}, -+ // FMADD.D fd, fj, fk, fa -+ {mask: 0xfff00000, value: 0x08200000, op: FMADD_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, -+ // FMADD.S fd, fj, fk, fa -+ {mask: 0xfff00000, value: 0x08100000, op: FMADD_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, -+ // FMAXA.D fd, fj, fk -+ {mask: 0xffff8000, value: 0x010d0000, op: FMAXA_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FMAXA.S fd, fj, fk -+ {mask: 0xffff8000, value: 0x010c8000, op: FMAXA_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FMAX.D fd, fj, fk -+ {mask: 0xffff8000, value: 0x01090000, op: FMAX_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FMAX.S fd, fj, fk -+ {mask: 0xffff8000, value: 0x01088000, op: FMAX_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FMINA.D fd, fj, fk -+ {mask: 0xffff8000, value: 0x010f0000, op: FMINA_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FMINA.S fd, fj, fk -+ {mask: 0xffff8000, value: 0x010e8000, op: FMINA_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FMIN.D fd, fj, fk -+ {mask: 0xffff8000, value: 0x010b0000, op: FMIN_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FMIN.S fd, fj, fk -+ {mask: 0xffff8000, value: 0x010a8000, op: FMIN_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FMOV.D fd, fj -+ {mask: 0xfffffc00, value: 0x01149800, op: FMOV_D, args: instArgs{arg_fd, arg_fj}}, -+ // FMOV.S fd, fj -+ {mask: 0xfffffc00, value: 0x01149400, op: FMOV_S, args: instArgs{arg_fd, arg_fj}}, -+ // FMSUB.D fd, fj, fk, fa -+ {mask: 0xfff00000, value: 0x08600000, op: FMSUB_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, -+ // FMSUB.S fd, fj, fk, fa -+ {mask: 0xfff00000, value: 0x08500000, op: FMSUB_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, -+ // FMUL.D fd, fj, fk -+ {mask: 0xffff8000, value: 0x01050000, op: FMUL_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FMUL.S fd, fj, fk -+ {mask: 0xffff8000, value: 0x01048000, op: FMUL_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FNEG.D fd, fj -+ {mask: 0xfffffc00, value: 0x01141800, op: FNEG_D, args: instArgs{arg_fd, arg_fj}}, -+ // FNEG.S fd, fj -+ {mask: 0xfffffc00, value: 0x01141400, op: FNEG_S, args: instArgs{arg_fd, arg_fj}}, -+ // FNMADD.D fd, fj, fk, fa -+ {mask: 0xfff00000, value: 0x08a00000, op: FNMADD_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, -+ // FNMADD.S fd, fj, fk, fa -+ {mask: 0xfff00000, value: 0x08900000, op: FNMADD_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, -+ // FNMSUB.D fd, fj, fk, fa -+ {mask: 0xfff00000, value: 0x08e00000, op: FNMSUB_D, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, -+ // FNMSUB.S fd, fj, fk, fa -+ {mask: 0xfff00000, value: 0x08d00000, op: FNMSUB_S, args: instArgs{arg_fd, arg_fj, arg_fk, arg_fa}}, -+ // FRECIP.D fd, fj -+ {mask: 0xfffffc00, value: 0x01145800, op: FRECIP_D, args: instArgs{arg_fd, arg_fj}}, -+ // FRECIP.S fd, fj -+ {mask: 0xfffffc00, value: 0x01145400, op: FRECIP_S, args: instArgs{arg_fd, arg_fj}}, -+ // FRINT.D fd, fj -+ {mask: 0xfffffc00, value: 0x011e4800, op: FRINT_D, args: instArgs{arg_fd, arg_fj}}, -+ // FRINT.S fd, fj -+ {mask: 0xfffffc00, value: 0x011e4400, op: FRINT_S, args: instArgs{arg_fd, arg_fj}}, -+ // FRSQRT.D fd, fj -+ {mask: 0xfffffc00, value: 0x01146800, op: FRSQRT_D, args: instArgs{arg_fd, arg_fj}}, -+ // FRSQRT.S fd, fj -+ {mask: 0xfffffc00, value: 0x01146400, op: FRSQRT_S, args: instArgs{arg_fd, arg_fj}}, -+ // FSCALEB.D fd, fj, fk -+ {mask: 0xffff8000, value: 0x01110000, op: FSCALEB_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FSCALEB.S fd, fj, fk -+ {mask: 0xffff8000, value: 0x01108000, op: FSCALEB_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FSEL fd, fj, fk, ca -+ {mask: 0xfffc0000, value: 0x0d000000, op: FSEL, args: instArgs{arg_fd, arg_fj, arg_fk, arg_ca}}, -+ // FSQRT.D fd, fj -+ {mask: 0xfffffc00, value: 0x01144800, op: FSQRT_D, args: instArgs{arg_fd, arg_fj}}, -+ // FSQRT.S fd, fj -+ {mask: 0xfffffc00, value: 0x01144400, op: FSQRT_S, args: instArgs{arg_fd, arg_fj}}, -+ // FSTGT.D fd, rj, rk -+ {mask: 0xffff8000, value: 0x38768000, op: FSTGT_D, args: instArgs{arg_fd, arg_rj, arg_rk}}, -+ // FSTGT.S fd, rj, rk -+ {mask: 0xffff8000, value: 0x38760000, op: FSTGT_S, args: instArgs{arg_fd, arg_rj, arg_rk}}, -+ // FSTLE.D fd, rj, rk -+ {mask: 0xffff8000, value: 0x38778000, op: FSTLE_D, args: instArgs{arg_fd, arg_rj, arg_rk}}, -+ // FSTLE.S fd, rj, rk -+ {mask: 0xffff8000, value: 0x38770000, op: FSTLE_S, args: instArgs{arg_fd, arg_rj, arg_rk}}, -+ // FSTX.D fd, rj, rk -+ {mask: 0xffff8000, value: 0x383c0000, op: FSTX_D, args: instArgs{arg_fd, arg_rj, arg_rk}}, -+ // FSTX.S fd, rj, rk -+ {mask: 0xffff8000, value: 0x38380000, op: FSTX_S, args: instArgs{arg_fd, arg_rj, arg_rk}}, -+ // FST.D fd, rj, si12 -+ {mask: 0xffc00000, value: 0x2bc00000, op: FST_D, args: instArgs{arg_fd, arg_rj, arg_si12_21_10}}, -+ // FST.S fd, rj, si12 -+ {mask: 0xffc00000, value: 0x2b400000, op: FST_S, args: instArgs{arg_fd, arg_rj, arg_si12_21_10}}, -+ // FSUB.D fd, fj, fk -+ {mask: 0xffff8000, value: 0x01030000, op: FSUB_D, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FSUB.S fd, fj, fk -+ {mask: 0xffff8000, value: 0x01028000, op: FSUB_S, args: instArgs{arg_fd, arg_fj, arg_fk}}, -+ // FTINTRM.L.D fd, fj -+ {mask: 0xfffffc00, value: 0x011a2800, op: FTINTRM_L_D, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRM.L.S fd, fj -+ {mask: 0xfffffc00, value: 0x011a2400, op: FTINTRM_L_S, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRM.W.D fd, fj -+ {mask: 0xfffffc00, value: 0x011a0800, op: FTINTRM_W_D, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRM.W.S fd, fj -+ {mask: 0xfffffc00, value: 0x011a0400, op: FTINTRM_W_S, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRNE.L.D fd, fj -+ {mask: 0xfffffc00, value: 0x011ae800, op: FTINTRNE_L_D, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRNE.L.S fd, fj -+ {mask: 0xfffffc00, value: 0x011ae400, op: FTINTRNE_L_S, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRNE.W.D fd, fj -+ {mask: 0xfffffc00, value: 0x011ac800, op: FTINTRNE_W_D, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRNE.W.S fd, fj -+ {mask: 0xfffffc00, value: 0x011ac400, op: FTINTRNE_W_S, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRP.L.D fd, fj -+ {mask: 0xfffffc00, value: 0x011a6800, op: FTINTRP_L_D, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRP.L.S fd, fj -+ {mask: 0xfffffc00, value: 0x011a6400, op: FTINTRP_L_S, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRP.W.D fd, fj -+ {mask: 0xfffffc00, value: 0x011a4800, op: FTINTRP_W_D, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRP.W.S fd, fj -+ {mask: 0xfffffc00, value: 0x011a4400, op: FTINTRP_W_S, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRZ.L.D fd, fj -+ {mask: 0xfffffc00, value: 0x011aa800, op: FTINTRZ_L_D, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRZ.L.S fd, fj -+ {mask: 0xfffffc00, value: 0x011aa400, op: FTINTRZ_L_S, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRZ.W.D fd, fj -+ {mask: 0xfffffc00, value: 0x011a8800, op: FTINTRZ_W_D, args: instArgs{arg_fd, arg_fj}}, -+ // FTINTRZ.W.S fd, fj -+ {mask: 0xfffffc00, value: 0x011a8400, op: FTINTRZ_W_S, args: instArgs{arg_fd, arg_fj}}, -+ // FTINT.L.D fd, fj -+ {mask: 0xfffffc00, value: 0x011b2800, op: FTINT_L_D, args: instArgs{arg_fd, arg_fj}}, -+ // FTINT.L.S fd, fj -+ {mask: 0xfffffc00, value: 0x011b2400, op: FTINT_L_S, args: instArgs{arg_fd, arg_fj}}, -+ // FTINT.W.D fd, fj -+ {mask: 0xfffffc00, value: 0x011b0800, op: FTINT_W_D, args: instArgs{arg_fd, arg_fj}}, -+ // FTINT.W.S fd, fj -+ {mask: 0xfffffc00, value: 0x011b0400, op: FTINT_W_S, args: instArgs{arg_fd, arg_fj}}, -+ // IBAR hint -+ {mask: 0xffff8000, value: 0x38728000, op: IBAR, args: instArgs{arg_hint_14_0}}, -+ // IDLE level -+ {mask: 0xffff8000, value: 0x06488000, op: IDLE, args: instArgs{arg_level_14_0}}, -+ // INVTLB op, rj, rk -+ {mask: 0xffff8000, value: 0x06498000, op: INVTLB, args: instArgs{arg_op_4_0, arg_rj, arg_rk}}, -+ // IOCSRRD.B rd, rj -+ {mask: 0xfffffc00, value: 0x06480000, op: IOCSRRD_B, args: instArgs{arg_rd, arg_rj}}, -+ // IOCSRRD.D rd, rj -+ {mask: 0xfffffc00, value: 0x06480c00, op: IOCSRRD_D, args: instArgs{arg_rd, arg_rj}}, -+ // IOCSRRD.H rd, rj -+ {mask: 0xfffffc00, value: 0x06480400, op: IOCSRRD_H, args: instArgs{arg_rd, arg_rj}}, -+ // IOCSRRD.W rd, rj -+ {mask: 0xfffffc00, value: 0x06480800, op: IOCSRRD_W, args: instArgs{arg_rd, arg_rj}}, -+ // IOCSRWR.B rd, rj -+ {mask: 0xfffffc00, value: 0x06481000, op: IOCSRWR_B, args: instArgs{arg_rd, arg_rj}}, -+ // IOCSRWR.D rd, rj -+ {mask: 0xfffffc00, value: 0x06481c00, op: IOCSRWR_D, args: instArgs{arg_rd, arg_rj}}, -+ // IOCSRWR.H rd, rj -+ {mask: 0xfffffc00, value: 0x06481400, op: IOCSRWR_H, args: instArgs{arg_rd, arg_rj}}, -+ // IOCSRWR.W rd, rj -+ {mask: 0xfffffc00, value: 0x06481800, op: IOCSRWR_W, args: instArgs{arg_rd, arg_rj}}, -+ // JIRL rd, rj, offs -+ {mask: 0xfc000000, value: 0x4c000000, op: JIRL, args: instArgs{arg_rd, arg_rj, arg_offset_15_0}}, -+ // LDDIR rd, rj, level -+ {mask: 0xfffc0000, value: 0x06400000, op: LDDIR, args: instArgs{arg_rd, arg_rj, arg_level_17_10}}, -+ // LDGT.B rd, rj, rk -+ {mask: 0xffff8000, value: 0x38780000, op: LDGT_B, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDGT.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x38798000, op: LDGT_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDGT.H rd, rj, rk -+ {mask: 0xffff8000, value: 0x38788000, op: LDGT_H, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDGT.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x38790000, op: LDGT_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDLE.B rd, rj, rk -+ {mask: 0xffff8000, value: 0x387a0000, op: LDLE_B, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDLE.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x387b8000, op: LDLE_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDLE.H rd, rj, rk -+ {mask: 0xffff8000, value: 0x387a8000, op: LDLE_H, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDLE.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x387b0000, op: LDLE_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDPTE rj, seq -+ {mask: 0xfffc001f, value: 0x06440000, op: LDPTE, args: instArgs{arg_rj, arg_seq_17_10}}, -+ // LDPTR.D rd, rj, si14 -+ {mask: 0xff000000, value: 0x26000000, op: LDPTR_D, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, -+ // LDPTR.W rd, rj, si14 -+ {mask: 0xff000000, value: 0x24000000, op: LDPTR_W, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, -+ // LDX.B rd, rj, rk -+ {mask: 0xffff8000, value: 0x38000000, op: LDX_B, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDX.BU rd, rj, rk -+ {mask: 0xffff8000, value: 0x38200000, op: LDX_BU, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDX.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x380c0000, op: LDX_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDX.H rd, rj, rk -+ {mask: 0xffff8000, value: 0x38040000, op: LDX_H, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDX.HU rd, rj, rk -+ {mask: 0xffff8000, value: 0x38240000, op: LDX_HU, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDX.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x38080000, op: LDX_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LDX.WU rd, rj, rk -+ {mask: 0xffff8000, value: 0x38280000, op: LDX_WU, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // LD.B rd, rj, si12 -+ {mask: 0xffc00000, value: 0x28000000, op: LD_B, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // LD.BU rd, rj, si12 -+ {mask: 0xffc00000, value: 0x2a000000, op: LD_BU, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // LD.D rd, rj, si12 -+ {mask: 0xffc00000, value: 0x28c00000, op: LD_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // LD.H rd, rj, si12 -+ {mask: 0xffc00000, value: 0x28400000, op: LD_H, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // LD.HU rd, rj, si12 -+ {mask: 0xffc00000, value: 0x2a400000, op: LD_HU, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // LD.W rd, rj, si12 -+ {mask: 0xffc00000, value: 0x28800000, op: LD_W, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // LD.WU rd, rj, si12 -+ {mask: 0xffc00000, value: 0x2a800000, op: LD_WU, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // LL.D rd, rj, si14 -+ {mask: 0xff000000, value: 0x22000000, op: LL_D, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, -+ // LL.W rd, rj, si14 -+ {mask: 0xff000000, value: 0x20000000, op: LL_W, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, -+ // LU12I.W rd, si20 -+ {mask: 0xfe000000, value: 0x14000000, op: LU12I_W, args: instArgs{arg_rd, arg_si20_24_5}}, -+ // LU32I.D rd, si20 -+ {mask: 0xfe000000, value: 0x16000000, op: LU32I_D, args: instArgs{arg_rd, arg_si20_24_5}}, -+ // LU52I.D rd, rj, si12 -+ {mask: 0xffc00000, value: 0x03000000, op: LU52I_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // MASKEQZ rd, rj, rk -+ {mask: 0xffff8000, value: 0x00130000, op: MASKEQZ, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MASKNEZ rd, rj, rk -+ {mask: 0xffff8000, value: 0x00138000, op: MASKNEZ, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MOD.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x00228000, op: MOD_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MOD.DU rd, rj, rk -+ {mask: 0xffff8000, value: 0x00238000, op: MOD_DU, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MOD.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00208000, op: MOD_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MOD.WU rd, rj, rk -+ {mask: 0xffff8000, value: 0x00218000, op: MOD_WU, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MOVCF2FR fd, cj -+ {mask: 0xffffff00, value: 0x0114d400, op: MOVCF2FR, args: instArgs{arg_fd, arg_cj}}, -+ // MOVCF2GR rd, cj -+ {mask: 0xffffff00, value: 0x0114dc00, op: MOVCF2GR, args: instArgs{arg_rd, arg_cj}}, -+ // MOVFCSR2GR rd, fcsr -+ {mask: 0xfffffc00, value: 0x0114c800, op: MOVFCSR2GR, args: instArgs{arg_rd, arg_fcsr_9_5}}, -+ // MOVFR2CF cd, fj -+ {mask: 0xfffffc18, value: 0x0114d000, op: MOVFR2CF, args: instArgs{arg_cd, arg_fj}}, -+ // MOVFR2GR.D rd, fj -+ {mask: 0xfffffc00, value: 0x0114b800, op: MOVFR2GR_D, args: instArgs{arg_rd, arg_fj}}, -+ // MOVFR2GR.S rd, fj -+ {mask: 0xfffffc00, value: 0x0114b400, op: MOVFR2GR_S, args: instArgs{arg_rd, arg_fj}}, -+ // MOVFRH2GR.S rd, fj -+ {mask: 0xfffffc00, value: 0x0114bc00, op: MOVFRH2GR_S, args: instArgs{arg_rd, arg_fj}}, -+ // MOVGR2CF cd, rj -+ {mask: 0xfffffc18, value: 0x0114d800, op: MOVGR2CF, args: instArgs{arg_cd, arg_rj}}, -+ // MOVGR2FCSR fcsr, rj -+ {mask: 0xfffffc00, value: 0x0114c000, op: MOVGR2FCSR, args: instArgs{arg_fcsr_4_0, arg_rj}}, -+ // MOVGR2FRH.W fd, rj -+ {mask: 0xfffffc00, value: 0x0114ac00, op: MOVGR2FRH_W, args: instArgs{arg_fd, arg_rj}}, -+ // MOVGR2FR.D fd, rj -+ {mask: 0xfffffc00, value: 0x0114a800, op: MOVGR2FR_D, args: instArgs{arg_fd, arg_rj}}, -+ // MOVGR2FR.W fd, rj -+ {mask: 0xfffffc00, value: 0x0114a400, op: MOVGR2FR_W, args: instArgs{arg_fd, arg_rj}}, -+ // MULH.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x001e0000, op: MULH_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MULH.DU rd, rj, rk -+ {mask: 0xffff8000, value: 0x001e8000, op: MULH_DU, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MULH.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x001c8000, op: MULH_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MULH.WU rd, rj, rk -+ {mask: 0xffff8000, value: 0x001d0000, op: MULH_WU, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MULW.D.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x001f0000, op: MULW_D_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MULW.D.WU rd, rj, rk -+ {mask: 0xffff8000, value: 0x001f8000, op: MULW_D_WU, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MUL.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x001d8000, op: MUL_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // MUL.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x001c0000, op: MUL_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // NOR rd, rj, rk -+ {mask: 0xffff8000, value: 0x00140000, op: NOR, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // OR rd, rj, rk -+ {mask: 0xffff8000, value: 0x00150000, op: OR, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // ORI rd, rj, ui12 -+ {mask: 0xffc00000, value: 0x03800000, op: ORI, args: instArgs{arg_rd, arg_rj, arg_ui12_21_10}}, -+ // ORN rd, rj, rk -+ {mask: 0xffff8000, value: 0x00160000, op: ORN, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // PCADDI rd, si20 -+ {mask: 0xfe000000, value: 0x18000000, op: PCADDI, args: instArgs{arg_rd, arg_si20_24_5}}, -+ // PCADDU12I rd, si20 -+ {mask: 0xfe000000, value: 0x1c000000, op: PCADDU12I, args: instArgs{arg_rd, arg_si20_24_5}}, -+ // PCADDU18I rd, si20 -+ {mask: 0xfe000000, value: 0x1e000000, op: PCADDU18I, args: instArgs{arg_rd, arg_si20_24_5}}, -+ // PCALAU12I rd, si20 -+ {mask: 0xfe000000, value: 0x1a000000, op: PCALAU12I, args: instArgs{arg_rd, arg_si20_24_5}}, -+ // PRELD hint, rj, si12 -+ {mask: 0xffc00000, value: 0x2ac00000, op: PRELD, args: instArgs{arg_hint_4_0, arg_rj, arg_si12_21_10}}, -+ // PRELDX hint, rj, rk -+ {mask: 0xffff8000, value: 0x382c0000, op: PRELDX, args: instArgs{arg_hint_4_0, arg_rj, arg_rk}}, -+ // RDTIMEH.W rd, rj -+ {mask: 0xfffffc00, value: 0x00006400, op: RDTIMEH_W, args: instArgs{arg_rd, arg_rj}}, -+ // RDTIMEL.W rd, rj -+ {mask: 0xfffffc00, value: 0x00006000, op: RDTIMEL_W, args: instArgs{arg_rd, arg_rj}}, -+ // RDTIME.D rd, rj -+ {mask: 0xfffffc00, value: 0x00006800, op: RDTIME_D, args: instArgs{arg_rd, arg_rj}}, -+ // REVB.2H rd, rj -+ {mask: 0xfffffc00, value: 0x00003000, op: REVB_2H, args: instArgs{arg_rd, arg_rj}}, -+ // REVB.2W rd, rj -+ {mask: 0xfffffc00, value: 0x00003800, op: REVB_2W, args: instArgs{arg_rd, arg_rj}}, -+ // REVB.4H rd, rj -+ {mask: 0xfffffc00, value: 0x00003400, op: REVB_4H, args: instArgs{arg_rd, arg_rj}}, -+ // REVB.D rd, rj -+ {mask: 0xfffffc00, value: 0x00003c00, op: REVB_D, args: instArgs{arg_rd, arg_rj}}, -+ // REVH.2W rd, rj -+ {mask: 0xfffffc00, value: 0x00004000, op: REVH_2W, args: instArgs{arg_rd, arg_rj}}, -+ // REVH.D rd, rj -+ {mask: 0xfffffc00, value: 0x00004400, op: REVH_D, args: instArgs{arg_rd, arg_rj}}, -+ // ROTRI.D rd, rj, ui6 -+ {mask: 0xffff0000, value: 0x004d0000, op: ROTRI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}}, -+ // ROTRI.W rd, rj, ui5 -+ {mask: 0xffff8000, value: 0x004c8000, op: ROTRI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}}, -+ // ROTR.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x001b8000, op: ROTR_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // ROTR.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x001b0000, op: ROTR_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // SC.D rd, rj, si14 -+ {mask: 0xff000000, value: 0x23000000, op: SC_D, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, -+ // SC.W rd, rj, si14 -+ {mask: 0xff000000, value: 0x21000000, op: SC_W, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, -+ // SLLI.D rd, rj, ui6 -+ {mask: 0xffff0000, value: 0x00410000, op: SLLI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}}, -+ // SLLI.W rd, rj, ui5 -+ {mask: 0xffff8000, value: 0x00408000, op: SLLI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}}, -+ // SLL.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x00188000, op: SLL_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // SLL.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00170000, op: SLL_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // SLT rd, rj, rk -+ {mask: 0xffff8000, value: 0x00120000, op: SLT, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // SLTI rd, rj, si12 -+ {mask: 0xffc00000, value: 0x02000000, op: SLTI, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // SLTU rd, rj, rk -+ {mask: 0xffff8000, value: 0x00128000, op: SLTU, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // SLTUI rd, rj, si12 -+ {mask: 0xffc00000, value: 0x02400000, op: SLTUI, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // SRAI.D rd, rj, ui6 -+ {mask: 0xffff0000, value: 0x00490000, op: SRAI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}}, -+ // SRAI.W rd, rj, ui5 -+ {mask: 0xffff8000, value: 0x00488000, op: SRAI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}}, -+ // SRA.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x00198000, op: SRA_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // SRA.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00180000, op: SRA_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // SRLI.D rd, rj, ui6 -+ {mask: 0xffff0000, value: 0x00450000, op: SRLI_D, args: instArgs{arg_rd, arg_rj, arg_ui6_15_10}}, -+ // SRLI.W rd, rj, ui5 -+ {mask: 0xffff8000, value: 0x00448000, op: SRLI_W, args: instArgs{arg_rd, arg_rj, arg_ui5_14_10}}, -+ // SRL.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x00190000, op: SRL_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // SRL.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00178000, op: SRL_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // STGT.B rd, rj, rk -+ {mask: 0xffff8000, value: 0x387c0000, op: STGT_B, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // STGT.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x387d8000, op: STGT_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // STGT.H rd, rj, rk -+ {mask: 0xffff8000, value: 0x387c8000, op: STGT_H, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // STGT.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x387d0000, op: STGT_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // STLE.B rd, rj, rk -+ {mask: 0xffff8000, value: 0x387e0000, op: STLE_B, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // STLE.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x387f8000, op: STLE_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // STLE.H rd, rj, rk -+ {mask: 0xffff8000, value: 0x387e8000, op: STLE_H, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // STLE.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x387f0000, op: STLE_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // STPTR.D rd, rj, si14 -+ {mask: 0xff000000, value: 0x27000000, op: STPTR_D, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, -+ // STPTR.W rd, rj, si14 -+ {mask: 0xff000000, value: 0x25000000, op: STPTR_W, args: instArgs{arg_rd, arg_rj, arg_si14_23_10}}, -+ // STX.B rd, rj, rk -+ {mask: 0xffff8000, value: 0x38100000, op: STX_B, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // STX.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x381c0000, op: STX_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // STX.H rd, rj, rk -+ {mask: 0xffff8000, value: 0x38140000, op: STX_H, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // STX.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x38180000, op: STX_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // ST.B rd, rj, si12 -+ {mask: 0xffc00000, value: 0x29000000, op: ST_B, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // ST.D rd, rj, si12 -+ {mask: 0xffc00000, value: 0x29c00000, op: ST_D, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // ST.H rd, rj, si12 -+ {mask: 0xffc00000, value: 0x29400000, op: ST_H, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // ST.W rd, rj, si12 -+ {mask: 0xffc00000, value: 0x29800000, op: ST_W, args: instArgs{arg_rd, arg_rj, arg_si12_21_10}}, -+ // SUB.D rd, rj, rk -+ {mask: 0xffff8000, value: 0x00118000, op: SUB_D, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // SUB.W rd, rj, rk -+ {mask: 0xffff8000, value: 0x00110000, op: SUB_W, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // SYSCALL code -+ {mask: 0xffff8000, value: 0x002b0000, op: SYSCALL, args: instArgs{arg_code_14_0}}, -+ // TLBCLR -+ {mask: 0xffffffff, value: 0x06482000, op: TLBCLR, args: instArgs{}}, -+ // TLBFILL -+ {mask: 0xffffffff, value: 0x06483400, op: TLBFILL, args: instArgs{}}, -+ // TLBFLUSH -+ {mask: 0xffffffff, value: 0x06482400, op: TLBFLUSH, args: instArgs{}}, -+ // TLBRD -+ {mask: 0xffffffff, value: 0x06482c00, op: TLBRD, args: instArgs{}}, -+ // TLBSRCH -+ {mask: 0xffffffff, value: 0x06482800, op: TLBSRCH, args: instArgs{}}, -+ // TLBWR -+ {mask: 0xffffffff, value: 0x06483000, op: TLBWR, args: instArgs{}}, -+ // XOR rd, rj, rk -+ {mask: 0xffff8000, value: 0x00158000, op: XOR, args: instArgs{arg_rd, arg_rj, arg_rk}}, -+ // XORI rd, rj, ui12 -+ {mask: 0xffc00000, value: 0x03c00000, op: XORI, args: instArgs{arg_rd, arg_rj, arg_ui12_21_10}}, -+} --- -2.20.1 - diff --git a/0003-delve-support-linux-loong64-native-debug.patch b/0003-delve-support-linux-loong64-native-debug.patch deleted file mode 100644 index bfe5c8e2dc4e45cf571deaded7140173421f2ed7..0000000000000000000000000000000000000000 --- a/0003-delve-support-linux-loong64-native-debug.patch +++ /dev/null @@ -1,1797 +0,0 @@ -From 0367f35068f046d68bb7362590e38c2f1b890ce4 Mon Sep 17 00:00:00 2001 -From: Huang Qiqi -Date: Wed, 27 Nov 2024 10:30:50 +0800 -Subject: [PATCH 3/7] delve: support linux-loong64 native debug - ---- - Documentation/backend_test_health.md | 5 + - _fixtures/asmnilptr/main_loong64.s | 7 + - _fixtures/cgostacktest/hello.c | 2 + - _fixtures/testvariablescgo/test.c | 2 + - pkg/dwarf/regnum/loong64.go | 87 +++++ - pkg/proc/bininfo.go | 10 + - pkg/proc/core/linux_core.go | 57 ++++ - pkg/proc/dump.go | 2 + - pkg/proc/linutil/regs_loong64_arch.go | 235 +++++++++++++ - pkg/proc/loong64_arch.go | 368 +++++++++++++++++++++ - pkg/proc/loong64_disasm.go | 223 +++++++++++++ - pkg/proc/native/hwbreak_other.go | 2 +- - pkg/proc/native/ptrace_linux_64bit.go | 2 +- - pkg/proc/native/registers_linux_loong64.go | 158 +++++++++ - pkg/proc/native/support_sentinel_linux.go | 2 +- - pkg/proc/native/threads_linux_loong64.go | 54 +++ - pkg/proc/pe.go | 90 ++--- - pkg/proc/proc_test.go | 13 +- - pkg/proc/stack.go | 4 +- - pkg/proc/test/support.go | 3 + - pkg/terminal/command_test.go | 3 + - service/dap/server_test.go | 2 +- - service/debugger/debugger_test.go | 3 + - service/debugger/debugger_unix_test.go | 3 + - service/test/integration1_test.go | 4 +- - service/test/integration2_test.go | 4 +- - 26 files changed, 1290 insertions(+), 55 deletions(-) - create mode 100644 _fixtures/asmnilptr/main_loong64.s - create mode 100644 pkg/dwarf/regnum/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 - -diff --git a/Documentation/backend_test_health.md b/Documentation/backend_test_health.md -index 4aa80a9..c737017 100644 ---- a/Documentation/backend_test_health.md -+++ b/Documentation/backend_test_health.md -@@ -29,6 +29,11 @@ Tests skipped by each supported backend: - * 1 broken in linux ppc64le - * linux/ppc64le/native/pie skipped = 3 - * 3 broken - pie mode -+* loong64 skipped = 8 -+ * 1 broken -+ * 3 broken - cgo stacktraces -+ * 1 broken - global variable symbolication -+ * 3 not implemented - * pie skipped = 2 - * 2 upstream issue - https://github.com/golang/go/issues/29322 - * ppc64le skipped = 11 -diff --git a/_fixtures/asmnilptr/main_loong64.s b/_fixtures/asmnilptr/main_loong64.s -new file mode 100644 -index 0000000..e32b710 ---- /dev/null -+++ b/_fixtures/asmnilptr/main_loong64.s -@@ -0,0 +1,7 @@ -+#include "textflag.h" -+ -+TEXT ·asmFunc(SB),0,$0-16 -+ MOVV arg+0(FP), R5 -+ MOVV (R5), R5 -+ MOVV R5, ret+8(FP) -+ RET -diff --git a/_fixtures/cgostacktest/hello.c b/_fixtures/cgostacktest/hello.c -index b779bf9..081bda3 100644 ---- a/_fixtures/cgostacktest/hello.c -+++ b/_fixtures/cgostacktest/hello.c -@@ -14,6 +14,8 @@ - #else - #define BREAKPOINT asm("brk 0;") - #endif -+#elif __loongarch__ -+#define BREAKPOINT asm("break 0;") - #endif - - void helloworld_pt2(int x) { -diff --git a/_fixtures/testvariablescgo/test.c b/_fixtures/testvariablescgo/test.c -index fdcae84..c40d375 100644 ---- a/_fixtures/testvariablescgo/test.c -+++ b/_fixtures/testvariablescgo/test.c -@@ -12,6 +12,8 @@ - #else - #define BREAKPOINT asm("brk 0;") - #endif -+#elif __loongarch__ -+#define BREAKPOINT asm("break 0;") - #endif - - #define N 100 -diff --git a/pkg/dwarf/regnum/loong64.go b/pkg/dwarf/regnum/loong64.go -new file mode 100644 -index 0000000..94f41ea ---- /dev/null -+++ b/pkg/dwarf/regnum/loong64.go -@@ -0,0 +1,87 @@ -+package regnum -+ -+import ( -+ "fmt" -+) -+ -+// The mapping between hardware registers and DWARF registers, See -+// https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html -+// https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html -+ -+const ( -+ // General-purpose Register -+ LOONG64_R0 = 0 -+ LOONG64_LR = 1 // ra: address fro subroutine -+ LOONG64_SP = 3 // sp: stack pointer -+ LOONG64_R22 = 22 -+ LOONG64_FP = LOONG64_R22 // fp: frame pointer -+ LOONG64_R31 = 31 -+ -+ // Floating-point Register -+ LOONG64_F0 = 32 -+ LOONG64_F31 = 63 -+ -+ // Floating condition flag register -+ LOONG64_FCC0 = 64 -+ LOONG64_FCC7 = 71 -+ -+ LOONG64_FCSR = 72 -+ -+ // Extra, not defined in ELF-ABI specification -+ LOONG64_ERA = 73 -+ LOONG64_BADV = 74 -+ -+ // See golang src/cmd/link/internal/loong64/l.go -+ LOONG64_PC = LOONG64_ERA // rea : exception program counter -+ -+ _LOONG64_MaxRegNum = LOONG64_BADV -+) -+ -+func LOONG64ToName(num uint64) string { -+ switch { -+ case num <= LOONG64_R31: -+ return fmt.Sprintf("R%d", num) -+ -+ case num >= LOONG64_F0 && num <= LOONG64_F31: -+ return fmt.Sprintf("F%d", num-32) -+ -+ case num >= LOONG64_FCC0 && num <= LOONG64_FCC7: -+ return fmt.Sprintf("FCC%d", num-64) -+ -+ case num == LOONG64_FCSR: -+ return fmt.Sprintf("FCSR") -+ -+ case num == LOONG64_ERA: -+ return fmt.Sprintf("ERA") -+ -+ case num == LOONG64_BADV: -+ return fmt.Sprintf("BADV") -+ -+ default: -+ return fmt.Sprintf("Unknown%d", num) -+ } -+} -+ -+func LOONG64MaxRegNum() uint64 { -+ return _LOONG64_MaxRegNum -+} -+ -+var LOONG64NameToDwarf = func() map[string]int { -+ r := make(map[string]int) -+ for i := 0; i <= 31; i++ { -+ r[fmt.Sprintf("r%d", i)] = LOONG64_R0 + i -+ } -+ r[fmt.Sprintf("era")] = LOONG64_ERA -+ r[fmt.Sprintf("badv")] = LOONG64_BADV -+ -+ for i := 0; i <= 31; i++ { -+ r[fmt.Sprintf("f%d", i)] = LOONG64_F0 + i -+ } -+ -+ for i := 0; i <= 7; i++ { -+ r[fmt.Sprintf("fcc%d", i)] = LOONG64_FCC0 + i -+ } -+ r["fcsr"] = LOONG64_FCSR -+ -+ return r -+}() -diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go -index b20a5b6..2e3f410 100644 ---- a/pkg/proc/bininfo.go -+++ b/pkg/proc/bininfo.go -@@ -129,6 +129,7 @@ var ( - elf.EM_AARCH64: true, - elf.EM_386: true, - elf.EM_PPC64: true, -+ elf.EM_LOONGARCH: true, - } - - supportedWindowsArch = map[_PEMachine]bool{ -@@ -689,6 +690,8 @@ func NewBinaryInfo(goos, goarch string) *BinaryInfo { - r.Arch = ARM64Arch(goos) - case "ppc64le": - r.Arch = PPC64LEArch(goos) -+ case "loong64": -+ r.Arch = LOONG64Arch(goos) - } - return r - } -@@ -1742,6 +1745,13 @@ func (bi *BinaryInfo) setGStructOffsetElf(image *Image, exe *elf.File, wg *sync. - - case elf.EM_PPC64: - _ = getSymbol(image, bi.logger, exe, "runtime.tls_g") -+ case elf.EM_LOONGARCH: -+ tlsg := getSymbol(image, bi.logger, exe, "runtime.tls_g") -+ if tlsg == nil || tls == nil { -+ bi.gStructOffset = 6 * uint64(bi.Arch.PtrSize()) -+ return -+ } -+ bi.gStructOffset = tlsg.Value + (tls.Vaddr & (tls.Align - 1)) - - default: - // we should never get here -diff --git a/pkg/proc/core/linux_core.go b/pkg/proc/core/linux_core.go -index 7a2b011..c8e9c50 100644 ---- a/pkg/proc/core/linux_core.go -+++ b/pkg/proc/core/linux_core.go -@@ -39,6 +39,7 @@ const _NT_FPREGSET elf.NType = 0x2 - const ( - _EM_AARCH64 = 183 - _EM_X86_64 = 62 -+ _EM_LOONGARCH = 258 - _ARM_FP_HEADER_START = 512 - ) - -@@ -48,6 +49,8 @@ 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: -@@ -65,12 +68,24 @@ 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 { -@@ -146,6 +161,8 @@ func readLinuxOrPlatformIndependentCore(corePath, exePath string) (*process, pro - 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") - } -@@ -202,6 +219,22 @@ func (t *linuxARM64Thread) pid() int { - return int(t.t.Pid) - } - -+type linuxLOONG64Thread struct { -+ regs linutil.LOONG64Registers -+ t *linuxPrStatusLOONG64 -+} -+ -+func (t *linuxLOONG64Thread) registers() (proc.Registers, error) { -+ var r linutil.LOONG64Registers -+ r.Regs = t.regs.Regs -+ r.Fpregs = t.regs.Fpregs -+ return &r, nil -+} -+ -+func (t *linuxLOONG64Thread) pid() int { -+ return int(t.t.Pid) -+} -+ - // Note is a note from the PT_NOTE prog. - // Relevant types: - // - NT_FILE: File mapping information, e.g. program text mappings. Desc is a LinuxNTFile. -@@ -285,6 +318,8 @@ func readNote(r io.ReadSeeker, machineType elf.Machine) (*note, error) { - note.Desc = &linuxPrStatusAMD64{} - case _EM_AARCH64: - note.Desc = &linuxPrStatusARM64{} -+ case _EM_LOONGARCH: -+ note.Desc = &linuxPrStatusLOONG64{} - default: - return nil, fmt.Errorf("unsupported machine type") - } -@@ -332,6 +367,15 @@ 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) -@@ -446,6 +490,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/dump.go b/pkg/proc/dump.go -index ebda9d9..d0af628 100644 ---- a/pkg/proc/dump.go -+++ b/pkg/proc/dump.go -@@ -138,6 +138,8 @@ func (t *Target) Dump(out elfwriter.WriteCloserSeeker, flags DumpFlags, state *D - fhdr.Machine = elf.EM_AARCH64 - case "ppc64le": - fhdr.Machine = elf.EM_PPC64 -+ case "loong64": -+ fhdr.Machine = elf.EM_LOONGARCH - default: - panic("not implemented") - } -diff --git a/pkg/proc/linutil/regs_loong64_arch.go b/pkg/proc/linutil/regs_loong64_arch.go -new file mode 100644 -index 0000000..d1b3e24 ---- /dev/null -+++ b/pkg/proc/linutil/regs_loong64_arch.go -@@ -0,0 +1,235 @@ -+package linutil -+ -+import ( -+ "encoding/binary" -+ "fmt" -+ "github.com/go-delve/delve/pkg/dwarf/op" -+ "github.com/go-delve/delve/pkg/dwarf/regnum" -+ "github.com/go-delve/delve/pkg/proc" -+) -+ -+// Regs is a wrapper for sys.PtraceRegs. -+type LOONG64Registers struct { -+ Regs *LOONG64PtraceRegs // general-purpose registers -+ iscgo bool -+ tp_tls uint64 -+ Fpregs []proc.Register // Formatted floating point registers -+ Fpregset []byte // holding all floating point register values -+ loadFpRegs func(*LOONG64Registers) error -+} -+ -+func NewLOONG64Registers(regs *LOONG64PtraceRegs, iscgo bool, tp_tls uint64, -+ loadFpRegs func(*LOONG64Registers) error) *LOONG64Registers { -+ return &LOONG64Registers{ -+ Regs: regs, -+ iscgo: iscgo, -+ tp_tls: tp_tls, -+ loadFpRegs: loadFpRegs, -+ } -+} -+ -+// LOONG64PtraceRegs is the struct used by the linux kernel to return the GPR for -+// LoongArch64 CPUs. refer to sys/unix/zptrace_linux_loong64.go -+type LOONG64PtraceRegs struct { -+ Regs [32]uint64 -+ Orig_a0 uint64 -+ Era uint64 -+ Badv uint64 -+ Reserved [10]uint64 -+} -+ -+// Slice returns the registers as a list of (name, value) pairs. -+func (r *LOONG64Registers) Slice(floatingPoint bool) ([]proc.Register, error) { -+ var regs64 = []struct { -+ k string -+ v uint64 -+ }{ -+ {"R0", r.Regs.Regs[0]}, -+ {"R1", r.Regs.Regs[1]}, -+ {"R2", r.Regs.Regs[2]}, -+ {"R3", r.Regs.Regs[3]}, -+ {"R4", r.Regs.Regs[4]}, -+ {"R5", r.Regs.Regs[5]}, -+ {"R6", r.Regs.Regs[6]}, -+ {"R7", r.Regs.Regs[7]}, -+ {"R8", r.Regs.Regs[8]}, -+ {"R9", r.Regs.Regs[9]}, -+ {"R10", r.Regs.Regs[10]}, -+ {"R11", r.Regs.Regs[11]}, -+ {"R12", r.Regs.Regs[12]}, -+ {"R13", r.Regs.Regs[13]}, -+ {"R14", r.Regs.Regs[14]}, -+ {"R15", r.Regs.Regs[15]}, -+ {"R16", r.Regs.Regs[16]}, -+ {"R17", r.Regs.Regs[17]}, -+ {"R18", r.Regs.Regs[18]}, -+ {"R19", r.Regs.Regs[19]}, -+ {"R20", r.Regs.Regs[20]}, -+ {"R21", r.Regs.Regs[21]}, -+ {"R22", r.Regs.Regs[22]}, -+ {"R23", r.Regs.Regs[23]}, -+ {"R24", r.Regs.Regs[24]}, -+ {"R25", r.Regs.Regs[25]}, -+ {"R26", r.Regs.Regs[26]}, -+ {"R27", r.Regs.Regs[27]}, -+ {"R28", r.Regs.Regs[28]}, -+ {"R29", r.Regs.Regs[29]}, -+ {"R30", r.Regs.Regs[30]}, -+ {"R31", r.Regs.Regs[31]}, -+ {"ERA", r.Regs.Era}, -+ {"BADV", r.Regs.Badv}, -+ } -+ -+ out := make([]proc.Register, 0, (len(regs64) + len(r.Fpregs))) -+ for _, reg := range regs64 { -+ out = proc.AppendUint64Register(out, reg.k, reg.v) -+ } -+ -+ var floatLoadError error -+ if floatingPoint { -+ if r.loadFpRegs != nil { -+ floatLoadError = r.loadFpRegs(r) -+ r.loadFpRegs = nil -+ } -+ -+ out = append(out, r.Fpregs...) -+ } -+ -+ return out, floatLoadError -+} -+ -+// PC returns the value of PC register. -+func (r *LOONG64Registers) PC() uint64 { -+ // PC Register -+ return r.Regs.Era -+} -+ -+// SP returns the value of SP register. -+func (r *LOONG64Registers) SP() uint64 { -+ // Stack pointer -+ return r.Regs.Regs[regnum.LOONG64_SP] -+} -+ -+// BP returns the value of FP register -+func (r *LOONG64Registers) BP() uint64 { -+ // Frame pointer -+ //return r.Regs.Regs[regnum.LOONG64_FP] -+ // unused FP register -+ return 0 -+} -+ -+// TLS returns the address of the thread local storage memory segment. -+func (r *LOONG64Registers) TLS() uint64 { -+ // TODO: calling cgo may overwrite $r22,read it from the kernel -+ if !r.iscgo { -+ return 0 -+ } -+ -+ // refer to golang defined REGG: loong64/a.out.go -+ return r.tp_tls -+} -+ -+// GAddr returns the address of the G variable if it is known, 0 and false otherwise. -+func (r *LOONG64Registers) GAddr() (uint64, bool) { -+ // REGG is $r22,store the address of g -+ return r.Regs.Regs[regnum.LOONG64_R22], !r.iscgo -+} -+ -+// LR returns the link register. -+func (r *LOONG64Registers) LR() uint64 { -+ return r.Regs.Regs[regnum.LOONG64_LR] -+} -+ -+// Copy returns a copy of these registers that is guaranteed not to change. -+func (r *LOONG64Registers) Copy() (proc.Registers, error) { -+ if r.loadFpRegs != nil { -+ err := r.loadFpRegs(r) -+ r.loadFpRegs = nil -+ if err != nil { -+ return nil, err -+ } -+ } -+ -+ var rr LOONG64Registers -+ rr.Regs = &LOONG64PtraceRegs{} -+ *(rr.Regs) = *(r.Regs) -+ if r.Fpregs != nil { -+ rr.Fpregs = make([]proc.Register, len(r.Fpregs)) -+ copy(rr.Fpregs, r.Fpregs) -+ } -+ -+ if r.Fpregset != nil { -+ rr.Fpregset = make([]byte, len(r.Fpregset)) -+ copy(rr.Fpregset, r.Fpregset) -+ } -+ -+ return &rr, nil -+} -+ -+func (r *LOONG64Registers) SetReg(regNum uint64, reg *op.DwarfRegister) (fpchanged bool, err error) { -+ switch regNum { -+ case regnum.LOONG64_SP: -+ r.Regs.Regs[regnum.LOONG64_SP] = reg.Uint64Val -+ return false, nil -+ -+ case regnum.LOONG64_PC: -+ r.Regs.Era = reg.Uint64Val -+ return false, nil -+ } -+ -+ switch { -+ case regNum >= regnum.LOONG64_R0 && regNum <= regnum.LOONG64_R31: -+ r.Regs.Regs[regNum] = reg.Uint64Val -+ return false, nil -+ -+ case regNum >= regnum.LOONG64_F0 && regNum <= regnum.LOONG64_F31: -+ if r.loadFpRegs != nil { -+ err := r.loadFpRegs(r) -+ r.loadFpRegs = nil -+ if err != nil { -+ return false, err -+ } -+ } -+ -+ i := regNum - regnum.LOONG64_F0 -+ reg.FillBytes() -+ copy(r.Fpregset[8*i:], reg.Bytes) -+ return true, nil -+ -+ default: -+ return false, fmt.Errorf("changing register %d not implemented", regNum) -+ } -+} -+ -+// Refer to the definition of struct user_fp_state in the kernel ptrace.h -+type LOONG64PtraceFpRegs struct { -+ Fregs []byte -+ Fcc uint64 -+ Fcsr uint32 -+} -+ -+const _LOONG64_FPREGSET_LENGTH = (32 * 8) -+ -+func (fpregs *LOONG64PtraceFpRegs) Decode() (regs []proc.Register) { -+ for i := 0; i < len(fpregs.Fregs); i += 8 { -+ name := fmt.Sprintf("F%d", (i / 8)) -+ value := fpregs.Fregs[i : i+8] -+ regs = proc.AppendBytesRegister(regs, name, value) -+ } -+ -+ fccBytes := make([]byte, 8) -+ binary.LittleEndian.PutUint64(fccBytes, uint64(fpregs.Fcc)) -+ regs = proc.AppendBytesRegister(regs, "FCC0", fccBytes) -+ -+ fcsrBytes := make([]byte, 4) -+ binary.LittleEndian.PutUint32(fccBytes, uint32(fpregs.Fcsr)) -+ regs = proc.AppendBytesRegister(regs, "FCSR", fcsrBytes) -+ -+ return -+} -+ -+func (fpregs *LOONG64PtraceFpRegs) Byte() []byte { -+ fpregs.Fregs = make([]byte, _LOONG64_FPREGSET_LENGTH) -+ -+ return fpregs.Fregs[:] -+} -diff --git a/pkg/proc/loong64_arch.go b/pkg/proc/loong64_arch.go -new file mode 100644 -index 0000000..de05497 ---- /dev/null -+++ b/pkg/proc/loong64_arch.go -@@ -0,0 +1,368 @@ -+package proc -+ -+import ( -+ "encoding/binary" -+ "fmt" -+ "strings" -+ -+ "github.com/go-delve/delve/pkg/dwarf/frame" -+ "github.com/go-delve/delve/pkg/dwarf/op" -+ "github.com/go-delve/delve/pkg/dwarf/regnum" -+ "github.com/go-delve/delve/pkg/goversion" -+) -+ -+// Break Instruction : 0x002a0000 -+var loong64BreakInstruction = []byte{0x00, 0x00, 0x2a, 0x00} -+ -+// LOONG64Arch returns an initialized LOONG64 struct. -+func LOONG64Arch(goos string) *Arch { -+ return &Arch{ -+ Name: "loong64", -+ ptrSize: 8, -+ maxInstructionLength: 4, -+ breakpointInstruction: loong64BreakInstruction, -+ breakInstrMovesPC: false, -+ derefTLS: false, -+ prologues: prologuesLOONG64, -+ fixFrameUnwindContext: loong64FixFrameUnwindContext, -+ switchStack: loong64SwitchStack, -+ regSize: loong64RegSize, -+ RegistersToDwarfRegisters: loong64RegistersToDwarfRegisters, -+ addrAndStackRegsToDwarfRegisters: loong64AddrAndStackRegsToDwarfRegisters, -+ DwarfRegisterToString: loong64DwarfRegisterToString, -+ inhibitStepInto: func(*BinaryInfo, uint64) bool { return false }, -+ asmDecode: loong64AsmDecode, -+ usesLR: true, -+ PCRegNum: regnum.LOONG64_PC, -+ SPRegNum: regnum.LOONG64_SP, -+ asmRegisters: loong64AsmRegisters, -+ RegisterNameToDwarf: nameToDwarfFunc(regnum.LOONG64NameToDwarf), -+ RegnumToString: regnum.LOONG64ToName, -+ debugCallMinStackSize: 288, // TODO -+ maxRegArgBytes: 16*8 + 16*8, // 16 int argument registers plus 16 float argument registers, TODO -+ } -+} -+ -+func loong64FixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *BinaryInfo) *frame.FrameContext { -+ a := bi.Arch -+ -+ if a.sigreturnfn == nil { -+ a.sigreturnfn = bi.lookupOneFunc("runtime.sigreturn") -+ } -+ -+ if (fctxt == nil) || ((a.sigreturnfn != nil) && (pc >= a.sigreturnfn.Entry) && (pc < a.sigreturnfn.End)) { -+ // When there's no frame descriptor entry use BP (the frame pointer) instead -+ // - return register is [bp + a.PtrSize()] (i.e. [cfa-a.PtrSize()]) -+ // - cfa is bp + a.PtrSize()*2 -+ // - bp is [bp] (i.e. [cfa-a.PtrSize()*2]) -+ // - sp is cfa -+ -+ // When the signal handler runs it will move the execution to the signal -+ // handling stack (installed using the sigaltstack system call). -+ // This isn't a proper stack switch: the pointer to g in TLS will still -+ // refer to whatever g was executing on that thread before the signal was -+ // received. -+ // Since go did not execute a stack switch the previous value of sp, pc -+ // and bp is not saved inside g.sched, as it normally would. -+ // The only way to recover is to either read sp/pc from the signal context -+ // parameter (the ucontext_t* parameter) or to unconditionally follow the -+ // frame pointer when we get to runtime.sigreturn (which is what we do -+ // here). -+ -+ return &frame.FrameContext{ -+ RetAddrReg: regnum.LOONG64_PC, -+ Regs: map[uint64]frame.DWRule{ -+ regnum.LOONG64_PC: { -+ Rule: frame.RuleOffset, -+ Offset: int64(-a.PtrSize()), -+ }, -+ -+ regnum.LOONG64_FP: { -+ Rule: frame.RuleOffset, -+ Offset: int64(-2 * a.PtrSize()), -+ }, -+ -+ regnum.LOONG64_SP: { -+ Rule: frame.RuleValOffset, -+ Offset: 0, -+ }, -+ }, -+ -+ CFA: frame.DWRule{ -+ Rule: frame.RuleCFA, -+ Reg: regnum.LOONG64_FP, -+ Offset: int64(2 * a.PtrSize()), -+ }, -+ } -+ } -+ -+ if a.crosscall2fn == nil { -+ a.crosscall2fn = bi.lookupOneFunc("crosscall2") -+ } -+ -+ if a.crosscall2fn != nil && pc >= a.crosscall2fn.Entry && pc < a.crosscall2fn.End { -+ rule := fctxt.CFA -+ -+ if rule.Offset == crosscall2SPOffsetBad { -+ rule.Offset += crosscall2SPOffset -+ } -+ fctxt.CFA = rule -+ } -+ -+ // We assume that FP is the frame pointer and we want to keep it updated, -+ // so that we can use it to unwind the stack even when we encounter frames -+ // without descriptor entries. -+ // If there isn't a rule already we emit one. -+ if fctxt.Regs[regnum.LOONG64_FP].Rule == frame.RuleUndefined { -+ fctxt.Regs[regnum.LOONG64_FP] = frame.DWRule{ -+ Rule: frame.RuleFramePointer, -+ Reg: regnum.LOONG64_FP, -+ Offset: 0, -+ } -+ } -+ -+ if fctxt.Regs[regnum.LOONG64_LR].Rule == frame.RuleUndefined { -+ fctxt.Regs[regnum.LOONG64_LR] = frame.DWRule{ -+ Rule: frame.RuleRegister, -+ Reg: regnum.LOONG64_LR, -+ Offset: 0, -+ } -+ } -+ -+ return fctxt -+} -+ -+const loong64cgocallSPOffsetSaveSlot = 0x8 -+const loong64PrevG0schedSPOffsetSaveSlot = 0x10 -+ -+func loong64SwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) bool { -+ if it.frame.Current.Fn == nil { -+ if it.systemstack && it.g != nil && it.top { -+ it.switchToGoroutineStack() -+ return true -+ } -+ return false -+ } -+ switch it.frame.Current.Fn.Name { -+ case "runtime.cgocallback_gofunc", "runtime.cgocallback": -+ // For a detailed description of how this works read the long comment at -+ // the start of $GOROOT/src/runtime/cgocall.go and the source code of -+ // runtime.cgocallback_gofunc in $GOROOT/src/runtime/asm_loong64.s -+ // -+ // When a C function calls back into go it will eventually call into -+ // runtime.cgocallback_gofunc which is the function that does the stack -+ // switch from the system stack back into the goroutine stack -+ // Since we are going backwards on the stack here we see the transition -+ // as goroutine stack -> system stack. -+ if it.top || it.systemstack { -+ return false -+ } -+ -+ it.loadG0SchedSP() -+ if it.g0_sched_sp <= 0 { -+ return false -+ } -+ // Entering the system stack. -+ it.regs.Reg(callFrameRegs.SPRegNum).Uint64Val = it.g0_sched_sp -+ // Reads the previous value of g0.sched.sp that runtime.cgocallback_gofunc saved on the stack. -+ it.g0_sched_sp, _ = readUintRaw(it.mem, uint64(it.regs.SP()+loong64PrevG0schedSPOffsetSaveSlot), int64(it.bi.Arch.PtrSize())) -+ it.top = false -+ callFrameRegs, ret, retaddr := it.advanceRegs() -+ frameOnSystemStack := it.newStackframe(ret, retaddr) -+ it.pc = frameOnSystemStack.Ret -+ it.regs = callFrameRegs -+ it.systemstack = true -+ -+ return true -+ -+ case "runtime.asmcgocall": -+ if it.top || !it.systemstack { -+ return false -+ } -+ -+ // This function is called by a goroutine to execute a C function and -+ // switches from the goroutine stack to the system stack. -+ // Since we are unwinding the stack from callee to caller we have to switch -+ // from the system stack to the goroutine stack. -+ off, _ := readIntRaw(it.mem, uint64(it.regs.SP()+loong64cgocallSPOffsetSaveSlot), -+ int64(it.bi.Arch.PtrSize())) -+ oldsp := it.regs.SP() -+ it.regs.Reg(it.regs.SPRegNum).Uint64Val = uint64(int64(it.stackhi) - off) -+ -+ // runtime.asmcgocall can also be called from inside the system stack, -+ // in that case no stack switch actually happens -+ if it.regs.SP() == oldsp { -+ return false -+ } -+ -+ it.top = false -+ it.systemstack = false -+ // The return value is stored in the LR register which is saved at 24(SP). -+ addrret := uint64(int64(it.regs.SP()) + int64(it.bi.Arch.PtrSize()*3)) // TODO -+ it.frame.Ret, _ = readUintRaw(it.mem, addrret, int64(it.bi.Arch.PtrSize())) -+ it.pc = it.frame.Ret -+ -+ return true -+ -+ case "runtime.goexit", "runtime.rt0_go", "runtime.mcall": -+ // Look for "top of stack" functions. -+ it.atend = true -+ return true -+ -+ case "crosscall2": -+ // The offsets get from runtime/cgo/asm_loong64.s:10 -+ bpoff := uint64(14) -+ lroff := uint64(15) -+ if producer := it.bi.Producer(); producer != "" && goversion.ProducerAfterOrEqual(producer, 1, 19) { -+ // In Go 1.19 (specifically eee6f9f82) the order registers are saved was changed. -+ bpoff = 22 -+ lroff = 23 -+ } -+ newbp, _ := readUintRaw(it.mem, uint64(it.regs.SP()+8*bpoff), int64(it.bi.Arch.PtrSize())) -+ newlr, _ := readUintRaw(it.mem, uint64(it.regs.SP()+8*lroff), int64(it.bi.Arch.PtrSize())) -+ if it.regs.Reg(it.regs.BPRegNum) != nil { -+ it.regs.Reg(it.regs.BPRegNum).Uint64Val = uint64(newbp) -+ } else { -+ reg, _ := it.readRegisterAt(it.regs.BPRegNum, it.regs.SP()+8*bpoff) -+ it.regs.AddReg(it.regs.BPRegNum, reg) -+ } -+ it.regs.Reg(it.regs.LRRegNum).Uint64Val = uint64(newlr) -+ it.regs.Reg(it.regs.SPRegNum).Uint64Val = uint64(newbp) -+ it.pc = newlr -+ return true -+ case "runtime.mstart": -+ // Calls to runtime.systemstack will switch to the systemstack then: -+ // 1. alter the goroutine stack so that it looks like systemstack_switch -+ // was called -+ // 2. alter the system stack so that it looks like the bottom-most frame -+ // belongs to runtime.mstart -+ // If we find a runtime.mstart frame on the system stack of a goroutine -+ // parked on runtime.systemstack_switch we assume runtime.systemstack was -+ // called and continue tracing from the parked position. -+ -+ if it.top || !it.systemstack || it.g == nil { -+ return false -+ } -+ if fn := it.bi.PCToFunc(it.g.PC); fn == nil || fn.Name != "runtime.systemstack_switch" { -+ return false -+ } -+ -+ it.switchToGoroutineStack() -+ return true -+ default: -+ if it.systemstack && it.top && it.g != nil && strings.HasPrefix(it.frame.Current.Fn.Name, "runtime.") && it.frame.Current.Fn.Name != "runtime.throw" && it.frame.Current.Fn.Name != "runtime.fatalthrow" { -+ // The runtime switches to the system stack in multiple places. -+ // This usually happens through a call to runtime.systemstack but there -+ // are functions that switch to the system stack manually (for example -+ // runtime.morestack). -+ // Since we are only interested in printing the system stack for cgo -+ // calls we switch directly to the goroutine stack if we detect that the -+ // function at the top of the stack is a runtime function. -+ it.switchToGoroutineStack() -+ return true -+ } -+ } -+ -+ fn := it.bi.PCToFunc(it.frame.Ret) -+ if fn == nil { -+ return false -+ } -+ -+ switch fn.Name { -+ case "runtime.asmcgocall": -+ if !it.systemstack { -+ return false -+ } -+ -+ // This function is called by a goroutine to execute a C function and -+ // switches from the goroutine stack to the system stack. -+ // Since we are unwinding the stack from callee to caller we have to switch -+ // from the system stack to the goroutine stack. -+ off, _ := readIntRaw(it.mem, -+ uint64(callFrameRegs.SP()+loong64cgocallSPOffsetSaveSlot), -+ int64(it.bi.Arch.PtrSize())) -+ oldsp := callFrameRegs.SP() -+ newsp := uint64(int64(it.stackhi) - off) -+ -+ // runtime.asmcgocall can also be called from inside the system stack, -+ // in that case no stack switch actually happens -+ if newsp == oldsp { -+ return false -+ } -+ -+ it.systemstack = false -+ callFrameRegs.Reg(callFrameRegs.SPRegNum).Uint64Val = uint64(int64(newsp)) -+ -+ return false -+ -+ case "runtime.cgocallback_gofunc": -+ // For a detailed description of how this works read the long comment at -+ // the start of $GOROOT/src/runtime/cgocall.go and the source code of -+ // runtime.cgocallback_gofunc in $GOROOT/src/runtime/asm_loong64.s -+ // -+ // When a C functions calls back into go it will eventually call into -+ // runtime.cgocallback_gofunc which is the function that does the stack -+ // switch from the system stack back into the goroutine stack -+ // Since we are going backwards on the stack here we see the transition -+ // as goroutine stack -> system stack. -+ if it.systemstack { -+ return false -+ } -+ -+ it.loadG0SchedSP() -+ if it.g0_sched_sp <= 0 { -+ return false -+ } -+ -+ // entering the system stack -+ callFrameRegs.Reg(callFrameRegs.SPRegNum).Uint64Val = it.g0_sched_sp -+ -+ // reads the previous value of g0.sched.sp that runtime.cgocallback_gofunc saved on the stack -+ it.g0_sched_sp, _ = readUintRaw(it.mem, -+ uint64(callFrameRegs.SP()+loong64PrevG0schedSPOffsetSaveSlot), -+ int64(it.bi.Arch.PtrSize())) -+ it.systemstack = true -+ -+ return false -+ } -+ -+ return false -+} -+ -+func loong64RegSize(regnum uint64) int { -+ // All CPU registers are 64bit -+ return 8 -+} -+ -+func loong64RegistersToDwarfRegisters(staticBase uint64, regs Registers) *op.DwarfRegisters { -+ dregs := initDwarfRegistersFromSlice(int(regnum.LOONG64MaxRegNum()), regs, regnum.LOONG64NameToDwarf) -+ dr := op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.LOONG64_PC, regnum.LOONG64_SP, regnum.LOONG64_FP, regnum.LOONG64_LR) -+ dr.SetLoadMoreCallback(loadMoreDwarfRegistersFromSliceFunc(dr, regs, regnum.LOONG64NameToDwarf)) -+ return dr -+} -+ -+func loong64AddrAndStackRegsToDwarfRegisters(staticBase, pc, sp, bp, lr uint64) op.DwarfRegisters { -+ dregs := make([]*op.DwarfRegister, int(regnum.LOONG64MaxRegNum())) -+ dregs[regnum.LOONG64_PC] = op.DwarfRegisterFromUint64(pc) -+ dregs[regnum.LOONG64_SP] = op.DwarfRegisterFromUint64(sp) -+ dregs[regnum.LOONG64_FP] = op.DwarfRegisterFromUint64(bp) -+ dregs[regnum.LOONG64_LR] = op.DwarfRegisterFromUint64(lr) -+ -+ return *op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.LOONG64_PC, regnum.LOONG64_SP, regnum.LOONG64_FP, regnum.LOONG64_LR) -+} -+ -+func loong64DwarfRegisterToString(i int, reg *op.DwarfRegister) (name string, floatingPoint bool, repr string) { -+ name = regnum.LOONG64ToName(uint64(i)) -+ -+ if reg == nil { -+ return name, false, "" -+ } -+ -+ if strings.HasPrefix(name, "FCC") { -+ return name, true, fmt.Sprintf("%#x", reg.Uint64Val) -+ } else if strings.HasPrefix(name, "F") { -+ return name, true, fmt.Sprintf("%#016x", reg.Uint64Val) -+ } else { -+ return name, false, fmt.Sprintf("%#016x", reg.Uint64Val) -+ } -+} -diff --git a/pkg/proc/loong64_disasm.go b/pkg/proc/loong64_disasm.go -new file mode 100644 -index 0000000..98d191f ---- /dev/null -+++ b/pkg/proc/loong64_disasm.go -@@ -0,0 +1,223 @@ -+// TODO: disassembler support should be compiled in unconditionally, -+// instead of being decided by the build-target architecture, and be -+// part of the Arch object instead. -+ -+package proc -+ -+import ( -+ "fmt" -+ "github.com/go-delve/delve/pkg/dwarf/op" -+ "github.com/go-delve/delve/pkg/dwarf/regnum" -+ "golang.org/x/arch/loong64/loong64asm" -+) -+ -+var ( -+ errType = fmt.Errorf("unknown type") -+) -+ -+func loong64AsmDecode(asmInst *AsmInstruction, mem []byte, regs *op.DwarfRegisters, memrw MemoryReadWriter, bi *BinaryInfo) error { -+ asmInst.Size = 4 -+ asmInst.Bytes = mem[:asmInst.Size] -+ -+ inst, err := loong64asm.Decode(mem) -+ if err != nil { -+ asmInst.Inst = (*loong64ArchInst)(nil) -+ return err -+ } -+ -+ asmInst.Inst = (*loong64ArchInst)(&inst) -+ asmInst.Kind = OtherInstruction -+ -+ switch inst.Op { -+ case loong64asm.JIRL: -+ rd, _ := inst.Args[0].(loong64asm.Reg) -+ rj, _ := inst.Args[1].(loong64asm.Reg) -+ if rd == loong64asm.R1 { -+ asmInst.Kind = CallInstruction -+ } else if rd == loong64asm.R0 && rj == loong64asm.R1 { -+ asmInst.Kind = RetInstruction -+ } else { -+ asmInst.Kind = JmpInstruction -+ } -+ -+ case loong64asm.BL: -+ asmInst.Kind = CallInstruction -+ -+ case loong64asm.BEQZ, -+ loong64asm.BNEZ, -+ loong64asm.BCEQZ, -+ loong64asm.BCNEZ, -+ loong64asm.B, -+ loong64asm.BEQ, -+ loong64asm.BNE, -+ loong64asm.BLT, -+ loong64asm.BGE, -+ loong64asm.BLTU, -+ loong64asm.BGEU: -+ asmInst.Kind = JmpInstruction -+ -+ case loong64asm.BREAK: -+ asmInst.Kind = HardBreakInstruction -+ -+ default: -+ asmInst.Kind = OtherInstruction -+ } -+ -+ asmInst.DestLoc = resolveCallArgLOONG64(&inst, asmInst.Loc.PC, asmInst.AtPC, regs, memrw, bi) -+ -+ return nil -+} -+ -+func resolveCallArgLOONG64(inst *loong64asm.Inst, instAddr uint64, currentGoroutine bool, regs *op.DwarfRegisters, mem MemoryReadWriter, bininfo *BinaryInfo) *Location { -+ var pc uint64 -+ var err error -+ -+ switch inst.Op { -+ // Format: op offs26 -+ // Target: offs26 -+ case loong64asm.B, loong64asm.BL: -+ switch arg := inst.Args[0].(type) { -+ case loong64asm.OffsetSimm: -+ pc = uint64(int64(instAddr) + int64(arg.Imm)) -+ default: -+ return nil -+ } -+ -+ // Format: op rd,rj,offs16 -+ // Target: offs16 -+ case loong64asm.BEQ, -+ loong64asm.BNE, -+ loong64asm.BLT, -+ loong64asm.BGE, -+ loong64asm.BLTU, -+ loong64asm.BGEU: -+ -+ switch arg := inst.Args[2].(type) { -+ case loong64asm.OffsetSimm: -+ pc = uint64(int64(instAddr) + int64(arg.Imm)) -+ default: -+ return nil -+ } -+ -+ // Format: op rd,rj,offs16 -+ // Target: rj + offs16 -+ case loong64asm.JIRL: -+ if !currentGoroutine || regs == nil { -+ return nil -+ } -+ switch arg1 := inst.Args[1].(type) { -+ case loong64asm.Reg: -+ switch arg2 := inst.Args[2].(type) { -+ case loong64asm.OffsetSimm: -+ pc, err = bininfo.Arch.getAsmRegister(regs, int(arg1)) -+ if err != nil { -+ return nil -+ } -+ pc = uint64(int64(pc) + int64(arg2.Imm)) -+ } -+ } -+ -+ // Format: op rj,offs21 -+ // Target: offs21 -+ case loong64asm.BEQZ, -+ loong64asm.BNEZ, -+ loong64asm.BCEQZ, -+ loong64asm.BCNEZ: -+ -+ if (!currentGoroutine) || (regs == nil) { -+ return nil -+ } -+ -+ switch arg := inst.Args[1].(type) { -+ case loong64asm.OffsetSimm: -+ pc = uint64(int64(instAddr) + int64(arg.Imm)) -+ default: -+ return nil -+ } -+ -+ default: -+ return nil -+ } -+ -+ file, line, fn := bininfo.PCToLine(pc) -+ if fn == nil { -+ return &Location{PC: pc} -+ } -+ -+ return &Location{PC: pc, File: file, Line: line, Fn: fn} -+} -+ -+// Possible stacksplit prologues are inserted by stacksplit in -+// $GOROOT/src/cmd/internal/obj/loong64/obj.go. -+var prologuesLOONG64 []opcodeSeq -+ -+func init() { -+ var tinyStacksplit = opcodeSeq{uint64(loong64asm.ADDI_D)} -+ var smallStacksplit = opcodeSeq{} -+ // inst:{uint64(loong64asm.SLTUI), -+ // uint64(loong64asm.BNE), -+ // uint64(loong64asm.ADDI_D)} -+ var bigStacksplit = opcodeSeq{uint64(loong64asm.LU12I_W), -+ uint64(loong64asm.ORI), -+ uint64(loong64asm.SLTU), -+ uint64(loong64asm.BNE), -+ uint64(loong64asm.LU12I_W), -+ uint64(loong64asm.ORI), -+ uint64(loong64asm.ADD_D)} -+ -+ var unixGetG = opcodeSeq{uint64(loong64asm.LD_D)} -+ var tailPrologues = opcodeSeq{uint64(loong64asm.SLTU), -+ uint64(loong64asm.BNE), -+ uint64(loong64asm.OR), -+ uint64(loong64asm.BL), -+ uint64(loong64asm.BEQ)} -+ -+ prologuesLOONG64 = make([]opcodeSeq, 0, 3) -+ for _, stacksplit := range []opcodeSeq{tinyStacksplit, smallStacksplit, bigStacksplit} { -+ prologue := make(opcodeSeq, 0, len(unixGetG)+len(stacksplit)+len(tailPrologues)) -+ prologue = append(prologue, unixGetG...) -+ prologue = append(prologue, stacksplit...) -+ prologue = append(prologue, tailPrologues...) -+ prologuesLOONG64 = append(prologuesLOONG64, prologue) -+ } -+} -+ -+type loong64ArchInst loong64asm.Inst -+ -+func (inst *loong64ArchInst) Text(flavour AssemblyFlavour, pc uint64, symLookup func(uint64) (string, uint64)) string { -+ if inst == nil { -+ return "?" -+ } -+ -+ var text string -+ -+ switch flavour { -+ case GNUFlavour: -+ text = loong64asm.GNUSyntax(loong64asm.Inst(*inst)) -+ default: -+ // It should be disassembled to plan9, but loong64 -+ // doesn't support this at the moment, so it's better -+ // to use it as GNUSyntax. -+ 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 -+}() -diff --git a/pkg/proc/native/hwbreak_other.go b/pkg/proc/native/hwbreak_other.go -index e65bf5b..5d6909a 100644 ---- a/pkg/proc/native/hwbreak_other.go -+++ b/pkg/proc/native/hwbreak_other.go -@@ -1,4 +1,4 @@ --//go:build (linux && 386) || (darwin && arm64) || (windows && arm64) || (linux && ppc64le) -+//go:build (linux && 386) || (darwin && arm64) || (windows && arm64) || (linux && ppc64le) || (linux && loong64) - - package native - -diff --git a/pkg/proc/native/ptrace_linux_64bit.go b/pkg/proc/native/ptrace_linux_64bit.go -index 01a1170..680ccdd 100644 ---- a/pkg/proc/native/ptrace_linux_64bit.go -+++ b/pkg/proc/native/ptrace_linux_64bit.go -@@ -1,4 +1,4 @@ --//go:build (linux && amd64) || (linux && arm64) || (linux && ppc64le) -+//go:build (linux && amd64) || (linux && arm64) || (linux && ppc64le) || (linux && loong64) - - package native - -diff --git a/pkg/proc/native/registers_linux_loong64.go b/pkg/proc/native/registers_linux_loong64.go -new file mode 100644 -index 0000000..c9752b2 ---- /dev/null -+++ b/pkg/proc/native/registers_linux_loong64.go -@@ -0,0 +1,158 @@ -+//go:build linux && loong64 -+// +build linux,loong64 -+ -+package native -+ -+import ( -+ "debug/elf" -+ "encoding/binary" -+ "syscall" -+ "unsafe" -+ -+ sys "golang.org/x/sys/unix" -+ -+ "github.com/go-delve/delve/pkg/dwarf/op" -+ "github.com/go-delve/delve/pkg/proc" -+ "github.com/go-delve/delve/pkg/proc/linutil" -+) -+ -+const ( -+ // Refer to the definition of struct user_pt_regs in the kernel file ptrace.h -+ _LOONG64_GREGS_SIZE = (32 * 8) + 8 + 8 + 8 + (10 * 8) -+ -+ // In fact, the total number of bytes is 268(32 fpr * 8 + 1 Fcc * 8 + 1 Fcsr +4), -+ // but since the Len defined in sys.Iovec is uint64,the total numbel of bytes must -+ // be an integral multiple of 8,so add 4 bytes -+ _LOONG64_FPREGS_SIZE = (32 * 8) + (1 * 8) + (1 * 4) + 4 -+) -+ -+func ptraceGetGRegs(pid int, regs *linutil.LOONG64PtraceRegs) (err error) { -+ iov := sys.Iovec{Base: (*byte)(unsafe.Pointer(regs)), Len: _LOONG64_GREGS_SIZE} -+ -+ _, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_GETREGSET, uintptr(pid), -+ uintptr(elf.NT_PRSTATUS), uintptr(unsafe.Pointer(&iov)), 0, 0) -+ if err == syscall.Errno(0) { -+ err = nil -+ } -+ -+ return -+} -+ -+func ptraceSetGRegs(pid int, regs *linutil.LOONG64PtraceRegs) (err error) { -+ iov := sys.Iovec{Base: (*byte)(unsafe.Pointer(regs)), Len: _LOONG64_GREGS_SIZE} -+ -+ _, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_SETREGSET, uintptr(pid), -+ uintptr(elf.NT_PRSTATUS), uintptr(unsafe.Pointer(&iov)), 0, 0) -+ if err == syscall.Errno(0) { -+ err = nil -+ } -+ -+ return -+} -+ -+// ptraceGetFpRegset returns floating point registers of -+// the specified thread using PTRACE. -+func ptraceGetFpRegset(tid int, fpregs *linutil.LOONG64PtraceFpRegs) (err error) { -+ fprBytes := make([]byte, _LOONG64_FPREGS_SIZE) -+ iov := sys.Iovec{Base: &fprBytes[0], Len: uint64(_LOONG64_FPREGS_SIZE)} -+ -+ _, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_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 -+ } -+ -+ fpregs.Fregs = fprBytes[:iov.Len-16] -+ fpregs.Fcc = binary.LittleEndian.Uint64(fprBytes[iov.Len-16 : iov.Len-8]) -+ fpregs.Fcsr = binary.LittleEndian.Uint32(fprBytes[iov.Len-8 : iov.Len-4]) -+ -+ return -+} -+ -+// SetPC sets PC to the value specified by 'pc'. -+func (thread *nativeThread) setPC(pc uint64) error { -+ ir, err := registers(thread) -+ if err != nil { -+ return err -+ } -+ -+ r := ir.(*linutil.LOONG64Registers) -+ r.Regs.Era = pc -+ thread.dbp.execPtraceFunc(func() { err = ptraceSetGRegs(thread.ID, r.Regs) }) -+ -+ return err -+} -+ -+// SetSP sets SP to the value specified by 'sp' -+func (thread *nativeThread) setSP(sp uint64) (err error) { -+ var ir proc.Registers -+ -+ ir, err = registers(thread) -+ if err != nil { -+ return err -+ } -+ -+ r := ir.(*linutil.LOONG64Registers) -+ r.Regs.Regs[3] = sp -+ thread.dbp.execPtraceFunc(func() { err = ptraceSetGRegs(thread.ID, r.Regs) }) -+ -+ return nil -+} -+ -+func (thread *nativeThread) SetReg(regNum uint64, reg *op.DwarfRegister) error { -+ ir, err := registers(thread) -+ if err != nil { -+ return err -+ } -+ r := ir.(*linutil.LOONG64Registers) -+ fpchanged, err := r.SetReg(regNum, reg) -+ if err != nil { -+ return err -+ } -+ -+ thread.dbp.execPtraceFunc(func() { -+ err = ptraceSetGRegs(thread.ID, r.Regs) -+ if err != syscall.Errno(0) && err != nil { -+ return -+ } -+ if fpchanged && r.Fpregset != nil { -+ iov := sys.Iovec{Base: &r.Fpregset[0], Len: uint64(len(r.Fpregset))} -+ _, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_SETREGSET, uintptr(thread.ID), uintptr(elf.NT_FPREGSET), uintptr(unsafe.Pointer(&iov)), 0, 0) -+ } -+ }) -+ if err == syscall.Errno(0) { -+ err = nil -+ } -+ -+ return err -+} -+ -+func registers(thread *nativeThread) (proc.Registers, error) { -+ var ( -+ regs linutil.LOONG64PtraceRegs -+ err error -+ ) -+ -+ thread.dbp.execPtraceFunc(func() { err = ptraceGetGRegs(thread.ID, ®s) }) -+ if err != nil { -+ return nil, err -+ } -+ -+ var tp_tls uint64 -+ if thread.dbp.iscgo { -+ tp_tls = regs.Regs[2] -+ } -+ r := linutil.NewLOONG64Registers(®s, thread.dbp.iscgo, tp_tls, -+ func(r *linutil.LOONG64Registers) error { -+ var floatLoadError error -+ r.Fpregs, r.Fpregset, floatLoadError = thread.fpRegisters() -+ return floatLoadError -+ }) -+ -+ return r, nil -+} -diff --git a/pkg/proc/native/support_sentinel_linux.go b/pkg/proc/native/support_sentinel_linux.go -index afb7c0a..048ea84 100644 ---- a/pkg/proc/native/support_sentinel_linux.go -+++ b/pkg/proc/native/support_sentinel_linux.go -@@ -1,4 +1,4 @@ --//go:build linux && !amd64 && !arm64 && !386 && !(ppc64le && exp.linuxppc64le) -+//go:build linux && !amd64 && !arm64 && !386 && !(ppc64le && exp.linuxppc64le) && !loong64 - - // This file is used to detect build on unsupported GOOS/GOARCH combinations. - -diff --git a/pkg/proc/native/threads_linux_loong64.go b/pkg/proc/native/threads_linux_loong64.go -new file mode 100644 -index 0000000..c17b726 ---- /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() { err = ptraceGetFpRegset(thread.ID, &loong64_fpregs) }) -+ fpregs := loong64_fpregs.Decode() -+ -+ if err != nil { -+ err = fmt.Errorf("could not get floating point registers: %v", err.Error()) -+ } -+ -+ return fpregs, loong64_fpregs.Fregs, err -+} -+ -+func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error { -+ var restoreRegistersErr error -+ -+ sr := savedRegs.(*linutil.LOONG64Registers) -+ t.dbp.execPtraceFunc(func() { -+ restoreRegistersErr = ptraceSetGRegs(t.ID, sr.Regs) -+ if restoreRegistersErr != syscall.Errno(0) { -+ return -+ } -+ -+ if sr.Fpregset != nil { -+ iov := sys.Iovec{Base: &sr.Fpregset[0], Len: uint64(len(sr.Fpregset))} -+ _, _, restoreRegistersErr = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_SETREGSET, -+ uintptr(t.ID), uintptr(elf.NT_FPREGSET), uintptr(unsafe.Pointer(&iov)), 0, 0) -+ } -+ }) -+ -+ if restoreRegistersErr == syscall.Errno(0) { -+ restoreRegistersErr = nil -+ } -+ -+ return restoreRegistersErr -+} -diff --git a/pkg/proc/pe.go b/pkg/proc/pe.go -index 6295f8f..fab5890 100644 ---- a/pkg/proc/pe.go -+++ b/pkg/proc/pe.go -@@ -5,56 +5,58 @@ import ( - ) - - const ( -- _IMAGE_FILE_MACHINE_UNKNOWN = 0x0 -- _IMAGE_FILE_MACHINE_AM33 = 0x1d3 -- _IMAGE_FILE_MACHINE_AMD64 = 0x8664 -- _IMAGE_FILE_MACHINE_ARM = 0x1c0 -- _IMAGE_FILE_MACHINE_ARMNT = 0x1c4 -- _IMAGE_FILE_MACHINE_ARM64 = 0xaa64 -- _IMAGE_FILE_MACHINE_EBC = 0xebc -- _IMAGE_FILE_MACHINE_I386 = 0x14c -- _IMAGE_FILE_MACHINE_IA64 = 0x200 -- _IMAGE_FILE_MACHINE_M32R = 0x9041 -- _IMAGE_FILE_MACHINE_MIPS16 = 0x266 -- _IMAGE_FILE_MACHINE_MIPSFPU = 0x366 -- _IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466 -- _IMAGE_FILE_MACHINE_POWERPC = 0x1f0 -- _IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1 -- _IMAGE_FILE_MACHINE_R4000 = 0x166 -- _IMAGE_FILE_MACHINE_SH3 = 0x1a2 -- _IMAGE_FILE_MACHINE_SH3DSP = 0x1a3 -- _IMAGE_FILE_MACHINE_SH4 = 0x1a6 -- _IMAGE_FILE_MACHINE_SH5 = 0x1a8 -- _IMAGE_FILE_MACHINE_THUMB = 0x1c2 -- _IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169 -+ _IMAGE_FILE_MACHINE_UNKNOWN = 0x0 -+ _IMAGE_FILE_MACHINE_AM33 = 0x1d3 -+ _IMAGE_FILE_MACHINE_AMD64 = 0x8664 -+ _IMAGE_FILE_MACHINE_ARM = 0x1c0 -+ _IMAGE_FILE_MACHINE_ARMNT = 0x1c4 -+ _IMAGE_FILE_MACHINE_ARM64 = 0xaa64 -+ _IMAGE_FILE_MACHINE_LOONGARCH64 = 0x6264 -+ _IMAGE_FILE_MACHINE_EBC = 0xebc -+ _IMAGE_FILE_MACHINE_I386 = 0x14c -+ _IMAGE_FILE_MACHINE_IA64 = 0x200 -+ _IMAGE_FILE_MACHINE_M32R = 0x9041 -+ _IMAGE_FILE_MACHINE_MIPS16 = 0x266 -+ _IMAGE_FILE_MACHINE_MIPSFPU = 0x366 -+ _IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466 -+ _IMAGE_FILE_MACHINE_POWERPC = 0x1f0 -+ _IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1 -+ _IMAGE_FILE_MACHINE_R4000 = 0x166 -+ _IMAGE_FILE_MACHINE_SH3 = 0x1a2 -+ _IMAGE_FILE_MACHINE_SH3DSP = 0x1a3 -+ _IMAGE_FILE_MACHINE_SH4 = 0x1a6 -+ _IMAGE_FILE_MACHINE_SH5 = 0x1a8 -+ _IMAGE_FILE_MACHINE_THUMB = 0x1c2 -+ _IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169 - ) - - type _PEMachine uint16 - - // PEMachineString map pe machine to name, See $GOROOT/src/debug/pe/pe.go for detail - var _PEMachineString = map[_PEMachine]string{ -- _IMAGE_FILE_MACHINE_UNKNOWN: "unknown", -- _IMAGE_FILE_MACHINE_AM33: "am33", -- _IMAGE_FILE_MACHINE_AMD64: "amd64", -- _IMAGE_FILE_MACHINE_ARM: "arm", -- _IMAGE_FILE_MACHINE_ARMNT: "armnt", -- _IMAGE_FILE_MACHINE_ARM64: "arm64", -- _IMAGE_FILE_MACHINE_EBC: "ebc", -- _IMAGE_FILE_MACHINE_I386: "i386", -- _IMAGE_FILE_MACHINE_IA64: "ia64", -- _IMAGE_FILE_MACHINE_M32R: "m32r", -- _IMAGE_FILE_MACHINE_MIPS16: "mips16", -- _IMAGE_FILE_MACHINE_MIPSFPU: "mipsfpu", -- _IMAGE_FILE_MACHINE_MIPSFPU16: "mipsfpu16", -- _IMAGE_FILE_MACHINE_POWERPC: "powerpc", -- _IMAGE_FILE_MACHINE_POWERPCFP: "powerpcfp", -- _IMAGE_FILE_MACHINE_R4000: "r4000", -- _IMAGE_FILE_MACHINE_SH3: "sh3", -- _IMAGE_FILE_MACHINE_SH3DSP: "sh3dsp", -- _IMAGE_FILE_MACHINE_SH4: "sh4", -- _IMAGE_FILE_MACHINE_SH5: "sh5", -- _IMAGE_FILE_MACHINE_THUMB: "thumb", -- _IMAGE_FILE_MACHINE_WCEMIPSV2: "wcemipsv2", -+ _IMAGE_FILE_MACHINE_UNKNOWN: "unknown", -+ _IMAGE_FILE_MACHINE_AM33: "am33", -+ _IMAGE_FILE_MACHINE_AMD64: "amd64", -+ _IMAGE_FILE_MACHINE_ARM: "arm", -+ _IMAGE_FILE_MACHINE_ARMNT: "armnt", -+ _IMAGE_FILE_MACHINE_ARM64: "arm64", -+ _IMAGE_FILE_MACHINE_LOONGARCH64: "loong64", -+ _IMAGE_FILE_MACHINE_EBC: "ebc", -+ _IMAGE_FILE_MACHINE_I386: "i386", -+ _IMAGE_FILE_MACHINE_IA64: "ia64", -+ _IMAGE_FILE_MACHINE_M32R: "m32r", -+ _IMAGE_FILE_MACHINE_MIPS16: "mips16", -+ _IMAGE_FILE_MACHINE_MIPSFPU: "mipsfpu", -+ _IMAGE_FILE_MACHINE_MIPSFPU16: "mipsfpu16", -+ _IMAGE_FILE_MACHINE_POWERPC: "powerpc", -+ _IMAGE_FILE_MACHINE_POWERPCFP: "powerpcfp", -+ _IMAGE_FILE_MACHINE_R4000: "r4000", -+ _IMAGE_FILE_MACHINE_SH3: "sh3", -+ _IMAGE_FILE_MACHINE_SH3DSP: "sh3dsp", -+ _IMAGE_FILE_MACHINE_SH4: "sh4", -+ _IMAGE_FILE_MACHINE_SH5: "sh5", -+ _IMAGE_FILE_MACHINE_THUMB: "thumb", -+ _IMAGE_FILE_MACHINE_WCEMIPSV2: "wcemipsv2", - } - - func (m _PEMachine) String() string { -diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go -index 8aedfaf..67547fa 100644 ---- a/pkg/proc/proc_test.go -+++ b/pkg/proc/proc_test.go -@@ -3362,6 +3362,7 @@ func TestCgoStacktrace(t *testing.T) { - skipOn(t, "broken - cgo stacktraces", "386") - skipOn(t, "broken - cgo stacktraces", "windows", "arm64") - skipOn(t, "broken - cgo stacktraces", "linux", "ppc64le") -+ skipOn(t, "broken - cgo stacktraces", "loong64") - if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 21) { - skipOn(t, "broken - cgo stacktraces", "windows", "arm64") - } -@@ -3467,7 +3468,7 @@ func TestCgoSources(t *testing.T) { - } - } - -- if runtime.GOARCH == "386" { -+ if runtime.GOARCH == "386" || runtime.GOARCH == "loong64" { - t.Skip("cgo stacktraces not supported on i386 for now") - } - -@@ -3545,6 +3546,7 @@ func TestSystemstackOnRuntimeNewstack(t *testing.T) { - - func TestIssue1034(t *testing.T) { - skipOn(t, "broken - cgo stacktraces", "386") -+ skipOn(t, "broken - cgo stacktraces", "loong64") - protest.MustHaveCgo(t) - - // The external linker on macOS produces an abbrev for DW_TAG_subprogram -@@ -3565,6 +3567,7 @@ func TestIssue1034(t *testing.T) { - - func TestIssue1008(t *testing.T) { - skipOn(t, "broken - cgo stacktraces", "386") -+ skipOn(t, "broken - cgo stacktraces", "loong64") - protest.MustHaveCgo(t) - - // The external linker on macOS inserts "end of sequence" extended opcodes -@@ -3750,6 +3753,7 @@ func TestHaltKeepsSteppingBreakpoints(t *testing.T) { - func TestDisassembleGlobalVars(t *testing.T) { - skipOn(t, "broken - global variable symbolication", "arm64") // On ARM64 symLookup can't look up variables due to how they are loaded, see issue #1778 - skipOn(t, "broken - global variable symbolication", "ppc64le") // See comment on ARM64 above. -+ skipOn(t, "broken - global variable symbolication", "loong64") - // On 386 linux when pie, the generated code use __x86.get_pc_thunk to ensure position-independent. - // Locate global variable by - // `CALL __x86.get_pc_thunk.ax(SB) 0xb0f7f -@@ -4097,6 +4101,7 @@ func TestIssue951(t *testing.T) { - - func TestDWZCompression(t *testing.T) { - skipOn(t, "broken", "ppc64le") -+ skipOn(t, "broken", "loong64") - // If dwz is not available in the system, skip this test - if _, err := exec.LookPath("dwz"); err != nil { - t.Skip("dwz not installed") -@@ -4659,6 +4664,7 @@ func TestCgoStacktrace2(t *testing.T) { - skipOn(t, "broken", "386") - skipOn(t, "broken - cgo stacktraces", "darwin", "arm64") - skipOn(t, "broken", "ppc64le") -+ skipOn(t, "broken", "loong64") - protest.MustHaveCgo(t) - // If a panic happens during cgo execution the stacktrace should show the C - // function that caused the problem. -@@ -5394,6 +5400,7 @@ func TestWatchpointsBasic(t *testing.T) { - skipOn(t, "not implemented", "freebsd") - skipOn(t, "not implemented", "386") - skipOn(t, "not implemented", "ppc64le") -+ skipOn(t, "not implemented", "loong64") - skipOn(t, "see https://github.com/go-delve/delve/issues/2768", "windows") - protest.AllowRecording(t) - -@@ -5456,6 +5463,7 @@ func TestWatchpointCounts(t *testing.T) { - skipOn(t, "see https://github.com/go-delve/delve/issues/2768", "windows") - skipOn(t, "not implemented", "ppc64le") - skipOn(t, "fails on CI", "arm64") -+ skipOn(t, "not implemented", "loong64") - protest.AllowRecording(t) - - withTestProcess("databpcountstest", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { -@@ -5572,6 +5580,7 @@ func TestWatchpointStack(t *testing.T) { - skipOn(t, "not implemented", "386") - skipOn(t, "not implemented", "ppc64le") - skipOn(t, "see https://github.com/go-delve/delve/issues/2768", "windows") -+ skipOn(t, "not implemented", "loong64") - protest.AllowRecording(t) - - position1 := 17 -@@ -5730,6 +5739,8 @@ func TestNilPtrDerefInBreakInstr(t *testing.T) { - asmfile = "main_386.s" - case "ppc64le": - asmfile = "main_ppc64le.s" -+ case "loong64": -+ asmfile = "main_loong64.s" - default: - t.Fatalf("assembly file for %s not provided", runtime.GOARCH) - } -diff --git a/pkg/proc/stack.go b/pkg/proc/stack.go -index 55034eb..7bb4dd5 100644 ---- a/pkg/proc/stack.go -+++ b/pkg/proc/stack.go -@@ -284,7 +284,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" || it.bi.Arch.Name == "ppc64le" { -+ if it.bi.Arch.Name == "arm64" || it.bi.Arch.Name == "ppc64le" || it.bi.Arch.Name == "loong64" { - it.regs.Reg(it.regs.LRRegNum).Uint64Val = it.g.LR - } - } -@@ -523,7 +523,7 @@ func (it *stackIterator) advanceRegs() (callFrameRegs op.DwarfRegisters, ret uin - } - } - -- if it.bi.Arch.Name == "arm64" || it.bi.Arch.Name == "ppc64le" { -+ if it.bi.Arch.Name == "arm64" || it.bi.Arch.Name == "ppc64le" || it.bi.Arch.Name == "loong64" { - if ret == 0 && it.regs.Reg(it.regs.LRRegNum) != nil { - ret = it.regs.Reg(it.regs.LRRegNum).Uint64Val - } -diff --git a/pkg/proc/test/support.go b/pkg/proc/test/support.go -index f1d2ae6..b21c4f7 100644 ---- a/pkg/proc/test/support.go -+++ b/pkg/proc/test/support.go -@@ -310,6 +310,9 @@ func MustSupportFunctionCalls(t *testing.T, testBackend string) { - if runtime.GOARCH == "386" { - t.Skip(fmt.Errorf("%s does not support FunctionCall for now", runtime.GOARCH)) - } -+ if runtime.GOARCH == "loong64" { -+ t.Skip(fmt.Errorf("%s does not support FunctionCall for now", runtime.GOARCH)) -+ } - if runtime.GOARCH == "arm64" { - if !goversion.VersionAfterOrEqual(runtime.Version(), 1, 19) || runtime.GOOS == "windows" { - t.Skip("this version of Go does not support function calls") -diff --git a/pkg/terminal/command_test.go b/pkg/terminal/command_test.go -index 8b535d0..021947a 100644 ---- a/pkg/terminal/command_test.go -+++ b/pkg/terminal/command_test.go -@@ -1411,6 +1411,9 @@ func TestDisassPosCmd(t *testing.T) { - if runtime.GOARCH == "ppc64le" && buildMode == "pie" { - t.Skip("pie mode broken on ppc64le") - } -+ if runtime.GOARCH == "loong64" { -+ t.Skip("disassemble to plan9 nosupported on loong64 for now") -+ } - withTestTerminal("testvariables2", t, func(term *FakeTerminal) { - term.MustExec("continue") - out := term.MustExec("step-instruction") -diff --git a/service/dap/server_test.go b/service/dap/server_test.go -index f82fc76..d965a0f 100644 ---- a/service/dap/server_test.go -+++ b/service/dap/server_test.go -@@ -2717,7 +2717,7 @@ func findPcReg(regs []dap.Variable) int { - } - - func isPcReg(reg dap.Variable) bool { -- pcRegNames := []string{"rip", "pc", "eip"} -+ pcRegNames := []string{"rip", "pc", "eip", "era"} - for _, name := range pcRegNames { - if name == strings.TrimSpace(reg.Name) { - return true -diff --git a/service/debugger/debugger_test.go b/service/debugger/debugger_test.go -index c493ff9..fbddee8 100644 ---- a/service/debugger/debugger_test.go -+++ b/service/debugger/debugger_test.go -@@ -49,6 +49,9 @@ func TestDebugger_LaunchInvalidFormat(t *testing.T) { - if runtime.GOARCH == "ppc64le" && runtime.GOOS == "linux" { - t.Setenv("GOARCH", "amd64") - } -+ if runtime.GOARCH == "loong64" && runtime.GOOS == "linux" { -+ os.Setenv("GOARCH", "amd64") -+ } - t.Setenv("GOOS", switchOS[runtime.GOOS]) - exepath := filepath.Join(buildtestdir, debugname) - if err := gobuild.GoBuild(debugname, []string{buildtestdir}, fmt.Sprintf("-o %s", exepath)); err != nil { -diff --git a/service/debugger/debugger_unix_test.go b/service/debugger/debugger_unix_test.go -index df31e16..147f6e0 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 == "ppc64le" && runtime.GOOS == "linux" { - t.Setenv("GOARCH", "amd64") - } -+ if runtime.GOARCH == "loong64" && runtime.GOOS == "linux" { -+ os.Setenv("GOARCH", "amd64") -+ } - t.Setenv("GOOS", switchOS[runtime.GOOS]) - exepath := filepath.Join(buildtestdir, debugname) - defer os.Remove(exepath) -diff --git a/service/test/integration1_test.go b/service/test/integration1_test.go -index 80a6819..8d63fad 100644 ---- a/service/test/integration1_test.go -+++ b/service/test/integration1_test.go -@@ -910,7 +910,7 @@ func Test1Disasm(t *testing.T) { - // look for static call to afunction() on line 29 - found := false - for i := range d3 { -- if d3[i].Loc.Line == 29 && (strings.HasPrefix(d3[i].Text, "call") || strings.HasPrefix(d3[i].Text, "CALL")) && d3[i].DestLoc != nil && d3[i].DestLoc.Function != nil && d3[i].DestLoc.Function.Name() == "main.afunction" { -+ if d3[i].Loc.Line == 29 && (strings.HasPrefix(d3[i].Text, "call") || strings.HasPrefix(d3[i].Text, "CALL") || strings.HasPrefix(d3[i].Text, "bl")) && d3[i].DestLoc != nil && d3[i].DestLoc.Function != nil && d3[i].DestLoc.Function.Name() == "main.afunction" { - found = true - break - } -@@ -960,7 +960,7 @@ func Test1Disasm(t *testing.T) { - t.Fatal("Calling StepInstruction() repeatedly did not find the call instruction") - } - -- if strings.HasPrefix(curinstr.Text, "call") || strings.HasPrefix(curinstr.Text, "CALL") { -+ if strings.HasPrefix(curinstr.Text, "call") || strings.HasPrefix(curinstr.Text, "CALL") || strings.HasPrefix(curinstr.Text, "jirl") || strings.HasPrefix(curinstr.Text, "bl") { - t.Logf("call: %v", curinstr) - if curinstr.DestLoc == nil || curinstr.DestLoc.Function == nil { - t.Fatalf("Call instruction does not have destination: %v", curinstr) -diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go -index 7ab9665..3b6d78b 100644 ---- a/service/test/integration2_test.go -+++ b/service/test/integration2_test.go -@@ -1418,7 +1418,7 @@ func TestDisasm(t *testing.T) { - // look for static call to afunction() on line 29 - found := false - for i := range d3 { -- if d3[i].Loc.Line == 29 && (strings.HasPrefix(d3[i].Text, "call") || strings.HasPrefix(d3[i].Text, "CALL")) && d3[i].DestLoc != nil && d3[i].DestLoc.Function != nil && d3[i].DestLoc.Function.Name() == "main.afunction" { -+ if d3[i].Loc.Line == 29 && (strings.HasPrefix(d3[i].Text, "bl") || strings.HasPrefix(d3[i].Text, "jirl") || strings.HasPrefix(d3[i].Text, "call") || strings.HasPrefix(d3[i].Text, "CALL")) && d3[i].DestLoc != nil && d3[i].DestLoc.Function != nil && d3[i].DestLoc.Function.Name() == "main.afunction" { - found = true - break - } -@@ -1468,7 +1468,7 @@ func TestDisasm(t *testing.T) { - t.Fatal("Calling StepInstruction() repeatedly did not find the call instruction") - } - -- if strings.HasPrefix(curinstr.Text, "call") || strings.HasPrefix(curinstr.Text, "CALL") { -+ if strings.HasPrefix(curinstr.Text, "call") || strings.HasPrefix(curinstr.Text, "CALL") || strings.HasPrefix(curinstr.Text, "bl") || strings.HasPrefix(curinstr.Text, "jirl") { - t.Logf("call: %v", curinstr) - if curinstr.DestLoc == nil || curinstr.DestLoc.Function == nil { - t.Fatalf("Call instruction does not have destination: %v", curinstr) --- -2.20.1 - diff --git a/0004-all-update-golang.org-x-arch-to-9a59f1d32eedbf89830e.patch b/0004-all-update-golang.org-x-arch-to-9a59f1d32eedbf89830e.patch deleted file mode 100644 index cc67bb6ba2c5cdb2ff5755f29b8aa473b38dc09b..0000000000000000000000000000000000000000 --- a/0004-all-update-golang.org-x-arch-to-9a59f1d32eedbf89830e.patch +++ /dev/null @@ -1,1127 +0,0 @@ -From d0e50c2179cccf6ed87c3da69e72418b33cefbf5 Mon Sep 17 00:00:00 2001 -From: Huang Qiqi -Date: Wed, 20 Dec 2023 16:04:04 +0800 -Subject: [PATCH 4/7] all: update golang.org/x/arch to - 9a59f1d32eedbf89830e7b3039df8420139a89a6 - -go get -d golang.org/x/arch@9a59f1d32eedbf89830e7b3039df8420139a89a6 -go mod tidy -go mod vendor - -Change-Id: I09e15ae78e54588d73e03f89d402acfb32cf8bbd ---- - .../x/arch/loong64/loong64asm/arg.go | 2 +- - .../x/arch/loong64/loong64asm/decode.go | 22 +- - .../x/arch/loong64/loong64asm/ext_test.go | 402 ---------------- - .../x/arch/loong64/loong64asm/gnu.go | 2 +- - .../x/arch/loong64/loong64asm/inst.go | 84 ++-- - .../x/arch/loong64/loong64asm/plan9x.go | 437 ++++++++++++++++++ - .../x/arch/loong64/loong64asm/tables.go | 5 +- - 7 files changed, 498 insertions(+), 456 deletions(-) - delete mode 100644 vendor/golang.org/x/arch/loong64/loong64asm/ext_test.go - create mode 100644 vendor/golang.org/x/arch/loong64/loong64asm/plan9x.go - -diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/arg.go b/vendor/golang.org/x/arch/loong64/loong64asm/arg.go -index 9496e8c..88d2fa4 100644 ---- a/vendor/golang.org/x/arch/loong64/loong64asm/arg.go -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/arg.go -@@ -1,4 +1,4 @@ --// Copyright 2022 The Go Authors. All rights reserved. -+// Copyright 2023 The Go Authors. All rights reserved. - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. - -diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/decode.go b/vendor/golang.org/x/arch/loong64/loong64asm/decode.go -index ac3448f..43a482c 100644 ---- a/vendor/golang.org/x/arch/loong64/loong64asm/decode.go -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/decode.go -@@ -1,4 +1,4 @@ --// Copyright 2022 The Go Authors. All rights reserved. -+// Copyright 2023 The Go Authors. All rights reserved. - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. - -@@ -173,12 +173,12 @@ func decodeArg(aop instArg, x uint32, index int) Arg { - return Uimm{tmp, false} - - case arg_hint_4_0: -- tmp := int16(x & ((1 << 5) - 1)) -- return Simm16{tmp, 4} -+ tmp := x & ((1 << 5) - 1) -+ return Uimm{tmp, false} - - case arg_hint_14_0: -- tmp := int16(x & ((1 << 15) - 1)) -- return Simm16{tmp, 15} -+ tmp := x & ((1 << 15) - 1) -+ return Uimm{tmp, false} - - case arg_level_14_0: - tmp := x & ((1 << 15) - 1) -@@ -210,7 +210,7 @@ func decodeArg(aop instArg, x uint32, index int) Arg { - } else { - tmp = int32((((x >> 10) & ((1 << 14) - 1)) << 2) | 0x00000000) - } -- return Simm32{tmp, 16} -+ return Simm32{tmp, 14} - - case arg_si16_25_10: - var tmp int32 -@@ -235,13 +235,13 @@ func decodeArg(aop instArg, x uint32, index int) Arg { - case arg_offset_20_0: - var tmp int32 - -- if (x & 0x1000000) == 0x1000000 { -- tmp = int32((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 21) - 1)) << 2) -+ if (x & 0x10) == 0x10 { -+ tmp = int32(((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 21) - 1)) << 2) | 0xff800000) - } else { - tmp = int32((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 21) - 1)) << 2) - } - -- return OffsetSimm{tmp, 28} -+ return OffsetSimm{tmp, 21} - - case arg_offset_15_0: - var tmp int32 -@@ -251,7 +251,7 @@ func decodeArg(aop instArg, x uint32, index int) Arg { - tmp = int32((((x >> 10) & ((1 << 16) - 1)) << 2) | 0x00000000) - } - -- return OffsetSimm{tmp, 18} -+ return OffsetSimm{tmp, 16} - - case arg_offset_25_0: - var tmp int32 -@@ -262,7 +262,7 @@ func decodeArg(aop instArg, x uint32, index int) Arg { - tmp = int32(((((x << 16) | ((x >> 10) & ((1 << 16) - 1))) & ((1 << 26) - 1)) << 2) | 0x00000000) - } - -- return OffsetSimm{tmp, 28} -+ return OffsetSimm{tmp, 26} - default: - return nil - } -diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/ext_test.go b/vendor/golang.org/x/arch/loong64/loong64asm/ext_test.go -deleted file mode 100644 -index c79552c..0000000 ---- a/vendor/golang.org/x/arch/loong64/loong64asm/ext_test.go -+++ /dev/null -@@ -1,402 +0,0 @@ --// Copyright 2022 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. -- --// Support for testing against external disassembler program. -- --package loong64asm -- --import ( -- "bufio" -- "bytes" -- "encoding/hex" -- "flag" -- "fmt" -- "io" -- "io/ioutil" -- "log" -- "math/rand" -- "os" -- "os/exec" -- "path/filepath" -- "strings" -- "testing" -- "time" --) -- --var ( -- dumpTest = flag.Bool("dump", false, "dump all encodings") -- mismatch = flag.Bool("mismatch", false, "log allowed mismatches") -- keep = flag.Bool("keep", false, "keep object files around") -- debug = false --) -- --// An ExtInst represents a single decoded instruction parsed --// from an external disassembler's output. --type ExtInst struct { -- addr uint64 -- enc [4]byte -- nenc int -- text string --} -- --func (r ExtInst) String() string { -- return fmt.Sprintf("%#x: % x: %s", r.addr, r.enc, r.text) --} -- --// An ExtDis is a connection between an external disassembler and a test. --type ExtDis struct { -- Dec chan ExtInst -- File *os.File -- Size int -- Cmd *exec.Cmd --} -- --// Run runs the given command - the external disassembler - and returns --// a buffered reader of its standard output. --func (ext *ExtDis) Run(cmd ...string) (*bufio.Reader, error) { -- if *keep { -- log.Printf("%s\n", strings.Join(cmd, " ")) -- } -- ext.Cmd = exec.Command(cmd[0], cmd[1:]...) -- out, err := ext.Cmd.StdoutPipe() -- if err != nil { -- return nil, fmt.Errorf("stdoutpipe: %v", err) -- } -- if err := ext.Cmd.Start(); err != nil { -- return nil, fmt.Errorf("exec: %v", err) -- } -- -- b := bufio.NewReaderSize(out, 1<<20) -- return b, nil --} -- --// Wait waits for the command started with Run to exit. --func (ext *ExtDis) Wait() error { -- return ext.Cmd.Wait() --} -- --// testExtDis tests a set of byte sequences against an external disassembler. --// The disassembler is expected to produce the given syntax and run --// in the given architecture mode (16, 32, or 64-bit). --// The extdis function must start the external disassembler --// and then parse its output, sending the parsed instructions on ext.Dec. --// The generate function calls its argument f once for each byte sequence --// to be tested. The generate function itself will be called twice, and it must --// make the same sequence of calls to f each time. --// When a disassembly does not match the internal decoding, --// allowedMismatch determines whether this mismatch should be --// allowed, or else considered an error. --func testExtDis( -- t *testing.T, -- syntax string, -- extdis func(ext *ExtDis) error, -- generate func(f func([]byte)), -- allowedMismatch func(text string, inst *Inst, dec ExtInst) bool, --) { -- start := time.Now() -- ext := &ExtDis{ -- Dec: make(chan ExtInst), -- } -- errc := make(chan error) -- -- // First pass: write instructions to input file for external disassembler. -- file, f, size, err := writeInst(generate) -- if err != nil { -- t.Fatal(err) -- } -- ext.Size = size -- ext.File = f -- defer func() { -- f.Close() -- if !*keep { -- os.Remove(file) -- } -- }() -- -- // Second pass: compare disassembly against our decodings. -- var ( -- totalTests = 0 -- totalSkips = 0 -- totalErrors = 0 -- -- errors = make([]string, 0, 100) // Sampled errors, at most cap -- ) -- go func() { -- errc <- extdis(ext) -- }() -- -- generate(func(enc []byte) { -- dec, ok := <-ext.Dec -- if !ok { -- t.Errorf("decoding stream ended early") -- return -- } -- inst, text := disasm(syntax, pad(enc)) -- -- totalTests++ -- if *dumpTest { -- fmt.Printf("%x -> %s [%d]\n", enc[:len(enc)], dec.text, dec.nenc) -- } -- -- if text != dec.text && !strings.Contains(dec.text, "unknown") && syntax == "gnu" { -- suffix := "" -- if allowedMismatch(text, &inst, dec) { -- totalSkips++ -- if !*mismatch { -- return -- } -- suffix += " (allowed mismatch)" -- } -- totalErrors++ -- cmp := fmt.Sprintf("decode(%x) = %q, %d, want %q, %d%s\n", enc, text, len(enc), dec.text, dec.nenc, suffix) -- -- if len(errors) >= cap(errors) { -- j := rand.Intn(totalErrors) -- if j >= cap(errors) { -- return -- } -- errors = append(errors[:j], errors[j+1:]...) -- } -- errors = append(errors, cmp) -- } -- }) -- -- if *mismatch { -- totalErrors -= totalSkips -- } -- -- fmt.Printf("totalTest: %d total skip: %d total error: %d\n", totalTests, totalSkips, totalErrors) -- // Here are some errors about mismatches(44) -- // for _, b := range errors { -- // t.Log(b) -- // } -- -- if totalErrors > 0 { -- t.Fail() -- } -- t.Logf("%d test cases, %d expected mismatches, %d failures; %.0f cases/second", totalTests, totalSkips, totalErrors, float64(totalTests)/time.Since(start).Seconds()) -- t.Logf("decoder coverage: %.1f%%;\n", decodeCoverage()) --} -- --// Start address of text. --const start = 0x8000 -- --// writeInst writes the generated byte sequences to a new file --// starting at offset start. That file is intended to be the input to --// the external disassembler. --func writeInst(generate func(func([]byte))) (file string, f *os.File, size int, err error) { -- f, err = ioutil.TempFile("", "loong64asm") -- if err != nil { -- return -- } -- -- file = f.Name() -- -- f.Seek(start, io.SeekStart) -- w := bufio.NewWriter(f) -- defer w.Flush() -- size = 0 -- generate(func(x []byte) { -- if debug { -- fmt.Printf("%#x: %x%x\n", start+size, x, zeros[len(x):]) -- } -- w.Write(x) -- w.Write(zeros[len(x):]) -- size += len(zeros) -- }) -- return file, f, size, nil --} -- --var zeros = []byte{0, 0, 0, 0} -- --// pad pads the code sequence with pops. --func pad(enc []byte) []byte { -- if len(enc) < 4 { -- enc = append(enc[:len(enc):len(enc)], zeros[:4-len(enc)]...) -- } -- return enc --} -- --// disasm returns the decoded instruction and text --// for the given source bytes, using the given syntax and mode. --func disasm(syntax string, src []byte) (inst Inst, text string) { -- var err error -- inst, err = Decode(src) -- if err != nil { -- text = "error: " + err.Error() -- return -- } -- text = inst.String() -- switch syntax { -- case "gnu": -- text = GNUSyntax(inst) -- default: -- text = "error: unknown syntax " + syntax -- } -- return --} -- --// decodecoverage returns a floating point number denoting the --// decoder coverage. --func decodeCoverage() float64 { -- n := 0 -- for _, t := range decoderCover { -- if t { -- n++ -- } -- } -- return 100 * float64(1+n) / float64(1+len(decoderCover)) --} -- --// Helpers for writing disassembler output parsers. -- --// isHex reports whether b is a hexadecimal character (0-9a-fA-F). --func isHex(b byte) bool { -- return ('0' <= b && b <= '9') || ('a' <= b && b <= 'f') || ('A' <= b && b <= 'F') --} -- --// parseHex parses the hexadecimal byte dump in hex, --// appending the parsed bytes to raw and returning the updated slice. --// The returned bool reports whether any invalid hex was found. --// Spaces and tabs between bytes are okay but any other non-hex is not. --func parseHex(hex []byte, raw []byte) ([]byte, bool) { -- hex = bytes.TrimSpace(hex) -- for j := 0; j < len(hex); { -- for hex[j] == ' ' || hex[j] == '\t' { -- j++ -- } -- if j >= len(hex) { -- break -- } -- if j+2 > len(hex) || !isHex(hex[j]) || !isHex(hex[j+1]) { -- return nil, false -- } -- raw = append(raw, unhex(hex[j])<<4|unhex(hex[j+1])) -- j += 2 -- } -- return raw, true --} -- --func unhex(b byte) byte { -- if '0' <= b && b <= '9' { -- return b - '0' -- } else if 'A' <= b && b <= 'F' { -- return b - 'A' + 10 -- } else if 'a' <= b && b <= 'f' { -- return b - 'a' + 10 -- } -- return 0 --} -- --// index is like bytes.Index(s, []byte(t)) but avoids the allocation. --func index(s []byte, t string) int { -- i := 0 -- for { -- j := bytes.IndexByte(s[i:], t[0]) -- if j < 0 { -- return -1 -- } -- i = i + j -- if i+len(t) > len(s) { -- return -1 -- } -- for k := 1; k < len(t); k++ { -- if s[i+k] != t[k] { -- goto nomatch -- } -- } -- return i -- nomatch: -- i++ -- } --} -- --// fixSpace rewrites runs of spaces, tabs, and newline characters into single spaces in s. --// If s must be rewritten, it is rewritten in place. --func fixSpace(s []byte) []byte { -- s = bytes.TrimSpace(s) -- for i := 0; i < len(s); i++ { -- if s[i] == '\t' || s[i] == '\n' || i > 0 && s[i] == ' ' && s[i-1] == ' ' { -- goto Fix -- } -- } -- return s -- --Fix: -- b := s -- w := 0 -- for i := 0; i < len(s); i++ { -- c := s[i] -- if c == '\t' || c == '\n' { -- c = ' ' -- } -- if c == ' ' && w > 0 && b[w-1] == ' ' { -- continue -- } -- b[w] = c -- w++ -- } -- if w > 0 && b[w-1] == ' ' { -- w-- -- } -- return b[:w] --} -- --// Generators. --// --// The test cases are described as functions that invoke a callback repeatedly, --// with a new input sequence each time. These helpers make writing those --// a little easier. -- --// hexCases generates the cases written in hexadecimal in the encoded string. --// Spaces in 'encoded' separate entire test cases, not individual bytes. --func hexCases(t *testing.T, encoded string) func(func([]byte)) { -- return func(try func([]byte)) { -- for _, x := range strings.Fields(encoded) { -- src, err := hex.DecodeString(x) -- if err != nil { -- t.Errorf("parsing %q: %v", x, err) -- } -- try(src) -- } -- } --} -- --// testdataCases generates the test cases recorded in testdata/cases.txt. --// It only uses the inputs; it ignores the answers recorded in that file. --func testdataCases(t *testing.T, syntax string) func(func([]byte)) { -- var codes [][]byte -- input := filepath.Join("testdata", syntax+"cases.txt") -- data, err := ioutil.ReadFile(input) -- if err != nil { -- t.Fatal(err) -- } -- for _, line := range strings.Split(string(data), "\n") { -- line = strings.TrimSpace(line) -- if line == "" || strings.HasPrefix(line, "#") { -- continue -- } -- f := strings.Fields(line)[0] -- i := strings.Index(f, "|") -- if i < 0 { -- t.Errorf("parsing %q: missing | separator", f) -- continue -- } -- if i%2 != 0 { -- t.Errorf("parsing %q: misaligned | separator", f) -- } -- code, err := hex.DecodeString(f[:i] + f[i+1:]) -- if err != nil { -- t.Errorf("parsing %q: %v", f, err) -- continue -- } -- codes = append(codes, code) -- } -- -- return func(try func([]byte)) { -- for _, code := range codes { -- try(code) -- } -- } --} -diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go b/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go -index fd6bcff..de094cf 100644 ---- a/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/gnu.go -@@ -1,4 +1,4 @@ --// Copyright 2022 The Go Authors. All rights reserved. -+// Copyright 2023 The Go Authors. All rights reserved. - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. - -diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/inst.go b/vendor/golang.org/x/arch/loong64/loong64asm/inst.go -index 187a46f..1553129 100644 ---- a/vendor/golang.org/x/arch/loong64/loong64asm/inst.go -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/inst.go -@@ -1,4 +1,4 @@ --// Copyright 2022 The Go Authors. All rights reserved. -+// Copyright 2023 The Go Authors. All rights reserved. - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. - -@@ -6,9 +6,7 @@ package loong64asm - - import ( - "fmt" -- "strconv" - "strings" -- "unsafe" - ) - - // An Inst is a single instruction. -@@ -19,23 +17,56 @@ type Inst struct { - } - - func (i Inst) String() string { -+ var op string = i.Op.String() - var args []string - - for _, arg := range i.Args { - if arg == nil { - break - } -- - args = append(args, arg.String()) - } - -- str2 := strings.Join(args, ", ") -- if str2 == "" { -- str := i.Op.String() -- return strings.Replace(str, ", (", "(", -1) -+ switch i.Op { -+ case OR: -+ if i.Args[2].(Reg) == R0 { -+ op = "move" -+ args = args[0:2] -+ } -+ -+ case ANDI: -+ if i.Args[0].(Reg) == R0 && i.Args[1].(Reg) == R0 { -+ return "nop" -+ } -+ -+ case JIRL: -+ if i.Args[0].(Reg) == R0 && i.Args[2].(OffsetSimm).Imm == 0 { -+ return "jr " + args[1] -+ } -+ -+ case BLT: -+ if i.Args[0].(Reg) == R0 { -+ op = "bgtz" -+ args = args[1:] -+ } else if i.Args[1].(Reg) == R0 { -+ op = "bltz" -+ args = append(args[:1], args[2:]...) -+ } -+ -+ case BGE: -+ if i.Args[0].(Reg) == R0 { -+ op = "blez" -+ args = args[1:] -+ } else if i.Args[1].(Reg) == R0 { -+ op = "bgez" -+ args = append(args[:1], args[2:]...) -+ } -+ } -+ -+ if len(args) == 0 { -+ return op - } else { -- str := i.Op.String() + " " + strings.Join(args, ", ") -- return strings.Replace(str, ", (", "(", -1) -+ return op + " " + strings.Join(args, ", ") - } - } - -@@ -195,14 +226,7 @@ const ( - ) - - func (f Fcsr) String() string { -- switch f { -- case FCSR0: -- return fmt.Sprintf("$zero") -- case FCSR1, FCSR2, FCSR3: -- return fmt.Sprintf("$r%d", uint8(f)) -- } -- -- return fmt.Sprintf("$unknow%d", uint8(f)) -+ return fmt.Sprintf("$fcsr%d", uint8(f)) - } - - // float condition flags register -@@ -244,13 +268,7 @@ type Simm16 struct { - } - - func (si Simm16) String() string { -- if si.Imm == 0 { -- return fmt.Sprintf("%#x", int(si.Imm)) -- } else { -- hex := int16(si.Imm & ((1 << si.Width) - 1)) -- str := strconv.FormatUint(uint64(*(*int16)(unsafe.Pointer(&hex))), 16) -- return fmt.Sprintf("%d(0x%s)", int16(si.Imm), str) -- } -+ return fmt.Sprintf("%d", int32(si.Imm)) - } - - type Simm32 struct { -@@ -259,13 +277,7 @@ type Simm32 struct { - } - - func (si Simm32) String() string { -- if si.Imm == 0 { -- return fmt.Sprintf("%#x", int(si.Imm)) -- } else { -- hex := int32(si.Imm & ((1 << si.Width) - 1)) -- str := strconv.FormatUint(uint64(*(*int32)(unsafe.Pointer(&hex))), 16) -- return fmt.Sprintf("%d(0x%s)", int32(si.Imm), str) -- } -+ return fmt.Sprintf("%d", int32(si.Imm)) - } - - type OffsetSimm struct { -@@ -274,13 +286,7 @@ type OffsetSimm struct { - } - - func (o OffsetSimm) String() string { -- if o.Imm == 0 { -- return fmt.Sprintf("%#x", int(o.Imm)) -- } else { -- hex := int32(o.Imm & ((1 << o.Width) - 1)) -- str := strconv.FormatUint(uint64(*(*int32)(unsafe.Pointer(&hex))), 16) -- return fmt.Sprintf("%d(0x%s)", int32(o.Imm), str) -- } -+ return fmt.Sprintf("%d", int32(o.Imm)) - } - - type SaSimm int16 -diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/plan9x.go b/vendor/golang.org/x/arch/loong64/loong64asm/plan9x.go -new file mode 100644 -index 0000000..0ee56a4 ---- /dev/null -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/plan9x.go -@@ -0,0 +1,437 @@ -+// Copyright 2020 The Go Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style -+// license that can be found in the LICENSE file. -+ -+package loong64asm -+ -+import ( -+ "fmt" -+ "strings" -+) -+ -+// GoSyntax returns the Go assembler syntax for the instruction. -+// The syntax was originally defined by Plan 9. -+// The pc is the program counter of the instruction, used for -+// expanding PC-relative addresses into absolute ones. -+// The symname function queries the symbol table for the program -+// being disassembled. Given a target address it returns the name -+// and base address of the symbol containing the target, if any; -+// otherwise it returns "", 0. -+func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) string { -+ if symname == nil { -+ symname = func(uint64) (string, uint64) { return "", 0 } -+ } -+ if inst.Op == 0 && inst.Enc == 0 { -+ return "WORD $0" -+ } else if inst.Op == 0 { -+ return "?" -+ } -+ -+ var args []string -+ for _, a := range inst.Args { -+ if a == nil { -+ break -+ } -+ args = append(args, plan9Arg(&inst, pc, symname, a)) -+ } -+ -+ var op string = plan9OpMap[inst.Op] -+ if op == "" { -+ op = "Unknown " + inst.Op.String() -+ } -+ -+ switch inst.Op { -+ case BSTRPICK_D: -+ msbw, lsbw := inst.Args[2].(Uimm), inst.Args[3].(Uimm) -+ if msbw.Imm == 15 && lsbw.Imm == 0 { -+ op = "MOVHU" -+ } else if msbw.Imm == 31 && lsbw.Imm == 0 { -+ op = "MOVWU" -+ } -+ args = append(args[1:2], args[0:1]...) -+ -+ case BCNEZ, BCEQZ: -+ args = args[1:2] -+ -+ case BEQ, BNE: -+ rj := inst.Args[0].(Reg) -+ rd := inst.Args[1].(Reg) -+ if rj == rd && inst.Op == BEQ { -+ op = "JMP" -+ args = args[2:] -+ } else if rj == R0 { -+ args = args[1:] -+ } else if rd == R0 { -+ args = append(args[:1], args[2:]...) -+ } -+ -+ case BEQZ, BNEZ: -+ if inst.Args[0].(Reg) == R0 && inst.Op == BEQ { -+ op = "JMP" -+ args = args[1:] -+ } -+ -+ case BLT, BLTU, BGE, BGEU: -+ rj := inst.Args[0].(Reg) -+ rd := inst.Args[1].(Reg) -+ if rj == rd && (inst.Op == BGE || inst.Op == BGEU) { -+ op = "JMP" -+ args = args[2:] -+ } else if rj == R0 { -+ switch inst.Op { -+ case BGE: -+ op = "BLEZ" -+ case BLT: -+ op = "BGTZ" -+ } -+ args = args[1:] -+ } else if rd == R0 { -+ if !strings.HasSuffix(op, "U") { -+ op += "Z" -+ } -+ args = append(args[:1], args[2:]...) -+ } -+ -+ case JIRL: -+ rd := inst.Args[0].(Reg) -+ rj := inst.Args[1].(Reg) -+ regno := uint16(rj) & 31 -+ if rd == R0 { -+ return fmt.Sprintf("JMP (R%d)", regno) -+ } -+ return fmt.Sprintf("CALL (R%d)", regno) -+ -+ case LD_B, LD_H, LD_W, LD_D, LD_BU, LD_HU, LD_WU, LL_W, LL_D, -+ ST_B, ST_H, ST_W, ST_D, SC_W, SC_D, FLD_S, FLD_D, FST_S, FST_D: -+ var off int32 -+ switch a := inst.Args[2].(type) { -+ case Simm16: -+ off = signumConvInt32(int32(a.Imm), a.Width) -+ case Simm32: -+ off = signumConvInt32(int32(a.Imm), a.Width) >> 2 -+ } -+ Iop := strings.ToUpper(inst.Op.String()) -+ if strings.HasPrefix(Iop, "L") || strings.HasPrefix(Iop, "FL") { -+ return fmt.Sprintf("%s %d(%s), %s", op, off, args[1], args[0]) -+ } -+ return fmt.Sprintf("%s %s, %d(%s)", op, args[0], off, args[1]) -+ -+ case CACOP: -+ code := inst.Args[0].(CodeSimm) -+ si12 := inst.Args[2].(Simm16) -+ off := signumConvInt32(int32(si12.Imm), si12.Width) -+ return fmt.Sprintf("%s R%d, %d(%s)", op, code, off, args[1]) -+ -+ default: -+ // Reverse args, placing dest last -+ for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 { -+ args[i], args[j] = args[j], args[i] -+ } -+ switch len(args) { -+ case 0, 1: -+ if inst.Op != B && inst.Op != BL { -+ return op -+ } -+ -+ case 3: -+ switch a0 := inst.Args[0].(type) { -+ case Reg: -+ rj := inst.Args[1].(Reg) -+ if a0 == rj && a0 != R0 { -+ args = args[0:2] -+ } -+ case Fcc: -+ args = args[0:2] -+ } -+ switch inst.Op { -+ case SUB_W, SUB_D, ADDI_W, ADDI_D, ORI: -+ rj := inst.Args[1].(Reg) -+ if rj == R0 { -+ args = append(args[0:1], args[2:]...) -+ if inst.Op == SUB_W { -+ op = "NEGW" -+ } else if inst.Op == SUB_D { -+ op = "NEGV" -+ } else { -+ op = "MOVW" -+ } -+ } -+ -+ case ANDI: -+ ui12 := inst.Args[2].(Uimm) -+ if ui12.Imm == uint32(0xff) { -+ op = "MOVBU" -+ args = args[1:] -+ } else if ui12.Imm == 0 && inst.Args[0].(Reg) == R0 && inst.Args[1].(Reg) == R0 { -+ return "NOOP" -+ } -+ -+ case SLL_W, OR: -+ rk := inst.Args[2].(Reg) -+ if rk == R0 { -+ args = args[1:] -+ if inst.Op == SLL_W { -+ op = "MOVW" -+ } else { -+ op = "MOVV" -+ } -+ } -+ } -+ } -+ } -+ -+ if args != nil { -+ op += " " + strings.Join(args, ", ") -+ } -+ return op -+} -+ -+func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string { -+ // Reg: gpr[0, 31] and fpr[0, 31] -+ // Fcsr: fcsr[0, 3] -+ // Fcc: fcc[0, 7] -+ // Uimm: unsigned integer constant -+ // Simm16: si16 -+ // Simm32: si32 -+ // OffsetSimm: si32 -+ switch a := arg.(type) { -+ case Reg: -+ regenum := uint16(a) -+ regno := uint16(a) & 0x1f -+ // General-purpose register -+ if regenum >= uint16(R0) && regenum <= uint16(R31) { -+ return fmt.Sprintf("R%d", regno) -+ } else { // Float point register -+ return fmt.Sprintf("F%d", regno) -+ } -+ -+ case Fcsr: -+ regno := uint8(a) & 0x1f -+ return fmt.Sprintf("FCSR%d", regno) -+ -+ case Fcc: -+ regno := uint8(a) & 0x1f -+ return fmt.Sprintf("FCC%d", regno) -+ -+ case Uimm: -+ return fmt.Sprintf("$%d", a.Imm) -+ -+ case Simm16: -+ si16 := signumConvInt32(int32(a.Imm), a.Width) -+ return fmt.Sprintf("$%d", si16) -+ -+ case Simm32: -+ si32 := signumConvInt32(a.Imm, a.Width) -+ return fmt.Sprintf("$%d", si32) -+ -+ case OffsetSimm: -+ offs := offsConvInt32(a.Imm, a.Width) -+ if inst.Op == B || inst.Op == BL { -+ addr := int64(pc) + int64(a.Imm) -+ if s, base := symname(uint64(addr)); s != "" && uint64(addr) == base { -+ return fmt.Sprintf("%s(SB)", s) -+ } -+ } -+ return fmt.Sprintf("%d(PC)", offs>>2) -+ -+ case SaSimm: -+ return fmt.Sprintf("$%d", a) -+ -+ case CodeSimm: -+ return fmt.Sprintf("$%d", a) -+ -+ } -+ return strings.ToUpper(arg.String()) -+} -+ -+func signumConvInt32(imm int32, width uint8) int32 { -+ active := uint32(1<> (width - 1)) & 0x1) == 1 { -+ signum |= ^active -+ } -+ return int32(signum) -+} -+ -+func offsConvInt32(imm int32, width uint8) int32 { -+ relWidth := width + 2 -+ return signumConvInt32(imm, relWidth) -+} -+ -+var plan9OpMap = map[Op]string{ -+ ADD_W: "ADD", -+ ADD_D: "ADDV", -+ SUB_W: "SUB", -+ SUB_D: "SUBV", -+ ADDI_W: "ADD", -+ ADDI_D: "ADDV", -+ LU12I_W: "LU12IW", -+ LU32I_D: "LU32ID", -+ LU52I_D: "LU52ID", -+ SLT: "SGT", -+ SLTU: "SGTU", -+ SLTI: "SGT", -+ SLTUI: "SGTU", -+ PCADDU12I: "PCADDU12I", -+ PCALAU12I: "PCALAU12I", -+ AND: "AND", -+ OR: "OR", -+ NOR: "NOR", -+ XOR: "XOR", -+ ANDI: "AND", -+ ORI: "OR", -+ XORI: "XOR", -+ MUL_W: "MUL", -+ MULH_W: "MULH", -+ MULH_WU: "MULHU", -+ MUL_D: "MULV", -+ MULH_D: "MULHV", -+ MULH_DU: "MULHVU", -+ DIV_W: "DIV", -+ DIV_WU: "DIVU", -+ DIV_D: "DIVV", -+ DIV_DU: "DIVVU", -+ MOD_W: "REM", -+ MOD_WU: "REMU", -+ MOD_D: "REMV", -+ MOD_DU: "REMVU", -+ SLL_W: "SLL", -+ SRL_W: "SRL", -+ SRA_W: "SRA", -+ ROTR_W: "ROTR", -+ SLL_D: "SLLV", -+ SRL_D: "SRLV", -+ SRA_D: "SRAV", -+ ROTR_D: "ROTRV", -+ SLLI_W: "SLL", -+ SRLI_W: "SRL", -+ SRAI_W: "SRA", -+ ROTRI_W: "ROTR", -+ SLLI_D: "SLLV", -+ SRLI_D: "SRLV", -+ SRAI_D: "SRAV", -+ ROTRI_D: "ROTRV", -+ EXT_W_B: "", -+ EXT_W_H: "", -+ CLO_W: "CLO", -+ CLZ_W: "CLZ", -+ BSTRPICK_D: "", -+ MASKEQZ: "MASKEQZ", -+ MASKNEZ: "MASKNEZ", -+ BCNEZ: "BFPT", -+ BCEQZ: "BFPF", -+ BEQ: "BEQ", -+ BNE: "BNE", -+ BEQZ: "BEQ", -+ BNEZ: "BNE", -+ BLT: "BLT", -+ BLTU: "BLTU", -+ BGE: "BGE", -+ BGEU: "BGEU", -+ B: "JMP", -+ BL: "CALL", -+ LD_B: "MOVB", -+ LD_H: "MOVH", -+ LD_W: "MOVW", -+ LD_D: "MOVV", -+ LD_BU: "MOVBU", -+ LD_HU: "MOVHU", -+ LD_WU: "MOVWU", -+ ST_B: "MOVB", -+ ST_H: "MOVH", -+ ST_W: "MOVW", -+ ST_D: "MOVV", -+ AMSWAP_W: "AMSWAPW", -+ AMSWAP_D: "AMSWAPD", -+ AMADD_W: "AMADDW", -+ AMADD_D: "AMADDV", -+ AMAND_W: "AMANDW", -+ AMAND_D: "AMANDV", -+ AMOR_W: "AMORW", -+ AMOR_D: "AMORV", -+ AMXOR_W: "AMXORW", -+ AMXOR_D: "AMXORV", -+ AMMAX_W: "AMMAXW", -+ AMMAX_D: "AMMAXV", -+ AMMIN_W: "AMMINW", -+ AMMIN_D: "AMMINV", -+ AMMAX_WU: "AMMAXWU", -+ AMMAX_DU: "AMMAXVU", -+ AMMIN_WU: "AMMINWU", -+ AMMIN_DU: "AMMINVU", -+ AMSWAP_DB_W: "AMSWAPDBW", -+ AMSWAP_DB_D: "AMSWAPDBV", -+ AMADD_DB_W: "AMADDDBW", -+ AMADD_DB_D: "AMADDDBV", -+ AMAND_DB_W: "AMANDDBW", -+ AMAND_DB_D: "AMANDDBV", -+ AMOR_DB_W: "AMORDBW", -+ AMOR_DB_D: "AMORDBV", -+ AMXOR_DB_W: "AMXORDBW", -+ AMXOR_DB_D: "AMXORDBV", -+ AMMAX_DB_W: "AMMAXDBW", -+ AMMAX_DB_D: "AMMAXDBV", -+ AMMIN_DB_W: "AMMINDBW", -+ AMMIN_DB_D: "AMMINDBV", -+ AMMAX_DB_WU: "AMMAXDBWU", -+ AMMAX_DB_DU: "AMMAXDBVU", -+ AMMIN_DB_WU: "AMMINDBWU", -+ AMMIN_DB_DU: "AMMINDBVU", -+ LL_W: "LL", -+ LL_D: "LLV", -+ SC_W: "SC", -+ SC_D: "SCV", -+ DBAR: "DBAR", -+ SYSCALL: "SYSCALL", -+ BREAK: "BREAK", -+ CACOP: "BREAK", -+ RDTIMEL_W: "RDTIMELW", -+ RDTIMEH_W: "RDTIMEHW", -+ RDTIME_D: "RDTIMED", -+ FADD_S: "ADDF", -+ FADD_D: "ADDD", -+ FSUB_S: "SUBF", -+ FSUB_D: "SUBD", -+ FMUL_S: "MULF", -+ FMUL_D: "MULD", -+ FDIV_S: "DIVF", -+ FDIV_D: "DIVD", -+ FABS_S: "ABSF", -+ FABS_D: "ABSD", -+ FNEG_S: "NEGF", -+ FNEG_D: "NEGD", -+ FSQRT_S: "SQRTF", -+ FSQRT_D: "SQRTD", -+ FCMP_CEQ_S: "CMPEQF", -+ FCMP_CEQ_D: "CMPEQD", -+ FCMP_SLE_S: "CMPGEF", -+ FCMP_SLE_D: "CMPGED", -+ FCMP_SLT_S: "CMPGTF", -+ FCMP_SLT_D: "CMPGTD", -+ FCVT_D_S: "MOVFD", -+ FCVT_S_D: "MOVDF", -+ FFINT_S_W: "MOVWF", -+ FFINT_S_L: "MOVVF", -+ FFINT_D_W: "MOVWD", -+ FFINT_D_L: "MOVVD", -+ FTINT_W_S: "MOVFW", -+ FTINT_L_S: "MOVFV", -+ FTINT_W_D: "MOVDW", -+ FTINT_L_D: "MOVDV", -+ FTINTRZ_W_S: "TRUNCFW", -+ FTINTRZ_W_D: "TRUNCDW", -+ FTINTRZ_L_S: "TRUNCFV", -+ FTINTRZ_L_D: "TRUNCDV", -+ FMOV_S: "MOVF", -+ FMOV_D: "MOVD", -+ MOVGR2FR_W: "MOVW", -+ MOVGR2FR_D: "MOVV", -+ MOVFR2GR_S: "MOVW", -+ MOVFR2GR_D: "MOVV", -+ MOVGR2CF: "MOVV", -+ MOVCF2GR: "MOVV", -+ FLD_S: "MOVF", -+ FLD_D: "MOVD", -+ FST_S: "MOVF", -+ FST_D: "MOVD", -+} -diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/tables.go b/vendor/golang.org/x/arch/loong64/loong64asm/tables.go -index f90e929..54bd480 100644 ---- a/vendor/golang.org/x/arch/loong64/loong64asm/tables.go -+++ b/vendor/golang.org/x/arch/loong64/loong64asm/tables.go -@@ -1,6 +1,7 @@ --// Generated by Loong64 internal tool -+// Generated by loong64spec LoongArch-Vol1-EN.pdf - // DO NOT EDIT --// Copyright 2022 The Go Authors. All rights reserved. -+ -+// Copyright 2023 The Go Authors. All rights reserved. - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. - --- -2.20.1 - diff --git a/0005-pkg-proc-support-Plan-9-disassembly-on-loong64.patch b/0005-pkg-proc-support-Plan-9-disassembly-on-loong64.patch deleted file mode 100644 index 161ea1e21bbf23a244c1d7652a9c39a181ecc8da..0000000000000000000000000000000000000000 --- a/0005-pkg-proc-support-Plan-9-disassembly-on-loong64.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 916ef925de4cb352bde9a0496ffc00799aab7de9 Mon Sep 17 00:00:00 2001 -From: Huang Qiqi -Date: Tue, 26 Nov 2024 19:00:39 +0800 -Subject: [PATCH 5/7] pkg/proc: support Plan 9 disassembly on loong64 - ---- - pkg/proc/loong64_disasm.go | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/pkg/proc/loong64_disasm.go b/pkg/proc/loong64_disasm.go -index 98d191f..b861322 100644 ---- a/pkg/proc/loong64_disasm.go -+++ b/pkg/proc/loong64_disasm.go -@@ -198,7 +198,7 @@ func (inst *loong64ArchInst) Text(flavour AssemblyFlavour, pc uint64, symLookup - // It should be disassembled to plan9, but loong64 - // doesn't support this at the moment, so it's better - // to use it as GNUSyntax. -- text = loong64asm.GNUSyntax(loong64asm.Inst(*inst)) -+ text = loong64asm.GoSyntax(loong64asm.Inst(*inst), pc, symLookup) - } - - return text --- -2.20.1 - diff --git a/0006-pkg-proc-pkg-dwarf-modify-some-comments-and-test-fil.patch b/0006-pkg-proc-pkg-dwarf-modify-some-comments-and-test-fil.patch deleted file mode 100644 index 538f6acdfb59e4edc31f0a7381f61efa0906a64b..0000000000000000000000000000000000000000 --- a/0006-pkg-proc-pkg-dwarf-modify-some-comments-and-test-fil.patch +++ /dev/null @@ -1,174 +0,0 @@ -From 1d59e50cf3aa810a85bb2f6bbd8a669223086a5b Mon Sep 17 00:00:00 2001 -From: Huang Qiqi -Date: Tue, 21 May 2024 19:34:15 +0800 -Subject: [PATCH 6/7] pkg/proc, pkg/dwarf: modify some comments and test files - -Change-Id: I09874d10c96e45b07f0adf2ae65fb688cd760c5e ---- - pkg/dwarf/regnum/loong64.go | 4 ++-- - pkg/proc/linutil/regs_loong64_arch.go | 2 -- - pkg/proc/loong64_disasm.go | 3 --- - pkg/proc/native/registers_linux_loong64.go | 4 ++-- - pkg/proc/pe.go | 4 ++-- - pkg/proc/proc_test.go | 6 +++++- - pkg/terminal/command_test.go | 3 --- - vendor/golang.org/x/arch/loong64/loong64asm/log | 14 -------------- - 8 files changed, 11 insertions(+), 29 deletions(-) - delete mode 100644 vendor/golang.org/x/arch/loong64/loong64asm/log - -diff --git a/pkg/dwarf/regnum/loong64.go b/pkg/dwarf/regnum/loong64.go -index 94f41ea..9c47dad 100644 ---- a/pkg/dwarf/regnum/loong64.go -+++ b/pkg/dwarf/regnum/loong64.go -@@ -11,7 +11,7 @@ import ( - const ( - // General-purpose Register - LOONG64_R0 = 0 -- LOONG64_LR = 1 // ra: address fro subroutine -+ LOONG64_LR = 1 // ra: address for subroutine - LOONG64_SP = 3 // sp: stack pointer - LOONG64_R22 = 22 - LOONG64_FP = LOONG64_R22 // fp: frame pointer -@@ -32,7 +32,7 @@ const ( - LOONG64_BADV = 74 - - // See golang src/cmd/link/internal/loong64/l.go -- LOONG64_PC = LOONG64_ERA // rea : exception program counter -+ LOONG64_PC = LOONG64_ERA // era : exception program counter - - _LOONG64_MaxRegNum = LOONG64_BADV - ) -diff --git a/pkg/proc/linutil/regs_loong64_arch.go b/pkg/proc/linutil/regs_loong64_arch.go -index d1b3e24..1ebe963 100644 ---- a/pkg/proc/linutil/regs_loong64_arch.go -+++ b/pkg/proc/linutil/regs_loong64_arch.go -@@ -112,8 +112,6 @@ func (r *LOONG64Registers) SP() uint64 { - - // BP returns the value of FP register - func (r *LOONG64Registers) BP() uint64 { -- // Frame pointer -- //return r.Regs.Regs[regnum.LOONG64_FP] - // unused FP register - return 0 - } -diff --git a/pkg/proc/loong64_disasm.go b/pkg/proc/loong64_disasm.go -index b861322..7aa694d 100644 ---- a/pkg/proc/loong64_disasm.go -+++ b/pkg/proc/loong64_disasm.go -@@ -154,9 +154,6 @@ var prologuesLOONG64 []opcodeSeq - func init() { - var tinyStacksplit = opcodeSeq{uint64(loong64asm.ADDI_D)} - var smallStacksplit = opcodeSeq{} -- // inst:{uint64(loong64asm.SLTUI), -- // uint64(loong64asm.BNE), -- // uint64(loong64asm.ADDI_D)} - var bigStacksplit = opcodeSeq{uint64(loong64asm.LU12I_W), - uint64(loong64asm.ORI), - uint64(loong64asm.SLTU), -diff --git a/pkg/proc/native/registers_linux_loong64.go b/pkg/proc/native/registers_linux_loong64.go -index c9752b2..439f835 100644 ---- a/pkg/proc/native/registers_linux_loong64.go -+++ b/pkg/proc/native/registers_linux_loong64.go -@@ -20,7 +20,7 @@ const ( - // Refer to the definition of struct user_pt_regs in the kernel file ptrace.h - _LOONG64_GREGS_SIZE = (32 * 8) + 8 + 8 + 8 + (10 * 8) - -- // In fact, the total number of bytes is 268(32 fpr * 8 + 1 Fcc * 8 + 1 Fcsr +4), -+ // 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 -@@ -56,7 +56,7 @@ func ptraceGetFpRegset(tid int, fpregs *linutil.LOONG64PtraceFpRegs) (err error) - fprBytes := make([]byte, _LOONG64_FPREGS_SIZE) - iov := sys.Iovec{Base: &fprBytes[0], Len: uint64(_LOONG64_FPREGS_SIZE)} - -- _, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_SETREGSET, uintptr(tid), -+ _, _, err = syscall.Syscall6(syscall.SYS_PTRACE, sys.PTRACE_GETREGSET, uintptr(tid), - uintptr(elf.NT_FPREGSET), uintptr(unsafe.Pointer(&iov)), 0, 0) - if err != syscall.Errno(0) { - if err == syscall.ENODEV { -diff --git a/pkg/proc/pe.go b/pkg/proc/pe.go -index fab5890..edf3100 100644 ---- a/pkg/proc/pe.go -+++ b/pkg/proc/pe.go -@@ -11,10 +11,10 @@ const ( - _IMAGE_FILE_MACHINE_ARM = 0x1c0 - _IMAGE_FILE_MACHINE_ARMNT = 0x1c4 - _IMAGE_FILE_MACHINE_ARM64 = 0xaa64 -- _IMAGE_FILE_MACHINE_LOONGARCH64 = 0x6264 - _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 -@@ -40,10 +40,10 @@ var _PEMachineString = map[_PEMachine]string{ - _IMAGE_FILE_MACHINE_ARM: "arm", - _IMAGE_FILE_MACHINE_ARMNT: "armnt", - _IMAGE_FILE_MACHINE_ARM64: "arm64", -- _IMAGE_FILE_MACHINE_LOONGARCH64: "loong64", - _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/proc_test.go b/pkg/proc/proc_test.go -index 67547fa..fa82aec 100644 ---- a/pkg/proc/proc_test.go -+++ b/pkg/proc/proc_test.go -@@ -3468,10 +3468,14 @@ func TestCgoSources(t *testing.T) { - } - } - -- if runtime.GOARCH == "386" || runtime.GOARCH == "loong64" { -+ if runtime.GOARCH == "386" { - t.Skip("cgo stacktraces not supported on i386 for now") - } - -+ if runtime.GOARCH == "loong64" { -+ t.Skip("cgo stacktraces not supported on loong64 for now") -+ } -+ - protest.MustHaveCgo(t) - - withTestProcess("cgostacktest/", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { -diff --git a/pkg/terminal/command_test.go b/pkg/terminal/command_test.go -index 021947a..8b535d0 100644 ---- a/pkg/terminal/command_test.go -+++ b/pkg/terminal/command_test.go -@@ -1411,9 +1411,6 @@ func TestDisassPosCmd(t *testing.T) { - if runtime.GOARCH == "ppc64le" && buildMode == "pie" { - t.Skip("pie mode broken on ppc64le") - } -- if runtime.GOARCH == "loong64" { -- t.Skip("disassemble to plan9 nosupported on loong64 for now") -- } - withTestTerminal("testvariables2", t, func(term *FakeTerminal) { - term.MustExec("continue") - out := term.MustExec("step-instruction") -diff --git a/vendor/golang.org/x/arch/loong64/loong64asm/log b/vendor/golang.org/x/arch/loong64/loong64asm/log -deleted file mode 100644 -index 85bb80f..0000000 ---- a/vendor/golang.org/x/arch/loong64/loong64asm/log -+++ /dev/null -@@ -1,14 +0,0 @@ --=== RUN TestObjdumpLoong64TestDecodeGNUSyntaxdata --totalTest: 388 total skip: 0 total error: 0 -- ext_test.go:178: 388 test cases, 0 expected mismatches, 0 failures; 51516 cases/second -- ext_test.go:179: decoder coverage: 100.0%; ----- PASS: TestObjdumpLoong64TestDecodeGNUSyntaxdata (0.01s) --PASS --ok golang.org/x/arch/loong64/loong64asm 0.014s --=== RUN TestObjdumpLoong64Manual --totalTest: 32 total skip: 0 total error: 0 -- ext_test.go:178: 32 test cases, 0 expected mismatches, 0 failures; 7703 cases/second -- ext_test.go:179: decoder coverage: 8.8%; ----- PASS: TestObjdumpLoong64Manual (0.01s) --PASS --ok golang.org/x/arch/loong64/loong64asm 0.011s --- -2.20.1 - diff --git a/0007-pkg-proc-fixed-bugs-in-continue-couredump-and-call.patch b/0007-pkg-proc-fixed-bugs-in-continue-couredump-and-call.patch deleted file mode 100644 index 8fea40e72d567c20da14c87d9d36e2c65979a03e..0000000000000000000000000000000000000000 --- a/0007-pkg-proc-fixed-bugs-in-continue-couredump-and-call.patch +++ /dev/null @@ -1,96 +0,0 @@ -From dd0d6aba1034ebe1bf9d8f18b4dc6f95b3967b1d Mon Sep 17 00:00:00 2001 -From: Huang Qiqi -Date: Thu, 28 Mar 2024 15:25:37 +0800 -Subject: [PATCH 7/7] pkg/proc: fixed bugs in continue, couredump, and call - -Change-Id: I3b32ae73e8f6b96b9199d98a47c5a463aacc4d98 ---- - Documentation/backend_test_health.md | 4 ++-- - pkg/proc/linutil/regs_loong64_arch.go | 11 +++-------- - pkg/proc/native/proc.go | 4 ++-- - pkg/proc/test/support.go | 2 +- - 4 files changed, 8 insertions(+), 13 deletions(-) - -diff --git a/Documentation/backend_test_health.md b/Documentation/backend_test_health.md -index c737017..d9e7741 100644 ---- a/Documentation/backend_test_health.md -+++ b/Documentation/backend_test_health.md -@@ -29,8 +29,8 @@ Tests skipped by each supported backend: - * 1 broken in linux ppc64le - * linux/ppc64le/native/pie skipped = 3 - * 3 broken - pie mode --* loong64 skipped = 8 -- * 1 broken -+* loong64 skipped = 9 -+ * 2 broken - * 3 broken - cgo stacktraces - * 1 broken - global variable symbolication - * 3 not implemented -diff --git a/pkg/proc/linutil/regs_loong64_arch.go b/pkg/proc/linutil/regs_loong64_arch.go -index 1ebe963..6612d78 100644 ---- a/pkg/proc/linutil/regs_loong64_arch.go -+++ b/pkg/proc/linutil/regs_loong64_arch.go -@@ -1,8 +1,8 @@ - package linutil - - import ( -- "encoding/binary" - "fmt" -+ - "github.com/go-delve/delve/pkg/dwarf/op" - "github.com/go-delve/delve/pkg/dwarf/regnum" - "github.com/go-delve/delve/pkg/proc" -@@ -215,13 +215,8 @@ func (fpregs *LOONG64PtraceFpRegs) Decode() (regs []proc.Register) { - regs = proc.AppendBytesRegister(regs, name, value) - } - -- fccBytes := make([]byte, 8) -- binary.LittleEndian.PutUint64(fccBytes, uint64(fpregs.Fcc)) -- regs = proc.AppendBytesRegister(regs, "FCC0", fccBytes) -- -- fcsrBytes := make([]byte, 4) -- binary.LittleEndian.PutUint32(fccBytes, uint32(fpregs.Fcsr)) -- regs = proc.AppendBytesRegister(regs, "FCSR", fcsrBytes) -+ regs = proc.AppendUint64Register(regs, "FCC0", fpregs.Fcc) -+ regs = proc.AppendUint64Register(regs, "FCSR", uint64(fpregs.Fcsr)) - - return - } -diff --git a/pkg/proc/native/proc.go b/pkg/proc/native/proc.go -index e209d9f..aade966 100644 ---- a/pkg/proc/native/proc.go -+++ b/pkg/proc/native/proc.go -@@ -372,7 +372,7 @@ func (dbp *nativeProcess) initialize(path string, debugInfoDirs []string) (*proc - // with gdb once AsyncPreempt was enabled. While implementing the port, - // few tests failed while it was enabled, but cannot be warrantied that - // disabling it fixed the issues. -- DisableAsyncPreempt: runtime.GOOS == "windows" || (runtime.GOOS == "linux" && runtime.GOARCH == "arm64") || (runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le"), -+ DisableAsyncPreempt: runtime.GOOS == "windows" || (runtime.GOOS == "linux" && runtime.GOARCH == "arm64") || (runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le") || (runtime.GOOS == "linux" && runtime.GOARCH == "loong64"), - - StopReason: stopReason, - CanDump: runtime.GOOS == "linux" || runtime.GOOS == "freebsd" || (runtime.GOOS == "windows" && runtime.GOARCH == "amd64"), -@@ -382,7 +382,7 @@ func (dbp *nativeProcess) initialize(path string, debugInfoDirs []string) (*proc - if err != nil { - return nil, err - } -- if dbp.bi.Arch.Name == "arm64" || dbp.bi.Arch.Name == "ppc64le" { -+ if dbp.bi.Arch.Name == "arm64" || dbp.bi.Arch.Name == "ppc64le" || dbp.bi.Arch.Name == "loong64" { - dbp.iscgo = tgt.IsCgo() - } - return grp, nil -diff --git a/pkg/proc/test/support.go b/pkg/proc/test/support.go -index b21c4f7..12b2d6d 100644 ---- a/pkg/proc/test/support.go -+++ b/pkg/proc/test/support.go -@@ -385,7 +385,7 @@ func RegabiSupported() bool { - // Tracks regabiSupported variable in ParseGOEXPERIMENT internal/buildcfg/exp.go - switch { - case goversion.VersionAfterOrEqual(runtime.Version(), 1, 18): -- return runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "ppc64" -+ return runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "loong64" - case goversion.VersionAfterOrEqual(runtime.Version(), 1, 17): - return runtime.GOARCH == "amd64" && (runtime.GOOS == "android" || runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows") - default: --- -2.20.1 - diff --git a/delve.spec b/delve.spec index dd5e72db45c78f5b0d881b051c2be1f44931df94..35e3049d02e2608b4ce2c03ea59f0d4a01d3ae18 100644 --- a/delve.spec +++ b/delve.spec @@ -3,6 +3,10 @@ %global exp "-tags=exp.linuxppc64le" %endif +%ifarch loongarch64 +%global exp "-tags=exp.linuxloong64" +%endif + # Controls what ever we fail on failed tests %ifarch loongarch64 %bcond_with fail_on_tests @@ -11,7 +15,7 @@ %endif Name: delve -Version: 1.22.1 +Version: 1.24.1 Release: 1%{anolis_release}%{?dist} Summary: A debugger for the Go programming language @@ -26,15 +30,9 @@ BuildRequires: git BuildRequires: lsof Provides: dlv = %{version} - -Patch0001: modify-tests.patch -Patch0002: 0001-all-add-build-mode-vendor-support.patch -Patch0003: 0002-all-update-golang.org-x-arch-to-b835ee2a400a6a72a771.patch -Patch0004: 0003-delve-support-linux-loong64-native-debug.patch -Patch0005: 0004-all-update-golang.org-x-arch-to-9a59f1d32eedbf89830e.patch -Patch0006: 0005-pkg-proc-support-Plan-9-disassembly-on-loong64.patch -Patch0007: 0006-pkg-proc-pkg-dwarf-modify-some-comments-and-test-fil.patch -Patch0008: 0007-pkg-proc-fixed-bugs-in-continue-couredump-and-call.patch +Patch1: skip-coredump-test.patch +Patch2: skip-substitute-path-test.patch +Patch3: 0001-ABI1.0-support-for-ptrace-struct-on-loong64.patch %description @@ -90,12 +88,17 @@ done %changelog -* Tue Nov 26 2024 Huang Qiqi - 1.22.1-1.0.2 -- Add loongarch64 base support. +* Tue May 20 2025 chenguoqi - 1.24.1-1.0.2 +- Add loongarch64 re-support. -* Wed Nov 06 2024 Liwei Ge - 1.22.1-1.0.1 +* Fri Apr 18 2025 Liwei Ge - 1.24.1-1.0.1 - Exclude loongarch64 +* Fri Mar 14 2025 David Benoit - 1.24.1-1 +- Rebase to 1.24.1 +- Skip unsupported tests +- Resolves: RHEL-83451 + * Fri Aug 16 2024 Alejandro Sáez - 1.22.1-1 - Rebase to 1.22.1 - Resolves: RHEL-54307 diff --git a/download b/download index 8150c71a0d22819beb32b38ba8cc3ee6637c5195..560736343cbb672b118f94d2c90231fc9d30804b 100644 --- a/download +++ b/download @@ -1 +1 @@ -288b9e6caf74855e9c2bb9dcc9f4d317 delve-1.22.1.tar.gz +c5460554620ee3fec75059db190c6696 delve-1.24.1.tar.gz diff --git a/modify-tests.patch b/modify-tests.patch deleted file mode 100644 index 6e4d8ee0c1a6656609759eba01dd0b90ae475b6e..0000000000000000000000000000000000000000 --- a/modify-tests.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0d8ba2001ceacd67a8861f470399f695cabc8802 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lex=20S=C3=A1ez?= -Date: Wed, 24 Jan 2024 13:10:29 +0100 -Subject: [PATCH] Modify tests - -Some tests are not working properly with the build system so we need to -adapt them, like changing the ports they used. ---- - _fixtures/notify-v2.go | 2 +- - pkg/proc/proc_test.go | 3 +++ - pkg/terminal/command_test.go | 2 +- - 3 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/_fixtures/notify-v2.go b/_fixtures/notify-v2.go -index eb80526b..0f562c27 100644 ---- a/_fixtures/notify-v2.go -+++ b/_fixtures/notify-v2.go -@@ -19,5 +19,5 @@ func main() { - }() - }) - -- log.Fatalln(http.ListenAndServe("127.0.0.1:8888", nil)) -+ log.Fatalln(http.ListenAndServe("127.0.0.1:8889", nil)) - } -diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go -index 714a4d1d..ea1d94a9 100644 ---- a/pkg/proc/proc_test.go -+++ b/pkg/proc/proc_test.go -@@ -2512,6 +2512,7 @@ func TestStepConcurrentDirect(t *testing.T) { - } - - func TestStepConcurrentPtr(t *testing.T) { -+ t.Skipf("Skipping due to CI issues") - protest.AllowRecording(t) - withTestProcess("teststepconcurrent", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { - setFileBreakpoint(p, t, fixture.Source, 24) -@@ -5491,6 +5492,7 @@ func TestWatchpointCounts(t *testing.T) { - skipOn(t, "not implemented", "386") - skipOn(t, "see https://github.com/go-delve/delve/issues/2768", "windows") - skipOn(t, "not implemented", "ppc64le") -+ skipOn(t, "fails on CI", "arm64") - protest.AllowRecording(t) - - withTestProcess("databpcountstest", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { -@@ -6080,6 +6082,7 @@ func TestEscapeCheckUnreadable(t *testing.T) { - } - - func TestStepShadowConcurrentBreakpoint(t *testing.T) { -+ t.Skipf("Skipping due to CI issues") - // Checks that a StepBreakpoint can not shadow a concurrently hit user breakpoint - withTestProcess("stepshadow", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { - break2 := setFunctionBreakpoint(p, t, "main.stacktraceme2") -diff --git a/pkg/terminal/command_test.go b/pkg/terminal/command_test.go -index 57b62105..f6e3a3d9 100644 ---- a/pkg/terminal/command_test.go -+++ b/pkg/terminal/command_test.go -@@ -695,7 +695,7 @@ func TestIssue827(t *testing.T) { - withTestTerminal("notify-v2", t, func(term *FakeTerminal) { - go func() { - time.Sleep(1 * time.Second) -- resp, err := http.Get("http://127.0.0.1:8888/test") -+ resp, err := http.Get("http://127.0.0.1:8889/test") - if err == nil { - resp.Body.Close() - } --- -2.43.0 - diff --git a/skip-coredump-test.patch b/skip-coredump-test.patch new file mode 100644 index 0000000000000000000000000000000000000000..03f5d36eaf639a8f7ad6bd2438f3a3f7e023338e --- /dev/null +++ b/skip-coredump-test.patch @@ -0,0 +1,78 @@ +From d5fb3bee427202f0d4b1683bf743bfd2adb41757 Mon Sep 17 00:00:00 2001 +From: Derek Parker +Date: Thu, 20 Mar 2025 01:15:19 -0700 +Subject: [PATCH] proc/core: skip tests on ppc64le (#3954) + +These tests have been somewhat silently failing on our CI because the +test ends up being skipped [due to the lack of coredumpctl](https://delve.teamcity.com/buildConfiguration/Delve_linux_ppc64le_1_24/66766?buildTab=tests&focusLine=NaN&name=testcore&suite=github.com%2Fgo-delve%2Fdelve%2Fpkg%2Fproc%2Fcore%3A+&expandedTest=build%3A%28id%3A66766%29%2Cid%3A2000000704&showLog=66766_20670_112.20612.20670&logFilter=debug&logView=flowAware). + +When `coredumpctl` is present, the test [fails +anyways](https://issues.redhat.com/browse/RHEL-83939), so let's just +skip it on ppc64le for now. +--- + pkg/proc/core/core_test.go | 41 +++++++++++++++++++++----------------- + 1 file changed, 23 insertions(+), 18 deletions(-) + +diff --git a/pkg/proc/core/core_test.go b/pkg/proc/core/core_test.go +index dddc1d3e7..52b210b6f 100644 +--- a/pkg/proc/core/core_test.go ++++ b/pkg/proc/core/core_test.go +@@ -249,15 +249,8 @@ func logRegisters(t *testing.T, regs proc.Registers, arch *proc.Arch) { + } + + func TestCore(t *testing.T) { +- if runtime.GOOS != "linux" || runtime.GOARCH == "386" { +- t.Skip("unsupported") +- } +- if runtime.GOOS != "linux" || runtime.GOARCH == "loong64" { +- t.Skip("could not read runtime.sigtrampgo context") +- } +- if runtime.GOOS == "linux" && os.Getenv("CI") == "true" && buildMode == "pie" { +- t.Skip("disabled on linux, Github Actions, with PIE buildmode") +- } ++ mustSupportCore(t) ++ + grp := withCoreFile(t, "panic", "") + p := grp.Selected + +@@ -412,15 +405,8 @@ func TestCoreFpRegisters(t *testing.T) { + } + + func TestCoreWithEmptyString(t *testing.T) { +- if runtime.GOOS != "linux" || runtime.GOARCH == "386" { +- t.Skip("unsupported") +- } +- if runtime.GOOS != "linux" || runtime.GOARCH == "loong64" { +- t.Skip("could not read runtime.sigtrampgo context") +- } +- if runtime.GOOS == "linux" && os.Getenv("CI") == "true" && buildMode == "pie" { +- t.Skip("disabled on linux, Github Actions, with PIE buildmode") +- } ++ mustSupportCore(t) ++ + grp := withCoreFile(t, "coreemptystring", "") + p := grp.Selected + +@@ -536,3 +522,22 @@ func procdump(t *testing.T, exePath string) string { + t.Fatalf("could not find dump file") + return "" + } ++ ++func mustSupportCore(t *testing.T) { ++ t.Helper() ++ ++ if runtime.GOOS != "linux" { ++ t.Skip("test must be run on linux") ++ } ++ ++ switch runtime.GOARCH { ++ case "386", "ppc64le": ++ t.Skip("unsupported") ++ case "loong64": ++ t.Skip("could not read runtime.sigtrampgo context") ++ } ++ ++ if os.Getenv("CI") == "true" && buildMode == "pie" { ++ t.Skip("disabled on linux, Github Actions, with PIE buildmode") ++ } ++} diff --git a/skip-substitute-path-test.patch b/skip-substitute-path-test.patch new file mode 100644 index 0000000000000000000000000000000000000000..f234e60f7ca5d4ca8bb8d39318e803c3a754bfc8 --- /dev/null +++ b/skip-substitute-path-test.patch @@ -0,0 +1,42 @@ +From 55486fbab43420d67323cd3e79cda115e7e687c6 Mon Sep 17 00:00:00 2001 +From: Derek Parker +Date: Thu, 20 Mar 2025 01:14:20 -0700 +Subject: [PATCH] service/test: skip substitutepath test when modules disabled + (#3955) + +See: https://issues.redhat.com/browse/RHEL-83958 +--- + pkg/proc/test/support.go | 6 ++++++ + service/test/integration2_test.go | 2 ++ + 2 files changed, 8 insertions(+) + +diff --git a/pkg/proc/test/support.go b/pkg/proc/test/support.go +index d1f25bd49..c8efea360 100644 +--- a/pkg/proc/test/support.go ++++ b/pkg/proc/test/support.go +@@ -392,6 +392,12 @@ func MustHaveCgo(t *testing.T) { + } + } + ++func MustHaveModules(t *testing.T) { ++ if os.Getenv("GO111MODULE") == "off" { ++ t.Skip("skipping test which requires go modules") ++ } ++} ++ + func RegabiSupported() bool { + // Tracks regabiSupported variable in ParseGOEXPERIMENT internal/buildcfg/exp.go + switch { +diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go +index 9ef131a3e..2e3928fb8 100644 +--- a/service/test/integration2_test.go ++++ b/service/test/integration2_test.go +@@ -3157,6 +3157,8 @@ func TestBreakpointVariablesWithoutG(t *testing.T) { + } + + func TestGuessSubstitutePath(t *testing.T) { ++ protest.MustHaveModules(t) ++ + t.Setenv("NOCERT", "1") + ver, _ := goversion.Parse(runtime.Version()) + if ver.IsDevelBuild() && os.Getenv("CI") != "" && runtime.GOOS == "linux" {