- compilation fixes for MSVC toolkit 2003
[bochs-mirror.git] / cpu / i387.h
blob34d2e01f8a26c36c5a199f104ca690080b2184e0
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: i387.h,v 1.37 2008/05/10 13:34:47 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (c) 2004 Stanislav Shwartsman
6 // Written by Stanislav Shwartsman [sshwarts at sourceforge net]
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /////////////////////////////////////////////////////////////////////////
24 #ifndef _BX_I387_RELATED_EXTENSIONS_H_
25 #define _BX_I387_RELATED_EXTENSIONS_H_
27 #if BX_SUPPORT_FPU
29 #include "fpu/softfloat.h"
31 #define BX_FPU_REG(index) \
32 (BX_CPU_THIS_PTR the_i387.st_space[index])
34 #if defined(NEED_CPU_REG_SHORTCUTS)
35 #define FPU_PARTIAL_STATUS (BX_CPU_THIS_PTR the_i387.swd)
36 #define FPU_CONTROL_WORD (BX_CPU_THIS_PTR the_i387.cwd)
37 #define FPU_TAG_WORD (BX_CPU_THIS_PTR the_i387.twd)
38 #define FPU_TOS (BX_CPU_THIS_PTR the_i387.tos)
39 #endif
41 #include "fpu/tag_w.h"
42 #include "fpu/status_w.h"
43 #include "fpu/control_w.h"
45 extern int FPU_tagof(const floatx80 &reg);
48 // Minimal i387 structure
50 struct BOCHSAPI_MSVCONLY i387_t
52 i387_t() {}
54 public:
55 void init(); // used by FINIT/FNINIT instructions
56 void reset(); // called on CPU reset
58 int is_IA_masked() const { return (cwd & FPU_CW_Invalid); }
60 Bit16u get_control_word() const { return cwd; }
61 Bit16u get_tag_word() const { return twd; }
62 Bit16u get_status_word() const { return (swd & ~FPU_SW_Top & 0xFFFF) | ((tos << 11) & FPU_SW_Top); }
63 Bit16u get_partial_status() const { return swd; }
65 void FPU_pop ();
66 void FPU_push();
68 void FPU_settagi(int tag, int stnr);
69 void FPU_settagi_valid(int stnr);
70 int FPU_gettagi(int stnr);
72 floatx80 FPU_read_regi(int stnr) { return st_space[(tos+stnr) & 7]; }
73 void FPU_save_regi(floatx80 reg, int stnr);
74 void FPU_save_regi(floatx80 reg, int tag, int stnr);
76 public:
77 Bit16u cwd; // control word
78 Bit16u swd; // status word
79 Bit16u twd; // tag word
80 Bit16u foo; // last instruction opcode
82 bx_address fip;
83 bx_address fdp;
84 Bit16u fcs;
85 Bit16u fds;
87 floatx80 st_space[8];
89 unsigned char tos;
90 unsigned char align1;
91 unsigned char align2;
92 unsigned char align3;
95 #define IS_TAG_EMPTY(i) \
96 ((BX_CPU_THIS_PTR the_i387.FPU_gettagi(i)) == FPU_Tag_Empty)
98 #define BX_READ_FPU_REG(i) \
99 (BX_CPU_THIS_PTR the_i387.FPU_read_regi(i))
101 #define BX_WRITE_FPU_REG(value, i) \
102 BX_CPU_THIS_PTR the_i387.FPU_save_regi((value), (i));
104 #define BX_WRITE_FPU_REGISTER_AND_TAG(value, tag, i) \
105 BX_CPU_THIS_PTR the_i387.FPU_save_regi((value), (tag), (i));
107 BX_CPP_INLINE int i387_t::FPU_gettagi(int stnr)
109 return (twd >> (((stnr+tos) & 7)*2)) & 3;
112 BX_CPP_INLINE void i387_t::FPU_settagi_valid(int stnr)
114 int regnr = (stnr + tos) & 7;
115 twd &= ~(3 << (regnr*2)); // FPU_Tag_Valid == '00
118 BX_CPP_INLINE void i387_t::FPU_settagi(int tag, int stnr)
120 int regnr = (stnr + tos) & 7;
121 twd &= ~(3 << (regnr*2));
122 twd |= (tag & 3) << (regnr*2);
125 BX_CPP_INLINE void i387_t::FPU_push(void)
127 tos = (tos - 1) & 7;
130 BX_CPP_INLINE void i387_t::FPU_pop(void)
132 twd |= 3 << (tos*2);
133 tos = (tos + 1) & 7;
136 // it is only possisble to read FPU tag word through certain
137 // instructions like FNSAVE, and they update tag word to its
138 // real value anyway
139 BX_CPP_INLINE void i387_t::FPU_save_regi(floatx80 reg, int stnr)
141 st_space[(stnr+tos) & 7] = reg;
142 FPU_settagi_valid(stnr);
145 BX_CPP_INLINE void i387_t::FPU_save_regi(floatx80 reg, int tag, int stnr)
147 st_space[(stnr+tos) & 7] = reg;
148 FPU_settagi(tag, stnr);
151 #include <string.h>
153 BX_CPP_INLINE void i387_t::init()
155 cwd = 0x037F;
156 swd = 0;
157 tos = 0;
158 twd = 0xFFFF;
159 foo = 0;
160 fip = 0;
161 fcs = 0;
162 fds = 0;
163 fdp = 0;
166 BX_CPP_INLINE void i387_t::reset()
168 cwd = 0x0040;
169 swd = 0;
170 tos = 0;
171 twd = 0x5555;
172 foo = 0;
173 fip = 0;
174 fcs = 0;
175 fds = 0;
176 fdp = 0;
178 memset(st_space, 0, sizeof(floatx80)*8);
181 #if BX_SUPPORT_MMX
183 typedef union bx_packed_mmx_reg_t {
184 Bit8s _sbyte[8];
185 Bit16s _s16[4];
186 Bit32s _s32[2];
187 Bit64s _s64;
188 Bit8u _ubyte[8];
189 Bit16u _u16[4];
190 Bit32u _u32[2];
191 Bit64u _u64;
192 } BxPackedMmxRegister;
194 #ifdef BX_BIG_ENDIAN
195 #define mmx64s(i) _s64
196 #define mmx32s(i) _s32[1 - (i)]
197 #define mmx16s(i) _s16[3 - (i)]
198 #define mmxsbyte(i) _sbyte[7 - (i)]
199 #define mmxubyte(i) _ubyte[7 - (i)]
200 #define mmx16u(i) _u16[3 - (i)]
201 #define mmx32u(i) _u32[1 - (i)]
202 #define mmx64u _u64
203 #else
204 #define mmx64s(i) _s64
205 #define mmx32s(i) _s32[(i)]
206 #define mmx16s(i) _s16[(i)]
207 #define mmxsbyte(i) _sbyte[(i)]
208 #define mmxubyte(i) _ubyte[(i)]
209 #define mmx16u(i) _u16[(i)]
210 #define mmx32u(i) _u32[(i)]
211 #define mmx64u _u64
212 #endif
214 /* for compatability with already written code */
215 #define MMXSB0(reg) (reg.mmxsbyte(0))
216 #define MMXSB1(reg) (reg.mmxsbyte(1))
217 #define MMXSB2(reg) (reg.mmxsbyte(2))
218 #define MMXSB3(reg) (reg.mmxsbyte(3))
219 #define MMXSB4(reg) (reg.mmxsbyte(4))
220 #define MMXSB5(reg) (reg.mmxsbyte(5))
221 #define MMXSB6(reg) (reg.mmxsbyte(6))
222 #define MMXSB7(reg) (reg.mmxsbyte(7))
224 #define MMXSW0(reg) (reg.mmx16s(0))
225 #define MMXSW1(reg) (reg.mmx16s(1))
226 #define MMXSW2(reg) (reg.mmx16s(2))
227 #define MMXSW3(reg) (reg.mmx16s(3))
229 #define MMXSD0(reg) (reg.mmx32s(0))
230 #define MMXSD1(reg) (reg.mmx32s(1))
232 #define MMXSQ(reg) (reg.mmx64s)
233 #define MMXUQ(reg) (reg.mmx64u)
235 #define MMXUD0(reg) (reg.mmx32u(0))
236 #define MMXUD1(reg) (reg.mmx32u(1))
238 #define MMXUW0(reg) (reg.mmx16u(0))
239 #define MMXUW1(reg) (reg.mmx16u(1))
240 #define MMXUW2(reg) (reg.mmx16u(2))
241 #define MMXUW3(reg) (reg.mmx16u(3))
243 #define MMXUB0(reg) (reg.mmxubyte(0))
244 #define MMXUB1(reg) (reg.mmxubyte(1))
245 #define MMXUB2(reg) (reg.mmxubyte(2))
246 #define MMXUB3(reg) (reg.mmxubyte(3))
247 #define MMXUB4(reg) (reg.mmxubyte(4))
248 #define MMXUB5(reg) (reg.mmxubyte(5))
249 #define MMXUB6(reg) (reg.mmxubyte(6))
250 #define MMXUB7(reg) (reg.mmxubyte(7))
252 #define BX_MMX_REG(index) (BX_FPU_REG(index).fraction)
254 #define BX_READ_MMX_REG(index) \
255 (*((const BxPackedMmxRegister*)(&(BX_MMX_REG(index)))))
257 #define BX_WRITE_MMX_REG(index, value) \
259 (BX_FPU_REG(index)).fraction = MMXUQ(value); \
260 (BX_FPU_REG(index)).exp = 0xffff; \
263 #endif /* BX_SUPPORT_MMX */
265 #endif /* BX_SUPPORT_FPU */
267 #endif