Jit64: implement fctiw/fctiwz

This commit is contained in:
Tillmann Karras 2014-06-08 14:30:59 +02:00
parent 6df48ed432
commit 6521929f99
3 changed files with 45 additions and 2 deletions

View File

@ -174,6 +174,7 @@ public:
void fp_arith(UGeckoInstruction inst);
void fcmpx(UGeckoInstruction inst);
void fctiwx(UGeckoInstruction inst);
void fmrx(UGeckoInstruction inst);
void cmpXX(UGeckoInstruction inst);

View File

@ -337,8 +337,8 @@ static GekkoOPTemplate table63[] =
{264, &Jit64::fsign}, //"fabsx", OPTYPE_FPU, FL_RC_BIT_F}},
{32, &Jit64::fcmpx}, //"fcmpo", OPTYPE_FPU, FL_RC_BIT_F}},
{0, &Jit64::fcmpx}, //"fcmpu", OPTYPE_FPU, FL_RC_BIT_F}},
{14, &Jit64::FallBackToInterpreter}, //"fctiwx", OPTYPE_FPU, FL_RC_BIT_F}},
{15, &Jit64::FallBackToInterpreter}, //"fctiwzx", OPTYPE_FPU, FL_RC_BIT_F}},
{14, &Jit64::fctiwx}, //"fctiwx", OPTYPE_FPU, FL_RC_BIT_F}},
{15, &Jit64::fctiwx}, //"fctiwzx", OPTYPE_FPU, FL_RC_BIT_F}},
{72, &Jit64::fmrx}, //"fmrx", OPTYPE_FPU, FL_RC_BIT_F}},
{136, &Jit64::fsign}, //"fnabsx", OPTYPE_FPU, FL_RC_BIT_F}},
{40, &Jit64::fsign}, //"fnegx", OPTYPE_FPU, FL_RC_BIT_F}},

View File

@ -10,6 +10,7 @@
static const u64 GC_ALIGNED16(psSignBits2[2]) = {0x8000000000000000ULL, 0x8000000000000000ULL};
static const u64 GC_ALIGNED16(psAbsMask2[2]) = {0x7FFFFFFFFFFFFFFFULL, 0x7FFFFFFFFFFFFFFFULL};
static const double GC_ALIGNED16(half_qnan_and_s32_max[2]) = {0x7FFFFFFF, -0x80000};
void Jit64::fp_tri_op(int d, int a, int b, bool reversible, bool single, void (XEmitter::*op)(Gen::X64Reg, Gen::OpArg))
{
@ -267,3 +268,44 @@ void Jit64::fcmpx(UGeckoInstruction inst)
fpr.UnlockAll();
}
void Jit64::fctiwx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITFloatingPointOff);
FALLBACK_IF(inst.Rc);
int d = inst.RD;
int b = inst.RB;
fpr.Lock(d, b);
fpr.BindToRegister(d, d == b);
// Intel uses 0x80000000 as a generic error code while PowerPC uses clamping:
//
// input | output fctiw | output CVTPD2DQ
// ------------+--------------+----------------
// > +2^31 - 1 | 0x7fffffff | 0x80000000
// < -2^31 | 0x80000000 | 0x80000000
// any NaN | 0x80000000 | 0x80000000
//
// The upper 32 bits of the result are set to 0xfff80000,
// except for -0.0 where they are set to 0xfff80001 (TODO).
MOVAPD(XMM0, M(&half_qnan_and_s32_max));
MINSD(XMM0, fpr.R(b));
switch (inst.SUBOP10)
{
// fctiwx
case 14:
CVTPD2DQ(XMM0, R(XMM0));
break;
// fctiwzx
case 15:
CVTTPD2DQ(XMM0, R(XMM0));
break;
}
// d[64+] must not be modified
MOVSD(fpr.R(d), XMM0);
fpr.UnlockAll();
}