mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-24 15:01:16 +01:00
[ARM] Fix the FPR cache to not have to dump registers after every instruction. Add mullwox instruction.
This commit is contained in:
parent
06062d5744
commit
39a8645ffc
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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}},
|
||||||
|
@ -54,7 +54,7 @@ ARMReg *ArmFPRCache::GetPPCAllocationOrder(int &count)
|
|||||||
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);
|
||||||
@ -131,12 +131,6 @@ ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad)
|
|||||||
{
|
{
|
||||||
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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user