[JIT]: Remove redundant register write logic for constant propagation (i.e. if we're writing a simple variable, it's always constant)

This commit is contained in:
Simone
2025-01-22 11:33:04 +01:00
committed by GitHub
parent 0c0e857a6c
commit 9c78d71a29
3 changed files with 80 additions and 212 deletions

View File

@@ -10,7 +10,7 @@ using namespace Xbyak::util;
void JIT::lui(const u32 instr) { void JIT::lui(const u32 instr) {
u64 val = static_cast<s64>(static_cast<s16>(instr)); u64 val = static_cast<s64>(static_cast<s16>(instr));
val <<= 16; val <<= 16;
regs.Write<s64>(RT(instr), val, true); regs.Write<s64>(RT(instr), val);
} }
void JIT::add(const u32 instr) { void JIT::add(const u32 instr) {
@@ -23,7 +23,7 @@ void JIT::add(const u32 instr) {
Util::panic("[JIT]: Unhandled Overflow exception in ADD!"); Util::panic("[JIT]: Unhandled Overflow exception in ADD!");
} }
regs.Write<s32>(RD(instr), result, true); regs.Write<s32>(RD(instr), result);
return; return;
} }
@@ -57,7 +57,7 @@ void JIT::addu(u32 instr) {
const s32 rt = regs.Read<s32>(RT(instr)); const s32 rt = regs.Read<s32>(RT(instr));
const s32 result = rs + rt; const s32 result = rs + rt;
regs.Write<s32>(RD(instr), result, true); regs.Write<s32>(RD(instr), result);
return; return;
} }
@@ -92,7 +92,7 @@ void JIT::addi(u32 instr) {
Util::panic("[JIT]: Unhandled Overflow exception in ADDI!"); Util::panic("[JIT]: Unhandled Overflow exception in ADDI!");
} }
regs.Write<s32>(RT(instr), static_cast<s32>(result), true); regs.Write<s32>(RT(instr), static_cast<s32>(result));
return; return;
} }
@@ -106,7 +106,7 @@ void JIT::addiu(u32 instr) {
if (regs.IsRegConstant(RS(instr))) { if (regs.IsRegConstant(RS(instr))) {
auto rs = regs.Read<u32>(RS(instr)); auto rs = regs.Read<u32>(RS(instr));
u32 result = rs + imm; u32 result = rs + imm;
regs.Write(RT(instr), s32(result), true); regs.Write(RT(instr), s32(result));
return; return;
} }
@@ -119,7 +119,7 @@ void JIT::addiu(u32 instr) {
void JIT::andi(u32 instr) { void JIT::andi(u32 instr) {
const s64 imm = static_cast<u16>(instr); const s64 imm = static_cast<u16>(instr);
if (regs.IsRegConstant(RS(instr))) { if (regs.IsRegConstant(RS(instr))) {
regs.Write(RT(instr), regs.Read<s64>(RS(instr)) & imm, true); regs.Write(RT(instr), regs.Read<s64>(RS(instr)) & imm);
return; return;
} }
@@ -130,7 +130,7 @@ void JIT::andi(u32 instr) {
void JIT::and_(u32 instr) { void JIT::and_(u32 instr) {
if (regs.IsRegConstant(RS(instr), RT(instr))) { if (regs.IsRegConstant(RS(instr), RT(instr))) {
regs.Write(RD(instr), regs.Read<s64>(RS(instr)) & regs.Read<s64>(RT(instr)), true); regs.Write(RD(instr), regs.Read<s64>(RS(instr)) & regs.Read<s64>(RT(instr)));
return; return;
} }
@@ -317,7 +317,7 @@ void JIT::bgezl(const u32 instr) {
void JIT::bltzal(const u32 instr) { void JIT::bltzal(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;
regs.Write<s64>(31, blockPC + 4, true); regs.Write<s64>(31, blockPC + 4);
if (regs.IsRegConstant(RS(instr))) { if (regs.IsRegConstant(RS(instr))) {
branch_constant(regs.Read<s64>(RS(instr)) < 0, offset); branch_constant(regs.Read<s64>(RS(instr)) < 0, offset);
return; return;
@@ -331,7 +331,7 @@ void JIT::bltzal(const u32 instr) {
void JIT::bgezal(const u32 instr) { void JIT::bgezal(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;
regs.Write<s64>(31, blockPC + 4, true); regs.Write<s64>(31, blockPC + 4);
if (regs.IsRegConstant(RS(instr))) { if (regs.IsRegConstant(RS(instr))) {
branch_constant(regs.Read<s64>(RS(instr)) >= 0, offset); branch_constant(regs.Read<s64>(RS(instr)) >= 0, offset);
return; return;
@@ -345,7 +345,7 @@ void JIT::bgezal(const u32 instr) {
void JIT::bltzall(const u32 instr) { void JIT::bltzall(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;
regs.Write<s64>(31, blockPC + 4, true); regs.Write<s64>(31, blockPC + 4);
if (regs.IsRegConstant(RS(instr))) { if (regs.IsRegConstant(RS(instr))) {
branch_likely_constant(regs.Read<s64>(RS(instr)) < 0, offset); branch_likely_constant(regs.Read<s64>(RS(instr)) < 0, offset);
return; return;
@@ -359,7 +359,7 @@ void JIT::bltzall(const u32 instr) {
void JIT::bgezall(const u32 instr) { void JIT::bgezall(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;
regs.Write<s64>(31, blockPC + 4, true); regs.Write<s64>(31, blockPC + 4);
if (regs.IsRegConstant(RS(instr))) { if (regs.IsRegConstant(RS(instr))) {
branch_likely_constant(regs.Read<s64>(RS(instr)) >= 0, offset); branch_likely_constant(regs.Read<s64>(RS(instr)) >= 0, offset);
return; return;
@@ -543,7 +543,7 @@ void JIT::dadd(u32 instr) {
// regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC); // regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC);
Util::panic("[JIT]: Unhandled Overflow exception in DADD!"); Util::panic("[JIT]: Unhandled Overflow exception in DADD!");
} }
regs.Write(RD(instr), result, true); regs.Write(RD(instr), result);
} else { } else {
Util::panic("[JIT]: Implement non constant DADD!"); Util::panic("[JIT]: Implement non constant DADD!");
} }
@@ -553,7 +553,7 @@ void JIT::daddu(u32 instr) {
if (regs.IsRegConstant(RS(instr), RT(instr))) { if (regs.IsRegConstant(RS(instr), RT(instr))) {
auto rs = regs.Read<s64>(RS(instr)); auto rs = regs.Read<s64>(RS(instr));
auto rt = regs.Read<s64>(RT(instr)); auto rt = regs.Read<s64>(RT(instr));
regs.Write(RD(instr), rt + rs, true); regs.Write(RD(instr), rt + rs);
} else { } else {
Util::panic("[JIT]: Implement non constant DADD!"); Util::panic("[JIT]: Implement non constant DADD!");
} }
@@ -568,7 +568,7 @@ void JIT::daddi(u32 instr) {
// regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC); // regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC);
Util::panic("[JIT]: Unhandled Overflow exception in DADDI!"); Util::panic("[JIT]: Unhandled Overflow exception in DADDI!");
} }
regs.Write(RT(instr), result, true); regs.Write(RT(instr), result);
} else { } else {
Util::panic("[JIT]: Implement non constant DADDI!"); Util::panic("[JIT]: Implement non constant DADDI!");
} }
@@ -578,7 +578,7 @@ void JIT::daddiu(u32 instr) {
if (regs.IsRegConstant(RS(instr))) { if (regs.IsRegConstant(RS(instr))) {
s16 imm = s16(instr); s16 imm = s16(instr);
auto rs = regs.Read<s64>(RS(instr)); auto rs = regs.Read<s64>(RS(instr));
regs.Write(RT(instr), imm + rs, true); regs.Write(RT(instr), imm + rs);
} else { } else {
Util::panic("[JIT]: Implement non constant DADDI!"); Util::panic("[JIT]: Implement non constant DADDI!");
} }
@@ -712,7 +712,7 @@ void JIT::dsll(u32 instr) {
if (regs.IsRegConstant(RT(instr))) { if (regs.IsRegConstant(RT(instr))) {
u8 sa = ((instr >> 6) & 0x1f); u8 sa = ((instr >> 6) & 0x1f);
auto result = regs.Read<s64>(RT(instr)) << sa; auto result = regs.Read<s64>(RT(instr)) << sa;
regs.Write(RD(instr), result, true); regs.Write(RD(instr), result);
} else { } else {
Util::panic("[JIT]: Implement non constant DSLL!"); Util::panic("[JIT]: Implement non constant DSLL!");
} }
@@ -722,7 +722,7 @@ void JIT::dsllv(u32 instr) {
if (regs.IsRegConstant(RT(instr), RS(instr))) { if (regs.IsRegConstant(RT(instr), RS(instr))) {
auto sa = regs.Read<s64>(RS(instr)) & 63; auto sa = regs.Read<s64>(RS(instr)) & 63;
auto result = regs.Read<s64>(RT(instr)) << sa; auto result = regs.Read<s64>(RT(instr)) << sa;
regs.Write(RD(instr), result, true); regs.Write(RD(instr), result);
} else { } else {
Util::panic("[JIT]: Implement non constant DSLLV!"); Util::panic("[JIT]: Implement non constant DSLLV!");
} }
@@ -732,7 +732,7 @@ void JIT::dsll32(u32 instr) {
if (regs.IsRegConstant(RT(instr))) { if (regs.IsRegConstant(RT(instr))) {
u8 sa = ((instr >> 6) & 0x1f); u8 sa = ((instr >> 6) & 0x1f);
auto result = regs.Read<s64>(RT(instr)) << (sa + 32); auto result = regs.Read<s64>(RT(instr)) << (sa + 32);
regs.Write(RD(instr), result, true); regs.Write(RD(instr), result);
} else { } else {
Util::panic("[JIT]: Implement non constant DSLL32!"); Util::panic("[JIT]: Implement non constant DSLL32!");
} }
@@ -743,7 +743,7 @@ void JIT::dsra(u32 instr) {
auto rt = regs.Read<s64>(RT(instr)); auto rt = regs.Read<s64>(RT(instr));
u8 sa = ((instr >> 6) & 0x1f); u8 sa = ((instr >> 6) & 0x1f);
s64 result = rt >> sa; s64 result = rt >> sa;
regs.Write(RD(instr), result, true); regs.Write(RD(instr), result);
} else { } else {
Util::panic("[JIT]: Implement non constant DSRA!"); Util::panic("[JIT]: Implement non constant DSRA!");
} }
@@ -755,7 +755,7 @@ void JIT::dsrav(u32 instr) {
auto rs = regs.Read<s64>(RS(instr)); auto rs = regs.Read<s64>(RS(instr));
s64 sa = rs & 63; s64 sa = rs & 63;
s64 result = rt >> sa; s64 result = rt >> sa;
regs.Write(RD(instr), result, true); regs.Write(RD(instr), result);
} else { } else {
Util::panic("[JIT]: Implement non constant DSRAV!"); Util::panic("[JIT]: Implement non constant DSRAV!");
} }
@@ -766,7 +766,7 @@ void JIT::dsra32(u32 instr) {
auto rt = regs.Read<s64>(RT(instr)); auto rt = regs.Read<s64>(RT(instr));
u8 sa = ((instr >> 6) & 0x1f); u8 sa = ((instr >> 6) & 0x1f);
s64 result = rt >> (sa + 32); s64 result = rt >> (sa + 32);
regs.Write(RD(instr), result, true); regs.Write(RD(instr), result);
} else { } else {
Util::panic("[JIT]: Implement non constant DSRA32!"); Util::panic("[JIT]: Implement non constant DSRA32!");
} }
@@ -777,7 +777,7 @@ void JIT::dsrl(u32 instr) {
auto rt = regs.Read<u64>(RT(instr)); auto rt = regs.Read<u64>(RT(instr));
u8 sa = ((instr >> 6) & 0x1f); u8 sa = ((instr >> 6) & 0x1f);
u64 result = rt >> sa; u64 result = rt >> sa;
regs.Write(RD(instr), s64(result), true); regs.Write(RD(instr), s64(result));
} else { } else {
Util::panic("[JIT]: Implement non constant DSRL!"); Util::panic("[JIT]: Implement non constant DSRL!");
} }
@@ -788,7 +788,7 @@ void JIT::dsrlv(u32 instr) {
u8 amount = regs.Read<u8>(RS(instr)) & 63; u8 amount = regs.Read<u8>(RS(instr)) & 63;
auto rt = regs.Read<u64>(RT(instr)); auto rt = regs.Read<u64>(RT(instr));
u64 result = rt >> amount; u64 result = rt >> amount;
regs.Write(RD(instr), s64(result), true); regs.Write(RD(instr), s64(result));
} else { } else {
Util::panic("[JIT]: Implement non constant DSRLV!"); Util::panic("[JIT]: Implement non constant DSRLV!");
} }
@@ -799,7 +799,7 @@ void JIT::dsrl32(u32 instr) {
auto rt = regs.Read<u64>(RT(instr)); auto rt = regs.Read<u64>(RT(instr));
u8 sa = ((instr >> 6) & 0x1f); u8 sa = ((instr >> 6) & 0x1f);
u64 result = rt >> (sa + 32); u64 result = rt >> (sa + 32);
regs.Write(RD(instr), s64(result), true); regs.Write(RD(instr), s64(result));
} else { } else {
Util::panic("[JIT]: Implement non constant DSRL32!"); Util::panic("[JIT]: Implement non constant DSRL32!");
} }
@@ -814,7 +814,7 @@ void JIT::dsub(u32 instr) {
// regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC); // regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC);
Util::panic("[JIT]: Unhandled Overflow exception in DSUB!"); Util::panic("[JIT]: Unhandled Overflow exception in DSUB!");
} else { } else {
regs.Write(RD(instr), result, true); regs.Write(RD(instr), result);
} }
} else { } else {
Util::panic("[JIT]: Implement non constant DSUB!"); Util::panic("[JIT]: Implement non constant DSUB!");
@@ -826,7 +826,7 @@ void JIT::dsubu(u32 instr) {
auto rt = regs.Read<s64>(RT(instr)); auto rt = regs.Read<s64>(RT(instr));
auto rs = regs.Read<s64>(RS(instr)); auto rs = regs.Read<s64>(RS(instr));
s64 result = rs - rt; s64 result = rs - rt;
regs.Write(RD(instr), result, true); regs.Write(RD(instr), result);
} else { } else {
Util::panic("[JIT]: Implement non constant DSUBU!"); Util::panic("[JIT]: Implement non constant DSUBU!");
} }
@@ -851,12 +851,12 @@ void JIT::jr(const u32 instr) {
} }
void JIT::jal(const u32 instr) { void JIT::jal(const u32 instr) {
regs.Write<s64>(31, blockPC + 4, true); regs.Write<s64>(31, blockPC + 4);
j(instr); j(instr);
} }
void JIT::jalr(const u32 instr) { void JIT::jalr(const u32 instr) {
regs.Write<s64>(RD(instr), blockPC + 4, true); regs.Write<s64>(RD(instr), blockPC + 4);
jr(instr); jr(instr);
} }
@@ -870,7 +870,7 @@ void JIT::lbu(u32 instr) {
Util::panic("[JIT]: Unhandled TLBL exception in LBU!"); Util::panic("[JIT]: Unhandled TLBL exception in LBU!");
} else { } else {
const u8 value = mem.Read<u8>(regs, paddr); const u8 value = mem.Read<u8>(regs, paddr);
regs.Write(RT(instr), value, true); regs.Write(RT(instr), value);
} }
} else { } else {
Util::panic("[JIT]: Implement non constant LBU!"); Util::panic("[JIT]: Implement non constant LBU!");
@@ -885,7 +885,7 @@ void JIT::lb(u32 instr) {
// regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); // regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC);
Util::panic("[JIT]: Unhandled TLBL exception in LB!"); Util::panic("[JIT]: Unhandled TLBL exception in LB!");
} else { } else {
regs.Write(RT(instr), (s8)mem.Read<u8>(regs, paddr), true); regs.Write(RT(instr), (s8)mem.Read<u8>(regs, paddr));
} }
} else { } else {
Util::panic("[JIT]: Implement non constant LB!"); Util::panic("[JIT]: Implement non constant LB!");
@@ -909,7 +909,7 @@ void JIT::ld(u32 instr) {
Util::panic("[JIT]: Unhandled TLBL exception in LD!"); Util::panic("[JIT]: Unhandled TLBL exception in LD!");
} else { } else {
const s64 value = mem.Read<u64>(regs, paddr); const s64 value = mem.Read<u64>(regs, paddr);
regs.Write(RT(instr), value, true); regs.Write(RT(instr), value);
} }
} else { } else {
Util::panic("[JIT]: Implement non constant LD!"); Util::panic("[JIT]: Implement non constant LD!");
@@ -947,7 +947,7 @@ void JIT::ldl(u32 instr) {
const u64 mask = 0xFFFFFFFFFFFFFFFF << shift; const u64 mask = 0xFFFFFFFFFFFFFFFF << shift;
const u64 data = mem.Read<u64>(regs, paddr & ~7); const u64 data = mem.Read<u64>(regs, paddr & ~7);
const s64 result = (s64)((regs.Read<s64>(RT(instr)) & ~mask) | (data << shift)); const s64 result = (s64)((regs.Read<s64>(RT(instr)) & ~mask) | (data << shift));
regs.Write(RT(instr), result, true); regs.Write(RT(instr), result);
} }
} else { } else {
Util::panic("[JIT]: Implement non constant LDL!"); Util::panic("[JIT]: Implement non constant LDL!");
@@ -967,7 +967,7 @@ void JIT::ldr(u32 instr) {
const u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; const u64 mask = 0xFFFFFFFFFFFFFFFF >> shift;
const u64 data = mem.Read<u64>(regs, paddr & ~7); const u64 data = mem.Read<u64>(regs, paddr & ~7);
const s64 result = (s64)((regs.Read<s64>(RT(instr)) & ~mask) | (data >> shift)); const s64 result = (s64)((regs.Read<s64>(RT(instr)) & ~mask) | (data >> shift));
regs.Write(RT(instr), result, true); regs.Write(RT(instr), result);
} }
} else { } else {
Util::panic("[JIT]: Implement non constant LDR!"); Util::panic("[JIT]: Implement non constant LDR!");
@@ -1049,7 +1049,7 @@ void JIT::lwr(u32) {}
void JIT::mfhi(u32 instr) { void JIT::mfhi(u32 instr) {
if (regs.hiIsConstant) { if (regs.hiIsConstant) {
regs.Write(RD(instr), regs.hi, true); regs.Write(RD(instr), regs.hi);
} else { } else {
Util::panic("[JIT]: Implement non constant MFHI!"); Util::panic("[JIT]: Implement non constant MFHI!");
} }
@@ -1057,7 +1057,7 @@ void JIT::mfhi(u32 instr) {
void JIT::mflo(u32 instr) { void JIT::mflo(u32 instr) {
if (regs.loIsConstant) { if (regs.loIsConstant) {
regs.Write(RD(instr), regs.lo, true); regs.Write(RD(instr), regs.lo);
} else { } else {
Util::panic("[JIT]: Implement non constant MFLO!"); Util::panic("[JIT]: Implement non constant MFLO!");
} }
@@ -1111,7 +1111,7 @@ void JIT::mtlo(u32 instr) {
void JIT::nor(u32 instr) { void JIT::nor(u32 instr) {
if (regs.IsRegConstant(RS(instr), RT(instr))) { if (regs.IsRegConstant(RS(instr), RT(instr))) {
regs.Write(RD(instr), ~(regs.Read<s64>(RS(instr)) | regs.Read<s64>(RT(instr))), true); regs.Write(RD(instr), ~(regs.Read<s64>(RS(instr)) | regs.Read<s64>(RT(instr))));
} else { } else {
Util::panic("[JIT]: Implement non constant NOR!"); Util::panic("[JIT]: Implement non constant NOR!");
} }
@@ -1120,7 +1120,7 @@ void JIT::nor(u32 instr) {
void JIT::slti(u32 instr) { void JIT::slti(u32 instr) {
if (regs.IsRegConstant(RS(instr))) { if (regs.IsRegConstant(RS(instr))) {
s16 imm = instr; s16 imm = instr;
regs.Write(RT(instr), regs.Read<s64>(RS(instr)) < imm, true); regs.Write(RT(instr), regs.Read<s64>(RS(instr)) < imm);
} else { } else {
Util::panic("[JIT]: Implement non constant SLTI!"); Util::panic("[JIT]: Implement non constant SLTI!");
} }
@@ -1129,7 +1129,7 @@ void JIT::slti(u32 instr) {
void JIT::sltiu(u32 instr) { void JIT::sltiu(u32 instr) {
if (regs.IsRegConstant(RS(instr))) { if (regs.IsRegConstant(RS(instr))) {
s16 imm = instr; s16 imm = instr;
regs.Write(RT(instr), regs.Read<u64>(RS(instr)) < imm, true); regs.Write(RT(instr), regs.Read<u64>(RS(instr)) < imm);
} else { } else {
Util::panic("[JIT]: Implement non constant SLTIU!"); Util::panic("[JIT]: Implement non constant SLTIU!");
} }
@@ -1137,7 +1137,7 @@ void JIT::sltiu(u32 instr) {
void JIT::slt(u32 instr) { void JIT::slt(u32 instr) {
if (regs.IsRegConstant(RS(instr), RT(instr))) { if (regs.IsRegConstant(RS(instr), RT(instr))) {
regs.Write(RD(instr), regs.Read<s64>(RS(instr)) < regs.Read<s64>(RT(instr)), true); regs.Write(RD(instr), regs.Read<s64>(RS(instr)) < regs.Read<s64>(RT(instr)));
} else { } else {
Util::panic("[JIT]: Implement non constant SLT!"); Util::panic("[JIT]: Implement non constant SLT!");
} }
@@ -1145,7 +1145,7 @@ void JIT::slt(u32 instr) {
void JIT::sltu(u32 instr) { void JIT::sltu(u32 instr) {
if (regs.IsRegConstant(RS(instr), RT(instr))) { if (regs.IsRegConstant(RS(instr), RT(instr))) {
regs.Write(RD(instr), regs.Read<u64>(RS(instr)) < regs.Read<u64>(RT(instr)), true); regs.Write(RD(instr), regs.Read<u64>(RS(instr)) < regs.Read<u64>(RT(instr)));
} else { } else {
Util::panic("[JIT]: Implement non constant SLT!"); Util::panic("[JIT]: Implement non constant SLT!");
} }
@@ -1155,7 +1155,7 @@ void JIT::sll(u32 instr) {
if (regs.IsRegConstant(RT(instr))) { if (regs.IsRegConstant(RT(instr))) {
u8 sa = ((instr >> 6) & 0x1f); u8 sa = ((instr >> 6) & 0x1f);
s32 result = regs.Read<s64>(RT(instr)) << sa; s32 result = regs.Read<s64>(RT(instr)) << sa;
regs.Write(RD(instr), (s64)result, true); regs.Write(RD(instr), (s64)result);
} else { } else {
Util::panic("[JIT]: Implement non constant SLL!"); Util::panic("[JIT]: Implement non constant SLL!");
} }
@@ -1166,7 +1166,7 @@ void JIT::sllv(u32 instr) {
u8 sa = (regs.Read<s64>(RS(instr))) & 0x1F; u8 sa = (regs.Read<s64>(RS(instr))) & 0x1F;
u32 rt = regs.Read<s64>(RT(instr)); u32 rt = regs.Read<s64>(RT(instr));
s32 result = rt << sa; s32 result = rt << sa;
regs.Write(RD(instr), (s64)result, true); regs.Write(RD(instr), (s64)result);
} else { } else {
Util::panic("[JIT]: Implement non constant SLLV!"); Util::panic("[JIT]: Implement non constant SLLV!");
} }
@@ -1180,7 +1180,7 @@ void JIT::sub(u32 instr) {
if (check_signed_underflow(rs, rt, result)) { if (check_signed_underflow(rs, rt, result)) {
regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC); regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC);
} else { } else {
regs.Write(RD(instr), result, true); regs.Write(RD(instr), result);
} }
} else { } else {
Util::panic("[JIT]: Implement non constant SUB!"); Util::panic("[JIT]: Implement non constant SUB!");
@@ -1192,7 +1192,7 @@ void JIT::subu(u32 instr) {
u32 rt = regs.Read<s64>(RT(instr)); u32 rt = regs.Read<s64>(RT(instr));
u32 rs = regs.Read<s64>(RS(instr)); u32 rs = regs.Read<s64>(RS(instr));
u32 result = rs - rt; u32 result = rs - rt;
regs.Write(RD(instr), (s64)((s32)result), true); regs.Write(RD(instr), (s64)((s32)result));
} else { } else {
Util::panic("[JIT]: Implement non constant SUBU!"); Util::panic("[JIT]: Implement non constant SUBU!");
} }
@@ -1203,7 +1203,7 @@ void JIT::sra(u32 instr) {
s64 rt = regs.Read<s64>(RT(instr)); s64 rt = regs.Read<s64>(RT(instr));
u8 sa = ((instr >> 6) & 0x1f); u8 sa = ((instr >> 6) & 0x1f);
s32 result = rt >> sa; s32 result = rt >> sa;
regs.Write(RD(instr), result, true); regs.Write(RD(instr), result);
} else { } else {
Util::panic("[JIT]: Implement non constant SRA!"); Util::panic("[JIT]: Implement non constant SRA!");
} }
@@ -1215,7 +1215,7 @@ void JIT::srav(u32 instr) {
s64 rt = regs.Read<s64>(RT(instr)); s64 rt = regs.Read<s64>(RT(instr));
u8 sa = rs & 0x1f; u8 sa = rs & 0x1f;
s32 result = rt >> sa; s32 result = rt >> sa;
regs.Write(RD(instr), result, true); regs.Write(RD(instr), result);
} else { } else {
Util::panic("[JIT]: Implement non constant SRAV!"); Util::panic("[JIT]: Implement non constant SRAV!");
} }
@@ -1226,7 +1226,7 @@ void JIT::srl(u32 instr) {
u32 rt = regs.Read<s64>(RT(instr)); u32 rt = regs.Read<s64>(RT(instr));
u8 sa = ((instr >> 6) & 0x1f); u8 sa = ((instr >> 6) & 0x1f);
u32 result = rt >> sa; u32 result = rt >> sa;
regs.Write(RD(instr), (s32)result, true); regs.Write(RD(instr), (s32)result);
} else { } else {
Util::panic("[JIT]: Implement non constant SRL!"); Util::panic("[JIT]: Implement non constant SRL!");
} }
@@ -1323,7 +1323,7 @@ void JIT::srlv(u32 instr) {
u8 sa = (regs.Read<s64>(RS(instr)) & 0x1F); u8 sa = (regs.Read<s64>(RS(instr)) & 0x1F);
u32 rt = regs.Read<s64>(RT(instr)); u32 rt = regs.Read<s64>(RT(instr));
s32 result = rt >> sa; s32 result = rt >> sa;
regs.Write(RD(instr), (s64)result, true); regs.Write(RD(instr), (s64)result);
} else { } else {
Util::panic("[JIT]: Implement non constant SRLV!"); Util::panic("[JIT]: Implement non constant SRLV!");
} }
@@ -1331,7 +1331,7 @@ void JIT::srlv(u32 instr) {
void JIT::or_(u32 instr) { void JIT::or_(u32 instr) {
if (regs.IsRegConstant(RS(instr), RT(instr))) { if (regs.IsRegConstant(RS(instr), RT(instr))) {
regs.Write(RD(instr), regs.Read<s64>(RS(instr)) | regs.Read<s64>(RT(instr)), true); regs.Write(RD(instr), regs.Read<s64>(RS(instr)) | regs.Read<s64>(RT(instr)));
} else { } else {
Util::panic("[JIT]: Implement non constant OR!"); Util::panic("[JIT]: Implement non constant OR!");
} }
@@ -1344,7 +1344,7 @@ void JIT::ori(u32 instr) {
s64 imm = (u16)instr; s64 imm = (u16)instr;
if (regs.IsRegConstant(RS(instr))) { if (regs.IsRegConstant(RS(instr))) {
s64 result = imm | regs.Read<s64>(RS(instr)); s64 result = imm | regs.Read<s64>(RS(instr));
regs.Write(RT(instr), result, true); regs.Write(RT(instr), result);
return; return;
} }
@@ -1356,7 +1356,7 @@ void JIT::ori(u32 instr) {
void JIT::xori(u32 instr) { void JIT::xori(u32 instr) {
if (regs.IsRegConstant(RS(instr))) { if (regs.IsRegConstant(RS(instr))) {
s64 imm = (u16)instr; s64 imm = (u16)instr;
regs.Write(RT(instr), regs.Read<s64>(RS(instr)) ^ imm, true); regs.Write(RT(instr), regs.Read<s64>(RS(instr)) ^ imm);
} else { } else {
Util::panic("[JIT]: Implement non constant XORI!"); Util::panic("[JIT]: Implement non constant XORI!");
} }
@@ -1364,7 +1364,7 @@ void JIT::xori(u32 instr) {
void JIT::xor_(u32 instr) { void JIT::xor_(u32 instr) {
if (regs.IsRegConstant(RS(instr), RT(instr))) { if (regs.IsRegConstant(RS(instr), RT(instr))) {
regs.Write(RD(instr), regs.Read<s64>(RT(instr)) ^ regs.Read<s64>(RS(instr)), true); regs.Write(RD(instr), regs.Read<s64>(RT(instr)) ^ regs.Read<s64>(RS(instr)));
} else { } else {
Util::panic("[JIT]: Implement non constant XOR!"); Util::panic("[JIT]: Implement non constant XOR!");
} }

View File

@@ -116,210 +116,82 @@ void Registers::Read<s8>(size_t idx, Xbyak::Reg reg) {
} }
template <> template <>
void Registers::WriteJIT<bool>(size_t idx, bool v) { void Registers::Write<bool>(size_t idx, bool v) {
jit->code.mov(jit->code.al, v);
jit->code.mov(jit->GPR<u8>(idx), jit->code.al);
}
template <>
void Registers::Write<bool>(size_t idx, bool v, bool isConstant) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) {
gprIsConstant[idx] = isConstant; gprIsConstant[idx] = isConstant;
if (isConstant) {
gpr[idx] = v;
return;
}
WriteJIT<bool>(idx, v);
return;
}
gpr[idx] = v; gpr[idx] = v;
} }
template <> template <>
void Registers::WriteJIT<u64>(size_t idx, u64 v) { void Registers::Write<u64>(size_t idx, u64 v) {
jit->code.mov(jit->code.rax, v);
jit->code.mov(jit->GPR<u64>(idx), jit->code.rax);
}
template <>
void Registers::Write<u64>(size_t idx, u64 v, bool isConstant) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) {
gprIsConstant[idx] = isConstant; gprIsConstant[idx] = isConstant;
if (isConstant) {
gpr[idx] = v;
return;
}
WriteJIT<u64>(idx, v);
return;
}
gpr[idx] = v; gpr[idx] = v;
} }
template <> template <>
void Registers::Write<s64>(size_t idx, s64 v, bool isConstant) { void Registers::Write<s64>(size_t idx, s64 v) {
Write<u64>(idx, v, isConstant); Write<u64>(idx, v, isConstant);
} }
template <> template <>
void Registers::WriteJIT<u32>(size_t idx, u32 v) { void Registers::Write<u32>(size_t idx, u32 v) {
jit->code.mov(jit->code.eax, v);
jit->code.mov(jit->GPR<u32>(idx), jit->code.eax);
}
template <>
void Registers::Write<u32>(size_t idx, u32 v, bool isConstant) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) {
gprIsConstant[idx] = isConstant; gprIsConstant[idx] = isConstant;
if (isConstant) {
gpr[idx] = v;
return;
}
WriteJIT<u32>(idx, v);
return;
}
gpr[idx] = v; gpr[idx] = v;
} }
template <>
void Registers::WriteJIT<s32>(size_t idx, s32 v) {
jit->code.mov(jit->code.eax, v);
jit->code.movsxd(jit->code.rax, jit->code.eax);
jit->code.mov(jit->GPR<u64>(idx), jit->code.rax);
}
template <> template <>
void Registers::Write<s32>(size_t idx, s32 v, bool isConstant) { void Registers::Write<s32>(size_t idx, s32 v) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) {
gprIsConstant[idx] = isConstant; gprIsConstant[idx] = isConstant;
if (isConstant) {
gpr[idx] = v;
return;
}
WriteJIT<s32>(idx, v);
return;
}
gpr[idx] = v; gpr[idx] = v;
} }
template <> template <>
void Registers::WriteJIT<u16>(size_t idx, u16 v) { void Registers::Write<u16>(size_t idx, u16 v) {
jit->code.mov(jit->code.ax, v);
jit->code.mov(jit->GPR<u16>(idx), jit->code.ax);
}
template <>
void Registers::Write<u16>(size_t idx, u16 v, bool isConstant) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) {
gprIsConstant[idx] = isConstant; gprIsConstant[idx] = isConstant;
if (isConstant) {
gpr[idx] = v;
return;
}
WriteJIT<u16>(idx, v);
return;
}
gpr[idx] = v; gpr[idx] = v;
} }
template <>
void Registers::WriteJIT<s16>(size_t idx, s16 v) {
jit->code.mov(jit->code.ax, v);
jit->code.movsx(jit->code.rax, jit->code.ax);
jit->code.mov(jit->GPR<u64>(idx), jit->code.rax);
}
template <> template <>
void Registers::Write<s16>(size_t idx, s16 v, bool isConstant) { void Registers::Write<s16>(size_t idx, s16 v) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) {
gprIsConstant[idx] = isConstant; gprIsConstant[idx] = isConstant;
if (isConstant) {
gpr[idx] = v;
return;
}
WriteJIT<s16>(idx, v);
return;
}
gpr[idx] = v; gpr[idx] = v;
} }
template <> template <>
void Registers::WriteJIT<u8>(size_t idx, u8 v) { void Registers::Write<u8>(size_t idx, u8 v) {
jit->code.mov(jit->code.al, v);
jit->code.mov(jit->GPR<u8>(idx), jit->code.al);
}
template <>
void Registers::Write<u8>(size_t idx, u8 v, bool isConstant) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) {
gprIsConstant[idx] = isConstant; gprIsConstant[idx] = isConstant;
if (isConstant) {
gpr[idx] = v;
return;
}
WriteJIT<u8>(idx, v);
return;
}
gpr[idx] = v; gpr[idx] = v;
} }
template <>
void Registers::WriteJIT<s8>(size_t idx, s8 v) {
jit->code.mov(jit->code.al, v);
jit->code.movsx(jit->code.rax, jit->code.al);
jit->code.mov(jit->GPR<u64>(idx), jit->code.rax);
}
template <> template <>
void Registers::Write<s8>(size_t idx, s8 v, bool isConstant) { void Registers::Write<s8>(size_t idx, s8 v) {
if (idx == 0) if (idx == 0)
return; return;
if (jit) {
gprIsConstant[idx] = isConstant; gprIsConstant[idx] = isConstant;
if (isConstant) {
gpr[idx] = v;
return;
}
WriteJIT<s8>(idx, v);
return;
}
gpr[idx] = v; gpr[idx] = v;
} }

View File

@@ -46,14 +46,10 @@ struct Registers {
template <typename T> template <typename T>
void Read(size_t, Xbyak::Reg); void Read(size_t, Xbyak::Reg);
template <typename T> template <typename T>
void Write(size_t, T, bool = false); void Write(size_t, T);
template <typename T> template <typename T>
void Write(size_t, Xbyak::Reg); void Write(size_t, Xbyak::Reg);
std::array<s64, 32> gpr{}; std::array<s64, 32> gpr{};
private:
template <typename T>
void WriteJIT(size_t, T);
}; };
} // namespace n64 } // namespace n64