1
0
Fork 0

remove more fpu exception flags and refine fpu statusword updates;

add a more direct calling of fpu functions (dynamic core, thanks to kekko!);
avoid temporary storing of fpu values for eatree functions (x86 fpu only)


Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2644
This commit is contained in:
Sebastian Strohhäcker 2006-06-01 08:33:52 +00:00
parent 7312606796
commit 3500ea88eb
8 changed files with 657 additions and 105 deletions

View file

@ -40,4 +40,115 @@ void FPU_ESC6_EA(Bitu func,PhysPt ea);
void FPU_ESC7_Normal(Bitu rm);
void FPU_ESC7_EA(Bitu func,PhysPt ea);
typedef union {
double d;
#ifndef WORDS_BIGENDIAN
struct {
Bit32u lower;
Bit32s upper;
} l;
#else
struct {
Bit32s upper;
Bit32u lower;
} l;
#endif
Bit64s ll;
} FPU_Reg;
typedef struct {
Bit32u m1;
Bit32u m2;
Bit16u m3;
Bit16u d1;
Bit32u d2;
} FPU_P_Reg;
enum FPU_Tag {
TAG_Valid = 0,
TAG_Zero = 1,
TAG_Weird = 2,
TAG_Empty = 3
};
enum FPU_Round {
ROUND_Nearest = 0,
ROUND_Down = 1,
ROUND_Up = 2,
ROUND_Chop = 3
};
typedef struct {
FPU_Reg regs[9];
FPU_P_Reg p_regs[9];
FPU_Tag tags[9];
Bit16u cw,cw_mask_all;
Bit16u sw;
Bitu top;
FPU_Round round;
} FPU_rec;
//get pi from a real library
#define PI 3.14159265358979323846
#define L2E 1.4426950408889634
#define L2T 3.3219280948873623
#define LN2 0.69314718055994531
#define LG2 0.3010299956639812
extern FPU_rec fpu;
#define TOP fpu.top
#define STV(i) ( (fpu.top+ (i) ) & 7 )
Bit16u FPU_GetTag(void);
void FPU_FLDCW(PhysPt addr);
INLINE void FPU_SetTag(Bit16u tag){
for(Bitu i=0;i<8;i++)
fpu.tags[i] = static_cast<FPU_Tag>((tag >>(2*i))&3);
}
INLINE void FPU_SetCW(Bitu word){
fpu.cw = word;
fpu.cw_mask_all = word | 0x3f;
fpu.round = (FPU_Round)((word >> 10) & 3);
}
INLINE Bitu FPU_GET_TOP(void) {
return (fpu.sw & 0x3800)>>11;
}
INLINE void FPU_SET_TOP(Bitu val){
fpu.sw &= ~0x3800;
fpu.sw |= (val&7)<<11;
}
INLINE void FPU_SET_C0(Bitu C){
fpu.sw &= ~0x0100;
if(C) fpu.sw |= 0x0100;
}
INLINE void FPU_SET_C1(Bitu C){
fpu.sw &= ~0x0200;
if(C) fpu.sw |= 0x0200;
}
INLINE void FPU_SET_C2(Bitu C){
fpu.sw &= ~0x0400;
if(C) fpu.sw |= 0x0400;
}
INLINE void FPU_SET_C3(Bitu C){
fpu.sw &= ~0x4000;
if(C) fpu.sw |= 0x4000;
}
#endif

View file

@ -1 +1,2 @@
noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h
noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h \
dyn_fpu.h

View file

@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define X86_DYNFPU
#include "fpu.h"
#define DYN_FPU_ESC(code) { \
dyn_get_modrm(); \
@ -1223,6 +1225,10 @@ static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) {
}
}
#ifdef X86_DYNFPU
#include "dyn_fpu.h"
#endif
static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bitu max_opcodes) {
Bits i;
/* Init a load of variables */
@ -1568,6 +1574,32 @@ restart_prefix:
case 0xd3:dyn_grp2_ev(grp2_cl);break;
//FPU
#ifdef CPU_FPU
#ifdef X86_DYNFPU
case 0xd8:
dyn_fpu_esc0();
break;
case 0xd9:
dyn_fpu_esc1();
break;
case 0xda:
dyn_fpu_esc2();
break;
case 0xdb:
dyn_fpu_esc3();
break;
case 0xdc:
dyn_fpu_esc4();
break;
case 0xdd:
dyn_fpu_esc5();
break;
case 0xde:
dyn_fpu_esc6();
break;
case 0xdf:
dyn_fpu_esc7();
break;
#else
case 0xd8:
DYN_FPU_ESC(0);
break;
@ -1600,6 +1632,7 @@ restart_prefix:
gen_releasereg(DREG(EA));
}
break;
#endif
#endif
//Loop's
case 0xe2:dyn_loop(LOOP_NONE);goto finish_block;

View file

@ -1,5 +1,5 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libfpu.a
libfpu_a_SOURCES = fpu.cpp fpu_types.h fpu_instructions.h \
libfpu_a_SOURCES = fpu.cpp fpu_instructions.h \
fpu_instructions_x86.h

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: fpu.cpp,v 1.27 2006-02-09 11:47:48 qbix79 Exp $ */
/* $Id: fpu.cpp,v 1.28 2006-06-01 08:33:52 c2woody Exp $ */
#include "dosbox.h"
#if C_FPU
@ -28,74 +28,20 @@
#include "fpu.h"
#include "cpu.h"
typedef PhysPt EAPoint;
FPU_rec fpu;
#define TOP fpu.top
#define STV(i) ( (fpu.top+ (i) ) & 7 )
#define LoadMb(off) mem_readb(off)
#define LoadMw(off) mem_readw(off)
#define LoadMd(off) mem_readd(off)
#define SaveMb(off,val) mem_writeb(off,val)
#define SaveMw(off,val) mem_writew(off,val)
#define SaveMd(off,val) mem_writed(off,val)
#include "fpu_types.h"
static struct {
FPU_Reg regs[9];
FPU_P_Reg p_regs[9];
FPU_Tag tags[9];
Bit16u cw,cw_mask_all;
Bit16u sw;
Bitu top;
FPU_Round round;
} fpu;
INLINE void FPU_SetCW(Bitu word){
fpu.cw = word;
fpu.cw_mask_all = word | 0x3f;
fpu.round = (FPU_Round)((word >> 10) & 3);
void FPU_FLDCW(PhysPt addr){
Bit16u temp = mem_readw(addr);
FPU_SetCW(temp);
}
static Bit16u FPU_GetTag(void){
Bit16u FPU_GetTag(void){
Bit16u tag=0;
for(Bitu i=0;i<8;i++)
tag |= ( (fpu.tags[i]&3) <<(2*i));
return tag;
}
static void FPU_SetTag(Bit16u tag){
for(Bitu i=0;i<8;i++)
fpu.tags[i]= static_cast<FPU_Tag>((tag >>(2*i))&3);
}
INLINE Bitu FPU_GET_TOP(void){
return (fpu.sw & 0x3800)>>11;
}
INLINE void FPU_SET_TOP(Bitu val){
fpu.sw &= ~0x3800;
fpu.sw |= (val&7)<<11;
}
INLINE void FPU_SET_C0(Bitu C){
fpu.sw &= ~0x0100;
if(C) fpu.sw |= 0x0100;
}
INLINE void FPU_SET_C1(Bitu C){
fpu.sw &= ~0x0200;
if(C) fpu.sw |= 0x0200;
}
INLINE void FPU_SET_C2(Bitu C){
fpu.sw &= ~0x0400;
if(C) fpu.sw |= 0x0400;
}
INLINE void FPU_SET_C3(Bitu C){
fpu.sw &= ~0x4000;
if(C) fpu.sw |= 0x4000;
}
#if C_FPU_X86
#include "fpu_instructions_x86.h"
#else
@ -109,32 +55,31 @@ INLINE void FPU_SET_C3(Bitu C){
static void EATREE(Bitu _rm){
Bitu group=(_rm >> 3) & 7;
/* data will allready be put in register 8 by caller */
switch(group){
case 0x00: /* FADD */
FPU_FADD(TOP, 8);
FPU_FADD_EA(TOP);
break;
case 0x01: /* FMUL */
FPU_FMUL(TOP, 8);
FPU_FMUL_EA(TOP);
break;
case 0x02: /* FCOM */
FPU_FCOM(TOP,8);
FPU_FCOM_EA(TOP);
break;
case 0x03: /* FCOMP */
FPU_FCOM(TOP,8);
FPU_FCOM_EA(TOP);
FPU_FPOP();
break;
case 0x04: /* FSUB */
FPU_FSUB(TOP,8);
FPU_FSUB_EA(TOP);
break;
case 0x05: /* FSUBR */
FPU_FSUBR(TOP,8);
FPU_FSUBR_EA(TOP);
break;
case 0x06: /* FDIV */
FPU_FDIV(TOP, 8);
FPU_FDIV_EA(TOP);
break;
case 0x07: /* FDIVR */
FPU_FDIVR(TOP,8);
FPU_FDIVR_EA(TOP);
break;
default:
break;
@ -143,7 +88,7 @@ static void EATREE(Bitu _rm){
void FPU_ESC0_EA(Bitu rm,PhysPt addr) {
/* REGULAR TREE WITH 32 BITS REALS */
FPU_FLD_F32(addr,8);
FPU_FLD_F32_EA(addr);
EATREE(rm);
}
@ -204,10 +149,7 @@ void FPU_ESC1_EA(Bitu rm,PhysPt addr) {
FPU_FLDENV(addr);
break;
case 0x05: /* FLDCW */
{
Bit16u temp = mem_readw(addr);
FPU_SetCW(temp);
}
FPU_FLDCW(addr);
break;
case 0x06: /* FSTENV */
FPU_FSTENV(addr);
@ -364,7 +306,7 @@ void FPU_ESC1_Normal(Bitu rm) {
void FPU_ESC2_EA(Bitu rm,PhysPt addr) {
/* 32 bits integer operants */
FPU_FLD_I32(addr,8);
FPU_FLD_I32_EA(addr);
EATREE(rm);
}
@ -457,7 +399,7 @@ void FPU_ESC3_Normal(Bitu rm) {
void FPU_ESC4_EA(Bitu rm,PhysPt addr) {
/* REGULAR TREE WITH 64 BITS REALS */
FPU_FLD_F64(addr,8);
FPU_FLD_F64_EA(addr);
EATREE(rm);
}
@ -560,10 +502,9 @@ void FPU_ESC5_Normal(Bitu rm) {
}
}
void FPU_ESC6_EA(Bitu rm,PhysPt addr) {
/* 16 bit (word integer) operants */
FPU_FLD_I16(addr,8);
FPU_FLD_I16_EA(addr);
EATREE(rm);
}

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: fpu_instructions.h,v 1.28 2006-02-09 11:47:48 qbix79 Exp $ */
/* $Id: fpu_instructions.h,v 1.29 2006-06-01 08:33:52 c2woody Exp $ */
static void FPU_FINIT(void) {
@ -187,6 +187,21 @@ static void FPU_FBLD(PhysPt addr,Bitu store_to) {
fpu.regs[store_to].d = temp;
}
static INLINE void FPU_FLD_F32_EA(PhysPt addr) {
FPU_FLD_F32(addr,8);
}
static INLINE void FPU_FLD_F64_EA(PhysPt addr) {
FPU_FLD_F64(addr,8);
}
static INLINE void FPU_FLD_I32_EA(PhysPt addr) {
FPU_FLD_I32(addr,8);
}
static INLINE void FPU_FLD_I16_EA(PhysPt addr) {
FPU_FLD_I16(addr,8);
}
static void FPU_FST_F32(PhysPt addr) {
union {
float f;
@ -249,7 +264,6 @@ static void FPU_FBST(PhysPt addr) {
mem_writeb(addr+9,p);
}
static void FPU_FADD(Bitu op1, Bitu op2){
fpu.regs[op1].d+=fpu.regs[op2].d;
//flags and such :)
@ -556,3 +570,26 @@ static void FPU_FLDZ(void){
fpu.regs[TOP].d = 0.0;
fpu.tags[TOP] = TAG_Zero;
}
static INLINE void FPU_FADD_EA(Bitu op1){
FPU_FADD(op1,8);
}
static INLINE void FPU_FMUL_EA(Bitu op1){
FPU_FMUL(op1,8);
}
static INLINE void FPU_FSUB_EA(Bitu op1){
FPU_FSUB(op1,8);
}
static INLINE void FPU_FSUBR_EA(Bitu op1){
FPU_FSUBR(op1,8);
}
static INLINE void FPU_FDIV_EA(Bitu op1){
FPU_FDIV(op1,8);
}
static INLINE void FPU_FDIVR_EA(Bitu op1){
FPU_FDIVR(op1,8);
}
static INLINE void FPU_FCOM_EA(Bitu op1){
FPU_FCOM(op1,8);
}

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: fpu_instructions_x86.h,v 1.3 2006-02-09 11:47:48 qbix79 Exp $ */
/* $Id: fpu_instructions_x86.h,v 1.4 2006-06-01 08:33:52 c2woody Exp $ */
#define WEAK_EXCEPTIONS
@ -33,11 +33,9 @@
#ifdef WEAK_EXCEPTIONS
#define FPUD_LOAD(op,szI,szA) \
__asm { \
__asm mov eax, 8 \
__asm shl eax, 4 \
__asm mov ebx, store_to \
__asm shl ebx, 4 \
__asm op szI PTR fpu.p_regs[eax].m1 \
__asm op szI PTR fpu.p_regs[128].m1 \
__asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \
}
#else
@ -56,6 +54,37 @@
fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff);
#endif
#ifdef WEAK_EXCEPTIONS
#define FPUD_LOAD_EA(op,szI,szA) \
__asm { \
__asm op szI PTR fpu.p_regs[128].m1 \
}
#else
#define FPUD_LOAD_EA(op,szI,szA) \
Bit16u new_sw; \
__asm { \
__asm mov eax, 8 \
__asm shl eax, 4 \
__asm fclex \
__asm op szI PTR fpu.p_regs[eax].m1 \
__asm fnstsw new_sw \
} \
fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff);
#endif
#ifdef WEAK_EXCEPTIONS
#define FPUD_STORE(op,szI,szA) \
Bit16u save_cw; \
__asm { \
__asm fnstcw save_cw \
__asm mov eax, TOP \
__asm fldcw fpu.cw_mask_all \
__asm shl eax, 4 \
__asm fld TBYTE PTR fpu.p_regs[eax].m1 \
__asm op szI PTR fpu.p_regs[128].m1 \
__asm fldcw save_cw \
}
#else
#define FPUD_STORE(op,szI,szA) \
Bit16u new_sw,save_cw; \
__asm { \
@ -72,6 +101,7 @@
__asm fldcw save_cw \
} \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
#endif
// handles fsin,fcos,f2xm1,fchs,fabs
#define FPUD_TRIG(op) \
@ -179,6 +209,23 @@
#endif
// handles fadd,fmul,fsub,fsubr
#ifdef WEAK_EXCEPTIONS
#define FPUD_ARITH1(op) \
Bit16u save_cw; \
__asm { \
__asm fnstcw save_cw \
__asm mov eax, op1 \
__asm shl eax, 4 \
__asm fldcw fpu.cw_mask_all \
__asm mov ebx, op2 \
__asm shl ebx, 4 \
__asm fld TBYTE PTR fpu.p_regs[eax].m1 \
__asm fld TBYTE PTR fpu.p_regs[ebx].m1 \
__asm op st(1), st(0) \
__asm fstp TBYTE PTR fpu.p_regs[eax].m1 \
__asm fldcw save_cw \
}
#else
#define FPUD_ARITH1(op) \
Bit16u new_sw,save_cw; \
__asm { \
@ -197,8 +244,57 @@
__asm fldcw save_cw \
} \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
#endif
// handles fadd,fmul,fsub,fsubr
#ifdef WEAK_EXCEPTIONS
#define FPUD_ARITH1_EA(op) \
Bit16u save_cw; \
__asm { \
__asm fnstcw save_cw \
__asm mov eax, op1 \
__asm fldcw fpu.cw_mask_all \
__asm shl eax, 4 \
__asm fld TBYTE PTR fpu.p_regs[eax].m1 \
__asm fxch \
__asm op st(1), st(0) \
__asm fstp TBYTE PTR fpu.p_regs[eax].m1 \
__asm fldcw save_cw \
}
#else
#define FPUD_ARITH1_EA(op) \
Bit16u new_sw,save_cw; \
__asm { \
__asm fnstcw save_cw \
__asm fldcw fpu.cw_mask_all \
__asm mov eax, op1 \
__asm shl eax, 4 \
__asm fld TBYTE PTR fpu.p_regs[eax].m1 \
__asm fxch \
__asm clx \
__asm op st(1), st(0) \
__asm fnstsw new_sw \
__asm fstp TBYTE PTR fpu.p_regs[eax].m1 \
__asm fldcw save_cw \
} \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
#endif
// handles fsqrt,frndint
#ifdef WEAK_EXCEPTIONS
#define FPUD_ARITH2(op) \
Bit16u save_cw; \
__asm { \
__asm fnstcw save_cw \
__asm mov eax, TOP \
__asm fldcw fpu.cw_mask_all \
__asm shl eax, 4 \
__asm fld TBYTE PTR fpu.p_regs[eax].m1 \
__asm op \
__asm fstp TBYTE PTR fpu.p_regs[eax].m1 \
__asm fldcw save_cw \
}
#else
#define FPUD_ARITH2(op) \
Bit16u new_sw,save_cw; \
__asm { \
@ -214,8 +310,26 @@
__asm fldcw save_cw \
} \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
#endif
// handles fdiv,fdivr
#ifdef WEAK_EXCEPTIONS
#define FPUD_ARITH3(op) \
Bit16u save_cw; \
__asm { \
__asm fnstcw save_cw \
__asm mov eax, op1 \
__asm shl eax, 4 \
__asm fldcw fpu.cw_mask_all \
__asm mov ebx, op2 \
__asm shl ebx, 4 \
__asm fld TBYTE PTR fpu.p_regs[eax].m1 \
__asm fld TBYTE PTR fpu.p_regs[ebx].m1 \
__asm op st(1), st(0) \
__asm fstp TBYTE PTR fpu.p_regs[eax].m1 \
__asm fldcw save_cw \
}
#else
#define FPUD_ARITH3(op) \
Bit16u new_sw,save_cw; \
__asm { \
@ -234,6 +348,41 @@
__asm fldcw save_cw \
} \
fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff);
#endif
// handles fdiv,fdivr
#ifdef WEAK_EXCEPTIONS
#define FPUD_ARITH3_EA(op) \
Bit16u save_cw; \
__asm { \
__asm fnstcw save_cw \
__asm mov eax, op1 \
__asm fldcw fpu.cw_mask_all \
__asm shl eax, 4 \
__asm fld TBYTE PTR fpu.p_regs[eax].m1 \
__asm fxch \
__asm op st(1), st(0) \
__asm fstp TBYTE PTR fpu.p_regs[eax].m1 \
__asm fldcw save_cw \
}
#else
#define FPUD_ARITH3_EA(op) \
Bit16u new_sw,save_cw; \
__asm { \
__asm fnstcw save_cw \
__asm mov eax, op1 \
__asm fldcw fpu.cw_mask_all \
__asm shl eax, 4 \
__asm fld TBYTE PTR fpu.p_regs[eax].m1 \
__asm fxch \
__asm fclex \
__asm op st(1), st(0) \
__asm fnstsw new_sw \
__asm fstp TBYTE PTR fpu.p_regs[eax].m1 \
__asm fldcw save_cw \
} \
fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff);
#endif
// handles fprem,fprem1,fscale
#define FPUD_REMINDER(op) \
@ -260,8 +409,8 @@
Bit16u new_sw; \
__asm { \
__asm mov ebx, op2 \
__asm shl ebx, 4 \
__asm mov eax, op1 \
__asm shl ebx, 4 \
__asm shl eax, 4 \
__asm fld TBYTE PTR fpu.p_regs[ebx].m1 \
__asm fld TBYTE PTR fpu.p_regs[eax].m1 \
@ -271,6 +420,18 @@
} \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
#define FPUD_COMPARE_EA(op) \
Bit16u new_sw; \
__asm { \
__asm mov eax, op1 \
__asm shl eax, 4 \
__asm fld TBYTE PTR fpu.p_regs[eax].m1 \
__asm clx \
__asm op \
__asm fnstsw new_sw \
} \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
// handles fxam,ftst
#define FPUD_EXAMINE(op) \
Bit16u new_sw; \
@ -323,6 +484,22 @@
#endif
// handles fyl2x
#ifdef WEAK_EXCEPTIONS
#define FPUD_FYL2X(op) \
__asm { \
__asm mov eax, TOP \
__asm mov ebx, eax \
__asm inc ebx \
__asm and ebx, 7 \
__asm shl ebx, 4 \
__asm shl eax, 4 \
__asm fld TBYTE PTR fpu.p_regs[ebx].m1 \
__asm fld TBYTE PTR fpu.p_regs[eax].m1 \
__asm op \
__asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \
} \
FPU_FPOP();
#else
#define FPUD_FYL2X(op) \
Bit16u new_sw; \
__asm { \
@ -341,6 +518,7 @@
} \
fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \
FPU_FPOP();
#endif
// load math constants
#define FPUD_LOAD_CONST(op) \
@ -364,8 +542,7 @@
#ifdef WEAK_EXCEPTIONS
#define FPUD_LOAD(op,szI,szA) \
__asm__ volatile ( \
"movl $8, %%eax \n" \
"shl $4, %%eax \n" \
"movl $128, %%eax \n" \
"shl $4, %0 \n" \
#op #szA " (%1, %%eax) \n" \
"fstpt (%1, %0) " \
@ -391,6 +568,47 @@
fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff);
#endif
#ifdef WEAK_EXCEPTIONS
#define FPUD_LOAD_EA(op,szI,szA) \
__asm__ volatile ( \
"movl $128, %%eax \n" \
#op #szA " (%0, %%eax) \n" \
: \
: "r" (fpu.p_regs) \
: "eax", "memory" \
);
#else
#define FPUD_LOAD_EA(op,szI,szA) \
Bit16u new_sw; \
__asm__ volatile ( \
"movl $8, %%eax \n" \
"shl $4, %%eax \n" \
"fclex \n" \
#op #szA " (%1, %%eax) \n" \
"fnstsw %0 \n" \
: "=m" (new_sw) \
: "r" (fpu.p_regs) \
: "eax", "memory" \
); \
fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff);
#endif
#ifdef WEAK_EXCEPTIONS
#define FPUD_STORE(op,szI,szA) \
Bit16u save_cw; \
__asm__ volatile ( \
"fnstcw %0 \n" \
"shll $4, %1 \n" \
"fldcw %3 \n" \
"movl $128, %%eax \n" \
"fldt (%2, %1) \n" \
#op #szA " (%2, %%eax) \n" \
"fldcw %0 " \
: "=m" (save_cw) \
: "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \
: "eax", "memory" \
);
#else
#define FPUD_STORE(op,szI,szA) \
Bit16u new_sw,save_cw; \
__asm__ volatile ( \
@ -409,6 +627,7 @@
: "eax", "memory" \
); \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
#endif
// handles fsin,fcos,f2xm1,fchs,fabs
#define FPUD_TRIG(op) \
@ -422,7 +641,7 @@
"fstpt (%2, %1) " \
: "=m" (new_sw) \
: "r" (TOP), "r" (fpu.p_regs) \
: "memory" \
: "memory" \
); \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
@ -520,6 +739,24 @@
#endif
// handles fadd,fmul,fsub,fsubr
#ifdef WEAK_EXCEPTIONS
#define FPUD_ARITH1(op) \
Bit16u save_cw; \
__asm__ volatile ( \
"fnstcw %0 \n" \
"fldcw %4 \n" \
"shll $4, %2 \n" \
"shll $4, %1 \n" \
"fldt (%3, %2) \n" \
"fldt (%3, %1) \n" \
#op" \n" \
"fstpt (%3, %1) \n" \
"fldcw %0 " \
: "=m" (save_cw) \
: "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \
: "memory" \
);
#else
#define FPUD_ARITH1(op) \
Bit16u new_sw,save_cw; \
__asm__ volatile ( \
@ -539,8 +776,61 @@
: "memory" \
); \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
#endif
// handles fadd,fmul,fsub,fsubr
#ifdef WEAK_EXCEPTIONS
#define FPUD_ARITH1_EA(op) \
Bit16u save_cw; \
__asm__ volatile ( \
"fnstcw %0 \n" \
"fldcw %3 \n" \
"shll $4, %1 \n" \
"fldt (%2, %1) \n" \
#op" \n" \
"fstpt (%2, %1) \n" \
"fldcw %0 " \
: "=m" (save_cw) \
: "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \
: "memory" \
);
#else
#define FPUD_ARITH1_EA(op) \
Bit16u new_sw,save_cw; \
__asm__ volatile ( \
"fnstcw %1 \n" \
"fldcw %4 \n" \
"shll $4, %2 \n" \
"fldt (%3, %2) \n" \
clx" \n" \
#op" \n" \
"fnstsw %0 \n" \
"fstpt (%3, %2) \n" \
"fldcw %1 " \
: "=m" (new_sw), "=m" (save_cw) \
: "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \
: "memory" \
); \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
#endif
// handles fsqrt,frndint
#ifdef WEAK_EXCEPTIONS
#define FPUD_ARITH2(op) \
Bit16u save_cw; \
__asm__ volatile ( \
"fnstcw %0 \n" \
"fldcw %3 \n" \
"shll $4, %1 \n" \
"fldt (%2, %1) \n" \
#op" \n" \
"fstpt (%2, %1) \n" \
"fldcw %0 " \
: "=m" (save_cw) \
: "r" (TOP), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \
: "memory" \
);
#else
#define FPUD_ARITH2(op) \
Bit16u new_sw,save_cw; \
__asm__ volatile ( \
@ -558,8 +848,27 @@
: "memory" \
); \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
#endif
// handles fdiv,fdivr
#ifdef WEAK_EXCEPTIONS
#define FPUD_ARITH3(op) \
Bit16u save_cw; \
__asm__ volatile ( \
"fnstcw %0 \n" \
"fldcw %4 \n" \
"shll $4, %2 \n" \
"shll $4, %1 \n" \
"fldt (%3, %2) \n" \
"fldt (%3, %1) \n" \
#op" \n" \
"fstpt (%3, %1) \n" \
"fldcw %0 " \
: "=m" (save_cw) \
: "r" (op1), "r" (op2), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \
: "memory" \
);
#else
#define FPUD_ARITH3(op) \
Bit16u new_sw,save_cw; \
__asm__ volatile ( \
@ -579,6 +888,43 @@
: "memory" \
); \
fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff);
#endif
// handles fdiv,fdivr
#ifdef WEAK_EXCEPTIONS
#define FPUD_ARITH3_EA(op) \
Bit16u save_cw; \
__asm__ volatile ( \
"fnstcw %0 \n" \
"fldcw %3 \n" \
"shll $4, %1 \n" \
"fldt (%2, %1) \n" \
#op" \n" \
"fstpt (%2, %1) \n" \
"fldcw %0 " \
: "=m" (save_cw) \
: "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \
: "memory" \
);
#else
#define FPUD_ARITH3_EA(op) \
Bit16u new_sw,save_cw; \
__asm__ volatile ( \
"fnstcw %1 \n" \
"fldcw %4 \n" \
"shll $4, %2 \n" \
"fldt (%3, %2) \n" \
"fclex \n" \
#op" \n" \
"fnstsw %0 \n" \
"fstpt (%3, %2) \n" \
"fldcw %1 " \
: "=m" (new_sw), "=m" (save_cw) \
: "r" (op1), "r" (fpu.p_regs), "m" (fpu.cw_mask_all) \
: "memory" \
); \
fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff);
#endif
// handles fprem,fprem1,fscale
#define FPUD_REMINDER(op) \
@ -615,7 +961,22 @@
"fnstsw %0 " \
: "=m" (new_sw) \
: "r" (op1), "r" (op2), "r" (fpu.p_regs) \
: "memory" \
: "memory" \
); \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
// handles fcom,fucom
#define FPUD_COMPARE_EA(op) \
Bit16u new_sw; \
__asm__ volatile ( \
"shll $4, %1 \n" \
"fldt (%2, %1) \n" \
clx" \n" \
#op" \n" \
"fnstsw %0 " \
: "=m" (new_sw) \
: "r" (op1), "r" (fpu.p_regs) \
: "memory" \
); \
fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff);
@ -677,6 +1038,24 @@
#endif
// handles fyl2x
#ifdef WEAK_EXCEPTIONS
#define FPUD_FYL2X(op) \
__asm__ volatile ( \
"movl %0, %%eax \n" \
"incl %%eax \n" \
"andl $7, %%eax \n" \
"shll $4, %%eax \n" \
"shll $4, %0 \n" \
"fldt (%1, %%eax) \n" \
"fldt (%1, %0) \n" \
#op" \n" \
"fstpt (%1, %%eax) \n" \
: \
: "r" (TOP), "r" (fpu.p_regs) \
: "eax", "memory" \
); \
FPU_FPOP();
#else
#define FPUD_FYL2X(op) \
Bit16u new_sw; \
__asm__ volatile ( \
@ -697,6 +1076,7 @@
); \
fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \
FPU_FPOP();
#endif
// load math constants
#define FPUD_LOAD_CONST(op) \
@ -756,12 +1136,23 @@ static void FPU_FLD_F32(PhysPt addr,Bitu store_to) {
FPUD_LOAD(fld,DWORD,s)
}
static void FPU_FLD_F32_EA(PhysPt addr) {
fpu.p_regs[8].m1 = mem_readd(addr);
FPUD_LOAD_EA(fld,DWORD,s)
}
static void FPU_FLD_F64(PhysPt addr,Bitu store_to) {
fpu.p_regs[8].m1 = mem_readd(addr);
fpu.p_regs[8].m2 = mem_readd(addr+4);
FPUD_LOAD(fld,QWORD,l)
}
static void FPU_FLD_F64_EA(PhysPt addr) {
fpu.p_regs[8].m1 = mem_readd(addr);
fpu.p_regs[8].m2 = mem_readd(addr+4);
FPUD_LOAD_EA(fld,QWORD,l)
}
static void FPU_FLD_F80(PhysPt addr) {
fpu.p_regs[TOP].m1 = mem_readd(addr);
fpu.p_regs[TOP].m2 = mem_readd(addr+4);
@ -774,11 +1165,21 @@ static void FPU_FLD_I16(PhysPt addr,Bitu store_to) {
FPUD_LOAD(fild,WORD,)
}
static void FPU_FLD_I16_EA(PhysPt addr) {
fpu.p_regs[8].m1 = (Bit32u)mem_readw(addr);
FPUD_LOAD_EA(fild,WORD,)
}
static void FPU_FLD_I32(PhysPt addr,Bitu store_to) {
fpu.p_regs[8].m1 = mem_readd(addr);
FPUD_LOAD(fild,DWORD,l)
}
static void FPU_FLD_I32_EA(PhysPt addr) {
fpu.p_regs[8].m1 = mem_readd(addr);
FPUD_LOAD_EA(fild,DWORD,l)
}
static void FPU_FLD_I64(PhysPt addr,Bitu store_to) {
fpu.p_regs[8].m1 = mem_readd(addr);
fpu.p_regs[8].m2 = mem_readd(addr+4);
@ -863,26 +1264,50 @@ static void FPU_FADD(Bitu op1, Bitu op2){
FPUD_ARITH1(faddp)
}
static void FPU_FADD_EA(Bitu op1){
FPUD_ARITH1_EA(faddp)
}
static void FPU_FDIV(Bitu op1, Bitu op2){
FPUD_ARITH3(fdivp)
}
static void FPU_FDIV_EA(Bitu op1){
FPUD_ARITH3_EA(fdivp)
}
static void FPU_FDIVR(Bitu op1, Bitu op2){
FPUD_ARITH3(fdivrp)
}
static void FPU_FDIVR_EA(Bitu op1){
FPUD_ARITH3_EA(fdivrp)
}
static void FPU_FMUL(Bitu op1, Bitu op2){
FPUD_ARITH1(fmulp)
}
static void FPU_FMUL_EA(Bitu op1){
FPUD_ARITH1_EA(fmulp)
}
static void FPU_FSUB(Bitu op1, Bitu op2){
FPUD_ARITH1(fsubp)
}
static void FPU_FSUB_EA(Bitu op1){
FPUD_ARITH1_EA(fsubp)
}
static void FPU_FSUBR(Bitu op1, Bitu op2){
FPUD_ARITH1(fsubrp)
}
static void FPU_FSUBR_EA(Bitu op1){
FPUD_ARITH1_EA(fsubrp)
}
static void FPU_FXCH(Bitu stv, Bitu other){
FPU_Tag tag = fpu.tags[other];
fpu.tags[other] = fpu.tags[stv];
@ -916,6 +1341,10 @@ static void FPU_FCOM(Bitu op1, Bitu op2){
FPUD_COMPARE(fcompp)
}
static void FPU_FCOM_EA(Bitu op1){
FPUD_COMPARE_EA(fcompp)
}
static void FPU_FUCOM(Bitu op1, Bitu op2){
FPUD_COMPARE(fucompp)
}

View file

@ -262,6 +262,9 @@
<File
RelativePath="..\src\cpu\core_dyn_x86\decoder.h">
</File>
<File
RelativePath="..\src\cpu\core_dyn_x86\dyn_fpu.h">
</File>
<File
RelativePath="..\src\cpu\core_dyn_x86\helpers.h">
</File>
@ -368,13 +371,13 @@
<File
RelativePath="..\src\dos\cdrom_aspi_win32.cpp">
</File>
<File
RelativePath="..\src\dos\cdrom_ioctl_win32.cpp">
</File>
<File
RelativePath="..\src\dos\cdrom_image.cpp">
</File>
</Filter>
<File
RelativePath="..\src\dos\cdrom_ioctl_win32.cpp">
</File>
</Filter>
<Filter
Name="drives"
Filter="">
@ -384,15 +387,15 @@
<File
RelativePath="..\src\dos\drive_fat.cpp">
</File>
<File
RelativePath="..\src\dos\drive_iso.cpp">
</File>
<File
RelativePath="..\src\dos\drive_local.cpp">
</File>
<File
RelativePath="..\src\dos\drive_virtual.cpp">
</File>
<File
RelativePath="..\src\dos\drive_iso.cpp">
</File>
<File
RelativePath="..\src\dos\drives.cpp">
</File>
@ -470,15 +473,15 @@
<File
RelativePath="..\src\hardware\vga_other.cpp">
</File>
<File
RelativePath="..\src\hardware\vga_s3.cpp">
</File>
<File
RelativePath="..\src\hardware\vga_seq.cpp">
</File>
<File
RelativePath="..\src\hardware\vga_xga.cpp">
</File>
<File
RelativePath="..\src\hardware\vga_s3.cpp">
</File>
</Filter>
<Filter
Name="sound"
@ -678,9 +681,6 @@
<File
RelativePath="..\src\fpu\fpu_instructions_x86.h">
</File>
<File
RelativePath="..\src\fpu\fpu_types.h">
</File>
</Filter>
</Filter>
<Filter