LoongArch: Add elfNN_loongarch_mkobject to initialize LoongArch tdata
[binutils-gdb.git] / sim / mips / cp1.c
blob470215d93628aa4995e0aad324e9e982400a133c
1 /*> cp1.c <*/
2 /* MIPS Simulator FPU (CoProcessor 1) support.
3 Copyright (C) 2002-2024 Free Software Foundation, Inc.
4 Originally created by Cygnus Solutions. Extensive modifications,
5 including paired-single operation support and MIPS-3D support
6 contributed by Ed Satterthwaite and Chris Demetriou, of Broadcom
7 Corporation (SiByte).
9 This file is part of GDB, the GNU debugger.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 /* XXX: The following notice should be removed as soon as is practical: */
25 /* Floating Point Support for gdb MIPS simulators
27 This file is part of the MIPS sim
29 THIS SOFTWARE IS NOT COPYRIGHTED
30 (by Cygnus.)
32 Cygnus offers the following for use in the public domain. Cygnus
33 makes no warranty with regard to the software or it's performance
34 and the user accepts the software "AS IS" with all faults.
36 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
37 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
38 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
40 (Originally, this code was in interp.c)
43 /* This must come before any other includes. */
44 #include "defs.h"
46 #include "sim-main.h"
48 #include <stdlib.h>
50 /* Within cp1.c we refer to sim_cpu directly. */
51 #define CPU cpu
52 #define SD CPU_STATE(cpu)
54 /*-- FPU support routines ---------------------------------------------------*/
56 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
57 formats conform to ANSI/IEEE Std 754-1985.
59 SINGLE precision floating:
60 seeeeeeeefffffffffffffffffffffff
61 s = 1bit = sign
62 e = 8bits = exponent
63 f = 23bits = fraction
65 SINGLE precision fixed:
66 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
67 s = 1bit = sign
68 i = 31bits = integer
70 DOUBLE precision floating:
71 seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
72 s = 1bit = sign
73 e = 11bits = exponent
74 f = 52bits = fraction
76 DOUBLE precision fixed:
77 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
78 s = 1bit = sign
79 i = 63bits = integer
81 PAIRED SINGLE precision floating:
82 seeeeeeeefffffffffffffffffffffffseeeeeeeefffffffffffffffffffffff
83 | upper || lower |
84 s = 1bit = sign
85 e = 8bits = exponent
86 f = 23bits = fraction
87 Note: upper = [63..32], lower = [31..0]
90 /* Extract packed single values: */
91 #define FP_PS_upper(v) (((v) >> 32) & (unsigned)0xFFFFFFFF)
92 #define FP_PS_lower(v) ((v) & (unsigned)0xFFFFFFFF)
93 #define FP_PS_cat(u,l) (((uint64_t)((u) & (unsigned)0xFFFFFFFF) << 32) \
94 | (uint64_t)((l) & 0xFFFFFFFF))
96 /* Explicit QNaN values. */
97 #define FPQNaN_SINGLE (0x7FBFFFFF)
98 #define FPQNaN_WORD (0x7FFFFFFF)
99 #define FPQNaN_DOUBLE (UNSIGNED64 (0x7FF7FFFFFFFFFFFF))
100 #define FPQNaN_LONG (UNSIGNED64 (0x7FFFFFFFFFFFFFFF))
101 #define FPQNaN_PS (FP_PS_cat (FPQNaN_SINGLE, FPQNaN_SINGLE))
103 static void update_fcsr (sim_cpu *, address_word, sim_fpu_status);
105 static const char *fpu_format_name (FP_formats fmt);
106 #ifdef DEBUG
107 static const char *fpu_rounding_mode_name (int rm);
108 #endif
110 uword64
111 value_fpr (sim_cpu *cpu,
112 address_word cia,
113 int fpr,
114 FP_formats fmt)
116 uword64 value = 0;
117 int err = 0;
119 /* Treat unused register values, as fixed-point 64bit values. */
120 if (fmt == fmt_unknown)
122 #if 1
123 /* If request to read data as "unknown", then use the current
124 encoding: */
125 fmt = FPR_STATE[fpr];
126 #else
127 fmt = fmt_long;
128 #endif
131 /* For values not yet accessed, set to the desired format. */
132 if (fmt < fmt_uninterpreted && fmt != fmt_dc32)
134 if (FPR_STATE[fpr] == fmt_uninterpreted)
136 FPR_STATE[fpr] = fmt;
137 #ifdef DEBUG
138 printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
139 fpu_format_name (fmt));
140 #endif /* DEBUG */
142 else if (fmt != FPR_STATE[fpr]
143 && !(fmt == fmt_single
144 && FPR_STATE[fpr] == fmt_double
145 && (FGR[fpr] == 0 || FGR[fpr] == 0xFFFFFFFF)))
147 sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
148 fpr, fpu_format_name (FPR_STATE[fpr]),
149 fpu_format_name (fmt), pr_addr (cia));
150 FPR_STATE[fpr] = fmt_unknown;
154 if (FPR_STATE[fpr] == fmt_unknown)
156 /* Set QNaN value: */
157 switch (fmt)
159 case fmt_single: value = FPQNaN_SINGLE; break;
160 case fmt_double: value = FPQNaN_DOUBLE; break;
161 case fmt_word: value = FPQNaN_WORD; break;
162 case fmt_long: value = FPQNaN_LONG; break;
163 case fmt_ps: value = FPQNaN_PS; break;
164 default: err = -1; break;
167 else if (SizeFGR () == 64)
169 switch (fmt)
171 case fmt_uninterpreted_32:
172 case fmt_single:
173 case fmt_word:
174 case fmt_dc32:
175 value = (FGR[fpr] & 0xFFFFFFFF);
176 break;
178 case fmt_uninterpreted_64:
179 case fmt_uninterpreted:
180 case fmt_double:
181 case fmt_long:
182 case fmt_ps:
183 value = FGR[fpr];
184 break;
186 default:
187 err = -1;
188 break;
191 else
193 switch (fmt)
195 case fmt_uninterpreted_32:
196 case fmt_single:
197 case fmt_word:
198 value = (FGR[fpr] & 0xFFFFFFFF);
199 break;
201 case fmt_uninterpreted_64:
202 case fmt_uninterpreted:
203 case fmt_double:
204 case fmt_long:
205 if ((fpr & 1) == 0)
207 /* Even register numbers only. */
208 #ifdef DEBUG
209 printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
210 fpr + 1, pr_uword64 ((uword64) FGR[fpr+1]),
211 fpr, pr_uword64 ((uword64) FGR[fpr]));
212 #endif
213 value = ((((uword64) FGR[fpr+1]) << 32)
214 | (FGR[fpr] & 0xFFFFFFFF));
216 else
218 SignalException (ReservedInstruction, 0);
220 break;
222 case fmt_ps:
223 SignalException (ReservedInstruction, 0);
224 break;
226 default:
227 err = -1;
228 break;
232 if (err)
233 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
235 #ifdef DEBUG
236 printf ("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d\n",
237 fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
238 SizeFGR ());
239 #endif /* DEBUG */
241 return (value);
244 void
245 store_fpr (sim_cpu *cpu,
246 address_word cia,
247 int fpr,
248 FP_formats fmt,
249 uword64 value)
251 int err = 0;
253 #ifdef DEBUG
254 printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
255 fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
256 SizeFGR ());
257 #endif /* DEBUG */
259 if (SizeFGR () == 64)
261 switch (fmt)
263 case fmt_uninterpreted_32:
264 fmt = fmt_uninterpreted;
265 ATTRIBUTE_FALLTHROUGH;
266 case fmt_single:
267 case fmt_word:
268 if (STATE_VERBOSE_P (SD))
269 sim_io_eprintf (SD,
270 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
271 pr_addr (cia));
272 FGR[fpr] = (((uword64) 0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
273 FPR_STATE[fpr] = fmt;
274 break;
276 case fmt_uninterpreted_64:
277 fmt = fmt_uninterpreted;
278 ATTRIBUTE_FALLTHROUGH;
279 case fmt_uninterpreted:
280 case fmt_double:
281 case fmt_long:
282 case fmt_ps:
283 FGR[fpr] = value;
284 FPR_STATE[fpr] = fmt;
285 break;
287 default:
288 FPR_STATE[fpr] = fmt_unknown;
289 err = -1;
290 break;
293 else
295 switch (fmt)
297 case fmt_uninterpreted_32:
298 fmt = fmt_uninterpreted;
299 ATTRIBUTE_FALLTHROUGH;
300 case fmt_single:
301 case fmt_word:
302 FGR[fpr] = (value & 0xFFFFFFFF);
303 FPR_STATE[fpr] = fmt;
304 break;
306 case fmt_uninterpreted_64:
307 fmt = fmt_uninterpreted;
308 ATTRIBUTE_FALLTHROUGH;
309 case fmt_uninterpreted:
310 case fmt_double:
311 case fmt_long:
312 if ((fpr & 1) == 0)
314 /* Even register numbers only. */
315 FGR[fpr+1] = (value >> 32);
316 FGR[fpr] = (value & 0xFFFFFFFF);
317 FPR_STATE[fpr + 1] = fmt;
318 FPR_STATE[fpr] = fmt;
320 else
322 FPR_STATE[fpr] = fmt_unknown;
323 FPR_STATE[fpr ^ 1] = fmt_unknown;
324 SignalException (ReservedInstruction, 0);
326 break;
328 case fmt_ps:
329 FPR_STATE[fpr] = fmt_unknown;
330 SignalException (ReservedInstruction, 0);
331 break;
333 default:
334 FPR_STATE[fpr] = fmt_unknown;
335 err = -1;
336 break;
340 if (err)
341 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
343 #ifdef DEBUG
344 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
345 fpr, pr_uword64 (FGR[fpr]), fpu_format_name (fmt));
346 #endif /* DEBUG */
348 return;
352 /* CP1 control/status register access functions. */
354 void
355 test_fcsr (sim_cpu *cpu,
356 address_word cia)
358 unsigned int cause;
360 cause = (FCSR & fcsr_CAUSE_mask) >> fcsr_CAUSE_shift;
361 if ((cause & ((FCSR & fcsr_ENABLES_mask) >> fcsr_ENABLES_shift)) != 0
362 || (cause & (1 << UO)))
364 SignalExceptionFPE();
368 unsigned_word
369 value_fcr(sim_cpu *cpu,
370 address_word cia,
371 int fcr)
373 uint32_t value = 0;
375 switch (fcr)
377 case 0: /* FP Implementation and Revision Register. */
378 value = FCR0;
379 break;
380 case 25: /* FP Condition Codes Register (derived from FCSR). */
381 value = (FCR31 & fcsr_FCC_mask) >> fcsr_FCC_shift;
382 value = (value & 0x1) | (value >> 1); /* Close FCC gap. */
383 break;
384 case 26: /* FP Exceptions Register (derived from FCSR). */
385 value = FCR31 & (fcsr_CAUSE_mask | fcsr_FLAGS_mask);
386 break;
387 case 28: /* FP Enables Register (derived from FCSR). */
388 value = FCR31 & (fcsr_ENABLES_mask | fcsr_RM_mask);
389 if ((FCR31 & fcsr_FS) != 0)
390 value |= fenr_FS;
391 break;
392 case 31: /* FP Control/Status Register (FCSR). */
393 value = FCR31 & ~fcsr_ZERO_mask;
394 break;
397 return (EXTEND32 (value));
400 void
401 store_fcr(sim_cpu *cpu,
402 address_word cia,
403 int fcr,
404 unsigned_word value)
406 uint32_t v;
408 v = VL4_8(value);
409 switch (fcr)
411 case 25: /* FP Condition Codes Register (stored into FCSR). */
412 v = (v << 1) | (v & 0x1); /* Adjust for FCC gap. */
413 FCR31 &= ~fcsr_FCC_mask;
414 FCR31 |= ((v << fcsr_FCC_shift) & fcsr_FCC_mask);
415 break;
416 case 26: /* FP Exceptions Register (stored into FCSR). */
417 FCR31 &= ~(fcsr_CAUSE_mask | fcsr_FLAGS_mask);
418 FCR31 |= (v & (fcsr_CAUSE_mask | fcsr_FLAGS_mask));
419 test_fcsr(cpu, cia);
420 break;
421 case 28: /* FP Enables Register (stored into FCSR). */
422 if ((v & fenr_FS) != 0)
423 v |= fcsr_FS;
424 else
425 v &= ~fcsr_FS;
426 FCR31 &= (fcsr_FCC_mask | fcsr_CAUSE_mask | fcsr_FLAGS_mask);
427 FCR31 |= (v & (fcsr_FS | fcsr_ENABLES_mask | fcsr_RM_mask));
428 test_fcsr(cpu, cia);
429 break;
430 case 31: /* FP Control/Status Register (FCSR). */
431 FCR31 = v & ~fcsr_ZERO_mask;
432 test_fcsr(cpu, cia);
433 break;
437 static void
438 update_fcsr (sim_cpu *cpu,
439 address_word cia,
440 sim_fpu_status status)
442 FCSR &= ~fcsr_CAUSE_mask;
444 if (status != 0)
446 unsigned int cause = 0;
448 /* map between sim_fpu codes and MIPS FCSR */
449 if (status & (sim_fpu_status_invalid_snan
450 | sim_fpu_status_invalid_isi
451 | sim_fpu_status_invalid_idi
452 | sim_fpu_status_invalid_zdz
453 | sim_fpu_status_invalid_imz
454 | sim_fpu_status_invalid_cmp
455 | sim_fpu_status_invalid_sqrt
456 | sim_fpu_status_invalid_cvi))
457 cause |= (1 << IO);
458 if (status & sim_fpu_status_invalid_div0)
459 cause |= (1 << DZ);
460 if (status & sim_fpu_status_overflow)
461 cause |= (1 << OF);
462 if (status & sim_fpu_status_underflow)
463 cause |= (1 << UF);
464 if (status & sim_fpu_status_inexact)
465 cause |= (1 << IR);
466 #if 0 /* Not yet. */
467 /* Implicit clearing of other bits by unimplemented done by callers. */
468 if (status & sim_fpu_status_unimplemented)
469 cause |= (1 << UO);
470 #endif
472 FCSR |= (cause << fcsr_CAUSE_shift);
473 test_fcsr (cpu, cia);
474 FCSR |= ((cause & ~(1 << UO)) << fcsr_FLAGS_shift);
476 return;
479 static sim_fpu_round
480 rounding_mode(int rm)
482 sim_fpu_round round;
484 switch (rm)
486 case FP_RM_NEAREST:
487 /* Round result to nearest representable value. When two
488 representable values are equally near, round to the value
489 that has a least significant bit of zero (i.e. is even). */
490 round = sim_fpu_round_near;
491 break;
492 case FP_RM_TOZERO:
493 /* Round result to the value closest to, and not greater in
494 magnitude than, the result. */
495 round = sim_fpu_round_zero;
496 break;
497 case FP_RM_TOPINF:
498 /* Round result to the value closest to, and not less than,
499 the result. */
500 round = sim_fpu_round_up;
501 break;
502 case FP_RM_TOMINF:
503 /* Round result to the value closest to, and not greater than,
504 the result. */
505 round = sim_fpu_round_down;
506 break;
507 default:
508 round = 0;
509 fprintf (stderr, "Bad switch\n");
510 abort ();
512 return round;
515 /* When the FS bit is set, MIPS processors return zero for
516 denormalized results and optionally replace denormalized inputs
517 with zero. When FS is clear, some implementation trap on input
518 and/or output, while other perform the operation in hardware. */
519 static sim_fpu_denorm
520 denorm_mode(sim_cpu *cpu)
522 sim_fpu_denorm denorm;
524 /* XXX: FIXME: Eventually should be CPU model dependent. */
525 if (GETFS())
526 denorm = sim_fpu_denorm_zero;
527 else
528 denorm = 0;
529 return denorm;
533 /* Comparison operations. */
535 static sim_fpu_status
536 fp_test(uint64_t op1,
537 uint64_t op2,
538 FP_formats fmt,
539 int abs,
540 int cond,
541 int *condition)
543 sim_fpu wop1;
544 sim_fpu wop2;
545 sim_fpu_status status = 0;
546 int less, equal, unordered;
548 /* The format type has already been checked: */
549 switch (fmt)
551 case fmt_single:
553 sim_fpu_32to (&wop1, op1);
554 sim_fpu_32to (&wop2, op2);
555 break;
557 case fmt_double:
559 sim_fpu_64to (&wop1, op1);
560 sim_fpu_64to (&wop2, op2);
561 break;
563 default:
564 fprintf (stderr, "Bad switch\n");
565 abort ();
568 if (sim_fpu_is_nan (&wop1) || sim_fpu_is_nan (&wop2))
570 if ((cond & (1 << 3))
571 || sim_fpu_is_snan (&wop1) || sim_fpu_is_snan (&wop2))
572 status = sim_fpu_status_invalid_snan;
573 less = 0;
574 equal = 0;
575 unordered = 1;
577 else
579 if (abs)
581 status |= sim_fpu_abs (&wop1, &wop1);
582 status |= sim_fpu_abs (&wop2, &wop2);
584 equal = sim_fpu_is_eq (&wop1, &wop2);
585 less = !equal && sim_fpu_is_lt (&wop1, &wop2);
586 unordered = 0;
588 *condition = (((cond & (1 << 2)) && less)
589 || ((cond & (1 << 1)) && equal)
590 || ((cond & (1 << 0)) && unordered));
591 return status;
594 static const int sim_fpu_class_mips_mapping[] = {
595 FP_R6CLASS_SNAN, /* SIM_FPU_IS_SNAN = 1, Noisy not-a-number */
596 FP_R6CLASS_QNAN, /* SIM_FPU_IS_QNAN = 2, Quiet not-a-number */
597 FP_R6CLASS_NEGINF, /* SIM_FPU_IS_NINF = 3, -infinity */
598 FP_R6CLASS_POSINF, /* SIM_FPU_IS_PINF = 4, +infinity */
599 FP_R6CLASS_NEGNORM, /* SIM_FPU_IS_NNUMBER = 5, -num - [-MAX .. -MIN] */
600 FP_R6CLASS_POSNORM, /* SIM_FPU_IS_PNUMBER = 6, +num - [+MIN .. +MAX] */
601 FP_R6CLASS_NEGSUB, /* SIM_FPU_IS_NDENORM = 7, -denorm - (MIN .. 0) */
602 FP_R6CLASS_POSSUB, /* SIM_FPU_IS_PDENORM = 8, +denorm - (0 .. MIN) */
603 FP_R6CLASS_NEGZERO, /* SIM_FPU_IS_NZERO = 9, -0 */
604 FP_R6CLASS_POSZERO /* SIM_FPU_IS_PZERO = 10, +0 */
607 uint64_t
608 fp_classify (sim_cpu *cpu,
609 address_word cia,
610 uint64_t op,
611 FP_formats fmt)
613 sim_fpu wop;
615 switch (fmt)
617 case fmt_single:
618 sim_fpu_32to (&wop, op);
619 break;
620 case fmt_double:
621 sim_fpu_64to (&wop, op);
622 break;
623 default:
624 sim_io_error (SD, "Bad switch\n");
626 return sim_fpu_class_mips_mapping[sim_fpu_classify (&wop) - 1];
630 fp_rint (sim_cpu *cpu,
631 address_word cia,
632 uint64_t op,
633 uint64_t *ans,
634 FP_formats fmt)
636 sim_fpu wop = {0}, wtemp = {0}, wmagic = {0}, wans = {0};
637 int status = 0;
638 sim_fpu_round round = rounding_mode (GETRM());
640 switch (fmt)
642 case fmt_single:
643 sim_fpu_32to (&wop, op);
644 sim_fpu_32to (&wmagic, 0x4b000000);
645 break;
646 case fmt_double:
647 sim_fpu_64to (&wop, op);
648 sim_fpu_64to (&wmagic, 0x4330000000000000);
649 break;
650 default:
651 sim_io_error (SD, "Bad switch\n");
654 if (sim_fpu_is_nan (&wop) || sim_fpu_is_infinity (&wop))
656 status = sim_fpu_status_invalid_cvi;
657 update_fcsr (cpu, cia, status);
658 return status;
661 switch (fmt)
663 case fmt_single:
664 if (sim_fpu_is_ge (&wop, &wmagic))
665 wans = wop;
666 else
668 sim_fpu_add (&wtemp, &wop, &wmagic);
669 sim_fpu_round_32 (&wtemp, round, sim_fpu_denorm_default);
670 sim_fpu_sub (&wans, &wtemp, &wmagic);
672 sim_fpu_to32 ((uint32_t *) ans, &wans);
673 break;
674 case fmt_double:
675 if (sim_fpu_is_ge (&wop, &wmagic))
676 wans = wop;
677 else
679 sim_fpu_add (&wtemp, &wop, &wmagic);
680 sim_fpu_round_64 (&wtemp, round, sim_fpu_denorm_default);
681 sim_fpu_sub (&wans, &wtemp, &wmagic);
683 sim_fpu_to64 (ans, &wans);
684 break;
685 default:
686 sim_io_error (SD, "Bad switch\n");
689 if (*ans != op && status == 0)
690 status = sim_fpu_status_inexact;
692 update_fcsr (cpu, cia, status);
693 return status;
696 void
697 fp_cmp(sim_cpu *cpu,
698 address_word cia,
699 uint64_t op1,
700 uint64_t op2,
701 FP_formats fmt,
702 int abs,
703 int cond,
704 int cc)
706 sim_fpu_status status = 0;
708 /* The format type should already have been checked. The FCSR is
709 updated before the condition codes so that any exceptions will
710 be signalled before the condition codes are changed. */
711 switch (fmt)
713 case fmt_single:
714 case fmt_double:
716 int result;
717 status = fp_test(op1, op2, fmt, abs, cond, &result);
718 update_fcsr (cpu, cia, status);
719 SETFCC (cc, result);
720 break;
722 case fmt_ps:
724 int result0, result1;
725 status = fp_test(FP_PS_lower (op1), FP_PS_lower (op2), fmt_single,
726 abs, cond, &result0);
727 status |= fp_test(FP_PS_upper (op1), FP_PS_upper (op2), fmt_single,
728 abs, cond, &result1);
729 update_fcsr (cpu, cia, status);
730 SETFCC (cc, result0);
731 SETFCC (cc+1, result1);
732 break;
734 default:
735 sim_io_error (SD, "Bad switch\n");
739 uint64_t
740 fp_r6_cmp (sim_cpu *cpu,
741 address_word cia,
742 uint64_t op1,
743 uint64_t op2,
744 FP_formats fmt,
745 int cond)
747 sim_fpu wop1, wop2;
748 int result = 0;
750 switch (fmt)
752 case fmt_single:
753 sim_fpu_32to (&wop1, op1);
754 sim_fpu_32to (&wop2, op2);
755 break;
756 case fmt_double:
757 sim_fpu_64to (&wop1, op1);
758 sim_fpu_64to (&wop2, op2);
759 break;
760 default:
761 sim_io_error (SD, "Bad switch\n");
764 switch (cond)
766 case FP_R6CMP_AF:
767 result = 0;
768 break;
769 case FP_R6CMP_UN:
770 result = sim_fpu_is_un (&wop1, &wop2);
771 break;
772 case FP_R6CMP_OR:
773 result = sim_fpu_is_or (&wop1, &wop2);
774 break;
775 case FP_R6CMP_EQ:
776 result = sim_fpu_is_eq (&wop1, &wop2);
777 break;
778 case FP_R6CMP_NE:
779 result = sim_fpu_is_ne (&wop1, &wop2);
780 break;
781 case FP_R6CMP_LT:
782 result = sim_fpu_is_lt (&wop1, &wop2);
783 break;
784 case FP_R6CMP_LE:
785 result = sim_fpu_is_le (&wop1, &wop2);
786 break;
787 case FP_R6CMP_UEQ:
788 result = sim_fpu_is_un (&wop1, &wop2) || sim_fpu_is_eq (&wop1, &wop2);
789 break;
790 case FP_R6CMP_UNE:
791 result = sim_fpu_is_un (&wop1, &wop2) || sim_fpu_is_ne (&wop1, &wop2);
792 break;
793 case FP_R6CMP_ULT:
794 result = sim_fpu_is_un (&wop1, &wop2) || sim_fpu_is_lt (&wop1, &wop2);
795 break;
796 case FP_R6CMP_ULE:
797 result = sim_fpu_is_un (&wop1, &wop2) || sim_fpu_is_le (&wop1, &wop2);
798 break;
799 default:
800 update_fcsr (cpu, cia, sim_fpu_status_invalid_cmp);
801 break;
804 if (result)
806 switch (fmt)
808 case fmt_single:
809 return 0xFFFFFFFF;
810 case fmt_double:
811 return 0xFFFFFFFFFFFFFFFF;
812 default:
813 sim_io_error (SD, "Bad switch\n");
816 else
817 return 0;
820 /* Basic arithmetic operations. */
822 static uint64_t
823 fp_unary(sim_cpu *cpu,
824 address_word cia,
825 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *),
826 uint64_t op,
827 FP_formats fmt)
829 sim_fpu wop = {0};
830 sim_fpu ans;
831 sim_fpu_round round = rounding_mode (GETRM());
832 sim_fpu_denorm denorm = denorm_mode (cpu);
833 sim_fpu_status status = 0;
834 uint64_t result = 0;
836 /* The format type has already been checked: */
837 switch (fmt)
839 case fmt_single:
841 uint32_t res;
842 sim_fpu_32to (&wop, op);
843 status |= (*sim_fpu_op) (&ans, &wop);
844 status |= sim_fpu_round_32 (&ans, round, denorm);
845 sim_fpu_to32 (&res, &ans);
846 result = res;
847 break;
849 case fmt_double:
851 uint64_t res;
852 sim_fpu_64to (&wop, op);
853 status |= (*sim_fpu_op) (&ans, &wop);
854 status |= sim_fpu_round_64 (&ans, round, denorm);
855 sim_fpu_to64 (&res, &ans);
856 result = res;
857 break;
859 case fmt_ps:
861 int status_u = 0, status_l = 0;
862 uint32_t res_u, res_l;
863 sim_fpu_32to (&wop, FP_PS_upper(op));
864 status_u |= (*sim_fpu_op) (&ans, &wop);
865 sim_fpu_to32 (&res_u, &ans);
866 sim_fpu_32to (&wop, FP_PS_lower(op));
867 status_l |= (*sim_fpu_op) (&ans, &wop);
868 sim_fpu_to32 (&res_l, &ans);
869 result = FP_PS_cat(res_u, res_l);
870 status = status_u | status_l;
871 break;
873 default:
874 sim_io_error (SD, "Bad switch\n");
877 update_fcsr (cpu, cia, status);
878 return result;
881 static uint64_t
882 fp_binary(sim_cpu *cpu,
883 address_word cia,
884 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
885 uint64_t op1,
886 uint64_t op2,
887 FP_formats fmt)
889 sim_fpu wop1 = {0};
890 sim_fpu wop2 = {0};
891 sim_fpu ans = {0};
892 sim_fpu_round round = rounding_mode (GETRM());
893 sim_fpu_denorm denorm = denorm_mode (cpu);
894 sim_fpu_status status = 0;
895 uint64_t result = 0;
897 /* The format type has already been checked: */
898 switch (fmt)
900 case fmt_single:
902 uint32_t res;
903 sim_fpu_32to (&wop1, op1);
904 sim_fpu_32to (&wop2, op2);
905 status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
906 status |= sim_fpu_round_32 (&ans, round, denorm);
907 sim_fpu_to32 (&res, &ans);
908 result = res;
909 break;
911 case fmt_double:
913 uint64_t res;
914 sim_fpu_64to (&wop1, op1);
915 sim_fpu_64to (&wop2, op2);
916 status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
917 status |= sim_fpu_round_64 (&ans, round, denorm);
918 sim_fpu_to64 (&res, &ans);
919 result = res;
920 break;
922 case fmt_ps:
924 int status_u = 0, status_l = 0;
925 uint32_t res_u, res_l;
926 sim_fpu_32to (&wop1, FP_PS_upper(op1));
927 sim_fpu_32to (&wop2, FP_PS_upper(op2));
928 status_u |= (*sim_fpu_op) (&ans, &wop1, &wop2);
929 sim_fpu_to32 (&res_u, &ans);
930 sim_fpu_32to (&wop1, FP_PS_lower(op1));
931 sim_fpu_32to (&wop2, FP_PS_lower(op2));
932 status_l |= (*sim_fpu_op) (&ans, &wop1, &wop2);
933 sim_fpu_to32 (&res_l, &ans);
934 result = FP_PS_cat(res_u, res_l);
935 status = status_u | status_l;
936 break;
938 default:
939 sim_io_error (SD, "Bad switch\n");
942 update_fcsr (cpu, cia, status);
943 return result;
946 /* Common MAC code for single operands (.s or .d), defers setting FCSR. */
947 static sim_fpu_status
948 inner_mac(int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
949 uint64_t op1,
950 uint64_t op2,
951 uint64_t op3,
952 int scale,
953 int negate,
954 FP_formats fmt,
955 sim_fpu_round round,
956 sim_fpu_denorm denorm,
957 uint64_t *result)
959 sim_fpu wop1;
960 sim_fpu wop2;
961 sim_fpu ans;
962 sim_fpu_status status = 0;
963 sim_fpu_status op_status;
964 uint64_t temp = 0;
966 switch (fmt)
968 case fmt_single:
970 uint32_t res;
971 sim_fpu_32to (&wop1, op1);
972 sim_fpu_32to (&wop2, op2);
973 status |= sim_fpu_mul (&ans, &wop1, &wop2);
974 if (scale != 0 && sim_fpu_is_number (&ans)) /* number or denorm */
975 ans.normal_exp += scale;
976 status |= sim_fpu_round_32 (&ans, round, denorm);
977 wop1 = ans;
978 op_status = 0;
979 sim_fpu_32to (&wop2, op3);
980 op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
981 op_status |= sim_fpu_round_32 (&ans, round, denorm);
982 status |= op_status;
983 if (negate)
985 wop1 = ans;
986 op_status = sim_fpu_neg (&ans, &wop1);
987 op_status |= sim_fpu_round_32 (&ans, round, denorm);
988 status |= op_status;
990 sim_fpu_to32 (&res, &ans);
991 temp = res;
992 break;
994 case fmt_double:
996 uint64_t res;
997 sim_fpu_64to (&wop1, op1);
998 sim_fpu_64to (&wop2, op2);
999 status |= sim_fpu_mul (&ans, &wop1, &wop2);
1000 if (scale != 0 && sim_fpu_is_number (&ans)) /* number or denorm */
1001 ans.normal_exp += scale;
1002 status |= sim_fpu_round_64 (&ans, round, denorm);
1003 wop1 = ans;
1004 op_status = 0;
1005 sim_fpu_64to (&wop2, op3);
1006 op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
1007 op_status |= sim_fpu_round_64 (&ans, round, denorm);
1008 status |= op_status;
1009 if (negate)
1011 wop1 = ans;
1012 op_status = sim_fpu_neg (&ans, &wop1);
1013 op_status |= sim_fpu_round_64 (&ans, round, denorm);
1014 status |= op_status;
1016 sim_fpu_to64 (&res, &ans);
1017 temp = res;
1018 break;
1020 default:
1021 fprintf (stderr, "Bad switch\n");
1022 abort ();
1024 *result = temp;
1025 return status;
1028 /* Common implementation of madd, nmadd, msub, nmsub that does
1029 intermediate rounding per spec. Also used for recip2 and rsqrt2,
1030 which are transformed into equivalent nmsub operations. The scale
1031 argument is an adjustment to the exponent of the intermediate
1032 product op1*op2. It is currently non-zero for rsqrt2 (-1), which
1033 requires an effective division by 2. */
1034 static uint64_t
1035 fp_mac(sim_cpu *cpu,
1036 address_word cia,
1037 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
1038 uint64_t op1,
1039 uint64_t op2,
1040 uint64_t op3,
1041 int scale,
1042 int negate,
1043 FP_formats fmt)
1045 sim_fpu_round round = rounding_mode (GETRM());
1046 sim_fpu_denorm denorm = denorm_mode (cpu);
1047 sim_fpu_status status = 0;
1048 uint64_t result = 0;
1050 /* The format type has already been checked: */
1051 switch (fmt)
1053 case fmt_single:
1054 case fmt_double:
1055 status = inner_mac(sim_fpu_op, op1, op2, op3, scale,
1056 negate, fmt, round, denorm, &result);
1057 break;
1058 case fmt_ps:
1060 int status_u, status_l;
1061 uint64_t result_u, result_l;
1062 status_u = inner_mac(sim_fpu_op, FP_PS_upper(op1), FP_PS_upper(op2),
1063 FP_PS_upper(op3), scale, negate, fmt_single,
1064 round, denorm, &result_u);
1065 status_l = inner_mac(sim_fpu_op, FP_PS_lower(op1), FP_PS_lower(op2),
1066 FP_PS_lower(op3), scale, negate, fmt_single,
1067 round, denorm, &result_l);
1068 result = FP_PS_cat(result_u, result_l);
1069 status = status_u | status_l;
1070 break;
1072 default:
1073 sim_io_error (SD, "Bad switch\n");
1076 update_fcsr (cpu, cia, status);
1077 return result;
1080 /* Common FMAC code for .s, .d. Defers setting FCSR to caller. */
1081 static sim_fpu_status
1082 inner_fmac (sim_cpu *cpu,
1083 int (*sim_fpu_op) (sim_fpu *, const sim_fpu *, const sim_fpu *),
1084 uint64_t op1,
1085 uint64_t op2,
1086 uint64_t op3,
1087 sim_fpu_round round,
1088 sim_fpu_denorm denorm,
1089 FP_formats fmt,
1090 uint64_t *result)
1092 sim_fpu wop1, wop2, ans;
1093 sim_fpu_status status = 0;
1094 sim_fpu_status op_status;
1095 uint32_t t32 = 0;
1096 uint64_t t64 = 0;
1098 switch (fmt)
1100 case fmt_single:
1101 sim_fpu_32to (&wop1, op1);
1102 sim_fpu_32to (&wop2, op2);
1103 status |= sim_fpu_mul (&ans, &wop1, &wop2);
1104 wop1 = ans;
1105 op_status = 0;
1106 sim_fpu_32to (&wop2, op3);
1107 op_status |= (*sim_fpu_op) (&ans, &wop2, &wop1);
1108 op_status |= sim_fpu_round_32 (&ans, round, denorm);
1109 status |= op_status;
1110 sim_fpu_to32 (&t32, &ans);
1111 t64 = t32;
1112 break;
1113 case fmt_double:
1114 sim_fpu_64to (&wop1, op1);
1115 sim_fpu_64to (&wop2, op2);
1116 status |= sim_fpu_mul (&ans, &wop1, &wop2);
1117 wop1 = ans;
1118 op_status = 0;
1119 sim_fpu_64to (&wop2, op3);
1120 op_status |= (*sim_fpu_op) (&ans, &wop2, &wop1);
1121 op_status |= sim_fpu_round_64 (&ans, round, denorm);
1122 status |= op_status;
1123 sim_fpu_to64 (&t64, &ans);
1124 break;
1125 default:
1126 sim_io_error (SD, "Bad switch\n");
1129 *result = t64;
1130 return status;
1133 static uint64_t
1134 fp_fmac (sim_cpu *cpu,
1135 address_word cia,
1136 int (*sim_fpu_op) (sim_fpu *, const sim_fpu *, const sim_fpu *),
1137 uint64_t op1,
1138 uint64_t op2,
1139 uint64_t op3,
1140 FP_formats fmt)
1142 sim_fpu_round round = rounding_mode (GETRM());
1143 sim_fpu_denorm denorm = denorm_mode (cpu);
1144 sim_fpu_status status = 0;
1145 uint64_t result = 0;
1147 switch (fmt)
1149 case fmt_single:
1150 case fmt_double:
1151 status = inner_fmac (cpu, sim_fpu_op, op1, op2, op3,
1152 round, denorm, fmt, &result);
1153 break;
1154 default:
1155 sim_io_error (SD, "Bad switch\n");
1158 update_fcsr (cpu, cia, status);
1159 return result;
1162 /* Common rsqrt code for single operands (.s or .d), intermediate rounding. */
1163 static sim_fpu_status
1164 inner_rsqrt(uint64_t op1,
1165 FP_formats fmt,
1166 sim_fpu_round round,
1167 sim_fpu_denorm denorm,
1168 uint64_t *result)
1170 sim_fpu wop1;
1171 sim_fpu ans;
1172 sim_fpu_status status = 0;
1173 sim_fpu_status op_status;
1174 uint64_t temp = 0;
1176 switch (fmt)
1178 case fmt_single:
1180 uint32_t res;
1181 sim_fpu_32to (&wop1, op1);
1182 status |= sim_fpu_sqrt (&ans, &wop1);
1183 status |= sim_fpu_round_32 (&ans, round, denorm);
1184 wop1 = ans;
1185 op_status = sim_fpu_inv (&ans, &wop1);
1186 op_status |= sim_fpu_round_32 (&ans, round, denorm);
1187 sim_fpu_to32 (&res, &ans);
1188 temp = res;
1189 status |= op_status;
1190 break;
1192 case fmt_double:
1194 uint64_t res;
1195 sim_fpu_64to (&wop1, op1);
1196 status |= sim_fpu_sqrt (&ans, &wop1);
1197 status |= sim_fpu_round_64 (&ans, round, denorm);
1198 wop1 = ans;
1199 op_status = sim_fpu_inv (&ans, &wop1);
1200 op_status |= sim_fpu_round_64 (&ans, round, denorm);
1201 sim_fpu_to64 (&res, &ans);
1202 temp = res;
1203 status |= op_status;
1204 break;
1206 default:
1207 fprintf (stderr, "Bad switch\n");
1208 abort ();
1210 *result = temp;
1211 return status;
1214 static uint64_t
1215 fp_inv_sqrt(sim_cpu *cpu,
1216 address_word cia,
1217 uint64_t op1,
1218 FP_formats fmt)
1220 sim_fpu_round round = rounding_mode (GETRM());
1221 sim_fpu_denorm denorm = denorm_mode (cpu);
1222 sim_fpu_status status = 0;
1223 uint64_t result = 0;
1225 /* The format type has already been checked: */
1226 switch (fmt)
1228 case fmt_single:
1229 case fmt_double:
1230 status = inner_rsqrt (op1, fmt, round, denorm, &result);
1231 break;
1232 case fmt_ps:
1234 int status_u, status_l;
1235 uint64_t result_u, result_l;
1236 status_u = inner_rsqrt (FP_PS_upper(op1), fmt_single, round, denorm,
1237 &result_u);
1238 status_l = inner_rsqrt (FP_PS_lower(op1), fmt_single, round, denorm,
1239 &result_l);
1240 result = FP_PS_cat(result_u, result_l);
1241 status = status_u | status_l;
1242 break;
1244 default:
1245 sim_io_error (SD, "Bad switch\n");
1248 update_fcsr (cpu, cia, status);
1249 return result;
1253 uint64_t
1254 fp_abs(sim_cpu *cpu,
1255 address_word cia,
1256 uint64_t op,
1257 FP_formats fmt)
1259 return fp_unary(cpu, cia, &sim_fpu_abs, op, fmt);
1262 uint64_t
1263 fp_neg(sim_cpu *cpu,
1264 address_word cia,
1265 uint64_t op,
1266 FP_formats fmt)
1268 return fp_unary(cpu, cia, &sim_fpu_neg, op, fmt);
1271 uint64_t
1272 fp_add(sim_cpu *cpu,
1273 address_word cia,
1274 uint64_t op1,
1275 uint64_t op2,
1276 FP_formats fmt)
1278 return fp_binary(cpu, cia, &sim_fpu_add, op1, op2, fmt);
1281 uint64_t
1282 fp_sub(sim_cpu *cpu,
1283 address_word cia,
1284 uint64_t op1,
1285 uint64_t op2,
1286 FP_formats fmt)
1288 return fp_binary(cpu, cia, &sim_fpu_sub, op1, op2, fmt);
1291 uint64_t
1292 fp_mul(sim_cpu *cpu,
1293 address_word cia,
1294 uint64_t op1,
1295 uint64_t op2,
1296 FP_formats fmt)
1298 return fp_binary(cpu, cia, &sim_fpu_mul, op1, op2, fmt);
1301 uint64_t
1302 fp_div(sim_cpu *cpu,
1303 address_word cia,
1304 uint64_t op1,
1305 uint64_t op2,
1306 FP_formats fmt)
1308 return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt);
1311 uint64_t
1312 fp_min (sim_cpu *cpu,
1313 address_word cia,
1314 uint64_t op1,
1315 uint64_t op2,
1316 FP_formats fmt)
1318 return fp_binary (cpu, cia, &sim_fpu_min, op1, op2, fmt);
1321 uint64_t
1322 fp_max (sim_cpu *cpu,
1323 address_word cia,
1324 uint64_t op1,
1325 uint64_t op2,
1326 FP_formats fmt)
1328 return fp_binary (cpu, cia, &sim_fpu_max, op1, op2, fmt);
1331 uint64_t
1332 fp_mina (sim_cpu *cpu,
1333 address_word cia,
1334 uint64_t op1,
1335 uint64_t op2,
1336 FP_formats fmt)
1338 uint64_t ret;
1339 sim_fpu wop1 = {0}, wop2 = {0}, waop1, waop2, wans;
1340 sim_fpu_status status = 0;
1342 switch (fmt)
1344 case fmt_single:
1345 sim_fpu_32to (&wop1, op1);
1346 sim_fpu_32to (&wop2, op2);
1347 break;
1348 case fmt_double:
1349 sim_fpu_64to (&wop1, op1);
1350 sim_fpu_64to (&wop2, op2);
1351 break;
1352 default:
1353 sim_io_error (SD, "Bad switch\n");
1356 status |= sim_fpu_abs (&waop1, &wop1);
1357 status |= sim_fpu_abs (&waop2, &wop2);
1358 status |= sim_fpu_min (&wans, &waop1, &waop2);
1359 ret = (sim_fpu_is_eq (&wans, &waop1)) ? op1 : op2;
1361 update_fcsr (cpu, cia, status);
1362 return ret;
1365 uint64_t
1366 fp_maxa (sim_cpu *cpu,
1367 address_word cia,
1368 uint64_t op1,
1369 uint64_t op2,
1370 FP_formats fmt)
1372 uint64_t ret;
1373 sim_fpu wop1 = {0}, wop2 = {0}, waop1, waop2, wans;
1374 sim_fpu_status status = 0;
1376 switch (fmt)
1378 case fmt_single:
1379 sim_fpu_32to (&wop1, op1);
1380 sim_fpu_32to (&wop2, op2);
1381 break;
1382 case fmt_double:
1383 sim_fpu_64to (&wop1, op1);
1384 sim_fpu_64to (&wop2, op2);
1385 break;
1386 default:
1387 sim_io_error (SD, "Bad switch\n");
1390 status |= sim_fpu_abs (&waop1, &wop1);
1391 status |= sim_fpu_abs (&waop2, &wop2);
1392 status |= sim_fpu_max (&wans, &waop1, &waop2);
1393 ret = (sim_fpu_is_eq (&wans, &waop1)) ? op1 : op2;
1395 update_fcsr (cpu, cia, status);
1396 return ret;
1399 uint64_t
1400 fp_recip(sim_cpu *cpu,
1401 address_word cia,
1402 uint64_t op,
1403 FP_formats fmt)
1405 return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt);
1408 uint64_t
1409 fp_sqrt(sim_cpu *cpu,
1410 address_word cia,
1411 uint64_t op,
1412 FP_formats fmt)
1414 return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
1417 uint64_t
1418 fp_rsqrt(sim_cpu *cpu,
1419 address_word cia,
1420 uint64_t op,
1421 FP_formats fmt)
1423 return fp_inv_sqrt(cpu, cia, op, fmt);
1426 uint64_t
1427 fp_madd(sim_cpu *cpu,
1428 address_word cia,
1429 uint64_t op1,
1430 uint64_t op2,
1431 uint64_t op3,
1432 FP_formats fmt)
1434 return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 0, fmt);
1437 uint64_t
1438 fp_msub(sim_cpu *cpu,
1439 address_word cia,
1440 uint64_t op1,
1441 uint64_t op2,
1442 uint64_t op3,
1443 FP_formats fmt)
1445 return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 0, fmt);
1448 uint64_t
1449 fp_fmadd (sim_cpu *cpu,
1450 address_word cia,
1451 uint64_t op1,
1452 uint64_t op2,
1453 uint64_t op3,
1454 FP_formats fmt)
1456 return fp_fmac (cpu, cia, &sim_fpu_add, op1, op2, op3, fmt);
1459 uint64_t
1460 fp_fmsub (sim_cpu *cpu,
1461 address_word cia,
1462 uint64_t op1,
1463 uint64_t op2,
1464 uint64_t op3,
1465 FP_formats fmt)
1467 return fp_fmac (cpu, cia, &sim_fpu_sub, op1, op2, op3, fmt);
1470 uint64_t
1471 fp_nmadd(sim_cpu *cpu,
1472 address_word cia,
1473 uint64_t op1,
1474 uint64_t op2,
1475 uint64_t op3,
1476 FP_formats fmt)
1478 return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 1, fmt);
1481 uint64_t
1482 fp_nmsub(sim_cpu *cpu,
1483 address_word cia,
1484 uint64_t op1,
1485 uint64_t op2,
1486 uint64_t op3,
1487 FP_formats fmt)
1489 return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 1, fmt);
1493 /* MIPS-3D ASE operations. */
1495 /* Variant of fp_binary for *r.ps MIPS-3D operations. */
1496 static uint64_t
1497 fp_binary_r(sim_cpu *cpu,
1498 address_word cia,
1499 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
1500 uint64_t op1,
1501 uint64_t op2)
1503 sim_fpu wop1;
1504 sim_fpu wop2;
1505 sim_fpu ans;
1506 sim_fpu_round round = rounding_mode (GETRM ());
1507 sim_fpu_denorm denorm = denorm_mode (cpu);
1508 sim_fpu_status status_u, status_l;
1509 uint64_t result;
1510 uint32_t res_u, res_l;
1512 /* The format must be fmt_ps. */
1513 status_u = 0;
1514 sim_fpu_32to (&wop1, FP_PS_upper (op1));
1515 sim_fpu_32to (&wop2, FP_PS_lower (op1));
1516 status_u |= (*sim_fpu_op) (&ans, &wop1, &wop2);
1517 status_u |= sim_fpu_round_32 (&ans, round, denorm);
1518 sim_fpu_to32 (&res_u, &ans);
1519 status_l = 0;
1520 sim_fpu_32to (&wop1, FP_PS_upper (op2));
1521 sim_fpu_32to (&wop2, FP_PS_lower (op2));
1522 status_l |= (*sim_fpu_op) (&ans, &wop1, &wop2);
1523 status_l |= sim_fpu_round_32 (&ans, round, denorm);
1524 sim_fpu_to32 (&res_l, &ans);
1525 result = FP_PS_cat (res_u, res_l);
1527 update_fcsr (cpu, cia, status_u | status_l);
1528 return result;
1531 uint64_t
1532 fp_add_r(sim_cpu *cpu,
1533 address_word cia,
1534 uint64_t op1,
1535 uint64_t op2,
1536 FP_formats fmt)
1538 return fp_binary_r (cpu, cia, &sim_fpu_add, op1, op2);
1541 uint64_t
1542 fp_mul_r(sim_cpu *cpu,
1543 address_word cia,
1544 uint64_t op1,
1545 uint64_t op2,
1546 FP_formats fmt)
1548 return fp_binary_r (cpu, cia, &sim_fpu_mul, op1, op2);
1551 #define NR_FRAC_GUARD (60)
1552 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
1554 static int
1555 fpu_inv1(sim_fpu *f, const sim_fpu *l)
1557 static const sim_fpu sim_fpu_one = {
1558 sim_fpu_class_number, 0, IMPLICIT_1, 0
1560 int status = 0;
1562 if (sim_fpu_is_zero (l))
1564 *f = sim_fpu_maxfp;
1565 f->sign = l->sign;
1566 return sim_fpu_status_invalid_div0;
1568 if (sim_fpu_is_infinity (l))
1570 *f = sim_fpu_zero;
1571 f->sign = l->sign;
1572 return status;
1574 status |= sim_fpu_div (f, &sim_fpu_one, l);
1575 return status;
1578 static int
1579 fpu_inv1_32(sim_fpu *f, const sim_fpu *l)
1581 if (sim_fpu_is_zero (l))
1583 *f = sim_fpu_max32;
1584 f->sign = l->sign;
1585 return sim_fpu_status_invalid_div0;
1587 return fpu_inv1 (f, l);
1590 static int
1591 fpu_inv1_64(sim_fpu *f, const sim_fpu *l)
1593 if (sim_fpu_is_zero (l))
1595 *f = sim_fpu_max64;
1596 f->sign = l->sign;
1597 return sim_fpu_status_invalid_div0;
1599 return fpu_inv1 (f, l);
1602 uint64_t
1603 fp_recip1(sim_cpu *cpu,
1604 address_word cia,
1605 uint64_t op,
1606 FP_formats fmt)
1608 switch (fmt)
1610 case fmt_single:
1611 case fmt_ps:
1612 return fp_unary (cpu, cia, &fpu_inv1_32, op, fmt);
1613 case fmt_double:
1614 return fp_unary (cpu, cia, &fpu_inv1_64, op, fmt);
1616 return 0;
1619 uint64_t
1620 fp_recip2(sim_cpu *cpu,
1621 address_word cia,
1622 uint64_t op1,
1623 uint64_t op2,
1624 FP_formats fmt)
1626 static const uint64_t one_single = UNSIGNED64 (0x3F800000);
1627 static const uint64_t one_double = UNSIGNED64 (0x3FF0000000000000);
1628 static const uint64_t one_ps = (UNSIGNED64 (0x3F800000) << 32 | UNSIGNED64 (0x3F800000));
1629 uint64_t one;
1631 /* Implemented as nmsub fd, 1, fs, ft. */
1632 switch (fmt)
1634 case fmt_single: one = one_single; break;
1635 case fmt_double: one = one_double; break;
1636 case fmt_ps: one = one_ps; break;
1637 default: one = 0; abort ();
1639 return fp_mac (cpu, cia, &sim_fpu_sub, op1, op2, one, 0, 1, fmt);
1642 static int
1643 fpu_inv_sqrt1(sim_fpu *f, const sim_fpu *l)
1645 static const sim_fpu sim_fpu_one = {
1646 sim_fpu_class_number, 0, IMPLICIT_1, 0
1648 int status = 0;
1649 sim_fpu t;
1651 if (sim_fpu_is_zero (l))
1653 *f = sim_fpu_maxfp;
1654 f->sign = l->sign;
1655 return sim_fpu_status_invalid_div0;
1657 if (sim_fpu_is_infinity (l))
1659 if (!l->sign)
1661 f->class = sim_fpu_class_zero;
1662 f->sign = 0;
1664 else
1666 *f = sim_fpu_qnan;
1667 status = sim_fpu_status_invalid_sqrt;
1669 return status;
1671 status |= sim_fpu_sqrt (&t, l);
1672 status |= sim_fpu_div (f, &sim_fpu_one, &t);
1673 return status;
1676 static int
1677 fpu_inv_sqrt1_32(sim_fpu *f, const sim_fpu *l)
1679 if (sim_fpu_is_zero (l))
1681 *f = sim_fpu_max32;
1682 f->sign = l->sign;
1683 return sim_fpu_status_invalid_div0;
1685 return fpu_inv_sqrt1 (f, l);
1688 static int
1689 fpu_inv_sqrt1_64(sim_fpu *f, const sim_fpu *l)
1691 if (sim_fpu_is_zero (l))
1693 *f = sim_fpu_max64;
1694 f->sign = l->sign;
1695 return sim_fpu_status_invalid_div0;
1697 return fpu_inv_sqrt1 (f, l);
1700 uint64_t
1701 fp_rsqrt1(sim_cpu *cpu,
1702 address_word cia,
1703 uint64_t op,
1704 FP_formats fmt)
1706 switch (fmt)
1708 case fmt_single:
1709 case fmt_ps:
1710 return fp_unary (cpu, cia, &fpu_inv_sqrt1_32, op, fmt);
1711 case fmt_double:
1712 return fp_unary (cpu, cia, &fpu_inv_sqrt1_64, op, fmt);
1714 return 0;
1717 uint64_t
1718 fp_rsqrt2(sim_cpu *cpu,
1719 address_word cia,
1720 uint64_t op1,
1721 uint64_t op2,
1722 FP_formats fmt)
1724 static const uint64_t half_single = UNSIGNED64 (0x3F000000);
1725 static const uint64_t half_double = UNSIGNED64 (0x3FE0000000000000);
1726 static const uint64_t half_ps = (UNSIGNED64 (0x3F000000) << 32 | UNSIGNED64 (0x3F000000));
1727 uint64_t half;
1729 /* Implemented as (nmsub fd, 0.5, fs, ft)/2, where the divide is
1730 done by scaling the exponent during multiply. */
1731 switch (fmt)
1733 case fmt_single: half = half_single; break;
1734 case fmt_double: half = half_double; break;
1735 case fmt_ps: half = half_ps; break;
1736 default: half = 0; abort ();
1738 return fp_mac (cpu, cia, &sim_fpu_sub, op1, op2, half, -1, 1, fmt);
1742 /* Conversion operations. */
1744 uword64
1745 convert (sim_cpu *cpu,
1746 address_word cia,
1747 int rm,
1748 uword64 op,
1749 FP_formats from,
1750 FP_formats to)
1752 sim_fpu wop;
1753 sim_fpu_round round = rounding_mode (rm);
1754 sim_fpu_denorm denorm = denorm_mode (cpu);
1755 uint32_t result32;
1756 uint64_t result64;
1757 sim_fpu_status status = 0;
1759 /* Convert the input to sim_fpu internal format */
1760 switch (from)
1762 case fmt_double:
1763 sim_fpu_64to (&wop, op);
1764 break;
1765 case fmt_single:
1766 sim_fpu_32to (&wop, op);
1767 break;
1768 case fmt_word:
1769 status = sim_fpu_i32to (&wop, op, round);
1770 break;
1771 case fmt_long:
1772 status = sim_fpu_i64to (&wop, op, round);
1773 break;
1774 default:
1775 sim_io_error (SD, "Bad switch\n");
1778 /* Convert sim_fpu format into the output */
1779 /* The value WOP is converted to the destination format, rounding
1780 using mode RM. When the destination is a fixed-point format, then
1781 a source value of Infinity, NaN or one which would round to an
1782 integer outside the fixed point range then an IEEE Invalid Operation
1783 condition is raised. Not used if destination format is PS. */
1784 switch (to)
1786 case fmt_single:
1787 status |= sim_fpu_round_32 (&wop, round, denorm);
1788 /* For a NaN, normalize mantissa bits (cvt.s.d can't preserve them) */
1789 if (sim_fpu_is_qnan (&wop))
1790 wop = sim_fpu_qnan;
1791 sim_fpu_to32 (&result32, &wop);
1792 result64 = result32;
1793 break;
1794 case fmt_double:
1795 status |= sim_fpu_round_64 (&wop, round, denorm);
1796 /* For a NaN, normalize mantissa bits (make cvt.d.s consistent) */
1797 if (sim_fpu_is_qnan (&wop))
1798 wop = sim_fpu_qnan;
1799 sim_fpu_to64 (&result64, &wop);
1800 break;
1801 case fmt_word:
1802 status |= sim_fpu_to32u (&result32, &wop, round);
1803 result64 = result32;
1804 break;
1805 case fmt_long:
1806 status |= sim_fpu_to64u (&result64, &wop, round);
1807 break;
1808 default:
1809 result64 = 0;
1810 sim_io_error (SD, "Bad switch\n");
1813 update_fcsr (cpu, cia, status);
1814 return result64;
1817 uint64_t
1818 ps_lower(sim_cpu *cpu,
1819 address_word cia,
1820 uint64_t op)
1822 return FP_PS_lower (op);
1825 uint64_t
1826 ps_upper(sim_cpu *cpu,
1827 address_word cia,
1828 uint64_t op)
1830 return FP_PS_upper(op);
1833 uint64_t
1834 pack_ps(sim_cpu *cpu,
1835 address_word cia,
1836 uint64_t op1,
1837 uint64_t op2,
1838 FP_formats fmt)
1840 uint64_t result = 0;
1842 /* The registers must specify FPRs valid for operands of type
1843 "fmt". If they are not valid, the result is undefined. */
1845 /* The format type should already have been checked: */
1846 switch (fmt)
1848 case fmt_single:
1850 sim_fpu wop;
1851 uint32_t res_u, res_l;
1852 sim_fpu_32to (&wop, op1);
1853 sim_fpu_to32 (&res_u, &wop);
1854 sim_fpu_32to (&wop, op2);
1855 sim_fpu_to32 (&res_l, &wop);
1856 result = FP_PS_cat(res_u, res_l);
1857 break;
1859 default:
1860 sim_io_error (SD, "Bad switch\n");
1863 return result;
1866 uint64_t
1867 convert_ps (sim_cpu *cpu,
1868 address_word cia,
1869 int rm,
1870 uint64_t op,
1871 FP_formats from,
1872 FP_formats to)
1874 sim_fpu wop_u, wop_l;
1875 sim_fpu_round round = rounding_mode (rm);
1876 sim_fpu_denorm denorm = denorm_mode (cpu);
1877 uint32_t res_u, res_l;
1878 uint64_t result;
1879 sim_fpu_status status_u = 0, status_l = 0;
1881 /* As convert, but used only for paired values (formats PS, PW) */
1883 /* Convert the input to sim_fpu internal format */
1884 switch (from)
1886 case fmt_word: /* fmt_pw */
1887 sim_fpu_i32to (&wop_u, (op >> 32) & (unsigned)0xFFFFFFFF, round);
1888 sim_fpu_i32to (&wop_l, op & (unsigned)0xFFFFFFFF, round);
1889 break;
1890 case fmt_ps:
1891 sim_fpu_32to (&wop_u, FP_PS_upper(op));
1892 sim_fpu_32to (&wop_l, FP_PS_lower(op));
1893 break;
1894 default:
1895 sim_io_error (SD, "Bad switch\n");
1898 /* Convert sim_fpu format into the output */
1899 switch (to)
1901 case fmt_word: /* fmt_pw */
1902 status_u |= sim_fpu_to32u (&res_u, &wop_u, round);
1903 status_l |= sim_fpu_to32u (&res_l, &wop_l, round);
1904 result = (((uint64_t)res_u) << 32) | (uint64_t)res_l;
1905 break;
1906 case fmt_ps:
1907 status_u |= sim_fpu_round_32 (&wop_u, round, denorm);
1908 status_l |= sim_fpu_round_32 (&wop_l, round, denorm);
1909 sim_fpu_to32 (&res_u, &wop_u);
1910 sim_fpu_to32 (&res_l, &wop_l);
1911 result = FP_PS_cat(res_u, res_l);
1912 break;
1913 default:
1914 result = 0;
1915 sim_io_error (SD, "Bad switch\n");
1918 update_fcsr (cpu, cia, status_u | status_l);
1919 return result;
1922 static const char *
1923 fpu_format_name (FP_formats fmt)
1925 switch (fmt)
1927 case fmt_single:
1928 return "single";
1929 case fmt_double:
1930 return "double";
1931 case fmt_word:
1932 return "word";
1933 case fmt_long:
1934 return "long";
1935 case fmt_ps:
1936 return "ps";
1937 case fmt_unknown:
1938 return "<unknown>";
1939 case fmt_uninterpreted:
1940 return "<uninterpreted>";
1941 case fmt_uninterpreted_32:
1942 return "<uninterpreted_32>";
1943 case fmt_uninterpreted_64:
1944 return "<uninterpreted_64>";
1945 default:
1946 return "<format error>";
1950 #ifdef DEBUG
1951 static const char *
1952 fpu_rounding_mode_name (int rm)
1954 switch (rm)
1956 case FP_RM_NEAREST:
1957 return "Round";
1958 case FP_RM_TOZERO:
1959 return "Trunc";
1960 case FP_RM_TOPINF:
1961 return "Ceil";
1962 case FP_RM_TOMINF:
1963 return "Floor";
1964 default:
1965 return "<rounding mode error>";
1968 #endif /* DEBUG */