JitArm64: Merge 3 way FP instructions.

This commit is contained in:
degasus
2016-02-10 14:49:06 +01:00
parent 3938fa791c
commit 83eb1d8c31
3 changed files with 35 additions and 136 deletions

View File

@ -137,16 +137,13 @@ public:
void stfXX(UGeckoInstruction inst); void stfXX(UGeckoInstruction inst);
// Floating point // Floating point
void fp_arith(UGeckoInstruction inst);
void fabsx(UGeckoInstruction inst); void fabsx(UGeckoInstruction inst);
void faddsx(UGeckoInstruction inst);
void faddx(UGeckoInstruction inst);
void fmaddsx(UGeckoInstruction inst); void fmaddsx(UGeckoInstruction inst);
void fmaddx(UGeckoInstruction inst); void fmaddx(UGeckoInstruction inst);
void fmrx(UGeckoInstruction inst); void fmrx(UGeckoInstruction inst);
void fmsubsx(UGeckoInstruction inst); void fmsubsx(UGeckoInstruction inst);
void fmsubx(UGeckoInstruction inst); void fmsubx(UGeckoInstruction inst);
void fmulsx(UGeckoInstruction inst);
void fmulx(UGeckoInstruction inst);
void fnabsx(UGeckoInstruction inst); void fnabsx(UGeckoInstruction inst);
void fnegx(UGeckoInstruction inst); void fnegx(UGeckoInstruction inst);
void fnmaddsx(UGeckoInstruction inst); void fnmaddsx(UGeckoInstruction inst);
@ -154,13 +151,9 @@ public:
void fnmsubsx(UGeckoInstruction inst); void fnmsubsx(UGeckoInstruction inst);
void fnmsubx(UGeckoInstruction inst); void fnmsubx(UGeckoInstruction inst);
void fselx(UGeckoInstruction inst); void fselx(UGeckoInstruction inst);
void fsubsx(UGeckoInstruction inst);
void fsubx(UGeckoInstruction inst);
void fcmpX(UGeckoInstruction inst); void fcmpX(UGeckoInstruction inst);
void frspx(UGeckoInstruction inst); void frspx(UGeckoInstruction inst);
void fctiwzx(UGeckoInstruction inst); void fctiwzx(UGeckoInstruction inst);
void fdivx(UGeckoInstruction inst);
void fdivsx(UGeckoInstruction inst);
// Paired // Paired
void ps_abs(UGeckoInstruction inst); void ps_abs(UGeckoInstruction inst);

View File

@ -30,37 +30,42 @@ void JitArm64::fabsx(UGeckoInstruction inst)
m_float_emit.FABS(EncodeRegToDouble(VD), EncodeRegToDouble(VB)); m_float_emit.FABS(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
} }
void JitArm64::faddsx(UGeckoInstruction inst) void JitArm64::fp_arith(UGeckoInstruction inst)
{ {
INSTRUCTION_START INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff); JITDISABLE(bJITFloatingPointOff);
FALLBACK_IF(inst.Rc); FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, d = inst.FD; u32 a = inst.FA, d = inst.FD;
u32 b = inst.SUBOP5 == 25 ? inst.FC : inst.FB;
ARM64Reg VA = fpr.R(a, REG_IS_LOADED); bool single = inst.OPCD == 4 || inst.OPCD == 59;
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.RW(d, REG_DUP);
m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB)); ARM64Reg VA = EncodeRegToDouble(fpr.R(a, REG_IS_LOADED));
fpr.FixSinglePrecision(d); ARM64Reg VB = EncodeRegToDouble(fpr.R(b, REG_IS_LOADED));
} ARM64Reg VD = EncodeRegToDouble(fpr.RW(d, single ? REG_DUP : REG_LOWER_PAIR));
void JitArm64::faddx(UGeckoInstruction inst) switch (inst.SUBOP5)
{ {
INSTRUCTION_START case 18:
JITDISABLE(bJITFloatingPointOff); m_float_emit.FDIV(VD, VA, VB);
FALLBACK_IF(inst.Rc); break;
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF); case 20:
m_float_emit.FSUB(VD, VA, VB);
break;
case 21:
m_float_emit.FADD(VD, VA, VB);
break;
case 25:
m_float_emit.FMUL(VD, VA, VB);
break;
default:
_assert_msg_(DYNA_REC, 0, "fp_arith WTF!!!");
}
u32 a = inst.FA, b = inst.FB, d = inst.FD; if (single)
fpr.FixSinglePrecision(d);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.RW(d);
m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
} }
void JitArm64::fmaddsx(UGeckoInstruction inst) void JitArm64::fmaddsx(UGeckoInstruction inst)
@ -155,39 +160,6 @@ void JitArm64::fmsubx(UGeckoInstruction inst)
m_float_emit.FNMSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB)); m_float_emit.FNMSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
} }
void JitArm64::fmulsx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, c = inst.FC, d = inst.FD;
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c, REG_IS_LOADED);
ARM64Reg VD = fpr.RW(d, REG_DUP);
m_float_emit.FMUL(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
fpr.FixSinglePrecision(d);
}
void JitArm64::fmulx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, c = inst.FC, d = inst.FD;
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c, REG_IS_LOADED);
ARM64Reg VD = fpr.RW(d);
m_float_emit.FMUL(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
}
void JitArm64::fnabsx(UGeckoInstruction inst) void JitArm64::fnabsx(UGeckoInstruction inst)
{ {
INSTRUCTION_START INSTRUCTION_START
@ -314,39 +286,6 @@ void JitArm64::fselx(UGeckoInstruction inst)
m_float_emit.FCSEL(EncodeRegToDouble(VD), EncodeRegToDouble(VC), EncodeRegToDouble(VB), CC_GE); m_float_emit.FCSEL(EncodeRegToDouble(VD), EncodeRegToDouble(VC), EncodeRegToDouble(VB), CC_GE);
} }
void JitArm64::fsubsx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, d = inst.FD;
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.RW(d, REG_DUP);
m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
fpr.FixSinglePrecision(d);
}
void JitArm64::fsubx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, d = inst.FD;
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.RW(d);
m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
}
void JitArm64::frspx(UGeckoInstruction inst) void JitArm64::frspx(UGeckoInstruction inst)
{ {
INSTRUCTION_START INSTRUCTION_START
@ -448,36 +387,3 @@ void JitArm64::fctiwzx(UGeckoInstruction inst)
m_float_emit.ORR(EncodeRegToDouble(VD), EncodeRegToDouble(VD), EncodeRegToDouble(V0)); m_float_emit.ORR(EncodeRegToDouble(VD), EncodeRegToDouble(VD), EncodeRegToDouble(V0));
fpr.Unlock(V0); fpr.Unlock(V0);
} }
void JitArm64::fdivx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, d = inst.FD;
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.RW(d);
m_float_emit.FDIV(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
}
void JitArm64::fdivsx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, d = inst.FD;
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.RW(d, REG_DUP);
m_float_emit.FDIV(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
fpr.FixSinglePrecision(d);
}

View File

@ -313,11 +313,11 @@ static GekkoOPTemplate table31[] =
static GekkoOPTemplate table59[] = static GekkoOPTemplate table59[] =
{ {
{18, &JitArm64::fdivsx}, // fdivsx {18, &JitArm64::fp_arith}, // fdivsx
{20, &JitArm64::fsubsx}, // fsubsx {20, &JitArm64::fp_arith}, // fsubsx
{21, &JitArm64::faddsx}, // faddsx {21, &JitArm64::fp_arith}, // faddsx
{24, &JitArm64::FallBackToInterpreter}, // fresx {24, &JitArm64::FallBackToInterpreter}, // fresx
{25, &JitArm64::fmulsx}, // fmulsx {25, &JitArm64::fp_arith}, // fmulsx
{28, &JitArm64::fmsubsx}, // fmsubsx {28, &JitArm64::fmsubsx}, // fmsubsx
{29, &JitArm64::fmaddsx}, // fmaddsx {29, &JitArm64::fmaddsx}, // fmaddsx
{30, &JitArm64::fnmsubsx}, // fnmsubsx {30, &JitArm64::fnmsubsx}, // fnmsubsx
@ -346,11 +346,11 @@ static GekkoOPTemplate table63[] =
static GekkoOPTemplate table63_2[] = static GekkoOPTemplate table63_2[] =
{ {
{18, &JitArm64::fdivx}, // fdivx {18, &JitArm64::fp_arith}, // fdivx
{20, &JitArm64::fsubx}, // fsubx {20, &JitArm64::fp_arith}, // fsubx
{21, &JitArm64::faddx}, // faddx {21, &JitArm64::fp_arith}, // faddx
{23, &JitArm64::fselx}, // fselx {23, &JitArm64::fselx}, // fselx
{25, &JitArm64::fmulx}, // fmulx {25, &JitArm64::fp_arith}, // fmulx
{26, &JitArm64::FallBackToInterpreter}, // frsqrtex {26, &JitArm64::FallBackToInterpreter}, // frsqrtex
{28, &JitArm64::fmsubx}, // fmsubx {28, &JitArm64::fmsubx}, // fmsubx
{29, &JitArm64::fmaddx}, // fmaddx {29, &JitArm64::fmaddx}, // fmaddx