Use correct rounding mode on x86 and x86-64 recompiled versions of PF2ID. Fixes rendering errors on Unreal 3DNow! software renderer
This commit is contained in:
parent
8ee9b07ab2
commit
56a4d5cf83
6 changed files with 14 additions and 0 deletions
|
|
@ -310,6 +310,7 @@ void codegen_backend_init()
|
||||||
"stmxcsr %0\n"
|
"stmxcsr %0\n"
|
||||||
: "=m" (cpu_state.old_fp_control)
|
: "=m" (cpu_state.old_fp_control)
|
||||||
);
|
);
|
||||||
|
cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void codegen_set_rounding_mode(int mode)
|
void codegen_set_rounding_mode(int mode)
|
||||||
|
|
|
||||||
|
|
@ -541,6 +541,11 @@ void host_x86_LDMXCSR(codeblock_t *block, void *p)
|
||||||
{
|
{
|
||||||
codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/
|
codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/
|
||||||
}
|
}
|
||||||
|
else if (offset < (1ull << 32))
|
||||||
|
{
|
||||||
|
codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/
|
||||||
|
codegen_addlong(block, offset);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fatal("host_x86_LDMXCSR - out of range %p\n", p);
|
fatal("host_x86_LDMXCSR - out of range %p\n", p);
|
||||||
|
|
|
||||||
|
|
@ -1576,7 +1576,9 @@ static int codegen_PF2ID(codeblock_t *block, uop_t *uop)
|
||||||
|
|
||||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a))
|
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a))
|
||||||
{
|
{
|
||||||
|
host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control);
|
||||||
host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a);
|
host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a);
|
||||||
|
host_x86_LDMXCSR(block, &cpu_state.old_fp_control);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real);
|
fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real);
|
||||||
|
|
|
||||||
|
|
@ -333,6 +333,7 @@ pclog(" offsetof(codeblock_t, next_2)=%i\n", offsetof(codeblock_t, next_2));
|
||||||
: "=m" (cpu_state.old_fp_control2),
|
: "=m" (cpu_state.old_fp_control2),
|
||||||
"=m" (cpu_state.old_fp_control)
|
"=m" (cpu_state.old_fp_control)
|
||||||
);
|
);
|
||||||
|
cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000;
|
||||||
}
|
}
|
||||||
|
|
||||||
void codegen_set_rounding_mode(int mode)
|
void codegen_set_rounding_mode(int mode)
|
||||||
|
|
|
||||||
|
|
@ -1579,7 +1579,9 @@ static int codegen_PF2ID(codeblock_t *block, uop_t *uop)
|
||||||
|
|
||||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a))
|
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a))
|
||||||
{
|
{
|
||||||
|
host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control);
|
||||||
host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a);
|
host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a);
|
||||||
|
host_x86_LDMXCSR(block, &cpu_state.old_fp_control);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real);
|
fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real);
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,9 @@ struct
|
||||||
uint32_t old_fp_control, new_fp_control;
|
uint32_t old_fp_control, new_fp_control;
|
||||||
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_
|
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_
|
||||||
uint16_t old_fp_control2, new_fp_control2;
|
uint16_t old_fp_control2, new_fp_control2;
|
||||||
|
#endif
|
||||||
|
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__
|
||||||
|
uint32_t trunc_fp_control;
|
||||||
#endif
|
#endif
|
||||||
x86seg seg_cs,seg_ds,seg_es,seg_ss,seg_fs,seg_gs;
|
x86seg seg_cs,seg_ds,seg_es,seg_ss,seg_fs,seg_gs;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue