Remove remaining references to 32-bit addresses in x86-64 recompiler.
This commit is contained in:
parent
ea4cd4f35c
commit
6aef53e854
9 changed files with 509 additions and 237 deletions
|
|
@ -483,7 +483,7 @@ static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
|
|||
int host_reg;
|
||||
|
||||
FP_ENTER();
|
||||
host_reg = LOAD_VAR_W(&npxs);
|
||||
host_reg = LOAD_VAR_W(&cpu_state.npxs);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX);
|
||||
|
||||
return op_pc;
|
||||
|
|
@ -579,7 +579,7 @@ static uint32_t ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
|||
CHECK_SEG_READ(target_seg);
|
||||
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t)&npxc, 0);
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.npxc, 0);
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
|
@ -594,7 +594,7 @@ static uint32_t ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
|||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&npxc);
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxc);
|
||||
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
|
||||
#define HOST_REG_XMM_START 0
|
||||
#define HOST_REG_XMM_END 7
|
||||
|
||||
#define IS_32_ADDR(x) !(((uintptr_t)x) & 0xffffffff00000000)
|
||||
|
||||
static inline int find_host_xmm_reg()
|
||||
{
|
||||
int c;
|
||||
|
|
@ -515,7 +518,12 @@ static void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val)
|
|||
}
|
||||
else
|
||||
{
|
||||
fatal("addr > 32-bit\n");
|
||||
addbyte(0x48); /*MOV ESI, &addr*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad(addr);
|
||||
addbyte(0xc7); /*MOVL [ESI], val*/
|
||||
addbyte(0x00 | REG_ESI);
|
||||
addlong(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -859,11 +867,23 @@ static void CHECK_SEG_READ(x86seg *seg)
|
|||
if (seg->checked)
|
||||
return;
|
||||
|
||||
addbyte(0x83); /*CMP seg->base, -1*/
|
||||
addbyte(0x3c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(-1);
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x83); /*CMP seg->base, -1*/
|
||||
addbyte(0x3c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, &addr*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)&seg->base);
|
||||
addbyte(0x83); /*CMP RSI, -1*/
|
||||
addbyte(0xe8 | REG_ESI);
|
||||
addbyte(0xff);
|
||||
}
|
||||
addbyte(0x0f); /*JE end*/
|
||||
addbyte(0x84);
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
|
|
@ -881,11 +901,23 @@ static void CHECK_SEG_WRITE(x86seg *seg)
|
|||
if (seg->checked)
|
||||
return;
|
||||
|
||||
addbyte(0x83); /*CMP seg->base, -1*/
|
||||
addbyte(0x3c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(-1);
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x83); /*CMP seg->base, -1*/
|
||||
addbyte(0x3c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
addbyte(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, &addr*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)&seg->base);
|
||||
addbyte(0x83); /*CMP RSI, -1*/
|
||||
addbyte(0xe8 | REG_ESI);
|
||||
addbyte(0xff);
|
||||
}
|
||||
addbyte(0x0f); /*JE end*/
|
||||
addbyte(0x84);
|
||||
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
|
||||
|
|
@ -894,10 +926,20 @@ static void CHECK_SEG_WRITE(x86seg *seg)
|
|||
}
|
||||
static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
|
||||
{
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/
|
||||
addlong((uint32_t)seg);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, &addr*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)seg);
|
||||
}
|
||||
addbyte(0x3b); /*CMP EAX, seg->limit_low*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->limit_low);
|
||||
addbyte(0x46);
|
||||
addbyte((uintptr_t)&seg->limit_low - (uintptr_t)seg);
|
||||
addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/
|
||||
addbyte(0x82);
|
||||
addlong(BLOCK_GPF_OFFSET - (block_pos + 4));
|
||||
|
|
@ -907,9 +949,8 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
|
|||
addbyte(0xc0);
|
||||
addbyte(end_offset);
|
||||
addbyte(0x3b); /*CMP EAX, seg->limit_high*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->limit_high);
|
||||
addbyte(0x46);
|
||||
addbyte((uintptr_t)&seg->limit_high - (uintptr_t)seg);
|
||||
addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/
|
||||
addbyte(0x87);
|
||||
addlong(BLOCK_GPF_OFFSET - (block_pos + 4));
|
||||
|
|
@ -919,14 +960,23 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
|
|||
}
|
||||
}
|
||||
|
||||
#define IS_32_ADDR(x) !(((uintptr_t)x) & 0xffffffff00000000)
|
||||
|
||||
static void MEM_LOAD_ADDR_EA_B(x86seg *seg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, &seg->base*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)&seg->base);
|
||||
addbyte(0x8b); /*MOV ECX, [RSI]*/
|
||||
addbyte(0x0e);
|
||||
}
|
||||
addbyte(0x67); /*LEA ESI, (EAX,ECX)*/
|
||||
addbyte(0x8d);
|
||||
addbyte(0x34);
|
||||
|
|
@ -980,10 +1030,21 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg)
|
|||
}
|
||||
static void MEM_LOAD_ADDR_EA_W(x86seg *seg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, &seg->base*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)&seg->base);
|
||||
addbyte(0x8b); /*MOV ECX, [RSI]*/
|
||||
addbyte(0x0e);
|
||||
}
|
||||
addbyte(0x67); /*LEA ESI, (EAX,ECX)*/
|
||||
addbyte(0x8d);
|
||||
addbyte(0x34);
|
||||
|
|
@ -1046,10 +1107,21 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg)
|
|||
}
|
||||
static void MEM_LOAD_ADDR_EA_L(x86seg *seg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, &seg->base*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)&seg->base);
|
||||
addbyte(0x8b); /*MOV ECX, [RSI]*/
|
||||
addbyte(0x0e);
|
||||
}
|
||||
addbyte(0x67); /*LEA ESI, (EAX,ECX)*/
|
||||
addbyte(0x8d);
|
||||
addbyte(0x34);
|
||||
|
|
@ -1111,10 +1183,21 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg)
|
|||
}
|
||||
static void MEM_LOAD_ADDR_EA_Q(x86seg *seg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, &seg->base*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)&seg->base);
|
||||
addbyte(0x8b); /*MOV ECX, [RSI]*/
|
||||
addbyte(0x0e);
|
||||
}
|
||||
addbyte(0x67); /*LEA ESI, (EAX,ECX)*/
|
||||
addbyte(0x8d);
|
||||
addbyte(0x34);
|
||||
|
|
@ -1219,10 +1302,21 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
|
|||
addbyte(8);
|
||||
host_reg = 8;
|
||||
}
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, &seg->base*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)&seg->base);
|
||||
addbyte(0x8b); /*MOV ECX, [RSI]*/
|
||||
addbyte(0x0e);
|
||||
}
|
||||
addbyte(0x67); /*LEA ESI, (EAX,ECX)*/
|
||||
addbyte(0x8d);
|
||||
addbyte(0x34);
|
||||
|
|
@ -1287,10 +1381,21 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
|
|||
}
|
||||
static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, &seg->base*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)&seg->base);
|
||||
addbyte(0x8b); /*MOV ECX, [RSI]*/
|
||||
addbyte(0x0e);
|
||||
}
|
||||
addbyte(0x67); /*LEA ESI, (EAX,ECX)*/
|
||||
addbyte(0x8d);
|
||||
addbyte(0x34);
|
||||
|
|
@ -1366,10 +1471,21 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
|
|||
}
|
||||
static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, &seg->base*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)&seg->base);
|
||||
addbyte(0x8b); /*MOV ECX, [RSI]*/
|
||||
addbyte(0x0e);
|
||||
}
|
||||
addbyte(0x67); /*LEA ESI, (EAX,ECX)*/
|
||||
addbyte(0x8d);
|
||||
addbyte(0x34);
|
||||
|
|
@ -1443,10 +1559,21 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
|
|||
}
|
||||
static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL ECX, seg->base*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)&seg->base);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, &seg->base*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)&seg->base);
|
||||
addbyte(0x8b); /*MOV ECX, [RSI]*/
|
||||
addbyte(0x0e);
|
||||
}
|
||||
addbyte(0x67); /*LEA ESI, (EAX,ECX)*/
|
||||
addbyte(0x8d);
|
||||
addbyte(0x34);
|
||||
|
|
@ -1560,10 +1687,27 @@ static void STORE_HOST_REG_ADDR_BL(uintptr_t addr, int host_reg)
|
|||
addbyte(0xb6);
|
||||
addbyte(0xc0 | (REG_ECX << 3) | (host_reg & 7));
|
||||
}
|
||||
addbyte(0x89); /*MOV addr, EBX*/
|
||||
addbyte(0x04 | (REG_ECX << 3));
|
||||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100)
|
||||
{
|
||||
addbyte(0x89); /*MOV addr, ECX*/
|
||||
addbyte(0x45 | (REG_ECX << 3));
|
||||
addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128);
|
||||
}
|
||||
else if (IS_32_ADDR(addr))
|
||||
{
|
||||
addbyte(0x89); /*MOV addr, ECX*/
|
||||
addbyte(0x04 | (REG_ECX << 3));
|
||||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, addr*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)addr);
|
||||
addbyte(0x89); /*MOV [RSI], ECX*/
|
||||
addbyte(0x0e);
|
||||
}
|
||||
}
|
||||
static void STORE_HOST_REG_ADDR_WL(uintptr_t addr, int host_reg)
|
||||
{
|
||||
|
|
@ -1578,13 +1722,21 @@ static void STORE_HOST_REG_ADDR_WL(uintptr_t addr, int host_reg)
|
|||
addbyte(0x45 | (REG_ECX << 3));
|
||||
addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128);
|
||||
}
|
||||
else
|
||||
else if (IS_32_ADDR(addr))
|
||||
{
|
||||
addbyte(0x89); /*MOV addr, ECX*/
|
||||
addbyte(0x04 | (REG_ECX << 3));
|
||||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, addr*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)addr);
|
||||
addbyte(0x89); /*MOV [RSI], ECX*/
|
||||
addbyte(0x0e);
|
||||
}
|
||||
}
|
||||
static void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg)
|
||||
{
|
||||
|
|
@ -1597,16 +1749,28 @@ static void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg)
|
|||
addbyte(0x45 | ((host_reg & 7) << 3));
|
||||
addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128);
|
||||
}
|
||||
else
|
||||
else if (IS_32_ADDR(addr))
|
||||
{
|
||||
addbyte(0x66);
|
||||
if (host_reg & 8)
|
||||
addbyte(0x44);
|
||||
addbyte(0x89); /*MOVL addr,host_reg*/
|
||||
addbyte(0x89); /*MOVW addr,host_reg*/
|
||||
addbyte(0x04 | ((host_reg & 7) << 3));
|
||||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, addr*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)addr);
|
||||
|
||||
addbyte(0x66);
|
||||
if (host_reg & 8)
|
||||
addbyte(0x44);
|
||||
addbyte(0x89); /*MOVW [RSI],host_reg*/
|
||||
addbyte(0x06 | ((host_reg & 7) << 3));
|
||||
}
|
||||
}
|
||||
static void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg)
|
||||
{
|
||||
|
|
@ -1618,7 +1782,7 @@ static void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg)
|
|||
addbyte(0x45 | ((host_reg & 7) << 3));
|
||||
addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128);
|
||||
}
|
||||
else
|
||||
else if (IS_32_ADDR(addr))
|
||||
{
|
||||
if (host_reg & 8)
|
||||
addbyte(0x44);
|
||||
|
|
@ -1627,6 +1791,17 @@ static void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg)
|
|||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RSI, addr*/
|
||||
addbyte(0xb8 | REG_ESI);
|
||||
addquad((uint64_t)addr);
|
||||
|
||||
if (host_reg & 8)
|
||||
addbyte(0x44);
|
||||
addbyte(0x89); /*MOVL [RSI],host_reg*/
|
||||
addbyte(0x06 | ((host_reg & 7) << 3));
|
||||
}
|
||||
}
|
||||
|
||||
static void AND_HOST_REG_B(int dst_reg, int src_reg)
|
||||
|
|
@ -3008,11 +3183,30 @@ static int LOAD_VAR_W(uintptr_t addr)
|
|||
{
|
||||
int host_reg = REG_EBX;
|
||||
|
||||
addbyte(0x0f); /*MOVZX host_reg,[reg]*/
|
||||
addbyte(0xb7);
|
||||
addbyte(0x04 | (host_reg << 3));
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)addr);
|
||||
if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100)
|
||||
{
|
||||
addbyte(0x0f); /*MOVZX host_reg, offset[cpu_state]*/
|
||||
addbyte(0xb7);
|
||||
addbyte(0x45 | (host_reg << 3));
|
||||
addbyte(addr - (uintptr_t)&cpu_state - 128);
|
||||
}
|
||||
else if (IS_32_ADDR(addr))
|
||||
{
|
||||
addbyte(0x0f); /*MOVZX host_reg,[reg]*/
|
||||
addbyte(0xb7);
|
||||
addbyte(0x04 | (host_reg << 3));
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV host_reg, &addr*/
|
||||
addbyte(0xb8 | host_reg);
|
||||
addquad(addr);
|
||||
addbyte(0x0f); /*MOVZX host_reg, [host_reg]*/
|
||||
addbyte(0xb7);
|
||||
addbyte(host_reg | (host_reg << 3));
|
||||
}
|
||||
|
||||
return host_reg;
|
||||
}
|
||||
|
|
@ -3020,10 +3214,27 @@ static int LOAD_VAR_L(uintptr_t addr)
|
|||
{
|
||||
int host_reg = REG_EBX;
|
||||
|
||||
addbyte(0x8b); /*MOVL host_reg,[reg]*/
|
||||
addbyte(0x04 | (host_reg << 3));
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)addr);
|
||||
if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL host_reg, offset[cpu_state]*/
|
||||
addbyte(0x45 | (host_reg << 3));
|
||||
addbyte(addr - (uintptr_t)&cpu_state - 128);
|
||||
}
|
||||
else if (IS_32_ADDR(addr))
|
||||
{
|
||||
addbyte(0x8b); /*MOVL host_reg,[reg]*/
|
||||
addbyte(0x04 | (host_reg << 3));
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t)addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV host_reg, &addr*/
|
||||
addbyte(0xb8 | host_reg);
|
||||
addquad(addr);
|
||||
addbyte(0x8b); /*MOVL host_reg, [host_reg]*/
|
||||
addbyte(host_reg | (host_reg << 3));
|
||||
}
|
||||
|
||||
return host_reg;
|
||||
}
|
||||
|
|
@ -3323,12 +3534,23 @@ static void FP_ENTER()
|
|||
{
|
||||
if (codegen_fpu_entered)
|
||||
return;
|
||||
|
||||
addbyte(0xf6); /*TEST cr0, 0xc*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uintptr_t)&cr0);
|
||||
addbyte(0xc);
|
||||
if (IS_32_ADDR(&cr0))
|
||||
{
|
||||
addbyte(0xf6); /*TEST cr0, 0xc*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uintptr_t)&cr0);
|
||||
addbyte(0x0c);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RAX, &cr0*/
|
||||
addbyte(0xb8 | REG_EAX);
|
||||
addquad(&cr0);
|
||||
addbyte(0xf6); /*TEST [RAX], 0xc*/
|
||||
addbyte(0 | (REG_EAX << 3));
|
||||
addbyte(0x0c);
|
||||
}
|
||||
addbyte(0x74); /*JZ +*/
|
||||
addbyte(7+5+12+5);
|
||||
addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/
|
||||
|
|
@ -3773,7 +3995,7 @@ static int64_t x87_fround(double b)
|
|||
{
|
||||
int64_t a, c;
|
||||
|
||||
switch ((npxc>>10)&3)
|
||||
switch ((cpu_state.npxc >> 10) & 3)
|
||||
{
|
||||
case 0: /*Nearest*/
|
||||
a = (int64_t)floor(b);
|
||||
|
|
@ -4131,7 +4353,7 @@ static void FP_OP_D(int op)
|
|||
addbyte(0x0f);
|
||||
addbyte(0x6e);
|
||||
addbyte(0xc8);
|
||||
if (((npxc >> 10) & 3) && op == FPU_ADD)
|
||||
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
||||
{
|
||||
addbyte(0x0f); /*STMXCSR [ESP+8]*/
|
||||
addbyte(0xae);
|
||||
|
|
@ -4145,7 +4367,7 @@ static void FP_OP_D(int op)
|
|||
addbyte(0x25); /*AND EAX, ~(3 << 13)*/
|
||||
addlong(~(3 << 10));
|
||||
addbyte(0x0d); /*OR EAX, (npxc & (3 << 10)) << 3*/
|
||||
addlong((npxc & (3 << 10)) << 3);
|
||||
addlong((cpu_state.npxc & (3 << 10)) << 3);
|
||||
addbyte(0x89); /*MOV [RSP+12], EAX*/
|
||||
addbyte(0x44);
|
||||
addbyte(0x24);
|
||||
|
|
@ -4157,7 +4379,7 @@ static void FP_OP_D(int op)
|
|||
addbyte(0x0c);
|
||||
}
|
||||
FP_OP_MEM(op);
|
||||
if (((npxc >> 10) & 3) && op == FPU_ADD)
|
||||
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
||||
{
|
||||
addbyte(0x0f); /*LDMXCSR [RSP+8]*/
|
||||
addbyte(0xae);
|
||||
|
|
@ -4209,9 +4431,8 @@ static void FP_COMPARE_REG(int dst, int src)
|
|||
}
|
||||
|
||||
addbyte(0x8a); /*MOV CL, [npxs+1]*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x4d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
// addbyte(0xdb); /*FCLEX*/
|
||||
// addbyte(0xe2);
|
||||
addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/
|
||||
|
|
@ -4256,9 +4477,8 @@ static void FP_COMPARE_REG(int dst, int src)
|
|||
addbyte(0x08); /*OR CL, AH*/
|
||||
addbyte(0xe1);
|
||||
addbyte(0x88); /*MOV [npxs+1], CL*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x4d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
}
|
||||
|
||||
static void FP_COMPARE_MEM()
|
||||
|
|
@ -4268,9 +4488,8 @@ static void FP_COMPARE_MEM()
|
|||
addbyte(cpu_state_offset(TOP));
|
||||
|
||||
addbyte(0x8a); /*MOV CL, [npxs+1]*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x4d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
// addbyte(0xdb); /*FCLEX*/
|
||||
// addbyte(0xe2);
|
||||
addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/
|
||||
|
|
@ -4293,9 +4512,8 @@ static void FP_COMPARE_MEM()
|
|||
addbyte(0x08); /*OR CL, AH*/
|
||||
addbyte(0xe1);
|
||||
addbyte(0x88); /*MOV [npxs+1], CL*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x4d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
}
|
||||
static void FP_COMPARE_S()
|
||||
{
|
||||
|
|
@ -4340,40 +4558,83 @@ static void FP_COMPARE_IL()
|
|||
|
||||
static void SET_BITS(uintptr_t addr, uint32_t val)
|
||||
{
|
||||
if (val & ~0xff)
|
||||
if (IS_32_ADDR(addr))
|
||||
{
|
||||
addbyte(0x81);
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
addlong(val);
|
||||
if (val & ~0xff)
|
||||
{
|
||||
addbyte(0x81); /*OR [addr], val*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
addlong(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x80); /*OR [addr], val*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
addbyte(val);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x80);
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
addbyte(val);
|
||||
{
|
||||
addbyte(0x48); /*MOV RAX, &addr*/
|
||||
addbyte(0xb8 | REG_EAX);
|
||||
addquad(addr);
|
||||
if (val & ~0xff)
|
||||
{
|
||||
addbyte(0x81); /*OR [RAX], val*/
|
||||
addbyte(0x08);
|
||||
addlong(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x80); /*OR [RAX], val*/
|
||||
addbyte(0x08);
|
||||
addbyte(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CLEAR_BITS(uintptr_t addr, uint32_t val)
|
||||
{
|
||||
if (val & ~0xff)
|
||||
if (IS_32_ADDR(addr))
|
||||
{
|
||||
addbyte(0x81);
|
||||
addbyte(0x24);
|
||||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
addlong(~val);
|
||||
if (val & ~0xff)
|
||||
{
|
||||
addbyte(0x81); /*AND [addr], val*/
|
||||
addbyte(0x24);
|
||||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
addlong(~val);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x80); /*AND [addr], val*/
|
||||
addbyte(0x24);
|
||||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
addbyte(~val);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x80);
|
||||
addbyte(0x24);
|
||||
addbyte(0x25);
|
||||
addlong(addr);
|
||||
addbyte(~val);
|
||||
{
|
||||
addbyte(0x48); /*MOV RAX, &addr*/
|
||||
addbyte(0xb8 | REG_EAX);
|
||||
addquad(addr);
|
||||
if (val & ~0xff)
|
||||
{
|
||||
addbyte(0x81); /*AND [RAX], val*/
|
||||
addbyte(0x20);
|
||||
addlong(~val);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x80); /*AND [RAX], val*/
|
||||
addbyte(0x20);
|
||||
addbyte(~val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4385,11 +4646,23 @@ static void MMX_ENTER()
|
|||
if (codegen_mmx_entered)
|
||||
return;
|
||||
|
||||
addbyte(0xf6); /*TEST cr0, 0xc*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uintptr_t)&cr0);
|
||||
addbyte(0xc);
|
||||
if (IS_32_ADDR(&cr0))
|
||||
{
|
||||
addbyte(0xf6); /*TEST cr0, 0xc*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uintptr_t)&cr0);
|
||||
addbyte(0x0c);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RAX, &cr0*/
|
||||
addbyte(0xb8 | REG_EAX);
|
||||
addquad(&cr0);
|
||||
addbyte(0xf6); /*TEST [RAX], 0xc*/
|
||||
addbyte(0 | (REG_EAX << 3));
|
||||
addbyte(0x0c);
|
||||
}
|
||||
addbyte(0x74); /*JZ +*/
|
||||
addbyte(7+5+12+5);
|
||||
addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/
|
||||
|
|
|
|||
|
|
@ -2307,10 +2307,10 @@ static double _fp_half = 0.5;
|
|||
|
||||
static void FP_LOAD_ROUNDING()
|
||||
{
|
||||
pclog("npxc %04x\n", npxc);
|
||||
pclog("cpu_state.npxc %04x\n", cpu_state.npxc);
|
||||
addbyte(0x8b); /*MOV EDX, npxc*/
|
||||
addbyte(0x15);
|
||||
addlong((uintptr_t)&npxc);
|
||||
addlong((uintptr_t)&cpu_state.npxc);
|
||||
addbyte(0xd9); /*FSTCW [ESP+8]*/
|
||||
addbyte(0x7c);
|
||||
addbyte(0x24);
|
||||
|
|
@ -2336,7 +2336,7 @@ static int32_t x87_fround32(double b)
|
|||
{
|
||||
int64_t a, c;
|
||||
|
||||
switch ((npxc>>10)&3)
|
||||
switch ((cpu_state.npxc >> 10) & 3)
|
||||
{
|
||||
case 0: /*Nearest*/
|
||||
a = (int64_t)floor(b);
|
||||
|
|
@ -2359,7 +2359,7 @@ static int64_t x87_fround64(double b)
|
|||
{
|
||||
int64_t a, c;
|
||||
|
||||
switch ((npxc>>10)&3)
|
||||
switch ((cpu_state.npxc >> 10) & 3)
|
||||
{
|
||||
case 0: /*Nearest*/
|
||||
a = (int64_t)floor(b);
|
||||
|
|
@ -2599,7 +2599,7 @@ static void FP_OP_D(int op)
|
|||
addbyte(0x89); /*MOV [ESP], EAX*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x24);
|
||||
if (((npxc >> 10) & 3) && op == FPU_ADD)
|
||||
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
||||
{
|
||||
addbyte(0x9b); /*FSTCW [ESP+8]*/
|
||||
addbyte(0xd9);
|
||||
|
|
@ -2616,7 +2616,7 @@ static void FP_OP_D(int op)
|
|||
addword(~(3 << 10));
|
||||
addbyte(0x66); /*OR AX, npxc & (3 << 10)*/
|
||||
addbyte(0x0d);
|
||||
addword(npxc & (3 << 10));
|
||||
addword(cpu_state.npxc & (3 << 10));
|
||||
addbyte(0x66); /*MOV [ESP+12], AX*/
|
||||
addbyte(0x89);
|
||||
addbyte(0x44);
|
||||
|
|
@ -2647,7 +2647,7 @@ static void FP_OP_D(int op)
|
|||
addbyte(0x5c);
|
||||
addbyte(0xdd);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
if (((npxc >> 10) & 3) && op == FPU_ADD)
|
||||
if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD)
|
||||
{
|
||||
addbyte(0xd9); /*FLDCW [ESP+8]*/
|
||||
addbyte(0x6c);
|
||||
|
|
@ -2753,8 +2753,8 @@ static void FP_COMPARE_S()
|
|||
addbyte(0xdd);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
addbyte(0x8a); /*MOV BL, [npxs+1]*/
|
||||
addbyte(0x1d);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
addbyte(0xdb); /*FCLEX*/
|
||||
addbyte(0xe2);
|
||||
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
|
||||
|
|
@ -2771,8 +2771,8 @@ static void FP_COMPARE_S()
|
|||
addbyte(0x08); /*OR BL, AH*/
|
||||
addbyte(0xe3);
|
||||
addbyte(0x88); /*MOV [npxs+1], BL*/
|
||||
addbyte(0x1d);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
}
|
||||
static void FP_COMPARE_D()
|
||||
{
|
||||
|
|
@ -2791,8 +2791,8 @@ static void FP_COMPARE_D()
|
|||
addbyte(0xdd);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
addbyte(0x8a); /*MOV BL, [npxs+1]*/
|
||||
addbyte(0x1d);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
addbyte(0xdb); /*FCLEX*/
|
||||
addbyte(0xe2);
|
||||
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
|
||||
|
|
@ -2809,8 +2809,8 @@ static void FP_COMPARE_D()
|
|||
addbyte(0x08); /*OR BL, AH*/
|
||||
addbyte(0xe3);
|
||||
addbyte(0x88); /*MOV [npxs+1], BL*/
|
||||
addbyte(0x1d);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
}
|
||||
static void FP_COMPARE_IW()
|
||||
{
|
||||
|
|
@ -2825,8 +2825,8 @@ static void FP_COMPARE_IW()
|
|||
addbyte(0xdd);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
addbyte(0x8a); /*MOV BL, [npxs+1]*/
|
||||
addbyte(0x1d);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
addbyte(0xdb); /*FCLEX*/
|
||||
addbyte(0xe2);
|
||||
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
|
||||
|
|
@ -2843,8 +2843,8 @@ static void FP_COMPARE_IW()
|
|||
addbyte(0x08); /*OR BL, AH*/
|
||||
addbyte(0xe3);
|
||||
addbyte(0x88); /*MOV [npxs+1], BL*/
|
||||
addbyte(0x1d);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
}
|
||||
static void FP_COMPARE_IL()
|
||||
{
|
||||
|
|
@ -2859,8 +2859,8 @@ static void FP_COMPARE_IL()
|
|||
addbyte(0xdd);
|
||||
addbyte(cpu_state_offset(ST));
|
||||
addbyte(0x8a); /*MOV BL, [npxs+1]*/
|
||||
addbyte(0x1d);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
addbyte(0xdb); /*FCLEX*/
|
||||
addbyte(0xe2);
|
||||
addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/
|
||||
|
|
@ -2877,8 +2877,8 @@ static void FP_COMPARE_IL()
|
|||
addbyte(0x08); /*OR BL, AH*/
|
||||
addbyte(0xe3);
|
||||
addbyte(0x88); /*MOV [npxs+1], BL*/
|
||||
addbyte(0x1d);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x5d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
}
|
||||
|
||||
static void FP_OP_REG(int op, int dst, int src)
|
||||
|
|
@ -2962,8 +2962,8 @@ static void FP_COMPARE_REG(int dst, int src)
|
|||
}
|
||||
|
||||
addbyte(0x8a); /*MOV CL, [npxs+1]*/
|
||||
addbyte(0x0d);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x4d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
addbyte(0xdb); /*FCLEX*/
|
||||
addbyte(0xe2);
|
||||
addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/
|
||||
|
|
@ -3001,8 +3001,8 @@ static void FP_COMPARE_REG(int dst, int src)
|
|||
addbyte(0x08); /*OR CL, AH*/
|
||||
addbyte(0xe1);
|
||||
addbyte(0x88); /*MOV [npxs+1], CL*/
|
||||
addbyte(0x0d);
|
||||
addlong(((uintptr_t)&npxs) + 1);
|
||||
addbyte(0x4d);
|
||||
addbyte(cpu_state_offset(npxs) + 1);
|
||||
}
|
||||
|
||||
static int ZERO_EXTEND_W_B(int reg)
|
||||
|
|
|
|||
|
|
@ -155,6 +155,8 @@ struct
|
|||
|
||||
int _cycles;
|
||||
int cpu_recomp_ins;
|
||||
|
||||
uint16_t npxs, npxc;
|
||||
|
||||
double ST[8];
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@
|
|||
#include "x87.h"
|
||||
#include "386_common.h"
|
||||
|
||||
uint16_t npxs,npxc;
|
||||
|
||||
uint16_t x87_gettag()
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
|
|
@ -61,7 +59,7 @@ void x87_dumpregs()
|
|||
pclog("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n",cpu_state.ST[cpu_state.TOP],cpu_state.ST[(cpu_state.TOP+1)&7],cpu_state.ST[(cpu_state.TOP+2)&7],cpu_state.ST[(cpu_state.TOP+3)&7]);
|
||||
pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n",cpu_state.ST[(cpu_state.TOP+4)&7],cpu_state.ST[(cpu_state.TOP+5)&7],cpu_state.ST[(cpu_state.TOP+6)&7],cpu_state.ST[(cpu_state.TOP+7)&7]);
|
||||
}
|
||||
pclog("Status = %04X Control = %04X Tag = %04X\n",npxs,npxc,x87_gettag());
|
||||
pclog("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag());
|
||||
}
|
||||
|
||||
void x87_print()
|
||||
|
|
@ -74,7 +72,7 @@ void x87_print()
|
|||
else
|
||||
{
|
||||
pclog("\tST(0)=%.20f\tST(1)=%.20f\tST(2)=%f\tST(3)=%f\t",cpu_state.ST[cpu_state.TOP&7],cpu_state.ST[(cpu_state.TOP+1)&7],cpu_state.ST[(cpu_state.TOP+2)&7],cpu_state.ST[(cpu_state.TOP+3)&7]);
|
||||
pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\tTOP=%i CR=%04X SR=%04X TAG=%04X\n",cpu_state.ST[(cpu_state.TOP+4)&7],cpu_state.ST[(cpu_state.TOP+5)&7],cpu_state.ST[(cpu_state.TOP+6)&7],cpu_state.ST[(cpu_state.TOP+7)&7], cpu_state.TOP, npxc, npxs, x87_gettag());
|
||||
pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\tTOP=%i CR=%04X SR=%04X TAG=%04X\n",cpu_state.ST[(cpu_state.TOP+4)&7],cpu_state.ST[(cpu_state.TOP+5)&7],cpu_state.ST[(cpu_state.TOP+6)&7],cpu_state.ST[(cpu_state.TOP+7)&7], cpu_state.TOP, cpu_state.npxc, cpu_state.npxs, x87_gettag());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
uint32_t x87_pc_off,x87_op_off;
|
||||
uint16_t x87_pc_seg,x87_op_seg;
|
||||
extern uint16_t npxs, npxc;
|
||||
|
||||
static inline void x87_set_mmx();
|
||||
static inline void x87_emms();
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZ
|
|||
{ \
|
||||
if (((double)src2) == 0.0) \
|
||||
{ \
|
||||
npxs |= STATUS_ZERODIVIDE; \
|
||||
if (npxc & STATUS_ZERODIVIDE) \
|
||||
cpu_state.npxs |= STATUS_ZERODIVIDE; \
|
||||
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
|
||||
dst = src1 / (double)src2; \
|
||||
else \
|
||||
{ \
|
||||
|
|
@ -68,7 +68,7 @@ static inline int64_t x87_fround(double b)
|
|||
{
|
||||
int64_t a, c;
|
||||
|
||||
switch ((npxc>>10)&3)
|
||||
switch ((cpu_state.npxc >> 10) & 3)
|
||||
{
|
||||
case 0: /*Nearest*/
|
||||
a = (int64_t)floor(b);
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
if ((npxc >> 10) & 3) \
|
||||
fesetround(rounding_modes[(npxc >> 10) & 3]); \
|
||||
if ((cpu_state.npxc >> 10) & 3) \
|
||||
fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \
|
||||
ST(0) += use_var; \
|
||||
if ((npxc >> 10) & 3) \
|
||||
if ((cpu_state.npxc >> 10) & 3) \
|
||||
fesetround(FE_TONEAREST); \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(8); \
|
||||
|
|
@ -20,8 +20,8 @@ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
npxs &= ~(C0|C2|C3); \
|
||||
npxs |= x87_compare(ST(0), (double)use_var); \
|
||||
cpu_state.npxs &= ~(C0|C2|C3); \
|
||||
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
|
||||
CLOCK_CYCLES(4); \
|
||||
return 0; \
|
||||
} \
|
||||
|
|
@ -31,8 +31,8 @@ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
npxs &= ~(C0|C2|C3); \
|
||||
npxs |= x87_compare(ST(0), (double)use_var); \
|
||||
cpu_state.npxs &= ~(C0|C2|C3); \
|
||||
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
|
||||
x87_pop(); \
|
||||
CLOCK_CYCLES(4); \
|
||||
return 0; \
|
||||
|
|
@ -144,9 +144,9 @@ static int opFCOM(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
if (fplog) pclog("FCOM\n");
|
||||
npxs &= ~(C0|C2|C3);
|
||||
if (ST(0) == ST(fetchdat & 7)) npxs |= C3;
|
||||
else if (ST(0) < ST(fetchdat & 7)) npxs |= C0;
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0;
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -156,8 +156,8 @@ static int opFCOMP(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
if (fplog) pclog("FCOMP\n");
|
||||
npxs &= ~(C0|C2|C3);
|
||||
npxs |= x87_compare(ST(0), ST(fetchdat & 7));
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7));
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
|
|
@ -168,11 +168,11 @@ static int opFCOMPP(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
if (fplog) pclog("FCOMPP\n");
|
||||
npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
if (*(uint64_t *)&ST(0) == ((uint64_t)1 << 63) && *(uint64_t *)&ST(1) == 0)
|
||||
npxs |= C0; /*Nasty hack to fix 80387 detection*/
|
||||
cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/
|
||||
else
|
||||
npxs |= x87_compare(ST(0), ST(1));
|
||||
cpu_state.npxs |= x87_compare(ST(0), ST(1));
|
||||
|
||||
x87_pop();
|
||||
x87_pop();
|
||||
|
|
@ -184,8 +184,8 @@ static int opFUCOMPP(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
if (fplog) pclog("FUCOMPP\n", easeg, cpu_state.eaaddr);
|
||||
npxs &= ~(C0|C2|C3);
|
||||
npxs |= x87_ucompare(ST(0), ST(1));
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(1));
|
||||
x87_pop();
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(5);
|
||||
|
|
@ -383,8 +383,8 @@ static int opFUCOM(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
if (fplog) pclog("FUCOM\n");
|
||||
npxs &= ~(C0|C2|C3);
|
||||
npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -394,8 +394,8 @@ static int opFUCOMP(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
if (fplog) pclog("FUCOMP\n");
|
||||
npxs &= ~(C0|C2|C3);
|
||||
npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ static int opFSTSW_AX(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
if (fplog) pclog("FSTSW\n");
|
||||
AX = npxs;
|
||||
AX = cpu_state.npxs;
|
||||
CLOCK_CYCLES(3);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ static int opFCLEX(uint32_t fetchdat)
|
|||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
npxs &= 0xff00;
|
||||
cpu_state.npxs &= 0xff00;
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -31,8 +31,8 @@ static int opFINIT(uint32_t fetchdat)
|
|||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
npxc = 0x37F;
|
||||
npxs = 0;
|
||||
cpu_state.npxc = 0x37F;
|
||||
cpu_state.npxs = 0;
|
||||
*(uint64_t *)cpu_state.tag = 0x0303030303030303ll;
|
||||
cpu_state.TOP = 0;
|
||||
CLOCK_CYCLES(17);
|
||||
|
|
@ -84,18 +84,18 @@ static int FSTOR()
|
|||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
case 0x001: /*16-bit protected mode*/
|
||||
npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
npxs = readmemw(easeg, cpu_state.eaaddr+2);
|
||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2);
|
||||
x87_settag(readmemw(easeg, cpu_state.eaaddr+4));
|
||||
cpu_state.TOP = (npxs >> 11) & 7;
|
||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||
cpu_state.eaaddr += 14;
|
||||
break;
|
||||
case 0x100: /*32-bit real mode*/
|
||||
case 0x101: /*32-bit protected mode*/
|
||||
npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
npxs = readmemw(easeg, cpu_state.eaaddr+4);
|
||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4);
|
||||
x87_settag(readmemw(easeg, cpu_state.eaaddr+8));
|
||||
cpu_state.TOP = (npxs >> 11) & 7;
|
||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||
cpu_state.eaaddr += 28;
|
||||
break;
|
||||
}
|
||||
|
|
@ -139,13 +139,13 @@ static int FSAVE()
|
|||
{
|
||||
FP_ENTER();
|
||||
if (fplog) pclog("FSAVE %08X:%08X %i\n", easeg, cpu_state.eaaddr, cpu_state.ismmx);
|
||||
npxs = (npxs & ~(7 << 11)) | (cpu_state.TOP << 11);
|
||||
cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (cpu_state.TOP << 11);
|
||||
|
||||
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
|
||||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
writememw(easeg,cpu_state.eaaddr,npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+2,npxs);
|
||||
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs);
|
||||
writememw(easeg,cpu_state.eaaddr+4,x87_gettag());
|
||||
writememw(easeg,cpu_state.eaaddr+6,x87_pc_off);
|
||||
writememw(easeg,cpu_state.eaaddr+10,x87_op_off);
|
||||
|
|
@ -174,8 +174,8 @@ static int FSAVE()
|
|||
}
|
||||
break;
|
||||
case 0x001: /*16-bit protected mode*/
|
||||
writememw(easeg,cpu_state.eaaddr,npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+2,npxs);
|
||||
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs);
|
||||
writememw(easeg,cpu_state.eaaddr+4,x87_gettag());
|
||||
writememw(easeg,cpu_state.eaaddr+6,x87_pc_off);
|
||||
writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg);
|
||||
|
|
@ -206,8 +206,8 @@ static int FSAVE()
|
|||
}
|
||||
break;
|
||||
case 0x100: /*32-bit real mode*/
|
||||
writememw(easeg,cpu_state.eaaddr,npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+4,npxs);
|
||||
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs);
|
||||
writememw(easeg,cpu_state.eaaddr+8,x87_gettag());
|
||||
writememw(easeg,cpu_state.eaaddr+12,x87_pc_off);
|
||||
writememw(easeg,cpu_state.eaaddr+20,x87_op_off);
|
||||
|
|
@ -237,8 +237,8 @@ static int FSAVE()
|
|||
}
|
||||
break;
|
||||
case 0x101: /*32-bit protected mode*/
|
||||
writememw(easeg,cpu_state.eaaddr,npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+4,npxs);
|
||||
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs);
|
||||
writememw(easeg,cpu_state.eaaddr+8,x87_gettag());
|
||||
writememl(easeg,cpu_state.eaaddr+12,x87_pc_off);
|
||||
writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg);
|
||||
|
|
@ -292,7 +292,7 @@ static int opFSTSW_a16(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
if (fplog) pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
seteaw((npxs & 0xC7FF) | (cpu_state.TOP << 11));
|
||||
seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11));
|
||||
CLOCK_CYCLES(3);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
|
@ -301,7 +301,7 @@ static int opFSTSW_a32(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
if (fplog) pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
seteaw((npxs & 0xC7FF) | (cpu_state.TOP << 11));
|
||||
seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11));
|
||||
CLOCK_CYCLES(3);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
|
@ -373,9 +373,9 @@ static int opFTST(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
if (fplog) pclog("FTST\n");
|
||||
npxs &= ~(C0|C2|C3);
|
||||
if (ST(0) == 0.0) npxs |= C3;
|
||||
else if (ST(0) < 0.0) npxs |= C0;
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
if (ST(0) == 0.0) cpu_state.npxs |= C3;
|
||||
else if (ST(0) < 0.0) cpu_state.npxs |= C0;
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -385,11 +385,11 @@ static int opFXAM(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
if (fplog) pclog("FXAM %i %f\n", cpu_state.tag[cpu_state.TOP&7], ST(0));
|
||||
npxs &= ~(C0|C1|C2|C3);
|
||||
if (cpu_state.tag[cpu_state.TOP&7] == 3) npxs |= (C0|C3);
|
||||
else if (ST(0) == 0.0) npxs |= C3;
|
||||
else npxs |= C2;
|
||||
if (ST(0) < 0.0) npxs |= C1;
|
||||
cpu_state.npxs &= ~(C0|C1|C2|C3);
|
||||
if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3);
|
||||
else if (ST(0) == 0.0) cpu_state.npxs |= C3;
|
||||
else cpu_state.npxs |= C2;
|
||||
if (ST(0) < 0.0) cpu_state.npxs |= C1;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -508,7 +508,7 @@ static int opFPTAN(uint32_t fetchdat)
|
|||
ST(0) = tan(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
x87_push(1.0);
|
||||
npxs &= ~C2;
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(235);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -555,10 +555,10 @@ static int opFPREM(uint32_t fetchdat)
|
|||
ST(0) = ST(0) - (ST(1) * (double)temp64);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
if (fplog) pclog("%f\n", ST(0));
|
||||
npxs &= ~(C0|C1|C2|C3);
|
||||
if (temp64 & 4) npxs|=C0;
|
||||
if (temp64 & 2) npxs|=C3;
|
||||
if (temp64 & 1) npxs|=C1;
|
||||
cpu_state.npxs &= ~(C0|C1|C2|C3);
|
||||
if (temp64 & 4) cpu_state.npxs|=C0;
|
||||
if (temp64 & 2) cpu_state.npxs|=C3;
|
||||
if (temp64 & 1) cpu_state.npxs|=C1;
|
||||
CLOCK_CYCLES(100);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -572,10 +572,10 @@ static int opFPREM1(uint32_t fetchdat)
|
|||
ST(0) = ST(0) - (ST(1) * (double)temp64);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
if (fplog) pclog("%f\n", ST(0));
|
||||
npxs &= ~(C0|C1|C2|C3);
|
||||
if (temp64 & 4) npxs|=C0;
|
||||
if (temp64 & 2) npxs|=C3;
|
||||
if (temp64 & 1) npxs|=C1;
|
||||
cpu_state.npxs &= ~(C0|C1|C2|C3);
|
||||
if (temp64 & 4) cpu_state.npxs|=C0;
|
||||
if (temp64 & 2) cpu_state.npxs|=C3;
|
||||
if (temp64 & 1) cpu_state.npxs|=C1;
|
||||
CLOCK_CYCLES(100);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -601,7 +601,7 @@ static int opFSINCOS(uint32_t fetchdat)
|
|||
ST(0) = sin(td);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
x87_push(cos(td));
|
||||
npxs &= ~C2;
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(330);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -638,7 +638,7 @@ static int opFSIN(uint32_t fetchdat)
|
|||
if (fplog) pclog("FSIN\n");
|
||||
ST(0) = sin(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
npxs &= ~C2;
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(300);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -650,7 +650,7 @@ static int opFCOS(uint32_t fetchdat)
|
|||
if (fplog) pclog("FCOS\n");
|
||||
ST(0) = cos(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
npxs &= ~C2;
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(300);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -664,17 +664,17 @@ static int FLDENV()
|
|||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
case 0x001: /*16-bit protected mode*/
|
||||
npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
npxs = readmemw(easeg, cpu_state.eaaddr+2);
|
||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2);
|
||||
x87_settag(readmemw(easeg, cpu_state.eaaddr+4));
|
||||
cpu_state.TOP = (npxs >> 11) & 7;
|
||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||
break;
|
||||
case 0x100: /*32-bit real mode*/
|
||||
case 0x101: /*32-bit protected mode*/
|
||||
npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
npxs = readmemw(easeg, cpu_state.eaaddr+4);
|
||||
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
|
||||
cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4);
|
||||
x87_settag(readmemw(easeg, cpu_state.eaaddr+8));
|
||||
cpu_state.TOP = (npxs >> 11) & 7;
|
||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
|
|
@ -704,7 +704,7 @@ static int opFLDCW_a16(uint32_t fetchdat)
|
|||
if (fplog) pclog("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
tempw = geteaw();
|
||||
if (cpu_state.abrt) return 1;
|
||||
npxc = tempw;
|
||||
cpu_state.npxc = tempw;
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -716,7 +716,7 @@ static int opFLDCW_a32(uint32_t fetchdat)
|
|||
if (fplog) pclog("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
tempw = geteaw();
|
||||
if (cpu_state.abrt) return 1;
|
||||
npxc = tempw;
|
||||
cpu_state.npxc = tempw;
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -728,15 +728,15 @@ static int FSTENV()
|
|||
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
|
||||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
writememw(easeg,cpu_state.eaaddr,npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+2,npxs);
|
||||
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs);
|
||||
writememw(easeg,cpu_state.eaaddr+4,x87_gettag());
|
||||
writememw(easeg,cpu_state.eaaddr+6,x87_pc_off);
|
||||
writememw(easeg,cpu_state.eaaddr+10,x87_op_off);
|
||||
break;
|
||||
case 0x001: /*16-bit protected mode*/
|
||||
writememw(easeg,cpu_state.eaaddr,npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+2,npxs);
|
||||
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs);
|
||||
writememw(easeg,cpu_state.eaaddr+4,x87_gettag());
|
||||
writememw(easeg,cpu_state.eaaddr+6,x87_pc_off);
|
||||
writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg);
|
||||
|
|
@ -744,16 +744,16 @@ static int FSTENV()
|
|||
writememw(easeg,cpu_state.eaaddr+12,x87_op_seg);
|
||||
break;
|
||||
case 0x100: /*32-bit real mode*/
|
||||
writememw(easeg,cpu_state.eaaddr,npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+4,npxs);
|
||||
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs);
|
||||
writememw(easeg,cpu_state.eaaddr+8,x87_gettag());
|
||||
writememw(easeg,cpu_state.eaaddr+12,x87_pc_off);
|
||||
writememw(easeg,cpu_state.eaaddr+20,x87_op_off);
|
||||
writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12);
|
||||
break;
|
||||
case 0x101: /*32-bit protected mode*/
|
||||
writememw(easeg,cpu_state.eaaddr,npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+4,npxs);
|
||||
writememw(easeg,cpu_state.eaaddr,cpu_state.npxc);
|
||||
writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs);
|
||||
writememw(easeg,cpu_state.eaaddr+8,x87_gettag());
|
||||
writememl(easeg,cpu_state.eaaddr+12,x87_pc_off);
|
||||
writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg);
|
||||
|
|
@ -785,7 +785,7 @@ static int opFSTCW_a16(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
if (fplog) pclog("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
seteaw(npxc);
|
||||
seteaw(cpu_state.npxc);
|
||||
CLOCK_CYCLES(3);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
|
@ -794,7 +794,7 @@ static int opFSTCW_a32(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
if (fplog) pclog("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
seteaw(npxc);
|
||||
seteaw(cpu_state.npxc);
|
||||
CLOCK_CYCLES(3);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue