diff --git a/disasm/disasm.go b/disasm/disasm.go index 0e5f3d4..dfd7b10 100644 --- a/disasm/disasm.go +++ b/disasm/disasm.go @@ -69,7 +69,7 @@ func Decode(a arch.Arch, code []byte, addr uint64) (Instruction, error) { if err != nil { return Instruction{Addr: addr, Text: "???", Len: 4}, nil } - return Instruction{Addr: addr, Text: loong64asm.GoSyntax(inst, addr, nil), Len: 4}, nil + return Instruction{Addr: addr, Text: nameLoong64(inst, loong64asm.GoSyntax(inst, addr, nil)), Len: 4}, nil default: // amd64 inst, err := x86asm.Decode(code, 64) diff --git a/disasm/loong64_naming.go b/disasm/loong64_naming.go new file mode 100644 index 0000000..e12afdd --- /dev/null +++ b/disasm/loong64_naming.go @@ -0,0 +1,140 @@ +// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) +// SPDX-License-Identifier: BSD-3-Clause + +package disasm + +import ( + "fmt" + + "golang.org/x/arch/loong64/loong64asm" +) + +// golang.org/x/arch's Plan 9 renderer leaves two holes over instructions +// it decodes perfectly well: a set of operations absent from its op-name +// table, which it renders as "Unknown OP.ARGS", and the sign-extension +// pair EXT.W.B/EXT.W.H, whose table entries are the literal "?" while the +// operands print fine. The toolchain's assembler corpus carries every one +// of these families with machine-checked encodings and its own spellings +// (loong64enc1.s's "EXTWB R4, R5 // 855c0000" and its kin), so the +// disassembler re-renders them after the decode: the operations whose +// operand order x/arch already prints the Plan 9 way keep their operand +// text and trade only the mnemonic, and the handful whose order differs +// (the pointer loads and stores, the acquire loads, the release stores, +// PRELD and ALSL) are rebuilt from the decoded arguments. + +// loong64OpNames maps the decoder operations rendered as "Unknown OPS" to +// the toolchain's Plan 9 mnemonics. The operand text x/arch prints for +// these is already the Plan 9 order; only the name is replaced. +var loong64OpNames = map[loong64asm.Op]string{ + loong64asm.REVH_2W: "REVH2W", + loong64asm.REVH_D: "REVHV", + loong64asm.BITREV_4B: "BITREV4B", + loong64asm.BITREV_8B: "BITREV8B", + loong64asm.ANDN: "ANDN", + loong64asm.ORN: "ORN", + loong64asm.MULW_D_W: "MULWVW", + loong64asm.MULW_D_WU: "MULWVWU", + loong64asm.FMAXA_S: "FMAXAF", + loong64asm.FMAXA_D: "FMAXAD", + loong64asm.FMINA_S: "FMINAF", + loong64asm.FMINA_D: "FMINAD", + loong64asm.FSCALEB_S: "FSCALEBF", + loong64asm.FSCALEB_D: "FSCALEBD", + loong64asm.FLOGB_S: "FLOGBF", + loong64asm.FLOGB_D: "FLOGBD", + loong64asm.FSEL: "FSEL", +} + +// nameLoong64 re-renders the instruction text for the families above. It +// takes the decoded instruction and the renderer's own text and returns the +// text to print; untouched families return text unchanged. +func nameLoong64(inst loong64asm.Inst, text string) string { + // The operations whose operand order the renderer prints wrong, plus + // the two it names "?": rebuild the text from the arguments. + switch inst.Op { + case loong64asm.EXT_W_B, loong64asm.EXT_W_H: + name := "EXTWB" + if inst.Op == loong64asm.EXT_W_H { + name = "EXTWH" + } + return fmt.Sprintf("%s %s, %s", name, loong64Reg(inst, 1), loong64Reg(inst, 0)) + case loong64asm.STPTR_W, loong64asm.STPTR_D: + name := "MOVWP" + if inst.Op == loong64asm.STPTR_D { + name = "MOVVP" + } + return fmt.Sprintf("%s %s, %s(%s)", name, loong64Reg(inst, 0), loong64Disp(inst, 2), loong64Reg(inst, 1)) + case loong64asm.LDPTR_W, loong64asm.LDPTR_D: + name := "MOVWP" + if inst.Op == loong64asm.LDPTR_D { + name = "MOVVP" + } + return fmt.Sprintf("%s %s(%s), %s", name, loong64Disp(inst, 2), loong64Reg(inst, 1), loong64Reg(inst, 0)) + case loong64asm.LLACQ_W, loong64asm.LLACQ_D: + name := "LLACQW" + if inst.Op == loong64asm.LLACQ_D { + name = "LLACQV" + } + return fmt.Sprintf("%s (%s), %s", name, loong64Reg(inst, 1), loong64Reg(inst, 0)) + case loong64asm.SC_Q: + return fmt.Sprintf("SCQ %s, %s, (%s)", loong64Reg(inst, 0), loong64Reg(inst, 1), loong64Reg(inst, 2)) + case loong64asm.SCREL_W, loong64asm.SCREL_D: + name := "SCRELW" + if inst.Op == loong64asm.SCREL_D { + name = "SCRELV" + } + return fmt.Sprintf("%s %s, (%s)", name, loong64Reg(inst, 0), loong64Reg(inst, 1)) + case loong64asm.PRELD: + disp := int32(inst.Args[2].(loong64asm.Simm16).Imm) + hint := inst.Args[0].(loong64asm.Uimm).Imm + if disp == 0 { + return fmt.Sprintf("PRELD (%s), $%d", loong64Reg(inst, 1), hint) + } + return fmt.Sprintf("PRELD %d(%s), $%d", disp, loong64Reg(inst, 1), hint) + case loong64asm.ALSL_W, loong64asm.ALSL_WU, loong64asm.ALSL_D: + name := "ALSLW" + switch inst.Op { + case loong64asm.ALSL_WU: + name = "ALSLWU" + case loong64asm.ALSL_D: + name = "ALSLV" + } + return fmt.Sprintf("%s $%d, %s, %s, %s", name, inst.Args[3].(loong64asm.SaSimm), + loong64Reg(inst, 1), loong64Reg(inst, 2), loong64Reg(inst, 0)) + } + // The name-only families: replace the "Unknown OPS" prefix, keeping + // the operand text. + if name, ok := loong64OpNames[inst.Op]; ok { + prefix := "Unknown " + inst.Op.String() + if rest, found := trimSpacePrefix(text, prefix); found { + return name + rest + } + } + return text +} + +// loong64Reg renders the general-purpose register of argument i, which the +// families here all use; the decoder stores the plain register number. +func loong64Reg(inst loong64asm.Inst, i int) string { + return fmt.Sprintf("R%d", int(inst.Args[i].(loong64asm.Reg))&31) +} + +// loong64Disp renders the displacement of argument i. The pointer +// loads and stores scale their immediate by four: the decoder hands back +// the unscaled field as a 16-bit quantity (32764, say, whose field the +// assembler wrote from 32764 >> 2), and the round-tripping spelling is +// the same quantity read as signed 16-bit, the way the toolchain's own +// assembler takes it back: 32764 keeps the positive reading and the +// fields with the sign bit set render negative (-4, not 65532). +func loong64Disp(inst loong64asm.Inst, i int) string { + return fmt.Sprintf("%d", int16(inst.Args[i].(loong64asm.Simm32).Imm)) +} + +// trimSpacePrefix reports the text beyond prefix plus its separating +// space, and whether prefix really opened text. +func trimSpacePrefix(text, prefix string) (string, bool) { + if len(text) > len(prefix) && text[:len(prefix)] == prefix && text[len(prefix)] == ' ' { + return text[len(prefix):], true + } + return text, false +} diff --git a/disasm/loong64_naming_test.go b/disasm/loong64_naming_test.go new file mode 100644 index 0000000..b5f148e --- /dev/null +++ b/disasm/loong64_naming_test.go @@ -0,0 +1,111 @@ +// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) +// SPDX-License-Identifier: BSD-3-Clause + +package disasm + +import ( + "testing" + + "sourcedock.dev/petrbalvin/gasm-sdk/arch" +) + +// TestUnknownNaming pins the loong64 re-rendering table over the corpus +// rows whose operations x/arch decodes but names "Unknown" or "?": every +// row's bytes are the corpus's own expected-encoding comments +// (machine-checked by the toolchain's assembler test suite) and every text +// is the toolchain's own spelling, operand order included. +func TestUnknownNaming(t *testing.T) { + for _, tt := range []struct { + code []byte + text string + }{ + // loong64enc1.s: EXTWB R4, R5 // 855c0000 and EXTWH R4, R5 // 85580000. + {[]byte{0x85, 0x5c, 0x00, 0x00}, "EXTWB R4, R5"}, + {[]byte{0x85, 0x58, 0x00, 0x00}, "EXTWH R4, R5"}, + // loong64enc1.s: the bit and reverse families. + {[]byte{0x85, 0x40, 0x00, 0x00}, "REVH2W R4, R5"}, + {[]byte{0x85, 0x44, 0x00, 0x00}, "REVHV R4, R5"}, + {[]byte{0x85, 0x48, 0x00, 0x00}, "BITREV4B R4, R5"}, + {[]byte{0x85, 0x4c, 0x00, 0x00}, "BITREV8B R4, R5"}, + // loong64enc1.s: ANDN and ORN, two- and three-operand forms. + {[]byte{0xa6, 0x90, 0x16, 0x00}, "ANDN R4, R5, R6"}, + {[]byte{0xa5, 0x90, 0x16, 0x00}, "ANDN R4, R5"}, + {[]byte{0xa6, 0x10, 0x16, 0x00}, "ORN R4, R5, R6"}, + {[]byte{0xa5, 0x10, 0x16, 0x00}, "ORN R4, R5"}, + // loong64enc1.s: MULWVW and MULWVWU. + {[]byte{0xa5, 0x10, 0x1f, 0x00}, "MULWVW R4, R5"}, + {[]byte{0xa6, 0x10, 0x1f, 0x00}, "MULWVW R4, R5, R6"}, + {[]byte{0xa5, 0x90, 0x1f, 0x00}, "MULWVWU R4, R5"}, + {[]byte{0xa6, 0x90, 0x1f, 0x00}, "MULWVWU R4, R5, R6"}, + // loong64enc1.s: the pointer store and load pair. The + // displacement is the scaled field read the way the toolchain + // takes it back: 32764, not the renderer's -4. + {[]byte{0x85, 0x04, 0x00, 0x25}, "MOVWP R5, 4(R4)"}, + {[]byte{0x85, 0x00, 0x00, 0x25}, "MOVWP R5, 0(R4)"}, + {[]byte{0x85, 0xfc, 0x7f, 0x25}, "MOVWP R5, 32764(R4)"}, + {[]byte{0xa4, 0xfc, 0x7f, 0x24}, "MOVWP 32764(R5), R4"}, + {[]byte{0xa4, 0x04, 0x00, 0x24}, "MOVWP 4(R5), R4"}, + {[]byte{0xa4, 0x00, 0x00, 0x26}, "MOVVP 0(R5), R4"}, + {[]byte{0x85, 0xfc, 0x7f, 0x27}, "MOVVP R5, 32764(R4)"}, + // loong64enc1.s: the acquire loads and release stores. + {[]byte{0xa4, 0x80, 0x57, 0x38}, "LLACQW (R5), R4"}, + {[]byte{0xa4, 0x88, 0x57, 0x38}, "LLACQV (R5), R4"}, + {[]byte{0xc4, 0x14, 0x57, 0x38}, "SCQ R4, R5, (R6)"}, + {[]byte{0xc4, 0x84, 0x57, 0x38}, "SCRELW R4, (R6)"}, + {[]byte{0xc4, 0x8c, 0x57, 0x38}, "SCRELV R4, (R6)"}, + // loong64enc1.s: the floating-point minima and maxima. + {[]byte{0xa6, 0x90, 0x0c, 0x01}, "FMAXAF F4, F5, F6"}, + {[]byte{0xa5, 0x90, 0x0c, 0x01}, "FMAXAF F4, F5"}, + {[]byte{0xa6, 0x10, 0x0d, 0x01}, "FMAXAD F4, F5, F6"}, + {[]byte{0xa6, 0x90, 0x0e, 0x01}, "FMINAF F4, F5, F6"}, + {[]byte{0xa6, 0x10, 0x0f, 0x01}, "FMINAD F4, F5, F6"}, + // loong64enc1.s: FSEL, FSCALEB and FLOGB. + {[]byte{0x43, 0x04, 0x00, 0x0d}, "FSEL FCC0, F1, F2, F3"}, + {[]byte{0x42, 0x84, 0x00, 0x0d}, "FSEL FCC1, F1, F2, F2"}, + {[]byte{0xa6, 0x90, 0x10, 0x01}, "FSCALEBF F4, F5, F6"}, + {[]byte{0xa6, 0x10, 0x11, 0x01}, "FSCALEBD F4, F5, F6"}, + {[]byte{0x85, 0x24, 0x14, 0x01}, "FLOGBF F4, F5"}, + {[]byte{0x85, 0x28, 0x14, 0x01}, "FLOGBD F4, F5"}, + // loong64enc1.s: PRELD, all three hint rows. + {[]byte{0x80, 0x00, 0xc0, 0x2a}, "PRELD (R4), $0"}, + {[]byte{0x88, 0xfc, 0xff, 0x2a}, "PRELD -1(R4), $8"}, + {[]byte{0x9f, 0x20, 0xc0, 0x2a}, "PRELD 8(R4), $31"}, + // loong64enc1.s: the address-add-and-shift-left family, whose + // rj and rk the renderer prints crossed. + {[]byte{0x86, 0x94, 0x05, 0x00}, "ALSLW $4, R4, R5, R6"}, + {[]byte{0x86, 0x94, 0x07, 0x00}, "ALSLWU $4, R4, R5, R6"}, + {[]byte{0x86, 0x94, 0x2d, 0x00}, "ALSLV $4, R4, R5, R6"}, + } { + ins, err := Decode(arch.LOONG64, tt.code, 0) + if err != nil { + t.Errorf("% x: %v", tt.code, err) + continue + } + if ins.Text != tt.text || ins.Len != len(tt.code) { + t.Errorf("% x: %q (%d bytes), want %q (%d)", + tt.code, ins.Text, ins.Len, tt.text, len(tt.code)) + } + } +} + +// TestUnknownNamingBoundaries pins what stays untouched: the macro helper +// ADDU16I.D has no toolchain spelling (the assembler never takes it as +// input), so its "Unknown" render is the decoder's own and stays. +func TestUnknownNamingBoundaries(t *testing.T) { + for _, tt := range []struct { + code []byte + text string + }{ + {[]byte{0x84, 0x40, 0x00, 0x10}, "Unknown ADDU16I.D $16, R4"}, + {[]byte{0x85, 0x00, 0x17, 0x00}, "MOVW R4, R5"}, + } { + ins, err := Decode(arch.LOONG64, tt.code, 0) + if err != nil { + t.Errorf("% x: %v", tt.code, err) + continue + } + if ins.Text != tt.text { + t.Errorf("% x: %q, want %q", tt.code, ins.Text, tt.text) + } + } +} diff --git a/disasm/parity_test.go b/disasm/parity_test.go index 7e1dce2..40786a5 100644 --- a/disasm/parity_test.go +++ b/disasm/parity_test.go @@ -208,9 +208,11 @@ var toolchainRenderNames = map[string]bool{ // where the pinned bytes took the alternative). arm64: the CRC32 forms // take the wrong Rm; the register-indexed load and store forms lose the // index operand; BFXIL encodes as BFI with shifted immediates. loong64: -// the SC displacement encodes unscaled. riscv64: FSGNJXS encodes as -// FMIN.S; FCLASSS and FCLASSD encode as MOVF; the AUIPC immediate loses -// its high bits. Keyed by the fixture text. +// the LL and SC displacements encode scaled where the toolchain takes them +// raw ("LL 1024(R5), R4" assembles to a field of 256, and the re-decoded +// text reads 256(R5)). riscv64: FSGNJXS encodes as FMIN.S; FCLASSS and +// FCLASSD encode as MOVF; the AUIPC immediate loses its high bits. Keyed +// by the fixture text. var encoderDivergences = map[string]bool{ "CMOVLE 0(BX), DX": true, "MOVQ FS:0, DX": true, @@ -225,6 +227,9 @@ var encoderDivergences = map[string]bool{ "MOVD R27, (R5)(R15.UXTW<<3)": true, "MOVH R11, (R27)(R14.SXTW<<1)": true, "SC R4, 1024(R5)": true, + "LL 1024(R5), R4": true, + "LLV 1024(R5), R4": true, + "SCV R4, 1024(R5)": true, "FSGNJXS F1, F0, F2": true, "FCLASSS F0, X5": true, "FCLASSD F0, X5": true, diff --git a/disasm/testdata/parity_loong64.txt b/disasm/testdata/parity_loong64.txt index 8d6c0fe..afb45d9 100644 --- a/disasm/testdata/parity_loong64.txt +++ b/disasm/testdata/parity_loong64.txt @@ -8,7 +8,7 @@ a5101800 SRA R4, R5 a5901b00 ROTRV R4, R5 85200000 CLOV R4, R5 85380000 REVB2W R4, R5 -854c0000 Unknown BITREV.8B R4, R5 +854c0000 BITREV8B R4, R5 a6900001 ADDF F4, F5, F6 64608029 MOVW R4, 24(R3) a404c029 MOVV R4, 1(R5) @@ -22,7 +22,7 @@ a404002a MOVBU 1(R5), R4 80040068 BLTU R4, 1(PC) 6460c02b MOVD F4, 24(R3) 85b81401 MOVV F4, R5 -a5101600 Unknown ORN R4, R5 +a5101600 ORN R4, R5 a6901d00 MULV R4, R5, R6 a6901e00 MULHVU R4, R5, R6 a6102200 DIVV R4, R5, R6 @@ -39,9 +39,9 @@ a6102600 CRCCWBW R4, R5, R6 00004003 NOOP a510220c CMPEQD F4, F5, FCC5 80d01401 MOVV F4, FCC0 -85040025 Unknown STPTR.W $4, R4, R5 -a4fc7f24 Unknown LDPTR.W $-4, R5, R4 -a4040026 Unknown LDPTR.D $4, R5, R4 +85040025 MOVWP R5, 4(R4) +a4fc7f24 MOVWP 32764(R5), R4 +a4040026 MOVVP 4(R5), R4 84400010 Unknown ADDU16I.D $16, R4 acb95838 AMCASH R14, (R13), R12 acb96238 AMANDV R14, (R13), R12 @@ -59,7 +59,7 @@ a6100b01 FMIND F4, F5, F6 a6901201 FCOPYSGF F4, F5, F6 01201d01 FFINTDW F0, F1 01441e01 FRINTS F0, F1 -a6900e01 Unknown FMINA.S F4, F5, F6 +a6900e01 FMINAF F4, F5, F6 02241a01 FTINTRMVF F0, F2 02841a01 FTINTRZWF F0, F2 02e41a01 FTINTRNEVF F0, F2 @@ -70,4 +70,316 @@ c2353c38 MOVD F2, (R14)(R13) 8518cf00 BSTRPICKV $15, R4, $6, R5 04a43a03 LU52ID $-343, R0, R4 a484cc02 ADDV $801, R5, R4 -88fcff2a Unknown PRELD $-1, R4, $8 +88fcff2a PRELD -1(R4), $8 +00050048 BFPT 1(PC) +00040048 BFPF 1(PC) +00000050 JMP 0(PC) +8000004c JMP (R4) +00040050 JMP 1(PC) +24000014 LU12IW $1, R4 +855c0000 EXTWB R4, R5 +85580000 EXTWH R4, R5 +8500df00 BSTRPICKV $31, R4, $0, R5 +85001500 MOVV R4, R5 +85fc4303 MOVBU R4, R5 +a6101100 SUB R4, R5, R6 +a6101000 ADD R4, R5, R6 +a6901000 ADDV R4, R5, R6 +a6901400 AND R4, R5, R6 +a5901100 SUBV R4, R5 +a5101000 ADD R4, R5 +a5901000 ADDV R4, R5 +a5901400 AND R4, R5 +05901100 NEGV R4, R5 +a5101700 SLL R4, R5 +a6101700 SLL R4, R5, R6 +a5901700 SRL R4, R5 +a6901700 SRL R4, R5, R6 +a6101800 SRA R4, R5, R6 +a5101b00 ROTR R4, R5 +a6101b00 ROTR R4, R5, R6 +a5901800 SLLV R4, R5 +a6901800 SLLV R4, R5, R6 +a6901b00 ROTRV R4, R5, R6 +85100000 CLOW R4, R5 +85140000 CLZW R4, R5 +85180000 CTOW R4, R5 +851c0000 CTZW R4, R5 +85240000 CLZV R4, R5 +85280000 CTOV R4, R5 +852c0000 CTZV R4, R5 +85300000 REVB2H R4, R5 +85340000 REVB4H R4, R5 +853c0000 REVBV R4, R5 +85400000 REVH2W R4, R5 +85440000 REVHV R4, R5 +85480000 BITREV4B R4, R5 +85500000 BITREVW R4, R5 +85540000 BITREVV R4, R5 +856c0000 CPUCFG R4, R5 +a5900001 ADDF F4, F5 +85041401 ABSF F4, F5 +85181d01 FFINTFV F4, F5 +85941401 MOVF F4, F5 +85981401 MOVD F4, F5 +6460c029 MOVV R4, 24(R3) +64600029 MOVB R4, 24(R3) +a4048029 MOVW R4, 1(R5) +a4040029 MOVB R4, 1(R5) +64408028 MOVW 16(R3), R4 +6440802a MOVWU 16(R3), R4 +6440c028 MOVV 16(R3), R4 +6440002a MOVBU 16(R3), R4 +a4048028 MOVW 1(R5), R4 +a404802a MOVWU 1(R5), R4 +a404c028 MOVV 1(R5), R4 +a4040028 MOVB 1(R5), R4 +8510c002 ADDV $4, R4, R5 +04fcff02 MOVW $-1, R4 +85fcbf02 ADD $-1, R4, R5 +84fcbf02 ADD $-1, R4 +85fcff02 ADDV $-1, R4, R5 +85044003 AND $1, R4, R5 +84044003 AND $1, R4 +85904000 SLL $4, R4, R5 +84904000 SLL $4, R4 +85904400 SRL $4, R4, R5 +85904800 SRA $4, R4, R5 +84904800 SRA $4, R4 +85904c00 ROTR $4, R4, R5 +84904c00 ROTR $4, R4 +85104100 SLLV $4, R4, R5 +85104d00 ROTRV $4, R4, R5 +84104d00 ROTRV $4, R4 +00002b00 SYSCALL +85040058 BEQ R4, R5, 1(PC) +8504005c BNE R4, R5, 1(PC) +80040044 BNE R4, 1(PC) +6440002b MOVF 16(R3), F4 +6440802b MOVD 16(R3), F4 +a404002b MOVF 1(R5), F4 +a404802b MOVD 1(R5), F4 +6460402b MOVF F4, 24(R3) +a404402b MOVF F4, 1(R5) +a404c02b MOVD F4, 1(R5) +85a41401 MOVW R4, F5 +85b41401 MOVW F4, R5 +85a81401 MOVV R4, F5 +00002a00 BREAK +a6901600 ANDN R4, R5, R6 +a5901600 ANDN R4, R5 +a6101600 ORN R4, R5, R6 +a5101c00 MUL R4, R5 +a6101c00 MUL R4, R5, R6 +a5901d00 MULV R4, R5 +a5101e00 MULHV R4, R5 +a6101e00 MULHV R4, R5, R6 +a5901e00 MULHVU R4, R5 +a5902200 REMV R4, R5 +a6902200 REMV R4, R5, R6 +a5902300 REMVU R4, R5 +a6902300 REMVU R4, R5, R6 +a5102200 DIVV R4, R5 +a5102300 DIVVU R4, R5 +a6102300 DIVVU R4, R5, R6 +64604029 MOVH R4, 24(R3) +a4044029 MOVH R4, 1(R5) +64404028 MOVH 16(R3), R4 +8500cf00 MOVHU R4, R5 +6440402a MOVHU 16(R3), R4 +a404402a MOVHU 1(R5), R4 +a6901c00 MULH R4, R5, R6 +a5101d00 MULHU R4, R5 +a6101d00 MULHU R4, R5, R6 +a6902000 REM R4, R5, R6 +a5902100 REMU R4, R5 +a6902100 REMU R4, R5, R6 +a6102000 DIV R4, R5, R6 +a6102100 DIVU R4, R5, R6 +a5101900 SRLV R4, R5 +a6101900 SRLV R4, R5, R6 +85104500 SRLV $4, R4, R5 +84104500 SRLV $4, R4 +84804500 SRLV $32, R4 +a5101f00 MULWVW R4, R5 +a6101f00 MULWVW R4, R5, R6 +a5901f00 MULWVWU R4, R5 +a6901f00 MULWVWU R4, R5, R6 +a6901300 MASKNEZ R4, R5, R6 +a6102400 CRCWBW R4, R5, R6 +a6902400 CRCWHW R4, R5, R6 +a6102500 CRCWWW R4, R5, R6 +a6902500 CRCWVW R4, R5, R6 +a6902600 CRCCWHW R4, R5, R6 +a6102700 CRCCWWW R4, R5, R6 +a6902700 CRCCWVW R4, R5, R6 +85241901 MOVFD F4, F5 +85181901 MOVDF F4, F5 +85041b01 FTINTWF F4, F5 +85201d01 FFINTDW F4, F5 +85081b01 FTINTWD F4, F5 +85141401 NEGF F4, F5 +85181401 NEGD F4, F5 +85881a01 FTINTRZWD F4, F5 +85841a01 FTINTRZWF F4, F5 +85441401 SQRTF F4, F5 +85481401 SQRTD F4, F5 +00007238 DBAR +a010120c CMPEQF F4, F5, FCC0 +a190110c CMPGTF F4, F5, FCC1 +a290210c CMPGTD F4, F5, FCC2 +a390130c CMPGEF F4, F5, FCC3 +a490230c CMPGED F4, F5, FCC4 +80600000 RDTIMELW R4, R0 +80640000 RDTIMEHW R4, R0 +85680000 RDTIMED R4, R5 +83c01401 MOVV R4, FCSR3 +64c81401 MOVV FCSR3, R4 +04d41401 MOVV FCC0, F4 +04dc1401 MOVV FCC0, R4 +80d81401 MOVV R4, FCC0 +85fc7f25 MOVWP R5, 32764(R4) +85200025 MOVWP R5, 32(R4) +85000025 MOVWP R5, 0(R4) +85fc7f27 MOVVP R5, 32764(R4) +85200027 MOVVP R5, 32(R4) +85040027 MOVVP R5, 4(R4) +85000027 MOVVP R5, 0(R4) +a4200024 MOVWP 32(R5), R4 +a4040024 MOVWP 4(R5), R4 +a4000024 MOVWP 0(R5), R4 +a4fc7f26 MOVVP 32764(R5), R4 +a4200026 MOVVP 32(R5), R4 +a4000026 MOVVP 0(R5), R4 +ac395c38 AMSWAPB R14, (R13), R12 +acb95c38 AMSWAPH R14, (R13), R12 +ac396038 AMSWAPW R14, (R13), R12 +acb96038 AMSWAPV R14, (R13), R12 +ac395838 AMCASB R14, (R13), R12 +ac395938 AMCASW R14, (R13), R12 +acb95938 AMCASV R14, (R13), R12 +ac396138 AMADDW R14, (R13), R12 +acb96138 AMADDV R14, (R13), R12 +ac396238 AMANDW R14, (R13), R12 +ac396338 AMORW R14, (R13), R12 +acb96338 AMORV R14, (R13), R12 +ac396438 AMXORW R14, (R13), R12 +acb96438 AMXORV R14, (R13), R12 +ac396538 AMMAXW R14, (R13), R12 +ac396638 AMMINW R14, (R13), R12 +acb96638 AMMINV R14, (R13), R12 +ac396738 AMMAXWU R14, (R13), R12 +acb96738 AMMAXVU R14, (R13), R12 +ac396838 AMMINWU R14, (R13), R12 +ac395e38 AMSWAPDBB R14, (R13), R12 +acb95e38 AMSWAPDBH R14, (R13), R12 +ac396938 AMSWAPDBW R14, (R13), R12 +acb96938 AMSWAPDBV R14, (R13), R12 +ac395a38 AMCASDBB R14, (R13), R12 +ac395b38 AMCASDBW R14, (R13), R12 +acb95b38 AMCASDBV R14, (R13), R12 +ac396a38 AMADDDBW R14, (R13), R12 +acb96a38 AMADDDBV R14, (R13), R12 +ac396b38 AMANDDBW R14, (R13), R12 +ac396c38 AMORDBW R14, (R13), R12 +acb96c38 AMORDBV R14, (R13), R12 +ac396d38 AMXORDBW R14, (R13), R12 +acb96d38 AMXORDBV R14, (R13), R12 +ac396e38 AMMAXDBW R14, (R13), R12 +ac396f38 AMMINDBW R14, (R13), R12 +acb96f38 AMMINDBV R14, (R13), R12 +ac397038 AMMAXDBWU R14, (R13), R12 +acb97038 AMMAXDBVU R14, (R13), R12 +ac397138 AMMINDBWU R14, (R13), R12 +a4001020 LL 1024(R5), R4 +a4001022 LLV 1024(R5), R4 +a4805738 LLACQW (R5), R4 +a4885738 LLACQV (R5), R4 +a4001023 SCV R4, 1024(R5) +c4145738 SCQ R4, R5, (R6) +c4845738 SCRELW R4, (R6) +c48c5738 SCRELV R4, (R6) +ecd22508 FMADDD F11, F20, F23, F12 +f6af5108 FMSUBF F3, F11, F31, F22 +2ff96608 FMSUBD F13, F30, F9, F15 +b5ac9d08 FNMADDF F27, F11, F5, F21 +66bbae08 FNMADDD F29, F14, F27, F6 +71d4ee08 FNMSUBD F29, F21, F3, F17 +29391108 FMADDF F2, F14, F9, F9 +f7d22508 FMADDD F11, F20, F23, F23 +ffaf5108 FMSUBF F3, F11, F31, F31 +29f96608 FMSUBD F13, F30, F9, F9 +7bbbae08 FNMADDD F29, F14, F27, F27 +8ca1d808 FNMSUBF F17, F8, F12, F12 +63d4ee08 FNMSUBD F29, F21, F3, F3 +a6900a01 FMINF F4, F5, F6 +a5900a01 FMINF F4, F5 +a5100b01 FMIND F4, F5 +a6900801 FMAXF F4, F5, F6 +a5900801 FMAXF F4, F5 +a6100901 FMAXD F4, F5, F6 +a5100901 FMAXD F4, F5 +a6101301 FCOPYSGD F4, F5, F6 +85341401 FCLASSF F4, F5 +85381401 FCLASSD F4, F5 +01101d01 FFINTFW F0, F1 +01181d01 FFINTFV F0, F1 +01281d01 FFINTDV F0, F1 +01041b01 FTINTWF F0, F1 +01081b01 FTINTWD F0, F1 +01241b01 FTINTVF F0, F1 +01281b01 FTINTVD F0, F1 +01481e01 FRINTD F0, F1 +a6900c01 FMAXAF F4, F5, F6 +a5900c01 FMAXAF F4, F5 +a6100d01 FMAXAD F4, F5, F6 +a5100d01 FMAXAD F4, F5 +a5900e01 FMINAF F4, F5 +a6100f01 FMINAD F4, F5, F6 +a5100f01 FMINAD F4, F5 +02041a01 FTINTRMWF F0, F2 +02081a01 FTINTRMWD F0, F2 +02281a01 FTINTRMVD F0, F2 +02441a01 FTINTRPWF F0, F2 +02481a01 FTINTRPWD F0, F2 +02641a01 FTINTRPVF F0, F2 +02681a01 FTINTRPVD F0, F2 +02881a01 FTINTRZWD F0, F2 +02a41a01 FTINTRZVF F0, F2 +02a81a01 FTINTRZVD F0, F2 +02c41a01 FTINTRNEWF F0, F2 +02c81a01 FTINTRNEWD F0, F2 +02e81a01 FTINTRNEVD F0, F2 +4304000d FSEL FCC0, F1, F2, F3 +4284000d FSEL FCC1, F1, F2, F2 +cc350038 MOVB (R14)(R13), R12 +cc352038 MOVBU (R14)(R13), R12 +cc352438 MOVHU (R14)(R13), R12 +cc350838 MOVW (R14)(R13), R12 +cc352838 MOVWU (R14)(R13), R12 +cc350c38 MOVV (R14)(R13), R12 +cc351038 MOVB R12, (R14)(R13) +cc351838 MOVW R12, (R14)(R13) +cc351c38 MOVV R12, (R14)(R13) +c2353038 MOVF (R14)(R13), F2 +c2353438 MOVD (R14)(R13), F2 +c2353838 MOVF F2, (R14)(R13) +85006000 BSTRINSW $0, R4, $0, R5 +85007f00 BSTRINSW $31, R4, $0, R5 +85186f00 BSTRINSW $15, R4, $6, R5 +85008000 BSTRINSV $0, R4, $0, R5 +8500bf00 BSTRINSV $63, R4, $0, R5 +85806000 BSTRPICKW $0, R4, $0, R5 +85807f00 BSTRPICKW $31, R4, $0, R5 +85986f00 BSTRPICKW $15, R4, $6, R5 +8500c000 BSTRPICKV $0, R4, $0, R5 +8500ff00 BSTRPICKV $63, R4, $0, R5 +a6901001 FSCALEBF F4, F5, F6 +a6101101 FSCALEBD F4, F5, F6 +85241401 FLOGBF F4, F5 +85281401 FLOGBD F4, F5 +8000c02a PRELD (R4), $0 +9f20c02a PRELD 8(R4), $31 +86940500 ALSLW $4, R4, R5, R6 +86940700 ALSLWU $4, R4, R5, R6 +86942d00 ALSLV $4, R4, R5, R6