Merge pull request #3447 from degasus/arm

JITArm64: Single precision + FPRF
This commit is contained in:
Ryan Houdek 2016-01-04 22:09:44 -05:00
commit b00bb300e5
4 changed files with 75 additions and 0 deletions

View File

@ -34,6 +34,7 @@ void JitArm64::faddsx(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;
@ -42,6 +43,7 @@ void JitArm64::faddsx(UGeckoInstruction inst)
ARM64Reg VD = fpr.RW(d, REG_DUP);
m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
fpr.FixSinglePrecision(d);
}
void JitArm64::faddx(UGeckoInstruction inst)
@ -49,6 +51,7 @@ void JitArm64::faddx(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;
@ -64,6 +67,7 @@ void JitArm64::fmaddsx(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, c = inst.FC, d = inst.FD;
@ -75,6 +79,7 @@ void JitArm64::fmaddsx(UGeckoInstruction inst)
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(V0), EncodeRegToDouble(VB));
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -84,6 +89,7 @@ void JitArm64::fmaddx(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, c = inst.FC, d = inst.FD;
@ -114,6 +120,7 @@ void JitArm64::fmsubsx(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, c = inst.FC, d = inst.FD;
@ -125,6 +132,7 @@ void JitArm64::fmsubsx(UGeckoInstruction inst)
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(V0), EncodeRegToDouble(VB));
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -134,6 +142,7 @@ void JitArm64::fmsubx(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, c = inst.FC, d = inst.FD;
@ -150,6 +159,7 @@ 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;
@ -158,6 +168,7 @@ void JitArm64::fmulsx(UGeckoInstruction inst)
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)
@ -165,6 +176,7 @@ 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;
@ -209,6 +221,7 @@ void JitArm64::fnmaddsx(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, c = inst.FC, d = inst.FD;
@ -221,6 +234,7 @@ void JitArm64::fnmaddsx(UGeckoInstruction inst)
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(V0), EncodeRegToDouble(VB));
m_float_emit.FNEG(EncodeRegToDouble(VD), EncodeRegToDouble(VD));
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -230,6 +244,7 @@ void JitArm64::fnmaddx(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, c = inst.FC, d = inst.FD;
@ -246,6 +261,7 @@ void JitArm64::fnmsubsx(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, c = inst.FC, d = inst.FD;
@ -258,6 +274,7 @@ void JitArm64::fnmsubsx(UGeckoInstruction inst)
m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(V0), EncodeRegToDouble(VB));
m_float_emit.FNEG(EncodeRegToDouble(VD), EncodeRegToDouble(VD));
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -267,6 +284,7 @@ void JitArm64::fnmsubx(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, c = inst.FC, d = inst.FD;
@ -300,6 +318,7 @@ 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;
@ -308,6 +327,7 @@ void JitArm64::fsubsx(UGeckoInstruction inst)
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)
@ -315,6 +335,7 @@ 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;
@ -330,6 +351,7 @@ void JitArm64::frspx(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 b = inst.FB, d = inst.FD;
@ -453,6 +475,7 @@ 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;
@ -468,6 +491,7 @@ 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;
@ -476,4 +500,5 @@ void JitArm64::fdivsx(UGeckoInstruction inst)
ARM64Reg VD = fpr.RW(d, REG_DUP);
m_float_emit.FDIV(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
fpr.FixSinglePrecision(d);
}

View File

@ -35,6 +35,7 @@ void JitArm64::ps_add(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, d = inst.FD;
@ -43,6 +44,7 @@ void JitArm64::ps_add(UGeckoInstruction inst)
ARM64Reg VD = fpr.RW(d, REG_REG);
m_float_emit.FADD(64, VD, VA, VB);
fpr.FixSinglePrecision(d);
}
void JitArm64::ps_div(UGeckoInstruction inst)
@ -50,6 +52,7 @@ void JitArm64::ps_div(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, d = inst.FD;
@ -58,6 +61,7 @@ void JitArm64::ps_div(UGeckoInstruction inst)
ARM64Reg VD = fpr.RW(d, REG_REG);
m_float_emit.FDIV(64, VD, VA, VB);
fpr.FixSinglePrecision(d);
}
void JitArm64::ps_madd(UGeckoInstruction inst)
@ -65,6 +69,7 @@ void JitArm64::ps_madd(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
@ -76,6 +81,7 @@ void JitArm64::ps_madd(UGeckoInstruction inst)
m_float_emit.FMUL(64, V0, VA, VC);
m_float_emit.FADD(64, VD, V0, VB);
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -85,6 +91,7 @@ void JitArm64::ps_madds0(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
@ -97,6 +104,7 @@ void JitArm64::ps_madds0(UGeckoInstruction inst)
m_float_emit.DUP(64, V0, VC, 0);
m_float_emit.FMUL(64, V0, V0, VA);
m_float_emit.FADD(64, VD, V0, VB);
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -106,6 +114,7 @@ void JitArm64::ps_madds1(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
@ -118,6 +127,7 @@ void JitArm64::ps_madds1(UGeckoInstruction inst)
m_float_emit.DUP(64, V0, VC, 1);
m_float_emit.FMUL(64, V0, V0, VA);
m_float_emit.FADD(64, VD, V0, VB);
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -217,6 +227,7 @@ void JitArm64::ps_mul(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, c = inst.FC, d = inst.FD;
@ -225,6 +236,7 @@ void JitArm64::ps_mul(UGeckoInstruction inst)
ARM64Reg VD = fpr.RW(d, REG_REG);
m_float_emit.FMUL(64, VD, VA, VC);
fpr.FixSinglePrecision(d);
}
void JitArm64::ps_muls0(UGeckoInstruction inst)
@ -232,6 +244,7 @@ void JitArm64::ps_muls0(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, c = inst.FC, d = inst.FD;
@ -242,6 +255,7 @@ void JitArm64::ps_muls0(UGeckoInstruction inst)
m_float_emit.DUP(64, V0, VC, 0);
m_float_emit.FMUL(64, VD, VA, V0);
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -250,6 +264,7 @@ void JitArm64::ps_muls1(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, c = inst.FC, d = inst.FD;
@ -260,6 +275,7 @@ void JitArm64::ps_muls1(UGeckoInstruction inst)
m_float_emit.DUP(64, V0, VC, 1);
m_float_emit.FMUL(64, VD, VA, V0);
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -268,6 +284,7 @@ void JitArm64::ps_msub(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
@ -279,6 +296,7 @@ void JitArm64::ps_msub(UGeckoInstruction inst)
m_float_emit.FMUL(64, V0, VA, VC);
m_float_emit.FSUB(64, VD, V0, VB);
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -317,6 +335,7 @@ void JitArm64::ps_nmadd(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
@ -329,6 +348,7 @@ void JitArm64::ps_nmadd(UGeckoInstruction inst)
m_float_emit.FMUL(64, V0, VA, VC);
m_float_emit.FADD(64, VD, V0, VB);
m_float_emit.FNEG(64, VD, VD);
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -338,6 +358,7 @@ void JitArm64::ps_nmsub(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
@ -350,6 +371,7 @@ void JitArm64::ps_nmsub(UGeckoInstruction inst)
m_float_emit.FMUL(64, V0, VA, VC);
m_float_emit.FSUB(64, VD, V0, VB);
m_float_emit.FNEG(64, VD, VD);
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -359,6 +381,7 @@ void JitArm64::ps_res(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 b = inst.FB, d = inst.FD;
@ -366,6 +389,7 @@ void JitArm64::ps_res(UGeckoInstruction inst)
ARM64Reg VD = fpr.RW(d, REG_REG);
m_float_emit.FRSQRTE(64, VD, VB);
fpr.FixSinglePrecision(d);
}
void JitArm64::ps_sel(UGeckoInstruction inst)
@ -401,6 +425,7 @@ void JitArm64::ps_sub(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, d = inst.FD;
@ -409,6 +434,7 @@ void JitArm64::ps_sub(UGeckoInstruction inst)
ARM64Reg VD = fpr.RW(d, REG_REG);
m_float_emit.FSUB(64, VD, VA, VB);
fpr.FixSinglePrecision(d);
}
void JitArm64::ps_sum0(UGeckoInstruction inst)
@ -416,6 +442,7 @@ void JitArm64::ps_sum0(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
@ -436,6 +463,7 @@ void JitArm64::ps_sum0(UGeckoInstruction inst)
m_float_emit.FADD(64, V0, V0, VA);
m_float_emit.INS(64, VD, 0, V0, 0);
}
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}
@ -445,6 +473,7 @@ void JitArm64::ps_sum1(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITPairedOff);
FALLBACK_IF(inst.Rc);
FALLBACK_IF(SConfig::GetInstance().bFPRF && js.op->wantsFPRF);
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
@ -465,6 +494,7 @@ void JitArm64::ps_sum1(UGeckoInstruction inst)
m_float_emit.FADD(64, V0, V0, VB);
m_float_emit.INS(64, VD, 1, V0, 1);
}
fpr.FixSinglePrecision(d);
fpr.Unlock(V0);
}

View File

@ -559,3 +559,21 @@ BitSet32 Arm64FPRCache::GetCallerSavedUsed()
registers[it.GetReg() - Q0] = 1;
return registers;
}
void Arm64FPRCache::FixSinglePrecision(u32 preg)
{
ARM64Reg host_reg = m_guest_registers[preg].GetReg();
switch (m_guest_registers[preg].GetType())
{
case REG_DUP: // only PS0 needs to be converted
m_float_emit->FCVT(32, 64, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg));
m_float_emit->FCVT(64, 32, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg));
break;
case REG_REG: // PS0 and PS1 needs to be converted
m_float_emit->FCVTN(32, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg));
m_float_emit->FCVTL(64, EncodeRegToDouble(host_reg), EncodeRegToDouble(host_reg));
break;
default:
break;
}
}

View File

@ -277,6 +277,8 @@ public:
BitSet32 GetCallerSavedUsed() override;
void FixSinglePrecision(u32 preg);
protected:
// Get the order of the host registers
void GetAllocationOrder();