Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[ARM] Implement psq_st. Optimizations in psq_l and fix all the remain…
…ing bugs...except clamping within the max value range of the value. Causes some minor visual effects mostly.
  • Loading branch information
Sonicadvance1 committed Sep 8, 2013
1 parent c1aa80c commit 4146e1f
Show file tree
Hide file tree
Showing 4 changed files with 497 additions and 36 deletions.
2 changes: 2 additions & 0 deletions Source/Core/Core/Src/PowerPC/JitArm32/Jit.h
Expand Up @@ -221,6 +221,8 @@ class JitArm : public JitBase, public ArmGen::ARMXCodeBlock

// LoadStore paired
void psq_l(UGeckoInstruction _inst);
void psq_st(UGeckoInstruction _inst);

};

#endif // _JIT64_H
62 changes: 56 additions & 6 deletions Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStorePaired.cpp
Expand Up @@ -18,22 +18,24 @@ void JitArm::psq_l(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITLoadStorePairedOff)

bool update = inst.OPCD == 57;
s32 offset = inst.SIMM_12;

// R12 contains scale
// R11 contains type
// R10 is the ADDR

if (js.memcheck) { Default(inst); return; }

LDR(R11, R9, PPCSTATE_OFF(spr[SPR_GQR0 + inst.I]));
UBFX(R12, R11, 13, 3); // Type
UBFX(R11, R11, 2, 6); // Scale
UBFX(R12, R11, 16, 3); // Type
LSL(R12, R12, 2);
UBFX(R11, R11, 24, 6); // Scale
LSL(R11, R11, 2);

MOVI2R(R10, (u32)offset);
if (inst.RA)
if (inst.RA || update) // Always uses the register on update
ADD(R10, R10, gpr.R(inst.RA));
if (update)
MOV(gpr.R(inst.RA), R10);
Expand All @@ -47,5 +49,53 @@ void JitArm::psq_l(UGeckoInstruction inst)
ARMReg vD0 = fpr.R0(inst.RS, false);
ARMReg vD1 = fpr.R1(inst.RS, false);
VCVT(vD0, S0, 0);
VCVT(vD1, S1, 0);
if (!inst.W)
VCVT(vD1, S1, 0);
else
MOVI2F(vD1, 1.0f, INVALID_REG); // No need for temp reg with 1.0f
}

void JitArm::psq_st(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITLoadStorePairedOff)

bool update = inst.OPCD == 61;
s32 offset = inst.SIMM_12;

// R12 contains scale
// R11 contains type
// R10 is the ADDR
if (js.memcheck) { 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
{
MOVI2R(R14, offset);
ADD(R10, gpr.R(inst.RA), R14);
}
else
MOVI2R(R10, (u32)offset);

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
}
6 changes: 3 additions & 3 deletions Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp
Expand Up @@ -108,9 +108,9 @@ static GekkoOPTemplate primarytable[] =
{55, &JitArm::Default}, //"stfdu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}},

{56, &JitArm::psq_l}, //"psq_l", OPTYPE_PS, FL_IN_A}},
{57, &JitArm::Default}, //"psq_lu", OPTYPE_PS, FL_OUT_A | FL_IN_A}},
{60, &JitArm::Default}, //"psq_st", OPTYPE_PS, FL_IN_A}},
{61, &JitArm::Default}, //"psq_stu", OPTYPE_PS, FL_OUT_A | FL_IN_A}},
{57, &JitArm::psq_l}, //"psq_lu", OPTYPE_PS, FL_OUT_A | FL_IN_A}},
{60, &JitArm::psq_st}, //"psq_st", OPTYPE_PS, FL_IN_A}},
{61, &JitArm::psq_st}, //"psq_stu", OPTYPE_PS, FL_OUT_A | FL_IN_A}},

//missing: 0, 5, 6, 9, 22, 30, 62, 58
{0, &JitArm::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}},
Expand Down

0 comments on commit 4146e1f

Please sign in to comment.