mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
IR: Add FExp2 and FLog2 for vexp2, vlog2 and vrexp2
These were always interpreted. They're now IR ops that the native backends compile to calls to vfpu_exp2 and vfpu_log2, like FSin and FAsin. vrexp2 is FNeg followed by FExp2, which is how vfpu_rexp2 computes it. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
d313cf7626
commit
b832ceab83
10 files changed
+75
-3
No files matched your search
@@ -563,6 +563,14 @@ void Arm64JitBackend::CompIR_FSpecial(IRInst inst) {
|
||||
callFuncF_F(&vfpu_sqrt);
|
||||
break;
|
||||
|
||||
case IROp::FExp2:
|
||||
callFuncF_F(&vfpu_exp2);
|
||||
break;
|
||||
|
||||
case IROp::FLog2:
|
||||
callFuncF_F(&vfpu_log2);
|
||||
break;
|
||||
|
||||
default:
|
||||
INVALIDOP;
|
||||
break;
|
||||
|
||||
@@ -1122,10 +1122,10 @@ namespace MIPSComp {
|
||||
ir.Write(IROp::FCos, tempregs[i], sregs[i]);
|
||||
break;
|
||||
case 20: // d[i] = powf(2.0f, s[i]); break; //vexp2
|
||||
DISABLE;
|
||||
ir.Write(IROp::FExp2, tempregs[i], sregs[i]);
|
||||
break;
|
||||
case 21: // d[i] = logf(s[i])/log(2.0f); break; //vlog2
|
||||
DISABLE;
|
||||
ir.Write(IROp::FLog2, tempregs[i], sregs[i]);
|
||||
break;
|
||||
case 22: // d[i] = sqrtf(s[i]); break; //vsqrt
|
||||
ir.Write(IROp::FVSqrt, tempregs[i], sregs[i]);
|
||||
@@ -1142,7 +1142,9 @@ namespace MIPSComp {
|
||||
ir.Write(IROp::FNeg, tempregs[i], tempregs[i]);
|
||||
break;
|
||||
case 28: // d[i] = 1.0f / expf(s[i] * (float)M_LOG2E); break; // vrexp2
|
||||
DISABLE;
|
||||
// exp2(-x), as vfpu_rexp2 computes it.
|
||||
ir.Write(IROp::FNeg, tempregs[i], sregs[i]);
|
||||
ir.Write(IROp::FExp2, tempregs[i], tempregs[i]);
|
||||
break;
|
||||
default:
|
||||
INVALIDOP;
|
||||
|
||||
@@ -110,6 +110,8 @@ static const IRMeta irMeta[] = {
|
||||
{ IROp::FRecip, "FRecip", "FF" },
|
||||
{ IROp::FAsin, "FAsin", "FF" },
|
||||
{ IROp::FVSqrt, "FVSqrt", "FF" },
|
||||
{ IROp::FExp2, "FExp2", "FF" },
|
||||
{ IROp::FLog2, "FLog2", "FF" },
|
||||
{ IROp::FNeg, "FNeg", "FF" },
|
||||
{ IROp::FSign, "FSign", "FF" },
|
||||
{ IROp::FAbs, "FAbs", "FF" },
|
||||
|
||||
@@ -201,6 +201,8 @@ enum class IROp : uint8_t {
|
||||
FRecip, // vrcp, bit-exact with the PSP
|
||||
FAsin,
|
||||
FVSqrt, // vsqrt, bit-exact with the PSP (FSqrt is the FPU's IEEE sqrt.s)
|
||||
FExp2, // vexp2, bit-exact with the PSP
|
||||
FLog2, // vlog2, bit-exact with the PSP
|
||||
|
||||
// Fake/System instructions
|
||||
Interpret,
|
||||
|
||||
@@ -640,6 +640,12 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst) {
|
||||
case IROp::FVSqrt:
|
||||
mips->f[inst->dest] = vfpu_sqrt(mips->f[inst->src1]);
|
||||
break;
|
||||
case IROp::FExp2:
|
||||
mips->f[inst->dest] = vfpu_exp2(mips->f[inst->src1]);
|
||||
break;
|
||||
case IROp::FLog2:
|
||||
mips->f[inst->dest] = vfpu_log2(mips->f[inst->src1]);
|
||||
break;
|
||||
|
||||
case IROp::ShlImm:
|
||||
mips->r[inst->dest] = mips->r[inst->src1] << (int)inst->src2;
|
||||
|
||||
@@ -433,6 +433,8 @@ void IRNativeBackend::CompileIRInst(IRInst inst) {
|
||||
case IROp::FRecip:
|
||||
case IROp::FAsin:
|
||||
case IROp::FVSqrt:
|
||||
case IROp::FExp2:
|
||||
case IROp::FLog2:
|
||||
CompIR_FSpecial(inst);
|
||||
break;
|
||||
|
||||
|
||||
@@ -766,6 +766,8 @@ bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts
|
||||
case IROp::FRecip:
|
||||
case IROp::FAsin:
|
||||
case IROp::FVSqrt:
|
||||
case IROp::FExp2:
|
||||
case IROp::FLog2:
|
||||
out.Write(inst);
|
||||
break;
|
||||
|
||||
|
||||
@@ -608,6 +608,14 @@ void LoongArch64JitBackend::CompIR_FSpecial(IRInst inst) {
|
||||
callFuncF_F(&vfpu_sqrt);
|
||||
break;
|
||||
|
||||
case IROp::FExp2:
|
||||
callFuncF_F(&vfpu_exp2);
|
||||
break;
|
||||
|
||||
case IROp::FLog2:
|
||||
callFuncF_F(&vfpu_log2);
|
||||
break;
|
||||
|
||||
default:
|
||||
INVALIDOP;
|
||||
break;
|
||||
|
||||
@@ -633,6 +633,14 @@ void RiscVJitBackend::CompIR_FSpecial(IRInst inst) {
|
||||
callFuncF_F(&vfpu_sqrt);
|
||||
break;
|
||||
|
||||
case IROp::FExp2:
|
||||
callFuncF_F(&vfpu_exp2);
|
||||
break;
|
||||
|
||||
case IROp::FLog2:
|
||||
callFuncF_F(&vfpu_log2);
|
||||
break;
|
||||
|
||||
default:
|
||||
INVALIDOP;
|
||||
break;
|
||||
|
||||
@@ -970,6 +970,14 @@ static float X64JIT_XMM_CALL x64_asin(float f) {
|
||||
return vfpu_asin(f);
|
||||
}
|
||||
|
||||
static float X64JIT_XMM_CALL x64_exp2(float f) {
|
||||
return vfpu_exp2(f);
|
||||
}
|
||||
|
||||
static float X64JIT_XMM_CALL x64_log2(float f) {
|
||||
return vfpu_log2(f);
|
||||
}
|
||||
|
||||
static float X64JIT_XMM_CALL x64_vsqrt(float f) {
|
||||
return vfpu_sqrt(f);
|
||||
}
|
||||
@@ -1006,6 +1014,22 @@ static uint32_t x64_asin(uint32_t v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
static uint32_t x64_exp2(uint32_t v) {
|
||||
float f;
|
||||
memcpy(&f, &v, sizeof(v));
|
||||
f = vfpu_exp2(f);
|
||||
memcpy(&v, &f, sizeof(v));
|
||||
return v;
|
||||
}
|
||||
|
||||
static uint32_t x64_log2(uint32_t v) {
|
||||
float f;
|
||||
memcpy(&f, &v, sizeof(v));
|
||||
f = vfpu_log2(f);
|
||||
memcpy(&v, &f, sizeof(v));
|
||||
return v;
|
||||
}
|
||||
|
||||
static uint32_t x64_vsqrt(uint32_t v) {
|
||||
float f;
|
||||
memcpy(&f, &v, sizeof(v));
|
||||
@@ -1098,6 +1122,14 @@ void X64JitBackend::CompIR_FSpecial(IRInst inst) {
|
||||
callFuncF_F((const void *)&x64_vsqrt);
|
||||
break;
|
||||
|
||||
case IROp::FExp2:
|
||||
callFuncF_F((const void *)&x64_exp2);
|
||||
break;
|
||||
|
||||
case IROp::FLog2:
|
||||
callFuncF_F((const void *)&x64_log2);
|
||||
break;
|
||||
|
||||
default:
|
||||
INVALIDOP;
|
||||
break;
|
||||
|
||||
Reference in new issue
Block a user