mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-14 02:38:37 +12:00
spu: Check exponent bits in FMA ops (#2683)
This commit is contained in:
parent
a5fd7abcf7
commit
65bdcaed29
2 changed files with 91 additions and 14 deletions
|
@ -1297,17 +1297,50 @@ void spu_interpreter::MPYA(SPUThread& spu, spu_opcode_t op)
|
|||
|
||||
void spu_interpreter_fast::FNMS(SPUThread& spu, spu_opcode_t op)
|
||||
{
|
||||
spu.gpr[op.rt4].vf = _mm_sub_ps(spu.gpr[op.rc].vf, _mm_mul_ps(spu.gpr[op.ra].vf, spu.gpr[op.rb].vf));
|
||||
const u32 test_bits = 0x7f800000;
|
||||
auto mask = _mm_set1_ps((f32&)test_bits);
|
||||
|
||||
auto test_a = _mm_and_ps(spu.gpr[op.ra].vf, mask);
|
||||
auto mask_a = _mm_cmpneq_ps(test_a, mask);
|
||||
auto test_b = _mm_and_ps(spu.gpr[op.rb].vf, mask);
|
||||
auto mask_b = _mm_cmpneq_ps(test_b, mask);
|
||||
|
||||
auto a = _mm_and_ps(spu.gpr[op.ra].vf, mask_a);
|
||||
auto b = _mm_and_ps(spu.gpr[op.rb].vf, mask_b);
|
||||
|
||||
spu.gpr[op.rt4].vf = _mm_sub_ps(spu.gpr[op.rc].vf, _mm_mul_ps(a, b));
|
||||
}
|
||||
|
||||
void spu_interpreter_fast::FMA(SPUThread& spu, spu_opcode_t op)
|
||||
{
|
||||
spu.gpr[op.rt4].vf = _mm_add_ps(_mm_mul_ps(spu.gpr[op.ra].vf, spu.gpr[op.rb].vf), spu.gpr[op.rc].vf);
|
||||
const u32 test_bits = 0x7f800000;
|
||||
auto mask = _mm_set1_ps((f32&)test_bits);
|
||||
|
||||
auto test_a = _mm_and_ps(spu.gpr[op.ra].vf, mask);
|
||||
auto mask_a = _mm_cmpneq_ps(test_a, mask);
|
||||
auto test_b = _mm_and_ps(spu.gpr[op.rb].vf, mask);
|
||||
auto mask_b = _mm_cmpneq_ps(test_b, mask);
|
||||
|
||||
auto a = _mm_and_ps(spu.gpr[op.ra].vf, mask_a);
|
||||
auto b = _mm_and_ps(spu.gpr[op.rb].vf, mask_b);
|
||||
|
||||
spu.gpr[op.rt4].vf = _mm_add_ps(_mm_mul_ps(a, b), spu.gpr[op.rc].vf);
|
||||
}
|
||||
|
||||
void spu_interpreter_fast::FMS(SPUThread& spu, spu_opcode_t op)
|
||||
{
|
||||
spu.gpr[op.rt4].vf = _mm_sub_ps(_mm_mul_ps(spu.gpr[op.ra].vf, spu.gpr[op.rb].vf), spu.gpr[op.rc].vf);
|
||||
const u32 test_bits = 0x7f800000;
|
||||
auto mask = _mm_set1_ps((f32&)test_bits);
|
||||
|
||||
auto test_a = _mm_and_ps(spu.gpr[op.ra].vf, mask);
|
||||
auto mask_a = _mm_cmpneq_ps(test_a, mask);
|
||||
auto test_b = _mm_and_ps(spu.gpr[op.rb].vf, mask);
|
||||
auto mask_b = _mm_cmpneq_ps(test_b, mask);
|
||||
|
||||
auto a = _mm_and_ps(spu.gpr[op.ra].vf, mask_a);
|
||||
auto b = _mm_and_ps(spu.gpr[op.rb].vf, mask_b);
|
||||
|
||||
spu.gpr[op.rt4].vf = _mm_sub_ps(_mm_mul_ps(a, b), spu.gpr[op.rc].vf);
|
||||
}
|
||||
|
||||
static void SetHostRoundingMode(u32 rn)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue