diff --git a/include/fpu.h b/include/fpu.h index 6bea5cef..448ba5db 100644 --- a/include/fpu.h +++ b/include/fpu.h @@ -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((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 diff --git a/src/cpu/core_dyn_x86/Makefile.am b/src/cpu/core_dyn_x86/Makefile.am index ad1008a7..8c432515 100644 --- a/src/cpu/core_dyn_x86/Makefile.am +++ b/src/cpu/core_dyn_x86/Makefile.am @@ -1 +1,2 @@ -noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h \ No newline at end of file +noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h \ + dyn_fpu.h \ No newline at end of file diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 9be546ae..7d1baa13 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -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; diff --git a/src/fpu/Makefile.am b/src/fpu/Makefile.am index d081a682..541d5a46 100644 --- a/src/fpu/Makefile.am +++ b/src/fpu/Makefile.am @@ -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 diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 69872c0b..ef57cf88 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -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((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); } diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 8609aae0..8bdf648d 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -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); +} \ No newline at end of file diff --git a/src/fpu/fpu_instructions_x86.h b/src/fpu/fpu_instructions_x86.h index f3babb49..8acb2f08 100644 --- a/src/fpu/fpu_instructions_x86.h +++ b/src/fpu/fpu_instructions_x86.h @@ -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) } diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index c7706767..09b10a58 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -262,6 +262,9 @@ + + @@ -368,13 +371,13 @@ - - - + + + @@ -384,15 +387,15 @@ + + - - @@ -470,15 +473,15 @@ + + - - - -