mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-29 11:20:40 +00:00
Jit reg+reg compile time, and avoid flushing EDX.
This commit is contained in:
parent
ce5f393fb8
commit
ab9bea068c
@ -142,23 +142,54 @@ namespace MIPSComp
|
||||
}
|
||||
|
||||
//rd = rs X rt
|
||||
void Jit::CompTriArith(u32 op, void (XEmitter::*arith)(int, const OpArg &, const OpArg &))
|
||||
void Jit::CompTriArith(u32 op, void (XEmitter::*arith)(int, const OpArg &, const OpArg &), u32 (*doImm)(const u32, const u32))
|
||||
{
|
||||
int rt = _RT;
|
||||
int rs = _RS;
|
||||
int rd = _RD;
|
||||
|
||||
gpr.FlushLockX(EDX);
|
||||
// Yes, this happens. Let's make it fast.
|
||||
if (doImm && gpr.IsImmediate(rs) && gpr.IsImmediate(rt))
|
||||
{
|
||||
gpr.SetImmediate32(rd, doImm(gpr.GetImmediate32(rs), gpr.GetImmediate32(rt)));
|
||||
return;
|
||||
}
|
||||
|
||||
gpr.Lock(rt, rs, rd);
|
||||
MOV(32, R(EAX), gpr.R(rs));
|
||||
MOV(32, R(EDX), gpr.R(rt));
|
||||
gpr.BindToRegister(rd, true, true);
|
||||
(this->*arith)(32, R(EAX), R(EDX));
|
||||
MOV(32, gpr.R(rd), R(EAX));
|
||||
// Use EAX as a temporary if we'd overwrite it.
|
||||
if (rd == rt)
|
||||
MOV(32, R(EAX), gpr.R(rt));
|
||||
gpr.BindToRegister(rd, rs == rd, true);
|
||||
if (rs != rd)
|
||||
MOV(32, gpr.R(rd), gpr.R(rs));
|
||||
(this->*arith)(32, gpr.R(rd), rd == rt ? R(EAX) : gpr.R(rt));
|
||||
gpr.UnlockAll();
|
||||
gpr.UnlockAllX();
|
||||
}
|
||||
|
||||
static u32 RType3_ImmAdd(const u32 a, const u32 b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
static u32 RType3_ImmSub(const u32 a, const u32 b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
static u32 RType3_ImmAnd(const u32 a, const u32 b)
|
||||
{
|
||||
return a & b;
|
||||
}
|
||||
|
||||
static u32 RType3_ImmOr(const u32 a, const u32 b)
|
||||
{
|
||||
return a | b;
|
||||
}
|
||||
|
||||
static u32 RType3_ImmXor(const u32 a, const u32 b)
|
||||
{
|
||||
return a ^ b;
|
||||
}
|
||||
|
||||
void Jit::Comp_RType3(u32 op)
|
||||
{
|
||||
@ -168,6 +199,10 @@ namespace MIPSComp
|
||||
int rs = _RS;
|
||||
int rd = _RD;
|
||||
|
||||
// noop, won't write to ZERO.
|
||||
if (rd == 0)
|
||||
return;
|
||||
|
||||
switch (op & 63)
|
||||
{
|
||||
//case 10: if (!R(rt)) R(rd) = R(rs); break; //movz
|
||||
@ -175,25 +210,28 @@ namespace MIPSComp
|
||||
|
||||
// case 32: //R(rd) = R(rs) + R(rt); break; //add
|
||||
case 33: //R(rd) = R(rs) + R(rt); break; //addu
|
||||
CompTriArith(op, &XEmitter::ADD);
|
||||
CompTriArith(op, &XEmitter::ADD, &RType3_ImmAdd);
|
||||
break;
|
||||
case 34: //R(rd) = R(rs) - R(rt); break; //sub
|
||||
case 35:
|
||||
CompTriArith(op, &XEmitter::SUB);
|
||||
CompTriArith(op, &XEmitter::SUB, &RType3_ImmSub);
|
||||
break;
|
||||
case 36: //R(rd) = R(rs) & R(rt); break; //and
|
||||
CompTriArith(op, &XEmitter::AND);
|
||||
CompTriArith(op, &XEmitter::AND, &RType3_ImmAnd);
|
||||
break;
|
||||
case 37: //R(rd) = R(rs) | R(rt); break; //or
|
||||
CompTriArith(op, &XEmitter::OR);
|
||||
CompTriArith(op, &XEmitter::OR, &RType3_ImmOr);
|
||||
break;
|
||||
case 38: //R(rd) = R(rs) ^ R(rt); break; //xor
|
||||
CompTriArith(op, &XEmitter::XOR);
|
||||
CompTriArith(op, &XEmitter::XOR, &RType3_ImmXor);
|
||||
break;
|
||||
|
||||
case 39: // R(rd) = ~(R(rs) | R(rt)); //nor
|
||||
CompTriArith(op, &XEmitter::OR);
|
||||
NOT(32, gpr.R(rd));
|
||||
CompTriArith(op, &XEmitter::OR, &RType3_ImmOr);
|
||||
if (gpr.IsImmediate(rd))
|
||||
gpr.SetImmediate32(rd, ~gpr.GetImmediate32(rd));
|
||||
else
|
||||
NOT(32, gpr.R(rd));
|
||||
break;
|
||||
|
||||
case 42: //R(rd) = (int)R(rs) < (int)R(rt); break; //slt
|
||||
|
@ -121,7 +121,7 @@ private:
|
||||
|
||||
// Utilities to reduce duplicated code
|
||||
void CompImmLogic(u32 op, void (XEmitter::*arith)(int, const OpArg &, const OpArg &));
|
||||
void CompTriArith(u32 op, void (XEmitter::*arith)(int, const OpArg &, const OpArg &));
|
||||
void CompTriArith(u32 op, void (XEmitter::*arith)(int, const OpArg &, const OpArg &), u32 (*doImm)(const u32, const u32));
|
||||
void CompShiftImm(u32 op, void (XEmitter::*shift)(int, OpArg, OpArg));
|
||||
void CompShiftVar(u32 op, void (XEmitter::*shift)(int, OpArg, OpArg));
|
||||
void CompITypeMemRead(u32 op, u32 bits, void (XEmitter::*mov)(int, int, X64Reg, OpArg), void *safeFunc);
|
||||
|
Loading…
Reference in New Issue
Block a user