macemu/BasiliskII/src/uae_cpu/fpu/core.h

269 lines
9.8 KiB
C

/*
* fpu/core.h - base fpu context definition
*
* Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS)
*
* Inspired by Christian Bauer's Basilisk II
*
* This file is part of the ARAnyM project which builds a new and powerful
* TOS/FreeMiNT compatible virtual machine running on almost any hardware.
*
* MC68881/68040 fpu emulation
*
* Original UAE FPU, copyright 1996 Herman ten Brugge
* Rewrite for x86, copyright 1999-2001 Lauri Pesonen
* New framework, copyright 2000-2001 Gwenole Beauchesne
* Adapted for JIT compilation (c) Bernd Meyer, 2000-2001
*
* ARAnyM 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.
*
* ARAnyM 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 ARAnyM; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef FPU_CORE_H
#define FPU_CORE_H
#include "sysdeps.h"
#include "fpu/types.h"
/* Always use x87 FPU stack on IA-32. */
#if defined(X86_ASSEMBLY)
#define USE_X87_ASSEMBLY 1
#ifndef USE_JIT_FPU
#define ACCURATE_SIN_COS_TAN 1
#endif
#endif
/* Only use x87 FPU on x86-64 if long double precision is requested. */
#if defined(X86_64_ASSEMBLY) && defined(USE_LONG_DOUBLE)
#define USE_X87_ASSEMBLY 1
#define ACCURATE_SIN_COS_TAN 1
#endif
/* ========================================================================== */
/* ========================= FPU CONTEXT DEFINITION ========================= */
/* ========================================================================== */
/* We don't use all features of the C++ language so that we may still
* easily backport that code to C.
*/
struct fpu_t {
/* ---------------------------------------------------------------------- */
/* --- Floating-Point Data Registers --- */
/* ---------------------------------------------------------------------- */
/* The eight %fp0 .. %fp7 registers */
fpu_register registers[8];
/* Used for lazy evalualation of FPU flags */
fpu_register result;
/* ---------------------------------------------------------------------- */
/* --- Floating-Point Control Register --- */
/* ---------------------------------------------------------------------- */
struct {
/* Exception Enable Byte */
uae_u32 exception_enable;
#define FPCR_EXCEPTION_ENABLE 0x0000ff00
#define FPCR_EXCEPTION_BSUN 0x00008000
#define FPCR_EXCEPTION_SNAN 0x00004000
#define FPCR_EXCEPTION_OPERR 0x00002000
#define FPCR_EXCEPTION_OVFL 0x00001000
#define FPCR_EXCEPTION_UNFL 0x00000800
#define FPCR_EXCEPTION_DZ 0x00000400
#define FPCR_EXCEPTION_INEX2 0x00000200
#define FPCR_EXCEPTION_INEX1 0x00000100
/* Mode Control Byte Mask */
#define FPCR_MODE_CONTROL 0x000000ff
/* Rounding precision */
uae_u32 rounding_precision;
#define FPCR_ROUNDING_PRECISION 0x000000c0
#define FPCR_PRECISION_SINGLE 0x00000040
#define FPCR_PRECISION_DOUBLE 0x00000080
#define FPCR_PRECISION_EXTENDED 0x00000000
/* Rounding mode */
uae_u32 rounding_mode;
#define FPCR_ROUNDING_MODE 0x00000030
#define FPCR_ROUND_NEAR 0x00000000
#define FPCR_ROUND_ZERO 0x00000010
#define FPCR_ROUND_MINF 0x00000020
#define FPCR_ROUND_PINF 0x00000030
} fpcr;
/* ---------------------------------------------------------------------- */
/* --- Floating-Point Status Register --- */
/* ---------------------------------------------------------------------- */
struct {
/* Floating-Point Condition Code Byte */
uae_u32 condition_codes;
#define FPSR_CCB 0x0f000000
#define FPSR_CCB_NEGATIVE 0x08000000
#define FPSR_CCB_ZERO 0x04000000
#define FPSR_CCB_INFINITY 0x02000000
#define FPSR_CCB_NAN 0x01000000
/* Quotient Byte */
uae_u32 quotient;
#define FPSR_QUOTIENT 0x00ff0000
#define FPSR_QUOTIENT_SIGN 0x00800000
#define FPSR_QUOTIENT_VALUE 0x007f0000
/* Exception Status Byte */
uae_u32 exception_status;
#define FPSR_EXCEPTION_STATUS FPCR_EXCEPTION_ENABLE
#define FPSR_EXCEPTION_BSUN FPCR_EXCEPTION_BSUN
#define FPSR_EXCEPTION_SNAN FPCR_EXCEPTION_SNAN
#define FPSR_EXCEPTION_OPERR FPCR_EXCEPTION_OPERR
#define FPSR_EXCEPTION_OVFL FPCR_EXCEPTION_OVFL
#define FPSR_EXCEPTION_UNFL FPCR_EXCEPTION_UNFL
#define FPSR_EXCEPTION_DZ FPCR_EXCEPTION_DZ
#define FPSR_EXCEPTION_INEX2 FPCR_EXCEPTION_INEX2
#define FPSR_EXCEPTION_INEX1 FPCR_EXCEPTION_INEX1
/* Accrued Exception Byte */
uae_u32 accrued_exception;
#define FPSR_ACCRUED_EXCEPTION 0x000000ff
#define FPSR_ACCR_IOP 0x00000080
#define FPSR_ACCR_OVFL 0x00000040
#define FPSR_ACCR_UNFL 0x00000020
#define FPSR_ACCR_DZ 0x00000010
#define FPSR_ACCR_INEX 0x00000008
} fpsr;
/* ---------------------------------------------------------------------- */
/* --- Floating-Point Instruction Address Register --- */
/* ---------------------------------------------------------------------- */
uae_u32 instruction_address;
/* ---------------------------------------------------------------------- */
/* --- Initialization / Finalization --- */
/* ---------------------------------------------------------------------- */
/* Flag set if we emulate an integral 68040 FPU */
bool is_integral;
/* ---------------------------------------------------------------------- */
/* --- Extra FPE-dependant defines --- */
/* ---------------------------------------------------------------------- */
#if defined(FPU_X86) \
|| (defined(FPU_UAE) && defined(USE_X87_ASSEMBLY)) \
|| (defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY))
#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_ROUNDING_MODE 0x0C00
#define X86_ROUNDING_PRECISION 0x0300
#endif /* FPU_X86 */
};
/* We handle only one global fpu */
extern fpu_t fpu;
/* Return the address of a particular register */
inline fpu_register * fpu_register_address(int i)
{ return &fpu.registers[i]; }
/* Dump functions for m68k_dumpstate */
extern void fpu_dump_registers(void);
extern void fpu_dump_flags(void);
/* Accessors to FPU Control Register */
//static inline uae_u32 get_fpcr(void);
//static inline void set_fpcr(uae_u32 new_fpcr);
/* Accessors to FPU Status Register */
//static inline uae_u32 get_fpsr(void);
//static inline void set_fpsr(uae_u32 new_fpsr);
/* Accessors to FPU Instruction Address Register */
//static inline uae_u32 get_fpiar();
//static inline void set_fpiar(uae_u32 new_fpiar);
/* Initialization / Finalization */
extern void fpu_init(bool integral_68040);
extern void fpu_exit(void);
extern void fpu_reset(void);
/* Floating-point arithmetic instructions */
void fpuop_arithmetic(uae_u32 opcode, uae_u32 extra) REGPARAM;
/* Floating-point program control operations */
void fpuop_bcc(uae_u32 opcode, uaecptr pc, uae_u32 extra) REGPARAM;
void fpuop_dbcc(uae_u32 opcode, uae_u32 extra) REGPARAM;
void fpuop_scc(uae_u32 opcode, uae_u32 extra) REGPARAM;
/* Floating-point system control operations */
void fpuop_save(uae_u32 opcode) REGPARAM;
void fpuop_restore(uae_u32 opcode) REGPARAM;
void fpuop_trapcc(uae_u32 opcode, uaecptr oldpc, uae_u32 extra) REGPARAM;
#endif /* FPU_CORE_H */