From b81081ed2b809e0a3a08e7fb9814eae1dcef9210 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Tue, 27 May 2003 12:09:03 +0000 Subject: [PATCH] New FPU opcode handling layout Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1020 --- src/fpu/Makefile.am | 2 +- src/fpu/fpu.cpp | 203 +++++--------------------------- src/fpu/fpu_flags.cpp | 235 ------------------------------------- src/fpu/fpu_instructions.h | 155 ++---------------------- src/fpu/fpu_types.h | 62 +++++----- 5 files changed, 77 insertions(+), 580 deletions(-) delete mode 100644 src/fpu/fpu_flags.cpp diff --git a/src/fpu/Makefile.am b/src/fpu/Makefile.am index fb3045f2..14c2d3d4 100644 --- a/src/fpu/Makefile.am +++ b/src/fpu/Makefile.am @@ -1,4 +1,4 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LIBRARIES = libfpu.a -libfpu_a_SOURCES = fpu.cpp fpu_flags.cpp fpu_types.h fpu_instructions.h \ No newline at end of file +libfpu_a_SOURCES = fpu.cpp fpu_types.h fpu_instructions.h \ No newline at end of file diff --git a/src/fpu/fpu.cpp b/src/fpu/fpu.cpp index 79ee2b97..036cfa02 100644 --- a/src/fpu/fpu.cpp +++ b/src/fpu/fpu.cpp @@ -30,101 +30,32 @@ typedef PhysPt EAPoint; #define LoadMw(off) mem_readw(off) #define LoadMd(off) mem_readd(off) -#define LoadMbs(off) (Bit8s)(LoadMb(off)) -#define LoadMws(off) (Bit16s)(LoadMw(off)) -#define LoadMds(off) (Bit32s)(LoadMd(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) -typedef double Real; - #include "fpu_types.h" + +struct { + FPU_Reg regs[8]; + FPU_Tag tags[8]; + Bitu cw; + FPU_Round round; + Bitu ex_mask; + Bitu sw; + Bitu top; + +} fpu; + +INLINE void FPU_SetCW(Bitu word) { + fpu.cw = word; + fpu.round = (FPU_Round)((word >> 8) & 3); + fpu.ex_mask = word & 0x3f; +} + #include "fpu_instructions.h" -FPU_Flag_Info fpu_flags; -FPU_Reg fpu_regs[8]; -#define FPU_GetZF fpu_flags.sw.zf = FPU_get_ZF(); - -#define FPU_ParseCW(newcw) { \ - fpu_flags.cw.ic = ((bool)((newcw&0x1000)>>12)?true:false); \ - fpu_flags.cw.rc = (Bit8u)((newcw&0x0C00)>>10); \ - fpu_flags.cw.pc = (Bit8u)((newcw&0x0300)>>8); \ - fpu_flags.cw.ie = ((bool)((newcw&0x0080)>>7)?true:false); \ - fpu_flags.cw.sf = ((bool)((newcw&0x0040)>>6)?true:false); \ - fpu_flags.cw.pf = ((bool)((newcw&0x0020)>>5)?true:false); \ - fpu_flags.cw.uf = ((bool)((newcw&0x0010)>>4)?true:false); \ - fpu_flags.cw.of = ((bool)((newcw&0x0008)>>3)?true:false); \ - fpu_flags.cw.zf = ((bool)((newcw&0x0004)>>2)?true:false); \ - fpu_flags.cw.df = ((bool)((newcw&0x0002)>>1)?true:false); \ - fpu_flags.cw.in = ((bool)(newcw&0x0001)?true:false); \ -} - -#define FPU_makeCW(newcw) { \ - newcw = (Bit16u)fpu_flags.cw.in; \ - newcw |= (fpu_flags.cw.df<<1); \ - newcw |= (fpu_flags.cw.zf<<2); \ - newcw |= (fpu_flags.cw.of<<3); \ - newcw |= (fpu_flags.cw.uf<<4); \ - newcw |= (fpu_flags.cw.pf<<5); \ - newcw |= (fpu_flags.cw.sf<<6); \ - newcw |= (fpu_flags.cw.ie<<7); \ - newcw |= (fpu_flags.cw.pc<<8); \ - newcw |= (fpu_flags.cw.rc<<10); \ - newcw |= (fpu_flags.cw.ic<<12); \ -} - -#define FPU_ParseSW(newsw) { \ - fpu_flags.sw.bf = ((bool)((newsw&0x8000)>>15)?true:false); \ - fpu_flags.sw.c3 = ((bool)((newsw&0x4000)>>14)?true:false); \ - fpu_flags.sw.tos = (Bit8s)((newsw&0x3800)>>11); \ - fpu_flags.sw.c2 = ((bool)((newsw&0x0400)>>10)?true:false); \ - fpu_flags.sw.c1 = ((bool)((newsw&0x0200)>>9)?true:false); \ - fpu_flags.sw.c0 = ((bool)((newsw&0x0100)>>8)?true:false); \ - fpu_flags.sw.ir = ((bool)((newsw&0x0080)>>7)?true:false); \ - fpu_flags.sw.sf = ((bool)((newsw&0x0040)>>6)?true:false); \ - fpu_flags.sw.pf = ((bool)((newsw&0x0020)>>5)?true:false); \ - fpu_flags.sw.uf = ((bool)((newsw&0x0010)>>4)?true:false); \ - fpu_flags.sw.of = ((bool)((newsw&0x0008)>>3)?true:false); \ - fpu_flags.sw.zf = ((bool)((newsw&0x0004)>>2)?true:false); \ - fpu_flags.sw.df = ((bool)((newsw&0x0002)>>1)?true:false); \ - fpu_flags.sw.in = ((bool)(newsw&0x0001)?true:false); \ -} - -#define FPU_makeSW(newsw) { \ - newsw = (Bit16u)fpu_flags.sw.in; \ - newsw |= (fpu_flags.sw.df<<1); \ - newsw |= (fpu_flags.sw.zf<<2); \ - newsw |= (fpu_flags.sw.of<<3); \ - newsw |= (fpu_flags.sw.uf<<4); \ - newsw |= (fpu_flags.sw.pf<<5); \ - newsw |= (fpu_flags.sw.sf<<6); \ - newsw |= (fpu_flags.sw.ir<<7); \ - newsw |= (fpu_flags.sw.c0<<8); \ - newsw |= (fpu_flags.sw.c1<<9); \ - newsw |= (fpu_flags.sw.c2<<10); \ - newsw |= (fpu_flags.sw.tos<<11); \ - newsw |= (fpu_flags.sw.c3<<14); \ - newsw |= (fpu_flags.sw.bf<<15); \ -} - -#define FPU_LOADFLAGS { \ - fpu_flags.sw.bf = false; \ - fpu_flags.sw.c3 = FPU_get_C3(); \ - fpu_flags.sw.c2 = FPU_get_C2(); \ - fpu_flags.sw.c1 = FPU_get_C1(); \ - fpu_flags.sw.c0 = FPU_get_C0(); \ - fpu_flags.sw.ir = FPU_get_IR(); \ - fpu_flags.sw.sf = FPU_get_SF(); \ - fpu_flags.sw.pf = FPU_get_PF(); \ - fpu_flags.sw.uf = FPU_get_UF(); \ - fpu_flags.sw.of = FPU_get_OF(); \ - fpu_flags.sw.zf = FPU_get_ZF(); \ - fpu_flags.sw.df = FPU_get_DF(); \ - fpu_flags.sw.in = FPU_get_IN(); \ -} void FPU_ESC0_EA(Bitu rm,PhysPt addr) { } @@ -134,50 +65,10 @@ void FPU_ESC0_Normal(Bitu rm) { void FPU_ESC1_EA(Bitu rm,PhysPt addr) { - Bit16u cw; - Bitu opcode = (rm&0x38)>>3; - switch(opcode) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 6: - break; - case 5: - FPU_ParseCW(LoadMw(addr)); /* FLDCW */ - break; - case 7: /* FSTCW */ - FPU_makeCW(cw); - SaveMw(addr,cw); - break; - } } void FPU_ESC1_Normal(Bitu rm) { - Bitu opcode = (rm&0xF0); - - switch(opcode) { - case 0xC0: -// if(rm&8) -// else - FLDST(rm-0xC0); /* FLDST */ - break; - case 0xD0: - break; - } - switch(rm) { - case 0xE0: /* FCHS */ - FCHS; - break; - case 0xE8: /* FLD1 */ - FLD(1); - break; - case 0xEE: /* FLDZ */ - FLD(0); - break; - } } @@ -192,14 +83,18 @@ void FPU_ESC3_EA(Bitu rm,PhysPt addr) { } void FPU_ESC3_Normal(Bitu rm) { - switch( rm ) { - case 0xE3: /* FINIT */ - FPU_ParseCW(0x037F); - for(int i=0;i<8;i++) { - fpu_regs.st[i].r = 0; - fpu_regs.st[i].tag = FPUREG_EMPTY; - } + Bitu group=(rm >> 3) & 7; + Bitu sub=(rm & 7); + switch (group) { + case 0x04: + switch (sub) { + case 0x03: //FINIT + FPU_FINIT(); break; + default: + LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub); + } + LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d",group); } } @@ -212,23 +107,6 @@ void FPU_ESC4_Normal(Bitu rm) { void FPU_ESC5_EA(Bitu rm,PhysPt addr) { - Bit16u sw; - Bitu opcode = (rm&0x38)>>3; - - switch(opcode) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: /* FSTSW */ - FPU_LOADFLAGS; - FPU_makeSW(sw); - SaveMw(addr,sw); - break; - } } void FPU_ESC5_Normal(Bitu rm) { @@ -239,27 +117,6 @@ void FPU_ESC6_EA(Bitu rm,PhysPt addr) { } void FPU_ESC6_Normal(Bitu rm) { - Bitu opcode = (rm&0xF0); - - if(rm==0xD9) { /* FCOMPP */ - FCOMPP; - return; - } - switch(opcode) { - case 0xC0: -// if(rm&8) - break; - case 0xD0: -// if(rm&8) - break; - case 0xE0: -// if(rm&8) - break; - case 0xF0: - if(rm&8) - FDIVP(rm-0xF8,0); - break; - } } @@ -271,7 +128,7 @@ void FPU_ESC7_Normal(Bitu rm) { void FPU_Init(void) { - fpu_flags.type = t_FUNKNOWN; + FPU_FINIT(); } #endif diff --git a/src/fpu/fpu_flags.cpp b/src/fpu/fpu_flags.cpp deleted file mode 100644 index 924614fc..00000000 --- a/src/fpu/fpu_flags.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2002 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "dosbox.h" -#include "fpu.h" -#include "pic.h" -#include "fpu_types.h" -extern FPU_Flag_Info fpu_flags; - -bool FPU_get_C3() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.c3; - case t_FCOMP: - return (fpu_flags.result.tag==FPUREG_EMPTY||fpu_flags.result.tag==FPUREG_ZERO); - default: - E_Exit("FPU_get_C3 Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_C2() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.c2; - case t_FCOMP: - return (fpu_flags.result.tag==FPUREG_EMPTY); - default: - E_Exit("FPU_get_C2 Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_C1() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.c1; - case t_FCOMP: - return false; /* FIXME */ - default: - E_Exit("FPU_get_C1 Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_C0() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.c0; - case t_FCOMP: - return (fpu_flags.result.tag!=FPUREG_ZERO&&fpu_flags.result.tag!=FPUREG_PNAN); - default: - E_Exit("FPU_get_C0 Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_IR() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - case t_FCOMP: - return fpu_flags.sw.ir; - default: - E_Exit("FPU_get_IR Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_SF() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.sf; - case t_FCOMP: - return false; /* FIXME */ - default: - E_Exit("FPU_get_SF Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_PF() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - case t_FCOMP: - return fpu_flags.sw.pf; - default: - E_Exit("FPU_get_PF Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_UF() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - case t_FCOMP: - return fpu_flags.sw.uf; - default: - E_Exit("FPU_get_UF Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_OF() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - case t_FCOMP: - return fpu_flags.sw.of; - default: - E_Exit("FPU_get_OF Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_ZF() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - case t_FCOMP: - return fpu_flags.sw.zf; - case t_FDIV: - case t_FDIVP: - return (fpu_flags.result.tag==FPUREG_PNAN||fpu_flags.result.tag==FPUREG_NNAN); - default: - E_Exit("FPU_get_ZF Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_DF() { - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.df; - case t_FCOMP: - return false; /* FIXME */ - default: - E_Exit("FPU_get_DF Unknown %d",fpu_flags.type); - } - return 0; -} - -bool FPU_get_IN(){ - switch(fpu_flags.type) { - case t_FLD: - case t_FLDST: - case t_FDIV: - case t_FDIVP: - case t_FCHS: - case t_FUNKNOWN: - case t_FNOTDONE: - return fpu_flags.sw.in; - case t_FCOMP: - return (fpu_flags.result.tag==FPUREG_EMPTY); /* FIXME */ - default: - E_Exit("FPU_get_IN Unknown %d",fpu_flags.type); - } - return 0; -} diff --git a/src/fpu/fpu_instructions.h b/src/fpu/fpu_instructions.h index 49de9d00..3b133566 100644 --- a/src/fpu/fpu_instructions.h +++ b/src/fpu/fpu_instructions.h @@ -16,147 +16,16 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define FLD(op1) { \ - FPU_GetZF; \ - fpu_flags.type=t_FLD; \ - if(--fpu_flags.sw.tos < 0) \ - fpu_flags.sw.tos = 7; \ - if( fpu_regs.st[fpu_flags.sw.tos].tag != FPUREG_EMPTY ) { \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ - break; \ - } \ - if(op1) \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_VALID; \ - else \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_ZERO; \ - fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = op1; \ -} - -#define FLDST(op1) { \ - FPU_GetZF; \ - fpu_flags.type=t_FLDST; \ - Bit8u reg = fpu_flags.sw.tos+op1; \ - if(reg>7) reg-=8; \ - if(--fpu_flags.sw.tos < 0) \ - fpu_flags.sw.tos = 7; \ - if(fpu_regs.st[fpu_flags.sw.tos].tag!=FPUREG_EMPTY) { \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ - break; \ - } \ - fpu_flags.result.tag = fpu_regs.st[fpu_flags.sw.tos].tag = fpu_regs.st[reg].tag; \ - fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = fpu_regs.st[reg].r; \ -} - -#define FPOP { \ - fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_EMPTY; \ - if(++fpu_flags.sw.tos > 7 ) \ - fpu_flags.sw.tos = 0; \ -} -/* FPOP: fpu_flags.result.r = fpu_regs.st[fpu_flags.sw.tos].r = 0; is not really neccessary */ - -#define FDIVP(op1,op2) { \ - Bit8u reg1 = fpu_flags.sw.tos+op1; \ - Bit8u reg2 = fpu_flags.sw.tos+op2; \ - fpu_flags.type=t_FDIVP; \ - if(reg1>7) reg1-=8; \ - if(reg2>7) reg2-=8; \ - if((fpu_regs.st[reg1].tag!=FPUREG_VALID && fpu_regs.st[reg1].tag!=FPUREG_ZERO)||(fpu_regs.st[reg2].tag!=FPUREG_VALID && fpu_regs.st[reg2].tag!=FPUREG_ZERO)) { \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ - FPOP; \ - break; \ - } \ - if(fpu_regs.st[reg2].tag == FPUREG_ZERO) { \ - if(fpu_regs.st[reg1].r > 0) \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_PNAN; \ - else \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ - FPOP; \ - break; \ - } \ - if(fpu_regs.st[reg1].tag == FPUREG_ZERO) { \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_ZERO; \ - FPOP; \ - break; \ - } \ - fpu_flags.result.tag = FPUREG_VALID; \ - fpu_flags.result.r = fpu_regs.st[reg1].r = fpu_regs.st[reg1].r / fpu_regs.st[reg2].r; \ - FPOP; \ -} - -#define FDIV(op1,op2) { \ - Bit8u reg1 = fpu_flags.sw.tos+op1; \ - Bit8u reg2 = fpu_flags.sw.tos+op2; \ - fpu_flags.type=t_FDIV; \ - if(reg1>7) reg1-=7; \ - if(reg2>7) reg2-=7; \ - if((fpu_regs.st[reg1].tag!=FPUREG_VALID && fpu_regs.st[reg1].tag!=FPUREG_ZERO)||(fpu_regs.st[reg2].tag!=FPUREG_VALID && fpu_regs.st[reg2].tag!=FPUREG_ZERO)) { \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ - break; \ - } \ - if(fpu_regs.st[reg2].tag == FPUREG_ZERO) { \ - if(fpu_regs.st[reg1].r > 0) \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_PNAN; \ - else \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_NNAN; \ - break; \ - } \ - if(fpu_regs.st[reg1].tag == FPUREG_ZERO) { \ - fpu_flags.result.tag = fpu_regs.st[reg1].tag = FPUREG_ZERO; \ - break; \ - } \ - fpu_flags.result.tag = FPUREG_VALID; \ - fpu_flags.result.r = fpu_regs.st[reg1].r = fpu_regs.st[reg1].r / fpu_regs.st[reg2].r; \ -} - -#define FCHS { \ - FPU_GetZF; \ - fpu_flags.type=t_FCHS; \ - if(fpu_regs.st[fpu_flags.sw.tos].tag == FPUREG_PNAN) { \ - fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_NNAN; \ - } else if(fpu_regs.st[fpu_flags.sw.tos].tag == FPUREG_NNAN) { \ - fpu_regs.st[fpu_flags.sw.tos].tag = FPUREG_PNAN; \ - } else \ - fpu_regs.st[fpu_flags.sw.tos].r = -fpu_regs.st[fpu_flags.sw.tos].r; \ -} - -#define FCOMPP { \ - Bit8u reg = fpu_flags.sw.tos+1; \ - FPU_GetZF; \ - fpu_flags.type=t_FCOMP; \ - if(reg>7) \ - reg=0; \ - if((fpu_regs.st[reg].tag==FPUREG_VALID||fpu_regs.st[reg].tag==FPUREG_ZERO)&&(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_VALID||fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_ZERO)) { \ - fpu_flags.result.r = fpu_regs.st[reg].r - fpu_regs.st[fpu_flags.sw.tos].r; \ - if(fpu_flags.result.r==0) \ - fpu_flags.result.tag = FPUREG_ZERO; \ - else \ - fpu_flags.result.tag = FPUREG_VALID; \ - FPOP; \ - FPOP; \ - return; \ - } else if(((fpu_regs.st[reg].tag==FPUREG_EMPTY)||(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_EMPTY))||((fpu_regs.st[reg].tag==FPUREG_VALID||fpu_regs.st[reg].tag==FPUREG_ZERO)||(fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_VALID||fpu_regs.st[fpu_flags.sw.tos].tag==FPUREG_ZERO))) { \ - fpu_flags.result.tag = FPUREG_EMPTY; \ - FPOP; \ - FPOP; \ - return; \ - } \ - Bit8s res = (fpu_regs.st[reg].tag-fpu_regs.st[fpu_flags.sw.tos].tag); \ - if(res==0||fpu_flags.cw.ic==0) { \ - fpu_flags.result.tag = FPUREG_ZERO; \ - FPOP; \ - FPOP; \ - return; \ - } else if(res>0) { \ - fpu_flags.result.tag = FPUREG_NNAN; \ - FPOP; \ - FPOP; \ - return; \ - } \ - fpu_flags.result.tag = FPUREG_PNAN; \ - FPOP; \ - FPOP; \ -} - - - +static void FPU_FINIT(void) { + FPU_SetCW(0x37); + fpu.sw=0; + fpu.tags[0]=TAG_Empty; + fpu.tags[1]=TAG_Empty; + fpu.tags[2]=TAG_Empty; + fpu.tags[3]=TAG_Empty; + fpu.tags[4]=TAG_Empty; + fpu.tags[5]=TAG_Empty; + fpu.tags[6]=TAG_Empty; + fpu.tags[7]=TAG_Empty; +} \ No newline at end of file diff --git a/src/fpu/fpu_types.h b/src/fpu/fpu_types.h index 2d0ced0f..ce9cfaec 100644 --- a/src/fpu/fpu_types.h +++ b/src/fpu/fpu_types.h @@ -1,33 +1,39 @@ +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; + +/* the following deal with IEEE double-precision numbers */ +#define MAXEXPD 0x7ff +#define EXPBIAS 1023 +#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) +#define SIGND(fp) ((fp.l.upper) & 0x80000000) +#define MANTD(fp) (fp.ll & ((1LL << 52) - 1)) +#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20) -enum { FPUREG_VALID=0, FPUREG_ZERO, FPUREG_PNAN, FPUREG_NNAN, FPUREG_EMPTY }; - -enum { - t_FLD=0, t_FLDST, t_FDIV, - t_FDIVP, t_FCHS, t_FCOMP, - - t_FUNKNOWN, - t_FNOTDONE +enum FPU_Tag { + TAG_Valid = 0, + TAG_Zero = 1, + TAG_Weird = 2, + TAG_Empty = 3 }; -struct FPU_Flag_Info { - struct { - Real64 r; - Bit8u tag; - } var1,var2, result; - struct { - bool bf,c3,c2,c1,c0,ir,sf,pf,uf,of,zf,df,in; - Bit8s tos; - } sw; - struct { - bool ic,ie,sf,pf,uf,of,zf,df,in; - Bit8u rc,pc; - } cw; - Bitu type; - Bitu prev_type; -}; -struct FPU_Reg { - Real64 r; - Bit8u tag; -}; +enum FPU_Round { + ROUND_Nearest = 0, + ROUND_Down = 1, + ROUND_Up = 2, + ROUND_Chop = 3 +}; \ No newline at end of file