Cleaned up x87 tag register handling.
This commit is contained in:
parent
e9ff110021
commit
dbb01ef9e2
6 changed files with 82 additions and 63 deletions
34
src/x87.c
34
src/x87.c
|
|
@ -19,6 +19,11 @@
|
|||
#include "x87.h"
|
||||
#include "386_common.h"
|
||||
|
||||
#define X87_TAG_VALID 0
|
||||
#define X87_TAG_ZERO 1
|
||||
#define X87_TAG_INVALID 2
|
||||
#define X87_TAG_EMPTY 3
|
||||
|
||||
uint16_t x87_gettag()
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
|
|
@ -26,10 +31,14 @@ uint16_t x87_gettag()
|
|||
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
if (cpu_state.tag[c] & TAG_UINT64)
|
||||
if (cpu_state.tag[c] == TAG_EMPTY)
|
||||
ret |= X87_TAG_EMPTY << (c * 2);
|
||||
else if (cpu_state.tag[c] & TAG_UINT64)
|
||||
ret |= 2 << (c*2);
|
||||
else if (cpu_state.ST[c] == 0.0)
|
||||
ret |= X87_TAG_ZERO << (c * 2);
|
||||
else
|
||||
ret |= (cpu_state.tag[c] << (c*2));
|
||||
ret |= X87_TAG_VALID << (c * 2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -37,14 +46,19 @@ uint16_t x87_gettag()
|
|||
|
||||
void x87_settag(uint16_t new_tag)
|
||||
{
|
||||
cpu_state.tag[0] = new_tag & 3;
|
||||
cpu_state.tag[1] = (new_tag >> 2) & 3;
|
||||
cpu_state.tag[2] = (new_tag >> 4) & 3;
|
||||
cpu_state.tag[3] = (new_tag >> 6) & 3;
|
||||
cpu_state.tag[4] = (new_tag >> 8) & 3;
|
||||
cpu_state.tag[5] = (new_tag >> 10) & 3;
|
||||
cpu_state.tag[6] = (new_tag >> 12) & 3;
|
||||
cpu_state.tag[7] = (new_tag >> 14) & 3;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
int tag = (new_tag >> (c * 2)) & 3;
|
||||
|
||||
if (tag == X87_TAG_EMPTY)
|
||||
cpu_state.tag[c] = TAG_EMPTY;
|
||||
else if (tag == 2)
|
||||
cpu_state.tag[c] = TAG_VALID | TAG_UINT64;
|
||||
else
|
||||
cpu_state.tag[c] = TAG_VALID;
|
||||
}
|
||||
}
|
||||
|
||||
void x87_dumpregs()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ static inline void x87_set_mmx()
|
|||
|
||||
static inline void x87_emms()
|
||||
{
|
||||
*(uint64_t *)cpu_state.tag = 0x0303030303030303ll;
|
||||
*(uint64_t *)cpu_state.tag = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
}
|
||||
|
||||
|
|
@ -19,5 +19,8 @@ void x87_settag(uint16_t new_tag);
|
|||
void x87_dumpregs();
|
||||
void x87_reset();
|
||||
|
||||
#define TAG_EMPTY 0
|
||||
#define TAG_VALID (1 << 0)
|
||||
/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/
|
||||
#define TAG_UINT64 (1 << 2)
|
||||
#define TAG_UINT64 (1 << 7)
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ static inline void x87_push(double i)
|
|||
{
|
||||
cpu_state.TOP=(cpu_state.TOP-1)&7;
|
||||
cpu_state.ST[cpu_state.TOP] = i;
|
||||
cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? 1 : 0;
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
}
|
||||
|
||||
static inline void x87_push_u64(uint64_t i)
|
||||
|
|
@ -55,13 +55,13 @@ static inline void x87_push_u64(uint64_t i)
|
|||
|
||||
cpu_state.TOP=(cpu_state.TOP-1)&7;
|
||||
cpu_state.ST[cpu_state.TOP] = td.d;
|
||||
cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? 1 : 0;
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
}
|
||||
|
||||
static inline double x87_pop()
|
||||
{
|
||||
double t = cpu_state.ST[cpu_state.TOP];
|
||||
cpu_state.tag[cpu_state.TOP&7] = 3;
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY;
|
||||
cpu_state.TOP=(cpu_state.TOP+1)&7;
|
||||
return t;
|
||||
}
|
||||
|
|
@ -186,13 +186,15 @@ static inline void x87_ld_frstor(int reg)
|
|||
cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr);
|
||||
cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
|
||||
if (cpu_state.MM_w4[reg] == 0x5555 && cpu_state.tag[reg] == 2)
|
||||
if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64))
|
||||
{
|
||||
cpu_state.tag[reg] = TAG_UINT64;
|
||||
cpu_state.ST[reg] = (double)cpu_state.MM[reg].q;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.tag[reg] = TAG_VALID;
|
||||
cpu_state.ST[reg] = x87_ld80();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void x87_ldmmx(MMX_REG *r, uint16_t *w4)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
ST(0) += use_var; \
|
||||
if ((cpu_state.npxc >> 10) & 3) \
|
||||
fesetround(FE_TONEAREST); \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
} \
|
||||
|
|
@ -48,7 +48,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
x87_div(ST(0), ST(0), use_var); \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID; \
|
||||
CLOCK_CYCLES(73); \
|
||||
return 0; \
|
||||
} \
|
||||
|
|
@ -60,7 +60,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
x87_div(ST(0), use_var, ST(0)); \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID; \
|
||||
CLOCK_CYCLES(73); \
|
||||
return 0; \
|
||||
} \
|
||||
|
|
@ -72,7 +72,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) *= use_var; \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID; \
|
||||
CLOCK_CYCLES(11); \
|
||||
return 0; \
|
||||
} \
|
||||
|
|
@ -84,7 +84,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) -= use_var; \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
} \
|
||||
|
|
@ -96,7 +96,7 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \
|
|||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) = use_var - ST(0); \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
}
|
||||
|
|
@ -121,7 +121,7 @@ static int opFADD(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FADD\n");
|
||||
ST(0) = ST(0) + ST(fetchdat & 7);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -131,7 +131,7 @@ static int opFADDr(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FADD\n");
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ static int opFADDP(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FADDP\n");
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
|
|
@ -232,7 +232,7 @@ static int opFDIV(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FDIV\n");
|
||||
x87_div(ST(0), ST(0), ST(fetchdat & 7));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -242,7 +242,7 @@ static int opFDIVr(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FDIV\n");
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -252,7 +252,7 @@ static int opFDIVP(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FDIVP\n");
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
|
|
@ -264,7 +264,7 @@ static int opFDIVR(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FDIVR\n");
|
||||
x87_div(ST(0), ST(fetchdat&7), ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -274,7 +274,7 @@ static int opFDIVRr(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FDIVR\n");
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -284,7 +284,7 @@ static int opFDIVRP(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FDIVR\n");
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
|
|
@ -296,7 +296,7 @@ static int opFMUL(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FMUL\n");
|
||||
ST(0) = ST(0) * ST(fetchdat & 7);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
CLOCK_CYCLES(16);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -306,7 +306,7 @@ static int opFMULr(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FMUL\n");
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
CLOCK_CYCLES(16);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -316,7 +316,7 @@ static int opFMULP(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FMULP\n");
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(16);
|
||||
return 0;
|
||||
|
|
@ -328,7 +328,7 @@ static int opFSUB(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FSUB\n");
|
||||
ST(0) = ST(0) - ST(fetchdat & 7);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -338,7 +338,7 @@ static int opFSUBr(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FSUB\n");
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -348,7 +348,7 @@ static int opFSUBP(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FSUBP\n");
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
|
|
@ -360,7 +360,7 @@ static int opFSUBR(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FSUBR\n");
|
||||
ST(0) = ST(fetchdat & 7) - ST(0);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -370,7 +370,7 @@ static int opFSUBRr(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FSUBR\n");
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -380,7 +380,7 @@ static int opFSUBRP(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FSUBRP\n");
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ static int opFILDiq_a16(uint32_t fetchdat)
|
|||
if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4));
|
||||
x87_push((double)temp64);
|
||||
cpu_state.MM[cpu_state.TOP].q = temp64;
|
||||
cpu_state.tag[cpu_state.TOP] |= TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID | TAG_UINT64;
|
||||
|
||||
CLOCK_CYCLES(10);
|
||||
return 0;
|
||||
|
|
@ -112,7 +112,7 @@ static int opFILDiq_a32(uint32_t fetchdat)
|
|||
if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4));
|
||||
x87_push((double)temp64);
|
||||
cpu_state.MM[cpu_state.TOP].q = temp64;
|
||||
cpu_state.tag[cpu_state.TOP] |= TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID | TAG_UINT64;
|
||||
|
||||
CLOCK_CYCLES(10);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ static int opFINIT(uint32_t fetchdat)
|
|||
cpu_state.npxc = 0x37F;
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00);
|
||||
cpu_state.npxs = 0;
|
||||
*(uint64_t *)cpu_state.tag = 0x0303030303030303ll;
|
||||
*(uint64_t *)cpu_state.tag = 0;
|
||||
cpu_state.TOP = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
CLOCK_CYCLES(17);
|
||||
|
|
@ -47,7 +47,7 @@ static int opFFREE(uint32_t fetchdat)
|
|||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
if (fplog) pclog("FFREE\n");
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY;
|
||||
CLOCK_CYCLES(3);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -278,7 +278,7 @@ static int FSAVE()
|
|||
cpu_state.npxc = 0x37F;
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00);
|
||||
cpu_state.npxs = 0;
|
||||
*(uint64_t *)cpu_state.tag = 0x0303030303030303ll;
|
||||
*(uint64_t *)cpu_state.tag = 0;
|
||||
cpu_state.TOP = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
|
||||
|
|
@ -369,7 +369,7 @@ static int opFCHS(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FCHS\n");
|
||||
ST(0) = -ST(0);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
CLOCK_CYCLES(6);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -380,7 +380,7 @@ static int opFABS(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FABS %f\n", ST(0));
|
||||
ST(0) = fabs(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
CLOCK_CYCLES(3);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -403,7 +403,7 @@ static int opFXAM(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FXAM %i %f\n", cpu_state.tag[cpu_state.TOP&7], ST(0));
|
||||
cpu_state.npxs &= ~(C0|C1|C2|C3);
|
||||
if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3);
|
||||
if (cpu_state.tag[cpu_state.TOP&7] == TAG_EMPTY) cpu_state.npxs |= (C0|C3);
|
||||
else if (ST(0) == 0.0) cpu_state.npxs |= C3;
|
||||
else cpu_state.npxs |= C2;
|
||||
if (ST(0) < 0.0) cpu_state.npxs |= C1;
|
||||
|
|
@ -477,7 +477,7 @@ static int opFLDZ(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FLDZ\n");
|
||||
x87_push(0.0);
|
||||
cpu_state.tag[cpu_state.TOP&7] = 1;
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -488,7 +488,7 @@ static int opF2XM1(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("F2XM1\n");
|
||||
ST(0) = pow(2.0, ST(0)) - 1.0;
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
CLOCK_CYCLES(200);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -499,7 +499,7 @@ static int opFYL2X(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FYL2X\n");
|
||||
ST(1) = ST(1) * (log(ST(0)) / log(2.0));
|
||||
cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(250);
|
||||
return 0;
|
||||
|
|
@ -511,7 +511,7 @@ static int opFYL2XP1(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FYL2XP1\n");
|
||||
ST(1) = ST(1) * (log(ST(0)+1.0) / log(2.0));
|
||||
cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(250);
|
||||
return 0;
|
||||
|
|
@ -523,7 +523,7 @@ static int opFPTAN(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FPTAN\n");
|
||||
ST(0) = tan(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
x87_push(1.0);
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(235);
|
||||
|
|
@ -536,7 +536,7 @@ static int opFPATAN(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FPATAN\n");
|
||||
ST(1) = atan2(ST(1), ST(0));
|
||||
cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64;
|
||||
cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(250);
|
||||
return 0;
|
||||
|
|
@ -570,7 +570,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);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
if (fplog) pclog("%f\n", ST(0));
|
||||
cpu_state.npxs &= ~(C0|C1|C2|C3);
|
||||
if (temp64 & 4) cpu_state.npxs|=C0;
|
||||
|
|
@ -587,7 +587,7 @@ static int opFPREM1(uint32_t fetchdat)
|
|||
if (fplog) pclog("FPREM1 %f %f ", ST(0), ST(1));
|
||||
temp64 = (int64_t)(ST(0) / ST(1));
|
||||
ST(0) = ST(0) - (ST(1) * (double)temp64);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
if (fplog) pclog("%f\n", ST(0));
|
||||
cpu_state.npxs &= ~(C0|C1|C2|C3);
|
||||
if (temp64 & 4) cpu_state.npxs|=C0;
|
||||
|
|
@ -603,7 +603,7 @@ static int opFSQRT(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FSQRT\n");
|
||||
ST(0) = sqrt(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
CLOCK_CYCLES(83);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -616,7 +616,7 @@ static int opFSINCOS(uint32_t fetchdat)
|
|||
if (fplog) pclog("FSINCOS\n");
|
||||
td = ST(0);
|
||||
ST(0) = sin(td);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
x87_push(cos(td));
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(330);
|
||||
|
|
@ -629,7 +629,7 @@ static int opFRNDINT(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FRNDINT %g ", ST(0));
|
||||
ST(0) = (double)x87_fround(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
if (fplog) pclog("%g\n", ST(0));
|
||||
CLOCK_CYCLES(21);
|
||||
return 0;
|
||||
|
|
@ -643,7 +643,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);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
CLOCK_CYCLES(30);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -654,7 +654,7 @@ static int opFSIN(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FSIN\n");
|
||||
ST(0) = sin(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(300);
|
||||
return 0;
|
||||
|
|
@ -666,7 +666,7 @@ static int opFCOS(uint32_t fetchdat)
|
|||
cpu_state.pc++;
|
||||
if (fplog) pclog("FCOS\n");
|
||||
ST(0) = cos(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.tag[cpu_state.TOP] = TAG_VALID;
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(300);
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue