1 /////////////////////////////////////////////////////////////////////////
2 // $Id: fpu_arith.cc 13466 2018-02-16 07:57:32Z sshwarts $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (c) 2003-2018 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.
12 //
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.
17 //
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 //
22 /////////////////////////////////////////////////////////////////////////
23
24 #define NEED_CPU_REG_SHORTCUTS 1
25 #include "bochs.h"
26 #include "cpu/cpu.h"
27 #define LOG_THIS BX_CPU_THIS_PTR
28
29 #if BX_SUPPORT_FPU
30
i387cw_to_softfloat_status_word(Bit16u control_word)31 float_status_t i387cw_to_softfloat_status_word(Bit16u control_word)
32 {
33 float_status_t status;
34
35 int precision = control_word & FPU_CW_PC;
36
37 switch(precision)
38 {
39 case FPU_PR_32_BITS:
40 status.float_rounding_precision = 32;
41 break;
42 case FPU_PR_64_BITS:
43 status.float_rounding_precision = 64;
44 break;
45 case FPU_PR_80_BITS:
46 status.float_rounding_precision = 80;
47 break;
48 default:
49 /* With the precision control bits set to 01 "(reserved)", a
50 real CPU behaves as if the precision control bits were
51 set to 11 "80 bits" */
52 status.float_rounding_precision = 80;
53 }
54
55 status.float_exception_flags = 0; // clear exceptions before execution
56 status.float_nan_handling_mode = float_first_operand_nan;
57 status.float_rounding_mode = (control_word & FPU_CW_RC) >> 10;
58 status.flush_underflow_to_zero = 0;
59 status.float_suppress_exception = 0;
60 status.float_exception_masks = control_word & FPU_CW_Exceptions_Mask;
61 status.denormals_are_zeros = 0;
62
63 return status;
64 }
65
66 #include "softfloatx80.h"
67
FPU_handle_NaN(floatx80 a,int aIsNaN,float32 b32,int bIsNaN,float_status_t & status)68 floatx80 FPU_handle_NaN(floatx80 a, int aIsNaN, float32 b32, int bIsNaN, float_status_t &status)
69 {
70 int aIsSignalingNaN = floatx80_is_signaling_nan(a);
71 int bIsSignalingNaN = float32_is_signaling_nan(b32);
72
73 if (aIsSignalingNaN | bIsSignalingNaN)
74 float_raise(status, float_flag_invalid);
75
76 // propagate QNaN to SNaN
77 a = propagateFloatx80NaN(a, status);
78
79 if (aIsNaN & !bIsNaN) return a;
80
81 // float32 is NaN so conversion will propagate SNaN to QNaN and raise
82 // appropriate exception flags
83 floatx80 b = float32_to_floatx80(b32, status);
84
85 if (aIsSignalingNaN) {
86 if (bIsSignalingNaN) goto returnLargerSignificand;
87 return bIsNaN ? b : a;
88 }
89 else if (aIsNaN) {
90 if (bIsSignalingNaN) return a;
91 returnLargerSignificand:
92 if (a.fraction < b.fraction) return b;
93 if (b.fraction < a.fraction) return a;
94 return (a.exp < b.exp) ? a : b;
95 }
96 else {
97 return b;
98 }
99 }
100
FPU_handle_NaN(floatx80 a,float32 b,floatx80 & r,float_status_t & status)101 int FPU_handle_NaN(floatx80 a, float32 b, floatx80 &r, float_status_t &status)
102 {
103 if (floatx80_is_unsupported(a)) {
104 float_raise(status, float_flag_invalid);
105 r = floatx80_default_nan;
106 return 1;
107 }
108
109 int aIsNaN = floatx80_is_nan(a), bIsNaN = float32_is_nan(b);
110 if (aIsNaN | bIsNaN) {
111 r = FPU_handle_NaN(a, aIsNaN, b, bIsNaN, status);
112 return 1;
113 }
114 return 0;
115 }
116
FPU_handle_NaN(floatx80 a,int aIsNaN,float64 b64,int bIsNaN,float_status_t & status)117 floatx80 FPU_handle_NaN(floatx80 a, int aIsNaN, float64 b64, int bIsNaN, float_status_t &status)
118 {
119 int aIsSignalingNaN = floatx80_is_signaling_nan(a);
120 int bIsSignalingNaN = float64_is_signaling_nan(b64);
121
122 if (aIsSignalingNaN | bIsSignalingNaN)
123 float_raise(status, float_flag_invalid);
124
125 // propagate QNaN to SNaN
126 a = propagateFloatx80NaN(a, status);
127
128 if (aIsNaN & !bIsNaN) return a;
129
130 // float64 is NaN so conversion will propagate SNaN to QNaN and raise
131 // appropriate exception flags
132 floatx80 b = float64_to_floatx80(b64, status);
133
134 if (aIsSignalingNaN) {
135 if (bIsSignalingNaN) goto returnLargerSignificand;
136 return bIsNaN ? b : a;
137 }
138 else if (aIsNaN) {
139 if (bIsSignalingNaN) return a;
140 returnLargerSignificand:
141 if (a.fraction < b.fraction) return b;
142 if (b.fraction < a.fraction) return a;
143 return (a.exp < b.exp) ? a : b;
144 }
145 else {
146 return b;
147 }
148 }
149
FPU_handle_NaN(floatx80 a,float64 b,floatx80 & r,float_status_t & status)150 int FPU_handle_NaN(floatx80 a, float64 b, floatx80 &r, float_status_t &status)
151 {
152 if (floatx80_is_unsupported(a)) {
153 float_raise(status, float_flag_invalid);
154 r = floatx80_default_nan;
155 return 1;
156 }
157
158 int aIsNaN = floatx80_is_nan(a), bIsNaN = float64_is_nan(b);
159 if (aIsNaN | bIsNaN) {
160 r = FPU_handle_NaN(a, aIsNaN, b, bIsNaN, status);
161 return 1;
162 }
163 return 0;
164 }
165
FADD_ST0_STj(bxInstruction_c * i)166 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FADD_ST0_STj(bxInstruction_c *i)
167 {
168 BX_CPU_THIS_PTR prepareFPU(i);
169 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
170
171 clear_C1();
172
173 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->src()))
174 {
175 FPU_stack_underflow(i, 0);
176 BX_NEXT_INSTR(i);
177 }
178
179 floatx80 a = BX_READ_FPU_REG(0);
180 floatx80 b = BX_READ_FPU_REG(i->src());
181
182 float_status_t status =
183 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
184
185 floatx80 result = floatx80_add(a, b, status);
186
187 if (! FPU_exception(i, status.float_exception_flags))
188 BX_WRITE_FPU_REG(result, 0);
189
190 BX_NEXT_INSTR(i);
191 }
192
FADD_STi_ST0(bxInstruction_c * i)193 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FADD_STi_ST0(bxInstruction_c *i)
194 {
195 BX_CPU_THIS_PTR prepareFPU(i);
196 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
197
198 int pop_stack = i->b1() & 2;
199
200 clear_C1();
201
202 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->dst()))
203 {
204 FPU_stack_underflow(i, i->dst(), pop_stack);
205 BX_NEXT_INSTR(i);
206 }
207
208 floatx80 a = BX_READ_FPU_REG(i->dst());
209 floatx80 b = BX_READ_FPU_REG(0);
210
211 float_status_t status =
212 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
213
214 floatx80 result = floatx80_add(a, b, status);
215
216 if (! FPU_exception(i, status.float_exception_flags)) {
217 BX_WRITE_FPU_REG(result, i->dst());
218 if (pop_stack)
219 BX_CPU_THIS_PTR the_i387.FPU_pop();
220 }
221
222 BX_NEXT_INSTR(i);
223 }
224
FADD_SINGLE_REAL(bxInstruction_c * i)225 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FADD_SINGLE_REAL(bxInstruction_c *i)
226 {
227 BX_CPU_THIS_PTR prepareFPU(i);
228
229 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
230 float32 load_reg = read_virtual_dword(i->seg(), RMAddr(i));
231
232 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
233
234 clear_C1();
235
236 if (IS_TAG_EMPTY(0)) {
237 FPU_stack_underflow(i, 0);
238 BX_NEXT_INSTR(i);
239 }
240
241 float_status_t status =
242 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
243
244 floatx80 a = BX_READ_FPU_REG(0), result;
245 if (! FPU_handle_NaN(a, load_reg, result, status))
246 result = floatx80_add(a, float32_to_floatx80(load_reg, status), status);
247
248 if (! FPU_exception(i, status.float_exception_flags))
249 BX_WRITE_FPU_REG(result, 0);
250
251 BX_NEXT_INSTR(i);
252 }
253
FADD_DOUBLE_REAL(bxInstruction_c * i)254 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FADD_DOUBLE_REAL(bxInstruction_c *i)
255 {
256 BX_CPU_THIS_PTR prepareFPU(i);
257
258 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
259 float64 load_reg = read_virtual_qword(i->seg(), RMAddr(i));
260
261 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
262
263 clear_C1();
264
265 if (IS_TAG_EMPTY(0)) {
266 FPU_stack_underflow(i, 0);
267 BX_NEXT_INSTR(i);
268 }
269
270 float_status_t status =
271 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
272
273 floatx80 a = BX_READ_FPU_REG(0), result;
274 if (! FPU_handle_NaN(a, load_reg, result, status))
275 result = floatx80_add(a, float64_to_floatx80(load_reg, status), status);
276
277 if (! FPU_exception(i, status.float_exception_flags))
278 BX_WRITE_FPU_REG(result, 0);
279
280 BX_NEXT_INSTR(i);
281 }
282
FIADD_WORD_INTEGER(bxInstruction_c * i)283 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIADD_WORD_INTEGER(bxInstruction_c *i)
284 {
285 BX_CPU_THIS_PTR prepareFPU(i);
286
287 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
288 Bit16s load_reg = (Bit16s) read_virtual_word(i->seg(), RMAddr(i));
289
290 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
291
292 clear_C1();
293
294 if (IS_TAG_EMPTY(0)) {
295 FPU_stack_underflow(i, 0);
296 BX_NEXT_INSTR(i);
297 }
298
299 floatx80 a = BX_READ_FPU_REG(0);
300 floatx80 b = int32_to_floatx80((Bit32s)(load_reg));
301
302 float_status_t status =
303 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
304
305 floatx80 result = floatx80_add(a, b, status);
306
307 if (! FPU_exception(i, status.float_exception_flags))
308 BX_WRITE_FPU_REG(result, 0);
309
310 BX_NEXT_INSTR(i);
311 }
312
FIADD_DWORD_INTEGER(bxInstruction_c * i)313 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIADD_DWORD_INTEGER(bxInstruction_c *i)
314 {
315 BX_CPU_THIS_PTR prepareFPU(i);
316
317 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
318 Bit32s load_reg = (Bit32s) read_virtual_dword(i->seg(), RMAddr(i));
319
320 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
321
322 clear_C1();
323
324 if (IS_TAG_EMPTY(0)) {
325 FPU_stack_underflow(i, 0);
326 BX_NEXT_INSTR(i);
327 }
328
329 floatx80 a = BX_READ_FPU_REG(0);
330 floatx80 b = int32_to_floatx80(load_reg);
331
332 float_status_t status =
333 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
334
335 floatx80 result = floatx80_add(a, b, status);
336
337 if (! FPU_exception(i, status.float_exception_flags))
338 BX_WRITE_FPU_REG(result, 0);
339
340 BX_NEXT_INSTR(i);
341 }
342
FMUL_ST0_STj(bxInstruction_c * i)343 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FMUL_ST0_STj(bxInstruction_c *i)
344 {
345 BX_CPU_THIS_PTR prepareFPU(i);
346 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
347
348 clear_C1();
349
350 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->src()))
351 {
352 FPU_stack_underflow(i, 0);
353 BX_NEXT_INSTR(i);
354 }
355
356 floatx80 a = BX_READ_FPU_REG(0);
357 floatx80 b = BX_READ_FPU_REG(i->src());
358
359 float_status_t status =
360 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
361
362 floatx80 result = floatx80_mul(a, b, status);
363
364 if (! FPU_exception(i, status.float_exception_flags))
365 BX_WRITE_FPU_REG(result, 0);
366
367 BX_NEXT_INSTR(i);
368 }
369
FMUL_STi_ST0(bxInstruction_c * i)370 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FMUL_STi_ST0(bxInstruction_c *i)
371 {
372 BX_CPU_THIS_PTR prepareFPU(i);
373 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
374
375 int pop_stack = i->b1() & 2;
376
377 clear_C1();
378
379 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->dst()))
380 {
381 FPU_stack_underflow(i, i->dst(), pop_stack);
382 BX_NEXT_INSTR(i);
383 }
384
385 floatx80 a = BX_READ_FPU_REG(i->dst());
386 floatx80 b = BX_READ_FPU_REG(0);
387
388 float_status_t status =
389 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
390
391 floatx80 result = floatx80_mul(a, b, status);
392
393 if (! FPU_exception(i, status.float_exception_flags)) {
394 BX_WRITE_FPU_REG(result, i->dst());
395 if (pop_stack)
396 BX_CPU_THIS_PTR the_i387.FPU_pop();
397 }
398
399 BX_NEXT_INSTR(i);
400 }
401
FMUL_SINGLE_REAL(bxInstruction_c * i)402 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FMUL_SINGLE_REAL(bxInstruction_c *i)
403 {
404 BX_CPU_THIS_PTR prepareFPU(i);
405
406 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
407 float32 load_reg = read_virtual_dword(i->seg(), RMAddr(i));
408
409 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
410
411 clear_C1();
412
413 if (IS_TAG_EMPTY(0)) {
414 FPU_stack_underflow(i, 0);
415 BX_NEXT_INSTR(i);
416 }
417
418 float_status_t status =
419 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
420
421 floatx80 a = BX_READ_FPU_REG(0), result;
422 if (! FPU_handle_NaN(a, load_reg, result, status))
423 result = floatx80_mul(a, float32_to_floatx80(load_reg, status), status);
424
425 if (! FPU_exception(i, status.float_exception_flags))
426 BX_WRITE_FPU_REG(result, 0);
427
428 BX_NEXT_INSTR(i);
429 }
430
FMUL_DOUBLE_REAL(bxInstruction_c * i)431 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FMUL_DOUBLE_REAL(bxInstruction_c *i)
432 {
433 BX_CPU_THIS_PTR prepareFPU(i);
434
435 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
436 float64 load_reg = read_virtual_qword(i->seg(), RMAddr(i));
437
438 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
439
440 clear_C1();
441
442 if (IS_TAG_EMPTY(0)) {
443 FPU_stack_underflow(i, 0);
444 BX_NEXT_INSTR(i);
445 }
446
447 float_status_t status =
448 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
449
450 floatx80 a = BX_READ_FPU_REG(0), result;
451 if (! FPU_handle_NaN(a, load_reg, result, status))
452 result = floatx80_mul(a, float64_to_floatx80(load_reg, status), status);
453
454 if (! FPU_exception(i, status.float_exception_flags))
455 BX_WRITE_FPU_REG(result, 0);
456
457 BX_NEXT_INSTR(i);
458 }
459
FIMUL_WORD_INTEGER(bxInstruction_c * i)460 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIMUL_WORD_INTEGER(bxInstruction_c *i)
461 {
462 BX_CPU_THIS_PTR prepareFPU(i);
463
464 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
465 Bit16s load_reg = (Bit16s) read_virtual_word(i->seg(), RMAddr(i));
466
467 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
468
469 clear_C1();
470
471 if (IS_TAG_EMPTY(0)) {
472 FPU_stack_underflow(i, 0);
473 BX_NEXT_INSTR(i);
474 }
475
476 floatx80 a = BX_READ_FPU_REG(0);
477 floatx80 b = int32_to_floatx80((Bit32s)(load_reg));
478
479 float_status_t status =
480 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
481
482 floatx80 result = floatx80_mul(a, b, status);
483
484 if (! FPU_exception(i, status.float_exception_flags))
485 BX_WRITE_FPU_REG(result, 0);
486
487 BX_NEXT_INSTR(i);
488 }
489
FIMUL_DWORD_INTEGER(bxInstruction_c * i)490 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIMUL_DWORD_INTEGER(bxInstruction_c *i)
491 {
492 BX_CPU_THIS_PTR prepareFPU(i);
493
494 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
495 Bit32s load_reg = (Bit32s) read_virtual_dword(i->seg(), RMAddr(i));
496
497 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
498
499 clear_C1();
500
501 if (IS_TAG_EMPTY(0)) {
502 FPU_stack_underflow(i, 0);
503 BX_NEXT_INSTR(i);
504 }
505
506 floatx80 a = BX_READ_FPU_REG(0);
507 floatx80 b = int32_to_floatx80(load_reg);
508
509 float_status_t status =
510 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
511
512 floatx80 result = floatx80_mul(a, b, status);
513
514 if (! FPU_exception(i, status.float_exception_flags))
515 BX_WRITE_FPU_REG(result, 0);
516
517 BX_NEXT_INSTR(i);
518 }
519
FSUB_ST0_STj(bxInstruction_c * i)520 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUB_ST0_STj(bxInstruction_c *i)
521 {
522 BX_CPU_THIS_PTR prepareFPU(i);
523 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
524
525 clear_C1();
526
527 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->src()))
528 {
529 FPU_stack_underflow(i, 0);
530 BX_NEXT_INSTR(i);
531 }
532
533 floatx80 a = BX_READ_FPU_REG(0);
534 floatx80 b = BX_READ_FPU_REG(i->src());
535
536 float_status_t status =
537 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
538
539 floatx80 result = floatx80_sub(a, b, status);
540
541 if (! FPU_exception(i, status.float_exception_flags))
542 BX_WRITE_FPU_REG(result, 0);
543
544 BX_NEXT_INSTR(i);
545 }
546
FSUBR_ST0_STj(bxInstruction_c * i)547 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUBR_ST0_STj(bxInstruction_c *i)
548 {
549 BX_CPU_THIS_PTR prepareFPU(i);
550 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
551
552 clear_C1();
553
554 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->src()))
555 {
556 FPU_stack_underflow(i, 0);
557 BX_NEXT_INSTR(i);
558 }
559
560 floatx80 a = BX_READ_FPU_REG(i->src());
561 floatx80 b = BX_READ_FPU_REG(0);
562
563 float_status_t status =
564 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
565
566 floatx80 result = floatx80_sub(a, b, status);
567
568 if (! FPU_exception(i, status.float_exception_flags))
569 BX_WRITE_FPU_REG(result, 0);
570
571 BX_NEXT_INSTR(i);
572 }
573
FSUB_STi_ST0(bxInstruction_c * i)574 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUB_STi_ST0(bxInstruction_c *i)
575 {
576 BX_CPU_THIS_PTR prepareFPU(i);
577 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
578
579 int pop_stack = i->b1() & 2;
580
581 clear_C1();
582
583 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->dst()))
584 {
585 FPU_stack_underflow(i, i->dst(), pop_stack);
586 BX_NEXT_INSTR(i);
587 }
588
589 floatx80 a = BX_READ_FPU_REG(i->dst());
590 floatx80 b = BX_READ_FPU_REG(0);
591
592 float_status_t status =
593 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
594
595 floatx80 result = floatx80_sub(a, b, status);
596
597 if (! FPU_exception(i, status.float_exception_flags)) {
598 BX_WRITE_FPU_REG(result, i->dst());
599 if (pop_stack)
600 BX_CPU_THIS_PTR the_i387.FPU_pop();
601 }
602
603 BX_NEXT_INSTR(i);
604 }
605
FSUBR_STi_ST0(bxInstruction_c * i)606 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUBR_STi_ST0(bxInstruction_c *i)
607 {
608 BX_CPU_THIS_PTR prepareFPU(i);
609 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
610
611 int pop_stack = i->b1() & 2;
612
613 clear_C1();
614
615 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->dst()))
616 {
617 FPU_stack_underflow(i, i->dst(), pop_stack);
618 BX_NEXT_INSTR(i);
619 }
620
621 floatx80 a = BX_READ_FPU_REG(0);
622 floatx80 b = BX_READ_FPU_REG(i->dst());
623
624 float_status_t status =
625 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
626
627 floatx80 result = floatx80_sub(a, b, status);
628
629 if (! FPU_exception(i, status.float_exception_flags)) {
630 BX_WRITE_FPU_REG(result, i->dst());
631 if (pop_stack)
632 BX_CPU_THIS_PTR the_i387.FPU_pop();
633 }
634
635 BX_NEXT_INSTR(i);
636 }
637
FSUB_SINGLE_REAL(bxInstruction_c * i)638 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUB_SINGLE_REAL(bxInstruction_c *i)
639 {
640 BX_CPU_THIS_PTR prepareFPU(i);
641
642 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
643 float32 load_reg = read_virtual_dword(i->seg(), RMAddr(i));
644
645 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
646
647 clear_C1();
648
649 if (IS_TAG_EMPTY(0)) {
650 FPU_stack_underflow(i, 0);
651 BX_NEXT_INSTR(i);
652 }
653
654 float_status_t status =
655 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
656
657 floatx80 a = BX_READ_FPU_REG(0), result;
658 if (! FPU_handle_NaN(a, load_reg, result, status))
659 result = floatx80_sub(a, float32_to_floatx80(load_reg, status), status);
660
661 if (! FPU_exception(i, status.float_exception_flags))
662 BX_WRITE_FPU_REG(result, 0);
663
664 BX_NEXT_INSTR(i);
665 }
666
FSUBR_SINGLE_REAL(bxInstruction_c * i)667 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUBR_SINGLE_REAL(bxInstruction_c *i)
668 {
669 BX_CPU_THIS_PTR prepareFPU(i);
670
671 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
672 float32 load_reg = read_virtual_dword(i->seg(), RMAddr(i));
673
674 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
675
676 clear_C1();
677
678 if (IS_TAG_EMPTY(0)) {
679 FPU_stack_underflow(i, 0);
680 BX_NEXT_INSTR(i);
681 }
682
683 float_status_t status =
684 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
685
686 floatx80 b = BX_READ_FPU_REG(0), result;
687 if (! FPU_handle_NaN(b, load_reg, result, status))
688 result = floatx80_sub(float32_to_floatx80(load_reg, status), b, status);
689
690 if (! FPU_exception(i, status.float_exception_flags))
691 BX_WRITE_FPU_REG(result, 0);
692
693 BX_NEXT_INSTR(i);
694 }
695
FSUB_DOUBLE_REAL(bxInstruction_c * i)696 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUB_DOUBLE_REAL(bxInstruction_c *i)
697 {
698 BX_CPU_THIS_PTR prepareFPU(i);
699
700 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
701 float64 load_reg = read_virtual_qword(i->seg(), RMAddr(i));
702
703 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
704
705 clear_C1();
706
707 if (IS_TAG_EMPTY(0)) {
708 FPU_stack_underflow(i, 0);
709 BX_NEXT_INSTR(i);
710 }
711
712 float_status_t status =
713 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
714
715 floatx80 a = BX_READ_FPU_REG(0), result;
716 if (! FPU_handle_NaN(a, load_reg, result, status))
717 result = floatx80_sub(a, float64_to_floatx80(load_reg, status), status);
718
719 if (! FPU_exception(i, status.float_exception_flags))
720 BX_WRITE_FPU_REG(result, 0);
721
722 BX_NEXT_INSTR(i);
723 }
724
FSUBR_DOUBLE_REAL(bxInstruction_c * i)725 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSUBR_DOUBLE_REAL(bxInstruction_c *i)
726 {
727 BX_CPU_THIS_PTR prepareFPU(i);
728
729 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
730 float64 load_reg = read_virtual_qword(i->seg(), RMAddr(i));
731
732 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
733
734 clear_C1();
735
736 if (IS_TAG_EMPTY(0)) {
737 FPU_stack_underflow(i, 0);
738 BX_NEXT_INSTR(i);
739 }
740
741 float_status_t status =
742 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
743
744
745 floatx80 b = BX_READ_FPU_REG(0), result;
746 if (! FPU_handle_NaN(b, load_reg, result, status))
747 result = floatx80_sub(float64_to_floatx80(load_reg, status), b, status);
748
749 if (! FPU_exception(i, status.float_exception_flags))
750 BX_WRITE_FPU_REG(result, 0);
751
752 BX_NEXT_INSTR(i);
753 }
754
FISUB_WORD_INTEGER(bxInstruction_c * i)755 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISUB_WORD_INTEGER(bxInstruction_c *i)
756 {
757 BX_CPU_THIS_PTR prepareFPU(i);
758
759 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
760 Bit16s load_reg = (Bit16s) read_virtual_word(i->seg(), RMAddr(i));
761
762 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
763
764 clear_C1();
765
766 if (IS_TAG_EMPTY(0)) {
767 FPU_stack_underflow(i, 0);
768 BX_NEXT_INSTR(i);
769 }
770
771 floatx80 a = BX_READ_FPU_REG(0);
772 floatx80 b = int32_to_floatx80((Bit32s)(load_reg));
773
774 float_status_t status =
775 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
776
777 floatx80 result = floatx80_sub(a, b, status);
778
779 if (! FPU_exception(i, status.float_exception_flags))
780 BX_WRITE_FPU_REG(result, 0);
781
782 BX_NEXT_INSTR(i);
783 }
784
FISUBR_WORD_INTEGER(bxInstruction_c * i)785 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISUBR_WORD_INTEGER(bxInstruction_c *i)
786 {
787 BX_CPU_THIS_PTR prepareFPU(i);
788
789 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
790 Bit16s load_reg = (Bit16s) read_virtual_word(i->seg(), RMAddr(i));
791
792 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
793
794 clear_C1();
795
796 if (IS_TAG_EMPTY(0)) {
797 FPU_stack_underflow(i, 0);
798 BX_NEXT_INSTR(i);
799 }
800
801 floatx80 a = int32_to_floatx80((Bit32s)(load_reg));
802 floatx80 b = BX_READ_FPU_REG(0);
803
804 float_status_t status =
805 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
806
807 floatx80 result = floatx80_sub(a, b, status);
808
809 if (! FPU_exception(i, status.float_exception_flags))
810 BX_WRITE_FPU_REG(result, 0);
811
812 BX_NEXT_INSTR(i);
813 }
814
FISUB_DWORD_INTEGER(bxInstruction_c * i)815 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISUB_DWORD_INTEGER(bxInstruction_c *i)
816 {
817 BX_CPU_THIS_PTR prepareFPU(i);
818
819 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
820 Bit32s load_reg = (Bit32s) read_virtual_dword(i->seg(), RMAddr(i));
821
822 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
823
824 clear_C1();
825
826 if (IS_TAG_EMPTY(0)) {
827 FPU_stack_underflow(i, 0);
828 BX_NEXT_INSTR(i);
829 }
830
831 float_status_t status =
832 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
833
834 floatx80 result = floatx80_sub(BX_READ_FPU_REG(0), int32_to_floatx80(load_reg), status);
835
836 if (! FPU_exception(i, status.float_exception_flags))
837 BX_WRITE_FPU_REG(result, 0);
838
839 BX_NEXT_INSTR(i);
840 }
841
FISUBR_DWORD_INTEGER(bxInstruction_c * i)842 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FISUBR_DWORD_INTEGER(bxInstruction_c *i)
843 {
844 BX_CPU_THIS_PTR prepareFPU(i);
845
846 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
847 Bit32s load_reg = (Bit32s) read_virtual_dword(i->seg(), RMAddr(i));
848
849 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
850
851 clear_C1();
852
853 if (IS_TAG_EMPTY(0)) {
854 FPU_stack_underflow(i, 0);
855 BX_NEXT_INSTR(i);
856 }
857
858 floatx80 a = int32_to_floatx80(load_reg);
859 floatx80 b = BX_READ_FPU_REG(0);
860
861 float_status_t status =
862 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
863
864 floatx80 result = floatx80_sub(a, b, status);
865
866 if (! FPU_exception(i, status.float_exception_flags))
867 BX_WRITE_FPU_REG(result, 0);
868
869 BX_NEXT_INSTR(i);
870 }
871
FDIV_ST0_STj(bxInstruction_c * i)872 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIV_ST0_STj(bxInstruction_c *i)
873 {
874 BX_CPU_THIS_PTR prepareFPU(i);
875 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
876
877 clear_C1();
878
879 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->src()))
880 {
881 FPU_stack_underflow(i, 0);
882 BX_NEXT_INSTR(i);
883 }
884
885 floatx80 a = BX_READ_FPU_REG(0);
886 floatx80 b = BX_READ_FPU_REG(i->src());
887
888 float_status_t status =
889 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
890
891 floatx80 result = floatx80_div(a, b, status);
892
893 if (! FPU_exception(i, status.float_exception_flags))
894 BX_WRITE_FPU_REG(result, 0);
895
896 BX_NEXT_INSTR(i);
897 }
898
FDIVR_ST0_STj(bxInstruction_c * i)899 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIVR_ST0_STj(bxInstruction_c *i)
900 {
901 BX_CPU_THIS_PTR prepareFPU(i);
902 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
903
904 clear_C1();
905
906 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->src()))
907 {
908 FPU_stack_underflow(i, 0);
909 BX_NEXT_INSTR(i);
910 }
911
912 floatx80 a = BX_READ_FPU_REG(i->src());
913 floatx80 b = BX_READ_FPU_REG(0);
914
915 float_status_t status =
916 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
917
918 floatx80 result = floatx80_div(a, b, status);
919
920 if (! FPU_exception(i, status.float_exception_flags))
921 BX_WRITE_FPU_REG(result, 0);
922
923 BX_NEXT_INSTR(i);
924 }
925
FDIV_STi_ST0(bxInstruction_c * i)926 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIV_STi_ST0(bxInstruction_c *i)
927 {
928 BX_CPU_THIS_PTR prepareFPU(i);
929 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
930
931 int pop_stack = i->b1() & 2;
932
933 clear_C1();
934
935 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->dst()))
936 {
937 FPU_stack_underflow(i, i->dst(), pop_stack);
938 BX_NEXT_INSTR(i);
939 }
940
941 floatx80 a = BX_READ_FPU_REG(i->dst());
942 floatx80 b = BX_READ_FPU_REG(0);
943
944 float_status_t status =
945 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
946
947 floatx80 result = floatx80_div(a, b, status);
948
949 if (! FPU_exception(i, status.float_exception_flags)) {
950 BX_WRITE_FPU_REG(result, i->dst());
951 if (pop_stack)
952 BX_CPU_THIS_PTR the_i387.FPU_pop();
953 }
954
955 BX_NEXT_INSTR(i);
956 }
957
FDIVR_STi_ST0(bxInstruction_c * i)958 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIVR_STi_ST0(bxInstruction_c *i)
959 {
960 BX_CPU_THIS_PTR prepareFPU(i);
961 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
962
963 int pop_stack = i->b1() & 2;
964
965 clear_C1();
966
967 if (IS_TAG_EMPTY(0) || IS_TAG_EMPTY(i->dst()))
968 {
969 FPU_stack_underflow(i, i->dst(), pop_stack);
970 BX_NEXT_INSTR(i);
971 }
972
973 floatx80 a = BX_READ_FPU_REG(0);
974 floatx80 b = BX_READ_FPU_REG(i->dst());
975
976 float_status_t status =
977 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
978
979 floatx80 result = floatx80_div(a, b, status);
980
981 if (! FPU_exception(i, status.float_exception_flags)) {
982 BX_WRITE_FPU_REG(result, i->dst());
983 if (pop_stack)
984 BX_CPU_THIS_PTR the_i387.FPU_pop();
985 }
986
987 BX_NEXT_INSTR(i);
988 }
989
FDIV_SINGLE_REAL(bxInstruction_c * i)990 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIV_SINGLE_REAL(bxInstruction_c *i)
991 {
992 BX_CPU_THIS_PTR prepareFPU(i);
993
994 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
995 float32 load_reg = read_virtual_dword(i->seg(), RMAddr(i));
996
997 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
998
999 clear_C1();
1000
1001 if (IS_TAG_EMPTY(0)) {
1002 FPU_stack_underflow(i, 0);
1003 BX_NEXT_INSTR(i);
1004 }
1005
1006 float_status_t status =
1007 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
1008
1009 floatx80 a = BX_READ_FPU_REG(0), result;
1010 if (! FPU_handle_NaN(a, load_reg, result, status))
1011 result = floatx80_div(a, float32_to_floatx80(load_reg, status), status);
1012
1013 if (! FPU_exception(i, status.float_exception_flags))
1014 BX_WRITE_FPU_REG(result, 0);
1015
1016 BX_NEXT_INSTR(i);
1017 }
1018
FDIVR_SINGLE_REAL(bxInstruction_c * i)1019 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIVR_SINGLE_REAL(bxInstruction_c *i)
1020 {
1021 BX_CPU_THIS_PTR prepareFPU(i);
1022
1023 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
1024 float32 load_reg = read_virtual_dword(i->seg(), RMAddr(i));
1025
1026 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
1027
1028 clear_C1();
1029
1030 if (IS_TAG_EMPTY(0)) {
1031 FPU_stack_underflow(i, 0);
1032 BX_NEXT_INSTR(i);
1033 }
1034
1035 float_status_t status =
1036 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
1037
1038 floatx80 b = BX_READ_FPU_REG(0), result;
1039 if (! FPU_handle_NaN(b, load_reg, result, status))
1040 result = floatx80_div(float32_to_floatx80(load_reg, status), b, status);
1041
1042 if (! FPU_exception(i, status.float_exception_flags))
1043 BX_WRITE_FPU_REG(result, 0);
1044
1045 BX_NEXT_INSTR(i);
1046 }
1047
FDIV_DOUBLE_REAL(bxInstruction_c * i)1048 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIV_DOUBLE_REAL(bxInstruction_c *i)
1049 {
1050 BX_CPU_THIS_PTR prepareFPU(i);
1051
1052 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
1053 float64 load_reg = read_virtual_qword(i->seg(), RMAddr(i));
1054
1055 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
1056
1057 clear_C1();
1058
1059 if (IS_TAG_EMPTY(0)) {
1060 FPU_stack_underflow(i, 0);
1061 BX_NEXT_INSTR(i);
1062 }
1063
1064 float_status_t status =
1065 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
1066
1067 floatx80 a = BX_READ_FPU_REG(0), result;
1068 if (! FPU_handle_NaN(a, load_reg, result, status))
1069 result = floatx80_div(a, float64_to_floatx80(load_reg, status), status);
1070
1071 if (! FPU_exception(i, status.float_exception_flags))
1072 BX_WRITE_FPU_REG(result, 0);
1073
1074 BX_NEXT_INSTR(i);
1075 }
1076
FDIVR_DOUBLE_REAL(bxInstruction_c * i)1077 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FDIVR_DOUBLE_REAL(bxInstruction_c *i)
1078 {
1079 BX_CPU_THIS_PTR prepareFPU(i);
1080
1081 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
1082 float64 load_reg = read_virtual_qword(i->seg(), RMAddr(i));
1083
1084 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
1085
1086 clear_C1();
1087
1088 if (IS_TAG_EMPTY(0)) {
1089 FPU_stack_underflow(i, 0);
1090 BX_NEXT_INSTR(i);
1091 }
1092
1093 float_status_t status =
1094 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
1095
1096 floatx80 b = BX_READ_FPU_REG(0), result;
1097 if (! FPU_handle_NaN(b, load_reg, result, status))
1098 result = floatx80_div(float64_to_floatx80(load_reg, status), b, status);
1099
1100 if (! FPU_exception(i, status.float_exception_flags))
1101 BX_WRITE_FPU_REG(result, 0);
1102
1103 BX_NEXT_INSTR(i);
1104 }
1105
FIDIV_WORD_INTEGER(bxInstruction_c * i)1106 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIDIV_WORD_INTEGER(bxInstruction_c *i)
1107 {
1108 BX_CPU_THIS_PTR prepareFPU(i);
1109
1110 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
1111 Bit16s load_reg = (Bit16s) read_virtual_word(i->seg(), RMAddr(i));
1112
1113 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
1114
1115 clear_C1();
1116
1117 if (IS_TAG_EMPTY(0)) {
1118 FPU_stack_underflow(i, 0);
1119 BX_NEXT_INSTR(i);
1120 }
1121
1122 floatx80 a = BX_READ_FPU_REG(0);
1123 floatx80 b = int32_to_floatx80((Bit32s)(load_reg));
1124
1125 float_status_t status =
1126 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
1127
1128 floatx80 result = floatx80_div(a, b, status);
1129
1130 if (! FPU_exception(i, status.float_exception_flags))
1131 BX_WRITE_FPU_REG(result, 0);
1132
1133 BX_NEXT_INSTR(i);
1134 }
1135
FIDIVR_WORD_INTEGER(bxInstruction_c * i)1136 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIDIVR_WORD_INTEGER(bxInstruction_c *i)
1137 {
1138 BX_CPU_THIS_PTR prepareFPU(i);
1139
1140 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
1141 Bit16s load_reg = (Bit16s) read_virtual_word(i->seg(), RMAddr(i));
1142
1143 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
1144
1145 clear_C1();
1146
1147 if (IS_TAG_EMPTY(0)) {
1148 FPU_stack_underflow(i, 0);
1149 BX_NEXT_INSTR(i);
1150 }
1151
1152 floatx80 a = int32_to_floatx80((Bit32s)(load_reg));
1153 floatx80 b = BX_READ_FPU_REG(0);
1154
1155 float_status_t status =
1156 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
1157
1158 floatx80 result = floatx80_div(a, b, status);
1159
1160 if (! FPU_exception(i, status.float_exception_flags))
1161 BX_WRITE_FPU_REG(result, 0);
1162
1163 BX_NEXT_INSTR(i);
1164 }
1165
FIDIV_DWORD_INTEGER(bxInstruction_c * i)1166 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIDIV_DWORD_INTEGER(bxInstruction_c *i)
1167 {
1168 BX_CPU_THIS_PTR prepareFPU(i);
1169
1170 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
1171 Bit32s load_reg = (Bit32s) read_virtual_dword(i->seg(), RMAddr(i));
1172
1173 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
1174
1175 clear_C1();
1176
1177 if (IS_TAG_EMPTY(0)) {
1178 FPU_stack_underflow(i, 0);
1179 BX_NEXT_INSTR(i);
1180 }
1181
1182 floatx80 a = BX_READ_FPU_REG(0);
1183 floatx80 b = int32_to_floatx80(load_reg);
1184
1185 float_status_t status =
1186 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
1187
1188 floatx80 result = floatx80_div(a, b, status);
1189
1190 if (! FPU_exception(i, status.float_exception_flags))
1191 BX_WRITE_FPU_REG(result, 0);
1192
1193 BX_NEXT_INSTR(i);
1194 }
1195
FIDIVR_DWORD_INTEGER(bxInstruction_c * i)1196 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FIDIVR_DWORD_INTEGER(bxInstruction_c *i)
1197 {
1198 BX_CPU_THIS_PTR prepareFPU(i);
1199
1200 RMAddr(i) = BX_CPU_RESOLVE_ADDR(i);
1201 Bit32s load_reg = (Bit32s) read_virtual_dword(i->seg(), RMAddr(i));
1202
1203 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
1204
1205 clear_C1();
1206
1207 if (IS_TAG_EMPTY(0)) {
1208 FPU_stack_underflow(i, 0);
1209 BX_NEXT_INSTR(i);
1210 }
1211
1212 floatx80 a = int32_to_floatx80(load_reg);
1213 floatx80 b = BX_READ_FPU_REG(0);
1214
1215 float_status_t status =
1216 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
1217
1218 floatx80 result = floatx80_div(a, b, status);
1219
1220 if (! FPU_exception(i, status.float_exception_flags))
1221 BX_WRITE_FPU_REG(result, 0);
1222
1223 BX_NEXT_INSTR(i);
1224 }
1225
FSQRT(bxInstruction_c * i)1226 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FSQRT(bxInstruction_c *i)
1227 {
1228 BX_CPU_THIS_PTR prepareFPU(i);
1229 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
1230
1231 clear_C1();
1232
1233 if (IS_TAG_EMPTY(0)) {
1234 FPU_stack_underflow(i, 0);
1235 BX_NEXT_INSTR(i);
1236 }
1237
1238 float_status_t status =
1239 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
1240
1241 floatx80 result = floatx80_sqrt(BX_READ_FPU_REG(0), status);
1242
1243 if (! FPU_exception(i, status.float_exception_flags))
1244 BX_WRITE_FPU_REG(result, 0);
1245
1246 BX_NEXT_INSTR(i);
1247 }
1248
1249 /* D9 FC */
FRNDINT(bxInstruction_c * i)1250 void BX_CPP_AttrRegparmN(1) BX_CPU_C::FRNDINT(bxInstruction_c *i)
1251 {
1252 BX_CPU_THIS_PTR prepareFPU(i);
1253 BX_CPU_THIS_PTR FPU_update_last_instruction(i);
1254
1255 clear_C1();
1256
1257 if (IS_TAG_EMPTY(0)) {
1258 FPU_stack_underflow(i, 0);
1259 BX_NEXT_INSTR(i);
1260 }
1261
1262 float_status_t status =
1263 i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
1264
1265 floatx80 result = floatx80_round_to_int(BX_READ_FPU_REG(0), status);
1266
1267 if (! FPU_exception(i, status.float_exception_flags))
1268 BX_WRITE_FPU_REG(result, 0);
1269
1270 BX_NEXT_INSTR(i);
1271 }
1272
1273 #endif
1274