clang format in cpu
This commit is contained in:
@@ -24,443 +24,446 @@
|
||||
#include <fenv.h>
|
||||
#include "x87_timings.h"
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FPU_LOG
|
||||
extern void fpu_log(const char *fmt, ...);
|
||||
extern void fpu_log(const char *fmt, ...);
|
||||
#else
|
||||
#ifndef fpu_log
|
||||
#define fpu_log(fmt, ...)
|
||||
#endif
|
||||
# ifndef fpu_log
|
||||
# define fpu_log(fmt, ...)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO};
|
||||
static int rounding_modes[4] = { FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO };
|
||||
|
||||
#define ST(x) cpu_state.ST[((cpu_state.TOP+(x))&7)]
|
||||
#define ST(x) cpu_state.ST[((cpu_state.TOP + (x)) & 7)]
|
||||
|
||||
#define C0 (1<<8)
|
||||
#define C1 (1<<9)
|
||||
#define C2 (1<<10)
|
||||
#define C3 (1<<14)
|
||||
#define C0 (1 << 8)
|
||||
#define C1 (1 << 9)
|
||||
#define C2 (1 << 10)
|
||||
#define C3 (1 << 14)
|
||||
|
||||
#define STATUS_ZERODIVIDE 4
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
|
||||
# define X87_INLINE_ASM
|
||||
# endif
|
||||
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
|
||||
# define X87_INLINE_ASM
|
||||
# endif
|
||||
#else
|
||||
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__
|
||||
# define X87_INLINE_ASM
|
||||
# endif
|
||||
# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__
|
||||
# define X87_INLINE_ASM
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef FPU_8087
|
||||
#define x87_div(dst, src1, src2) do \
|
||||
{ \
|
||||
if (((double)src2) == 0.0) \
|
||||
{ \
|
||||
cpu_state.npxs |= STATUS_ZERODIVIDE; \
|
||||
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
|
||||
dst = src1 / (double)src2; \
|
||||
else \
|
||||
{ \
|
||||
fpu_log("FPU : divide by zero\n"); \
|
||||
if (!(cpu_state.npxc & 0x80)) { \
|
||||
cpu_state.npxs |= 0x80; \
|
||||
nmi = 1; \
|
||||
} \
|
||||
return 1; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
dst = src1 / (double)src2; \
|
||||
# define x87_div(dst, src1, src2) \
|
||||
do { \
|
||||
if (((double) src2) == 0.0) { \
|
||||
cpu_state.npxs |= STATUS_ZERODIVIDE; \
|
||||
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
|
||||
dst = src1 / (double) src2; \
|
||||
else { \
|
||||
fpu_log("FPU : divide by zero\n"); \
|
||||
if (!(cpu_state.npxc & 0x80)) { \
|
||||
cpu_state.npxs |= 0x80; \
|
||||
nmi = 1; \
|
||||
} \
|
||||
return 1; \
|
||||
} \
|
||||
} else \
|
||||
dst = src1 / (double) src2; \
|
||||
} while (0)
|
||||
#else
|
||||
#define x87_div(dst, src1, src2) do \
|
||||
{ \
|
||||
if (((double)src2) == 0.0) \
|
||||
{ \
|
||||
cpu_state.npxs |= STATUS_ZERODIVIDE; \
|
||||
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
|
||||
dst = src1 / (double)src2; \
|
||||
else \
|
||||
{ \
|
||||
fpu_log("FPU : divide by zero\n"); \
|
||||
picint(1 << 13); \
|
||||
return 1; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
dst = src1 / (double)src2; \
|
||||
# define x87_div(dst, src1, src2) \
|
||||
do { \
|
||||
if (((double) src2) == 0.0) { \
|
||||
cpu_state.npxs |= STATUS_ZERODIVIDE; \
|
||||
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
|
||||
dst = src1 / (double) src2; \
|
||||
else { \
|
||||
fpu_log("FPU : divide by zero\n"); \
|
||||
picint(1 << 13); \
|
||||
return 1; \
|
||||
} \
|
||||
} else \
|
||||
dst = src1 / (double) src2; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static __inline void x87_checkexceptions(void)
|
||||
static __inline void
|
||||
x87_checkexceptions(void)
|
||||
{
|
||||
}
|
||||
|
||||
static __inline void x87_push(double i)
|
||||
static __inline void
|
||||
x87_push(double i)
|
||||
{
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.TOP--;
|
||||
cpu_state.TOP--;
|
||||
#else
|
||||
cpu_state.TOP=(cpu_state.TOP-1)&7;
|
||||
cpu_state.TOP = (cpu_state.TOP - 1) & 7;
|
||||
#endif
|
||||
cpu_state.ST[cpu_state.TOP&7] = i;
|
||||
cpu_state.ST[cpu_state.TOP & 7] = i;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
|
||||
#else
|
||||
cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? TAG_VALID : 0;
|
||||
cpu_state.tag[cpu_state.TOP & 7] = (i == 0.0) ? TAG_VALID : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline void x87_push_u64(uint64_t i)
|
||||
static __inline void
|
||||
x87_push_u64(uint64_t i)
|
||||
{
|
||||
union
|
||||
{
|
||||
double d;
|
||||
uint64_t ll;
|
||||
} td;
|
||||
union {
|
||||
double d;
|
||||
uint64_t ll;
|
||||
} td;
|
||||
|
||||
td.ll = i;
|
||||
td.ll = i;
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.TOP--;
|
||||
cpu_state.TOP--;
|
||||
#else
|
||||
cpu_state.TOP=(cpu_state.TOP-1)&7;
|
||||
cpu_state.TOP = (cpu_state.TOP - 1) & 7;
|
||||
#endif
|
||||
cpu_state.ST[cpu_state.TOP&7] = td.d;
|
||||
cpu_state.ST[cpu_state.TOP & 7] = td.d;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID;
|
||||
#else
|
||||
cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? TAG_VALID : 0;
|
||||
cpu_state.tag[cpu_state.TOP & 7] = (td.d == 0.0) ? TAG_VALID : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline double x87_pop(void)
|
||||
static __inline double
|
||||
x87_pop(void)
|
||||
{
|
||||
double t = cpu_state.ST[cpu_state.TOP&7];
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY;
|
||||
double t = cpu_state.ST[cpu_state.TOP & 7];
|
||||
cpu_state.tag[cpu_state.TOP & 7] = TAG_EMPTY;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.TOP++;
|
||||
cpu_state.TOP++;
|
||||
#else
|
||||
cpu_state.tag[cpu_state.TOP&7] |= TAG_UINT64;
|
||||
cpu_state.TOP=(cpu_state.TOP+1)&7;
|
||||
cpu_state.tag[cpu_state.TOP & 7] |= TAG_UINT64;
|
||||
cpu_state.TOP = (cpu_state.TOP + 1) & 7;
|
||||
#endif
|
||||
return t;
|
||||
return t;
|
||||
}
|
||||
|
||||
static __inline int16_t x87_fround16(double b)
|
||||
static __inline int16_t
|
||||
x87_fround16(double b)
|
||||
{
|
||||
int16_t a, c;
|
||||
int16_t a, c;
|
||||
|
||||
switch ((cpu_state.npxc >> 10) & 3)
|
||||
{
|
||||
case 0: /*Nearest*/
|
||||
a = (int16_t)floor(b);
|
||||
c = (int16_t)floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int16_t)floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int16_t)ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int16_t)b;
|
||||
}
|
||||
switch ((cpu_state.npxc >> 10) & 3) {
|
||||
case 0: /*Nearest*/
|
||||
a = (int16_t) floor(b);
|
||||
c = (int16_t) floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int16_t) floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int16_t) ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int16_t) b;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline int64_t x87_fround16_64(double b)
|
||||
static __inline int64_t
|
||||
x87_fround16_64(double b)
|
||||
{
|
||||
return (int64_t) x87_fround16(b);
|
||||
}
|
||||
|
||||
static __inline int32_t x87_fround32(double b)
|
||||
static __inline int32_t
|
||||
x87_fround32(double b)
|
||||
{
|
||||
int32_t a, c;
|
||||
int32_t a, c;
|
||||
|
||||
switch ((cpu_state.npxc >> 10) & 3)
|
||||
{
|
||||
case 0: /*Nearest*/
|
||||
a = (int32_t)floor(b);
|
||||
c = (int32_t)floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int32_t)floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int32_t)ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int32_t)b;
|
||||
}
|
||||
switch ((cpu_state.npxc >> 10) & 3) {
|
||||
case 0: /*Nearest*/
|
||||
a = (int32_t) floor(b);
|
||||
c = (int32_t) floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int32_t) floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int32_t) ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int32_t) b;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline int64_t x87_fround32_64(double b)
|
||||
static __inline int64_t
|
||||
x87_fround32_64(double b)
|
||||
{
|
||||
return (int64_t) x87_fround32(b);
|
||||
}
|
||||
|
||||
static __inline int64_t x87_fround(double b)
|
||||
static __inline int64_t
|
||||
x87_fround(double b)
|
||||
{
|
||||
int64_t a, c;
|
||||
int64_t a, c;
|
||||
|
||||
switch ((cpu_state.npxc >> 10) & 3)
|
||||
{
|
||||
case 0: /*Nearest*/
|
||||
a = (int64_t)floor(b);
|
||||
c = (int64_t)floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int64_t)floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int64_t)ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int64_t)b;
|
||||
}
|
||||
switch ((cpu_state.npxc >> 10) & 3) {
|
||||
case 0: /*Nearest*/
|
||||
a = (int64_t) floor(b);
|
||||
c = (int64_t) floor(b + 1.0);
|
||||
if ((b - a) < (c - b))
|
||||
return a;
|
||||
else if ((b - a) > (c - b))
|
||||
return c;
|
||||
else
|
||||
return (a & 1) ? c : a;
|
||||
case 1: /*Down*/
|
||||
return (int64_t) floor(b);
|
||||
case 2: /*Up*/
|
||||
return (int64_t) ceil(b);
|
||||
case 3: /*Chop*/
|
||||
return (int64_t) b;
|
||||
}
|
||||
|
||||
return 0LL;
|
||||
return 0LL;
|
||||
}
|
||||
|
||||
#include "x87_ops_conv.h"
|
||||
|
||||
static __inline double x87_ld80(void)
|
||||
static __inline double
|
||||
x87_ld80(void)
|
||||
{
|
||||
x87_conv_t test;
|
||||
test.eind.ll = readmeml(easeg,cpu_state.eaaddr);
|
||||
test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32;
|
||||
test.begin = readmemw(easeg,cpu_state.eaaddr+8);
|
||||
return x87_from80(&test);
|
||||
x87_conv_t test;
|
||||
test.eind.ll = readmeml(easeg, cpu_state.eaaddr);
|
||||
test.eind.ll |= (uint64_t) readmeml(easeg, cpu_state.eaaddr + 4) << 32;
|
||||
test.begin = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
return x87_from80(&test);
|
||||
}
|
||||
|
||||
static __inline void x87_st80(double d)
|
||||
static __inline void
|
||||
x87_st80(double d)
|
||||
{
|
||||
x87_conv_t test;
|
||||
x87_to80(d, &test);
|
||||
writememl(easeg,cpu_state.eaaddr,test.eind.ll & 0xffffffff);
|
||||
writememl(easeg,cpu_state.eaaddr+4,test.eind.ll>>32);
|
||||
writememw(easeg,cpu_state.eaaddr+8,test.begin);
|
||||
x87_conv_t test;
|
||||
x87_to80(d, &test);
|
||||
writememl(easeg, cpu_state.eaaddr, test.eind.ll & 0xffffffff);
|
||||
writememl(easeg, cpu_state.eaaddr + 4, test.eind.ll >> 32);
|
||||
writememw(easeg, cpu_state.eaaddr + 8, test.begin);
|
||||
}
|
||||
|
||||
static __inline void x87_st_fsave(int reg)
|
||||
static __inline void
|
||||
x87_st_fsave(int reg)
|
||||
{
|
||||
reg = (cpu_state.TOP + reg) & 7;
|
||||
reg = (cpu_state.TOP + reg) & 7;
|
||||
|
||||
if (cpu_state.tag[reg] & TAG_UINT64)
|
||||
{
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff);
|
||||
writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32);
|
||||
writememw(easeg, cpu_state.eaaddr + 8, 0x5555);
|
||||
}
|
||||
else
|
||||
x87_st80(cpu_state.ST[reg]);
|
||||
if (cpu_state.tag[reg] & TAG_UINT64) {
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff);
|
||||
writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32);
|
||||
writememw(easeg, cpu_state.eaaddr + 8, 0x5555);
|
||||
} else
|
||||
x87_st80(cpu_state.ST[reg]);
|
||||
}
|
||||
|
||||
static __inline void x87_ld_frstor(int reg)
|
||||
static __inline void
|
||||
x87_ld_frstor(int reg)
|
||||
{
|
||||
reg = (cpu_state.TOP + reg) & 7;
|
||||
reg = (cpu_state.TOP + reg) & 7;
|
||||
|
||||
cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr);
|
||||
cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr);
|
||||
cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64))
|
||||
if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64))
|
||||
#else
|
||||
if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] == 2))
|
||||
if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] == 2))
|
||||
#endif
|
||||
{
|
||||
{
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
cpu_state.tag[reg] = TAG_UINT64;
|
||||
cpu_state.tag[reg] = TAG_UINT64;
|
||||
#endif
|
||||
cpu_state.ST[reg] = (double)cpu_state.MM[reg].q;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.ST[reg] = (double) cpu_state.MM[reg].q;
|
||||
} else {
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.tag[reg] &= ~TAG_UINT64;
|
||||
cpu_state.tag[reg] &= ~TAG_UINT64;
|
||||
#endif
|
||||
cpu_state.ST[reg] = x87_ld80();
|
||||
}
|
||||
cpu_state.ST[reg] = x87_ld80();
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void x87_ldmmx(MMX_REG *r, uint16_t *w4)
|
||||
static __inline void
|
||||
x87_ldmmx(MMX_REG *r, uint16_t *w4)
|
||||
{
|
||||
r->l[0] = readmeml(easeg, cpu_state.eaaddr);
|
||||
r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4);
|
||||
*w4 = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
r->l[0] = readmeml(easeg, cpu_state.eaaddr);
|
||||
r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4);
|
||||
*w4 = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
}
|
||||
|
||||
static __inline void x87_stmmx(MMX_REG r)
|
||||
static __inline void
|
||||
x87_stmmx(MMX_REG r)
|
||||
{
|
||||
writememl(easeg, cpu_state.eaaddr, r.l[0]);
|
||||
writememl(easeg, cpu_state.eaaddr + 4, r.l[1]);
|
||||
writememw(easeg, cpu_state.eaaddr + 8, 0xffff);
|
||||
writememl(easeg, cpu_state.eaaddr, r.l[0]);
|
||||
writememl(easeg, cpu_state.eaaddr + 4, r.l[1]);
|
||||
writememw(easeg, cpu_state.eaaddr + 8, 0xffff);
|
||||
}
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
static __inline uint16_t x87_compare(double a, double b)
|
||||
static __inline uint16_t
|
||||
x87_compare(double a, double b)
|
||||
{
|
||||
#ifdef X87_INLINE_ASM
|
||||
uint32_t result;
|
||||
double ea = a, eb = b;
|
||||
const uint64_t ia = 0x3fec1a6ff866a936ull;
|
||||
const uint64_t ib = 0x3fec1a6ff866a938ull;
|
||||
uint32_t result;
|
||||
double ea = a, eb = b;
|
||||
const uint64_t ia = 0x3fec1a6ff866a936ull;
|
||||
const uint64_t ib = 0x3fec1a6ff866a938ull;
|
||||
|
||||
/* Hack to make CHKCOP happy. */
|
||||
if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8))
|
||||
return C3;
|
||||
/* Hack to make CHKCOP happy. */
|
||||
if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8))
|
||||
return C3;
|
||||
|
||||
if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) &&
|
||||
((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||
eb = ea;
|
||||
if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||
eb = ea;
|
||||
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
/* Memory barrier, to force GCC to write to the input parameters
|
||||
* before the compare rather than after */
|
||||
__asm volatile ("" : : : "memory");
|
||||
# if !defined(_MSC_VER) || defined(__clang__)
|
||||
/* Memory barrier, to force GCC to write to the input parameters
|
||||
* before the compare rather than after */
|
||||
__asm volatile(""
|
||||
:
|
||||
:
|
||||
: "memory");
|
||||
|
||||
__asm(
|
||||
"fldl %2\n"
|
||||
"fldl %1\n"
|
||||
"fclex\n"
|
||||
"fcompp\n"
|
||||
"fnstsw %0\n"
|
||||
: "=m" (result)
|
||||
: "m" (ea), "m" (eb)
|
||||
);
|
||||
#else
|
||||
_ReadWriteBarrier();
|
||||
_asm
|
||||
{
|
||||
__asm(
|
||||
"fldl %2\n"
|
||||
"fldl %1\n"
|
||||
"fclex\n"
|
||||
"fcompp\n"
|
||||
"fnstsw %0\n"
|
||||
: "=m"(result)
|
||||
: "m"(ea), "m"(eb));
|
||||
# else
|
||||
_ReadWriteBarrier();
|
||||
_asm
|
||||
{
|
||||
fld eb
|
||||
fld ea
|
||||
fclex
|
||||
fcompp
|
||||
fnstsw result
|
||||
}
|
||||
#endif
|
||||
}
|
||||
# endif
|
||||
|
||||
return result & (C0|C2|C3);
|
||||
return result & (C0 | C2 | C3);
|
||||
#else
|
||||
/* Generic C version is known to give incorrect results in some
|
||||
* situations, eg comparison of infinity (Unreal) */
|
||||
uint32_t result = 0;
|
||||
double ea = a, eb = b;
|
||||
/* Generic C version is known to give incorrect results in some
|
||||
* situations, eg comparison of infinity (Unreal) */
|
||||
uint32_t result = 0;
|
||||
double ea = a, eb = b;
|
||||
|
||||
if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) &&
|
||||
((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||
eb = ea;
|
||||
if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||
eb = ea;
|
||||
|
||||
if (ea == eb)
|
||||
result |= C3;
|
||||
else if (ea < eb)
|
||||
result |= C0;
|
||||
if (ea == eb)
|
||||
result |= C3;
|
||||
else if (ea < eb)
|
||||
result |= C0;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline uint16_t x87_ucompare(double a, double b)
|
||||
static __inline uint16_t
|
||||
x87_ucompare(double a, double b)
|
||||
{
|
||||
#ifdef X87_INLINE_ASM
|
||||
uint32_t result;
|
||||
uint32_t result;
|
||||
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
/* Memory barrier, to force GCC to write to the input parameters
|
||||
* before the compare rather than after */
|
||||
__asm volatile ("" : : : "memory");
|
||||
# if !defined(_MSC_VER) || defined(__clang__)
|
||||
/* Memory barrier, to force GCC to write to the input parameters
|
||||
* before the compare rather than after */
|
||||
__asm volatile(""
|
||||
:
|
||||
:
|
||||
: "memory");
|
||||
|
||||
__asm(
|
||||
"fldl %2\n"
|
||||
"fldl %1\n"
|
||||
"fclex\n"
|
||||
"fucompp\n"
|
||||
"fnstsw %0\n"
|
||||
: "=m" (result)
|
||||
: "m" (a), "m" (b)
|
||||
);
|
||||
#else
|
||||
_ReadWriteBarrier();
|
||||
_asm
|
||||
{
|
||||
__asm(
|
||||
"fldl %2\n"
|
||||
"fldl %1\n"
|
||||
"fclex\n"
|
||||
"fucompp\n"
|
||||
"fnstsw %0\n"
|
||||
: "=m"(result)
|
||||
: "m"(a), "m"(b));
|
||||
# else
|
||||
_ReadWriteBarrier();
|
||||
_asm
|
||||
{
|
||||
fld b
|
||||
fld a
|
||||
fclex
|
||||
fcompp
|
||||
fnstsw result
|
||||
}
|
||||
#endif
|
||||
}
|
||||
# endif
|
||||
|
||||
return result & (C0|C2|C3);
|
||||
return result & (C0 | C2 | C3);
|
||||
#else
|
||||
/* Generic C version is known to give incorrect results in some
|
||||
* situations, eg comparison of infinity (Unreal) */
|
||||
uint32_t result = 0;
|
||||
/* Generic C version is known to give incorrect results in some
|
||||
* situations, eg comparison of infinity (Unreal) */
|
||||
uint32_t result = 0;
|
||||
|
||||
if (a == b)
|
||||
result |= C3;
|
||||
else if (a < b)
|
||||
result |= C0;
|
||||
if (a == b)
|
||||
result |= C3;
|
||||
else if (a < b)
|
||||
result |= C0;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef union
|
||||
{
|
||||
float s;
|
||||
uint32_t i;
|
||||
typedef union {
|
||||
float s;
|
||||
uint32_t i;
|
||||
} x87_ts;
|
||||
|
||||
typedef union
|
||||
{
|
||||
double d;
|
||||
uint64_t i;
|
||||
typedef union {
|
||||
double d;
|
||||
uint64_t i;
|
||||
} x87_td;
|
||||
|
||||
#ifdef FPU_8087
|
||||
#define FP_ENTER() { \
|
||||
}
|
||||
# define FP_ENTER() \
|
||||
{ \
|
||||
}
|
||||
#else
|
||||
#define FP_ENTER() do \
|
||||
{ \
|
||||
if (cr0 & 0xc) \
|
||||
{ \
|
||||
x86_int(7); \
|
||||
return 1; \
|
||||
} \
|
||||
# define FP_ENTER() \
|
||||
do { \
|
||||
if (cr0 & 0xc) { \
|
||||
x86_int(7); \
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP&7] = TAG_VALID
|
||||
# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID
|
||||
# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64
|
||||
# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID
|
||||
# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID
|
||||
# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID
|
||||
# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID | TAG_UINT64
|
||||
# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID
|
||||
#else
|
||||
# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64
|
||||
# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64
|
||||
# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP] |= TAG_UINT64;
|
||||
# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64
|
||||
# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64
|
||||
# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64
|
||||
# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP] |= TAG_UINT64;
|
||||
# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64
|
||||
#endif
|
||||
|
||||
#include "x87_ops_arith.h"
|
||||
@@ -468,56 +471,55 @@ typedef union
|
||||
#include "x87_ops_loadstore.h"
|
||||
|
||||
#ifndef FPU_8087
|
||||
static int op_nofpu_a16(uint32_t fetchdat)
|
||||
static int
|
||||
op_nofpu_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (cr0 & 0xc)
|
||||
{
|
||||
x86_int(7);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
return 0;
|
||||
}
|
||||
if (cr0 & 0xc) {
|
||||
x86_int(7);
|
||||
return 1;
|
||||
} else {
|
||||
fetch_ea_16(fetchdat);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static int op_nofpu_a32(uint32_t fetchdat)
|
||||
static int
|
||||
op_nofpu_a32(uint32_t fetchdat)
|
||||
{
|
||||
if (cr0 & 0xc)
|
||||
{
|
||||
x86_int(7);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
return 0;
|
||||
}
|
||||
if (cr0 & 0xc) {
|
||||
x86_int(7);
|
||||
return 1;
|
||||
} else {
|
||||
fetch_ea_32(fetchdat);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FPU_8087
|
||||
static int FPU_ILLEGAL_a16(uint32_t fetchdat)
|
||||
static int
|
||||
FPU_ILLEGAL_a16(uint32_t fetchdat)
|
||||
{
|
||||
geteaw();
|
||||
wait(timing_rr, 0);
|
||||
return 0;
|
||||
geteaw();
|
||||
wait(timing_rr, 0);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int FPU_ILLEGAL_a16(uint32_t fetchdat)
|
||||
static int
|
||||
FPU_ILLEGAL_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
fetch_ea_16(fetchdat);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FPU_ILLEGAL_a32(uint32_t fetchdat)
|
||||
static int
|
||||
FPU_ILLEGAL_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
fetch_ea_32(fetchdat);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -774,7 +776,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] =
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
};
|
||||
#else
|
||||
#define ILLEGAL_a32 FPU_ILLEGAL_a32
|
||||
# define ILLEGAL_a32 FPU_ILLEGAL_a32
|
||||
|
||||
const OpFn OP_TABLE(fpu_d8_a16)[32] =
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user