diff --git a/core/hw/sh4/dyna/shil_canonical.h b/core/hw/sh4/dyna/shil_canonical.h index 68a7755aa..0dd421be9 100644 --- a/core/hw/sh4/dyna/shil_canonical.h +++ b/core/hw/sh4/dyna/shil_canonical.h @@ -677,9 +677,10 @@ shil_opc(cvt_f2i_t) shil_canonical ( u32,f1,(f32 f1), - if (f1 > 0x7FFFFFBF) - f1 = 0x7FFFFFBF; - return (s32)f1; + if (f1 > 2147483520.0f) // IEEE 754: 0x4effffff + return 0x7fffffff; + else + return (s32)f1; ) shil_compile @@ -687,7 +688,6 @@ shil_compile shil_cf_arg_f32(rs1); shil_cf(f1); shil_cf_rv_u32(rd); - //die(); ) shil_opc_end() @@ -1044,4 +1044,4 @@ SHIL_END #undef UN_OP_I #undef UN_OP_F #undef BIN_OP_FU -#undef shil_recimp \ No newline at end of file +#undef shil_recimp diff --git a/core/hw/sh4/interpr/sh4_fpu.cpp b/core/hw/sh4/interpr/sh4_fpu.cpp index a64b030c5..2d28687e2 100644 --- a/core/hw/sh4/interpr/sh4_fpu.cpp +++ b/core/hw/sh4/interpr/sh4_fpu.cpp @@ -628,22 +628,25 @@ sh4op(i1111_nnnn_0011_1101) if (fpscr.PR == 0) { u32 n = GetN(op); - fpul = (u32)(s32)min(fr[n],(float)0x7FFFFFBF); + fpul = (u32)(s32)min(fr[n], 2147483520.0f); // IEEE 754: 0x4effffff - if (fpul==0x80000000) //this is actually a x86-specific fix. I think ARM saturates + // Intel CPUs convert out of range float numbers to 0x80000000. Manually set the correct sign + if (fpul == 0x80000000) { - if (fr[n]>0) + if (*(int *)&fr[n] > 0) // Using integer math to avoid issues with Inf and NaN fpul--; } } else { u32 n = (op >> 9) & 0x07; - fpul = (u32)(s32)GetDR(n); + f64 f = GetDR(n); + fpul = (u32)(s32)f; - if (fpul==0x80000000) //this is actually a x86-specific fix. I think ARM saturates + // Intel CPUs convert out of range float numbers to 0x80000000. Manually set the correct sign + if (fpul == 0x80000000) { - if (GetDR(n)>0) + if (*(s64 *)&f > 0) // Using integer math to avoid issues with Inf and NaN fpul--; } } diff --git a/core/rec-x86/rec_x86_il.cpp b/core/rec-x86/rec_x86_il.cpp index 38bb27976..80d43bdc6 100644 --- a/core/rec-x86/rec_x86_il.cpp +++ b/core/rec-x86/rec_x86_il.cpp @@ -1453,7 +1453,7 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool verify(op->rs1.is_r32f()); verify(reg.IsAllocg(op->rd)); verify(reg.IsAllocf(op->rs1)); - static f32 sse_ftrc_saturate = 0x7FFFFFBF;//1.11111111111111111111111 << 31 + static f32 sse_ftrc_saturate = 2147483520.0f; // IEEE 754: 0x4effffff x86e->Emit(op_movaps, XMM0, reg.mapf(op->rs1)); x86e->Emit(op_minss, XMM0, &sse_ftrc_saturate); x86e->Emit(op_cvttss2si, reg.mapg(op->rd), XMM0); @@ -1536,4 +1536,4 @@ defaulty: } } -#endif \ No newline at end of file +#endif