1 /////////////////////////////////////////////////////////////////////////
2 // $Id: i387.h,v 1.37 2008/05/10 13:34:47 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (c) 2004 Stanislav Shwartsman
6 // Written by Stanislav Shwartsman [sshwarts at sourceforge net]
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_
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)
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
®
);
48 // Minimal i387 structure
50 struct BOCHSAPI_MSVCONLY i387_t
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
; }
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
);
77 Bit16u cwd
; // control word
78 Bit16u swd
; // status word
79 Bit16u twd
; // tag word
80 Bit16u foo
; // last instruction opcode
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)
130 BX_CPP_INLINE
void i387_t::FPU_pop(void)
136 // it is only possisble to read FPU tag word through certain
137 // instructions like FNSAVE, and they update tag word to its
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
);
153 BX_CPP_INLINE
void i387_t::init()
166 BX_CPP_INLINE
void i387_t::reset()
178 memset(st_space
, 0, sizeof(floatx80
)*8);
183 typedef union bx_packed_mmx_reg_t
{
192 } BxPackedMmxRegister
;
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)]
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)]
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 */