mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
armjit: Use our I2R funcs on reg/reg math too.
When one is a known immediate. This should catch more cases, like: ori v0, $0, 0xFFFF and v1, v1, v0
This commit is contained in:
parent
8e979da0f9
commit
e783627947
@ -204,6 +204,20 @@ bool ARMXEmitter::TryADDI2R(ARMReg rd, ARMReg rs, u32 val)
|
||||
}
|
||||
}
|
||||
|
||||
void ARMXEmitter::SUBI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch)
|
||||
{
|
||||
if (!TrySUBI2R(rd, rs, val)) {
|
||||
MOVI2R(scratch, val);
|
||||
SUB(rd, rs, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
bool ARMXEmitter::TrySUBI2R(ARMReg rd, ARMReg rs, u32 val)
|
||||
{
|
||||
// Just add a negative.
|
||||
return TryADDI2R(rd, rs, (u32)-(s32)val);
|
||||
}
|
||||
|
||||
void ARMXEmitter::ANDI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch)
|
||||
{
|
||||
if (!TryANDI2R(rd, rs, val)) {
|
||||
|
@ -796,6 +796,8 @@ public:
|
||||
|
||||
void ADDI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch);
|
||||
bool TryADDI2R(ARMReg rd, ARMReg rs, u32 val);
|
||||
void SUBI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch);
|
||||
bool TrySUBI2R(ARMReg rd, ARMReg rs, u32 val);
|
||||
void ANDI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch);
|
||||
bool TryANDI2R(ARMReg rd, ARMReg rs, u32 val);
|
||||
void CMPI2R(ARMReg rs, u32 val, ARMReg scratch);
|
||||
|
@ -183,7 +183,7 @@ namespace MIPSComp
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::CompType3(MIPSGPReg rd, MIPSGPReg rs, MIPSGPReg rt, void (ARMXEmitter::*arith)(ARMReg dst, ARMReg rm, Operand2 rn), u32 (*eval)(u32 a, u32 b), bool symmetric, bool useMOV)
|
||||
void Jit::CompType3(MIPSGPReg rd, MIPSGPReg rs, MIPSGPReg rt, void (ARMXEmitter::*arith)(ARMReg dst, ARMReg rm, Operand2 rn), bool (ARMXEmitter::*tryArithI2R)(ARMReg dst, ARMReg rm, u32 val), u32 (*eval)(u32 a, u32 b), bool symmetric)
|
||||
{
|
||||
if (gpr.IsImm(rs) && gpr.IsImm(rt)) {
|
||||
gpr.SetImm(rd, (*eval)(gpr.GetImm(rs), gpr.GetImm(rt)));
|
||||
@ -192,18 +192,17 @@ namespace MIPSComp
|
||||
|
||||
if (gpr.IsImm(rt) || (gpr.IsImm(rs) && symmetric)) {
|
||||
MIPSGPReg lhs = gpr.IsImm(rs) ? rt : rs;
|
||||
u32 rhsImm = gpr.IsImm(rs) ? gpr.GetImm(rs) : gpr.GetImm(rt);
|
||||
Operand2 op2;
|
||||
// TODO: AND could be reversed, OR/EOR could use multiple ops (maybe still cheaper.)
|
||||
if (TryMakeOperand2(rhsImm, op2)) {
|
||||
gpr.MapDirtyIn(rd, lhs);
|
||||
// MOV can avoid the ALU so might be faster?
|
||||
if (!useMOV || rhsImm != 0)
|
||||
(this->*arith)(gpr.R(rd), gpr.R(lhs), op2);
|
||||
else if (rd != lhs)
|
||||
MOV(gpr.R(rd), gpr.R(lhs));
|
||||
MIPSGPReg rhs = gpr.IsImm(rs) ? rs : rt;
|
||||
u32 rhsImm = gpr.GetImm(rhs);
|
||||
gpr.MapDirtyIn(rd, lhs);
|
||||
if ((this->*tryArithI2R)(gpr.R(rd), gpr.R(lhs), rhsImm)) {
|
||||
return;
|
||||
}
|
||||
// If rd is rhs, we may have lost it in the MapDirtyIn(). lhs was kept.
|
||||
if (rd == rhs) {
|
||||
// Luckily, it was just an imm.
|
||||
gpr.SetImm(rhs, rhsImm);
|
||||
}
|
||||
} else if (gpr.IsImm(rs) && !symmetric) {
|
||||
Operand2 op2;
|
||||
// For SUB, we can use RSB as a reverse operation.
|
||||
@ -288,21 +287,21 @@ namespace MIPSComp
|
||||
case 32: //R(rd) = R(rs) + R(rt); break; //add
|
||||
case 33: //R(rd) = R(rs) + R(rt); break; //addu
|
||||
// We optimize out 0 as an operand2 ADD.
|
||||
CompType3(rd, rs, rt, &ARMXEmitter::ADD, &EvalAdd, true, true);
|
||||
CompType3(rd, rs, rt, &ARMXEmitter::ADD, &ARMXEmitter::TryADDI2R, &EvalAdd, true);
|
||||
break;
|
||||
|
||||
case 34: //R(rd) = R(rs) - R(rt); break; //sub
|
||||
case 35: //R(rd) = R(rs) - R(rt); break; //subu
|
||||
CompType3(rd, rs, rt, &ARMXEmitter::SUB, &EvalSub, false, false);
|
||||
CompType3(rd, rs, rt, &ARMXEmitter::SUB, &ARMXEmitter::TrySUBI2R, &EvalSub, false);
|
||||
break;
|
||||
case 36: //R(rd) = R(rs) & R(rt); break; //and
|
||||
CompType3(rd, rs, rt, &ARMXEmitter::AND, &EvalAnd, true, false);
|
||||
CompType3(rd, rs, rt, &ARMXEmitter::AND, &ARMXEmitter::TryANDI2R, &EvalAnd, true);
|
||||
break;
|
||||
case 37: //R(rd) = R(rs) | R(rt); break; //or
|
||||
CompType3(rd, rs, rt, &ARMXEmitter::ORR, &EvalOr, true, true);
|
||||
CompType3(rd, rs, rt, &ARMXEmitter::ORR, &ARMXEmitter::TryORI2R, &EvalOr, true);
|
||||
break;
|
||||
case 38: //R(rd) = R(rs) ^ R(rt); break; //xor/eor
|
||||
CompType3(rd, rs, rt, &ARMXEmitter::EOR, &EvalEor, true, true);
|
||||
CompType3(rd, rs, rt, &ARMXEmitter::EOR, &ARMXEmitter::TryEORI2R, &EvalEor, true);
|
||||
break;
|
||||
|
||||
case 39: // R(rd) = ~(R(rs) | R(rt)); break; //nor
|
||||
|
@ -209,7 +209,7 @@ private:
|
||||
|
||||
// Utilities to reduce duplicated code
|
||||
void CompImmLogic(MIPSGPReg rs, MIPSGPReg rt, u32 uimm, void (ARMXEmitter::*arith)(ARMReg dst, ARMReg src, Operand2 op2), bool (ARMXEmitter::*tryArithI2R)(ARMReg dst, ARMReg src, u32 val), u32 (*eval)(u32 a, u32 b));
|
||||
void CompType3(MIPSGPReg rd, MIPSGPReg rs, MIPSGPReg rt, void (ARMXEmitter::*arithOp2)(ARMReg dst, ARMReg rm, Operand2 rn), u32 (*eval)(u32 a, u32 b), bool symmetric = false, bool useMOV = false);
|
||||
void CompType3(MIPSGPReg rd, MIPSGPReg rs, MIPSGPReg rt, void (ARMXEmitter::*arithOp2)(ARMReg dst, ARMReg rm, Operand2 rn), bool (ARMXEmitter::*tryArithI2R)(ARMReg dst, ARMReg rm, u32 val), u32 (*eval)(u32 a, u32 b), bool symmetric = false);
|
||||
|
||||
void CompShiftImm(MIPSOpcode op, ArmGen::ShiftType shiftType, int sa);
|
||||
void CompShiftVar(MIPSOpcode op, ArmGen::ShiftType shiftType);
|
||||
|
Loading…
Reference in New Issue
Block a user