From 08dd95e52b75d4f6b7c7376c6e21f0533ab72371 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 21 Mar 2015 22:39:56 +0300 Subject: [PATCH] SPU: Floating Interpolate implemented --- rpcs3/Emu/Cell/SPUInterpreter.cpp | 51 ++++++++++++++++++------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUInterpreter.cpp b/rpcs3/Emu/Cell/SPUInterpreter.cpp index faddf20138..b2bcc91d0a 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/SPUInterpreter.cpp @@ -18,6 +18,27 @@ #define rotl32(x,r) (((u32)(x) << (r)) | ((u32)(x) >> (32 - (r)))) #endif +class spu_scale_table_t +{ + std::array<__m128, 155 + 174> m_data; + +public: + spu_scale_table_t() + { + for (s32 i = -155; i < 174; i++) + { + m_data[i + 155] = _mm_set1_ps(static_cast(pow(2, i))); + } + } + + __forceinline __m128 operator [] (s32 scale) const + { + return m_data[scale + 155]; + } +} +const g_spu_scale_table; + + void spu_interpreter::DEFAULT(SPUThread& CPU, spu_opcode_t op) { SPUInterpreter inter(CPU); (*SPU_instr::rrr_list)(&inter, op.opcode); @@ -891,7 +912,14 @@ void spu_interpreter::CEQB(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::FI(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt] = CPU.GPR[op.rb]; + const auto mask_se = _mm_castsi128_ps(_mm_set1_epi32(0xff800000)); // sign and exponent mask + const auto mask_bf = _mm_castsi128_ps(_mm_set1_epi32(0x007ffc00)); // base fraction mask + const auto mask_sf = _mm_set1_epi32(0x000003ff); // step fraction mask + const auto mask_yf = _mm_set1_epi32(0x0007ffff); // Y fraction mask (bits 13..31) + const auto base = _mm_or_ps(_mm_and_ps(CPU.GPR[op.rb].vf, mask_bf), _mm_castsi128_ps(_mm_set1_epi32(0x3f800000))); + const auto step = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(CPU.GPR[op.rb].vi, mask_sf)), g_spu_scale_table[-13]); + const auto y = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(CPU.GPR[op.ra].vi, mask_yf)), g_spu_scale_table[-19]); + CPU.GPR[op.rt].vf = _mm_or_ps(_mm_and_ps(mask_se, CPU.GPR[op.rb].vf), _mm_andnot_ps(mask_se, _mm_sub_ps(base, _mm_mul_ps(step, y)))); } void spu_interpreter::HEQ(SPUThread& CPU, spu_opcode_t op) @@ -903,27 +931,6 @@ void spu_interpreter::HEQ(SPUThread& CPU, spu_opcode_t op) } -class spu_scale_table_t -{ - std::array<__m128, 155 + 174> m_data; - -public: - spu_scale_table_t() - { - for (s32 i = -155; i < 174; i++) - { - m_data[i + 155] = _mm_set1_ps(static_cast(pow(2, i))); - } - } - - __forceinline __m128 operator [] (s32 scale) const - { - return m_data[scale + 155]; - } -} -const g_spu_scale_table; - - void spu_interpreter::CFLTS(SPUThread& CPU, spu_opcode_t op) { const auto scaled = _mm_mul_ps(CPU.GPR[op.ra].vf, g_spu_scale_table[173 - op.i8]);