1 |
gbeauche |
1.1 |
/* |
2 |
|
|
* fpu/core.h - base fpu context definition |
3 |
|
|
* |
4 |
|
|
* Basilisk II (C) 1997-1999 Christian Bauer |
5 |
|
|
* |
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 |
|
|
/* ========================================================================== */ |
35 |
|
|
/* ========================= FPU CONTEXT DEFINITION ========================= */ |
36 |
|
|
/* ========================================================================== */ |
37 |
|
|
|
38 |
|
|
/* We don't use all features of the C++ language so that we may still |
39 |
|
|
* easily backport that code to C. |
40 |
|
|
*/ |
41 |
|
|
|
42 |
|
|
struct fpu_t { |
43 |
|
|
|
44 |
|
|
/* ---------------------------------------------------------------------- */ |
45 |
|
|
/* --- Floating-Point Data Registers --- */ |
46 |
|
|
/* ---------------------------------------------------------------------- */ |
47 |
|
|
|
48 |
|
|
/* The eight %fp0 .. %fp7 registers */ |
49 |
|
|
fpu_register registers[8]; |
50 |
|
|
|
51 |
|
|
/* Used for lazy evalualation of FPU flags */ |
52 |
|
|
fpu_register result; |
53 |
|
|
|
54 |
|
|
/* ---------------------------------------------------------------------- */ |
55 |
|
|
/* --- Floating-Point Control Register --- */ |
56 |
|
|
/* ---------------------------------------------------------------------- */ |
57 |
|
|
|
58 |
|
|
struct { |
59 |
|
|
|
60 |
|
|
/* Exception Enable Byte */ |
61 |
|
|
uae_u32 exception_enable; |
62 |
|
|
#define FPCR_EXCEPTION_ENABLE 0x0000ff00 |
63 |
|
|
#define FPCR_EXCEPTION_BSUN 0x00008000 |
64 |
|
|
#define FPCR_EXCEPTION_SNAN 0x00004000 |
65 |
|
|
#define FPCR_EXCEPTION_OPERR 0x00002000 |
66 |
|
|
#define FPCR_EXCEPTION_OVFL 0x00001000 |
67 |
|
|
#define FPCR_EXCEPTION_UNFL 0x00000800 |
68 |
|
|
#define FPCR_EXCEPTION_DZ 0x00000400 |
69 |
|
|
#define FPCR_EXCEPTION_INEX2 0x00000200 |
70 |
|
|
#define FPCR_EXCEPTION_INEX1 0x00000100 |
71 |
|
|
|
72 |
|
|
/* Mode Control Byte Mask */ |
73 |
|
|
#define FPCR_MODE_CONTROL 0x000000ff |
74 |
|
|
|
75 |
|
|
/* Rounding precision */ |
76 |
|
|
uae_u32 rounding_precision; |
77 |
|
|
#define FPCR_ROUNDING_PRECISION 0x000000c0 |
78 |
|
|
#define FPCR_PRECISION_SINGLE 0x00000040 |
79 |
|
|
#define FPCR_PRECISION_DOUBLE 0x00000080 |
80 |
|
|
#define FPCR_PRECISION_EXTENDED 0x00000000 |
81 |
|
|
|
82 |
|
|
/* Rounding mode */ |
83 |
|
|
uae_u32 rounding_mode; |
84 |
|
|
#define FPCR_ROUNDING_MODE 0x00000030 |
85 |
|
|
#define FPCR_ROUND_NEAR 0x00000000 |
86 |
|
|
#define FPCR_ROUND_ZERO 0x00000010 |
87 |
|
|
#define FPCR_ROUND_MINF 0x00000020 |
88 |
|
|
#define FPCR_ROUND_PINF 0x00000030 |
89 |
|
|
|
90 |
|
|
} fpcr; |
91 |
|
|
|
92 |
|
|
/* ---------------------------------------------------------------------- */ |
93 |
|
|
/* --- Floating-Point Status Register --- */ |
94 |
|
|
/* ---------------------------------------------------------------------- */ |
95 |
|
|
|
96 |
|
|
struct { |
97 |
|
|
|
98 |
|
|
/* Floating-Point Condition Code Byte */ |
99 |
|
|
uae_u32 condition_codes; |
100 |
|
|
#define FPSR_CCB 0xff000000 |
101 |
|
|
#define FPSR_CCB_NEGATIVE 0x08000000 |
102 |
|
|
#define FPSR_CCB_ZERO 0x04000000 |
103 |
|
|
#define FPSR_CCB_INFINITY 0x02000000 |
104 |
|
|
#define FPSR_CCB_NAN 0x01000000 |
105 |
|
|
|
106 |
|
|
/* Quotient Byte */ |
107 |
|
|
uae_u32 quotient; |
108 |
|
|
#define FPSR_QUOTIENT 0x00ff0000 |
109 |
|
|
#define FPSR_QUOTIENT_SIGN 0x00800000 |
110 |
|
|
#define FPSR_QUOTIENT_VALUE 0x007f0000 |
111 |
|
|
|
112 |
|
|
/* Exception Status Byte */ |
113 |
|
|
uae_u32 exception_status; |
114 |
|
|
#define FPSR_EXCEPTION_STATUS FPCR_EXCEPTION_ENABLE |
115 |
|
|
#define FPSR_EXCEPTION_BSUN FPCR_EXCEPTION_BSUN |
116 |
|
|
#define FPSR_EXCEPTION_SNAN FPCR_EXCEPTION_SNAN |
117 |
|
|
#define FPSR_EXCEPTION_OPERR FPCR_EXCEPTION_OPERR |
118 |
|
|
#define FPSR_EXCEPTION_OVFL FPCR_EXCEPTION_OVFL |
119 |
|
|
#define FPSR_EXCEPTION_UNFL FPCR_EXCEPTION_UNFL |
120 |
|
|
#define FPSR_EXCEPTION_DZ FPCR_EXCEPTION_DZ |
121 |
|
|
#define FPSR_EXCEPTION_INEX2 FPCR_EXCEPTION_INEX2 |
122 |
|
|
#define FPSR_EXCEPTION_INEX1 FPCR_EXCEPTION_INEX1 |
123 |
|
|
|
124 |
|
|
/* Accrued Exception Byte */ |
125 |
|
|
uae_u32 accrued_exception; |
126 |
|
|
#define FPSR_ACCRUED_EXCEPTION 0x000000ff |
127 |
|
|
#define FPSR_ACCR_IOP 0x00000080 |
128 |
|
|
#define FPSR_ACCR_OVFL 0x00000040 |
129 |
|
|
#define FPSR_ACCR_UNFL 0x00000020 |
130 |
|
|
#define FPSR_ACCR_DZ 0x00000010 |
131 |
|
|
#define FPSR_ACCR_INEX 0x00000008 |
132 |
|
|
|
133 |
|
|
} fpsr; |
134 |
|
|
|
135 |
|
|
/* ---------------------------------------------------------------------- */ |
136 |
|
|
/* --- Floating-Point Instruction Address Register --- */ |
137 |
|
|
/* ---------------------------------------------------------------------- */ |
138 |
|
|
|
139 |
|
|
uae_u32 instruction_address; |
140 |
|
|
|
141 |
|
|
/* ---------------------------------------------------------------------- */ |
142 |
|
|
/* --- Initialization / Finalization --- */ |
143 |
|
|
/* ---------------------------------------------------------------------- */ |
144 |
|
|
|
145 |
|
|
/* Flag set if we emulate an integral 68040 FPU */ |
146 |
|
|
bool is_integral; |
147 |
|
|
|
148 |
|
|
/* ---------------------------------------------------------------------- */ |
149 |
|
|
/* --- Extra FPE-dependant defines --- */ |
150 |
|
|
/* ---------------------------------------------------------------------- */ |
151 |
|
|
|
152 |
|
|
#if defined(FPU_X86) \ |
153 |
|
|
|| (defined(FPU_UAE) && defined(X86_ASSEMBLY)) \ |
154 |
|
|
|| (defined(FPU_IEEE) && defined(X86_ASSEMBLY)) |
155 |
|
|
|
156 |
|
|
#define CW_RESET 0x0040 // initial CW value after RESET |
157 |
|
|
#define CW_FINIT 0x037F // initial CW value after FINIT |
158 |
|
|
#define SW_RESET 0x0000 // initial SW value after RESET |
159 |
|
|
#define SW_FINIT 0x0000 // initial SW value after FINIT |
160 |
|
|
#define TW_RESET 0x5555 // initial TW value after RESET |
161 |
|
|
#define TW_FINIT 0x0FFF // initial TW value after FINIT |
162 |
|
|
|
163 |
|
|
#define CW_X 0x1000 // infinity control |
164 |
|
|
#define CW_RC_ZERO 0x0C00 // rounding control toward zero |
165 |
|
|
#define CW_RC_UP 0x0800 // rounding control toward + |
166 |
|
|
#define CW_RC_DOWN 0x0400 // rounding control toward - |
167 |
|
|
#define CW_RC_NEAR 0x0000 // rounding control toward even |
168 |
|
|
#define CW_PC_EXTENDED 0x0300 // precision control 64bit |
169 |
|
|
#define CW_PC_DOUBLE 0x0200 // precision control 53bit |
170 |
|
|
#define CW_PC_RESERVED 0x0100 // precision control reserved |
171 |
|
|
#define CW_PC_SINGLE 0x0000 // precision control 24bit |
172 |
|
|
#define CW_PM 0x0020 // precision exception mask |
173 |
|
|
#define CW_UM 0x0010 // underflow exception mask |
174 |
|
|
#define CW_OM 0x0008 // overflow exception mask |
175 |
|
|
#define CW_ZM 0x0004 // zero divide exception mask |
176 |
|
|
#define CW_DM 0x0002 // denormalized operand exception mask |
177 |
|
|
#define CW_IM 0x0001 // invalid operation exception mask |
178 |
|
|
|
179 |
|
|
#define SW_B 0x8000 // busy flag |
180 |
|
|
#define SW_C3 0x4000 // condition code flag 3 |
181 |
|
|
#define SW_TOP_7 0x3800 // top of stack = ST(7) |
182 |
|
|
#define SW_TOP_6 0x3000 // top of stack = ST(6) |
183 |
|
|
#define SW_TOP_5 0x2800 // top of stack = ST(5) |
184 |
|
|
#define SW_TOP_4 0x2000 // top of stack = ST(4) |
185 |
|
|
#define SW_TOP_3 0x1800 // top of stack = ST(3) |
186 |
|
|
#define SW_TOP_2 0x1000 // top of stack = ST(2) |
187 |
|
|
#define SW_TOP_1 0x0800 // top of stack = ST(1) |
188 |
|
|
#define SW_TOP_0 0x0000 // top of stack = ST(0) |
189 |
|
|
#define SW_C2 0x0400 // condition code flag 2 |
190 |
|
|
#define SW_C1 0x0200 // condition code flag 1 |
191 |
|
|
#define SW_C0 0x0100 // condition code flag 0 |
192 |
|
|
#define SW_ES 0x0080 // error summary status flag |
193 |
|
|
#define SW_SF 0x0040 // stack fault flag |
194 |
|
|
#define SW_PE 0x0020 // precision exception flag |
195 |
|
|
#define SW_UE 0x0010 // underflow exception flag |
196 |
|
|
#define SW_OE 0x0008 // overflow exception flag |
197 |
|
|
#define SW_ZE 0x0004 // zero divide exception flag |
198 |
|
|
#define SW_DE 0x0002 // denormalized operand exception flag |
199 |
|
|
#define SW_IE 0x0001 // invalid operation exception flag |
200 |
|
|
|
201 |
|
|
#define X86_ROUNDING_MODE 0x0C00 |
202 |
|
|
#define X86_ROUNDING_PRECISION 0x0300 |
203 |
|
|
|
204 |
|
|
#endif /* FPU_X86 */ |
205 |
|
|
|
206 |
|
|
}; |
207 |
|
|
|
208 |
|
|
/* We handle only one global fpu */ |
209 |
|
|
extern fpu_t fpu; |
210 |
|
|
|
211 |
|
|
/* Return the address of a particular register */ |
212 |
|
|
inline fpu_register * const fpu_register_address(int i) |
213 |
|
|
{ return &fpu.registers[i]; } |
214 |
|
|
|
215 |
|
|
/* Dump functions for m68k_dumpstate */ |
216 |
|
|
extern void fpu_dump_registers(void); |
217 |
|
|
extern void fpu_dump_flags(void); |
218 |
|
|
|
219 |
|
|
/* Accessors to FPU Control Register */ |
220 |
|
|
extern inline uae_u32 get_fpcr(void); |
221 |
|
|
extern inline void set_fpcr(uae_u32 new_fpcr); |
222 |
|
|
|
223 |
|
|
/* Accessors to FPU Status Register */ |
224 |
|
|
extern inline uae_u32 get_fpsr(void); |
225 |
|
|
extern void set_fpsr(uae_u32 new_fpsr); |
226 |
|
|
|
227 |
|
|
/* Accessors to FPU Instruction Address Register */ |
228 |
|
|
extern inline uae_u32 get_fpiar(); |
229 |
|
|
extern inline void set_fpiar(uae_u32 new_fpiar); |
230 |
|
|
|
231 |
|
|
/* Initialization / Finalization */ |
232 |
|
|
extern void fpu_init(bool integral_68040); |
233 |
|
|
extern void fpu_exit(void); |
234 |
|
|
extern void fpu_reset(void); |
235 |
|
|
|
236 |
|
|
/* Floating-point arithmetic instructions */ |
237 |
|
|
void fpuop_arithmetic(uae_u32 opcode, uae_u32 extra) REGPARAM; |
238 |
|
|
|
239 |
|
|
/* Floating-point program control operations */ |
240 |
|
|
void fpuop_bcc(uae_u32 opcode, uaecptr pc, uae_u32 extra) REGPARAM; |
241 |
|
|
void fpuop_dbcc(uae_u32 opcode, uae_u32 extra) REGPARAM; |
242 |
|
|
void fpuop_scc(uae_u32 opcode, uae_u32 extra) REGPARAM; |
243 |
|
|
|
244 |
|
|
/* Floating-point system control operations */ |
245 |
|
|
void fpuop_save(uae_u32 opcode) REGPARAM; |
246 |
|
|
void fpuop_restore(uae_u32 opcode) REGPARAM; |
247 |
|
|
void fpuop_trapcc(uae_u32 opcode, uaecptr oldpc) REGPARAM; |
248 |
|
|
|
249 |
|
|
#endif /* FPU_CORE_H */ |