x86-32 recompiler performs float->integer rounding by loading FPU control word instead of calling helper function - speedup on some stuff.
This commit is contained in:
parent
aab2c3e7cf
commit
dd2a608707
6 changed files with 88 additions and 182 deletions
|
|
@ -580,6 +580,7 @@ static uint32_t ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
||||||
|
|
||||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||||
STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.npxc, 0);
|
STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.npxc, 0);
|
||||||
|
UPDATE_NPXC(0);
|
||||||
|
|
||||||
return op_pc + 1;
|
return op_pc + 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4556,6 +4556,10 @@ static void FP_COMPARE_IL()
|
||||||
FP_COMPARE_MEM();
|
FP_COMPARE_MEM();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void UPDATE_NPXC(int reg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static void SET_BITS(uintptr_t addr, uint32_t val)
|
static void SET_BITS(uintptr_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
if (IS_32_ADDR(addr))
|
if (IS_32_ADDR(addr))
|
||||||
|
|
|
||||||
|
|
@ -2173,82 +2173,6 @@ static void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2)
|
||||||
*host_reg2 = REG_ECX;
|
*host_reg2 = REG_ECX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static double _fp_half = 0.5;
|
|
||||||
|
|
||||||
static void FP_LOAD_ROUNDING()
|
|
||||||
{
|
|
||||||
pclog("cpu_state.npxc %04x\n", cpu_state.npxc);
|
|
||||||
addbyte(0x8b); /*MOV EDX, npxc*/
|
|
||||||
addbyte(0x15);
|
|
||||||
addlong((uintptr_t)&cpu_state.npxc);
|
|
||||||
addbyte(0xd9); /*FSTCW [ESP+8]*/
|
|
||||||
addbyte(0x7c);
|
|
||||||
addbyte(0x24);
|
|
||||||
addbyte(0x08);
|
|
||||||
addbyte(0x89); /*MOV [ESP+12],EDX*/
|
|
||||||
addbyte(0x54);
|
|
||||||
addbyte(0x24);
|
|
||||||
addbyte(0x0c);
|
|
||||||
addbyte(0xd9); /*FLDCW [ESP+12]*/
|
|
||||||
addbyte(0x6c);
|
|
||||||
addbyte(0x24);
|
|
||||||
addbyte(0x0c);
|
|
||||||
}
|
|
||||||
static void FP_RESTORE_ROUNDING()
|
|
||||||
{
|
|
||||||
addbyte(0xd9); /*FLDCW [ESP+8]*/
|
|
||||||
addbyte(0x6c);
|
|
||||||
addbyte(0x24);
|
|
||||||
addbyte(0x08);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t x87_fround32(double b)
|
|
||||||
{
|
|
||||||
int64_t a, c;
|
|
||||||
|
|
||||||
switch ((cpu_state.npxc >> 10) & 3)
|
|
||||||
{
|
|
||||||
case 0: /*Nearest*/
|
|
||||||
a = (int64_t)floor(b);
|
|
||||||
c = (int64_t)floor(b + 1.0);
|
|
||||||
if ((b - a) < (c - b))
|
|
||||||
return a;
|
|
||||||
else if ((b - a) > (c - b))
|
|
||||||
return c;
|
|
||||||
else
|
|
||||||
return (a & 1) ? c : a;
|
|
||||||
case 1: /*Down*/
|
|
||||||
return (int32_t)floor(b);
|
|
||||||
case 2: /*Up*/
|
|
||||||
return (int32_t)ceil(b);
|
|
||||||
case 3: /*Chop*/
|
|
||||||
return (int32_t)b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static int64_t x87_fround64(double b)
|
|
||||||
{
|
|
||||||
int64_t a, c;
|
|
||||||
|
|
||||||
switch ((cpu_state.npxc >> 10) & 3)
|
|
||||||
{
|
|
||||||
case 0: /*Nearest*/
|
|
||||||
a = (int64_t)floor(b);
|
|
||||||
c = (int64_t)floor(b + 1.0);
|
|
||||||
if ((b - a) < (c - b))
|
|
||||||
return a;
|
|
||||||
else if ((b - a) > (c - b))
|
|
||||||
return c;
|
|
||||||
else
|
|
||||||
return (a & 1) ? c : a;
|
|
||||||
case 1: /*Down*/
|
|
||||||
return (int64_t)floor(b);
|
|
||||||
case 2: /*Up*/
|
|
||||||
return (int64_t)ceil(b);
|
|
||||||
case 3: /*Chop*/
|
|
||||||
return (int64_t)b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static int FP_LOAD_REG_INT_W(int reg)
|
static int FP_LOAD_REG_INT_W(int reg)
|
||||||
{
|
{
|
||||||
addbyte(0x8b); /*MOV EBX, TOP*/
|
addbyte(0x8b); /*MOV EBX, TOP*/
|
||||||
|
|
@ -2268,25 +2192,19 @@ static int FP_LOAD_REG_INT_W(int reg)
|
||||||
addbyte(0xdd);
|
addbyte(0xdd);
|
||||||
addbyte(cpu_state_offset(ST));
|
addbyte(cpu_state_offset(ST));
|
||||||
|
|
||||||
addbyte(0x89); /*MOV [ESP+8], EAX*/
|
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
|
||||||
addbyte(0x44);
|
addbyte(0x6d);
|
||||||
|
addbyte(cpu_state_offset(new_npxc));
|
||||||
|
addbyte(0xdb); /*FISTP [ESP]*/
|
||||||
|
addbyte(0x1c);
|
||||||
addbyte(0x24);
|
addbyte(0x24);
|
||||||
addbyte(0x08);
|
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
|
||||||
|
addbyte(0x6d);
|
||||||
addbyte(0xdd); /*FSTP [ESP]*/
|
addbyte(cpu_state_offset(old_npxc));
|
||||||
|
addbyte(0x8b); /*MOV EBX, [ESP]*/
|
||||||
addbyte(0x1c);
|
addbyte(0x1c);
|
||||||
addbyte(0x24);
|
addbyte(0x24);
|
||||||
|
|
||||||
CALL_FUNC(x87_fround32);
|
|
||||||
|
|
||||||
addbyte(0x89); /*MOV EBX, EAX*/
|
|
||||||
addbyte(0xc3);
|
|
||||||
|
|
||||||
addbyte(0x8b); /*MOV EAX, [ESP+8]*/
|
|
||||||
addbyte(0x44);
|
|
||||||
addbyte(0x24);
|
|
||||||
addbyte(0x08);
|
|
||||||
|
|
||||||
return REG_EBX;
|
return REG_EBX;
|
||||||
}
|
}
|
||||||
static int FP_LOAD_REG_INT(int reg)
|
static int FP_LOAD_REG_INT(int reg)
|
||||||
|
|
@ -2308,25 +2226,19 @@ static int FP_LOAD_REG_INT(int reg)
|
||||||
addbyte(0xdd);
|
addbyte(0xdd);
|
||||||
addbyte(cpu_state_offset(ST));
|
addbyte(cpu_state_offset(ST));
|
||||||
|
|
||||||
addbyte(0x89); /*MOV [ESP+8], EAX*/
|
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
|
||||||
addbyte(0x44);
|
addbyte(0x6d);
|
||||||
|
addbyte(cpu_state_offset(new_npxc));
|
||||||
|
addbyte(0xdb); /*FISTP [ESP]*/
|
||||||
|
addbyte(0x1c);
|
||||||
addbyte(0x24);
|
addbyte(0x24);
|
||||||
addbyte(0x08);
|
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
|
||||||
|
addbyte(0x6d);
|
||||||
addbyte(0xdd); /*FSTP [ESP]*/
|
addbyte(cpu_state_offset(old_npxc));
|
||||||
|
addbyte(0x8b); /*MOV EBX, [ESP]*/
|
||||||
addbyte(0x1c);
|
addbyte(0x1c);
|
||||||
addbyte(0x24);
|
addbyte(0x24);
|
||||||
|
|
||||||
CALL_FUNC(x87_fround32);
|
|
||||||
|
|
||||||
addbyte(0x89); /*MOV EBX, EAX*/
|
|
||||||
addbyte(0xc3);
|
|
||||||
|
|
||||||
addbyte(0x8b); /*MOV EAX, [ESP+8]*/
|
|
||||||
addbyte(0x44);
|
|
||||||
addbyte(0x24);
|
|
||||||
addbyte(0x08);
|
|
||||||
|
|
||||||
return REG_EBX;
|
return REG_EBX;
|
||||||
}
|
}
|
||||||
static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2)
|
static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2)
|
||||||
|
|
@ -2378,34 +2290,29 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2)
|
||||||
addbyte(cpu_state_offset(MM));
|
addbyte(cpu_state_offset(MM));
|
||||||
|
|
||||||
addbyte(0xeb); /*JMP done*/
|
addbyte(0xeb); /*JMP done*/
|
||||||
addbyte(4+4+3+5+2+2+4);
|
addbyte(4+3+3+3+3+4);
|
||||||
|
|
||||||
addbyte(0xdd); /*FLD ST[EBX*8]*/
|
addbyte(0xdd); /*FLD ST[EBX*8]*/
|
||||||
addbyte(0x44);
|
addbyte(0x44);
|
||||||
addbyte(0xdd);
|
addbyte(0xdd);
|
||||||
addbyte(cpu_state_offset(ST));
|
addbyte(cpu_state_offset(ST));
|
||||||
|
|
||||||
addbyte(0x89); /*MOV [ESP+8], EAX*/
|
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
|
||||||
addbyte(0x44);
|
addbyte(0x6d);
|
||||||
|
addbyte(cpu_state_offset(new_npxc));
|
||||||
|
addbyte(0xdf); /*FISTPQ [ESP]*/
|
||||||
|
addbyte(0x3c);
|
||||||
addbyte(0x24);
|
addbyte(0x24);
|
||||||
addbyte(0x08);
|
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
|
||||||
|
addbyte(0x6d);
|
||||||
addbyte(0xdd); /*FSTP [ESP]*/
|
addbyte(cpu_state_offset(old_npxc));
|
||||||
|
addbyte(0x8b); /*MOV EBX, [ESP]*/
|
||||||
addbyte(0x1c);
|
addbyte(0x1c);
|
||||||
addbyte(0x24);
|
addbyte(0x24);
|
||||||
|
addbyte(0x8b); /*MOV ECX, 4[ESP]*/
|
||||||
CALL_FUNC(x87_fround64);
|
addbyte(0x4c);
|
||||||
|
|
||||||
addbyte(0x89); /*MOV EBX, EAX*/
|
|
||||||
addbyte(0xc3);
|
|
||||||
|
|
||||||
addbyte(0x89); /*MOV ECX, EDX*/
|
|
||||||
addbyte(0xd1);
|
|
||||||
|
|
||||||
addbyte(0x8b); /*MOV EAX, [ESP+8]*/
|
|
||||||
addbyte(0x44);
|
|
||||||
addbyte(0x24);
|
addbyte(0x24);
|
||||||
addbyte(0x08);
|
addbyte(4);
|
||||||
|
|
||||||
*host_reg1 = REG_EBX;
|
*host_reg1 = REG_EBX;
|
||||||
*host_reg2 = REG_ECX;
|
*host_reg2 = REG_ECX;
|
||||||
|
|
@ -2511,31 +2418,9 @@ static void FP_OP_D(int op)
|
||||||
addbyte(0x04);
|
addbyte(0x04);
|
||||||
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
||||||
{
|
{
|
||||||
addbyte(0x9b); /*FSTCW [ESP+8]*/
|
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
|
||||||
addbyte(0xd9);
|
addbyte(0x6d);
|
||||||
addbyte(0x7c);
|
addbyte(cpu_state_offset(new_npxc));
|
||||||
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(cpu_state.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(0xdd); /*FLD ST[dst][EBP]*/
|
addbyte(0xdd); /*FLD ST[dst][EBP]*/
|
||||||
addbyte(0x45);
|
addbyte(0x45);
|
||||||
|
|
@ -2552,10 +2437,9 @@ static void FP_OP_D(int op)
|
||||||
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
|
addbyte(cpu_state_offset(ST[cpu_state.TOP]));
|
||||||
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
||||||
{
|
{
|
||||||
addbyte(0xd9); /*FLDCW [ESP+8]*/
|
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
|
||||||
addbyte(0x6c);
|
addbyte(0x6d);
|
||||||
addbyte(0x24);
|
addbyte(cpu_state_offset(old_npxc));
|
||||||
addbyte(0x08);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -2568,31 +2452,9 @@ static void FP_OP_D(int op)
|
||||||
addbyte(0x24);
|
addbyte(0x24);
|
||||||
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
||||||
{
|
{
|
||||||
addbyte(0x9b); /*FSTCW [ESP+8]*/
|
addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/
|
||||||
addbyte(0xd9);
|
addbyte(0x6d);
|
||||||
addbyte(0x7c);
|
addbyte(cpu_state_offset(new_npxc));
|
||||||
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(cpu_state.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(0x89); /*MOV [ESP+4], EDX*/
|
||||||
addbyte(0x54);
|
addbyte(0x54);
|
||||||
|
|
@ -2616,10 +2478,9 @@ static void FP_OP_D(int op)
|
||||||
addbyte(cpu_state_offset(ST));
|
addbyte(cpu_state_offset(ST));
|
||||||
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
||||||
{
|
{
|
||||||
addbyte(0xd9); /*FLDCW [ESP+8]*/
|
addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/
|
||||||
addbyte(0x6c);
|
addbyte(0x6d);
|
||||||
addbyte(0x24);
|
addbyte(cpu_state_offset(old_npxc));
|
||||||
addbyte(0x08);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3226,6 +3087,32 @@ static void FP_COMPARE_REG(int dst, int src)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void UPDATE_NPXC(int reg)
|
||||||
|
{
|
||||||
|
addbyte(0x66); /*AND cpu_state.new_npxc, ~0xc00*/
|
||||||
|
addbyte(0x81);
|
||||||
|
addbyte(0x65);
|
||||||
|
addbyte(cpu_state_offset(new_npxc));
|
||||||
|
addword(~0xc00);
|
||||||
|
if (reg)
|
||||||
|
{
|
||||||
|
addbyte(0x66); /*AND reg, 0xc00*/
|
||||||
|
addbyte(0x81);
|
||||||
|
addbyte(0xe0 | reg);
|
||||||
|
addword(0xc00);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addbyte(0x66); /*AND AX, 0xc00*/
|
||||||
|
addbyte(0x25);
|
||||||
|
addword(0xc00);
|
||||||
|
}
|
||||||
|
addbyte(0x66); /*OR cpu_state.new_npxc, reg*/
|
||||||
|
addbyte(0x09);
|
||||||
|
addbyte(0x45 | (reg << 3));
|
||||||
|
addbyte(cpu_state_offset(new_npxc));
|
||||||
|
}
|
||||||
|
|
||||||
static int ZERO_EXTEND_W_B(int reg)
|
static int ZERO_EXTEND_W_B(int reg)
|
||||||
{
|
{
|
||||||
addbyte(0x0f); /*MOVZX regl, regb*/
|
addbyte(0x0f); /*MOVZX regl, regb*/
|
||||||
|
|
|
||||||
|
|
@ -563,6 +563,11 @@ void codegen_init()
|
||||||
mem_store_addr_ea_b = gen_MEM_STORE_ADDR_EA_B();
|
mem_store_addr_ea_b = gen_MEM_STORE_ADDR_EA_B();
|
||||||
block_pos = 1024;
|
block_pos = 1024;
|
||||||
mem_store_addr_ea_q = gen_MEM_STORE_ADDR_EA_Q();
|
mem_store_addr_ea_q = gen_MEM_STORE_ADDR_EA_Q();
|
||||||
|
|
||||||
|
asm(
|
||||||
|
"fstcw %0\n"
|
||||||
|
: "=m" (cpu_state.old_npxc)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void codegen_reset()
|
void codegen_reset()
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,8 @@ struct
|
||||||
uint16_t MM_w4[8];
|
uint16_t MM_w4[8];
|
||||||
|
|
||||||
MMX_REG MM[8];
|
MMX_REG MM[8];
|
||||||
|
|
||||||
|
uint16_t old_npxc, new_npxc;
|
||||||
} cpu_state;
|
} cpu_state;
|
||||||
|
|
||||||
#define cycles cpu_state._cycles
|
#define cycles cpu_state._cycles
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ static int opFINIT(uint32_t fetchdat)
|
||||||
FP_ENTER();
|
FP_ENTER();
|
||||||
cpu_state.pc++;
|
cpu_state.pc++;
|
||||||
cpu_state.npxc = 0x37F;
|
cpu_state.npxc = 0x37F;
|
||||||
|
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00);
|
||||||
cpu_state.npxs = 0;
|
cpu_state.npxs = 0;
|
||||||
*(uint64_t *)cpu_state.tag = 0x0303030303030303ll;
|
*(uint64_t *)cpu_state.tag = 0x0303030303030303ll;
|
||||||
cpu_state.TOP = 0;
|
cpu_state.TOP = 0;
|
||||||
|
|
@ -85,6 +86,7 @@ static int FSTOR()
|
||||||
case 0x000: /*16-bit real mode*/
|
case 0x000: /*16-bit real mode*/
|
||||||
case 0x001: /*16-bit protected mode*/
|
case 0x001: /*16-bit protected mode*/
|
||||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||||
|
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
|
||||||
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2);
|
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2);
|
||||||
x87_settag(readmemw(easeg, cpu_state.eaaddr+4));
|
x87_settag(readmemw(easeg, cpu_state.eaaddr+4));
|
||||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||||
|
|
@ -93,6 +95,7 @@ static int FSTOR()
|
||||||
case 0x100: /*32-bit real mode*/
|
case 0x100: /*32-bit real mode*/
|
||||||
case 0x101: /*32-bit protected mode*/
|
case 0x101: /*32-bit protected mode*/
|
||||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||||
|
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
|
||||||
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4);
|
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4);
|
||||||
x87_settag(readmemw(easeg, cpu_state.eaaddr+8));
|
x87_settag(readmemw(easeg, cpu_state.eaaddr+8));
|
||||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||||
|
|
@ -665,6 +668,7 @@ static int FLDENV()
|
||||||
case 0x000: /*16-bit real mode*/
|
case 0x000: /*16-bit real mode*/
|
||||||
case 0x001: /*16-bit protected mode*/
|
case 0x001: /*16-bit protected mode*/
|
||||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||||
|
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
|
||||||
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2);
|
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2);
|
||||||
x87_settag(readmemw(easeg, cpu_state.eaaddr+4));
|
x87_settag(readmemw(easeg, cpu_state.eaaddr+4));
|
||||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||||
|
|
@ -672,6 +676,7 @@ static int FLDENV()
|
||||||
case 0x100: /*32-bit real mode*/
|
case 0x100: /*32-bit real mode*/
|
||||||
case 0x101: /*32-bit protected mode*/
|
case 0x101: /*32-bit protected mode*/
|
||||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||||
|
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
|
||||||
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4);
|
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4);
|
||||||
x87_settag(readmemw(easeg, cpu_state.eaaddr+8));
|
x87_settag(readmemw(easeg, cpu_state.eaaddr+8));
|
||||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||||
|
|
@ -705,6 +710,7 @@ static int opFLDCW_a16(uint32_t fetchdat)
|
||||||
tempw = geteaw();
|
tempw = geteaw();
|
||||||
if (cpu_state.abrt) return 1;
|
if (cpu_state.abrt) return 1;
|
||||||
cpu_state.npxc = tempw;
|
cpu_state.npxc = tempw;
|
||||||
|
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
|
||||||
CLOCK_CYCLES(4);
|
CLOCK_CYCLES(4);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -717,6 +723,7 @@ static int opFLDCW_a32(uint32_t fetchdat)
|
||||||
tempw = geteaw();
|
tempw = geteaw();
|
||||||
if (cpu_state.abrt) return 1;
|
if (cpu_state.abrt) return 1;
|
||||||
cpu_state.npxc = tempw;
|
cpu_state.npxc = tempw;
|
||||||
|
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
|
||||||
CLOCK_CYCLES(4);
|
CLOCK_CYCLES(4);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue