1 /////////////////////////////////////////////////////////////////////////
2 // $Id: fpu_trans.cc,v 1.11 2007/03/23 21:27:13 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (c) 2003 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 /////////////////////////////////////////////////////////////////////////
25 #define NEED_CPU_REG_SHORTCUTS 1
28 #define LOG_THIS BX_CPU_THIS_PTR
30 #include "softfloatx80.h"
31 #include "softfloat-specialize.h"
33 extern float_status_t
FPU_pre_exception_handling(Bit16u control_word
);
36 void BX_CPU_C::F2XM1(bxInstruction_c
*i
)
39 BX_CPU_THIS_PTR
prepareFPU(i
);
45 BX_CPU_THIS_PTR
FPU_stack_underflow(0);
49 float_status_t status
=
50 FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387
.get_control_word() | FPU_PR_80_BITS
);
52 floatx80 result
= f2xm1(BX_READ_FPU_REG(0), status
);
54 if (BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
57 BX_WRITE_FPU_REG(result
, 0);
59 BX_INFO(("F2XM1: required FPU, configure --enable-fpu"));
64 void BX_CPU_C::FYL2X(bxInstruction_c
*i
)
67 BX_CPU_THIS_PTR
prepareFPU(i
);
71 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1))
73 BX_CPU_THIS_PTR
FPU_stack_underflow(0, 1);
77 float_status_t status
=
78 FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387
.get_control_word() | FPU_PR_80_BITS
);
80 floatx80 result
= fyl2x(BX_READ_FPU_REG(0), BX_READ_FPU_REG(1), status
);
82 if (BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
85 BX_CPU_THIS_PTR the_i387
.FPU_pop();
86 BX_WRITE_FPU_REG(result
, 0);
88 BX_INFO(("FYL2X: required FPU, configure --enable-fpu"));
93 void BX_CPU_C::FPTAN(bxInstruction_c
*i
)
96 BX_CPU_THIS_PTR
prepareFPU(i
);
101 if (! IS_TAG_EMPTY(-1) || IS_TAG_EMPTY(0))
103 BX_CPU_THIS_PTR
FPU_exception(FPU_EX_Stack_Overflow
);
105 /* The masked response */
106 if (BX_CPU_THIS_PTR the_i387
.is_IA_masked())
108 BX_WRITE_FPU_REGISTER_AND_TAG(floatx80_default_nan
, FPU_Tag_Special
, 0);
109 BX_CPU_THIS_PTR the_i387
.FPU_push();
110 BX_WRITE_FPU_REGISTER_AND_TAG(floatx80_default_nan
, FPU_Tag_Special
, 0);
116 extern const floatx80 Const_1
;
118 float_status_t status
=
119 FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387
.get_control_word() | FPU_PR_80_BITS
);
121 floatx80 y
= BX_READ_FPU_REG(0);
122 if (ftan(y
, status
) == -1)
124 FPU_PARTIAL_STATUS
|= FPU_SW_C2
;
128 if (floatx80_is_nan(y
))
130 if (! BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
132 BX_WRITE_FPU_REGISTER_AND_TAG(y
, FPU_Tag_Special
, 0);
133 BX_CPU_THIS_PTR the_i387
.FPU_push();
134 BX_WRITE_FPU_REGISTER_AND_TAG(y
, FPU_Tag_Special
, 0);
140 if (BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
143 BX_WRITE_FPU_REG(y
, 0);
144 BX_CPU_THIS_PTR the_i387
.FPU_push();
145 BX_WRITE_FPU_REGISTER_AND_TAG(Const_1
, FPU_Tag_Valid
, 0);
147 BX_INFO(("FPTAN: required FPU, configure --enable-fpu"));
152 void BX_CPU_C::FPATAN(bxInstruction_c
*i
)
158 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1))
160 BX_CPU_THIS_PTR
FPU_stack_underflow(0, 1);
164 float_status_t status
=
165 FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387
.get_control_word() | FPU_PR_80_BITS
);
167 floatx80 result
= fpatan(BX_READ_FPU_REG(0), BX_READ_FPU_REG(1), status
);
169 if (BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
172 BX_CPU_THIS_PTR the_i387
.FPU_pop();
173 BX_WRITE_FPU_REG(result
, 0);
175 BX_INFO(("FPATAN: required FPU, configure --enable-fpu"));
180 void BX_CPU_C::FXTRACT(bxInstruction_c
*i
)
183 BX_CPU_THIS_PTR
prepareFPU(i
);
187 if (! IS_TAG_EMPTY(-1) || IS_TAG_EMPTY(0))
189 BX_CPU_THIS_PTR
FPU_exception(FPU_EX_Stack_Overflow
);
191 /* The masked response */
192 if (BX_CPU_THIS_PTR the_i387
.is_IA_masked())
194 BX_WRITE_FPU_REGISTER_AND_TAG(floatx80_default_nan
, FPU_Tag_Special
, 0);
195 BX_CPU_THIS_PTR the_i387
.FPU_push();
196 BX_WRITE_FPU_REGISTER_AND_TAG(floatx80_default_nan
, FPU_Tag_Special
, 0);
202 float_status_t status
=
203 FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387
.get_control_word());
205 floatx80 a
= BX_READ_FPU_REG(0);
206 floatx80 b
= floatx80_extract(a
, status
);
208 if (BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
211 BX_WRITE_FPU_REG(b
, 0); // exponent
212 BX_CPU_THIS_PTR the_i387
.FPU_push();
213 BX_WRITE_FPU_REG(a
, 0); // fraction
215 BX_INFO(("FXTRACT: required FPU, configure --enable-fpu"));
220 void BX_CPU_C::FPREM1(bxInstruction_c
*i
)
223 BX_CPU_THIS_PTR
prepareFPU(i
);
227 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1))
229 BX_CPU_THIS_PTR
FPU_stack_underflow(0);
233 float_status_t status
=
234 FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387
.get_control_word());
238 floatx80 a
= BX_READ_FPU_REG(0);
239 floatx80 b
= BX_READ_FPU_REG(1);
241 floatx80 result
= floatx80_ieee754_remainder(a
, b
, quotient
, status
);
243 if (BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
247 if (quotient
== (Bit64u
) -1) cc
= FPU_SW_C2
;
250 if (quotient
& 1) cc
|= FPU_SW_C1
;
251 if (quotient
& 2) cc
|= FPU_SW_C3
;
252 if (quotient
& 4) cc
|= FPU_SW_C0
;
256 BX_WRITE_FPU_REG(result
, 0);
258 BX_INFO(("FPREM1: required FPU, configure --enable-fpu"));
263 void BX_CPU_C::FPREM(bxInstruction_c
*i
)
266 BX_CPU_THIS_PTR
prepareFPU(i
);
270 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1))
272 BX_CPU_THIS_PTR
FPU_stack_underflow(0);
276 float_status_t status
=
277 FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387
.get_control_word());
281 floatx80 a
= BX_READ_FPU_REG(0);
282 floatx80 b
= BX_READ_FPU_REG(1);
284 floatx80 result
= floatx80_remainder(a
, b
, quotient
, status
);
286 if (BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
290 if (quotient
== (Bit64u
) -1) cc
= FPU_SW_C2
;
293 if (quotient
& 1) cc
|= FPU_SW_C1
;
294 if (quotient
& 2) cc
|= FPU_SW_C3
;
295 if (quotient
& 4) cc
|= FPU_SW_C0
;
299 BX_WRITE_FPU_REG(result
, 0);
301 BX_INFO(("FPREM: required FPU, configure --enable-fpu"));
306 void BX_CPU_C::FYL2XP1(bxInstruction_c
*i
)
309 BX_CPU_THIS_PTR
prepareFPU(i
);
313 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1))
315 BX_CPU_THIS_PTR
FPU_stack_underflow(0, 1);
319 float_status_t status
=
320 FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387
.get_control_word() | FPU_PR_80_BITS
);
322 floatx80 result
= fyl2xp1(BX_READ_FPU_REG(0), BX_READ_FPU_REG(1), status
);
324 if (BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
327 BX_CPU_THIS_PTR the_i387
.FPU_pop();
328 BX_WRITE_FPU_REG(result
, 0);
330 BX_INFO(("FYL2XP1: required FPU, configure --enable-fpu"));
335 void BX_CPU_C::FSINCOS(bxInstruction_c
*i
)
338 BX_CPU_THIS_PTR
prepareFPU(i
);
343 if (! IS_TAG_EMPTY(-1) || IS_TAG_EMPTY(0))
345 BX_CPU_THIS_PTR
FPU_exception(FPU_EX_Stack_Overflow
);
347 /* The masked response */
348 if (BX_CPU_THIS_PTR the_i387
.is_IA_masked())
350 BX_WRITE_FPU_REGISTER_AND_TAG(floatx80_default_nan
, FPU_Tag_Special
, 0);
351 BX_CPU_THIS_PTR the_i387
.FPU_push();
352 BX_WRITE_FPU_REGISTER_AND_TAG(floatx80_default_nan
, FPU_Tag_Special
, 0);
358 float_status_t status
=
359 FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387
.get_control_word() | FPU_PR_80_BITS
);
361 floatx80 y
= BX_READ_FPU_REG(0);
362 floatx80 sin_y
, cos_y
;
363 if (fsincos(y
, &sin_y
, &cos_y
, status
) == -1)
365 FPU_PARTIAL_STATUS
|= FPU_SW_C2
;
369 if (BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
372 BX_WRITE_FPU_REG(sin_y
, 0);
373 BX_CPU_THIS_PTR the_i387
.FPU_push();
374 BX_WRITE_FPU_REG(cos_y
, 0);
376 BX_INFO(("FSINCOS: required FPU, configure --enable-fpu"));
381 void BX_CPU_C::FSCALE(bxInstruction_c
*i
)
384 BX_CPU_THIS_PTR
prepareFPU(i
);
388 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(1))
390 BX_CPU_THIS_PTR
FPU_stack_underflow(0);
394 float_status_t status
=
395 FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387
.get_control_word());
397 floatx80 result
= floatx80_scale(BX_READ_FPU_REG(0), BX_READ_FPU_REG(1), status
);
399 if (BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
402 BX_WRITE_FPU_REG(result
, 0);
404 BX_INFO(("FSCALE: required FPU, configure --enable-fpu"));
409 void BX_CPU_C::FSIN(bxInstruction_c
*i
)
412 BX_CPU_THIS_PTR
prepareFPU(i
);
419 BX_CPU_THIS_PTR
FPU_stack_underflow(0);
423 float_status_t status
=
424 FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387
.get_control_word() | FPU_PR_80_BITS
);
426 floatx80 y
= BX_READ_FPU_REG(0);
427 if (fsin(y
, status
) == -1)
429 FPU_PARTIAL_STATUS
|= FPU_SW_C2
;
433 if (BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
436 BX_WRITE_FPU_REG(y
, 0);
438 BX_INFO(("FSIN: required FPU, configure --enable-fpu"));
443 void BX_CPU_C::FCOS(bxInstruction_c
*i
)
446 BX_CPU_THIS_PTR
prepareFPU(i
);
453 BX_CPU_THIS_PTR
FPU_stack_underflow(0);
457 float_status_t status
=
458 FPU_pre_exception_handling(BX_CPU_THIS_PTR the_i387
.get_control_word() | FPU_PR_80_BITS
);
460 floatx80 y
= BX_READ_FPU_REG(0);
461 if (fcos(y
, status
) == -1)
463 FPU_PARTIAL_STATUS
|= FPU_SW_C2
;
467 if (BX_CPU_THIS_PTR
FPU_exception(status
.float_exception_flags
))
470 BX_WRITE_FPU_REG(y
, 0);
472 BX_INFO(("FCOS: required FPU, configure --enable-fpu"));