mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-12 09:09:29 +01:00
Merge pull request #17798 from unknownbrackets/irjit-vf2ix
irjit: Implement vf2ix
This commit is contained in:
7 files changed
+86
-30
No files matched your search
+46
-26
@@ -929,37 +929,17 @@ namespace MIPSComp {
|
||||
VectorSize sz = GetVecSize(op);
|
||||
int n = GetNumVectorElements(sz);
|
||||
|
||||
int imm = (op >> 16) & 0x1f;
|
||||
const float mult = 1.0f / (float)(1UL << imm);
|
||||
uint8_t imm = (op >> 16) & 0x1f;
|
||||
|
||||
u8 sregs[4], dregs[4];
|
||||
GetVectorRegsPrefixS(sregs, sz, _VS);
|
||||
GetVectorRegsPrefixD(dregs, sz, _VD);
|
||||
|
||||
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 (mult != 1.0f)
|
||||
ir.Write(IROp::SetConstF, IRVTEMP_0, ir.AddConstantFloat(mult));
|
||||
// TODO: Use the SCVTF with builtin scaling where possible.
|
||||
for (int i = 0; i < n; i++) {
|
||||
ir.Write(IROp::FCvtSW, tempregs[i], sregs[i]);
|
||||
}
|
||||
if (mult != 1.0f) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
ir.Write(IROp::FMul, tempregs[i], tempregs[i], IRVTEMP_0);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (dregs[i] != tempregs[i]) {
|
||||
ir.Write(IROp::FMov, dregs[i], tempregs[i]);
|
||||
}
|
||||
if (imm == 0)
|
||||
ir.Write(IROp::FCvtSW, dregs[i], sregs[i]);
|
||||
else
|
||||
ir.Write(IROp::FCvtScaledSW, dregs[i], sregs[i], imm);
|
||||
}
|
||||
ApplyPrefixD(dregs, sz);
|
||||
}
|
||||
@@ -986,7 +966,47 @@ namespace MIPSComp {
|
||||
// d[N] = int(S[N] * mult)
|
||||
// Note: saturates on overflow.
|
||||
|
||||
DISABLE;
|
||||
VectorSize sz = GetVecSize(op);
|
||||
int n = GetNumVectorElements(sz);
|
||||
|
||||
uint8_t 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;
|
||||
|
||||
if (imm != 0) {
|
||||
for (int i = 0; i < n; i++)
|
||||
ir.Write(IROp::FCvtScaledWS, dregs[i], sregs[i], 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,8 @@ static const IRMeta irMeta[] = {
|
||||
{ IROp::FFloor, "FFloor", "FF" },
|
||||
{ IROp::FCvtWS, "FCvtWS", "FF" },
|
||||
{ IROp::FCvtSW, "FCvtSW", "FF" },
|
||||
{ IROp::FCvtScaledWS, "FCvtScaledWS", "FFI" },
|
||||
{ IROp::FCvtScaledSW, "FCvtScaledSW", "FFI" },
|
||||
{ IROp::FCmp, "FCmp", "mFF" },
|
||||
{ IROp::FSat0_1, "FSat(0 - 1)", "FF" },
|
||||
{ IROp::FSatMinus1_1, "FSat(-1 - 1)", "FF" },
|
||||
|
||||
@@ -127,6 +127,8 @@ enum class IROp : u8 {
|
||||
|
||||
FCvtWS,
|
||||
FCvtSW,
|
||||
FCvtScaledWS,
|
||||
FCvtScaledSW,
|
||||
|
||||
FMovFromGPR,
|
||||
FMovToGPR,
|
||||
@@ -304,9 +306,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,35 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) {
|
||||
}
|
||||
break; //cvt.w.s
|
||||
}
|
||||
case IROp::FCvtScaledSW:
|
||||
mips->f[inst->dest] = (float)mips->fs[inst->src1] * (1.0f / (1UL << (inst->src2 & 0x1F)));
|
||||
break;
|
||||
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,8 @@ bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts
|
||||
case IROp::FCeil:
|
||||
case IROp::FFloor:
|
||||
case IROp::FCvtSW:
|
||||
case IROp::FCvtScaledWS:
|
||||
case IROp::FCvtScaledSW:
|
||||
case IROp::FSin:
|
||||
case IROp::FCos:
|
||||
case IROp::FSqrt:
|
||||
|
||||
@@ -190,7 +190,9 @@ void RiscVJit::CompIR_FCvt(IRInst inst) {
|
||||
|
||||
switch (inst.op) {
|
||||
case IROp::FCvtWS:
|
||||
case IROp::FCvtScaledWS:
|
||||
case IROp::FCvtSW:
|
||||
case IROp::FCvtScaledSW:
|
||||
CompIR_Generic(inst);
|
||||
break;
|
||||
|
||||
|
||||
@@ -265,6 +265,8 @@ void RiscVJit::CompileIRInst(IRInst inst) {
|
||||
|
||||
case IROp::FCvtWS:
|
||||
case IROp::FCvtSW:
|
||||
case IROp::FCvtScaledWS:
|
||||
case IROp::FCvtScaledSW:
|
||||
CompIR_FCvt(inst);
|
||||
break;
|
||||
|
||||
|
||||
Reference in new issue
Block a user