mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-26 10:49:21 +00:00
Ported Lauri's FPU core to GCC/i386
This commit is contained in:
parent
fdf9c9938a
commit
9b2887536f
6459
BasiliskII/src/uae_cpu/fpu_x86.cpp
Normal file
6459
BasiliskII/src/uae_cpu/fpu_x86.cpp
Normal file
File diff suppressed because it is too large
Load Diff
134
BasiliskII/src/uae_cpu/fpu_x86.h
Normal file
134
BasiliskII/src/uae_cpu/fpu_x86.h
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* fpu_x86.h - 68881/68040 fpu code for x86/Windows and Linux/x86.
|
||||||
|
*
|
||||||
|
* Basilisk II (C) 1997-1999 Christian Bauer
|
||||||
|
*
|
||||||
|
* MC68881 emulation
|
||||||
|
*
|
||||||
|
* Based on UAE FPU, original copyright 1996 Herman ten Brugge,
|
||||||
|
* rewritten by Lauri Pesonen 1999-2000,
|
||||||
|
* accomodated to GCC's Extended Asm syntax by Gwenole Beauchesne 2000.
|
||||||
|
*
|
||||||
|
* 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 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* gb-- defined in newcpu.h
|
||||||
|
// is_integral: true == 68040, false == 68881
|
||||||
|
void fpu_set_integral_fpu( bool is_integral );
|
||||||
|
|
||||||
|
// MUST be called before the cpu starts up.
|
||||||
|
void fpu_init( void );
|
||||||
|
|
||||||
|
// Finalize.
|
||||||
|
void fpu_exit( void );
|
||||||
|
|
||||||
|
// Soft reset.
|
||||||
|
void fpu_reset( void );
|
||||||
|
*/
|
||||||
|
|
||||||
|
// The same as original. "ftrapcc_opp" is bound to change soon.
|
||||||
|
/* gb-- defined in newcpu.h
|
||||||
|
void REGPARAM2 fpp_opp (uae_u32, uae_u16);
|
||||||
|
void REGPARAM2 fdbcc_opp (uae_u32, uae_u16);
|
||||||
|
void REGPARAM2 fscc_opp (uae_u32, uae_u16);
|
||||||
|
void REGPARAM2 ftrapcc_opp (uae_u32,uaecptr);
|
||||||
|
void REGPARAM2 fbcc_opp (uae_u32, uaecptr, uae_u32);
|
||||||
|
void REGPARAM2 fsave_opp (uae_u32);
|
||||||
|
void REGPARAM2 frestore_opp (uae_u32);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ---------------------------- Motorola ---------------------------- */
|
||||||
|
|
||||||
|
// Exception byte
|
||||||
|
#define BSUN 0x00008000
|
||||||
|
#define SNAN 0x00004000
|
||||||
|
#define OPERR 0x00002000
|
||||||
|
#define OVFL 0x00001000
|
||||||
|
#define UNFL 0x00000800
|
||||||
|
#define DZ 0x00000400
|
||||||
|
#define INEX2 0x00000200
|
||||||
|
#define INEX1 0x00000100
|
||||||
|
|
||||||
|
// Accrued exception byte
|
||||||
|
#define ACCR_IOP 0x80
|
||||||
|
#define ACCR_OVFL 0x40
|
||||||
|
#define ACCR_UNFL 0x20
|
||||||
|
#define ACCR_DZ 0x10
|
||||||
|
#define ACCR_INEX 0x08
|
||||||
|
|
||||||
|
// fpcr rounding modes
|
||||||
|
#define ROUND_CONTROL_MASK 0x30
|
||||||
|
#define ROUND_TO_NEAREST 0
|
||||||
|
#define ROUND_TO_ZERO 0x10
|
||||||
|
#define ROUND_TO_NEGATIVE_INFINITY 0x20
|
||||||
|
#define ROUND_TO_POSITIVE_INFINITY 0x30
|
||||||
|
|
||||||
|
// fpcr precision control
|
||||||
|
#define PRECISION_CONTROL_MASK 0xC0
|
||||||
|
#define PRECISION_CONTROL_EXTENDED 0
|
||||||
|
#define PRECISION_CONTROL_DOUBLE 0x80
|
||||||
|
#define PRECISION_CONTROL_SINGLE 0x40
|
||||||
|
#define PRECISION_CONTROL_UNDEFINED 0xC0
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------- Intel ---------------------------- */
|
||||||
|
|
||||||
|
#define CW_RESET 0x0040 // initial CW value after RESET
|
||||||
|
#define CW_FINIT 0x037F // initial CW value after FINIT
|
||||||
|
#define SW_RESET 0x0000 // initial SW value after RESET
|
||||||
|
#define SW_FINIT 0x0000 // initial SW value after FINIT
|
||||||
|
#define TW_RESET 0x5555 // initial TW value after RESET
|
||||||
|
#define TW_FINIT 0x0FFF // initial TW value after FINIT
|
||||||
|
|
||||||
|
#define CW_X 0x1000 // infinity control
|
||||||
|
#define CW_RC_ZERO 0x0C00 // rounding control toward zero
|
||||||
|
#define CW_RC_UP 0x0800 // rounding control toward +
|
||||||
|
#define CW_RC_DOWN 0x0400 // rounding control toward -
|
||||||
|
#define CW_RC_NEAR 0x0000 // rounding control toward even
|
||||||
|
#define CW_PC_EXTENDED 0x0300 // precision control 64bit
|
||||||
|
#define CW_PC_DOUBLE 0x0200 // precision control 53bit
|
||||||
|
#define CW_PC_RESERVED 0x0100 // precision control reserved
|
||||||
|
#define CW_PC_SINGLE 0x0000 // precision control 24bit
|
||||||
|
#define CW_PM 0x0020 // precision exception mask
|
||||||
|
#define CW_UM 0x0010 // underflow exception mask
|
||||||
|
#define CW_OM 0x0008 // overflow exception mask
|
||||||
|
#define CW_ZM 0x0004 // zero divide exception mask
|
||||||
|
#define CW_DM 0x0002 // denormalized operand exception mask
|
||||||
|
#define CW_IM 0x0001 // invalid operation exception mask
|
||||||
|
|
||||||
|
#define SW_B 0x8000 // busy flag
|
||||||
|
#define SW_C3 0x4000 // condition code flag 3
|
||||||
|
#define SW_TOP_7 0x3800 // top of stack = ST(7)
|
||||||
|
#define SW_TOP_6 0x3000 // top of stack = ST(6)
|
||||||
|
#define SW_TOP_5 0x2800 // top of stack = ST(5)
|
||||||
|
#define SW_TOP_4 0x2000 // top of stack = ST(4)
|
||||||
|
#define SW_TOP_3 0x1800 // top of stack = ST(3)
|
||||||
|
#define SW_TOP_2 0x1000 // top of stack = ST(2)
|
||||||
|
#define SW_TOP_1 0x0800 // top of stack = ST(1)
|
||||||
|
#define SW_TOP_0 0x0000 // top of stack = ST(0)
|
||||||
|
#define SW_C2 0x0400 // condition code flag 2
|
||||||
|
#define SW_C1 0x0200 // condition code flag 1
|
||||||
|
#define SW_C0 0x0100 // condition code flag 0
|
||||||
|
#define SW_ES 0x0080 // error summary status flag
|
||||||
|
#define SW_SF 0x0040 // stack fault flag
|
||||||
|
#define SW_PE 0x0020 // precision exception flag
|
||||||
|
#define SW_UE 0x0010 // underflow exception flag
|
||||||
|
#define SW_OE 0x0008 // overflow exception flag
|
||||||
|
#define SW_ZE 0x0004 // zero divide exception flag
|
||||||
|
#define SW_DE 0x0002 // denormalized operand exception flag
|
||||||
|
#define SW_IE 0x0001 // invalid operation exception flag
|
||||||
|
|
||||||
|
#define X86_ROUND_CONTROL_MASK 0x0C00
|
||||||
|
#define X86_PRECISION_CONTROL_MASK 0x0300
|
117
BasiliskII/src/uae_cpu/fpu_x86_asm.h
Normal file
117
BasiliskII/src/uae_cpu/fpu_x86_asm.h
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// gb-- stupid hack to insert macros in the generated assembly file
|
||||||
|
static void fpu_emit_macro_definitions()
|
||||||
|
{
|
||||||
|
# define DEFINE_MACRO(name, value) \
|
||||||
|
__asm__ __volatile__ (#name ## " = " #value)
|
||||||
|
DEFINE_MACRO(BSUN, 0x00008000);
|
||||||
|
DEFINE_MACRO(SNAN, 0x00004000);
|
||||||
|
DEFINE_MACRO(OPERR, 0x00002000);
|
||||||
|
DEFINE_MACRO(OVFL, 0x00001000);
|
||||||
|
DEFINE_MACRO(UNFL, 0x00000800);
|
||||||
|
DEFINE_MACRO(DZ, 0x00000400);
|
||||||
|
DEFINE_MACRO(INEX2, 0x00000200);
|
||||||
|
DEFINE_MACRO(INEX1, 0x00000100);
|
||||||
|
DEFINE_MACRO(ACCR_IOP, 0x80);
|
||||||
|
DEFINE_MACRO(ACCR_OVFL, 0x40);
|
||||||
|
DEFINE_MACRO(ACCR_UNFL, 0x20);
|
||||||
|
DEFINE_MACRO(ACCR_DZ, 0x10);
|
||||||
|
DEFINE_MACRO(ACCR_INEX, 0x08);
|
||||||
|
DEFINE_MACRO(ROUND_CONTROL_MASK, 0x30);
|
||||||
|
DEFINE_MACRO(ROUND_TO_NEAREST, 0);
|
||||||
|
DEFINE_MACRO(ROUND_TO_ZERO, 0x10);
|
||||||
|
DEFINE_MACRO(ROUND_TO_NEGATIVE_INFINITY, 0x20);
|
||||||
|
DEFINE_MACRO(ROUND_TO_POSITIVE_INFINITY, 0x30);
|
||||||
|
DEFINE_MACRO(PRECISION_CONTROL_MASK, 0xC0);
|
||||||
|
DEFINE_MACRO(PRECISION_CONTROL_EXTENDED, 0);
|
||||||
|
DEFINE_MACRO(PRECISION_CONTROL_DOUBLE, 0x80);
|
||||||
|
DEFINE_MACRO(PRECISION_CONTROL_SINGLE, 0x40);
|
||||||
|
DEFINE_MACRO(PRECISION_CONTROL_UNDEFINED, 0xC0);
|
||||||
|
DEFINE_MACRO(CW_RESET, 0x0040);
|
||||||
|
DEFINE_MACRO(CW_FINIT, 0x037F);
|
||||||
|
DEFINE_MACRO(SW_RESET, 0x0000);
|
||||||
|
DEFINE_MACRO(SW_FINIT, 0x0000);
|
||||||
|
DEFINE_MACRO(TW_RESET, 0x5555);
|
||||||
|
DEFINE_MACRO(TW_FINIT, 0x0FFF);
|
||||||
|
DEFINE_MACRO(CW_X, 0x1000);
|
||||||
|
DEFINE_MACRO(CW_RC_ZERO, 0x0C00);
|
||||||
|
DEFINE_MACRO(CW_RC_UP, 0x0800);
|
||||||
|
DEFINE_MACRO(CW_RC_DOWN, 0x0400);
|
||||||
|
DEFINE_MACRO(CW_RC_NEAR, 0x0000);
|
||||||
|
DEFINE_MACRO(CW_PC_EXTENDED, 0x0300);
|
||||||
|
DEFINE_MACRO(CW_PC_DOUBLE, 0x0200);
|
||||||
|
DEFINE_MACRO(CW_PC_RESERVED, 0x0100);
|
||||||
|
DEFINE_MACRO(CW_PC_SINGLE, 0x0000);
|
||||||
|
DEFINE_MACRO(CW_PM, 0x0020);
|
||||||
|
DEFINE_MACRO(CW_UM, 0x0010);
|
||||||
|
DEFINE_MACRO(CW_OM, 0x0008);
|
||||||
|
DEFINE_MACRO(CW_ZM, 0x0004);
|
||||||
|
DEFINE_MACRO(CW_DM, 0x0002);
|
||||||
|
DEFINE_MACRO(CW_IM, 0x0001);
|
||||||
|
DEFINE_MACRO(SW_B, 0x8000);
|
||||||
|
DEFINE_MACRO(SW_C3, 0x4000);
|
||||||
|
DEFINE_MACRO(SW_TOP_7, 0x3800);
|
||||||
|
DEFINE_MACRO(SW_TOP_6, 0x3000);
|
||||||
|
DEFINE_MACRO(SW_TOP_5, 0x2800);
|
||||||
|
DEFINE_MACRO(SW_TOP_4, 0x2000);
|
||||||
|
DEFINE_MACRO(SW_TOP_3, 0x1800);
|
||||||
|
DEFINE_MACRO(SW_TOP_2, 0x1000);
|
||||||
|
DEFINE_MACRO(SW_TOP_1, 0x0800);
|
||||||
|
DEFINE_MACRO(SW_TOP_0, 0x0000);
|
||||||
|
DEFINE_MACRO(SW_C2, 0x0400);
|
||||||
|
DEFINE_MACRO(SW_C1, 0x0200);
|
||||||
|
DEFINE_MACRO(SW_C0, 0x0100);
|
||||||
|
DEFINE_MACRO(SW_ES, 0x0080);
|
||||||
|
DEFINE_MACRO(SW_SF, 0x0040);
|
||||||
|
DEFINE_MACRO(SW_PE, 0x0020);
|
||||||
|
DEFINE_MACRO(SW_UE, 0x0010);
|
||||||
|
DEFINE_MACRO(SW_OE, 0x0008);
|
||||||
|
DEFINE_MACRO(SW_ZE, 0x0004);
|
||||||
|
DEFINE_MACRO(SW_DE, 0x0002);
|
||||||
|
DEFINE_MACRO(SW_IE, 0x0001);
|
||||||
|
DEFINE_MACRO(X86_ROUND_CONTROL_MASK, 0x0C00);
|
||||||
|
DEFINE_MACRO(X86_PRECISION_CONTROL_MASK, 0x0300);
|
||||||
|
# undef DEFINE_MACRO
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
awk=awk
|
||||||
|
ifile="fpu_x86.h"
|
||||||
|
ofile="fpu_x86_asm.h"
|
||||||
|
|
||||||
|
if [ ! -r "$ifile" ]; then
|
||||||
|
echo "Error: could not open input file ($ifile)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
touch $ofile
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: could not open output file ($ofile)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# header
|
||||||
|
cat > $ofile << EOF
|
||||||
|
// gb-- stupid hack to insert macros in the generated assembly file
|
||||||
|
static void fpu_emit_macro_definitions()
|
||||||
|
{
|
||||||
|
# define DEFINE_MACRO(name, value) \\
|
||||||
|
__asm__ __volatile__ (#name ## " = " #value)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# processing with awk
|
||||||
|
$awk '/#define/ { print " DEFINE_MACRO(" $2 ", " $3 ");"; }' $ifile >> $ofile
|
||||||
|
|
||||||
|
# footer
|
||||||
|
cat >> $ofile << EOF
|
||||||
|
# undef DEFINE_MACRO
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# insert this script
|
||||||
|
echo "/""*" >> $ofile
|
||||||
|
cat $0 >> $ofile
|
||||||
|
echo "*""/" >> $ofile
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
*/
|
Loading…
Reference in New Issue
Block a user