x87: Fix Final Reality discolored screen for all dynarecs

This commit is contained in:
Cacodemon345
2025-02-27 13:50:45 +06:00
parent 6d3816df64
commit 03dd94f361
5 changed files with 75 additions and 0 deletions

View File

@@ -3571,6 +3571,8 @@ FP_FLD(int reg)
addbyte(0x89); /*MOV [TOP], EBX*/
addbyte(0x5d);
addbyte((uint8_t) cpu_state_offset(TOP));
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void
@@ -3688,6 +3690,8 @@ FP_LOAD_S(void)
addbyte(0x44);
addbyte(0x1d);
addbyte((uint8_t) cpu_state_offset(tag));
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void
FP_LOAD_D(void)
@@ -3717,6 +3721,8 @@ FP_LOAD_D(void)
addbyte(0x44);
addbyte(0x1d);
addbyte((uint8_t) cpu_state_offset(tag));
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void
@@ -3754,6 +3760,8 @@ FP_LOAD_IW(void)
addbyte(0x44);
addbyte(0x1d);
addbyte((uint8_t) cpu_state_offset(tag));
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void
FP_LOAD_IL(void)
@@ -3787,6 +3795,8 @@ FP_LOAD_IL(void)
addbyte(0x44);
addbyte(0x1d);
addbyte((uint8_t) cpu_state_offset(tag));
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void
FP_LOAD_IQ(void)
@@ -3831,6 +3841,8 @@ FP_LOAD_IQ(void)
addbyte(0x44);
addbyte(0x1d);
addbyte((uint8_t) cpu_state_offset(tag));
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void
@@ -3863,6 +3875,8 @@ FP_LOAD_IMM_Q(uint64_t v)
addbyte(0x1d);
addbyte((uint8_t) cpu_state_offset(tag));
addbyte(v ? 0 : 1);
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void

View File

@@ -1794,6 +1794,7 @@ FP_FLD(int reg)
addbyte(0x5d);
addbyte((uint8_t) cpu_state_offset(TOP));
}
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void
@@ -2037,6 +2038,7 @@ FP_LOAD_S(void)
addbyte(0x1d);
addbyte((uint8_t) cpu_state_offset(tag[0]));
}
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void
FP_LOAD_D(void)
@@ -2096,6 +2098,7 @@ FP_LOAD_D(void)
addbyte(0x1d);
addbyte((uint8_t) cpu_state_offset(tag[0]));
}
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void
FP_LOAD_IW(void)
@@ -2154,6 +2157,7 @@ FP_LOAD_IW(void)
addbyte(0x1d);
addbyte((uint8_t) cpu_state_offset(tag[0]));
}
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void
FP_LOAD_IL(void)
@@ -2210,6 +2214,7 @@ FP_LOAD_IL(void)
addbyte(0x1d);
addbyte((uint8_t) cpu_state_offset(tag[0]));
}
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void
FP_LOAD_IQ(void)
@@ -2285,6 +2290,7 @@ FP_LOAD_IQ(void)
addbyte(0x1d);
addbyte((uint8_t) cpu_state_offset(tag[0]));
}
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline void
@@ -2336,6 +2342,7 @@ FP_LOAD_IMM_Q(uint64_t v)
addbyte(0x5d);
addbyte((uint8_t) cpu_state_offset(TOP));
}
CALL_FUNC((uintptr_t) x87_to_mmxreg);
}
static __inline int

View File

@@ -64,6 +64,9 @@ fpu_POP2(codeblock_t *block, ir_data_t *ir)
static inline void
fpu_PUSH(codeblock_t *block, ir_data_t *ir)
{
uop_LOAD_FUNC_ARG_IMM(ir, 0, ((uint16_t)cpu_state.TOP - 1));
uop_CALL_FUNC(ir, x87_to_mmxreg);
if (block->flags & CODEBLOCK_STATIC_TOP)
uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP - 1);
else

View File

@@ -74,6 +74,51 @@ x386_dynarec_log(const char *fmt, ...)
# define x386_dynarec_log(fmt, ...)
#endif
/* Deliberately stashed here; this function is only relevant for dynamic recompilers. */
#if defined(_MSC_VER) && !defined(__clang__)
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
# define X87_INLINE_ASM
# endif
#else
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__
# define X87_INLINE_ASM
# endif
#endif
#ifdef USE_NEW_DYNAREC
void
x87_to_mmxreg(uint16_t reg)
#else
void
x87_to_mmxreg(void)
#endif
{
#ifndef USE_NEW_DYNAREC
uint32_t reg = cpu_state.TOP & 7;
#endif
double val = cpu_state.ST[reg & 7];
#ifdef X87_INLINE_ASM
unsigned char buffer[10];
#else
x87_conv_t test;
#endif
#ifdef X87_INLINE_ASM
__asm volatile(""
:
:
: "memory");
__asm volatile("fldl %1\n"
"fstpt %0\n" : "=m"(buffer) : "m"(val));
cpu_state.MM[reg & 7].q = (*(uint64_t*)buffer);
#else
x87_to80(val, &test);
cpu_state.MM[reg & 7].q = test.eind.ll;
#endif
}
static __inline void
fetch_ea_32_long(uint32_t rmdat)
{

View File

@@ -829,6 +829,12 @@ extern uint16_t prefetch_queue_get_ip(void);
extern int prefetch_queue_get_prefetching(void);
extern int prefetch_queue_get_size(void);
#ifdef USE_NEW_DYNAREC
extern void x87_to_mmxreg(uint16_t reg);
#else
extern void x87_to_mmxreg(void);
#endif
#define prefetch_queue_set_suspended(s) prefetch_queue_set_prefetching(!s)
#define prefetch_queue_get_suspended !prefetch_queue_get_prefetching