[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); BKPT(0x7777);
} }
JitArmTables::CompileInstruction(ops[i]); JitArmTables::CompileInstruction(ops[i]);
fpr.Flush();
if (js.memcheck && (opinfo->flags & FL_LOADSTORE)) if (js.memcheck && (opinfo->flags & FL_LOADSTORE))
{ {
// Don't do this yet // Don't do this yet

View file

@ -249,6 +249,7 @@ void JitArm::arith(UGeckoInstruction inst)
isUnsigned = true; isUnsigned = true;
case 235: // mullwx case 235: // mullwx
case 266: case 266:
case 747: // mullwox
case 778: // both addx case 778: // both addx
if (gpr.IsImm(a)) if (gpr.IsImm(a))
{ {
@ -325,6 +326,7 @@ void JitArm::arith(UGeckoInstruction inst)
gpr.SetImmediate(a, ~Or(Imm[0], Imm[1])); gpr.SetImmediate(a, ~Or(Imm[0], Imm[1]));
dest = a; dest = a;
break; break;
case 747:
case 235: case 235:
gpr.SetImmediate(d, Mul(Imm[0], Imm[1])); gpr.SetImmediate(d, Mul(Imm[0], Imm[1]));
break; break;
@ -475,6 +477,7 @@ void JitArm::arith(UGeckoInstruction inst)
ORR(RA, RS, RB); ORR(RA, RS, RB);
MVNS(RA, RA); MVNS(RA, RA);
break; break;
case 747:
case 235: case 235:
RD = gpr.R(d); RD = gpr.R(d);
RA = gpr.R(a); 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}}, {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}}, {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}}, {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}}, {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}}, {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}}, {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. // the ppc side.
static ARMReg allocationOrder[] = static ARMReg allocationOrder[] =
{ {
D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13,
D14, D15, D16, D17, D18, D19, D20, D21, D22, D14, D15, D16, D17, D18, D19, D20, D21, D22,
D23, D24, D25, D26, D27, D28, D29, D30, D31 D23, D24, D25, D26, D27, D28, D29, D30, D31
}; };
count = sizeof(allocationOrder) / sizeof(const int); count = sizeof(allocationOrder) / sizeof(const int);
@ -126,17 +126,11 @@ bool ArmFPRCache::FindFreeRegister(u32 &regindex)
ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad) ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad)
{ {
u32 lastRegIndex = GetLeastUsedRegister(true); u32 lastRegIndex = GetLeastUsedRegister(true);
if (_regs[preg][PS1].GetType() != REG_NOTLOADED) if (_regs[preg][PS1].GetType() != REG_NOTLOADED)
{ {
u8 a = _regs[preg][PS1].GetRegIndex(); u8 a = _regs[preg][PS1].GetRegIndex();
ArmCRegs[a].LastLoad = 0; 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; return ArmCRegs[a].Reg;
} }
@ -144,12 +138,13 @@ ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad)
if (FindFreeRegister(regindex)) if (FindFreeRegister(regindex))
{ {
s16 offset = PPCSTATE_OFF(ps) + (preg * 16) + (PS1 ? 8 : 0); s16 offset = PPCSTATE_OFF(ps) + (preg * 16) + (PS1 ? 8 : 0);
emit->VLDR(ArmCRegs[regindex].Reg, R9, offset);
ArmCRegs[regindex].PPCReg = preg; ArmCRegs[regindex].PPCReg = preg;
ArmCRegs[regindex].LastLoad = 0; ArmCRegs[regindex].LastLoad = 0;
ArmCRegs[regindex].PS1 = PS1;
_regs[preg][PS1].LoadToReg(regindex); _regs[preg][PS1].LoadToReg(regindex);
emit->VLDR(ArmCRegs[regindex].Reg, R9, offset);
return ArmCRegs[regindex].Reg; 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); s16 offsetNew = PPCSTATE_OFF(ps) + (preg * 16) + (PS1 ? 8 : 0);
emit->VSTR(ArmCRegs[lastRegIndex].Reg, R9, offsetOld); 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].PPCReg = preg;
ArmCRegs[lastRegIndex].LastLoad = 0; ArmCRegs[lastRegIndex].LastLoad = 0;
ArmCRegs[lastRegIndex].PS1 = PS1; ArmCRegs[lastRegIndex].PS1 = PS1;
_regs[preg][PS1].LoadToReg(lastRegIndex); _regs[preg][PS1].LoadToReg(lastRegIndex);
emit->VLDR(ArmCRegs[lastRegIndex].Reg, R9, offsetNew);
return ArmCRegs[lastRegIndex].Reg; return ArmCRegs[lastRegIndex].Reg;
} }
@ -185,7 +179,7 @@ void ArmFPRCache::Flush()
{ {
for (u8 a = 0; a < 32; ++a) 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); s16 offset = PPCSTATE_OFF(ps) + (a * 16);
u32 regindex = _regs[a][0].GetRegIndex(); u32 regindex = _regs[a][0].GetRegIndex();
@ -195,7 +189,7 @@ void ArmFPRCache::Flush()
ArmCRegs[regindex].LastLoad = 0; ArmCRegs[regindex].LastLoad = 0;
_regs[a][0].Flush(); _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; s16 offset = PPCSTATE_OFF(ps) + (a * 16) + 8;
u32 regindex = _regs[a][1].GetRegIndex(); u32 regindex = _regs[a][1].GetRegIndex();