FPU copy should now work.
This commit is contained in:
parent
226b63d682
commit
52a27a9256
7 changed files with 232 additions and 44 deletions
|
|
@ -1275,6 +1275,14 @@ static void FP_FLD(int reg)
|
|||
addbyte(0x83); /*AND EBX, 7*/
|
||||
addbyte(0xe3);
|
||||
addbyte(0x07);
|
||||
addbyte(0x8b); /*MOV EDX, [ST_i64+EAX]*/
|
||||
addbyte(0x14);
|
||||
addbyte(0xc5);
|
||||
addlong((uintptr_t)ST_i64);
|
||||
addbyte(0x8b); /*MOV ECX, [ST_i64+4+EAX]*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0xc5);
|
||||
addlong(((uintptr_t)ST_i64) + 4);
|
||||
addbyte(0x8a); /*MOV AL, [tag+EAX]*/
|
||||
addbyte(0x80);
|
||||
addlong((uintptr_t)tag);
|
||||
|
|
@ -1285,6 +1293,14 @@ static void FP_FLD(int reg)
|
|||
addbyte(0x88); /*MOV [tag+EBX], AL*/
|
||||
addbyte(0x83);
|
||||
addlong((uintptr_t)tag);
|
||||
addbyte(0x89); /*MOV [ST_i64+EBX], EDX*/
|
||||
addbyte(0x14);
|
||||
addbyte(0xdd);
|
||||
addlong((uintptr_t)ST_i64);
|
||||
addbyte(0x89); /*MOV [ST_i64+EBX+4], ECX*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0xdd);
|
||||
addlong(((uintptr_t)ST_i64) + 4);
|
||||
|
||||
addbyte(0x89); /*MOV [TOP], EBX*/
|
||||
addbyte(0x1d);
|
||||
|
|
@ -1351,6 +1367,51 @@ static void FP_FXCH(int reg)
|
|||
addbyte(0x1c);
|
||||
addbyte(0xc5);
|
||||
addlong((uintptr_t)ST);
|
||||
addbyte(0xbe); /*MOVL ESI, tag*/
|
||||
addlong((uintptr_t)tag);
|
||||
addbyte(0x8a); /*MOV CL, tag[EAX]*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x06);
|
||||
addbyte(0x8a); /*MOV DL, tag[EBX]*/
|
||||
addbyte(0x14);
|
||||
addbyte(0x1e);
|
||||
addbyte(0x88); /*MOV tag[EBX], CL*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x1e);
|
||||
addbyte(0x88); /*MOV tag[EAX], DL*/
|
||||
addbyte(0x14);
|
||||
addbyte(0x06);
|
||||
addbyte(0xbe); /*MOVL ESI, ST_int64*/
|
||||
addlong((uintptr_t)ST_i64);
|
||||
addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0xc6);
|
||||
addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]*/
|
||||
addbyte(0x14);
|
||||
addbyte(0xde);
|
||||
addbyte(0x89); /*MOV ST_int64[EBX*8], ECX*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0xde);
|
||||
addbyte(0x89); /*MOV ST_int64[EAX*8], EDX*/
|
||||
addbyte(0x14);
|
||||
addbyte(0xc6);
|
||||
addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]+4*/
|
||||
addbyte(0x4c);
|
||||
addbyte(0xc6);
|
||||
addbyte(0x04);
|
||||
addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]+4*/
|
||||
addbyte(0x54);
|
||||
addbyte(0xde);
|
||||
addbyte(0x04);
|
||||
addbyte(0x89); /*MOV ST_int64[EBX*8]+4, ECX*/
|
||||
addbyte(0x4c);
|
||||
addbyte(0xde);
|
||||
addbyte(0x04);
|
||||
addbyte(0x89); /*MOV ST_int64[EAX*8]+4, EDX*/
|
||||
addbyte(0x54);
|
||||
addbyte(0xc6);
|
||||
addbyte(0x04);
|
||||
reg = reg;
|
||||
//#endif
|
||||
#if 0
|
||||
addbyte(0xbe); /*MOVL ESI, ST*/
|
||||
|
|
@ -1633,6 +1694,10 @@ static void FP_OP_S(int op)
|
|||
addbyte(0x04);
|
||||
addbyte(0xdd);
|
||||
addlong((uintptr_t)ST);
|
||||
addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/
|
||||
addbyte(0xa3);
|
||||
addlong((uintptr_t)tag);
|
||||
addbyte(~TAG_UINT64);
|
||||
addbyte(0xd8); /*FADD [ESP]*/
|
||||
addbyte(0x04 | op);
|
||||
addbyte(0x24);
|
||||
|
|
@ -1665,6 +1730,10 @@ static void FP_OP_REG(int op, int dst, int src)
|
|||
addbyte(0xdd); /*FLD ST[EBX*8]*/
|
||||
addbyte(0x04);
|
||||
addbyte(0xde);
|
||||
addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/
|
||||
addbyte(0xa3);
|
||||
addlong((uintptr_t)tag);
|
||||
addbyte(~TAG_UINT64);
|
||||
addbyte(0xdc); /*FADD ST[EAX*8]*/
|
||||
addbyte(0x04 | op);
|
||||
addbyte(0xc6);
|
||||
|
|
@ -1677,6 +1746,10 @@ static void FP_OP_REG(int op, int dst, int src)
|
|||
addbyte(0xdd); /*FLD [ESI+EAX*8]*/
|
||||
addbyte(0x04);
|
||||
addbyte(0xc6);
|
||||
addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/
|
||||
addbyte(0xa0);
|
||||
addlong((uintptr_t)tag);
|
||||
addbyte(~TAG_UINT64);
|
||||
addbyte(0xdc); /*FADD ST[EBX*8]*/
|
||||
addbyte(0x04 | op);
|
||||
addbyte(0xde);
|
||||
|
|
|
|||
15
src/x87.c
15
src/x87.c
|
|
@ -20,6 +20,7 @@
|
|||
#include "386_common.h"
|
||||
|
||||
double ST[8];
|
||||
uint64_t ST_i64[8];
|
||||
MMX_REG MM[8];
|
||||
int ismmx;
|
||||
uint16_t npxs,npxc;
|
||||
|
|
@ -29,8 +30,18 @@ int TOP;
|
|||
|
||||
uint16_t x87_gettag()
|
||||
{
|
||||
return tag[0] | (tag[1] << 2) | (tag[2] << 4) | (tag[3] << 6) |
|
||||
(tag[4] << 8) | (tag[5] << 10) | (tag[6] << 12) | (tag[7] << 14);
|
||||
uint16_t ret = 0;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
if (tag[c] & TAG_UINT64)
|
||||
ret |= 2 << (c*2);
|
||||
else
|
||||
ret |= (tag[c] << (c*2));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void x87_settag(uint16_t new_tag)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ extern uint16_t npxs, npxc;
|
|||
extern uint8_t tag[8];
|
||||
extern int ismmx;
|
||||
extern double ST[8];
|
||||
extern uint64_t ST_i64[8];
|
||||
|
||||
typedef union MMX_REG
|
||||
{
|
||||
|
|
@ -26,3 +27,6 @@ static inline void x87_emms();
|
|||
|
||||
uint16_t x87_gettag();
|
||||
void x87_settag(uint16_t new_tag);
|
||||
|
||||
/*Hack for FPU copy. If set then ST_i64 contains the 64-bit integer loaded by FILD*/
|
||||
#define TAG_UINT64 (1 << 2)
|
||||
|
|
|
|||
|
|
@ -149,6 +149,39 @@ static inline void x87_st80(double d)
|
|||
writememw(easeg,eaaddr+8,test.begin);
|
||||
}
|
||||
|
||||
static inline void x87_st_fsave(int reg)
|
||||
{
|
||||
reg = (TOP + reg) & 7;
|
||||
|
||||
if (tag[reg] & TAG_UINT64)
|
||||
{
|
||||
writememl(easeg, eaaddr, ST_i64[reg] & 0xffffffff);
|
||||
writememl(easeg, eaaddr + 4, ST_i64[reg] >> 32);
|
||||
writememw(easeg, eaaddr + 8, 0x5555);
|
||||
}
|
||||
else
|
||||
x87_st80(ST[reg]);
|
||||
}
|
||||
|
||||
static inline void x87_ld_frstor(int reg)
|
||||
{
|
||||
uint16_t temp;
|
||||
|
||||
reg = (TOP + reg) & 7;
|
||||
|
||||
temp = readmemw(easeg, eaaddr + 8);
|
||||
|
||||
if (temp == 0x5555 && tag[reg] == 2)
|
||||
{
|
||||
tag[reg] = TAG_UINT64;
|
||||
ST_i64[reg] = readmeml(easeg, eaaddr);
|
||||
ST_i64[reg] |= ((uint64_t)readmeml(easeg, eaaddr + 4) << 32);
|
||||
ST[reg] = (double)ST_i64[reg];
|
||||
}
|
||||
else
|
||||
ST[reg] = x87_ld80();
|
||||
}
|
||||
|
||||
static inline void x87_ldmmx(MMX_REG *r)
|
||||
{
|
||||
r->l[0] = readmeml(easeg, eaaddr);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
fetch_ea_ ## a_size(fetchdat); \
|
||||
load_var = get(); if (abrt) return 1; \
|
||||
ST(0) += use_var; \
|
||||
tag[TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
} \
|
||||
|
|
@ -39,6 +40,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
fetch_ea_ ## a_size(fetchdat); \
|
||||
load_var = get(); if (abrt) return 1; \
|
||||
x87_div(ST(0), ST(0), use_var); \
|
||||
tag[TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(73); \
|
||||
return 0; \
|
||||
} \
|
||||
|
|
@ -49,6 +51,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
fetch_ea_ ## a_size(fetchdat); \
|
||||
load_var = get(); if (abrt) return 1; \
|
||||
x87_div(ST(0), use_var, ST(0)); \
|
||||
tag[TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(73); \
|
||||
return 0; \
|
||||
} \
|
||||
|
|
@ -59,6 +62,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
fetch_ea_ ## a_size(fetchdat); \
|
||||
load_var = get(); if (abrt) return 1; \
|
||||
ST(0) *= use_var; \
|
||||
tag[TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(11); \
|
||||
return 0; \
|
||||
} \
|
||||
|
|
@ -69,6 +73,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
fetch_ea_ ## a_size(fetchdat); \
|
||||
load_var = get(); if (abrt) return 1; \
|
||||
ST(0) -= use_var; \
|
||||
tag[TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
} \
|
||||
|
|
@ -79,6 +84,7 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
fetch_ea_ ## a_size(fetchdat); \
|
||||
load_var = get(); if (abrt) return 1; \
|
||||
ST(0) = use_var - ST(0); \
|
||||
tag[TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
}
|
||||
|
|
@ -103,6 +109,7 @@ static int opFADD(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FADD\n");
|
||||
ST(0) = ST(0) + ST(fetchdat & 7);
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -112,6 +119,7 @@ static int opFADDr(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FADD\n");
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
tag[(TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -121,6 +129,7 @@ static int opFADDP(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FADDP\n");
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
tag[(TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
|
|
@ -185,6 +194,7 @@ static int opFDIV(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FDIV\n");
|
||||
x87_div(ST(0), ST(0), ST(fetchdat & 7));
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -194,6 +204,7 @@ static int opFDIVr(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FDIV\n");
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
tag[(TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -203,6 +214,7 @@ static int opFDIVP(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FDIVP\n");
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
tag[(TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
|
|
@ -214,6 +226,7 @@ static int opFDIVR(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FDIVR\n");
|
||||
x87_div(ST(0), ST(fetchdat&7), ST(0));
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -223,6 +236,7 @@ static int opFDIVRr(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FDIVR\n");
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
tag[(TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -232,6 +246,7 @@ static int opFDIVRP(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FDIVR\n");
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
tag[(TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
|
|
@ -243,6 +258,7 @@ static int opFMUL(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FMUL\n");
|
||||
ST(0) = ST(0) * ST(fetchdat & 7);
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(16);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -252,6 +268,7 @@ static int opFMULr(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FMUL\n");
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
tag[(TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(16);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -261,6 +278,7 @@ static int opFMULP(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FMULP\n");
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
tag[(TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(16);
|
||||
return 0;
|
||||
|
|
@ -272,6 +290,7 @@ static int opFSUB(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FSUB\n");
|
||||
ST(0) = ST(0) - ST(fetchdat & 7);
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -281,6 +300,7 @@ static int opFSUBr(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FSUB\n");
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
tag[(TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -290,6 +310,7 @@ static int opFSUBP(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FSUBP\n");
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
tag[(TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
|
|
@ -301,6 +322,7 @@ static int opFSUBR(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FSUBR\n");
|
||||
ST(0) = ST(fetchdat & 7) - ST(0);
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -310,6 +332,7 @@ static int opFSUBRr(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FSUBR\n");
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
tag[(TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -319,6 +342,7 @@ static int opFSUBRP(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FSUBRP\n");
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
tag[(TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ static int opFILDiq_a16(uint32_t fetchdat)
|
|||
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);
|
||||
ST_i64[TOP] = temp64;
|
||||
tag[TOP] |= TAG_UINT64;
|
||||
|
||||
CLOCK_CYCLES(10);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -100,6 +103,9 @@ static int opFILDiq_a32(uint32_t fetchdat)
|
|||
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);
|
||||
ST_i64[TOP] = temp64;
|
||||
tag[TOP] |= TAG_UINT64;
|
||||
|
||||
CLOCK_CYCLES(10);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -163,7 +169,10 @@ static int FISTPiq_a16(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
if (fplog) pclog("FISTPl %08X:%08X\n", easeg, eaaddr);
|
||||
temp64 = x87_fround(ST(0));
|
||||
if (tag[TOP] & TAG_UINT64)
|
||||
temp64 = ST_i64[TOP];
|
||||
else
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteaq(temp64); if (abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(29);
|
||||
|
|
@ -175,7 +184,10 @@ static int FISTPiq_a32(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
if (fplog) pclog("FISTPl %08X:%08X\n", easeg, eaaddr);
|
||||
temp64 = x87_fround(ST(0));
|
||||
if (tag[TOP] & TAG_UINT64)
|
||||
temp64 = ST_i64[TOP];
|
||||
else
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteaq(temp64); if (abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(29);
|
||||
|
|
|
|||
|
|
@ -98,14 +98,15 @@ static int FSTOR()
|
|||
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();
|
||||
x87_ldmmx(&MM[0]); x87_ld_frstor(0); eaaddr += 10;
|
||||
x87_ldmmx(&MM[1]); x87_ld_frstor(1); eaaddr += 10;
|
||||
x87_ldmmx(&MM[2]); x87_ld_frstor(2); eaaddr += 10;
|
||||
x87_ldmmx(&MM[3]); x87_ld_frstor(3); eaaddr += 10;
|
||||
x87_ldmmx(&MM[4]); x87_ld_frstor(4); eaaddr += 10;
|
||||
x87_ldmmx(&MM[5]); x87_ld_frstor(5); eaaddr += 10;
|
||||
x87_ldmmx(&MM[6]); x87_ld_frstor(6); eaaddr += 10;
|
||||
x87_ldmmx(&MM[7]); x87_ld_frstor(7);
|
||||
|
||||
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*/
|
||||
|
|
@ -160,14 +161,14 @@ static int FSAVE()
|
|||
}
|
||||
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));
|
||||
x87_st_fsave(0); eaaddr+=10;
|
||||
x87_st_fsave(1); eaaddr+=10;
|
||||
x87_st_fsave(2); eaaddr+=10;
|
||||
x87_st_fsave(3); eaaddr+=10;
|
||||
x87_st_fsave(4); eaaddr+=10;
|
||||
x87_st_fsave(5); eaaddr+=10;
|
||||
x87_st_fsave(6); eaaddr+=10;
|
||||
x87_st_fsave(7);
|
||||
}
|
||||
break;
|
||||
case 0x001: /*16-bit protected mode*/
|
||||
|
|
@ -192,14 +193,14 @@ static int FSAVE()
|
|||
}
|
||||
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));
|
||||
x87_st_fsave(0); eaaddr+=10;
|
||||
x87_st_fsave(1); eaaddr+=10;
|
||||
x87_st_fsave(2); eaaddr+=10;
|
||||
x87_st_fsave(3); eaaddr+=10;
|
||||
x87_st_fsave(4); eaaddr+=10;
|
||||
x87_st_fsave(5); eaaddr+=10;
|
||||
x87_st_fsave(6); eaaddr+=10;
|
||||
x87_st_fsave(7);
|
||||
}
|
||||
break;
|
||||
case 0x100: /*32-bit real mode*/
|
||||
|
|
@ -223,14 +224,14 @@ static int FSAVE()
|
|||
}
|
||||
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));
|
||||
x87_st_fsave(0); eaaddr+=10;
|
||||
x87_st_fsave(1); eaaddr+=10;
|
||||
x87_st_fsave(2); eaaddr+=10;
|
||||
x87_st_fsave(3); eaaddr+=10;
|
||||
x87_st_fsave(4); eaaddr+=10;
|
||||
x87_st_fsave(5); eaaddr+=10;
|
||||
x87_st_fsave(6); eaaddr+=10;
|
||||
x87_st_fsave(7);
|
||||
}
|
||||
break;
|
||||
case 0x101: /*32-bit protected mode*/
|
||||
|
|
@ -255,14 +256,14 @@ static int FSAVE()
|
|||
}
|
||||
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));
|
||||
x87_st_fsave(0); eaaddr+=10;
|
||||
x87_st_fsave(1); eaaddr+=10;
|
||||
x87_st_fsave(2); eaaddr+=10;
|
||||
x87_st_fsave(3); eaaddr+=10;
|
||||
x87_st_fsave(4); eaaddr+=10;
|
||||
x87_st_fsave(5); eaaddr+=10;
|
||||
x87_st_fsave(6); eaaddr+=10;
|
||||
x87_st_fsave(7);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -306,10 +307,17 @@ static int opFSTSW_a32(uint32_t fetchdat)
|
|||
|
||||
static int opFLD(uint32_t fetchdat)
|
||||
{
|
||||
int old_tag;
|
||||
uint64_t old_i64;
|
||||
|
||||
FP_ENTER();
|
||||
pc++;
|
||||
if (fplog) pclog("FLD %f\n", ST(fetchdat & 7));
|
||||
old_tag = tag[(TOP + fetchdat) & 7];
|
||||
old_i64 = ST_i64[(TOP + fetchdat) & 7];
|
||||
x87_push(ST(fetchdat&7));
|
||||
tag[TOP] = old_tag;
|
||||
ST_i64[TOP] = old_i64;
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -317,12 +325,21 @@ static int opFLD(uint32_t fetchdat)
|
|||
static int opFXCH(uint32_t fetchdat)
|
||||
{
|
||||
double td;
|
||||
uint8_t old_tag;
|
||||
uint64_t old_i64;
|
||||
FP_ENTER();
|
||||
pc++;
|
||||
if (fplog) pclog("FXCH\n");
|
||||
td = ST(0);
|
||||
ST(0) = ST(fetchdat&7);
|
||||
ST(fetchdat&7) = td;
|
||||
old_tag = tag[TOP];
|
||||
tag[TOP] = tag[(TOP + fetchdat) & 7];
|
||||
tag[(TOP + fetchdat) & 7] = old_tag;
|
||||
old_i64 = ST_i64[TOP];
|
||||
ST_i64[TOP] = ST_i64[(TOP + fetchdat) & 7];
|
||||
ST_i64[(TOP + fetchdat) & 7] = old_i64;
|
||||
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -333,6 +350,7 @@ static int opFCHS(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FCHS\n");
|
||||
ST(0) = -ST(0);
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(6);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -343,6 +361,7 @@ static int opFABS(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FABS %f\n", ST(0));
|
||||
ST(0) = fabs(ST(0));
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(3);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -450,6 +469,7 @@ static int opF2XM1(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("F2XM1\n");
|
||||
ST(0) = pow(2.0, ST(0)) - 1.0;
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(200);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -460,6 +480,7 @@ static int opFYL2X(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FYL2X\n");
|
||||
ST(1) = ST(1) * (log(ST(0)) / log(2.0));
|
||||
tag[(TOP + 1) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(250);
|
||||
return 0;
|
||||
|
|
@ -471,6 +492,7 @@ static int opFYL2XP1(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FYL2XP1\n");
|
||||
ST(1) = ST(1) * (log(ST(0)+1.0) / log(2.0));
|
||||
tag[(TOP + 1) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(250);
|
||||
return 0;
|
||||
|
|
@ -482,6 +504,7 @@ static int opFPTAN(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FPTAN\n");
|
||||
ST(0) = tan(ST(0));
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
x87_push(1.0);
|
||||
npxs &= ~C2;
|
||||
CLOCK_CYCLES(235);
|
||||
|
|
@ -494,6 +517,7 @@ static int opFPATAN(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FPATAN\n");
|
||||
ST(1) = atan2(ST(1), ST(0));
|
||||
tag[(TOP + 1) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(250);
|
||||
return 0;
|
||||
|
|
@ -527,6 +551,7 @@ static int opFPREM(uint32_t fetchdat)
|
|||
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);
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
if (fplog) pclog("%f\n", ST(0));
|
||||
npxs &= ~(C0|C1|C2|C3);
|
||||
if (temp64 & 4) npxs|=C0;
|
||||
|
|
@ -542,6 +567,7 @@ static int opFSQRT(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FSQRT\n");
|
||||
ST(0) = sqrt(ST(0));
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(83);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -554,6 +580,7 @@ static int opFSINCOS(uint32_t fetchdat)
|
|||
if (fplog) pclog("FSINCOS\n");
|
||||
td = ST(0);
|
||||
ST(0) = sin(td);
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
x87_push(cos(td));
|
||||
npxs &= ~C2;
|
||||
CLOCK_CYCLES(330);
|
||||
|
|
@ -566,6 +593,7 @@ static int opFRNDINT(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FRNDINT %g ", ST(0));
|
||||
ST(0) = (double)x87_fround(ST(0));
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
if (fplog) pclog("%g\n", ST(0));
|
||||
CLOCK_CYCLES(21);
|
||||
return 0;
|
||||
|
|
@ -579,6 +607,7 @@ static int opFSCALE(uint32_t fetchdat)
|
|||
if (fplog) pclog("FSCALE\n");
|
||||
temp64 = (int64_t)ST(1);
|
||||
ST(0) = ST(0) * pow(2.0, (double)temp64);
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(30);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -589,6 +618,7 @@ static int opFSIN(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FSIN\n");
|
||||
ST(0) = sin(ST(0));
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
npxs &= ~C2;
|
||||
CLOCK_CYCLES(300);
|
||||
return 0;
|
||||
|
|
@ -600,6 +630,7 @@ static int opFCOS(uint32_t fetchdat)
|
|||
pc++;
|
||||
if (fplog) pclog("FCOS\n");
|
||||
ST(0) = cos(ST(0));
|
||||
tag[TOP] &= ~TAG_UINT64;
|
||||
npxs &= ~C2;
|
||||
CLOCK_CYCLES(300);
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue