mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Hit immediates in the ALU better and more simply.
This commit is contained in:
parent
4f8d3a9227
commit
ce5f393fb8
3 changed files with 53 additions and 18 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue