port some changes from spftfloat-fpu branch to the MT

This commit is contained in:
Stanislav Shwartsman 2004-04-09 15:34:59 +00:00
parent ac6bed9a17
commit cf6d1b8bd9
12 changed files with 1584 additions and 1758 deletions

View File

@ -10,10 +10,13 @@ Changes to next release:
- CS segment not present exception processing with IRET
- add MSVC host asm instructions (patch by suzu)
- fixed bug in HADDPD/HSUBPD (SSE3) instructions
- fixed bug in float to integer convert instructions
- fixed bug in float to integer SSE/SSE2 convert instructions
- fixed BCD instructions implementation
- speed optimizations in MMX and CPU core (sshwarts and psychosmur)
- FPU
- fixed #NM exception on when FPU is disabled for FPU opcodes
- I/O devices
- general
- handle cpu reset through port 0x92

View File

@ -29,7 +29,7 @@
static void prepare_softfloat_status_word
(softfloat_status_word_t &status, int rounding_mode)
{
status.float_detect_tininess = float_tininess_before_rounding;
status.float_detect_tininess = float_tininess_after_rounding;
status.float_exception_flags = 0; // clear exceptions before execution
status.float_nan_handling_mode = float_first_operand_nan;
status.float_rounding_mode = rounding_mode;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.161 2004-02-26 19:17:37 sshwarts Exp $
// $Id: cpu.h,v 1.162 2004-04-09 15:34:57 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1867,8 +1867,13 @@ union {
BX_SMF void BTR_EvIb(bxInstruction_c *);
BX_SMF void BTC_EvIb(bxInstruction_c *);
#if BX_SUPPORT_FPU == 0 // if FPU is disabled
BX_SMF void FPU_ESC(bxInstruction_c *);
#endif
BX_SMF void FWAIT(bxInstruction_c *);
#if BX_SUPPORT_FPU
BX_SMF void FLD_STi(bxInstruction_c *);
BX_SMF void FLD_SINGLE_REAL(bxInstruction_c *);
BX_SMF void FLD_DOUBLE_REAL(bxInstruction_c *);
@ -2028,6 +2033,7 @@ union {
BX_SMF void FNCLEX(bxInstruction_c *);
BX_SMF void FNINIT(bxInstruction_c *);
BX_SMF void FFREE_STi(bxInstruction_c *);
#endif
/* MMX */
BX_SMF void PUNPCKLBW_PqQd(bxInstruction_c *i);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode.cc,v 1.61 2003-12-28 18:19:41 sshwarts Exp $
// $Id: fetchdecode.cc,v 1.62 2004-04-09 15:34:57 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -682,6 +682,7 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
/* D5 */ { BxImmediate_Ib, &BX_CPU_C::AAD },
/* D6 */ { 0, &BX_CPU_C::SALC },
/* D7 */ { 0, &BX_CPU_C::XLAT },
#if BX_SUPPORT_FPU
// by default we have here pointer to the group .. as if mod <> 11b
/* D8 */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupD8 },
/* D9 */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupD9 },
@ -691,6 +692,16 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
/* DD */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDD },
/* DE */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDE },
/* DF */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDF },
#else
/* D8 */ { 0, &BX_CPU_C::FPU_ESC },
/* D9 */ { 0, &BX_CPU_C::FPU_ESC },
/* DA */ { 0, &BX_CPU_C::FPU_ESC },
/* DB */ { 0, &BX_CPU_C::FPU_ESC },
/* DC */ { 0, &BX_CPU_C::FPU_ESC },
/* DD */ { 0, &BX_CPU_C::FPU_ESC },
/* DE */ { 0, &BX_CPU_C::FPU_ESC },
/* DF */ { 0, &BX_CPU_C::FPU_ESC },
#endif
/* E0 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPNE_Jb },
/* E1 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPE_Jb },
/* E2 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOP_Jb },
@ -1217,6 +1228,7 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
/* D5 */ { BxImmediate_Ib, &BX_CPU_C::AAD },
/* D6 */ { 0, &BX_CPU_C::SALC },
/* D7 */ { 0, &BX_CPU_C::XLAT },
#if BX_SUPPORT_FPU
// by default we have here pointer to the group .. as if mod <> 11b
/* D8 */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupD8 },
/* D9 */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupD9 },
@ -1226,6 +1238,16 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
/* DD */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDD },
/* DE */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDE },
/* DF */ { BxAnother | BxFPGroup, NULL, BxOpcodeInfo_FPGroupDF },
#else
/* D8 */ { 0, &BX_CPU_C::FPU_ESC },
/* D9 */ { 0, &BX_CPU_C::FPU_ESC },
/* DA */ { 0, &BX_CPU_C::FPU_ESC },
/* DB */ { 0, &BX_CPU_C::FPU_ESC },
/* DC */ { 0, &BX_CPU_C::FPU_ESC },
/* DD */ { 0, &BX_CPU_C::FPU_ESC },
/* DE */ { 0, &BX_CPU_C::FPU_ESC },
/* DF */ { 0, &BX_CPU_C::FPU_ESC },
#endif
/* E0 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPNE_Jb },
/* E1 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPE_Jb },
/* E2 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOP_Jb },
@ -1865,15 +1887,16 @@ modrm_done:
*/
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[mod==0xc0]);
break;
#if BX_SUPPORT_FPU
case BxFPGroup:
if (mod != 0xc0) // mod != 11b
OpcodeInfoPtr = &(OpcodeInfoPtr->AnotherArray[nnn]);
else
{
else {
int index = (b1-0xD8)*64 + (0x3f & b2);
OpcodeInfoPtr = &(BxOpcodeInfo_FloatingPoint[index]);
}
break;
#endif
default:
BX_PANIC(("fetchdecode: Unknown opcode group"));
}

View File

@ -53,6 +53,8 @@ BX_CPP_INLINE Bit64u FetchQWORD(Bit8u *iptr)
// according to instruction prefixes)
//
#if BX_SUPPORT_FPU
/* ************************************************************************ */
/* FPU Opcodes */
@ -687,6 +689,8 @@ static BxOpcodeInfo_t BxOpcodeInfo_FloatingPoint[512] = {
/* DF FF */ { 0, &BX_CPU_C::BxError },
};
#endif
/* ************************************************************************ */
/* 3DNow! Opcodes */

File diff suppressed because it is too large Load Diff

View File

@ -1,159 +0,0 @@
/////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004 MandrakeSoft S.A.
//
// MandrakeSoft S.A.
// 43, rue d'Aboukir
// 75002 Paris - France
// http://www.linux-mandrake.com/
// http://www.mandrakesoft.com/
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
/////////////////////////////////////////////////////////////////////////
#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#define LOG_THIS BX_CPU_THIS_PTR
#if BX_SUPPORT_FPU
#include "softfloat-fpu.h"
#endif
/* D9 C8 */
void BX_CPU_C::FXCH_STi(bxInstruction_c *i)
{
#if BX_SUPPORT_FPU
BX_CPU_THIS_PTR prepareFPU(i);
int st0_tag = BX_CPU_THIS_PTR the_i387.FPU_gettagi(0);
int sti_tag = BX_CPU_THIS_PTR the_i387.FPU_gettagi(i->rm());
floatx80 st0_reg = BX_READ_FPU_REG(0);
floatx80 sti_reg = BX_READ_FPU_REG(i->rm());
clear_C1();
if (st0_tag == FPU_Tag_Empty || sti_tag == FPU_Tag_Empty)
{
BX_CPU_THIS_PTR FPU_exception(FPU_EX_Stack_Underflow);
if(BX_CPU_THIS_PTR the_i387.is_IA_masked())
{
/* Masked response */
if (st0_tag == FPU_Tag_Empty)
{
st0_reg = Const_QNaN;
st0_tag = FPU_Tag_Special;
}
if (sti_tag == FPU_Tag_Empty)
{
sti_reg = Const_QNaN;
sti_tag = FPU_Tag_Special;
}
}
else return;
}
BX_WRITE_FPU_REGISTER_AND_TAG(st0_reg, st0_tag, i->rm());
BX_WRITE_FPU_REGISTER_AND_TAG(sti_reg, sti_tag, 0);
#else
BX_INFO(("FXCH_STi: required FPU, configure --enable-fpu"));
#endif
}
/* D9 E0 */
void BX_CPU_C::FCHS(bxInstruction_c *i)
{
#if BX_SUPPORT_FPU
BX_CPU_THIS_PTR prepareFPU(i);
int st0_tag = BX_CPU_THIS_PTR the_i387.FPU_gettagi(0);
if (st0_tag == FPU_Tag_Empty)
{
BX_CPU_THIS_PTR FPU_stack_underflow(0);
return;
}
clear_C1();
floatx80 st0_reg = BX_READ_FPU_REG(0);
BX_WRITE_FPU_REGISTER_AND_TAG(floatx80_chs(st0_reg), st0_tag, 0);
#else
BX_INFO(("FCHS: required FPU, configure --enable-fpu"));
#endif
}
/* D9 E1 */
void BX_CPU_C::FABS(bxInstruction_c *i)
{
#if BX_SUPPORT_FPU
BX_CPU_THIS_PTR prepareFPU(i);
int st0_tag = BX_CPU_THIS_PTR the_i387.FPU_gettagi(0);
if (st0_tag == FPU_Tag_Empty)
{
BX_CPU_THIS_PTR FPU_stack_underflow(0);
return;
}
clear_C1();
floatx80 st0_reg = BX_READ_FPU_REG(0);
BX_WRITE_FPU_REGISTER_AND_TAG(floatx80_abs(st0_reg), st0_tag, 0);
#else
BX_INFO(("FABS: required FPU, configure --enable-fpu"));
#endif
}
/* D9 F6 */
void BX_CPU_C::FDECSTP(bxInstruction_c *i)
{
#if BX_SUPPORT_FPU
BX_CPU_THIS_PTR prepareFPU(i);
clear_C1();
BX_CPU_THIS_PTR the_i387.tos = (BX_CPU_THIS_PTR the_i387.tos-1) & 7;
#else
BX_INFO(("FDECSTP: required FPU, configure --enable-fpu"));
#endif
}
/* D9 F7 */
void BX_CPU_C::FINCSTP(bxInstruction_c *i)
{
#if BX_SUPPORT_FPU
BX_CPU_THIS_PTR prepareFPU(i);
clear_C1();
BX_CPU_THIS_PTR the_i387.tos = (BX_CPU_THIS_PTR the_i387.tos+1) & 7;
#else
BX_INFO(("FINCSTP: required FPU, configure --enable-fpu"));
#endif
}
/* DD C0 */
void BX_CPU_C::FFREE_STi(bxInstruction_c *i)
{
#if BX_SUPPORT_FPU
BX_CPU_THIS_PTR prepareFPU(i);
BX_CPU_THIS_PTR the_i387.FPU_settagi(FPU_Tag_Empty, i->rm());
#else
BX_INFO(("FFREE_STi: required FPU, configure --enable-fpu"));
#endif
}

View File

@ -1,104 +0,0 @@
/*============================================================================
This source file is an extension to the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
floating point emulation.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/
/*============================================================================
* Adapted for Bochs (x86 achitecture simulator) by
* Stanislav Shwartsman (gate at fidonet.org.il)
* ==========================================================================*/
#include "softfloat.h"
/*----------------------------------------------------------------------------
| Functions and definitions to determine: (1) whether tininess for underflow
| is detected before or after rounding by default, (2) what (if anything)
| happens when exceptions are raised, (3) how signaling NaNs are distinguished
| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
| are propagated from function inputs to output. These details are target-
| specific.
*----------------------------------------------------------------------------*/
#include "softfloat-specialize.h"
/*-----------------------------------------------------------------------------
| Calculates the absolute value of the extended double-precision floating-point
| value `a'. The operation is performed according to the IEC/IEEE Standard
| for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE floatx80& floatx80_abs(floatx80 &reg)
{
reg.exp &= 0x7FFF;
return reg;
}
/*-----------------------------------------------------------------------------
| Changes the sign of the extended double-precision floating-point value 'a'.
| The operation is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE floatx80& floatx80_chs(floatx80 &reg)
{
reg.exp ^= 0x8000;
return reg;
}
/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the 16-bit two's complement integer format. The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic - which means in particular that the conversion
| is rounded according to the current rounding mode. If `a' is a NaN or the
| conversion overflows, the integer indefinite value is returned.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE Bit16s floatx80_to_int16(floatx80 a, float_status_t &status)
{
Bit32s v32 = floatx80_to_int32(a, status);
if ((v32 > (Bit32s) BX_MAX_BIT16S) || (v32 < (Bit32s) BX_MIN_BIT16S))
{
float_raise(status, float_flag_invalid);
return int16_indefinite;
}
return (Bit16s) v32;
}
/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the 16-bit two's complement integer format. The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic, except that the conversion is always rounded
| toward zero. If `a' is a NaN or the conversion overflows, the integer
| indefinite value is returned.
*----------------------------------------------------------------------------*/
BX_CPP_INLINE Bit16s floatx80_to_int16_round_to_zero(floatx80 a, float_status_t &status)
{
Bit32s v32 = floatx80_to_int32_round_to_zero(a, status);
if ((v32 > (Bit32s) BX_MAX_BIT16S) || (v32 < (Bit32s) BX_MIN_BIT16S))
{
float_raise(status, float_flag_invalid);
return int16_indefinite;
}
return (Bit16s) v32;
}

View File

@ -42,7 +42,7 @@ void BX_CPU_C::check_exceptionsSSE(int exceptions_flags)
static void mxcsr_to_softfloat_status_word(softfloat_status_word_t &status, bx_mxcsr_t mxcsr)
{
status.float_detect_tininess = float_tininess_before_rounding;
status.float_detect_tininess = float_tininess_after_rounding;
status.float_exception_flags = 0; // clear exceptions before execution
status.float_nan_handling_mode = float_first_operand_nan;
status.float_rounding_mode = mxcsr.get_rounding_mode();

View File

@ -53,7 +53,7 @@ L_TARGET = libfpu.a
BX_INCDIRS = -I.. -I$(srcdir)/.. -I../@INSTRUMENT_DIR@ -I$(srcdir)/../@INSTRUMENT_DIR@ -I. -I$(srcdir)/. -I./stubs -I$(srcdir)/./stubs
FPU_FLAGS = -DUSE_WITH_CPU_SIM $(PARANOID) $(DEBUG) -DNO_ASSEMBLER
FPU_GLUE_OBJ = wmFPUemu_glue.o
FPU_GLUE_OBJ = wmFPUemu_glue.o fpu.o
# From 'C' language sources:
C_OBJS = fpu_entry.o errors.o reg_ld_str.o load_store.o \
@ -198,3 +198,16 @@ wmFPUemu_glue.o: wmFPUemu_glue.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
../iodev/gameport.h ../iodev/speaker.h ../instrument/stubs/instrument.h \
fpu_emu.h stubs/linux/linkage.h fpu_system.h fpu_proto.h \
stubs/linux/signal.h
fpu.o: fpu.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
../cpu/lazy_flags.h ../cpu/i387.h ../cpu/xmm.h ../memory/memory.h \
../pc_system.h ../plugin.h ../extplugin.h ../gui/gui.h \
../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/pci.h \
../iodev/pci2isa.h ../iodev/pcivga.h ../iodev/vga.h ../iodev/ioapic.h \
../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
../iodev/harddrv.h ../iodev/cdrom.h ../iodev/vmware3.h \
../iodev/keyboard.h ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h \
../iodev/pit_wrap.h ../iodev/pit82c54.h ../iodev/virt_timer.h \
../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
../iodev/guest2host.h ../iodev/slowdown_timer.h ../iodev/extfpuirq.h \
../instrument/stubs/instrument.h

1514
bochs/fpu/fpu.cc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: main.cc,v 1.273 2004-02-26 18:12:21 vruppert Exp $
// $Id: main.cc,v 1.274 2004-04-09 15:34:56 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -2566,6 +2566,7 @@ bx_init_hardware()
#if BX_SUPPORT_APIC
BX_CPU(0)->local_apic.set_id (0);
#endif
BX_CPU(0)->sanity_checks();
BX_INSTR_INIT(0);
BX_CPU(0)->reset(BX_RESET_HARDWARE);
#else
@ -2593,7 +2594,8 @@ bx_init_hardware()
// assign apic ID from the index of this loop
// if !BX_SUPPORT_APIC, this will not compile.
BX_CPU(i)->set_cpu_id(i);
BX_CPU(i)->local_apic.set_id (i);
BX_CPU(i)->local_apic.set_id(i);
BX_CPU(i)->sanity_checks();
BX_INSTR_INIT(i);
BX_CPU(i)->reset(BX_RESET_HARDWARE);
}