1 |
gbeauche |
1.1 |
/* |
2 |
|
|
* fpu/core.h - base fpu context definition |
3 |
|
|
* |
4 |
cebix |
1.4 |
* Basilisk II (C) 1997-2004 Christian Bauer |
5 |
gbeauche |
1.1 |
* |
6 |
|
|
* MC68881/68040 fpu emulation |
7 |
|
|
* |
8 |
|
|
* Original UAE FPU, copyright 1996 Herman ten Brugge |
9 |
|
|
* Rewrite for x86, copyright 1999-2000 Lauri Pesonen |
10 |
|
|
* New framework, copyright 2000 Gwenole Beauchesne |
11 |
|
|
* Adapted for JIT compilation (c) Bernd Meyer, 2000 |
12 |
|
|
* |
13 |
|
|
* This program is free software; you can redistribute it and/or modify |
14 |
|
|
* it under the terms of the GNU General Public License as published by |
15 |
|
|
* the Free Software Foundation; either version 2 of the License, or |
16 |
|
|
* (at your option) any later version. |
17 |
|
|
* |
18 |
|
|
* This program is distributed in the hope that it will be useful, |
19 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 |
|
|
* GNU General Public License for more details. |
22 |
|
|
* |
23 |
|
|
* You should have received a copy of the GNU General Public License |
24 |
|
|
* along with this program; if not, write to the Free Software |
25 |
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
26 |
|
|
*/ |
27 |
|
|
|
28 |
|
|
#ifndef FPU_CORE_H |
29 |
|
|
#define FPU_CORE_H |
30 |
|
|
|
31 |
|
|
#include "sysdeps.h" |
32 |
|
|
#include "fpu/types.h" |
33 |
|
|
|
34 |
gbeauche |
1.3 |
/* Always use x87 FPU stack on IA-32. */ |
35 |
|
|
#if defined(X86_ASSEMBLY) |
36 |
|
|
#define USE_X87_ASSEMBLY 1 |
37 |
|
|
#endif |
38 |
|
|
|
39 |
|
|
/* Only use x87 FPU on x86-64 if long double precision is requested. */ |
40 |
|
|
#if defined(X86_64_ASSEMBLY) && USE_LONG_DOUBLE |
41 |
|
|
#define USE_X87_ASSEMBLY 1 |
42 |
|
|
#endif |
43 |
|
|
|
44 |
gbeauche |
1.1 |
/* ========================================================================== */ |
45 |
|
|
/* ========================= FPU CONTEXT DEFINITION ========================= */ |
46 |
|
|
/* ========================================================================== */ |
47 |
|
|
|
48 |
|
|
/* We don't use all features of the C++ language so that we may still |
49 |
|
|
* easily backport that code to C. |
50 |
|
|
*/ |
51 |
|
|
|
52 |
|
|
struct fpu_t { |
53 |
|
|
|
54 |
|
|
/* ---------------------------------------------------------------------- */ |
55 |
|
|
/* --- Floating-Point Data Registers --- */ |
56 |
|
|
/* ---------------------------------------------------------------------- */ |
57 |
|
|
|
58 |
|
|
/* The eight %fp0 .. %fp7 registers */ |
59 |
|
|
fpu_register registers[8]; |
60 |
|
|
|
61 |
|
|
/* Used for lazy evalualation of FPU flags */ |
62 |
|
|
fpu_register result; |
63 |
|
|
|
64 |
|
|
/* ---------------------------------------------------------------------- */ |
65 |
|
|
/* --- Floating-Point Control Register --- */ |
66 |
|
|
/* ---------------------------------------------------------------------- */ |
67 |
|
|
|
68 |
|
|
struct { |
69 |
|
|
|
70 |
|
|
/* Exception Enable Byte */ |
71 |
|
|
uae_u32 exception_enable; |
72 |
|
|
#define FPCR_EXCEPTION_ENABLE 0x0000ff00 |
73 |
|
|
#define FPCR_EXCEPTION_BSUN 0x00008000 |
74 |
|
|
#define FPCR_EXCEPTION_SNAN 0x00004000 |
75 |
|
|
#define FPCR_EXCEPTION_OPERR 0x00002000 |
76 |
|
|
#define FPCR_EXCEPTION_OVFL 0x00001000 |
77 |
|
|
#define FPCR_EXCEPTION_UNFL 0x00000800 |
78 |
|
|
#define FPCR_EXCEPTION_DZ 0x00000400 |
79 |
|
|
#define FPCR_EXCEPTION_INEX2 0x00000200 |
80 |
|
|
#define FPCR_EXCEPTION_INEX1 0x00000100 |
81 |
|
|
|
82 |
|
|
/* Mode Control Byte Mask */ |
83 |
|
|
#define FPCR_MODE_CONTROL 0x000000ff |
84 |
|
|
|
85 |
|
|
/* Rounding precision */ |
86 |
|
|
uae_u32 rounding_precision; |
87 |
|
|
#define FPCR_ROUNDING_PRECISION 0x000000c0 |
88 |
|
|
#define FPCR_PRECISION_SINGLE 0x00000040 |
89 |
|
|
#define FPCR_PRECISION_DOUBLE 0x00000080 |
90 |
|
|
#define FPCR_PRECISION_EXTENDED 0x00000000 |
91 |
|
|
|
92 |
|
|
/* Rounding mode */ |
93 |
|
|
uae_u32 rounding_mode; |
94 |
|
|
#define FPCR_ROUNDING_MODE 0x00000030 |
95 |
|
|
#define FPCR_ROUND_NEAR 0x00000000 |
96 |
|
|
#define FPCR_ROUND_ZERO 0x00000010 |
97 |
|
|
#define FPCR_ROUND_MINF 0x00000020 |
98 |
|
|
#define FPCR_ROUND_PINF 0x00000030 |
99 |
|
|
|
100 |
|
|
} fpcr; |
101 |
|
|
|
102 |
|
|
/* ---------------------------------------------------------------------- */ |
103 |
|
|
/* --- Floating-Point Status Register --- */ |
104 |
|
|
/* ---------------------------------------------------------------------- */ |
105 |
|
|
|
106 |
|
|
struct { |
107 |
|
|
|
108 |
|
|
/* Floating-Point Condition Code Byte */ |
109 |
|
|
uae_u32 condition_codes; |
110 |
|
|
#define FPSR_CCB 0xff000000 |
111 |
|
|
#define FPSR_CCB_NEGATIVE 0x08000000 |
112 |
|
|
#define FPSR_CCB_ZERO 0x04000000 |
113 |
|
|
#define FPSR_CCB_INFINITY 0x02000000 |
114 |
|
|
#define FPSR_CCB_NAN 0x01000000 |
115 |
|
|
|
116 |
|
|
/* Quotient Byte */ |
117 |
|
|
uae_u32 quotient; |
118 |
|
|
#define FPSR_QUOTIENT 0x00ff0000 |
119 |
|
|
#define FPSR_QUOTIENT_SIGN 0x00800000 |
120 |
|
|
#define FPSR_QUOTIENT_VALUE 0x007f0000 |
121 |
|
|
|
122 |
|
|
/* Exception Status Byte */ |
123 |
|
|
uae_u32 exception_status; |
124 |
|
|
#define FPSR_EXCEPTION_STATUS FPCR_EXCEPTION_ENABLE |
125 |
|
|
#define FPSR_EXCEPTION_BSUN FPCR_EXCEPTION_BSUN |
126 |
|
|
#define FPSR_EXCEPTION_SNAN FPCR_EXCEPTION_SNAN |
127 |
|
|
#define FPSR_EXCEPTION_OPERR FPCR_EXCEPTION_OPERR |
128 |
|
|
#define FPSR_EXCEPTION_OVFL FPCR_EXCEPTION_OVFL |
129 |
|
|
#define FPSR_EXCEPTION_UNFL FPCR_EXCEPTION_UNFL |
130 |
|
|
#define FPSR_EXCEPTION_DZ FPCR_EXCEPTION_DZ |
131 |
|
|
#define FPSR_EXCEPTION_INEX2 FPCR_EXCEPTION_INEX2 |
132 |
|
|
#define FPSR_EXCEPTION_INEX1 FPCR_EXCEPTION_INEX1 |
133 |
|
|
|
134 |
|
|
/* Accrued Exception Byte */ |
135 |
|
|
uae_u32 accrued_exception; |
136 |
|
|
#define FPSR_ACCRUED_EXCEPTION 0x000000ff |
137 |
|
|
#define FPSR_ACCR_IOP 0x00000080 |
138 |
|
|
#define FPSR_ACCR_OVFL 0x00000040 |
139 |
|
|
#define FPSR_ACCR_UNFL 0x00000020 |
140 |
|
|
#define FPSR_ACCR_DZ 0x00000010 |
141 |
|
|
#define FPSR_ACCR_INEX 0x00000008 |
142 |
|
|
|
143 |
|
|
} fpsr; |
144 |
|
|
|
145 |
|
|
/* ---------------------------------------------------------------------- */ |
146 |
|
|
/* --- Floating-Point Instruction Address Register --- */ |
147 |
|
|
/* ---------------------------------------------------------------------- */ |
148 |
|
|
|
149 |
|
|
uae_u32 instruction_address; |
150 |
|
|
|
151 |
|
|
/* ---------------------------------------------------------------------- */ |
152 |
|
|
/* --- Initialization / Finalization --- */ |
153 |
|
|
/* ---------------------------------------------------------------------- */ |
154 |
|
|
|
155 |
|
|
/* Flag set if we emulate an integral 68040 FPU */ |
156 |
|
|
bool is_integral; |
157 |
|
|
|
158 |
|
|
/* ---------------------------------------------------------------------- */ |
159 |
|
|
/* --- Extra FPE-dependant defines --- */ |
160 |
|
|
/* ---------------------------------------------------------------------- */ |
161 |
|
|
|
162 |
|
|
#if defined(FPU_X86) \ |
163 |
gbeauche |
1.3 |
|| (defined(FPU_UAE) && defined(USE_X87_ASSEMBLY)) \ |
164 |
|
|
|| (defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY)) |
165 |
gbeauche |
1.1 |
|
166 |
|
|
#define CW_RESET 0x0040 // initial CW value after RESET |
167 |
|
|
#define CW_FINIT 0x037F // initial CW value after FINIT |
168 |
|
|
#define SW_RESET 0x0000 // initial SW value after RESET |
169 |
|
|
#define SW_FINIT 0x0000 // initial SW value after FINIT |
170 |
|
|
#define TW_RESET 0x5555 // initial TW value after RESET |
171 |
|
|
#define TW_FINIT 0x0FFF // initial TW value after FINIT |
172 |
|
|
|
173 |
|
|
#define CW_X 0x1000 // infinity control |
174 |
|
|
#define CW_RC_ZERO 0x0C00 // rounding control toward zero |
175 |
|
|
#define CW_RC_UP 0x0800 // rounding control toward + |
176 |
|
|
#define CW_RC_DOWN 0x0400 // rounding control toward - |
177 |
|
|
#define CW_RC_NEAR 0x0000 // rounding control toward even |
178 |
|
|
#define CW_PC_EXTENDED 0x0300 // precision control 64bit |
179 |
|
|
#define CW_PC_DOUBLE 0x0200 // precision control 53bit |
180 |
|
|
#define CW_PC_RESERVED 0x0100 // precision control reserved |
181 |
|
|
#define CW_PC_SINGLE 0x0000 // precision control 24bit |
182 |
|
|
#define CW_PM 0x0020 // precision exception mask |
183 |
|
|
#define CW_UM 0x0010 // underflow exception mask |
184 |
|
|
#define CW_OM 0x0008 // overflow exception mask |
185 |
|
|
#define CW_ZM 0x0004 // zero divide exception mask |
186 |
|
|
#define CW_DM 0x0002 // denormalized operand exception mask |
187 |
|
|
#define CW_IM 0x0001 // invalid operation exception mask |
188 |
|
|
|
189 |
|
|
#define SW_B 0x8000 // busy flag |
190 |
|
|
#define SW_C3 0x4000 // condition code flag 3 |
191 |
|
|
#define SW_TOP_7 0x3800 // top of stack = ST(7) |
192 |
|
|
#define SW_TOP_6 0x3000 // top of stack = ST(6) |
193 |
|
|
#define SW_TOP_5 0x2800 // top of stack = ST(5) |
194 |
|
|
#define SW_TOP_4 0x2000 // top of stack = ST(4) |
195 |
|
|
#define SW_TOP_3 0x1800 // top of stack = ST(3) |
196 |
|
|
#define SW_TOP_2 0x1000 // top of stack = ST(2) |
197 |
|
|
#define SW_TOP_1 0x0800 // top of stack = ST(1) |
198 |
|
|
#define SW_TOP_0 0x0000 // top of stack = ST(0) |
199 |
|
|
#define SW_C2 0x0400 // condition code flag 2 |
200 |
|
|
#define SW_C1 0x0200 // condition code flag 1 |
201 |
|
|
#define SW_C0 0x0100 // condition code flag 0 |
202 |
|
|
#define SW_ES 0x0080 // error summary status flag |
203 |
|
|
#define SW_SF 0x0040 // stack fault flag |
204 |
|
|
#define SW_PE 0x0020 // precision exception flag |
205 |
|
|
#define SW_UE 0x0010 // underflow exception flag |
206 |
|
|
#define SW_OE 0x0008 // overflow exception flag |
207 |
|
|
#define SW_ZE 0x0004 // zero divide exception flag |
208 |
|
|
#define SW_DE 0x0002 // denormalized operand exception flag |
209 |
|
|
#define SW_IE 0x0001 // invalid operation exception flag |
210 |
|
|
|
211 |
|
|
#define X86_ROUNDING_MODE 0x0C00 |
212 |
|
|
#define X86_ROUNDING_PRECISION 0x0300 |
213 |
|
|
|
214 |
|
|
#endif /* FPU_X86 */ |
215 |
|
|
|
216 |
|
|
}; |
217 |
|
|
|
218 |
|
|
/* We handle only one global fpu */ |
219 |
|
|
extern fpu_t fpu; |
220 |
|
|
|
221 |
|
|
/* Return the address of a particular register */ |
222 |
|
|
inline fpu_register * const fpu_register_address(int i) |
223 |
|
|
{ return &fpu.registers[i]; } |
224 |
|
|
|
225 |
|
|
/* Dump functions for m68k_dumpstate */ |
226 |
|
|
extern void fpu_dump_registers(void); |
227 |
|
|
extern void fpu_dump_flags(void); |
228 |
|
|
|
229 |
|
|
/* Accessors to FPU Control Register */ |
230 |
gbeauche |
1.2 |
static inline uae_u32 get_fpcr(void); |
231 |
|
|
static inline void set_fpcr(uae_u32 new_fpcr); |
232 |
gbeauche |
1.1 |
|
233 |
|
|
/* Accessors to FPU Status Register */ |
234 |
gbeauche |
1.2 |
static inline uae_u32 get_fpsr(void); |
235 |
|
|
static inline void set_fpsr(uae_u32 new_fpsr); |
236 |
gbeauche |
1.1 |
|
237 |
|
|
/* Accessors to FPU Instruction Address Register */ |
238 |
gbeauche |
1.2 |
static inline uae_u32 get_fpiar(); |
239 |
|
|
static inline void set_fpiar(uae_u32 new_fpiar); |
240 |
gbeauche |
1.1 |
|
241 |
|
|
/* Initialization / Finalization */ |
242 |
|
|
extern void fpu_init(bool integral_68040); |
243 |
|
|
extern void fpu_exit(void); |
244 |
|
|
extern void fpu_reset(void); |
245 |
|
|
|
246 |
|
|
/* Floating-point arithmetic instructions */ |
247 |
|
|
void fpuop_arithmetic(uae_u32 opcode, uae_u32 extra) REGPARAM; |
248 |
|
|
|
249 |
|
|
/* Floating-point program control operations */ |
250 |
|
|
void fpuop_bcc(uae_u32 opcode, uaecptr pc, uae_u32 extra) REGPARAM; |
251 |
|
|
void fpuop_dbcc(uae_u32 opcode, uae_u32 extra) REGPARAM; |
252 |
|
|
void fpuop_scc(uae_u32 opcode, uae_u32 extra) REGPARAM; |
253 |
|
|
|
254 |
|
|
/* Floating-point system control operations */ |
255 |
|
|
void fpuop_save(uae_u32 opcode) REGPARAM; |
256 |
|
|
void fpuop_restore(uae_u32 opcode) REGPARAM; |
257 |
|
|
void fpuop_trapcc(uae_u32 opcode, uaecptr oldpc) REGPARAM; |
258 |
|
|
|
259 |
|
|
#endif /* FPU_CORE_H */ |