From ce5f393fb81911e248c08d25a37874982de5e9ca Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 24 Jan 2013 22:23:29 -0800 Subject: [PATCH] Hit immediates in the ALU better and more simply. --- Core/MIPS/x86/CompALU.cpp | 52 +++++++++++++++++++++++++------------- Core/MIPS/x86/RegCache.cpp | 17 +++++++++++++ Core/MIPS/x86/RegCache.h | 2 ++ 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/Core/MIPS/x86/CompALU.cpp b/Core/MIPS/x86/CompALU.cpp index 674d685c16..8174d6b655 100644 --- a/Core/MIPS/x86/CompALU.cpp +++ b/Core/MIPS/x86/CompALU.cpp @@ -60,31 +60,28 @@ namespace MIPSComp int rt = _RT; int rs = _RS; + // noop, won't write to ZERO. + if (rt == 0) + return; + switch (op >> 26) { case 8: // same as addiu? case 9: //R(rt) = R(rs) + simm; break; //addiu { - if (gpr.R(rs).IsImm()) + if (gpr.IsImmediate(rs)) { - gpr.SetImmediate32(rt, gpr.R(rs).GetImmValue() + simm); + gpr.SetImmediate32(rt, gpr.GetImmediate32(rs) + simm); break; } gpr.Lock(rt, rs); - if (rs != 0) - { - gpr.BindToRegister(rt, rt == rs, true); - if (rt != rs) - MOV(32, gpr.R(rt), gpr.R(rs)); - if (simm != 0) - ADD(32, gpr.R(rt), Imm32((u32)(s32)simm)); - // TODO: Can also do LEA if both operands happen to be in registers. - } - else - { - gpr.SetImmediate32(rt, simm); - } + gpr.BindToRegister(rt, rt == rs, true); + if (rt != rs) + MOV(32, gpr.R(rt), gpr.R(rs)); + if (simm != 0) + ADD(32, gpr.R(rt), Imm32((u32)(s32)simm)); + // TODO: Can also do LEA if both operands happen to be in registers. gpr.UnlockAll(); } break; @@ -111,9 +108,28 @@ namespace MIPSComp gpr.UnlockAll(); break; - case 12: CompImmLogic(op, &XEmitter::AND); break; - case 13: CompImmLogic(op, &XEmitter::OR); break; - case 14: CompImmLogic(op, &XEmitter::XOR); break; + case 12: // R(rt) = R(rs) & uimm; break; //andi + if (uimm == 0) + gpr.SetImmediate32(rt, 0); + else if (gpr.IsImmediate(rs)) + gpr.SetImmediate32(rt, gpr.GetImmediate32(rs) & uimm); + else + CompImmLogic(op, &XEmitter::AND); + break; + + case 13: // R(rt) = R(rs) | uimm; break; //ori + if (gpr.IsImmediate(rs)) + gpr.SetImmediate32(rt, gpr.GetImmediate32(rs) | uimm); + else + CompImmLogic(op, &XEmitter::OR); + break; + + case 14: // R(rt) = R(rs) ^ uimm; break; //xori + if (gpr.IsImmediate(rs)) + gpr.SetImmediate32(rt, gpr.GetImmediate32(rs) ^ uimm); + else + CompImmLogic(op, &XEmitter::XOR); + break; case 15: //R(rt) = uimm << 16; break; //lui gpr.SetImmediate32(rt, uimm << 16); diff --git a/Core/MIPS/x86/RegCache.cpp b/Core/MIPS/x86/RegCache.cpp index e8090ec530..3ca19b7f03 100644 --- a/Core/MIPS/x86/RegCache.cpp +++ b/Core/MIPS/x86/RegCache.cpp @@ -220,6 +220,23 @@ void GPRRegCache::SetImmediate32(int preg, u32 immValue) regs[preg].location = Imm32(immValue); } +bool GPRRegCache::IsImmediate(int preg) const +{ + // Always say yes for ZERO, even if it's in a temp reg. + if (preg == 0) + return true; + return regs[preg].location.IsImm(); +} + +u32 GPRRegCache::GetImmediate32(int preg) const +{ + _dbg_assert_msg_(JIT, IsImmediate(preg), "Reg %d must be an immediate.", preg); + // Always 0 for ZERO. + if (preg == 0) + return 0; + return regs[preg].location.GetImmValue(); +} + void GPRRegCache::Start(MIPSState *mips, MIPSAnalyst::AnalysisResults &stats) { RegCache::Start(mips, stats); diff --git a/Core/MIPS/x86/RegCache.h b/Core/MIPS/x86/RegCache.h index 32e9ed4fd2..aa2ba91094 100644 --- a/Core/MIPS/x86/RegCache.h +++ b/Core/MIPS/x86/RegCache.h @@ -136,6 +136,8 @@ public: OpArg GetDefaultLocation(int reg) const; const int *GetAllocationOrder(int &count); void SetImmediate32(int preg, u32 immValue); + bool IsImmediate(int preg) const; + u32 GetImmediate32(int preg) const; };