register constant check optimization + disable branch likely's for now
This commit is contained in:
@@ -310,6 +310,7 @@ void JIT::bgez(const u32 instr) {
|
||||
}
|
||||
|
||||
void JIT::bltzl(const u32 instr) {
|
||||
Util::panic("Implement branch likely < 0");
|
||||
const s16 imm = instr;
|
||||
const s64 offset = u64((s64)imm) << 2;
|
||||
if (regs.IsRegConstant(RS(instr))) {
|
||||
@@ -323,6 +324,7 @@ void JIT::bltzl(const u32 instr) {
|
||||
}
|
||||
|
||||
void JIT::bgezl(const u32 instr) {
|
||||
Util::panic("Implement branch likely >= 0");
|
||||
const s16 imm = instr;
|
||||
const s64 offset = u64((s64)imm) << 2;
|
||||
if (regs.IsRegConstant(RS(instr))) {
|
||||
@@ -364,6 +366,7 @@ void JIT::bgezal(const u32 instr) {
|
||||
}
|
||||
|
||||
void JIT::bltzall(const u32 instr) {
|
||||
Util::panic("Implement branch likely and link < 0");
|
||||
const s16 imm = instr;
|
||||
const s64 offset = u64((s64)imm) << 2;
|
||||
regs.Write<s64>(31, blockNextPC);
|
||||
@@ -378,6 +381,7 @@ void JIT::bltzall(const u32 instr) {
|
||||
}
|
||||
|
||||
void JIT::bgezall(const u32 instr) {
|
||||
Util::panic("Implement branch likely and link >= 0");
|
||||
const s16 imm = instr;
|
||||
const s64 offset = u64((s64)imm) << 2;
|
||||
regs.Write<s64>(31, blockNextPC);
|
||||
@@ -420,6 +424,7 @@ void JIT::beq(const u32 instr) {
|
||||
}
|
||||
|
||||
void JIT::beql(const u32 instr) {
|
||||
Util::panic("Implement branch likely ==");
|
||||
const s16 imm = instr;
|
||||
const s64 offset = u64((s64)imm) << 2;
|
||||
if (regs.IsRegConstant(RS(instr)) && regs.IsRegConstant(RT(instr))) {
|
||||
@@ -476,6 +481,7 @@ void JIT::bne(const u32 instr) {
|
||||
}
|
||||
|
||||
void JIT::bnel(const u32 instr) {
|
||||
Util::panic("Implement branch likely !=");
|
||||
const s16 imm = instr;
|
||||
const s64 offset = u64((s64)imm) << 2;
|
||||
if (regs.IsRegConstant(RS(instr)) && regs.IsRegConstant(RT(instr))) {
|
||||
@@ -517,6 +523,7 @@ void JIT::blez(const u32 instr) {
|
||||
}
|
||||
|
||||
void JIT::blezl(const u32 instr) {
|
||||
Util::panic("Implement branch likely <= 0");
|
||||
const s16 imm = instr;
|
||||
const s64 offset = u64((s64)imm) << 2;
|
||||
if (regs.IsRegConstant(RS(instr))) {
|
||||
@@ -543,6 +550,7 @@ void JIT::bgtz(const u32 instr) {
|
||||
}
|
||||
|
||||
void JIT::bgtzl(const u32 instr) {
|
||||
Util::panic("Implement branch likely > 0");
|
||||
const s16 imm = instr;
|
||||
const s64 offset = u64((s64)imm) << 2;
|
||||
if (regs.IsRegConstant(RS(instr))) {
|
||||
@@ -639,8 +647,8 @@ void JIT::ddiv(u32 instr) {
|
||||
regs.hi = remainder;
|
||||
}
|
||||
|
||||
regs.loIsConstant = true;
|
||||
regs.hiIsConstant = true;
|
||||
regs.SetLOConstant();
|
||||
regs.SetHIConstant();
|
||||
} else {
|
||||
Util::panic("[JIT]: Implement non constant DDIV!");
|
||||
}
|
||||
@@ -660,8 +668,8 @@ void JIT::ddivu(u32 instr) {
|
||||
regs.hi = (s64)remainder;
|
||||
}
|
||||
|
||||
regs.loIsConstant = true;
|
||||
regs.hiIsConstant = true;
|
||||
regs.SetLOConstant();
|
||||
regs.SetHIConstant();
|
||||
} else {
|
||||
Util::panic("[JIT]: Implement non constant DDIVU!");
|
||||
}
|
||||
@@ -686,8 +694,8 @@ void JIT::div(u32 instr) {
|
||||
regs.hi = remainder;
|
||||
}
|
||||
|
||||
regs.loIsConstant = true;
|
||||
regs.hiIsConstant = true;
|
||||
regs.SetLOConstant();
|
||||
regs.SetHIConstant();
|
||||
} else {
|
||||
Util::panic("[JIT]: Implement non constant DIV!");
|
||||
}
|
||||
@@ -707,8 +715,8 @@ void JIT::divu(u32 instr) {
|
||||
regs.hi = remainder;
|
||||
}
|
||||
|
||||
regs.loIsConstant = true;
|
||||
regs.hiIsConstant = true;
|
||||
regs.SetLOConstant();
|
||||
regs.SetHIConstant();
|
||||
} else {
|
||||
Util::panic("[JIT]: Implement non constant DIVU!");
|
||||
}
|
||||
@@ -721,8 +729,8 @@ void JIT::dmult(u32 instr) {
|
||||
s128 result = (s128)rt * (s128)rs;
|
||||
regs.lo = result & 0xFFFFFFFFFFFFFFFF;
|
||||
regs.hi = result >> 64;
|
||||
regs.hiIsConstant = true;
|
||||
regs.loIsConstant = true;
|
||||
regs.SetHIConstant();
|
||||
regs.SetLOConstant();
|
||||
} else {
|
||||
Util::panic("[JIT]: Implement non constant DMULT!");
|
||||
}
|
||||
@@ -735,8 +743,8 @@ void JIT::dmultu(u32 instr) {
|
||||
u128 result = (u128)rt * (u128)rs;
|
||||
regs.lo = s64(result & 0xFFFFFFFFFFFFFFFF);
|
||||
regs.hi = s64(result >> 64);
|
||||
regs.hiIsConstant = true;
|
||||
regs.loIsConstant = true;
|
||||
regs.SetHIConstant();
|
||||
regs.SetLOConstant();
|
||||
} else {
|
||||
Util::panic("[JIT]: Implement non constant DMULT!");
|
||||
}
|
||||
@@ -1135,7 +1143,7 @@ void JIT::lwu(u32) { Util::panic("[JIT]: Implement constant LWU!"); }
|
||||
void JIT::lwr(u32) { Util::panic("[JIT]: Implement constant LWR!"); }
|
||||
|
||||
void JIT::mfhi(u32 instr) {
|
||||
if (regs.hiIsConstant) {
|
||||
if (regs.GetHIConstant()) {
|
||||
regs.Write(RD(instr), regs.hi);
|
||||
} else {
|
||||
code.mov(code.rax, REG(qword, hi));
|
||||
@@ -1144,7 +1152,7 @@ void JIT::mfhi(u32 instr) {
|
||||
}
|
||||
|
||||
void JIT::mflo(u32 instr) {
|
||||
if (regs.loIsConstant) {
|
||||
if (regs.GetLOConstant()) {
|
||||
regs.Write(RD(instr), regs.lo);
|
||||
} else {
|
||||
code.mov(code.rax, REG(qword, lo));
|
||||
@@ -1158,9 +1166,9 @@ void JIT::mult(u32 instr) {
|
||||
auto rs = regs.Read<s32>(RS(instr));
|
||||
s64 result = (s64)rt * (s64)rs;
|
||||
regs.lo = (s64)((s32)result);
|
||||
regs.loIsConstant = true;
|
||||
regs.SetLOConstant();
|
||||
regs.hi = (s64)((s32)(result >> 32));
|
||||
regs.hiIsConstant = true;
|
||||
regs.SetHIConstant();
|
||||
} else {
|
||||
Util::panic("[JIT]: Implement non constant MULT!");
|
||||
}
|
||||
@@ -1172,9 +1180,9 @@ void JIT::multu(u32 instr) {
|
||||
auto rs = regs.Read<u32>(RS(instr));
|
||||
u64 result = (u64)rt * (u64)rs;
|
||||
regs.lo = (s64)((s32)result);
|
||||
regs.loIsConstant = true;
|
||||
regs.SetLOConstant();
|
||||
regs.hi = (s64)((s32)(result >> 32));
|
||||
regs.hiIsConstant = true;
|
||||
regs.SetHIConstant();
|
||||
} else {
|
||||
Util::panic("[JIT]: Implement non constant MULTU!");
|
||||
}
|
||||
@@ -1183,22 +1191,22 @@ void JIT::multu(u32 instr) {
|
||||
void JIT::mthi(u32 instr) {
|
||||
if (regs.IsRegConstant(RS(instr))) {
|
||||
regs.hi = regs.Read<s64>(RS(instr));
|
||||
regs.hiIsConstant = true;
|
||||
regs.SetHIConstant();
|
||||
} else {
|
||||
regs.Read<s64>(RS(instr), code.rax);
|
||||
code.mov(REG(qword, hi), code.rax);
|
||||
regs.hiIsConstant = false;
|
||||
regs.UnsetHIConstant();
|
||||
}
|
||||
}
|
||||
|
||||
void JIT::mtlo(u32 instr) {
|
||||
if (regs.IsRegConstant(RS(instr))) {
|
||||
regs.lo = regs.Read<s64>(RS(instr));
|
||||
regs.loIsConstant = true;
|
||||
regs.SetLOConstant();
|
||||
} else {
|
||||
regs.Read<s64>(RS(instr), code.rax);
|
||||
code.mov(REG(qword, lo), code.rax);
|
||||
regs.loIsConstant = false;
|
||||
regs.UnsetLOConstant();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,7 @@ void Registers::Reset() {
|
||||
delaySlot = false;
|
||||
prevDelaySlot = false;
|
||||
gpr.fill(0);
|
||||
gprIsConstant.fill(false);
|
||||
gprIsConstant[0] = true;
|
||||
regIsConstant = 1; // first bit is true indicating $zero is constant which yes it is always
|
||||
|
||||
cop0.Reset();
|
||||
cop1.Reset();
|
||||
@@ -162,7 +161,7 @@ void Registers::Write<bool>(size_t idx, bool v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = true;
|
||||
regIsConstant |= (1 << idx);
|
||||
gpr[idx] = v;
|
||||
}
|
||||
|
||||
@@ -171,7 +170,7 @@ void Registers::Write<u64>(size_t idx, u64 v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = true;
|
||||
regIsConstant |= (1 << idx);
|
||||
gpr[idx] = v;
|
||||
}
|
||||
|
||||
@@ -185,7 +184,7 @@ void Registers::Write<u32>(size_t idx, u32 v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = true;
|
||||
regIsConstant |= (1 << idx);
|
||||
gpr[idx] = v;
|
||||
}
|
||||
|
||||
@@ -195,7 +194,7 @@ void Registers::Write<s32>(size_t idx, s32 v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = true;
|
||||
regIsConstant |= (1 << idx);
|
||||
gpr[idx] = v;
|
||||
}
|
||||
|
||||
@@ -204,7 +203,7 @@ void Registers::Write<u16>(size_t idx, u16 v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = true;
|
||||
regIsConstant |= (1 << idx);
|
||||
gpr[idx] = v;
|
||||
}
|
||||
|
||||
@@ -214,7 +213,7 @@ void Registers::Write<s16>(size_t idx, s16 v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = true;
|
||||
regIsConstant |= (1 << idx);
|
||||
gpr[idx] = v;
|
||||
}
|
||||
|
||||
@@ -223,7 +222,7 @@ void Registers::Write<u8>(size_t idx, u8 v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = true;
|
||||
regIsConstant |= (1 << idx);
|
||||
gpr[idx] = v;
|
||||
}
|
||||
|
||||
@@ -233,7 +232,7 @@ void Registers::Write<s8>(size_t idx, s8 v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = true;
|
||||
regIsConstant |= (1 << idx);
|
||||
gpr[idx] = v;
|
||||
}
|
||||
|
||||
@@ -243,7 +242,7 @@ void Registers::Write<bool>(size_t idx, Xbyak::Reg v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = false;
|
||||
regIsConstant &= ~(1 << idx);
|
||||
|
||||
if (!jit)
|
||||
Util::panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
|
||||
@@ -257,7 +256,7 @@ void Registers::Write<s8>(size_t idx, Xbyak::Reg v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = false;
|
||||
regIsConstant &= ~(1 << idx);
|
||||
|
||||
if (!jit)
|
||||
Util::panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
|
||||
@@ -271,7 +270,7 @@ void Registers::Write<u8>(size_t idx, Xbyak::Reg v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = false;
|
||||
regIsConstant &= ~(1 << idx);
|
||||
|
||||
if (!jit)
|
||||
Util::panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
|
||||
@@ -285,7 +284,7 @@ void Registers::Write<s16>(size_t idx, Xbyak::Reg v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = false;
|
||||
regIsConstant &= ~(1 << idx);
|
||||
|
||||
if (!jit)
|
||||
Util::panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
|
||||
@@ -299,7 +298,7 @@ void Registers::Write<u16>(size_t idx, Xbyak::Reg v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = false;
|
||||
regIsConstant &= ~(1 << idx);
|
||||
|
||||
if (!jit)
|
||||
Util::panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
|
||||
@@ -313,7 +312,7 @@ void Registers::Write<s32>(size_t idx, Xbyak::Reg v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = false;
|
||||
regIsConstant &= ~(1 << idx);
|
||||
|
||||
if (!jit)
|
||||
Util::panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
|
||||
@@ -327,7 +326,7 @@ void Registers::Write<u32>(size_t idx, Xbyak::Reg v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = false;
|
||||
regIsConstant &= ~(1 << idx);
|
||||
|
||||
if (!jit)
|
||||
Util::panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
|
||||
@@ -341,7 +340,7 @@ void Registers::Write<u64>(size_t idx, Xbyak::Reg v) {
|
||||
if (idx == 0)
|
||||
return;
|
||||
|
||||
gprIsConstant[idx] = false;
|
||||
regIsConstant &= ~(1 << idx);
|
||||
|
||||
if (!jit)
|
||||
Util::panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?");
|
||||
|
||||
@@ -14,17 +14,41 @@ struct Registers {
|
||||
[[nodiscard]] bool IsRegConstant(const u32 index) const {
|
||||
if (index == 0)
|
||||
return true;
|
||||
return gprIsConstant[index];
|
||||
return regIsConstant & (1 << index);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsRegConstant(const u32 first, const u32 second) const {
|
||||
return IsRegConstant(first) && IsRegConstant(second);
|
||||
}
|
||||
|
||||
bool GetLOConstant() {
|
||||
return regIsConstant & (1ull << 32);
|
||||
}
|
||||
|
||||
bool GetHIConstant() {
|
||||
return regIsConstant & (1ull << 33);
|
||||
}
|
||||
|
||||
void SetLOConstant() {
|
||||
regIsConstant |= (1ull << 32);
|
||||
}
|
||||
|
||||
void SetHIConstant() {
|
||||
regIsConstant |= (1ull << 33);
|
||||
}
|
||||
|
||||
void UnsetLOConstant() {
|
||||
regIsConstant &= ~(1ull << 32);
|
||||
}
|
||||
|
||||
void UnsetHIConstant() {
|
||||
regIsConstant &= ~(1ull << 33);
|
||||
}
|
||||
|
||||
JIT *jit = nullptr;
|
||||
|
||||
std::array<bool, 32> gprIsConstant{};
|
||||
bool loIsConstant = false, hiIsConstant = false;
|
||||
uint64_t regIsConstant = 0;
|
||||
|
||||
Cop0 cop0;
|
||||
Cop1 cop1;
|
||||
s64 oldPC{}, pc{}, nextPC{};
|
||||
|
||||
Reference in New Issue
Block a user