From e032330b07eeb00b06a656ec270533a272d59979 Mon Sep 17 00:00:00 2001 From: SimoneN64 Date: Sun, 19 Mar 2023 23:00:29 +0100 Subject: [PATCH] New calling method in JIT --- src/backend/core/JIT.cpp | 11 +- src/backend/core/jit/cop/cop0decode.cpp | 12 +- src/backend/core/jit/cop/cop1decode.cpp | 25 ++--- src/backend/core/jit/decode.cpp | 139 ------------------------ 4 files changed, 19 insertions(+), 168 deletions(-) diff --git a/src/backend/core/JIT.cpp b/src/backend/core/JIT.cpp index a316aee5..c667f740 100644 --- a/src/backend/core/JIT.cpp +++ b/src/backend/core/JIT.cpp @@ -58,7 +58,6 @@ void JIT::Recompile(Mem& mem, u32 pc) { InvalidateCache(); } - Util::debug("Start of block @ PC {:08X}\n", loopPC); code.sub(rsp, 8); while(!prevBranch) { @@ -67,9 +66,9 @@ void JIT::Recompile(Mem& mem, u32 pc) { u32 instr = mem.Read32(regs, loopPC); emitBreakpoint(); - code.mov(rdi, (uintptr_t)®s); + code.mov(rdi, (uintptr_t)this); + code.mov(rsi, instr); - Util::debug("\tInstr: {:08X}, PC: {:08X}\n", instr, loopPC); code.mov(r8, qword[rdi + REG_OFFSET(oldPC)]); code.mov(r9, qword[rdi + REG_OFFSET(pc)]); code.mov(r10, qword[rdi + REG_OFFSET(nextPC)]); @@ -87,7 +86,6 @@ void JIT::Recompile(Mem& mem, u32 pc) { code.add(rsp, 8); code.ret(); - Util::debug("End of block @ PC {:08X}, len: {}\n", loopPC, instrInBlock); dump.write(code.getCode(), code.getSize()); blockCache[startPC >> 20][startPC & 0xFFF] = block; @@ -99,7 +97,7 @@ void JIT::AllocateOuter(u32 pc) { } int JIT::Run() { - /*instrInBlock = 0; + instrInBlock = 0; regs.gpr[0] = 0; regs.prevDelaySlot = regs.delaySlot; regs.delaySlot = false; @@ -129,8 +127,7 @@ int JIT::Run() { FireException(regs, ExceptionCode::Interrupt, 0, false); } - return instrInBlock;*/ - Util::panic("JIT RECOMPILER NOT YET IMPLEMENTED!\n"); + return instrInBlock; } void JIT::Reset() { diff --git a/src/backend/core/jit/cop/cop0decode.cpp b/src/backend/core/jit/cop/cop0decode.cpp index 86dce9c4..62a35f9f 100644 --- a/src/backend/core/jit/cop/cop0decode.cpp +++ b/src/backend/core/jit/cop/cop0decode.cpp @@ -10,22 +10,18 @@ void cop0Decode(Registers& regs, JIT& cpu, u32 instr) { switch(mask_cop) { case 0x00: - code.mov(code.rsi, (u64)instr); code.mov(code.rax, (u64)mfc0); code.call(code.rax); break; case 0x01: - code.mov(code.rsi, (u64)instr); code.mov(code.rax, (u64)dmfc0); code.call(code.rax); break; case 0x04: - code.mov(code.rsi, (u64)instr); code.mov(code.rax, (uintptr_t)mtc0); code.call(code.rax); break; case 0x05: - code.mov(code.rsi, (u64)instr); code.mov(code.rax, (u64)dmtc0); code.call(code.rax); break; @@ -36,14 +32,14 @@ void cop0Decode(Registers& regs, JIT& cpu, u32 instr) { code.call(code.rax); break; case 0x02: - code.and_(code.dword[code.rdi + offsetof(Registers, cop0.index)], 0x3F); - code.mov(code.rsi, code.dword[code.rdi]); + code.mov(code.rcx, code.dword[code.rdi + offsetof(Registers, cop0.index)]); + code.and_(code.rcx, 0x3F); + code.mov(code.rsi, code.rcx); code.mov(code.rax, (u64)tlbw); code.call(code.rax); break; case 0x06: - code.mov(code.rax, (u64)regs.cop0.GetRandom()); - code.mov(code.rsi, code.rax); + code.mov(code.rsi, (u64)regs.cop0.GetRandom()); code.mov(code.rax, (u64)tlbw); code.call(code.rax); break; diff --git a/src/backend/core/jit/cop/cop1decode.cpp b/src/backend/core/jit/cop/cop1decode.cpp index 0a61a264..74ea97e8 100644 --- a/src/backend/core/jit/cop/cop1decode.cpp +++ b/src/backend/core/jit/cop/cop1decode.cpp @@ -10,9 +10,6 @@ bool cop1Decode(Registers& regs, JIT& cpu, u32 instr) { u8 mask_fun = instr & 0x3F; u8 mask_branch = (instr >> 16) & 0x1F; - code.mov(code.rdi, (u64)®s); - code.mov(code.esi, instr); - switch(mask_sub) { // 000r_rccc case 0x00: @@ -28,7 +25,7 @@ bool cop1Decode(Registers& regs, JIT& cpu, u32 instr) { code.call(code.rax); break; case 0x03: - Util::panic("[RECOMPILER] FPU Reserved instruction exception!\n"); + Util::panic("[RECOMPILER] FPU Reserved instruction exception! {:08X}\n", instr); case 0x04: code.mov(code.rax, (u64)mtc1); code.call(code.rax); @@ -42,26 +39,26 @@ bool cop1Decode(Registers& regs, JIT& cpu, u32 instr) { code.call(code.rax); break; case 0x07: - Util::panic("[RECOMPILER] FPU Reserved instruction exception!\n"); + Util::panic("[RECOMPILER] FPU Reserved instruction exception! {:08X}\n", instr); case 0x08: switch(mask_branch) { case 0: - code.mov(code.rdi, !regs.cop1.fcr31.compare); + code.mov(code.rdx, !regs.cop1.fcr31.compare); code.mov(code.rax, (u64)b); code.call(code.rax); return true; case 1: - code.mov(code.rdi, regs.cop1.fcr31.compare); + code.mov(code.rdx, regs.cop1.fcr31.compare); code.mov(code.rax, (u64)b); code.call(code.rax); return true; case 2: - code.mov(code.rdi, !regs.cop1.fcr31.compare); + code.mov(code.rdx, !regs.cop1.fcr31.compare); code.mov(code.rax, (u64)bl); code.call(code.rax); return true; case 3: - code.mov(code.rdi, regs.cop1.fcr31.compare); + code.mov(code.rdx, regs.cop1.fcr31.compare); code.mov(code.rax, (u64)bl); code.call(code.rax); return true; @@ -135,7 +132,7 @@ bool cop1Decode(Registers& regs, JIT& cpu, u32 instr) { code.call(code.rax); break; case 0x20: - Util::panic("[RECOMPILER] FPU Reserved instruction exception!\n"); + Util::panic("[RECOMPILER] FPU Reserved instruction exception! {:08X}\n", instr); case 0x21: code.mov(code.rax, (u64)cvtds); code.call(code.rax); @@ -302,7 +299,7 @@ bool cop1Decode(Registers& regs, JIT& cpu, u32 instr) { code.call(code.rax); break; case 0x21: - Util::panic("[RECOMPILER] FPU Reserved instruction exception!\n"); + Util::panic("[RECOMPILER] FPU Reserved instruction exception! {:08X}\n", instr); case 0x24: code.mov(code.rax, (u64)cvtwd); code.call(code.rax); @@ -421,7 +418,7 @@ bool cop1Decode(Registers& regs, JIT& cpu, u32 instr) { code.call(code.rax); break; case 0x24: - Util::panic("[RECOMPILER] FPU reserved instruction exception!\n"); + Util::panic("[RECOMPILER] FPU Reserved instruction exception! {:08X}\n", instr); default: Util::panic("Unimplemented COP1 function W[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); } break; @@ -452,9 +449,9 @@ bool cop1Decode(Registers& regs, JIT& cpu, u32 instr) { code.call(code.rax); break; case 0x24: - Util::panic("[RECOMPILER] FPU reserved instruction exception!\n"); + Util::panic("[RECOMPILER] FPU Reserved instruction exception! {:08X}\n", instr); case 0x25: - Util::panic("[RECOMPILER] FPU reserved instruction exception!\n"); + Util::panic("[RECOMPILER] FPU Reserved instruction exception! {:08X}\n", instr); default: Util::panic("Unimplemented COP1 function L[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); } break; diff --git a/src/backend/core/jit/decode.cpp b/src/backend/core/jit/decode.cpp index f221a804..26eafb3f 100644 --- a/src/backend/core/jit/decode.cpp +++ b/src/backend/core/jit/decode.cpp @@ -5,10 +5,6 @@ namespace n64 { void JIT::cop2Decode(u32 instr) { - code.mov(rdi, (u64)this); - code.mov(rsi, (u64)®s); - code.mov(rdx, instr); - switch(RS(instr)) { case 0x00: code.mov(rax, (u64)mfc2); @@ -40,44 +36,36 @@ bool JIT::special(u32 instr) { switch (mask) { // TODO: named constants for clearer code case 0: if (instr != 0) { - code.mov(rsi, instr); code.mov(rax, (u64)sll); code.call(rax); } break; case 0x02: - code.mov(rsi, instr); code.mov(rax, (u64)srl); code.call(rax); break; case 0x03: - code.mov(rsi, instr); code.mov(rax, (u64)sra); code.call(rax); break; case 0x04: - code.mov(rsi, instr); code.mov(rax, (u64)sllv); code.call(rax); break; case 0x06: - code.mov(rsi, instr); code.mov(rax, (u64)srlv); code.call(rax); break; case 0x07: - code.mov(rsi, instr); code.mov(rax, (u64)srav); code.call(rax); break; case 0x08: - code.mov(rsi, instr); code.mov(rax, (u64)jr); code.call(rax); res = true; break; case 0x09: - code.mov(rsi, instr); code.mov(rax, (u64)jalr); code.call(rax); res = true; @@ -86,147 +74,118 @@ bool JIT::special(u32 instr) { case 0x0D: Util::panic("[RECOMPILER] Unhandled break instruction {:016X}\n", (u64)regs.pc); case 0x0F: break; // SYNC case 0x10: - code.mov(rsi, instr); code.mov(rax, (u64)mfhi); code.call(rax); break; case 0x11: - code.mov(rsi, instr); code.mov(rax, (u64)mthi); code.call(rax); break; case 0x12: - code.mov(rsi, instr); code.mov(rax, (u64)mflo); code.call(rax); break; case 0x13: - code.mov(rsi, instr); code.mov(rax, (u64)mtlo); code.call(rax); break; case 0x14: - code.mov(rsi, instr); code.mov(rax, (u64)dsllv); code.call(rax); break; case 0x16: - code.mov(rsi, instr); code.mov(rax, (u64)dsrlv); code.call(rax); break; case 0x17: - code.mov(rsi, instr); code.mov(rax, (u64)dsrav); code.call(rax); break; case 0x18: - code.mov(rsi, instr); code.mov(rax, (u64)mult); code.call(rax); break; case 0x19: - code.mov(rsi, instr); code.mov(rax, (u64)multu); code.call(rax); break; case 0x1A: - code.mov(rsi, instr); code.mov(rax, (u64)div); code.call(rax); break; case 0x1B: - code.mov(rsi, instr); code.mov(rax, (u64)divu); code.call(rax); break; case 0x1C: - code.mov(rsi, instr); code.mov(rax, (u64)dmult); code.call(rax); break; case 0x1D: - code.mov(rsi, instr); code.mov(rax, (u64)dmultu); code.call(rax); break; case 0x1E: - code.mov(rsi, instr); code.mov(rax, (u64)ddiv); code.call(rax); break; case 0x1F: - code.mov(rsi, instr); code.mov(rax, (u64)ddivu); code.call(rax); break; case 0x20: - code.mov(rsi, instr); code.mov(rax, (u64)add); code.call(rax); break; case 0x21: - code.mov(rsi, instr); code.mov(rax, (u64)addu); code.call(rax); break; case 0x22: - code.mov(rsi, instr); code.mov(rax, (u64)sub); code.call(rax); break; case 0x23: - code.mov(rsi, instr); code.mov(rax, (u64)subu); code.call(rax); break; case 0x24: - code.mov(rsi, instr); code.mov(rax, (u64)and_); code.call(rax); break; case 0x25: - code.mov(rsi, instr); code.mov(rax, (u64)or_); code.call(rax); break; case 0x26: - code.mov(rsi, instr); code.mov(rax, (u64)xor_); code.call(rax); break; case 0x27: - code.mov(rsi, instr); code.mov(rax, (u64)nor); code.call(rax); break; case 0x2A: - code.mov(rsi, instr); code.mov(rax, (u64)slt); code.call(rax); break; case 0x2B: - code.mov(rsi, instr); code.mov(rax, (u64)sltu); code.call(rax); break; case 0x2C: - code.mov(rsi, instr); code.mov(rax, (u64)dadd); code.call(rax); break; case 0x2D: - code.mov(rsi, instr); code.mov(rax, (u64)daddu); code.call(rax); break; case 0x2E: - code.mov(rsi, instr); code.mov(rax, (u64)dsub); code.call(rax); break; case 0x2F: - code.mov(rsi, instr); code.mov(rax, (u64)dsubu); code.call(rax); break; @@ -291,32 +250,26 @@ bool JIT::special(u32 instr) { res = true; break; case 0x38: - code.mov(rsi, instr); code.mov(rax, (u64)dsll); code.call(rax); break; case 0x3A: - code.mov(rsi, instr); code.mov(rax, (u64)dsrl); code.call(rax); break; case 0x3B: - code.mov(rsi, instr); code.mov(rax, (u64)dsra); code.call(rax); break; case 0x3C: - code.mov(rsi, instr); code.mov(rax, (u64)dsll32); code.call(rax); break; case 0x3E: - code.mov(rsi, instr); code.mov(rax, (u64)dsrl32); code.call(rax); break; case 0x3F: - code.mov(rsi, instr); code.mov(rax, (u64)dsra32); code.call(rax); break; @@ -332,7 +285,6 @@ bool JIT::regimm(u32 instr) { // 000r_rccc switch (mask) { // TODO: named constants for clearer code case 0x00: - code.mov(rsi, instr); code.mov(r8, qword[rdi + GPR_OFFSET(RS(instr))]); code.xor_(rdx, rdx); code.cmp(r8, 0); @@ -341,7 +293,6 @@ bool JIT::regimm(u32 instr) { code.call(rax); break; case 0x01: - code.mov(rsi, instr); code.mov(r8, qword[rdi + GPR_OFFSET(RS(instr))]); code.xor_(rdx, rdx); code.cmp(r8, 0); @@ -350,7 +301,6 @@ bool JIT::regimm(u32 instr) { code.call(rax); break; case 0x02: - code.mov(rsi, instr); code.mov(r8, qword[rdi + GPR_OFFSET(RS(instr))]); code.xor_(rdx, rdx); code.cmp(r8, 0); @@ -359,7 +309,6 @@ bool JIT::regimm(u32 instr) { code.call(rax); break; case 0x03: - code.mov(rsi, instr); code.mov(r8, qword[rdi + GPR_OFFSET(RS(instr))]); code.xor_(rdx, rdx); code.cmp(r8, 0); @@ -416,7 +365,6 @@ bool JIT::regimm(u32 instr) { code.call(rax); break; case 0x10: - code.mov(rsi, instr); code.mov(rcx, qword[rdi + GPR_OFFSET(RS(instr))]); code.xor_(rdx, rdx); code.cmp(rcx, 0); @@ -425,7 +373,6 @@ bool JIT::regimm(u32 instr) { code.call(rax); break; case 0x11: - code.mov(rsi, instr); code.mov(rcx, qword[rdi + GPR_OFFSET(RS(instr))]); code.xor_(rdx, rdx); code.cmp(rcx, 0); @@ -434,7 +381,6 @@ bool JIT::regimm(u32 instr) { code.call(rax); break; case 0x12: - code.mov(rsi, instr); code.mov(rcx, qword[rdi + GPR_OFFSET(RS(instr))]); code.xor_(rdx, rdx); code.cmp(rcx, 0); @@ -443,7 +389,6 @@ bool JIT::regimm(u32 instr) { code.call(rax); break; case 0x13: - code.mov(rsi, instr); code.mov(rcx, qword[rdi + GPR_OFFSET(RS(instr))]); code.xor_(rdx, rdx); code.cmp(rcx, 0); @@ -467,19 +412,16 @@ bool JIT::Exec(Mem& mem, u32 instr) { case 0x00: res = special(instr); break; case 0x01: res = regimm(instr); break; case 0x02: - code.mov(rsi, instr); code.mov(rax, (u64)j); code.call(rax); res = true; break; case 0x03: - code.mov(rsi, instr); code.mov(rax, (u64)jal); code.call(rax); res = true; break; case 0x04: - code.mov(rsi, instr); code.mov(r8, qword[rdi + GPR_OFFSET(RS(instr))]); code.mov(rcx, qword[rdi + GPR_OFFSET(RT(instr))]); code.xor_(rdx, rdx); @@ -490,7 +432,6 @@ bool JIT::Exec(Mem& mem, u32 instr) { res = true; break; case 0x05: - code.mov(rsi, instr); code.mov(r8, qword[rdi + GPR_OFFSET(RS(instr))]); code.mov(rcx, qword[rdi + GPR_OFFSET(RT(instr))]); code.xor_(rdx, rdx); @@ -501,7 +442,6 @@ bool JIT::Exec(Mem& mem, u32 instr) { res = true; break; case 0x06: - code.mov(rsi, instr); code.mov(r8, qword[rdi + GPR_OFFSET(RS(instr))]); code.xor_(rdx, rdx); code.test(r8, r8); @@ -511,7 +451,6 @@ bool JIT::Exec(Mem& mem, u32 instr) { res = true; break; case 0x07: - code.mov(rsi, instr); code.mov(r8, qword[rdi + GPR_OFFSET(RS(instr))]); code.xor_(rdx, rdx); code.test(r8, r8); @@ -521,42 +460,34 @@ bool JIT::Exec(Mem& mem, u32 instr) { res = true; break; case 0x08: - code.mov(rsi, instr); code.mov(rax, (u64)addi); code.call(rax); break; case 0x09: - code.mov(rsi, instr); code.mov(rax, (u64)addiu); code.call(rax); break; case 0x0A: - code.mov(rsi, instr); code.mov(rax, (u64)slti); code.call(rax); break; case 0x0B: - code.mov(rsi, instr); code.mov(rax, (u64)sltiu); code.call(rax); break; case 0x0C: - code.mov(rsi, instr); code.mov(rax, (u64)andi); code.call(rax); break; case 0x0D: - code.mov(rsi, instr); code.mov(rax, (u64)ori); code.call(rax); break; case 0x0E: - code.mov(rsi, instr); code.mov(rax, (u64)xori); code.call(rax); break; case 0x0F: - code.mov(rsi, instr); code.mov(rax, (u64)lui); code.call(rax); break; @@ -564,7 +495,6 @@ bool JIT::Exec(Mem& mem, u32 instr) { case 0x11: res = cop1Decode(regs, *this, instr); break; case 0x12: cop2Decode(instr); break; case 0x14: - code.mov(rsi, instr); code.mov(r8, qword[rdi + GPR_OFFSET(RS(instr))]); code.mov(rcx, qword[rdi + GPR_OFFSET(RT(instr))]); code.xor_(rdx, rdx); @@ -574,7 +504,6 @@ bool JIT::Exec(Mem& mem, u32 instr) { code.call(rax); break; case 0x15: - code.mov(rsi, instr); code.mov(r8, qword[rdi + GPR_OFFSET(RS(instr))]); code.mov(rcx, qword[rdi + GPR_OFFSET(RT(instr))]); code.xor_(rdx, rdx); @@ -584,7 +513,6 @@ bool JIT::Exec(Mem& mem, u32 instr) { code.call(rax); break; case 0x16: - code.mov(rsi, instr); code.mov(r8, qword[rdi + GPR_OFFSET(RS(instr))]); code.xor_(rdx, rdx); code.cmp(r8, 0); @@ -593,7 +521,6 @@ bool JIT::Exec(Mem& mem, u32 instr) { code.call(rax); break; case 0x17: - code.mov(rsi, instr); code.mov(r8, qword[rdi + GPR_OFFSET(RS(instr))]); code.xor_(rdx, rdx); code.cmp(r8, 0); @@ -602,186 +529,120 @@ bool JIT::Exec(Mem& mem, u32 instr) { code.call(rax); break; case 0x18: - code.mov(rsi, instr); code.mov(rax, (u64)daddi); code.call(rax); break; case 0x19: - code.mov(rsi, instr); code.mov(rax, (u64)daddiu); code.call(rax); break; case 0x1A: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)ldl); code.call(rax); break; case 0x1B: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)ldr); code.call(rax); break; case 0x1F: Util::panic("[RECOMPILER] Unhandled reserved instruction exception {:016X}\n", regs.oldPC); break; case 0x20: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)lb); code.call(rax); break; case 0x21: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)lh); code.call(rax); break; case 0x22: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)lwl); code.call(rax); break; case 0x23: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)lw); code.call(rax); break; case 0x24: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)lbu); code.call(rax); break; case 0x25: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)lhu); code.call(rax); break; case 0x26: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)lwr); code.call(rax); break; case 0x27: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)lwu); code.call(rax); break; case 0x28: - code.mov(rsi, (u64)&mem); - code.mov(rdx, (u64)this); - code.mov(rcx, instr); code.mov(rax, (u64)sb); code.call(rax); break; case 0x29: - code.mov(rsi, (u64)&mem); - code.mov(rdx, (u64)this); - code.mov(rcx, instr); code.mov(rax, (u64)sh); code.call(rax); break; case 0x2A: - code.mov(rsi, (u64)&mem); - code.mov(rdx, (u64)this); - code.mov(rcx, instr); code.mov(rax, (u64)swl); code.call(rax); break; case 0x2B: - code.mov(rsi, (u64)&mem); - code.mov(rdx, (u64)this); - code.mov(rcx, instr); code.mov(rax, (u64)sw); code.call(rax); break; case 0x2C: - code.mov(rsi, (u64)&mem); - code.mov(rdx, (u64)this); - code.mov(rcx, instr); code.mov(rax, (u64)sdl); code.call(rax); break; case 0x2D: - code.mov(rsi, (u64)&mem); - code.mov(rdx, (u64)this); - code.mov(rcx, instr); code.mov(rax, (u64)sdr); code.call(rax); break; case 0x2E: - code.mov(rsi, (u64)&mem); - code.mov(rdx, (u64)this); - code.mov(rcx, instr); code.mov(rax, (u64)swr); code.call(rax); break; case 0x2F: break; // CACHE case 0x30: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)ll); code.call(rax); break; case 0x31: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)lwc1); code.call(rax); break; case 0x34: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)lld); code.call(rax); break; case 0x35: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)ldc1); code.call(rax); break; case 0x37: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)ld); code.call(rax); break; case 0x38: - code.mov(rsi, (u64)&mem); - code.mov(rdx, (u64)this); - code.mov(rcx, instr); code.mov(rax, (u64)sc); code.call(rax); break; case 0x39: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)swc1); code.call(rax); break; case 0x3C: - code.mov(rsi, (u64)&mem); - code.mov(rdx, (u64)this); - code.mov(rcx, instr); code.mov(rax, (u64)scd); code.call(rax); break; case 0x3D: - code.mov(rsi, (u64)&mem); - code.mov(rdx, instr); code.mov(rax, (u64)sdc1); code.call(rax); break; case 0x3F: - code.mov(rsi, (u64)&mem); - code.mov(rdx, (u64)this); - code.mov(rcx, instr); code.mov(rax, (u64)sd); code.call(rax); break;