mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
irjit: Implement vf2ix.
Used in LittleBigPlanet when playing intro movies.
This commit is contained in:
parent
b473f1e649
commit
a5a2671af3
7 changed files with 81 additions and 5 deletions
|
@ -986,7 +986,55 @@ namespace MIPSComp {
|
|||
// d[N] = int(S[N] * mult)
|
||||
// Note: saturates on overflow.
|
||||
|
||||
DISABLE;
|
||||
VectorSize sz = GetVecSize(op);
|
||||
int n = GetNumVectorElements(sz);
|
||||
|
||||
int imm = (op >> 16) & 0x1f;
|
||||
|
||||
u8 sregs[4], dregs[4];
|
||||
GetVectorRegsPrefixS(sregs, sz, _VS);
|
||||
GetVectorRegsPrefixD(dregs, sz, _VD);
|
||||
|
||||
// Same values as FCR31.
|
||||
uint8_t rmode = (op >> 21) & 3;
|
||||
if (((op >> 21) & 0x1C) != 0x10)
|
||||
INVALIDOP;
|
||||
|
||||
u8 tempregs[4];
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (!IsOverlapSafe(dregs[i], n, sregs)) {
|
||||
tempregs[i] = IRVTEMP_PFX_T + i; // Need IRVTEMP_0 for the scaling factor
|
||||
} else {
|
||||
tempregs[i] = dregs[i];
|
||||
}
|
||||
}
|
||||
if (imm != 0) {
|
||||
for (int i = 0; i < n; i++)
|
||||
ir.Write(IROp::FCvtScaledWS, dregs[i], sregs[i], (uint8_t)(imm | (rmode << 6)));
|
||||
} else {
|
||||
for (int i = 0; i < n; i++) {
|
||||
switch (rmode) {
|
||||
case 0: // vf2in
|
||||
ir.Write(IROp::FRound, dregs[i], sregs[i]);
|
||||
break;
|
||||
|
||||
case 1: // vf2iz
|
||||
ir.Write(IROp::FTrunc, dregs[i], sregs[i]);
|
||||
break;
|
||||
|
||||
case 2: // vf2iu
|
||||
ir.Write(IROp::FCeil, dregs[i], sregs[i]);
|
||||
break;
|
||||
|
||||
case 3: // vf2id
|
||||
ir.Write(IROp::FFloor, dregs[i], sregs[i]);
|
||||
break;
|
||||
|
||||
default:
|
||||
INVALIDOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IRFrontend::Comp_Mftv(MIPSOpcode op) {
|
||||
|
|
|
@ -105,6 +105,7 @@ static const IRMeta irMeta[] = {
|
|||
{ IROp::FFloor, "FFloor", "FF" },
|
||||
{ IROp::FCvtWS, "FCvtWS", "FF" },
|
||||
{ IROp::FCvtSW, "FCvtSW", "FF" },
|
||||
{ IROp::FCvtScaledWS, "FCvtScaledWS", "FFI" },
|
||||
{ IROp::FCmp, "FCmp", "mFF" },
|
||||
{ IROp::FSat0_1, "FSat(0 - 1)", "FF" },
|
||||
{ IROp::FSatMinus1_1, "FSat(-1 - 1)", "FF" },
|
||||
|
|
|
@ -127,6 +127,7 @@ enum class IROp : u8 {
|
|||
|
||||
FCvtWS,
|
||||
FCvtSW,
|
||||
FCvtScaledWS,
|
||||
|
||||
FMovFromGPR,
|
||||
FMovToGPR,
|
||||
|
@ -304,9 +305,6 @@ enum : IRReg {
|
|||
IRVTEMP_PFX_D = 232 - 32,
|
||||
IRVTEMP_0 = 236 - 32,
|
||||
|
||||
// 16 float temps for vector S and T prefixes and things like that.
|
||||
// IRVTEMP_0 = 208 - 64, // -64 to be relative to v[0]
|
||||
|
||||
// Hacky way to get to other state
|
||||
IRREG_VFPU_CTRL_BASE = 208,
|
||||
IRREG_VFPU_CC = 211,
|
||||
|
|
|
@ -834,7 +834,7 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) {
|
|||
mips->fi[inst->dest] = my_isinf(value) && value < 0.0f ? -2147483648LL : 2147483647LL;
|
||||
break;
|
||||
} else {
|
||||
mips->fs[inst->dest] = (int)floorf(value + 0.5f);
|
||||
mips->fs[inst->dest] = (int)round_ieee_754(value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -931,6 +931,32 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) {
|
|||
}
|
||||
break; //cvt.w.s
|
||||
}
|
||||
case IROp::FCvtScaledWS:
|
||||
{
|
||||
float src = mips->f[inst->src1];
|
||||
if (my_isnan(src)) {
|
||||
// TODO: True for negatives too?
|
||||
mips->fs[inst->dest] = 2147483647L;
|
||||
break;
|
||||
}
|
||||
|
||||
float mult = (float)(1UL << (inst->src2 & 0x1F));
|
||||
double sv = src * mult; // (float)0x7fffffff == (float)0x80000000
|
||||
// Cap/floor it to 0x7fffffff / 0x80000000
|
||||
if (sv > (double)0x7fffffff) {
|
||||
mips->fs[inst->dest] = 0x7fffffff;
|
||||
} else if (sv <= (double)(int)0x80000000) {
|
||||
mips->fs[inst->dest] = 0x80000000;
|
||||
} else {
|
||||
switch (inst->src2 >> 6) {
|
||||
case 0: mips->fs[inst->dest] = (int)round_ieee_754(sv); break;
|
||||
case 1: mips->fs[inst->dest] = src >= 0 ? (int)floor(sv) : (int)ceil(sv); break;
|
||||
case 2: mips->fs[inst->dest] = (int)ceil(sv); break;
|
||||
case 3: mips->fs[inst->dest] = (int)floor(sv); break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IROp::ZeroFpCond:
|
||||
mips->fpcond = 0;
|
||||
|
|
|
@ -667,6 +667,7 @@ bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts
|
|||
case IROp::FCeil:
|
||||
case IROp::FFloor:
|
||||
case IROp::FCvtSW:
|
||||
case IROp::FCvtScaledWS:
|
||||
case IROp::FSin:
|
||||
case IROp::FCos:
|
||||
case IROp::FSqrt:
|
||||
|
|
|
@ -190,6 +190,7 @@ void RiscVJit::CompIR_FCvt(IRInst inst) {
|
|||
|
||||
switch (inst.op) {
|
||||
case IROp::FCvtWS:
|
||||
case IROp::FCvtScaledWS:
|
||||
case IROp::FCvtSW:
|
||||
CompIR_Generic(inst);
|
||||
break;
|
||||
|
|
|
@ -265,6 +265,7 @@ void RiscVJit::CompileIRInst(IRInst inst) {
|
|||
|
||||
case IROp::FCvtWS:
|
||||
case IROp::FCvtSW:
|
||||
case IROp::FCvtScaledWS:
|
||||
CompIR_FCvt(inst);
|
||||
break;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue