diff --git a/rpcs3/Emu/Cell/PPUTranslator.cpp b/rpcs3/Emu/Cell/PPUTranslator.cpp index 0a17de2d0f..3e0959807b 100644 --- a/rpcs3/Emu/Cell/PPUTranslator.cpp +++ b/rpcs3/Emu/Cell/PPUTranslator.cpp @@ -1115,7 +1115,24 @@ void PPUTranslator::VCFSX(ppu_opcode_t op) void PPUTranslator::VCFUX(ppu_opcode_t op) { const auto b = get_vr(op.vb); - set_vr(op.vd, fpcast(b) * fsplat(std::pow(2, -static_cast(op.vuimm)))); + +#ifdef ARCH_ARM64 + return set_vr(op.vd, fpcast(b) * fsplat(std::pow(2, -static_cast(op.vuimm)))); +#else + if (m_use_avx512) + { + return set_vr(op.vd, fpcast(b) * fsplat(std::pow(2, -static_cast(op.vuimm)))); + } + + constexpr int bit_shift = 9; + const auto shifted = (b >> bit_shift); + const auto cleared = shifted << bit_shift; + const auto low_bits = b - cleared; + const auto high_part = fpcast(noncast(shifted)) * fsplat(static_cast(1u << bit_shift)); + const auto low_part = fpcast(noncast(low_bits)); + const auto temp = high_part + low_part; + set_vr(op.vd, temp * fsplat(std::pow(2, -static_cast(op.vuimm)))); +#endif } void PPUTranslator::VCMPBFP(ppu_opcode_t op) diff --git a/rpcs3/util/simd.hpp b/rpcs3/util/simd.hpp index ff4e0eed78..a60f8732a3 100644 --- a/rpcs3/util/simd.hpp +++ b/rpcs3/util/simd.hpp @@ -2213,8 +2213,11 @@ inline v128 gv_cvtu32_tofs(const v128& src) #if defined(__AVX512VL__) return _mm_cvtepu32_ps(src); #elif defined(ARCH_X64) - const auto fix = _mm_and_ps(_mm_castsi128_ps(_mm_srai_epi32(src, 31)), _mm_set1_ps(0x80000000)); - return _mm_add_ps(_mm_cvtepi32_ps(_mm_and_si128(src, _mm_set1_epi32(0x7fffffff))), fix); + constexpr u64 bit_shift = 9; + const auto shifted = _mm_srli_epi32(src, bit_shift); + const auto cleared = _mm_slli_epi32(shifted, bit_shift); + const auto low_bits = _mm_sub_epi32(src, cleared); + return _mm_add_ps(_mm_cvtepi32_ps(low_bits), _mm_mul_ps(_mm_cvtepi32_ps(shifted), _mm_set_ps1(1u << bit_shift))); #elif defined(ARCH_ARM64) return vcvtq_f32_u32(src); #endif