diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index 0faee4c347..7166870a8f 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -7869,7 +7869,7 @@ public: if (g_cfg.core.spu_accurate_xfloat) set_vr(op.rt, fsplat(1.0) / fsqrt(fabs(get_vr(op.ra)))); else - set_vr(op.rt, fsplat(1.0) / fsqrt(fabs(get_vr(op.ra)))); + set_vr(op.rt, frsqe(fabs(get_vr(op.ra)))); } void FCGT(spu_opcode_t op) @@ -8305,9 +8305,31 @@ public: { // TODO if (g_cfg.core.spu_accurate_xfloat) + { set_vr(op.rt, get_vr(op.rb)); + // const auto [a, b] = get_vrs(op.ra, op.rb); + + // const auto mask_se = splat(0xfff0000000000000ull); + // const auto mask_bf = splat(0x000fff8000000000ull); + // const auto mask_sf = splat(0x0000007fe0000000ull); + // const auto mask_yf = splat(0x0000ffffe0000000ull); + + // const auto base = bitcast((bitcast(b) & mask_bf) | 0x3ff0000000000000ull); + // const auto step = fpcast(bitcast(b) & mask_sf) * fsplat(std::exp2(-13.f)); + // const auto yval = fpcast(bitcast(a) & mask_yf) * fsplat(std::exp2(-19.f)); + // set_vr(op.rt, bitcast((bitcast(b) & mask_se) | (bitcast(base - step * yval) & ~mask_se))); + } else - set_vr(op.rt, get_vr(op.rb)); + { + const auto [a, b] = get_vrs(op.ra, op.rb); + + const auto mask_se = splat(0xff800000u); // Sign and exponent mask + + const auto base = (b & 0x007ffc00u) << 9; // Base fraction + const auto ymul = (b & 0x3ff) * (a & 0x7ffff); // Step fraction * Y fraction (fixed point at 2^-32) + const auto bnew = bitcast((base - ymul) >> 9) + (sext(ymul <= base) & (1 << 23)); // Subtract and correct invisible fraction bit + set_vr(op.rt, (b & mask_se) | (bitcast(fpcast(bnew)) & ~mask_se)); // Inject old sign and exponent + } } void CFLTS(spu_opcode_t op)