Actually mark scratch registers + comment out branches for now + rework compilation loop a bit
This commit is contained in:
@@ -72,11 +72,9 @@ int JIT::Step() {
|
|||||||
code.setProtectModeRW();
|
code.setProtectModeRW();
|
||||||
|
|
||||||
u32 instructionsInBlock = 0;
|
u32 instructionsInBlock = 0;
|
||||||
|
u32 instruction = 0;
|
||||||
|
|
||||||
bool instrEndsBlock = false;
|
bool instrEndsBlock = false;
|
||||||
bool instrInDelaySlot = false;
|
|
||||||
bool branchWasLikely = false;
|
|
||||||
bool blockEndsOnBranch = false;
|
|
||||||
|
|
||||||
code.sub(code.rsp, 8);
|
code.sub(code.rsp, 8);
|
||||||
code.push(code.rbp);
|
code.push(code.rbp);
|
||||||
@@ -84,7 +82,7 @@ int JIT::Step() {
|
|||||||
|
|
||||||
//cs_insn *insn;
|
//cs_insn *insn;
|
||||||
Util::trace("\tMIPS code (guest PC = 0x{:016X}):", blockPC);
|
Util::trace("\tMIPS code (guest PC = 0x{:016X}):", blockPC);
|
||||||
while (!instrInDelaySlot) {
|
while (!instrEndsBlock) {
|
||||||
// CheckCompareInterrupt();
|
// CheckCompareInterrupt();
|
||||||
|
|
||||||
if (check_address_error(0b11, u64(blockPC))) [[unlikely]] {
|
if (check_address_error(0b11, u64(blockPC))) [[unlikely]] {
|
||||||
@@ -104,7 +102,7 @@ int JIT::Step() {
|
|||||||
static_cast<int>(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD)), static_cast<u64>(blockPC));
|
static_cast<int>(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD)), static_cast<u64>(blockPC));
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32 instruction = mem.Read<u32>(regs, paddr);
|
instruction = mem.Read<u32>(regs, paddr);
|
||||||
|
|
||||||
/*u32 bswapped = bswap(instruction);
|
/*u32 bswapped = bswap(instruction);
|
||||||
auto count = cs_disasm(disassemblerMips, reinterpret_cast<const u8 *>(&bswapped), 4, blockPC, 0, &insn);
|
auto count = cs_disasm(disassemblerMips, reinterpret_cast<const u8 *>(&bswapped), 4, blockPC, 0, &insn);
|
||||||
@@ -127,29 +125,19 @@ int JIT::Step() {
|
|||||||
instructionsInBlock++;
|
instructionsInBlock++;
|
||||||
Emit(instruction);
|
Emit(instruction);
|
||||||
|
|
||||||
instrInDelaySlot = instrEndsBlock;
|
|
||||||
instrEndsBlock = InstrEndsBlock(instruction);
|
instrEndsBlock = InstrEndsBlock(instruction);
|
||||||
if (instrEndsBlock) {
|
|
||||||
branchWasLikely = IsBranchLikely(instruction);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instrInDelaySlot) {
|
|
||||||
blockEndsOnBranch = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instrInDelaySlot && branchWasLikely) {
|
|
||||||
branchWasLikely = false;
|
|
||||||
code.L(branch_likely_not_taken);
|
|
||||||
code.mov(code.rax, blockPC);
|
|
||||||
code.mov(REG(qword, pc), code.rax);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit code to store the value of pc
|
instruction = mem.Read<u32>(regs, paddr);
|
||||||
if (!blockEndsOnBranch) {
|
instrEndsBlock = InstrEndsBlock(instruction);
|
||||||
code.mov(code.rax, blockPC);
|
if(instrEndsBlock)
|
||||||
code.mov(REG(qword, pc), code.rax);
|
Util::panic("Branch in delay slot - YOU SHOULD KILL YOURSELF, NOW!!!");
|
||||||
}
|
|
||||||
|
blockOldPC = blockPC;
|
||||||
|
blockPC = blockNextPC;
|
||||||
|
blockNextPC += 4;
|
||||||
|
instructionsInBlock++;
|
||||||
|
Emit(instruction);
|
||||||
|
|
||||||
code.mov(code.rax, instructionsInBlock);
|
code.mov(code.rax, instructionsInBlock);
|
||||||
code.pop(code.rbp);
|
code.pop(code.rbp);
|
||||||
|
|||||||
@@ -77,6 +77,13 @@ static bool IsBranchLikely(const u32 instr) {
|
|||||||
#define ARG2 rdx
|
#define ARG2 rdx
|
||||||
#define ARG3 r8
|
#define ARG3 r8
|
||||||
#define ARG4 r9
|
#define ARG4 r9
|
||||||
|
#define SCR1 rax
|
||||||
|
#define SCR2 rcx
|
||||||
|
#define SCR3 rdx
|
||||||
|
#define SCR4 r8
|
||||||
|
#define SCR5 r9
|
||||||
|
#define SCR6 r10
|
||||||
|
#define SCR7 r11
|
||||||
#else
|
#else
|
||||||
#define ARG1 rdi
|
#define ARG1 rdi
|
||||||
#define ARG2 rsi
|
#define ARG2 rsi
|
||||||
@@ -84,5 +91,14 @@ static bool IsBranchLikely(const u32 instr) {
|
|||||||
#define ARG4 rcx
|
#define ARG4 rcx
|
||||||
#define ARG5 r8
|
#define ARG5 r8
|
||||||
#define ARG6 r9
|
#define ARG6 r9
|
||||||
|
#define SCR1 rax
|
||||||
|
#define SCR2 rdi
|
||||||
|
#define SCR3 rsi
|
||||||
|
#define SCR4 rdx
|
||||||
|
#define SCR5 rcx
|
||||||
|
#define SCR6 r8
|
||||||
|
#define SCR7 r9
|
||||||
|
#define SCR8 r10
|
||||||
|
#define SCR9 r11
|
||||||
#endif
|
#endif
|
||||||
} // namespace n64
|
} // namespace n64
|
||||||
|
|||||||
@@ -29,26 +29,26 @@ void JIT::add(const u32 instr) {
|
|||||||
|
|
||||||
if (regs.IsRegConstant(RS(instr))) {
|
if (regs.IsRegConstant(RS(instr))) {
|
||||||
const u32 rs = regs.Read<s32>(RS(instr));
|
const u32 rs = regs.Read<s32>(RS(instr));
|
||||||
regs.Read<u32>(RT(instr), code.eax);
|
regs.Read<u32>(RT(instr), code.SCR1.cvt32());
|
||||||
code.add(code.eax, rs);
|
code.add(code.SCR1.cvt32(), rs);
|
||||||
regs.Write<s32>(RD(instr), code.eax);
|
regs.Write<s32>(RD(instr), code.SCR1.cvt32());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regs.IsRegConstant(RT(instr))) {
|
if (regs.IsRegConstant(RT(instr))) {
|
||||||
const u32 rt = regs.Read<s32>(RT(instr));
|
const u32 rt = regs.Read<s32>(RT(instr));
|
||||||
regs.Read<u32>(RS(instr), code.eax);
|
regs.Read<u32>(RS(instr), code.SCR1.cvt32());
|
||||||
code.add(code.eax, rt);
|
code.add(code.SCR1.cvt32(), rt);
|
||||||
regs.Write<s32>(RD(instr), code.eax);
|
regs.Write<s32>(RD(instr), code.SCR1.cvt32());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.Read<u32>(RT(instr), code.eax);
|
regs.Read<u32>(RT(instr), code.SCR1.cvt32());
|
||||||
regs.Read<u32>(RS(instr), code.edi);
|
regs.Read<u32>(RS(instr), code.SCR2.cvt32());
|
||||||
code.add(code.eax, code.edi);
|
code.add(code.SCR1.cvt32(), code.SCR2.cvt32());
|
||||||
regs.Write<s32>(RD(instr), code.eax);
|
regs.Write<s32>(RD(instr), code.SCR1.cvt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::addu(u32 instr) {
|
void JIT::addu(u32 instr) {
|
||||||
@@ -63,24 +63,24 @@ void JIT::addu(u32 instr) {
|
|||||||
|
|
||||||
if (regs.IsRegConstant(RS(instr))) {
|
if (regs.IsRegConstant(RS(instr))) {
|
||||||
const s32 rs = regs.Read<s32>(RS(instr));
|
const s32 rs = regs.Read<s32>(RS(instr));
|
||||||
regs.Read<s32>(RT(instr), code.eax);
|
regs.Read<s32>(RT(instr), code.SCR1.cvt32());
|
||||||
code.add(code.eax, rs);
|
code.add(code.SCR1.cvt32(), rs);
|
||||||
regs.Write<s32>(RD(instr), code.eax);
|
regs.Write<s32>(RD(instr), code.SCR1.cvt32());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regs.IsRegConstant(RT(instr))) {
|
if (regs.IsRegConstant(RT(instr))) {
|
||||||
const s32 rs = regs.Read<s32>(RT(instr));
|
const s32 rs = regs.Read<s32>(RT(instr));
|
||||||
regs.Read<s32>(RS(instr), code.eax);
|
regs.Read<s32>(RS(instr), code.SCR1.cvt32());
|
||||||
code.add(code.eax, rs);
|
code.add(code.SCR1.cvt32(), rs);
|
||||||
regs.Write<s32>(RD(instr), code.eax);
|
regs.Write<s32>(RD(instr), code.SCR1.cvt32());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.Read<s32>(RS(instr), code.eax);
|
regs.Read<s32>(RS(instr), code.SCR1.cvt32());
|
||||||
regs.Read<s32>(RT(instr), code.edi);
|
regs.Read<s32>(RT(instr), code.SCR2.cvt32());
|
||||||
code.add(code.eax, code.edi);
|
code.add(code.SCR1.cvt32(), code.SCR2.cvt32());
|
||||||
regs.Write<s32>(RD(instr), code.eax);
|
regs.Write<s32>(RD(instr), code.SCR1.cvt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::addi(u32 instr) {
|
void JIT::addi(u32 instr) {
|
||||||
@@ -96,9 +96,9 @@ void JIT::addi(u32 instr) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.Read<u32>(RS(instr), code.eax);
|
regs.Read<u32>(RS(instr), code.SCR1.cvt32());
|
||||||
code.add(code.eax, imm);
|
code.add(code.eax, SCR1.cvt32());
|
||||||
regs.Write<s32>(RT(instr), code.eax);
|
regs.Write<s32>(RT(instr), code.SCR1.cvt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::addiu(u32 instr) {
|
void JIT::addiu(u32 instr) {
|
||||||
@@ -111,9 +111,9 @@ void JIT::addiu(u32 instr) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.Read<u32>(RS(instr), code.eax);
|
regs.Read<u32>(RS(instr), code.SCR1.cvt32());
|
||||||
code.add(code.eax, imm);
|
code.add(code.SCR1.cvt32(), imm);
|
||||||
regs.Write<s32>(RT(instr), code.eax);
|
regs.Write<s32>(RT(instr), code.SCR1.cvt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::andi(u32 instr) {
|
void JIT::andi(u32 instr) {
|
||||||
@@ -123,9 +123,9 @@ void JIT::andi(u32 instr) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.Read<s64>(RS(instr), code.rax);
|
regs.Read<s64>(RS(instr), code.SCR1);
|
||||||
code.and_(code.rax, imm);
|
code.and_(code.SCR1, imm);
|
||||||
regs.Write<s64>(RT(instr), code.rax);
|
regs.Write<s64>(RT(instr), code.SCR1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::and_(u32 instr) {
|
void JIT::and_(u32 instr) {
|
||||||
@@ -136,115 +136,24 @@ void JIT::and_(u32 instr) {
|
|||||||
|
|
||||||
if (regs.IsRegConstant(RS(instr))) {
|
if (regs.IsRegConstant(RS(instr))) {
|
||||||
const auto rs = regs.Read<s64>(RS(instr));
|
const auto rs = regs.Read<s64>(RS(instr));
|
||||||
regs.Read<s64>(RT(instr), code.rax);
|
regs.Read<s64>(RT(instr), code.SCR1);
|
||||||
code.and_(code.rax, rs);
|
code.and_(code.SCR1, rs);
|
||||||
regs.Write<s64>(RD(instr), code.rax);
|
regs.Write<s64>(RD(instr), code.SCR1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regs.IsRegConstant(RT(instr))) {
|
if (regs.IsRegConstant(RT(instr))) {
|
||||||
const auto rt = regs.Read<s64>(RT(instr));
|
const auto rt = regs.Read<s64>(RT(instr));
|
||||||
regs.Read<s64>(RS(instr), code.rax);
|
regs.Read<s64>(RS(instr), code.SCR1);
|
||||||
code.and_(code.rax, rt);
|
code.and_(code.SCR1, rt);
|
||||||
regs.Write<s64>(RD(instr), code.rax);
|
regs.Write<s64>(RD(instr), code.SCR1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.Read<s64>(RS(instr), code.rax);
|
regs.Read<s64>(RS(instr), code.SCR1);
|
||||||
regs.Read<s64>(RT(instr), code.rdi);
|
regs.Read<s64>(RT(instr), code.SCR2);
|
||||||
code.and_(code.rdi, code.rax);
|
code.and_(code.SCR2, code.SCR1);
|
||||||
regs.Write<s64>(RD(instr), code.rdi);
|
regs.Write<s64>(RD(instr), code.SCR2);
|
||||||
}
|
|
||||||
|
|
||||||
void JIT::SkipSlot() { code.jmp("not_taken"); }
|
|
||||||
|
|
||||||
void JIT::SkipSlotConstant() {
|
|
||||||
blockOldPC = blockPC;
|
|
||||||
blockPC = blockNextPC;
|
|
||||||
blockNextPC = blockPC + 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JIT::BranchTaken(const s64 offs) {
|
|
||||||
code.mov(code.rax, blockPC + offs);
|
|
||||||
code.mov(REG(qword, pc), code.rax);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JIT::BranchNotTaken() {
|
|
||||||
code.mov(code.rax, blockPC + 4);
|
|
||||||
code.mov(REG(qword, pc), code.rax);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JIT::BranchTaken(const Xbyak::Reg64 &offs) {
|
|
||||||
code.add(offs, blockPC);
|
|
||||||
code.mov(REG(qword, pc), offs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JIT::BranchAbsTaken(const s64 addr) {
|
|
||||||
code.mov(code.rax, addr);
|
|
||||||
code.mov(REG(qword, pc), code.rax);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JIT::BranchAbsTaken(const Xbyak::Reg64 &addr) { code.mov(REG(qword, pc), addr); }
|
|
||||||
|
|
||||||
#define branch(offs, cond) \
|
|
||||||
do { \
|
|
||||||
Xbyak::Label taken, not_taken; \
|
|
||||||
code.j##cond(taken); \
|
|
||||||
BranchNotTaken(); \
|
|
||||||
code.jmp(not_taken); \
|
|
||||||
code.L(taken); \
|
|
||||||
BranchTaken(offs); \
|
|
||||||
code.L(not_taken); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
#define branch_abs(addr, cond) \
|
|
||||||
do { \
|
|
||||||
Xbyak::Label taken, not_taken; \
|
|
||||||
code.j##cond(taken); \
|
|
||||||
BranchNotTaken(); \
|
|
||||||
code.jmp(not_taken); \
|
|
||||||
code.L(taken); \
|
|
||||||
BranchAbsTaken(addr); \
|
|
||||||
code.L(not_taken); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
#define branch_likely(offs, cond) \
|
|
||||||
do { \
|
|
||||||
Xbyak::Label taken; \
|
|
||||||
code.j##cond(taken); \
|
|
||||||
SkipSlot(); \
|
|
||||||
code.jmp(branch_likely_not_taken); \
|
|
||||||
code.L(taken); \
|
|
||||||
BranchTaken(offs); \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
void JIT::branch_constant(const bool cond, const s64 offset) {
|
|
||||||
if (cond) {
|
|
||||||
BranchTaken(offset);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BranchNotTaken();
|
|
||||||
}
|
|
||||||
|
|
||||||
void JIT::branch_likely_constant(const bool cond, const s64 offset) {
|
|
||||||
if (cond) {
|
|
||||||
BranchTaken(offset);
|
|
||||||
} else {
|
|
||||||
SkipSlotConstant();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JIT::branch_abs_constant(const bool cond, const s64 address) {
|
|
||||||
if (cond) {
|
|
||||||
BranchAbsTaken(address);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BranchNotTaken();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::bfc0(u32 instr) {
|
void JIT::bfc0(u32 instr) {
|
||||||
@@ -282,7 +191,7 @@ void JIT::blfc1(u32 instr) {
|
|||||||
// code.test(code.al, code.al);
|
// code.test(code.al, code.al);
|
||||||
// branch_likely(address, nz);
|
// branch_likely(address, nz);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
void JIT::bltz(const u32 instr) {
|
void JIT::bltz(const u32 instr) {
|
||||||
const s16 imm = instr;
|
const s16 imm = instr;
|
||||||
const s64 offset = u64((s64)imm) << 2;
|
const s64 offset = u64((s64)imm) << 2;
|
||||||
@@ -562,7 +471,7 @@ void JIT::bgtzl(const u32 instr) {
|
|||||||
code.cmp(code.rax, 0);
|
code.cmp(code.rax, 0);
|
||||||
branch_likely(offset, g);
|
branch_likely(offset, g);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
void JIT::dadd(u32 instr) {
|
void JIT::dadd(u32 instr) {
|
||||||
if (regs.IsRegConstant(RS(instr), RT(instr))) {
|
if (regs.IsRegConstant(RS(instr), RT(instr))) {
|
||||||
auto rs = regs.Read<u64>(RS(instr));
|
auto rs = regs.Read<u64>(RS(instr));
|
||||||
@@ -578,24 +487,24 @@ void JIT::dadd(u32 instr) {
|
|||||||
|
|
||||||
if (regs.IsRegConstant(RS(instr))) {
|
if (regs.IsRegConstant(RS(instr))) {
|
||||||
auto rs = regs.Read<u64>(RS(instr));
|
auto rs = regs.Read<u64>(RS(instr));
|
||||||
regs.Read<u64>(RT(instr), code.rax);
|
regs.Read<u64>(RT(instr), code.SCR1);
|
||||||
code.add(code.rax, rs);
|
code.add(code.SCR1, rs);
|
||||||
regs.Write<u64>(RD(instr), code.rax);
|
regs.Write<u64>(RD(instr), code.SCR1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regs.IsRegConstant(RT(instr))) {
|
if (regs.IsRegConstant(RT(instr))) {
|
||||||
auto rt = regs.Read<u64>(RT(instr));
|
auto rt = regs.Read<u64>(RT(instr));
|
||||||
regs.Read<u64>(RS(instr), code.rax);
|
regs.Read<u64>(RS(instr), code.SCR1);
|
||||||
code.add(code.rax, rt);
|
code.add(code.SCR1, rt);
|
||||||
regs.Write<u64>(RD(instr), code.rax);
|
regs.Write<u64>(RD(instr), code.SCR1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.Read<u64>(RS(instr), code.rax);
|
regs.Read<u64>(RS(instr), code.SCR1);
|
||||||
regs.Read<u64>(RT(instr), code.rdi);
|
regs.Read<u64>(RT(instr), code.SCR2);
|
||||||
code.add(code.rax, code.rdi);
|
code.add(code.SCR1, code.SCR2);
|
||||||
regs.Write<u64>(RD(instr), code.rax);
|
regs.Write<u64>(RD(instr), code.SCR1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::daddu(u32 instr) {
|
void JIT::daddu(u32 instr) {
|
||||||
@@ -616,9 +525,9 @@ void JIT::daddi(u32 instr) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.Read<u64>(RS(instr), code.rax);
|
regs.Read<u64>(RS(instr), code.SCR1);
|
||||||
code.add(code.rax, imm);
|
code.add(code.SCR1, imm);
|
||||||
regs.Write<u64>(RT(instr), code.rax);
|
regs.Write<u64>(RT(instr), code.SCR1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::daddiu(u32 instr) {
|
void JIT::daddiu(u32 instr) {
|
||||||
@@ -874,6 +783,7 @@ void JIT::dsubu(u32 instr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void JIT::j(const u32 instr) {
|
void JIT::j(const u32 instr) {
|
||||||
const s32 target = (instr & 0x3ffffff) << 2;
|
const s32 target = (instr & 0x3ffffff) << 2;
|
||||||
const s64 address = (blockOldPC & ~0xfffffff) | target;
|
const s64 address = (blockOldPC & ~0xfffffff) | target;
|
||||||
@@ -890,7 +800,7 @@ void JIT::jr(const u32 instr) {
|
|||||||
regs.Read<s64>(RS(instr), code.rax);
|
regs.Read<s64>(RS(instr), code.rax);
|
||||||
branch_abs(code.rax, mp);
|
branch_abs(code.rax, mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::jal(const u32 instr) {
|
void JIT::jal(const u32 instr) {
|
||||||
regs.Write<s64>(31, blockNextPC);
|
regs.Write<s64>(31, blockNextPC);
|
||||||
j(instr);
|
j(instr);
|
||||||
@@ -900,6 +810,7 @@ void JIT::jalr(const u32 instr) {
|
|||||||
regs.Write<s64>(RD(instr), blockNextPC);
|
regs.Write<s64>(RD(instr), blockNextPC);
|
||||||
jr(instr);
|
jr(instr);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void JIT::lbu(u32 instr) {
|
void JIT::lbu(u32 instr) {
|
||||||
if (regs.IsRegConstant(RS(instr))) {
|
if (regs.IsRegConstant(RS(instr))) {
|
||||||
@@ -1146,8 +1057,8 @@ void JIT::mfhi(u32 instr) {
|
|||||||
if (regs.GetHIConstant()) {
|
if (regs.GetHIConstant()) {
|
||||||
regs.Write(RD(instr), regs.hi);
|
regs.Write(RD(instr), regs.hi);
|
||||||
} else {
|
} else {
|
||||||
code.mov(code.rax, REG(qword, hi));
|
code.mov(code.SCR1, REG(qword, hi));
|
||||||
regs.Write<s64>(RD(instr), code.rax);
|
regs.Write<s64>(RD(instr), code.SCR1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1155,8 +1066,8 @@ void JIT::mflo(u32 instr) {
|
|||||||
if (regs.GetLOConstant()) {
|
if (regs.GetLOConstant()) {
|
||||||
regs.Write(RD(instr), regs.lo);
|
regs.Write(RD(instr), regs.lo);
|
||||||
} else {
|
} else {
|
||||||
code.mov(code.rax, REG(qword, lo));
|
code.mov(code.SCR1, REG(qword, lo));
|
||||||
regs.Write<s64>(RD(instr), code.rax);
|
regs.Write<s64>(RD(instr), code.SCR1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1193,8 +1104,8 @@ void JIT::mthi(u32 instr) {
|
|||||||
regs.hi = regs.Read<s64>(RS(instr));
|
regs.hi = regs.Read<s64>(RS(instr));
|
||||||
regs.SetHIConstant();
|
regs.SetHIConstant();
|
||||||
} else {
|
} else {
|
||||||
regs.Read<s64>(RS(instr), code.rax);
|
regs.Read<s64>(RS(instr), code.SCR1);
|
||||||
code.mov(REG(qword, hi), code.rax);
|
code.mov(REG(qword, hi), code.SCR1);
|
||||||
regs.UnsetHIConstant();
|
regs.UnsetHIConstant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1204,8 +1115,8 @@ void JIT::mtlo(u32 instr) {
|
|||||||
regs.lo = regs.Read<s64>(RS(instr));
|
regs.lo = regs.Read<s64>(RS(instr));
|
||||||
regs.SetLOConstant();
|
regs.SetLOConstant();
|
||||||
} else {
|
} else {
|
||||||
regs.Read<s64>(RS(instr), code.rax);
|
regs.Read<s64>(RS(instr), code.SCR1);
|
||||||
code.mov(REG(qword, lo), code.rax);
|
code.mov(REG(qword, lo), code.SCR1);
|
||||||
regs.UnsetLOConstant();
|
regs.UnsetLOConstant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1245,27 +1156,27 @@ void JIT::slt(u32 instr) {
|
|||||||
|
|
||||||
if (regs.IsRegConstant(RT(instr))) {
|
if (regs.IsRegConstant(RT(instr))) {
|
||||||
s64 rt = regs.Read<s64>(RT(instr));
|
s64 rt = regs.Read<s64>(RT(instr));
|
||||||
regs.Read<s64>(RS(instr), code.rax);
|
regs.Read<s64>(RS(instr), code.SCR1);
|
||||||
code.cmp(code.rax, rt);
|
code.cmp(code.SCR1, rt);
|
||||||
code.setl(code.al);
|
code.setl(code.SCR1.cvt8());
|
||||||
regs.Write<bool>(RD(instr), code.al);
|
regs.Write<bool>(RD(instr), code.SCR1.cvt8());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regs.IsRegConstant(RS(instr))) {
|
if (regs.IsRegConstant(RS(instr))) {
|
||||||
s64 rs = regs.Read<s64>(RS(instr));
|
s64 rs = regs.Read<s64>(RS(instr));
|
||||||
regs.Read<s64>(RT(instr), code.rax);
|
regs.Read<s64>(RT(instr), code.SCR1);
|
||||||
code.cmp(code.rax, rs);
|
code.cmp(code.SCR1, rs);
|
||||||
code.setge(code.al);
|
code.setge(code.SCR1.cvt8());
|
||||||
regs.Write<bool>(RD(instr), code.al);
|
regs.Write<bool>(RD(instr), code.SCR1.cvt8());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.Read<s64>(RS(instr), code.rax);
|
regs.Read<s64>(RS(instr), code.SCR1);
|
||||||
regs.Read<s64>(RT(instr), code.rdx);
|
regs.Read<s64>(RT(instr), code.SCR2);
|
||||||
code.cmp(code.rax, code.rdx);
|
code.cmp(code.SCR1, code.SCR2);
|
||||||
code.setl(code.al);
|
code.setl(code.SCR1.cvt8());
|
||||||
regs.Write<bool>(RD(instr), code.al);
|
regs.Write<bool>(RD(instr), code.SCR1.cvt8());
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::sltu(u32 instr) {
|
void JIT::sltu(u32 instr) {
|
||||||
@@ -1282,9 +1193,9 @@ void JIT::sll(u32 instr) {
|
|||||||
const s32 result = regs.Read<s64>(RT(instr)) << sa;
|
const s32 result = regs.Read<s64>(RT(instr)) << sa;
|
||||||
regs.Write(RD(instr), (s64)result);
|
regs.Write(RD(instr), (s64)result);
|
||||||
} else {
|
} else {
|
||||||
regs.Read<s64>(RT(instr), code.rax);
|
regs.Read<s64>(RT(instr), code.SCR1);
|
||||||
code.sal(code.rax, sa);
|
code.sal(code.SCR1, sa);
|
||||||
regs.Write<s32>(RD(instr), code.eax);
|
regs.Write<s32>(RD(instr), code.SCR1.cvt32());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1432,7 +1343,7 @@ void JIT::sw(const u32 instr) {
|
|||||||
const s16 offset = instr;
|
const s16 offset = instr;
|
||||||
code.mov(code.ARG2, Cop0::STORE);
|
code.mov(code.ARG2, Cop0::STORE);
|
||||||
|
|
||||||
regs.Read<s64>(RS(instr), code.rdx);
|
regs.Read<s64>(RS(instr), code.ARG3);
|
||||||
code.add(code.ARG3, offset);
|
code.add(code.ARG3, offset);
|
||||||
|
|
||||||
code.mov(code.ARG4, reinterpret_cast<uintptr_t>(&physical));
|
code.mov(code.ARG4, reinterpret_cast<uintptr_t>(&physical));
|
||||||
@@ -1471,9 +1382,9 @@ void JIT::ori(u32 instr) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs.Read<s64>(RS(instr), code.rax);
|
regs.Read<s64>(RS(instr), code.SCR1);
|
||||||
code.or_(code.rax, imm);
|
code.or_(code.SCR1, imm);
|
||||||
regs.Write<s64>(RT(instr), code.rax);
|
regs.Write<s64>(RT(instr), code.SCR1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JIT::xori(u32 instr) {
|
void JIT::xori(u32 instr) {
|
||||||
|
|||||||
Reference in New Issue
Block a user