[ARM] psq_lx/psq_lux/psq_stx/psq_stux implementations. Four more instructions that JIT64 doesn't have.

This commit is contained in:
Ryan Houdek 2013-09-25 02:22:52 +00:00
parent cd646d89e2
commit ae75f92b2a
3 changed files with 98 additions and 5 deletions

View File

@ -253,8 +253,9 @@ public:
// LoadStore paired // LoadStore paired
void psq_l(UGeckoInstruction _inst); void psq_l(UGeckoInstruction _inst);
void psq_lx(UGeckoInstruction _inst);
void psq_st(UGeckoInstruction _inst); void psq_st(UGeckoInstruction _inst);
void psq_stx(UGeckoInstruction _inst);
}; };
#endif // _JIT64_H #endif // _JIT64_H

View File

@ -54,6 +54,54 @@ void JitArm::psq_l(UGeckoInstruction inst)
MOVI2F(vD1, 1.0f, INVALID_REG); // No need for temp reg with 1.0f MOVI2F(vD1, 1.0f, INVALID_REG); // No need for temp reg with 1.0f
} }
void JitArm::psq_lx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITLoadStorePairedOff)
bool update = inst.SUBOP10 == 38;
// R12 contains scale
// R11 contains type
// R10 is the ADDR
if (js.memcheck || !Core::g_CoreStartupParameter.bFastmem) { Default(inst); return; }
LDR(R11, R9, PPCSTATE_OFF(spr[SPR_GQR0 + inst.Ix]));
UBFX(R12, R11, 16, 3); // Type
LSL(R12, R12, 2);
UBFX(R11, R11, 24, 6); // Scale
LSL(R11, R11, 2);
if (inst.RA || update) // Always uses the register on update
{
ADD(R10, gpr.R(inst.RB), gpr.R(inst.RA));
}
else
MOV(R10, gpr.R(inst.RB));
if (update)
MOV(gpr.R(inst.RA), R10);
MOVI2R(R14, (u32)asm_routines.pairedLoadQuantized);
ADD(R14, R14, R12);
LDR(R14, R14, inst.Wx ? 8 * 4 : 0);
// Values returned in S0, S1
BL(R14); // Jump to the quantizer Load
ARMReg vD0 = fpr.R0(inst.RS, false);
ARMReg vD1 = fpr.R1(inst.RS, false);
LDR(R14, R9, PPCSTATE_OFF(Exceptions));
CMP(R14, EXCEPTION_DSI);
SetCC(CC_NEQ);
VCVT(vD0, S0, 0);
if (!inst.Wx)
VCVT(vD1, S1, 0);
else
MOVI2F(vD1, 1.0f, INVALID_REG); // No need for temp reg with 1.0f
SetCC();
}
void JitArm::psq_st(UGeckoInstruction inst) void JitArm::psq_st(UGeckoInstruction inst)
{ {
INSTRUCTION_START INSTRUCTION_START
@ -98,3 +146,47 @@ void JitArm::psq_st(UGeckoInstruction inst)
// floats passed through D0 // floats passed through D0
BL(R14); // Jump to the quantizer Store BL(R14); // Jump to the quantizer Store
} }
void JitArm::psq_stx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITLoadStorePairedOff)
bool update = inst.SUBOP10 == 39;
// R12 contains scale
// R11 contains type
// R10 is the ADDR
if (js.memcheck || !Core::g_CoreStartupParameter.bFastmem) { Default(inst); return; }
LDR(R11, R9, PPCSTATE_OFF(spr[SPR_GQR0 + inst.I]));
UBFX(R12, R11, 0, 3); // Type
LSL(R12, R12, 2);
UBFX(R11, R11, 8, 6); // Scale
LSL(R11, R11, 2);
if (inst.RA || update) // Always uses the register on update
{
ADD(R10, gpr.R(inst.RA), gpr.R(inst.RB));
}
else
MOV(R10, gpr.R(inst.RB));
if (update)
MOV(gpr.R(inst.RA), R10);
MOVI2R(R14, (u32)asm_routines.pairedStoreQuantized);
ADD(R14, R14, R12);
LDR(R14, R14, inst.W ? 8 * 4 : 0);
ARMReg vD0 = fpr.R0(inst.RS);
VCVT(S0, vD0, 0);
if (!inst.W)
{
ARMReg vD1 = fpr.R1(inst.RS);
VCVT(S1, vD1, 0);
}
// floats passed through D0
BL(R14); // Jump to the quantizer Store
}

View File

@ -165,10 +165,10 @@ static GekkoOPTemplate table4_2[] =
static GekkoOPTemplate table4_3[] = static GekkoOPTemplate table4_3[] =
{ {
{6, &JitArm::Default}, //"psq_lx", OPTYPE_PS, 0}}, {6, &JitArm::psq_lx}, //"psq_lx", OPTYPE_PS, 0}},
{7, &JitArm::Default}, //"psq_stx", OPTYPE_PS, 0}}, {7, &JitArm::psq_stx}, //"psq_stx", OPTYPE_PS, 0}},
{38, &JitArm::Default}, //"psq_lux", OPTYPE_PS, 0}}, {38, &JitArm::psq_lx}, //"psq_lux", OPTYPE_PS, 0}},
{39, &JitArm::Default}, //"psq_stux", OPTYPE_PS, 0}}, {39, &JitArm::psq_stx}, //"psq_stux", OPTYPE_PS, 0}},
}; };
static GekkoOPTemplate table19[] = static GekkoOPTemplate table19[] =