diff --git a/core/hw/sh4/dyna/shil_canonical.h b/core/hw/sh4/dyna/shil_canonical.h index adf2e8a26..68a7755aa 100644 --- a/core/hw/sh4/dyna/shil_canonical.h +++ b/core/hw/sh4/dyna/shil_canonical.h @@ -677,6 +677,8 @@ shil_opc(cvt_f2i_t) shil_canonical ( u32,f1,(f32 f1), + if (f1 > 0x7FFFFFBF) + f1 = 0x7FFFFFBF; return (s32)f1; ) diff --git a/core/hw/sh4/interpr/sh4_fpu.cpp b/core/hw/sh4/interpr/sh4_fpu.cpp index aa6acaec7..a64b030c5 100644 --- a/core/hw/sh4/interpr/sh4_fpu.cpp +++ b/core/hw/sh4/interpr/sh4_fpu.cpp @@ -628,7 +628,7 @@ sh4op(i1111_nnnn_0011_1101) if (fpscr.PR == 0) { u32 n = GetN(op); - fpul = (u32)(s32)fr[n]; + fpul = (u32)(s32)min(fr[n],(float)0x7FFFFFBF); if (fpul==0x80000000) //this is actually a x86-specific fix. I think ARM saturates { diff --git a/core/rec-x86/rec_x86_il.cpp b/core/rec-x86/rec_x86_il.cpp index 13c7b8f8c..38bb27976 100644 --- a/core/rec-x86/rec_x86_il.cpp +++ b/core/rec-x86/rec_x86_il.cpp @@ -1448,13 +1448,17 @@ void ngen_opcode(RuntimeBlockInfo* block, shil_opcode* op,x86_block* x86e, bool break; case shop_cvt_f2i_t: + { verify(op->rd.is_r32i()); verify(op->rs1.is_r32f()); verify(reg.IsAllocg(op->rd)); verify(reg.IsAllocf(op->rs1)); - - x86e->Emit(op_cvttss2si,reg.mapg(op->rd),reg.mapf(op->rs1)); - break; + static f32 sse_ftrc_saturate = 0x7FFFFFBF;//1.11111111111111111111111 << 31 + 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); + } + break; //i hope that the round mode bit is set properly here :p case shop_cvt_i2f_n: