mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-06-12 04:29:29 +00:00
269 lines
9.8 KiB
C
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 */
|