Reorganised FPU emulation.

This commit is contained in:
TomW 2014-11-09 14:07:03 +00:00
commit 087f412d3f
12 changed files with 2670 additions and 1436 deletions

View file

@ -134,6 +134,12 @@ static inline uint32_t getlong()
return fastreadl(cs+(pc-4));
}
static inline uint64_t getquad()
{
pc+=8;
return fastreadl(cs+(pc-8)) | ((uint64_t)fastreadl(cs+(pc-4)) << 32);
}
static inline uint8_t geteab()
@ -162,6 +168,11 @@ static inline uint32_t geteal()
return readmeml(easeg,eaaddr);
}
static inline uint64_t geteaq()
{
return readmeml(easeg,eaaddr) | ((uint64_t)readmeml(easeg, eaaddr + 4) << 32);
}
static inline uint8_t geteab_mem()
{
if (eal_r) return *(uint8_t *)eal_r;
@ -178,6 +189,12 @@ static inline uint32_t geteal_mem()
return readmeml(easeg,eaaddr);
}
static inline void seteaq(uint64_t v)
{
writememll(easeg, eaaddr, v & 0xffffffff); if (abrt) return;
writememll(easeg, eaaddr + 4, v >> 32);
}
#define seteab(v) if (mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,eaaddr,v); } else if (rm&4) regs[rm&3].b.h=v; else regs[rm].b.l=v
#define seteaw(v) if (mod!=3) { if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,eaaddr,v); } else regs[rm].w=v
#define seteal(v) if (mod!=3) { if (eal_w) *eal_w=v; else writememll(easeg,eaaddr,v); } else regs[rm].l=v

View file

@ -1,11 +1,5 @@
#include "x86_ops.h"
OpFn *x86_opcodes;
OpFn *x86_opcodes_0f;
#ifdef DYNAREC
OpFn *x86_dynarec_opcodes;
OpFn *x86_dynarec_opcodes_0f;
#endif
#define ILLEGAL_ON(cond) \
do \
@ -638,3 +632,5 @@ OpFn OP_TABLE(386)[1024] =
/*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX,
/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32,
};
#include "x87_ops.h"

View file

@ -448,14 +448,19 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
OpFn *op_table = x86_dynarec_opcodes;
x86seg *op_ea_seg = &_ds;
int op_ssegs = 0;
int opcode_shift = 0;
int opcode_mask = 0x3ff;
int over = 0;
int pc_off = 0;
while (1)
while (!over)
{
switch (opcode)
{
case 0x0f:
op_table = x86_dynarec_opcodes_0f;
over = 1;
break;
case 0x26: /*ES:*/
@ -498,6 +503,57 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
addbyte(0x83); addbyte(0x2D); addlong((uint32_t)&cycles); addbyte(2);
break;
case 0xd8:
op_table = (op_32 & 0x200) ? x86_opcodes_d8_a32 : x86_opcodes_d8_a16;
opcode_shift = 3;
opcode_mask = 0x1f;
over = 1;
pc_off = -1;
break;
case 0xd9:
op_table = (op_32 & 0x200) ? x86_opcodes_d9_a32 : x86_opcodes_d9_a16;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
break;
case 0xda:
op_table = (op_32 & 0x200) ? x86_opcodes_da_a32 : x86_opcodes_da_a16;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
break;
case 0xdb:
op_table = (op_32 & 0x200) ? x86_opcodes_db_a32 : x86_opcodes_db_a16;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
break;
case 0xdc:
op_table = (op_32 & 0x200) ? x86_opcodes_dc_a32 : x86_opcodes_dc_a16;
opcode_shift = 3;
opcode_mask = 0x1f;
over = 1;
pc_off = -1;
break;
case 0xdd:
op_table = (op_32 & 0x200) ? x86_opcodes_dd_a32 : x86_opcodes_dd_a16;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
break;
case 0xde:
op_table = (op_32 & 0x200) ? x86_opcodes_de_a32 : x86_opcodes_de_a16;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
break;
case 0xdf:
op_table = (op_32 & 0x200) ? x86_opcodes_df_a32 : x86_opcodes_df_a16;
opcode_mask = 0xff;
over = 1;
pc_off = -1;
break;
case 0xf0: /*LOCK*/
addbyte(0x83); addbyte(0x2D); addlong((uint32_t)&cycles); addbyte(2);
break;
@ -510,13 +566,14 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
if (abrt)
return;
opcode = fetchdat & 0xff;
fetchdat >>= 8;
if (!pc_off)
fetchdat >>= 8;
op_pc++;
}
generate_call:
op = op_table[(opcode | op_32) & 0x3ff];
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
// if (output)
// pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]);
if (opcode_needs_tempc[opcode])
@ -548,7 +605,7 @@ generate_call:
addbyte(0xC7); /*MOVL $new_pc,(pc)*/
addbyte(0x05);
addlong((uint32_t)&pc);
addlong(op_pc);
addlong(op_pc + pc_off);
addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/
addbyte(0x05);
addlong((uint32_t)&oldpc);

119
src/cpu.c
View file

@ -4,6 +4,46 @@
#include "io.h"
#include "x86_ops.h"
#ifdef DYNAREC
OpFn *x86_dynarec_opcodes;
OpFn *x86_dynarec_opcodes_0f;
OpFn *x86_dynarec_opcodes_d8_a16;
OpFn *x86_dynarec_opcodes_d8_a32;
OpFn *x86_dynarec_opcodes_d9_a16;
OpFn *x86_dynarec_opcodes_d9_a32;
OpFn *x86_dynarec_opcodes_da_a16;
OpFn *x86_dynarec_opcodes_da_a32;
OpFn *x86_dynarec_opcodes_db_a16;
OpFn *x86_dynarec_opcodes_db_a32;
OpFn *x86_dynarec_opcodes_dc_a16;
OpFn *x86_dynarec_opcodes_dc_a32;
OpFn *x86_dynarec_opcodes_dd_a16;
OpFn *x86_dynarec_opcodes_dd_a32;
OpFn *x86_dynarec_opcodes_de_a16;
OpFn *x86_dynarec_opcodes_de_a32;
OpFn *x86_dynarec_opcodes_df_a16;
OpFn *x86_dynarec_opcodes_df_a32;
#endif
OpFn *x86_opcodes;
OpFn *x86_opcodes_0f;
OpFn *x86_opcodes_d8_a16;
OpFn *x86_opcodes_d8_a32;
OpFn *x86_opcodes_d9_a16;
OpFn *x86_opcodes_d9_a32;
OpFn *x86_opcodes_da_a16;
OpFn *x86_opcodes_da_a32;
OpFn *x86_opcodes_db_a16;
OpFn *x86_opcodes_db_a32;
OpFn *x86_opcodes_dc_a16;
OpFn *x86_opcodes_dc_a32;
OpFn *x86_opcodes_dd_a16;
OpFn *x86_opcodes_dd_a32;
OpFn *x86_opcodes_de_a16;
OpFn *x86_opcodes_de_a32;
OpFn *x86_opcodes_df_a16;
OpFn *x86_opcodes_df_a32;
enum
{
CPUID_FPU = (1 << 0),
@ -286,6 +326,85 @@ void cpu_set()
#else
x86_setopcodes(ops_386, ops_386_0f);
#endif
#ifdef DYNAREC
if (hasfpu)
{
x86_dynarec_opcodes_d8_a16 = dynarec_ops_fpu_d8_a16;
x86_dynarec_opcodes_d8_a32 = dynarec_ops_fpu_d8_a32;
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32;
}
else
{
x86_dynarec_opcodes_d8_a16 = dynarec_ops_nofpu_a16;
x86_dynarec_opcodes_d8_a16 = dynarec_ops_nofpu_a32;
x86_dynarec_opcodes_d9_a16 = dynarec_ops_nofpu_a16;
x86_dynarec_opcodes_d9_a16 = dynarec_ops_nofpu_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_nofpu_a16;
x86_dynarec_opcodes_da_a16 = dynarec_ops_nofpu_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_nofpu_a16;
x86_dynarec_opcodes_db_a16 = dynarec_ops_nofpu_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_nofpu_a16;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_nofpu_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_nofpu_a16;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_nofpu_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_nofpu_a16;
x86_dynarec_opcodes_de_a16 = dynarec_ops_nofpu_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a16;
x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a32;
}
#endif
if (hasfpu)
{
x86_opcodes_d8_a16 = ops_fpu_d8_a16;
x86_opcodes_d8_a32 = ops_fpu_d8_a32;
x86_opcodes_d9_a16 = ops_fpu_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_d9_a32;
x86_opcodes_da_a16 = ops_fpu_da_a16;
x86_opcodes_da_a32 = ops_fpu_da_a32;
x86_opcodes_db_a16 = ops_fpu_db_a16;
x86_opcodes_db_a32 = ops_fpu_db_a32;
x86_opcodes_dc_a16 = ops_fpu_dc_a16;
x86_opcodes_dc_a32 = ops_fpu_dc_a32;
x86_opcodes_dd_a16 = ops_fpu_dd_a16;
x86_opcodes_dd_a32 = ops_fpu_dd_a32;
x86_opcodes_de_a16 = ops_fpu_de_a16;
x86_opcodes_de_a32 = ops_fpu_de_a32;
x86_opcodes_df_a16 = ops_fpu_df_a16;
x86_opcodes_df_a32 = ops_fpu_df_a32;
}
else
{
x86_opcodes_d8_a16 = ops_nofpu_a16;
x86_opcodes_d8_a32 = ops_nofpu_a32;
x86_opcodes_d9_a16 = ops_nofpu_a16;
x86_opcodes_d9_a32 = ops_nofpu_a32;
x86_opcodes_da_a16 = ops_nofpu_a16;
x86_opcodes_da_a32 = ops_nofpu_a32;
x86_opcodes_db_a16 = ops_nofpu_a16;
x86_opcodes_db_a32 = ops_nofpu_a32;
x86_opcodes_dc_a16 = ops_nofpu_a16;
x86_opcodes_dc_a32 = ops_nofpu_a32;
x86_opcodes_dd_a16 = ops_nofpu_a16;
x86_opcodes_dd_a32 = ops_nofpu_a32;
x86_opcodes_de_a16 = ops_nofpu_a16;
x86_opcodes_de_a32 = ops_nofpu_a32;
x86_opcodes_df_a16 = ops_nofpu_a16;
x86_opcodes_df_a32 = ops_nofpu_a32;
}
memset(&msr, 0, sizeof(msr));
switch (cpu_s->cpu_type)

View file

@ -5,6 +5,22 @@ void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn
extern OpFn *x86_dynarec_opcodes;
extern OpFn *x86_dynarec_opcodes_0f;
extern OpFn *x86_dynarec_opcodes_d8_a16;
extern OpFn *x86_dynarec_opcodes_d8_a32;
extern OpFn *x86_dynarec_opcodes_d9_a16;
extern OpFn *x86_dynarec_opcodes_d9_a32;
extern OpFn *x86_dynarec_opcodes_da_a16;
extern OpFn *x86_dynarec_opcodes_da_a32;
extern OpFn *x86_dynarec_opcodes_db_a16;
extern OpFn *x86_dynarec_opcodes_db_a32;
extern OpFn *x86_dynarec_opcodes_dc_a16;
extern OpFn *x86_dynarec_opcodes_dc_a32;
extern OpFn *x86_dynarec_opcodes_dd_a16;
extern OpFn *x86_dynarec_opcodes_dd_a32;
extern OpFn *x86_dynarec_opcodes_de_a16;
extern OpFn *x86_dynarec_opcodes_de_a32;
extern OpFn *x86_dynarec_opcodes_df_a16;
extern OpFn *x86_dynarec_opcodes_df_a32;
extern OpFn dynarec_ops_286[1024];
extern OpFn dynarec_ops_286_0f[1024];
@ -14,12 +30,46 @@ extern OpFn dynarec_ops_386_0f[1024];
extern OpFn dynarec_ops_winchip_0f[1024];
extern OpFn dynarec_ops_fpu_d8_a16[32];
extern OpFn dynarec_ops_fpu_d8_a32[32];
extern OpFn dynarec_ops_fpu_d9_a16[256];
extern OpFn dynarec_ops_fpu_d9_a32[256];
extern OpFn dynarec_ops_fpu_da_a16[256];
extern OpFn dynarec_ops_fpu_da_a32[256];
extern OpFn dynarec_ops_fpu_db_a16[256];
extern OpFn dynarec_ops_fpu_db_a32[256];
extern OpFn dynarec_ops_fpu_dc_a16[32];
extern OpFn dynarec_ops_fpu_dc_a32[32];
extern OpFn dynarec_ops_fpu_dd_a16[256];
extern OpFn dynarec_ops_fpu_dd_a32[256];
extern OpFn dynarec_ops_fpu_de_a16[256];
extern OpFn dynarec_ops_fpu_de_a32[256];
extern OpFn dynarec_ops_fpu_df_a16[256];
extern OpFn dynarec_ops_fpu_df_a32[256];
extern OpFn dynarec_ops_nofpu_a16[256];
extern OpFn dynarec_ops_nofpu_a32[256];
#else
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f);
#endif
extern OpFn *x86_opcodes;
extern OpFn *x86_opcodes_0f;
extern OpFn *x86_opcodes_d8_a16;
extern OpFn *x86_opcodes_d8_a32;
extern OpFn *x86_opcodes_d9_a16;
extern OpFn *x86_opcodes_d9_a32;
extern OpFn *x86_opcodes_da_a16;
extern OpFn *x86_opcodes_da_a32;
extern OpFn *x86_opcodes_db_a16;
extern OpFn *x86_opcodes_db_a32;
extern OpFn *x86_opcodes_dc_a16;
extern OpFn *x86_opcodes_dc_a32;
extern OpFn *x86_opcodes_dd_a16;
extern OpFn *x86_opcodes_dd_a32;
extern OpFn *x86_opcodes_de_a16;
extern OpFn *x86_opcodes_de_a32;
extern OpFn *x86_opcodes_df_a16;
extern OpFn *x86_opcodes_df_a32;
extern OpFn ops_286[1024];
extern OpFn ops_286_0f[1024];
@ -28,3 +78,22 @@ extern OpFn ops_386[1024];
extern OpFn ops_386_0f[1024];
extern OpFn ops_winchip_0f[1024];
extern OpFn ops_fpu_d8_a16[32];
extern OpFn ops_fpu_d8_a32[32];
extern OpFn ops_fpu_d9_a16[256];
extern OpFn ops_fpu_d9_a32[256];
extern OpFn ops_fpu_da_a16[256];
extern OpFn ops_fpu_da_a32[256];
extern OpFn ops_fpu_db_a16[256];
extern OpFn ops_fpu_db_a32[256];
extern OpFn ops_fpu_dc_a16[32];
extern OpFn ops_fpu_dc_a32[32];
extern OpFn ops_fpu_dd_a16[256];
extern OpFn ops_fpu_dd_a32[256];
extern OpFn ops_fpu_de_a16[256];
extern OpFn ops_fpu_de_a32[256];
extern OpFn ops_fpu_df_a16[256];
extern OpFn ops_fpu_df_a32[256];
extern OpFn ops_nofpu_a16[256];
extern OpFn ops_nofpu_a32[256];

View file

@ -1,59 +1,74 @@
#define opESCAPE(num) \
static int opESCAPE_ ## num ##_a16(uint32_t fetchdat) \
{ \
flags_rebuild(); \
if (cr0 & 0xc) \
{ \
x86_int(7); \
return 1; \
} \
else \
{ \
fpucount++; \
fetch_ea_16(fetchdat); \
if (hasfpu) \
{ \
x87_pc_off = oldpc; \
x87_pc_seg = CS; \
x87_op_off = eaaddr; \
x87_op_seg = ea_rseg; \
x87_ ## num(fetchdat); \
} \
} \
return abrt; \
} \
static int opESCAPE_ ## num ## _a32(uint32_t fetchdat) \
{ \
flags_rebuild(); \
if (cr0 & 0xc) \
{ \
x86_int(7); \
return 1; \
} \
else \
{ \
fpucount++; \
fetch_ea_32(fetchdat); \
if (hasfpu) \
{ \
x87_pc_off = oldpc; \
x87_pc_seg = CS; \
x87_op_off = eaaddr; \
x87_op_seg = ea_rseg; \
x87_ ## num(fetchdat); \
} \
} \
return abrt; \
}
static int opESCAPE_d8_a16(uint32_t fetchdat)
{
return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int opESCAPE_d8_a32(uint32_t fetchdat)
{
return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat);
}
opESCAPE(d8);
opESCAPE(d9);
opESCAPE(da);
opESCAPE(db);
opESCAPE(dc);
opESCAPE(dd);
opESCAPE(de);
opESCAPE(df);
static int opESCAPE_d9_a16(uint32_t fetchdat)
{
return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_d9_a32(uint32_t fetchdat)
{
return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_da_a16(uint32_t fetchdat)
{
return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_da_a32(uint32_t fetchdat)
{
return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_db_a16(uint32_t fetchdat)
{
return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_db_a32(uint32_t fetchdat)
{
return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_dc_a16(uint32_t fetchdat)
{
return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int opESCAPE_dc_a32(uint32_t fetchdat)
{
return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat);
}
static int opESCAPE_dd_a16(uint32_t fetchdat)
{
return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_dd_a32(uint32_t fetchdat)
{
return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_de_a16(uint32_t fetchdat)
{
return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_de_a32(uint32_t fetchdat)
{
return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_df_a16(uint32_t fetchdat)
{
return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat);
}
static int opESCAPE_df_a32(uint32_t fetchdat)
{
return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat);
}
static int opWAIT(uint32_t fetchdat)
{

1374
src/x87.c

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,10 @@
uint32_t x87_pc_off,x87_op_off;
uint16_t x87_pc_seg,x87_op_seg;
extern uint32_t op32;
extern int TOP;
extern uint16_t npxs, npxc, tag;
extern int ismmx;
extern double ST[8];
typedef union MMX_REG
{
@ -16,5 +20,5 @@ typedef union MMX_REG
extern MMX_REG MM[8];
void x87_set_mmx();
void x87_emms();
static inline void x87_set_mmx();
static inline void x87_emms();

784
src/x87_ops.h Normal file
View file

@ -0,0 +1,784 @@
#include <math.h>
#define fplog 0
#define ST(x) ST[((TOP+(x))&7)]
#define C0 (1<<8)
#define C1 (1<<9)
#define C2 (1<<10)
#define C3 (1<<14)
#define STATUS_ZERODIVIDE 4
#define x87_div(dst, src1, src2) do \
{ \
if (((double)src2) == 0.0) \
{ \
npxs |= STATUS_ZERODIVIDE; \
if (npxc & STATUS_ZERODIVIDE) \
dst = src1 / (double)src2; \
else \
{ \
pclog("FPU : divide by zero\n"); \
picint(1 << 13); \
} \
return; \
} \
else \
dst = src1 / (double)src2; \
} while (0)
static inline void x87_set_mmx()
{
TOP = 0;
tag = 0;
ismmx = 1;
}
static inline void x87_emms()
{
tag = 0xffff;
ismmx = 0;
}
static inline void x87_checkexceptions()
{
}
static inline void x87_push(double i)
{
TOP=(TOP-1)&7;
ST[TOP]=i;
tag&=~(3<<((TOP&7)<<1));
if (i==0.0) tag|=(1<<((TOP&7)<<1));
}
static inline double x87_pop()
{
double t=ST[TOP];
tag|=(3<<((TOP&7)<<1));
TOP=(TOP+1)&7;
return t;
}
static inline int64_t x87_fround(double b)
{
switch ((npxc>>10)&3)
{
case 0: /*Nearest*/
return (int64_t)(b+0.5);
case 1: /*Down*/
return (int64_t)floor(b);
case 2: /*Up*/
return (int64_t)ceil(b);
case 3: /*Chop*/
return (int64_t)b;
}
}
#define BIAS80 16383
#define BIAS64 1023
static inline double x87_ld80()
{
struct {
int16_t begin;
union
{
double d;
uint64_t ll;
} eind;
} test;
test.eind.ll = readmeml(easeg,eaaddr);
test.eind.ll |= (uint64_t)readmeml(easeg,eaaddr+4)<<32;
test.begin = readmemw(easeg,eaaddr+8);
int64_t exp64 = (((test.begin&0x7fff) - BIAS80));
int64_t blah = ((exp64 >0)?exp64:-exp64)&0x3ff;
int64_t exp64final = ((exp64 >0)?blah:-blah) +BIAS64;
int64_t mant64 = (test.eind.ll >> 11) & (0xfffffffffffff);
int64_t sign = (test.begin&0x8000)?1:0;
if ((test.begin & 0x7fff) == 0x7fff)
exp64final = 0x7ff;
if ((test.begin & 0x7fff) == 0)
exp64final = 0;
if (test.eind.ll & 0x400)
mant64++;
test.eind.ll = (sign <<63)|(exp64final << 52)| mant64;
return test.eind.d;
}
static inline void x87_st80(double d)
{
struct {
int16_t begin;
union
{
double d;
uint64_t ll;
} eind;
} test;
test.eind.d=d;
int64_t sign80 = (test.eind.ll&(0x8000000000000000))?1:0;
int64_t exp80 = test.eind.ll&(0x7ff0000000000000);
int64_t exp80final = (exp80>>52);
int64_t mant80 = test.eind.ll&(0x000fffffffffffff);
int64_t mant80final = (mant80 << 11);
if (exp80final == 0x7ff) /*Infinity / Nan*/
{
exp80final = 0x7fff;
mant80final |= (0x8000000000000000);
}
else if (d != 0){ //Zero is a special case
// Elvira wants the 8 and tcalc doesn't
mant80final |= (0x8000000000000000);
//Ca-cyber doesn't like this when result is zero.
exp80final += (BIAS80 - BIAS64);
}
test.begin = (((int16_t)sign80)<<15)| (int16_t)exp80final;
test.eind.ll = mant80final;
writememl(easeg,eaaddr,test.eind.ll);
writememl(easeg,eaaddr+4,test.eind.ll>>32);
writememw(easeg,eaaddr+8,test.begin);
}
static inline void x87_ldmmx(MMX_REG *r)
{
r->l[0] = readmeml(easeg, eaaddr);
r->l[1] = readmeml(easeg, eaaddr + 4);
r->w[4] = readmemw(easeg, eaaddr + 8);
}
static inline void x87_stmmx(MMX_REG r)
{
writememl(easeg, eaaddr, r.l[0]);
writememl(easeg, eaaddr + 4, r.l[1]);
writememw(easeg, eaaddr + 8, 0xffff);
}
typedef union
{
float s;
uint32_t i;
} x87_ts;
typedef union
{
double d;
uint64_t i;
} x87_td;
#define FP_ENTER() do \
{ \
flags_rebuild(); \
if (cr0 & 0xc) \
{ \
x86_int(7); \
return 1; \
} \
fpucount++; \
} while (0)
#include "x87_ops_arith.h"
#include "x87_ops_misc.h"
#include "x87_ops_loadstore.h"
static int op_nofpu_a16(uint32_t fetchdat)
{
if (cr0 & 0xc)
{
x86_int(7);
return 1;
}
else
fetch_ea_16(fetchdat);
}
static int op_nofpu_a32(uint32_t fetchdat)
{
if (cr0 & 0xc)
{
x86_int(7);
return 1;
}
else
fetch_ea_32(fetchdat);
}
OpFn OP_TABLE(fpu_d8_a16)[32] =
{
opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16,
opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16,
opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16,
opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR
};
OpFn OP_TABLE(fpu_d8_a32)[32] =
{
opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32,
opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32,
opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32,
opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR
};
OpFn OP_TABLE(fpu_d9_a16)[256] =
{
opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16,
opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16,
opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16,
opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16,
opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16,
opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16,
opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16,
opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16,
opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16,
opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16,
opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16,
opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16,
opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16,
opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16,
opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16,
opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16,
opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16,
opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16,
opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD,
opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH,
opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/
opFCHS, opFABS, ILLEGAL, ILLEGAL, opFTST, opFXAM, ILLEGAL, ILLEGAL,
opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL, ILLEGAL, opFDECSTP, opFINCSTP,
opFPREM, ILLEGAL, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
};
OpFn OP_TABLE(fpu_d9_a32)[256] =
{
opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32,
opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32,
opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32,
opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32,
opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32,
opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32,
opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32,
opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32,
opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32,
opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32,
opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32,
opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32,
opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32,
opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32,
opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32,
opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32,
opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32,
opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32,
opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD,
opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH,
opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/
opFCHS, opFABS, ILLEGAL, ILLEGAL, opFTST, opFXAM, ILLEGAL, ILLEGAL,
opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL,
opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL, ILLEGAL, opFDECSTP, opFINCSTP,
opFPREM, ILLEGAL, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
};
OpFn OP_TABLE(fpu_da_a16)[256] =
{
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16,
opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16,
opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16,
opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16,
opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16,
opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16,
opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16,
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16,
opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16,
opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16,
opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16,
opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16,
opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16,
opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16,
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16,
opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16,
opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16,
opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16,
opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16,
opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16,
opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(fpu_da_a32)[256] =
{
opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32,
opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32,
opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32,
opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32,
opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32,
opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32,
opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32,
opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32,
opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32,
opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32,
opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32,
opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32,
opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32,
opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32,
opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32,
opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32,
opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32,
opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32,
opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32,
opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32,
opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32,
opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32,
opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32,
opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(fpu_db_a16)[256] =
{
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16,
opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16,
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16,
opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16,
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16,
opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(fpu_db_a32)[256] =
{
opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32,
opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32,
opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32,
opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32,
opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32,
opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(fpu_dc_a16)[32] =
{
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDr, opFMULr, ILLEGAL, ILLEGAL, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr
};
OpFn OP_TABLE(fpu_dc_a32)[32] =
{
opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32,
opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32,
opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32,
opFADDr, opFMULr, ILLEGAL, ILLEGAL, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr
};
OpFn OP_TABLE(fpu_dd_a16)[256] =
{
opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16,
opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16,
opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16,
opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16,
opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16,
opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16,
opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16,
opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16,
opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16,
opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16,
opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16,
opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16,
opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST,
opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP,
opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM,
opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(fpu_dd_a32)[256] =
{
opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32,
opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32,
opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32,
opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32,
opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32,
opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32,
opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32,
opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32,
opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32,
opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32,
opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32,
opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32,
opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST,
opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP,
opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM,
opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(fpu_de_a16)[256] =
{
opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16,
opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16,
opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16,
opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16,
opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16,
opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16,
opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16,
opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16,
opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16,
opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16,
opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16,
opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16,
opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16,
opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16,
opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16,
opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16,
opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16,
opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16,
opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16,
opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16,
opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16,
opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16,
opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16,
opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16,
opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP,
opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, opFCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP,
opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP,
opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP,
opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP,
};
OpFn OP_TABLE(fpu_de_a32)[256] =
{
opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32,
opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32,
opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32,
opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32,
opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32,
opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32,
opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32,
opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32,
opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32,
opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32,
opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32,
opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32,
opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32,
opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32,
opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32,
opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32,
opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32,
opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32,
opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32,
opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32,
opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32,
opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32,
opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32,
opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32, opFDIVRd_a32,
opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP,
opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, opFCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP,
opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP,
opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP,
opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP,
};
OpFn OP_TABLE(fpu_df_a16)[256] =
{
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(fpu_df_a32)[256] =
{
opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32,
opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32,
FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32,
FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32,
opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32,
opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32,
FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32,
FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32,
opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32,
opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32,
FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32,
FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(nofpu_a16)[256] =
{
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
};
OpFn OP_TABLE(nofpu_a32)[256] =
{
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
};

343
src/x87_ops_arith.h Normal file
View file

@ -0,0 +1,343 @@
#define opFPU(name, optype, a_size, load_var, get, use_var) \
static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
load_var = get(); if (abrt) return 1; \
ST(0) += use_var; \
cycles -= 8; \
} \
static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
load_var = get(); if (abrt) return 1; \
npxs &= ~(C0|C2|C3); \
if (ST(0) == use_var) npxs |= C3; \
else if (ST(0) < use_var) npxs |= C0; \
cycles -= 4; \
} \
static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
load_var = get(); if (abrt) return 1; \
npxs &= ~(C0|C2|C3); \
if (ST(0) == use_var) npxs |= C3; \
else if (ST(0) < use_var) npxs |= C0; \
x87_pop(); \
cycles -= 4; \
} \
static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
load_var = get(); if (abrt) return 1; \
x87_div(ST(0), ST(0), use_var); \
cycles -= 73; \
} \
static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
load_var = get(); if (abrt) return 1; \
x87_div(ST(0), use_var, ST(0)); \
cycles -= 73; \
} \
static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
load_var = get(); if (abrt) return 1; \
ST(0) *= use_var; \
cycles -= 11; \
} \
static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
load_var = get(); if (abrt) return 1; \
ST(0) -= use_var; \
cycles -= 8; \
} \
static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \
{ \
optype t; \
FP_ENTER(); \
fetch_ea_ ## a_size(fetchdat); \
load_var = get(); if (abrt) return 1; \
ST(0) = use_var - ST(0); \
cycles -= 8; \
}
opFPU(s, x87_ts, 16, t.i, geteal, t.s)
opFPU(s, x87_ts, 32, t.i, geteal, t.s)
opFPU(d, x87_td, 16, t.i, geteaq, t.d)
opFPU(d, x87_td, 32, t.i, geteaq, t.d)
opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t)
opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t)
opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t)
opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t)
static int opFADD(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FADD\n");
ST(0) = ST(0) + ST(fetchdat & 7);
cycles -= 8;
return 0;
}
static int opFADDr(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FADD\n");
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
cycles -= 8;
return 0;
}
static int opFADDP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FADDP\n");
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
x87_pop();
cycles -= 8;
return 0;
}
static int opFCOM(uint32_t fetchdat)
{
FP_ENTER();
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;
cycles -= 4;
return 0;
}
static int opFCOMP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FCOMP\n");
npxs &= ~(C0|C2|C3);
if (ST(0) == ST(fetchdat & 7)) npxs |= C3;
else if (ST(0) < ST(fetchdat & 7)) npxs |= C0;
x87_pop();
cycles -= 4;
return 0;
}
static int opFCOMPP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FCOMPP\n");
npxs &= ~(C0|C2|C3);
if (ST(0) == ST(1)) npxs |= C3;
else if (ST(0) < ST(1)) npxs |= C0;
x87_pop();
x87_pop();
cycles -= 4;
return 0;
}
static int opFUCOMPP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FUCOMPP\n", easeg, eaaddr);
npxs &= ~(C0|C2|C3);
if (ST(0) == ST(1)) npxs |= C3;
else if (ST(0) < ST(1)) npxs |= C0;
x87_pop();
x87_pop();
cycles -= 5;
return 0;
}
static int opFDIV(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FDIV\n");
x87_div(ST(0), ST(0), ST(fetchdat & 7));
cycles -= 73;
return 0;
}
static int opFDIVr(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FDIV\n");
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
cycles -= 73;
return 0;
}
static int opFDIVP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FDIVP\n");
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
x87_pop();
cycles -= 73;
return 0;
}
static int opFDIVR(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FDIVR\n");
x87_div(ST(0), ST(fetchdat&7), ST(0));
cycles -= 73;
return 0;
}
static int opFDIVRr(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FDIVR\n");
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
cycles -= 73;
return 0;
}
static int opFDIVRP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FDIVR\n");
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
x87_pop();
cycles -= 73;
return 0;
}
static int opFMUL(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FMUL\n");
ST(0) = ST(0) * ST(fetchdat & 7);
cycles -= 16;
return 0;
}
static int opFMULr(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FMUL\n");
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
cycles -= 16;
return 0;
}
static int opFMULP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FMULP\n");
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
x87_pop();
cycles -= 16;
return 0;
}
static int opFSUB(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FSUB\n");
ST(0) = ST(0) - ST(fetchdat & 7);
cycles -= 8;
return 0;
}
static int opFSUBr(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FSUB\n");
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
cycles -= 8;
return 0;
}
static int opFSUBP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FSUBP\n");
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
x87_pop();
cycles -= 8;
return 0;
}
static int opFSUBR(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FSUBR\n");
ST(0) = ST(fetchdat & 7) - ST(0);
cycles -= 8;
return 0;
}
static int opFSUBRr(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FSUBR\n");
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
cycles -= 8;
return 0;
}
static int opFSUBRP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FSUBRP\n");
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
x87_pop();
cycles -= 8;
return 0;
}
static int opFUCOM(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FUCOM\n");
npxs &= ~(C0|C2|C3);
if (ST(0) == ST(fetchdat&7)) npxs |= C3;
else if (ST(0) < ST(fetchdat&7)) npxs |= C0;
cycles -= 4;
return 0;
}
static int opFUCOMP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FUCOMP\n");
npxs &= ~(C0|C2|C3);
if (ST(0) == ST(fetchdat&7)) npxs |= C3;
else if (ST(0) < ST(fetchdat&7)) npxs |= C0;
x87_pop();
cycles -= 4;
return 0;
}

456
src/x87_ops_loadstore.h Normal file
View file

@ -0,0 +1,456 @@
static int opFILDiw_a16(uint32_t fetchdat)
{
int16_t temp;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FILDw %08X:%08X\n", easeg, eaaddr);
temp = geteaw(); if (abrt) return 1;
if (fplog) pclog(" %f\n", (double)temp);
x87_push((double)temp);
cycles -= 13;
return 0;
}
static int opFILDiw_a32(uint32_t fetchdat)
{
int16_t temp;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FILDw %08X:%08X\n", easeg, eaaddr);
temp = geteaw(); if (abrt) return 1;
if (fplog) pclog(" %f\n", (double)temp);
x87_push((double)temp);
cycles -= 13;
return 0;
}
static int opFISTiw_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FISTw %08X:%08X\n", easeg, eaaddr);
temp64 = x87_fround(ST(0));
/* if (temp64 > 32767 || temp64 < -32768)
fatal("FISTw overflow %i\n", temp64);*/
seteaw((int16_t)temp64);
cycles -= 29;
return abrt;
}
static int opFISTiw_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FISTw %08X:%08X\n", easeg, eaaddr);
temp64 = x87_fround(ST(0));
/* if (temp64 > 32767 || temp64 < -32768)
fatal("FISTw overflow %i\n", temp64);*/
seteaw((int16_t)temp64);
cycles -= 29;
return abrt;
}
static int opFISTPiw_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FISTw %08X:%08X\n", easeg, eaaddr);
temp64 = x87_fround(ST(0));
/* if (temp64 > 32767 || temp64 < -32768)
fatal("FISTw overflow %i\n", temp64);*/
seteaw((int16_t)temp64); if (abrt) return 1;
x87_pop();
cycles -= 29;
return 0;
}
static int opFISTPiw_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FISTw %08X:%08X\n", easeg, eaaddr);
temp64 = x87_fround(ST(0));
/* if (temp64 > 32767 || temp64 < -32768)
fatal("FISTw overflow %i\n", temp64);*/
seteaw((int16_t)temp64); if (abrt) return 1;
x87_pop();
cycles -= 29;
return 0;
}
static int opFILDiq_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FILDl %08X:%08X\n", easeg, eaaddr);
temp64 = geteaq(); if (abrt) return 1;
if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,eaaddr), readmeml(easeg,eaaddr+4));
x87_push((double)temp64);
cycles -= 10;
return 0;
}
static int opFILDiq_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FILDl %08X:%08X\n", easeg, eaaddr);
temp64 = geteaq(); if (abrt) return 1;
if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,eaaddr), readmeml(easeg,eaaddr+4));
x87_push((double)temp64);
cycles -= 10;
return 0;
}
static int FBSTP_a16(uint32_t fetchdat)
{
double tempd;
int c;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FBSTP %08X:%08X\n", easeg, eaaddr);
tempd = ST(0);
if (tempd < 0.0)
tempd = -tempd;
for (c = 0; c < 9; c++)
{
uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0));
tempd -= floor(fmod(tempd, 10.0));
tempd /= 10.0;
tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4;
tempd -= floor(fmod(tempd, 10.0));
tempd /= 10.0;
writememb(easeg, eaaddr + c, tempc);
}
tempc = (uint8_t)floor(fmod(tempd, 10.0));
if (ST(0) < 0.0) tempc |= 0x80;
writememb(easeg, eaaddr + 9, tempc); if (abrt) return 1;
x87_pop();
return 0;
}
static int FBSTP_a32(uint32_t fetchdat)
{
double tempd;
int c;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FBSTP %08X:%08X\n", easeg, eaaddr);
tempd = ST(0);
if (tempd < 0.0)
tempd = -tempd;
for (c = 0; c < 9; c++)
{
uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0));
tempd -= floor(fmod(tempd, 10.0));
tempd /= 10.0;
tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4;
tempd -= floor(fmod(tempd, 10.0));
tempd /= 10.0;
writememb(easeg, eaaddr + c, tempc);
}
tempc = (uint8_t)floor(fmod(tempd, 10.0));
if (ST(0) < 0.0) tempc |= 0x80;
writememb(easeg, eaaddr + 9, tempc); if (abrt) return 1;
x87_pop();
return 0;
}
static int FISTPiq_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FISTPl %08X:%08X\n", easeg, eaaddr);
temp64 = x87_fround(ST(0));
seteaq(temp64); if (abrt) return 1;
x87_pop();
cycles -= 29;
return 1;
}
static int FISTPiq_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FISTPl %08X:%08X\n", easeg, eaaddr);
temp64 = x87_fround(ST(0));
seteaq(temp64); if (abrt) return 1;
x87_pop();
cycles -= 29;
return 1;
}
static int opFILDil_a16(uint32_t fetchdat)
{
int32_t templ;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FILDs %08X:%08X\n", easeg, eaaddr);
templ = geteal(); if (abrt) return 1;
if (fplog) pclog(" %f %08X %i\n", (double)templ, templ, templ);
x87_push((double)templ);
cycles -= 9;
return 0;
}
static int opFILDil_a32(uint32_t fetchdat)
{
int32_t templ;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FILDs %08X:%08X\n", easeg, eaaddr);
templ = geteal(); if (abrt) return 1;
if (fplog) pclog(" %f %08X %i\n", (double)templ, templ, templ);
x87_push((double)templ);
cycles -= 9;
return 0;
}
static int opFISTil_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FISTs %08X:%08X\n", easeg, eaaddr);
temp64 = x87_fround(ST(0));
/* if (temp64 > 2147483647 || temp64 < -2147483647)
fatal("FISTl out of range! %i\n", temp64);*/
seteal((int32_t)temp64);
cycles -= 28;
return abrt;
}
static int opFISTil_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FISTs %08X:%08X\n", easeg, eaaddr);
temp64 = x87_fround(ST(0));
/* if (temp64 > 2147483647 || temp64 < -2147483647)
fatal("FISTl out of range! %i\n", temp64);*/
seteal((int32_t)temp64);
cycles -= 28;
return abrt;
}
static int opFISTPil_a16(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FISTs %08X:%08X\n", easeg, eaaddr);
temp64 = x87_fround(ST(0));
/* if (temp64 > 2147483647 || temp64 < -2147483647)
fatal("FISTl out of range! %i\n", temp64);*/
seteal((int32_t)temp64); if (abrt) return 1;
x87_pop();
cycles -= 28;
return 0;
}
static int opFISTPil_a32(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FISTs %08X:%08X\n", easeg, eaaddr);
temp64 = x87_fround(ST(0));
/* if (temp64 > 2147483647 || temp64 < -2147483647)
fatal("FISTl out of range! %i\n", temp64);*/
seteal((int32_t)temp64); if (abrt) return 1;
x87_pop();
cycles -= 28;
return 0;
}
static int opFLDe_a16(uint32_t fetchdat)
{
double t;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FLDe %08X:%08X\n", easeg, eaaddr);
t=x87_ld80(); if (abrt) return 1;
if (fplog) pclog(" %f\n", t);
x87_push(t);
cycles -= 6;
return 0;
}
static int opFLDe_a32(uint32_t fetchdat)
{
double t;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FLDe %08X:%08X\n", easeg, eaaddr);
t=x87_ld80(); if (abrt) return 1;
if (fplog) pclog(" %f\n", t);
x87_push(t);
cycles -= 6;
return 0;
}
static int opFSTPe_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FSTPe %08X:%08X\n", easeg, eaaddr);
x87_st80(ST(0)); if (abrt) return 1;
x87_pop();
cycles -= 6;
return 0;
}
static int opFSTPe_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FSTPe %08X:%08X\n", easeg, eaaddr);
x87_st80(ST(0)); if (abrt) return 1;
x87_pop();
cycles -= 6;
return 0;
}
static int opFLDd_a16(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FLDd %08X:%08X\n", easeg, eaaddr);
t.i = geteaq(); if (abrt) return 1;
if (fplog) pclog(" %f\n", t.d);
x87_push(t.d);
cycles -= 3;
return 0;
}
static int opFLDd_a32(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FLDd %08X:%08X\n", easeg, eaaddr);
t.i = geteaq(); if (abrt) return 1;
if (fplog) pclog(" %f\n", t.d);
x87_push(t.d);
cycles -= 3;
return 0;
}
static int opFSTd_a16(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FSTd %08X:%08X\n", easeg, eaaddr);
t.d = ST(0);
seteaq(t.i);
cycles -= 8;
return abrt;
}
static int opFSTd_a32(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FSTd %08X:%08X\n", easeg, eaaddr);
t.d = ST(0);
seteaq(t.i);
cycles -= 8;
return abrt;
}
static int opFSTPd_a16(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FSTd %08X:%08X\n", easeg, eaaddr);
t.d = ST(0);
seteaq(t.i); if (abrt) return 1;
x87_pop();
cycles -= 8;
return 0;
}
static int opFSTPd_a32(uint32_t fetchdat)
{
x87_td t;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FSTd %08X:%08X\n", easeg, eaaddr);
t.d = ST(0);
seteaq(t.i); if (abrt) return 1;
x87_pop();
cycles -= 8;
return 0;
}
static int opFLDs_a16(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FLDs %08X:%08X\n", easeg, eaaddr);
ts.i = geteal(); if (abrt) return 1;
if (fplog) pclog(" %f\n", ts.s);
x87_push((double)ts.s);
cycles -= 3;
return 0;
}
static int opFLDs_a32(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FLDs %08X:%08X\n", easeg, eaaddr);
ts.i = geteal(); if (abrt) return 1;
if (fplog) pclog(" %f\n", ts.s);
x87_push((double)ts.s);
cycles -= 3;
return 0;
}
static int opFSTs_a16(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FSTs %08X:%08X\n", easeg, eaaddr);
ts.s = (float)ST(0);
seteal(ts.i);
cycles -= 7;
return abrt;
}
static int opFSTs_a32(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FSTs %08X:%08X\n", easeg, eaaddr);
ts.s = (float)ST(0);
seteal(ts.i);
cycles -= 7;
return abrt;
}
static int opFSTPs_a16(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FSTs %08X:%08X\n", easeg, eaaddr);
ts.s = (float)ST(0);
seteal(ts.i); if (abrt) return 1;
x87_pop();
cycles -= 7;
return 0;
}
static int opFSTPs_a32(uint32_t fetchdat)
{
x87_ts ts;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FSTs %08X:%08X\n", easeg, eaaddr);
ts.s = (float)ST(0);
seteal(ts.i); if (abrt) return 1;
x87_pop();
cycles -= 7;
return 0;
}

738
src/x87_ops_misc.h Normal file
View file

@ -0,0 +1,738 @@
static int opFSTSW_AX(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FSTSW\n");
AX = npxs;
cycles -= 3;
return 0;
}
static int opFNOP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
cycles -= 4;
return 0;
}
static int opFCLEX(uint32_t fetchdat)
{
FP_ENTER();
pc++;
npxs &= 0xff00;
cycles -= 4;
return 0;
}
static int opFINIT(uint32_t fetchdat)
{
FP_ENTER();
pc++;
npxc = 0x37F;
npxs = 0;
tag = 0xFFFF;
TOP = 0;
cycles -= 17;
return 0;
}
static int opFFREE(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FFREE\n");
tag |= (3 << (((TOP + fetchdat) & 7) << 1));
cycles -= 3;
return 0;
}
static int opFST(uint32_t fetchdat)
{
int temp;
FP_ENTER();
pc++;
if (fplog) pclog("FST\n");
ST(fetchdat & 7) = ST(0);
temp = (tag >> ((TOP & 7) << 1)) & 3;
tag &= ~(3 << (((TOP + fetchdat) & 7) << 1));
tag |= (temp << (((TOP + fetchdat) & 7) << 1));
cycles -= 3;
return 0;
}
static int opFSTP(uint32_t fetchdat)
{
int temp;
FP_ENTER();
pc++;
if (fplog) pclog("FSTP\n");
ST(fetchdat & 7) = ST(0);
temp = (tag >> ((TOP & 7) << 1)) & 3;
tag &= ~(3 << (((TOP + fetchdat) & 7) << 1));
tag |= (temp << (((TOP + fetchdat) & 7) << 1));
x87_pop();
cycles -= 3;
return 0;
}
static void FSTOR()
{
switch ((cr0 & 1) | (op32 & 0x100))
{
case 0x000: /*16-bit real mode*/
case 0x001: /*16-bit protected mode*/
npxc = readmemw(easeg, eaaddr);
npxs = readmemw(easeg, eaaddr+2);
tag = readmemw(easeg, eaaddr+4);
TOP = (npxs >> 11) & 7;
eaaddr += 14;
break;
case 0x100: /*32-bit real mode*/
case 0x101: /*32-bit protected mode*/
npxc = readmemw(easeg, eaaddr);
npxs = readmemw(easeg, eaaddr+4);
tag = readmemw(easeg, eaaddr+8);
TOP = (npxs >> 11) & 7;
eaaddr += 28;
break;
}
x87_ldmmx(&MM[0]); ST(0)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[1]); ST(1)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[2]); ST(2)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[3]); ST(3)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[4]); ST(4)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[5]); ST(5)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[6]); ST(6)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[7]); ST(7)=x87_ld80();
ismmx = 0;
/*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times
something like this is needed*/
if (MM[0].w[4] == 0xffff && MM[1].w[4] == 0xffff && MM[2].w[4] == 0xffff && MM[3].w[4] == 0xffff &&
MM[4].w[4] == 0xffff && MM[5].w[4] == 0xffff && MM[6].w[4] == 0xffff && MM[7].w[4] == 0xffff &&
!TOP && !tag)
ismmx = 1;
cycles -= (cr0 & 1) ? 34 : 44;
if (fplog) pclog("FRSTOR %08X:%08X %i %i %04X\n", easeg, eaaddr, ismmx, TOP, tag);
}
static int opFSTOR_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
FSTOR();
return abrt;
}
static int opFSTOR_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
FSTOR();
return abrt;
}
static void FSAVE()
{
if (fplog) pclog("FSAVE %08X:%08X %i\n", easeg, eaaddr, ismmx);
npxs = (npxs & ~(7 << 11)) | (TOP << 11);
switch ((cr0&1)|(op32&0x100))
{
case 0x000: /*16-bit real mode*/
writememw(easeg,eaaddr,npxc);
writememw(easeg,eaaddr+2,npxs);
writememw(easeg,eaaddr+4,tag);
writememw(easeg,eaaddr+6,x87_pc_off);
writememw(easeg,eaaddr+10,x87_op_off);
eaaddr+=14;
if (ismmx)
{
x87_stmmx(MM[0]); eaaddr+=10;
x87_stmmx(MM[1]); eaaddr+=10;
x87_stmmx(MM[2]); eaaddr+=10;
x87_stmmx(MM[3]); eaaddr+=10;
x87_stmmx(MM[4]); eaaddr+=10;
x87_stmmx(MM[5]); eaaddr+=10;
x87_stmmx(MM[6]); eaaddr+=10;
x87_stmmx(MM[7]);
}
else
{
x87_st80(ST(0)); eaaddr+=10;
x87_st80(ST(1)); eaaddr+=10;
x87_st80(ST(2)); eaaddr+=10;
x87_st80(ST(3)); eaaddr+=10;
x87_st80(ST(4)); eaaddr+=10;
x87_st80(ST(5)); eaaddr+=10;
x87_st80(ST(6)); eaaddr+=10;
x87_st80(ST(7));
}
break;
case 0x001: /*16-bit protected mode*/
writememw(easeg,eaaddr,npxc);
writememw(easeg,eaaddr+2,npxs);
writememw(easeg,eaaddr+4,tag);
writememw(easeg,eaaddr+6,x87_pc_off);
writememw(easeg,eaaddr+8,x87_pc_seg);
writememw(easeg,eaaddr+10,x87_op_off);
writememw(easeg,eaaddr+12,x87_op_seg);
eaaddr+=14;
if (ismmx)
{
x87_stmmx(MM[0]); eaaddr+=10;
x87_stmmx(MM[1]); eaaddr+=10;
x87_stmmx(MM[2]); eaaddr+=10;
x87_stmmx(MM[3]); eaaddr+=10;
x87_stmmx(MM[4]); eaaddr+=10;
x87_stmmx(MM[5]); eaaddr+=10;
x87_stmmx(MM[6]); eaaddr+=10;
x87_stmmx(MM[7]);
}
else
{
x87_st80(ST(0)); eaaddr+=10;
x87_st80(ST(1)); eaaddr+=10;
x87_st80(ST(2)); eaaddr+=10;
x87_st80(ST(3)); eaaddr+=10;
x87_st80(ST(4)); eaaddr+=10;
x87_st80(ST(5)); eaaddr+=10;
x87_st80(ST(6)); eaaddr+=10;
x87_st80(ST(7));
}
break;
case 0x100: /*32-bit real mode*/
writememw(easeg,eaaddr,npxc);
writememw(easeg,eaaddr+4,npxs);
writememw(easeg,eaaddr+8,tag);
writememw(easeg,eaaddr+12,x87_pc_off);
writememw(easeg,eaaddr+20,x87_op_off);
writememl(easeg,eaaddr+24,(x87_op_off>>16)<<12);
eaaddr+=28;
if (ismmx)
{
x87_stmmx(MM[0]); eaaddr+=10;
x87_stmmx(MM[1]); eaaddr+=10;
x87_stmmx(MM[2]); eaaddr+=10;
x87_stmmx(MM[3]); eaaddr+=10;
x87_stmmx(MM[4]); eaaddr+=10;
x87_stmmx(MM[5]); eaaddr+=10;
x87_stmmx(MM[6]); eaaddr+=10;
x87_stmmx(MM[7]);
}
else
{
x87_st80(ST(0)); eaaddr+=10;
x87_st80(ST(1)); eaaddr+=10;
x87_st80(ST(2)); eaaddr+=10;
x87_st80(ST(3)); eaaddr+=10;
x87_st80(ST(4)); eaaddr+=10;
x87_st80(ST(5)); eaaddr+=10;
x87_st80(ST(6)); eaaddr+=10;
x87_st80(ST(7));
}
break;
case 0x101: /*32-bit protected mode*/
writememw(easeg,eaaddr,npxc);
writememw(easeg,eaaddr+4,npxs);
writememw(easeg,eaaddr+8,tag);
writememl(easeg,eaaddr+12,x87_pc_off);
writememl(easeg,eaaddr+16,x87_pc_seg);
writememl(easeg,eaaddr+20,x87_op_off);
writememl(easeg,eaaddr+24,x87_op_seg);
eaaddr+=28;
if (ismmx)
{
x87_stmmx(MM[0]); eaaddr+=10;
x87_stmmx(MM[1]); eaaddr+=10;
x87_stmmx(MM[2]); eaaddr+=10;
x87_stmmx(MM[3]); eaaddr+=10;
x87_stmmx(MM[4]); eaaddr+=10;
x87_stmmx(MM[5]); eaaddr+=10;
x87_stmmx(MM[6]); eaaddr+=10;
x87_stmmx(MM[7]);
}
else
{
x87_st80(ST(0)); eaaddr+=10;
x87_st80(ST(1)); eaaddr+=10;
x87_st80(ST(2)); eaaddr+=10;
x87_st80(ST(3)); eaaddr+=10;
x87_st80(ST(4)); eaaddr+=10;
x87_st80(ST(5)); eaaddr+=10;
x87_st80(ST(6)); eaaddr+=10;
x87_st80(ST(7));
}
break;
}
cycles-=(cr0&1)?56:67;
}
static int opFSAVE_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
FSAVE();
return abrt;
}
static int opFSAVE_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
FSAVE();
return abrt;
}
static int opFSTSW_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FSTSW %08X:%08X\n", easeg, eaaddr);
seteaw((npxs & 0xC7FF) | (TOP << 11));
cycles -= 3;
return abrt;
}
static int opFSTSW_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FSTSW %08X:%08X\n", easeg, eaaddr);
seteaw((npxs & 0xC7FF) | (TOP << 11));
cycles -= 3;
return abrt;
}
static int opFLD(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FLD %f\n", ST(fetchdat & 7));
x87_push(ST(fetchdat&7));
cycles -= 4;
return 0;
}
static int opFXCH(uint32_t fetchdat)
{
double td;
FP_ENTER();
pc++;
if (fplog) pclog("FXCH\n");
td = ST(0);
ST(0) = ST(fetchdat&7);
ST(fetchdat&7) = td;
cycles -= 4;
return 0;
}
static int opFCHS(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FCHS\n");
ST(0) = -ST(0);
cycles -= 6;
return 0;
}
static int opFABS(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FABS %f\n", ST(0));
ST(0) = fabs(ST(0));
cycles -= 3;
return 0;
}
static int opFTST(uint32_t fetchdat)
{
FP_ENTER();
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;
cycles -= 4;
return 0;
}
static int opFXAM(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FXAM %i %f\n", ((tag>>((TOP&7)<<1))&3), ST(0));
npxs &= ~(C0|C2|C3);
if (((tag>>((TOP&7)<<1))&3)==3) npxs |= (C0|C3);
else if (ST(0) == 0.0) npxs |= C3;
else npxs |= C2;
if (ST(0) < 0.0) npxs |= C1;
cycles -= 8;
return 0;
}
static int opFLD1(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FLD1\n");
x87_push(1.0);
cycles -= 4;
return 0;
}
static int opFLDL2T(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FLDL2T\n");
x87_push(3.3219280948873623);
cycles -= 8;
return 0;
}
static int opFLDL2E(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FLDL2E\n");
x87_push(1.4426950408889634);
cycles -= 8;
return 0;
}
static int opFLDPI(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FLDPI\n");
x87_push(3.141592653589793);
cycles -= 8;
return 0;
}
static int opFLDEG2(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FLDEG2\n");
x87_push(0.3010299956639812);
cycles -= 8;
return 0;
}
static int opFLDLN2(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FLDLN2\n");
x87_push(0.693147180559945);
cycles -= 8;
return 0;
}
static int opFLDZ(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FLDZ\n");
x87_push(0.0);
tag |= (1<<((TOP&7)<<1));
cycles -= 4;
return 0;
}
static int opF2XM1(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("F2XM1\n");
ST(0) = pow(2.0, ST(0)) - 1.0;
cycles -= 200;
return 0;
}
static int opFYL2X(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FYL2X\n");
ST(1) = ST(1) * (log(ST(0)) / log(2.0));
x87_pop();
cycles -= 250;
return 0;
}
static int opFPTAN(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FPTAN\n");
ST(0) = tan(ST(0));
x87_push(1.0);
npxs &= ~C2;
cycles -= 235;
return 0;
}
static int opFPATAN(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FPATAN\n");
ST(1) = atan2(ST(1), ST(0));
x87_pop();
cycles -= 250;
return 0;
}
static int opFDECSTP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FDECSTP\n");
TOP = (TOP - 1) & 7;
cycles -= 4;
return 0;
}
static int opFINCSTP(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FDECSTP\n");
TOP = (TOP + 1) & 7;
cycles -= 4;
return 0;
}
static int opFPREM(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
pc++;
if (fplog) pclog("FPREM %f %f ", ST(0), ST(1));
temp64 = (int64_t)(ST(0) / ST(1));
ST(0) = ST(0) - (ST(1) * (double)temp64);
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;
cycles -= 100;
return 0;
}
static int opFSQRT(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FSQRT\n");
ST(0) = sqrt(ST(0));
cycles -= 83;
return 0;
}
static int opFSINCOS(uint32_t fetchdat)
{
double td;
FP_ENTER();
pc++;
if (fplog) pclog("FSINCOS\n");
td = ST(0);
ST(0) = sin(td);
x87_push(cos(td));
npxs &= ~C2;
cycles -= 330;
return 0;
}
static int opFRNDINT(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FRNDINT %g ", ST(0));
ST(0) = (double)x87_fround(ST(0));
if (fplog) pclog("%g\n", ST(0));
cycles -= 21;
return 0;
}
static int opFSCALE(uint32_t fetchdat)
{
int64_t temp64;
FP_ENTER();
pc++;
if (fplog) pclog("FSCALE\n");
temp64 = (int64_t)ST(1);
ST(0) = ST(0) * pow(2.0, (double)temp64);
cycles -= 30;
return 0;
}
static int opFSIN(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FSIN\n");
ST(0) = sin(ST(0));
npxs &= ~C2;
cycles -= 300;
return 0;
}
static int opFCOS(uint32_t fetchdat)
{
FP_ENTER();
pc++;
if (fplog) pclog("FCOS\n");
ST(0) = cos(ST(0));
npxs &= ~C2;
cycles -= 300;
return 0;
}
static void FLDENV()
{
if (fplog) pclog("FLDENV %08X:%08X\n", easeg, eaaddr);
switch ((cr0 & 1) | (op32 & 0x100))
{
case 0x000: /*16-bit real mode*/
case 0x001: /*16-bit protected mode*/
npxc = readmemw(easeg, eaaddr);
npxs = readmemw(easeg, eaaddr+2);
tag = readmemw(easeg, eaaddr+4);
TOP = (npxs >> 11) & 7;
break;
case 0x100: /*32-bit real mode*/
case 0x101: /*32-bit protected mode*/
npxc = readmemw(easeg, eaaddr);
npxs = readmemw(easeg, eaaddr+4);
tag = readmemw(easeg, eaaddr+8);
TOP = (npxs >> 11) & 7;
break;
}
cycles -= (cr0 & 1) ? 34 : 44;
}
static int opFLDENV_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
FLDENV();
return abrt;
}
static int opFLDENV_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
FLDENV();
return abrt;
}
static int opFLDCW_a16(uint32_t fetchdat)
{
uint16_t tempw;
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FLDCW %08X:%08X\n", easeg, eaaddr);
tempw = geteaw();
if (abrt) return 1;
npxc = tempw;
cycles -= 4;
return 0;
}
static int opFLDCW_a32(uint32_t fetchdat)
{
uint16_t tempw;
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FLDCW %08X:%08X\n", easeg, eaaddr);
tempw = geteaw();
if (abrt) return 1;
npxc = tempw;
cycles -= 4;
return 0;
}
static void FSTENV()
{
if (fplog) pclog("FSTENV %08X:%08X\n", easeg, eaaddr);
switch ((cr0 & 1) | (op32 & 0x100))
{
case 0x000: /*16-bit real mode*/
writememw(easeg,eaaddr,npxc);
writememw(easeg,eaaddr+2,npxs);
writememw(easeg,eaaddr+4,tag);
writememw(easeg,eaaddr+6,x87_pc_off);
writememw(easeg,eaaddr+10,x87_op_off);
break;
case 0x001: /*16-bit protected mode*/
writememw(easeg,eaaddr,npxc);
writememw(easeg,eaaddr+2,npxs);
writememw(easeg,eaaddr+4,tag);
writememw(easeg,eaaddr+6,x87_pc_off);
writememw(easeg,eaaddr+8,x87_pc_seg);
writememw(easeg,eaaddr+10,x87_op_off);
writememw(easeg,eaaddr+12,x87_op_seg);
break;
case 0x100: /*32-bit real mode*/
writememw(easeg,eaaddr,npxc);
writememw(easeg,eaaddr+4,npxs);
writememw(easeg,eaaddr+8,tag);
writememw(easeg,eaaddr+12,x87_pc_off);
writememw(easeg,eaaddr+20,x87_op_off);
writememl(easeg,eaaddr+24,(x87_op_off>>16)<<12);
break;
case 0x101: /*32-bit protected mode*/
writememw(easeg,eaaddr,npxc);
writememw(easeg,eaaddr+4,npxs);
writememw(easeg,eaaddr+8,tag);
writememl(easeg,eaaddr+12,x87_pc_off);
writememl(easeg,eaaddr+16,x87_pc_seg);
writememl(easeg,eaaddr+20,x87_op_off);
writememl(easeg,eaaddr+24,x87_op_seg);
break;
}
cycles -= (cr0 & 1) ? 56 : 67;
}
static int opFSTENV_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
FSTENV();
return abrt;
}
static int opFSTENV_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
FSTENV();
return abrt;
}
static int opFSTCW_a16(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_16(fetchdat);
if (fplog) pclog("FSTCW %08X:%08X\n", easeg, eaaddr);
seteaw(npxc);
cycles -= 3;
return abrt;
}
static int opFSTCW_a32(uint32_t fetchdat)
{
FP_ENTER();
fetch_ea_32(fetchdat);
if (fplog) pclog("FSTCW %08X:%08X\n", easeg, eaaddr);
seteaw(npxc);
cycles -= 3;
return abrt;
}