FPU copy should now work.

This commit is contained in:
TomW 2015-05-18 20:33:33 +01:00
commit 52a27a9256
7 changed files with 232 additions and 44 deletions

View file

@ -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);

View file

@ -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)

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;