New calling method in JIT

This commit is contained in:
SimoneN64
2023-03-19 23:00:29 +01:00
parent fbfdbe730e
commit e032330b07
4 changed files with 19 additions and 168 deletions

View File

@@ -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)&regs);
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<char*>(), 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() {

View File

@@ -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;

View File

@@ -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)&regs);
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;

View File

@@ -5,10 +5,6 @@
namespace n64 {
void JIT::cop2Decode(u32 instr) {
code.mov(rdi, (u64)this);
code.mov(rsi, (u64)&regs);
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;