FPU rounding modes now have effect in FADD double precision. Fixes rendering in Interstate '76.
This commit is contained in:
parent
ea13ae015b
commit
986476b9db
4 changed files with 75 additions and 0 deletions
|
|
@ -4080,7 +4080,40 @@ static void FP_OP_D(int op)
|
|||
addbyte(0x0f);
|
||||
addbyte(0x6e);
|
||||
addbyte(0xc8);
|
||||
if (((npxc >> 10) & 3) && op == FPU_ADD)
|
||||
{
|
||||
addbyte(0x0f); /*STMXCSR [ESP+8]*/
|
||||
addbyte(0xae);
|
||||
addbyte(0x5c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0x8b); /*MOV EAX, [ESP+8]*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0x25); /*AND EAX, ~(3 << 13)*/
|
||||
addlong(~(3 << 10));
|
||||
addbyte(0x0d); /*OR EAX, (npxc & (3 << 10)) << 3*/
|
||||
addlong((npxc & (3 << 10)) << 3);
|
||||
addbyte(0x89); /*MOV [RSP+12], EAX*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x0c);
|
||||
addbyte(0x0f); /*LDMXCSR [RSP+12]*/
|
||||
addbyte(0xae);
|
||||
addbyte(0x54);
|
||||
addbyte(0x24);
|
||||
addbyte(0x0c);
|
||||
}
|
||||
FP_OP_MEM(op);
|
||||
if (((npxc >> 10) & 3) && op == FPU_ADD)
|
||||
{
|
||||
addbyte(0x0f); /*LDMXCSR [RSP+8]*/
|
||||
addbyte(0xae);
|
||||
addbyte(0x54);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
}
|
||||
}
|
||||
static void FP_OP_IW(int op)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2496,6 +2496,34 @@ static void FP_OP_D(int op)
|
|||
addbyte(0x89); /*MOV [ESP], EAX*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x24);
|
||||
if (((npxc >> 10) & 3) && op == FPU_ADD)
|
||||
{
|
||||
addbyte(0x9b); /*FSTCW [ESP+8]*/
|
||||
addbyte(0xd9);
|
||||
addbyte(0x7c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0x66); /*MOV AX, [ESP+8]*/
|
||||
addbyte(0x8b);
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
addbyte(0x66); /*AND AX, ~(3 << 10)*/
|
||||
addbyte(0x25);
|
||||
addword(~(3 << 10));
|
||||
addbyte(0x66); /*OR AX, npxc & (3 << 10)*/
|
||||
addbyte(0x0d);
|
||||
addword(npxc & (3 << 10));
|
||||
addbyte(0x66); /*MOV [ESP+12], AX*/
|
||||
addbyte(0x89);
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
addbyte(0x0c);
|
||||
addbyte(0xd9); /*FLDCW [ESP+12]*/
|
||||
addbyte(0x6c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x0c);
|
||||
}
|
||||
addbyte(0x89); /*MOV [ESP+4], EDX*/
|
||||
addbyte(0x54);
|
||||
addbyte(0x24);
|
||||
|
|
@ -2515,6 +2543,13 @@ static void FP_OP_D(int op)
|
|||
addbyte(0x1c);
|
||||
addbyte(0xdd);
|
||||
addlong((uintptr_t)ST);
|
||||
if (((npxc >> 10) & 3) && op == FPU_ADD)
|
||||
{
|
||||
addbyte(0xd9); /*FLDCW [ESP+8]*/
|
||||
addbyte(0x6c);
|
||||
addbyte(0x24);
|
||||
addbyte(0x08);
|
||||
}
|
||||
}
|
||||
static void FP_OP_IW(int op)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
#include <math.h>
|
||||
#include <fenv.h>
|
||||
|
||||
#define fplog 0
|
||||
|
||||
static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO};
|
||||
|
||||
#define ST(x) ST[((TOP+(x))&7)]
|
||||
|
||||
#define C0 (1<<8)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
load_var = get(); if (abrt) return 1; \
|
||||
if ((npxc >> 10) & 3) \
|
||||
fesetround(rounding_modes[(npxc >> 10) & 3]); \
|
||||
ST(0) += use_var; \
|
||||
if ((npxc >> 10) & 3) \
|
||||
fesetround(FE_TONEAREST); \
|
||||
tag[TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
|
|
|
|||
Loading…
Reference in a new issue