[ARM] Fix the FPR cache to not have to dump registers after every instruction. Add mullwox instruction.

This commit is contained in:
Ryan Houdek 2013-09-17 22:07:57 +00:00
parent 06062d5744
commit 39a8645ffc
4 changed files with 13 additions and 17 deletions

View file

@ -483,7 +483,6 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo
BKPT(0x7777);
}
JitArmTables::CompileInstruction(ops[i]);
fpr.Flush();
if (js.memcheck && (opinfo->flags & FL_LOADSTORE))
{
// Don't do this yet

View file

@ -249,6 +249,7 @@ void JitArm::arith(UGeckoInstruction inst)
isUnsigned = true;
case 235: // mullwx
case 266:
case 747: // mullwox
case 778: // both addx
if (gpr.IsImm(a))
{
@ -325,6 +326,7 @@ void JitArm::arith(UGeckoInstruction inst)
gpr.SetImmediate(a, ~Or(Imm[0], Imm[1]));
dest = a;
break;
case 747:
case 235:
gpr.SetImmediate(d, Mul(Imm[0], Imm[1]));
break;
@ -475,6 +477,7 @@ void JitArm::arith(UGeckoInstruction inst)
ORR(RA, RS, RB);
MVNS(RA, RA);
break;
case 747:
case 235:
RD = gpr.R(d);
RA = gpr.R(a);

View file

@ -320,7 +320,7 @@ static GekkoOPTemplate table31_2[] =
{75, &JitArm::Default}, //"mulhwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
{11, &JitArm::mulhwux}, //"mulhwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
{235, &JitArm::arith}, //"mullwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
{747, &JitArm::Default}, //"mullwox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
{747, &JitArm::arith}, //"mullwox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
{104, &JitArm::negx}, //"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
{40, &JitArm::arith}, //"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
{552, &JitArm::arith}, //"subox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},

View file

@ -53,8 +53,8 @@ ARMReg *ArmFPRCache::GetPPCAllocationOrder(int &count)
// the ppc side.
static ARMReg allocationOrder[] =
{
D4, D5, D6, D7, D8, D9, D10, D11, D12, D13,
D14, D15, D16, D17, D18, D19, D20, D21, D22,
D4, D5, D6, D7, D8, D9, D10, D11, D12, D13,
D14, D15, D16, D17, D18, D19, D20, D21, D22,
D23, D24, D25, D26, D27, D28, D29, D30, D31
};
count = sizeof(allocationOrder) / sizeof(const int);
@ -126,17 +126,11 @@ bool ArmFPRCache::FindFreeRegister(u32 &regindex)
ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad)
{
u32 lastRegIndex = GetLeastUsedRegister(true);
if (_regs[preg][PS1].GetType() != REG_NOTLOADED)
{
u8 a = _regs[preg][PS1].GetRegIndex();
ArmCRegs[a].LastLoad = 0;
if (_regs[preg][PS1].GetType() == REG_AWAY && preLoad)
{
s16 offset = PPCSTATE_OFF(ps) + (preg * 16) + (PS1 ? 8 : 0);
emit->VLDR(ArmCRegs[a].Reg, R9, offset);
_regs[preg][PS1].LoadToReg(a);
}
return ArmCRegs[a].Reg;
}
@ -144,12 +138,13 @@ ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad)
if (FindFreeRegister(regindex))
{
s16 offset = PPCSTATE_OFF(ps) + (preg * 16) + (PS1 ? 8 : 0);
emit->VLDR(ArmCRegs[regindex].Reg, R9, offset);
ArmCRegs[regindex].PPCReg = preg;
ArmCRegs[regindex].LastLoad = 0;
ArmCRegs[regindex].PS1 = PS1;
_regs[preg][PS1].LoadToReg(regindex);
emit->VLDR(ArmCRegs[regindex].Reg, R9, offset);
return ArmCRegs[regindex].Reg;
}
@ -158,16 +153,15 @@ ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad)
s16 offsetNew = PPCSTATE_OFF(ps) + (preg * 16) + (PS1 ? 8 : 0);
emit->VSTR(ArmCRegs[lastRegIndex].Reg, R9, offsetOld);
emit->VLDR(ArmCRegs[lastRegIndex].Reg, R9, offsetNew);
_regs[ArmCRegs[lastRegIndex].PPCReg][PS1].Flush();
_regs[ArmCRegs[lastRegIndex].PPCReg][ArmCRegs[lastRegIndex].PS1].Flush();
ArmCRegs[lastRegIndex].PPCReg = preg;
ArmCRegs[lastRegIndex].LastLoad = 0;
ArmCRegs[lastRegIndex].PS1 = PS1;
_regs[preg][PS1].LoadToReg(lastRegIndex);
emit->VLDR(ArmCRegs[lastRegIndex].Reg, R9, offsetNew);
return ArmCRegs[lastRegIndex].Reg;
}
@ -185,7 +179,7 @@ void ArmFPRCache::Flush()
{
for (u8 a = 0; a < 32; ++a)
{
if (_regs[a][0].GetType() == REG_REG)
if (_regs[a][0].GetType() != REG_NOTLOADED)
{
s16 offset = PPCSTATE_OFF(ps) + (a * 16);
u32 regindex = _regs[a][0].GetRegIndex();
@ -195,7 +189,7 @@ void ArmFPRCache::Flush()
ArmCRegs[regindex].LastLoad = 0;
_regs[a][0].Flush();
}
if (_regs[a][1].GetType() == REG_REG)
if (_regs[a][1].GetType() != REG_NOTLOADED)
{
s16 offset = PPCSTATE_OFF(ps) + (a * 16) + 8;
u32 regindex = _regs[a][1].GetRegIndex();