Remove path name from test case
[binutils-gdb.git] / sim / mips / cp1.c
1 /*> cp1.c <*/
2 /* MIPS Simulator FPU (CoProcessor 1) support.
3 Copyright (C) 2002-2023 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).
8
9 This file is part of GDB, the GNU debugger.
10
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.
15
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.
20
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/>. */
23
24 /* XXX: The following notice should be removed as soon as is practical: */
25 /* Floating Point Support for gdb MIPS simulators
26
27 This file is part of the MIPS sim
28
29 THIS SOFTWARE IS NOT COPYRIGHTED
30 (by Cygnus.)
31
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.
35
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.
39
40 (Originally, this code was in interp.c)
41 */
42
43 /* This must come before any other includes. */
44 #include "defs.h"
45
46 #include "sim-main.h"
47
48 #include <stdlib.h>
49
50 /* Within cp1.c we refer to sim_cpu directly. */
51 #define CPU cpu
52 #define SD CPU_STATE(cpu)
53
54 /*-- FPU support routines ---------------------------------------------------*/
55
56 /* Numbers are held in normalized form. The SINGLE and DOUBLE binary
57 formats conform to ANSI/IEEE Std 754-1985.
58
59 SINGLE precision floating:
60 seeeeeeeefffffffffffffffffffffff
61 s = 1bit = sign
62 e = 8bits = exponent
63 f = 23bits = fraction
64
65 SINGLE precision fixed:
66 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
67 s = 1bit = sign
68 i = 31bits = integer
69
70 DOUBLE precision floating:
71 seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
72 s = 1bit = sign
73 e = 11bits = exponent
74 f = 52bits = fraction
75
76 DOUBLE precision fixed:
77 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
78 s = 1bit = sign
79 i = 63bits = integer
80
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]
88 */
89
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))
95
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))
102
103 static void update_fcsr (sim_cpu *, address_word, sim_fpu_status);
104
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
109
110 uword64
111 value_fpr (sim_cpu *cpu,
112 address_word cia,
113 int fpr,
114 FP_formats fmt)
115 {
116 uword64 value = 0;
117 int err = 0;
118
119 /* Treat unused register values, as fixed-point 64bit values. */
120 if (fmt == fmt_unknown)
121 {
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
129 }
130
131 /* For values not yet accessed, set to the desired format. */
132 if (fmt < fmt_uninterpreted && fmt != fmt_dc32)
133 {
134 if (FPR_STATE[fpr] == fmt_uninterpreted)
135 {
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 */
141 }
142 else if (fmt != FPR_STATE[fpr]
143 && !(fmt == fmt_single
144 && FPR_STATE[fpr] == fmt_double
145 && (FGR[fpr] == 0 || FGR[fpr] == 0xFFFFFFFF)))
146 {
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;
151 }
152 }
153
154 if (FPR_STATE[fpr] == fmt_unknown)
155 {
156 /* Set QNaN value: */
157 switch (fmt)
158 {
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;
165 }
166 }
167 else if (SizeFGR () == 64)
168 {
169 switch (fmt)
170 {
171 case fmt_uninterpreted_32:
172 case fmt_single:
173 case fmt_word:
174 case fmt_dc32:
175 value = (FGR[fpr] & 0xFFFFFFFF);
176 break;
177
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;
185
186 default:
187 err = -1;
188 break;
189 }
190 }
191 else
192 {
193 switch (fmt)
194 {
195 case fmt_uninterpreted_32:
196 case fmt_single:
197 case fmt_word:
198 value = (FGR[fpr] & 0xFFFFFFFF);
199 break;
200
201 case fmt_uninterpreted_64:
202 case fmt_uninterpreted:
203 case fmt_double:
204 case fmt_long:
205 if ((fpr & 1) == 0)
206 {
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));
215 }
216 else
217 {
218 SignalException (ReservedInstruction, 0);
219 }
220 break;
221
222 case fmt_ps:
223 SignalException (ReservedInstruction, 0);
224 break;
225
226 default:
227 err = -1;
228 break;
229 }
230 }
231
232 if (err)
233 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
234
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 */
240
241 return (value);
242 }
243
244 void
245 store_fpr (sim_cpu *cpu,
246 address_word cia,
247 int fpr,
248 FP_formats fmt,
249 uword64 value)
250 {
251 int err = 0;
252
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 */
258
259 if (SizeFGR () == 64)
260 {
261 switch (fmt)
262 {
263 case fmt_uninterpreted_32:
264 fmt = fmt_uninterpreted;
265 case fmt_single:
266 case fmt_word:
267 if (STATE_VERBOSE_P (SD))
268 sim_io_eprintf (SD,
269 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
270 pr_addr (cia));
271 FGR[fpr] = (((uword64) 0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
272 FPR_STATE[fpr] = fmt;
273 break;
274
275 case fmt_uninterpreted_64:
276 fmt = fmt_uninterpreted;
277 case fmt_uninterpreted:
278 case fmt_double:
279 case fmt_long:
280 case fmt_ps:
281 FGR[fpr] = value;
282 FPR_STATE[fpr] = fmt;
283 break;
284
285 default:
286 FPR_STATE[fpr] = fmt_unknown;
287 err = -1;
288 break;
289 }
290 }
291 else
292 {
293 switch (fmt)
294 {
295 case fmt_uninterpreted_32:
296 fmt = fmt_uninterpreted;
297 case fmt_single:
298 case fmt_word:
299 FGR[fpr] = (value & 0xFFFFFFFF);
300 FPR_STATE[fpr] = fmt;
301 break;
302
303 case fmt_uninterpreted_64:
304 fmt = fmt_uninterpreted;
305 case fmt_uninterpreted:
306 case fmt_double:
307 case fmt_long:
308 if ((fpr & 1) == 0)
309 {
310 /* Even register numbers only. */
311 FGR[fpr+1] = (value >> 32);
312 FGR[fpr] = (value & 0xFFFFFFFF);
313 FPR_STATE[fpr + 1] = fmt;
314 FPR_STATE[fpr] = fmt;
315 }
316 else
317 {
318 FPR_STATE[fpr] = fmt_unknown;
319 FPR_STATE[fpr ^ 1] = fmt_unknown;
320 SignalException (ReservedInstruction, 0);
321 }
322 break;
323
324 case fmt_ps:
325 FPR_STATE[fpr] = fmt_unknown;
326 SignalException (ReservedInstruction, 0);
327 break;
328
329 default:
330 FPR_STATE[fpr] = fmt_unknown;
331 err = -1;
332 break;
333 }
334 }
335
336 if (err)
337 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
338
339 #ifdef DEBUG
340 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
341 fpr, pr_uword64 (FGR[fpr]), fpu_format_name (fmt));
342 #endif /* DEBUG */
343
344 return;
345 }
346
347
348 /* CP1 control/status register access functions. */
349
350 void
351 test_fcsr (sim_cpu *cpu,
352 address_word cia)
353 {
354 unsigned int cause;
355
356 cause = (FCSR & fcsr_CAUSE_mask) >> fcsr_CAUSE_shift;
357 if ((cause & ((FCSR & fcsr_ENABLES_mask) >> fcsr_ENABLES_shift)) != 0
358 || (cause & (1 << UO)))
359 {
360 SignalExceptionFPE();
361 }
362 }
363
364 unsigned_word
365 value_fcr(sim_cpu *cpu,
366 address_word cia,
367 int fcr)
368 {
369 uint32_t value = 0;
370
371 switch (fcr)
372 {
373 case 0: /* FP Implementation and Revision Register. */
374 value = FCR0;
375 break;
376 case 25: /* FP Condition Codes Register (derived from FCSR). */
377 value = (FCR31 & fcsr_FCC_mask) >> fcsr_FCC_shift;
378 value = (value & 0x1) | (value >> 1); /* Close FCC gap. */
379 break;
380 case 26: /* FP Exceptions Register (derived from FCSR). */
381 value = FCR31 & (fcsr_CAUSE_mask | fcsr_FLAGS_mask);
382 break;
383 case 28: /* FP Enables Register (derived from FCSR). */
384 value = FCR31 & (fcsr_ENABLES_mask | fcsr_RM_mask);
385 if ((FCR31 & fcsr_FS) != 0)
386 value |= fenr_FS;
387 break;
388 case 31: /* FP Control/Status Register (FCSR). */
389 value = FCR31 & ~fcsr_ZERO_mask;
390 break;
391 }
392
393 return (EXTEND32 (value));
394 }
395
396 void
397 store_fcr(sim_cpu *cpu,
398 address_word cia,
399 int fcr,
400 unsigned_word value)
401 {
402 uint32_t v;
403
404 v = VL4_8(value);
405 switch (fcr)
406 {
407 case 25: /* FP Condition Codes Register (stored into FCSR). */
408 v = (v << 1) | (v & 0x1); /* Adjust for FCC gap. */
409 FCR31 &= ~fcsr_FCC_mask;
410 FCR31 |= ((v << fcsr_FCC_shift) & fcsr_FCC_mask);
411 break;
412 case 26: /* FP Exceptions Register (stored into FCSR). */
413 FCR31 &= ~(fcsr_CAUSE_mask | fcsr_FLAGS_mask);
414 FCR31 |= (v & (fcsr_CAUSE_mask | fcsr_FLAGS_mask));
415 test_fcsr(cpu, cia);
416 break;
417 case 28: /* FP Enables Register (stored into FCSR). */
418 if ((v & fenr_FS) != 0)
419 v |= fcsr_FS;
420 else
421 v &= ~fcsr_FS;
422 FCR31 &= (fcsr_FCC_mask | fcsr_CAUSE_mask | fcsr_FLAGS_mask);
423 FCR31 |= (v & (fcsr_FS | fcsr_ENABLES_mask | fcsr_RM_mask));
424 test_fcsr(cpu, cia);
425 break;
426 case 31: /* FP Control/Status Register (FCSR). */
427 FCR31 = v & ~fcsr_ZERO_mask;
428 test_fcsr(cpu, cia);
429 break;
430 }
431 }
432
433 static void
434 update_fcsr (sim_cpu *cpu,
435 address_word cia,
436 sim_fpu_status status)
437 {
438 FCSR &= ~fcsr_CAUSE_mask;
439
440 if (status != 0)
441 {
442 unsigned int cause = 0;
443
444 /* map between sim_fpu codes and MIPS FCSR */
445 if (status & (sim_fpu_status_invalid_snan
446 | sim_fpu_status_invalid_isi
447 | sim_fpu_status_invalid_idi
448 | sim_fpu_status_invalid_zdz
449 | sim_fpu_status_invalid_imz
450 | sim_fpu_status_invalid_cmp
451 | sim_fpu_status_invalid_sqrt
452 | sim_fpu_status_invalid_cvi))
453 cause |= (1 << IO);
454 if (status & sim_fpu_status_invalid_div0)
455 cause |= (1 << DZ);
456 if (status & sim_fpu_status_overflow)
457 cause |= (1 << OF);
458 if (status & sim_fpu_status_underflow)
459 cause |= (1 << UF);
460 if (status & sim_fpu_status_inexact)
461 cause |= (1 << IR);
462 #if 0 /* Not yet. */
463 /* Implicit clearing of other bits by unimplemented done by callers. */
464 if (status & sim_fpu_status_unimplemented)
465 cause |= (1 << UO);
466 #endif
467
468 FCSR |= (cause << fcsr_CAUSE_shift);
469 test_fcsr (cpu, cia);
470 FCSR |= ((cause & ~(1 << UO)) << fcsr_FLAGS_shift);
471 }
472 return;
473 }
474
475 static sim_fpu_round
476 rounding_mode(int rm)
477 {
478 sim_fpu_round round;
479
480 switch (rm)
481 {
482 case FP_RM_NEAREST:
483 /* Round result to nearest representable value. When two
484 representable values are equally near, round to the value
485 that has a least significant bit of zero (i.e. is even). */
486 round = sim_fpu_round_near;
487 break;
488 case FP_RM_TOZERO:
489 /* Round result to the value closest to, and not greater in
490 magnitude than, the result. */
491 round = sim_fpu_round_zero;
492 break;
493 case FP_RM_TOPINF:
494 /* Round result to the value closest to, and not less than,
495 the result. */
496 round = sim_fpu_round_up;
497 break;
498 case FP_RM_TOMINF:
499 /* Round result to the value closest to, and not greater than,
500 the result. */
501 round = sim_fpu_round_down;
502 break;
503 default:
504 round = 0;
505 fprintf (stderr, "Bad switch\n");
506 abort ();
507 }
508 return round;
509 }
510
511 /* When the FS bit is set, MIPS processors return zero for
512 denormalized results and optionally replace denormalized inputs
513 with zero. When FS is clear, some implementation trap on input
514 and/or output, while other perform the operation in hardware. */
515 static sim_fpu_denorm
516 denorm_mode(sim_cpu *cpu)
517 {
518 sim_fpu_denorm denorm;
519
520 /* XXX: FIXME: Eventually should be CPU model dependent. */
521 if (GETFS())
522 denorm = sim_fpu_denorm_zero;
523 else
524 denorm = 0;
525 return denorm;
526 }
527
528
529 /* Comparison operations. */
530
531 static sim_fpu_status
532 fp_test(uint64_t op1,
533 uint64_t op2,
534 FP_formats fmt,
535 int abs,
536 int cond,
537 int *condition)
538 {
539 sim_fpu wop1;
540 sim_fpu wop2;
541 sim_fpu_status status = 0;
542 int less, equal, unordered;
543
544 /* The format type has already been checked: */
545 switch (fmt)
546 {
547 case fmt_single:
548 {
549 sim_fpu_32to (&wop1, op1);
550 sim_fpu_32to (&wop2, op2);
551 break;
552 }
553 case fmt_double:
554 {
555 sim_fpu_64to (&wop1, op1);
556 sim_fpu_64to (&wop2, op2);
557 break;
558 }
559 default:
560 fprintf (stderr, "Bad switch\n");
561 abort ();
562 }
563
564 if (sim_fpu_is_nan (&wop1) || sim_fpu_is_nan (&wop2))
565 {
566 if ((cond & (1 << 3))
567 || sim_fpu_is_snan (&wop1) || sim_fpu_is_snan (&wop2))
568 status = sim_fpu_status_invalid_snan;
569 less = 0;
570 equal = 0;
571 unordered = 1;
572 }
573 else
574 {
575 if (abs)
576 {
577 status |= sim_fpu_abs (&wop1, &wop1);
578 status |= sim_fpu_abs (&wop2, &wop2);
579 }
580 equal = sim_fpu_is_eq (&wop1, &wop2);
581 less = !equal && sim_fpu_is_lt (&wop1, &wop2);
582 unordered = 0;
583 }
584 *condition = (((cond & (1 << 2)) && less)
585 || ((cond & (1 << 1)) && equal)
586 || ((cond & (1 << 0)) && unordered));
587 return status;
588 }
589
590 static const int sim_fpu_class_mips_mapping[] = {
591 FP_R6CLASS_SNAN, /* SIM_FPU_IS_SNAN = 1, Noisy not-a-number */
592 FP_R6CLASS_QNAN, /* SIM_FPU_IS_QNAN = 2, Quiet not-a-number */
593 FP_R6CLASS_NEGINF, /* SIM_FPU_IS_NINF = 3, -infinity */
594 FP_R6CLASS_POSINF, /* SIM_FPU_IS_PINF = 4, +infinity */
595 FP_R6CLASS_NEGNORM, /* SIM_FPU_IS_NNUMBER = 5, -num - [-MAX .. -MIN] */
596 FP_R6CLASS_POSNORM, /* SIM_FPU_IS_PNUMBER = 6, +num - [+MIN .. +MAX] */
597 FP_R6CLASS_NEGSUB, /* SIM_FPU_IS_NDENORM = 7, -denorm - (MIN .. 0) */
598 FP_R6CLASS_POSSUB, /* SIM_FPU_IS_PDENORM = 8, +denorm - (0 .. MIN) */
599 FP_R6CLASS_NEGZERO, /* SIM_FPU_IS_NZERO = 9, -0 */
600 FP_R6CLASS_POSZERO /* SIM_FPU_IS_PZERO = 10, +0 */
601 };
602
603 uint64_t
604 fp_classify (sim_cpu *cpu,
605 address_word cia,
606 uint64_t op,
607 FP_formats fmt)
608 {
609 sim_fpu wop;
610
611 switch (fmt)
612 {
613 case fmt_single:
614 sim_fpu_32to (&wop, op);
615 break;
616 case fmt_double:
617 sim_fpu_64to (&wop, op);
618 break;
619 default:
620 sim_io_error (SD, "Bad switch\n");
621 }
622 return sim_fpu_class_mips_mapping[sim_fpu_classify (&wop) - 1];
623 }
624
625 int
626 fp_rint (sim_cpu *cpu,
627 address_word cia,
628 uint64_t op,
629 uint64_t *ans,
630 FP_formats fmt)
631 {
632 sim_fpu wop = {0}, wtemp = {0}, wmagic = {0}, wans = {0};
633 int64_t intermediate;
634 int status = 0;
635 sim_fpu_round round = rounding_mode (GETRM());
636
637 switch (fmt)
638 {
639 case fmt_single:
640 sim_fpu_32to (&wop, op);
641 sim_fpu_32to (&wmagic, 0x4b000000);
642 break;
643 case fmt_double:
644 sim_fpu_64to (&wop, op);
645 sim_fpu_64to (&wmagic, 0x4330000000000000);
646 break;
647 default:
648 sim_io_error (SD, "Bad switch\n");
649 }
650
651 if (sim_fpu_is_nan (&wop) || sim_fpu_is_infinity (&wop))
652 {
653 status = sim_fpu_status_invalid_cvi;
654 update_fcsr (cpu, cia, status);
655 return status;
656 }
657
658 switch (fmt)
659 {
660 case fmt_single:
661 if (sim_fpu_is_ge (&wop, &wmagic))
662 wans = wop;
663 else
664 {
665 sim_fpu_add (&wtemp, &wop, &wmagic);
666 sim_fpu_round_32 (&wtemp, round, sim_fpu_denorm_default);
667 sim_fpu_sub (&wans, &wtemp, &wmagic);
668 }
669 sim_fpu_to32 ((uint32_t *) ans, &wans);
670 break;
671 case fmt_double:
672 if (sim_fpu_is_ge (&wop, &wmagic))
673 wans = wop;
674 else
675 {
676 sim_fpu_add (&wtemp, &wop, &wmagic);
677 sim_fpu_round_64 (&wtemp, round, sim_fpu_denorm_default);
678 sim_fpu_sub (&wans, &wtemp, &wmagic);
679 }
680 sim_fpu_to64 (ans, &wans);
681 break;
682 default:
683 sim_io_error (SD, "Bad switch\n");
684 }
685
686 if (*ans != op && status == 0)
687 status = sim_fpu_status_inexact;
688
689 update_fcsr (cpu, cia, status);
690 return status;
691 }
692
693 void
694 fp_cmp(sim_cpu *cpu,
695 address_word cia,
696 uint64_t op1,
697 uint64_t op2,
698 FP_formats fmt,
699 int abs,
700 int cond,
701 int cc)
702 {
703 sim_fpu_status status = 0;
704
705 /* The format type should already have been checked. The FCSR is
706 updated before the condition codes so that any exceptions will
707 be signalled before the condition codes are changed. */
708 switch (fmt)
709 {
710 case fmt_single:
711 case fmt_double:
712 {
713 int result;
714 status = fp_test(op1, op2, fmt, abs, cond, &result);
715 update_fcsr (cpu, cia, status);
716 SETFCC (cc, result);
717 break;
718 }
719 case fmt_ps:
720 {
721 int result0, result1;
722 status = fp_test(FP_PS_lower (op1), FP_PS_lower (op2), fmt_single,
723 abs, cond, &result0);
724 status |= fp_test(FP_PS_upper (op1), FP_PS_upper (op2), fmt_single,
725 abs, cond, &result1);
726 update_fcsr (cpu, cia, status);
727 SETFCC (cc, result0);
728 SETFCC (cc+1, result1);
729 break;
730 }
731 default:
732 sim_io_error (SD, "Bad switch\n");
733 }
734 }
735
736 uint64_t
737 fp_r6_cmp (sim_cpu *cpu,
738 address_word cia,
739 uint64_t op1,
740 uint64_t op2,
741 FP_formats fmt,
742 int cond)
743 {
744 sim_fpu wop1, wop2;
745 int result = 0;
746 int signalling = cond & 0x8;
747
748 switch (fmt)
749 {
750 case fmt_single:
751 sim_fpu_32to (&wop1, op1);
752 sim_fpu_32to (&wop2, op2);
753 break;
754 case fmt_double:
755 sim_fpu_64to (&wop1, op1);
756 sim_fpu_64to (&wop2, op2);
757 break;
758 default:
759 sim_io_error (SD, "Bad switch\n");
760 }
761
762 switch (cond)
763 {
764 case FP_R6CMP_AF:
765 result = 0;
766 break;
767 case FP_R6CMP_UN:
768 result = sim_fpu_is_un (&wop1, &wop2);
769 break;
770 case FP_R6CMP_OR:
771 result = sim_fpu_is_or (&wop1, &wop2);
772 break;
773 case FP_R6CMP_EQ:
774 result = sim_fpu_is_eq (&wop1, &wop2);
775 break;
776 case FP_R6CMP_NE:
777 result = sim_fpu_is_ne (&wop1, &wop2);
778 break;
779 case FP_R6CMP_LT:
780 result = sim_fpu_is_lt (&wop1, &wop2);
781 break;
782 case FP_R6CMP_LE:
783 result = sim_fpu_is_le (&wop1, &wop2);
784 break;
785 case FP_R6CMP_UEQ:
786 result = sim_fpu_is_un (&wop1, &wop2) || sim_fpu_is_eq (&wop1, &wop2);
787 break;
788 case FP_R6CMP_UNE:
789 result = sim_fpu_is_un (&wop1, &wop2) || sim_fpu_is_ne (&wop1, &wop2);
790 break;
791 case FP_R6CMP_ULT:
792 result = sim_fpu_is_un (&wop1, &wop2) || sim_fpu_is_lt (&wop1, &wop2);
793 break;
794 case FP_R6CMP_ULE:
795 result = sim_fpu_is_un (&wop1, &wop2) || sim_fpu_is_le (&wop1, &wop2);
796 break;
797 default:
798 update_fcsr (cpu, cia, sim_fpu_status_invalid_cmp);
799 break;
800 }
801
802 if (result)
803 {
804 switch (fmt)
805 {
806 case fmt_single:
807 return 0xFFFFFFFF;
808 case fmt_double:
809 return 0xFFFFFFFFFFFFFFFF;
810 default:
811 sim_io_error (SD, "Bad switch\n");
812 }
813 }
814 else
815 return 0;
816 }
817
818 /* Basic arithmetic operations. */
819
820 static uint64_t
821 fp_unary(sim_cpu *cpu,
822 address_word cia,
823 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *),
824 uint64_t op,
825 FP_formats fmt)
826 {
827 sim_fpu wop = {0};
828 sim_fpu ans;
829 sim_fpu_round round = rounding_mode (GETRM());
830 sim_fpu_denorm denorm = denorm_mode (cpu);
831 sim_fpu_status status = 0;
832 uint64_t result = 0;
833
834 /* The format type has already been checked: */
835 switch (fmt)
836 {
837 case fmt_single:
838 {
839 uint32_t res;
840 sim_fpu_32to (&wop, op);
841 status |= (*sim_fpu_op) (&ans, &wop);
842 status |= sim_fpu_round_32 (&ans, round, denorm);
843 sim_fpu_to32 (&res, &ans);
844 result = res;
845 break;
846 }
847 case fmt_double:
848 {
849 uint64_t res;
850 sim_fpu_64to (&wop, op);
851 status |= (*sim_fpu_op) (&ans, &wop);
852 status |= sim_fpu_round_64 (&ans, round, denorm);
853 sim_fpu_to64 (&res, &ans);
854 result = res;
855 break;
856 }
857 case fmt_ps:
858 {
859 int status_u = 0, status_l = 0;
860 uint32_t res_u, res_l;
861 sim_fpu_32to (&wop, FP_PS_upper(op));
862 status_u |= (*sim_fpu_op) (&ans, &wop);
863 sim_fpu_to32 (&res_u, &ans);
864 sim_fpu_32to (&wop, FP_PS_lower(op));
865 status_l |= (*sim_fpu_op) (&ans, &wop);
866 sim_fpu_to32 (&res_l, &ans);
867 result = FP_PS_cat(res_u, res_l);
868 status = status_u | status_l;
869 break;
870 }
871 default:
872 sim_io_error (SD, "Bad switch\n");
873 }
874
875 update_fcsr (cpu, cia, status);
876 return result;
877 }
878
879 static uint64_t
880 fp_binary(sim_cpu *cpu,
881 address_word cia,
882 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
883 uint64_t op1,
884 uint64_t op2,
885 FP_formats fmt)
886 {
887 sim_fpu wop1 = {0};
888 sim_fpu wop2 = {0};
889 sim_fpu ans = {0};
890 sim_fpu_round round = rounding_mode (GETRM());
891 sim_fpu_denorm denorm = denorm_mode (cpu);
892 sim_fpu_status status = 0;
893 uint64_t result = 0;
894
895 /* The format type has already been checked: */
896 switch (fmt)
897 {
898 case fmt_single:
899 {
900 uint32_t res;
901 sim_fpu_32to (&wop1, op1);
902 sim_fpu_32to (&wop2, op2);
903 status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
904 status |= sim_fpu_round_32 (&ans, round, denorm);
905 sim_fpu_to32 (&res, &ans);
906 result = res;
907 break;
908 }
909 case fmt_double:
910 {
911 uint64_t res;
912 sim_fpu_64to (&wop1, op1);
913 sim_fpu_64to (&wop2, op2);
914 status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
915 status |= sim_fpu_round_64 (&ans, round, denorm);
916 sim_fpu_to64 (&res, &ans);
917 result = res;
918 break;
919 }
920 case fmt_ps:
921 {
922 int status_u = 0, status_l = 0;
923 uint32_t res_u, res_l;
924 sim_fpu_32to (&wop1, FP_PS_upper(op1));
925 sim_fpu_32to (&wop2, FP_PS_upper(op2));
926 status_u |= (*sim_fpu_op) (&ans, &wop1, &wop2);
927 sim_fpu_to32 (&res_u, &ans);
928 sim_fpu_32to (&wop1, FP_PS_lower(op1));
929 sim_fpu_32to (&wop2, FP_PS_lower(op2));
930 status_l |= (*sim_fpu_op) (&ans, &wop1, &wop2);
931 sim_fpu_to32 (&res_l, &ans);
932 result = FP_PS_cat(res_u, res_l);
933 status = status_u | status_l;
934 break;
935 }
936 default:
937 sim_io_error (SD, "Bad switch\n");
938 }
939
940 update_fcsr (cpu, cia, status);
941 return result;
942 }
943
944 /* Common MAC code for single operands (.s or .d), defers setting FCSR. */
945 static sim_fpu_status
946 inner_mac(int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
947 uint64_t op1,
948 uint64_t op2,
949 uint64_t op3,
950 int scale,
951 int negate,
952 FP_formats fmt,
953 sim_fpu_round round,
954 sim_fpu_denorm denorm,
955 uint64_t *result)
956 {
957 sim_fpu wop1;
958 sim_fpu wop2;
959 sim_fpu ans;
960 sim_fpu_status status = 0;
961 sim_fpu_status op_status;
962 uint64_t temp = 0;
963
964 switch (fmt)
965 {
966 case fmt_single:
967 {
968 uint32_t res;
969 sim_fpu_32to (&wop1, op1);
970 sim_fpu_32to (&wop2, op2);
971 status |= sim_fpu_mul (&ans, &wop1, &wop2);
972 if (scale != 0 && sim_fpu_is_number (&ans)) /* number or denorm */
973 ans.normal_exp += scale;
974 status |= sim_fpu_round_32 (&ans, round, denorm);
975 wop1 = ans;
976 op_status = 0;
977 sim_fpu_32to (&wop2, op3);
978 op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
979 op_status |= sim_fpu_round_32 (&ans, round, denorm);
980 status |= op_status;
981 if (negate)
982 {
983 wop1 = ans;
984 op_status = sim_fpu_neg (&ans, &wop1);
985 op_status |= sim_fpu_round_32 (&ans, round, denorm);
986 status |= op_status;
987 }
988 sim_fpu_to32 (&res, &ans);
989 temp = res;
990 break;
991 }
992 case fmt_double:
993 {
994 uint64_t res;
995 sim_fpu_64to (&wop1, op1);
996 sim_fpu_64to (&wop2, op2);
997 status |= sim_fpu_mul (&ans, &wop1, &wop2);
998 if (scale != 0 && sim_fpu_is_number (&ans)) /* number or denorm */
999 ans.normal_exp += scale;
1000 status |= sim_fpu_round_64 (&ans, round, denorm);
1001 wop1 = ans;
1002 op_status = 0;
1003 sim_fpu_64to (&wop2, op3);
1004 op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
1005 op_status |= sim_fpu_round_64 (&ans, round, denorm);
1006 status |= op_status;
1007 if (negate)
1008 {
1009 wop1 = ans;
1010 op_status = sim_fpu_neg (&ans, &wop1);
1011 op_status |= sim_fpu_round_64 (&ans, round, denorm);
1012 status |= op_status;
1013 }
1014 sim_fpu_to64 (&res, &ans);
1015 temp = res;
1016 break;
1017 }
1018 default:
1019 fprintf (stderr, "Bad switch\n");
1020 abort ();
1021 }
1022 *result = temp;
1023 return status;
1024 }
1025
1026 /* Common implementation of madd, nmadd, msub, nmsub that does
1027 intermediate rounding per spec. Also used for recip2 and rsqrt2,
1028 which are transformed into equivalent nmsub operations. The scale
1029 argument is an adjustment to the exponent of the intermediate
1030 product op1*op2. It is currently non-zero for rsqrt2 (-1), which
1031 requires an effective division by 2. */
1032 static uint64_t
1033 fp_mac(sim_cpu *cpu,
1034 address_word cia,
1035 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
1036 uint64_t op1,
1037 uint64_t op2,
1038 uint64_t op3,
1039 int scale,
1040 int negate,
1041 FP_formats fmt)
1042 {
1043 sim_fpu_round round = rounding_mode (GETRM());
1044 sim_fpu_denorm denorm = denorm_mode (cpu);
1045 sim_fpu_status status = 0;
1046 uint64_t result = 0;
1047
1048 /* The format type has already been checked: */
1049 switch (fmt)
1050 {
1051 case fmt_single:
1052 case fmt_double:
1053 status = inner_mac(sim_fpu_op, op1, op2, op3, scale,
1054 negate, fmt, round, denorm, &result);
1055 break;
1056 case fmt_ps:
1057 {
1058 int status_u, status_l;
1059 uint64_t result_u, result_l;
1060 status_u = inner_mac(sim_fpu_op, FP_PS_upper(op1), FP_PS_upper(op2),
1061 FP_PS_upper(op3), scale, negate, fmt_single,
1062 round, denorm, &result_u);
1063 status_l = inner_mac(sim_fpu_op, FP_PS_lower(op1), FP_PS_lower(op2),
1064 FP_PS_lower(op3), scale, negate, fmt_single,
1065 round, denorm, &result_l);
1066 result = FP_PS_cat(result_u, result_l);
1067 status = status_u | status_l;
1068 break;
1069 }
1070 default:
1071 sim_io_error (SD, "Bad switch\n");
1072 }
1073
1074 update_fcsr (cpu, cia, status);
1075 return result;
1076 }
1077
1078 /* Common FMAC code for .s, .d. Defers setting FCSR to caller. */
1079 static sim_fpu_status
1080 inner_fmac (sim_cpu *cpu,
1081 int (*sim_fpu_op) (sim_fpu *, const sim_fpu *, const sim_fpu *),
1082 uint64_t op1,
1083 uint64_t op2,
1084 uint64_t op3,
1085 sim_fpu_round round,
1086 sim_fpu_denorm denorm,
1087 FP_formats fmt,
1088 uint64_t *result)
1089 {
1090 sim_fpu wop1, wop2, ans;
1091 sim_fpu_status status = 0;
1092 sim_fpu_status op_status;
1093 uint32_t t32 = 0;
1094 uint64_t t64 = 0;
1095
1096 switch (fmt)
1097 {
1098 case fmt_single:
1099 sim_fpu_32to (&wop1, op1);
1100 sim_fpu_32to (&wop2, op2);
1101 status |= sim_fpu_mul (&ans, &wop1, &wop2);
1102 wop1 = ans;
1103 op_status = 0;
1104 sim_fpu_32to (&wop2, op3);
1105 op_status |= (*sim_fpu_op) (&ans, &wop2, &wop1);
1106 op_status |= sim_fpu_round_32 (&ans, round, denorm);
1107 status |= op_status;
1108 sim_fpu_to32 (&t32, &ans);
1109 t64 = t32;
1110 break;
1111 case fmt_double:
1112 sim_fpu_64to (&wop1, op1);
1113 sim_fpu_64to (&wop2, op2);
1114 status |= sim_fpu_mul (&ans, &wop1, &wop2);
1115 wop1 = ans;
1116 op_status = 0;
1117 sim_fpu_64to (&wop2, op3);
1118 op_status |= (*sim_fpu_op) (&ans, &wop2, &wop1);
1119 op_status |= sim_fpu_round_64 (&ans, round, denorm);
1120 status |= op_status;
1121 sim_fpu_to64 (&t64, &ans);
1122 break;
1123 default:
1124 sim_io_error (SD, "Bad switch\n");
1125 }
1126
1127 *result = t64;
1128 return status;
1129 }
1130
1131 static uint64_t
1132 fp_fmac (sim_cpu *cpu,
1133 address_word cia,
1134 int (*sim_fpu_op) (sim_fpu *, const sim_fpu *, const sim_fpu *),
1135 uint64_t op1,
1136 uint64_t op2,
1137 uint64_t op3,
1138 FP_formats fmt)
1139 {
1140 sim_fpu_round round = rounding_mode (GETRM());
1141 sim_fpu_denorm denorm = denorm_mode (cpu);
1142 sim_fpu_status status = 0;
1143 uint64_t result = 0;
1144
1145 switch (fmt)
1146 {
1147 case fmt_single:
1148 case fmt_double:
1149 status = inner_fmac (cpu, sim_fpu_op, op1, op2, op3,
1150 round, denorm, fmt, &result);
1151 break;
1152 default:
1153 sim_io_error (SD, "Bad switch\n");
1154 }
1155
1156 update_fcsr (cpu, cia, status);
1157 return result;
1158 }
1159
1160 /* Common rsqrt code for single operands (.s or .d), intermediate rounding. */
1161 static sim_fpu_status
1162 inner_rsqrt(uint64_t op1,
1163 FP_formats fmt,
1164 sim_fpu_round round,
1165 sim_fpu_denorm denorm,
1166 uint64_t *result)
1167 {
1168 sim_fpu wop1;
1169 sim_fpu ans;
1170 sim_fpu_status status = 0;
1171 sim_fpu_status op_status;
1172 uint64_t temp = 0;
1173
1174 switch (fmt)
1175 {
1176 case fmt_single:
1177 {
1178 uint32_t res;
1179 sim_fpu_32to (&wop1, op1);
1180 status |= sim_fpu_sqrt (&ans, &wop1);
1181 status |= sim_fpu_round_32 (&ans, status, round);
1182 wop1 = ans;
1183 op_status = sim_fpu_inv (&ans, &wop1);
1184 op_status |= sim_fpu_round_32 (&ans, round, denorm);
1185 sim_fpu_to32 (&res, &ans);
1186 temp = res;
1187 status |= op_status;
1188 break;
1189 }
1190 case fmt_double:
1191 {
1192 uint64_t res;
1193 sim_fpu_64to (&wop1, op1);
1194 status |= sim_fpu_sqrt (&ans, &wop1);
1195 status |= sim_fpu_round_64 (&ans, round, denorm);
1196 wop1 = ans;
1197 op_status = sim_fpu_inv (&ans, &wop1);
1198 op_status |= sim_fpu_round_64 (&ans, round, denorm);
1199 sim_fpu_to64 (&res, &ans);
1200 temp = res;
1201 status |= op_status;
1202 break;
1203 }
1204 default:
1205 fprintf (stderr, "Bad switch\n");
1206 abort ();
1207 }
1208 *result = temp;
1209 return status;
1210 }
1211
1212 static uint64_t
1213 fp_inv_sqrt(sim_cpu *cpu,
1214 address_word cia,
1215 uint64_t op1,
1216 FP_formats fmt)
1217 {
1218 sim_fpu_round round = rounding_mode (GETRM());
1219 sim_fpu_round denorm = denorm_mode (cpu);
1220 sim_fpu_status status = 0;
1221 uint64_t result = 0;
1222
1223 /* The format type has already been checked: */
1224 switch (fmt)
1225 {
1226 case fmt_single:
1227 case fmt_double:
1228 status = inner_rsqrt (op1, fmt, round, denorm, &result);
1229 break;
1230 case fmt_ps:
1231 {
1232 int status_u, status_l;
1233 uint64_t result_u, result_l;
1234 status_u = inner_rsqrt (FP_PS_upper(op1), fmt_single, round, denorm,
1235 &result_u);
1236 status_l = inner_rsqrt (FP_PS_lower(op1), fmt_single, round, denorm,
1237 &result_l);
1238 result = FP_PS_cat(result_u, result_l);
1239 status = status_u | status_l;
1240 break;
1241 }
1242 default:
1243 sim_io_error (SD, "Bad switch\n");
1244 }
1245
1246 update_fcsr (cpu, cia, status);
1247 return result;
1248 }
1249
1250
1251 uint64_t
1252 fp_abs(sim_cpu *cpu,
1253 address_word cia,
1254 uint64_t op,
1255 FP_formats fmt)
1256 {
1257 return fp_unary(cpu, cia, &sim_fpu_abs, op, fmt);
1258 }
1259
1260 uint64_t
1261 fp_neg(sim_cpu *cpu,
1262 address_word cia,
1263 uint64_t op,
1264 FP_formats fmt)
1265 {
1266 return fp_unary(cpu, cia, &sim_fpu_neg, op, fmt);
1267 }
1268
1269 uint64_t
1270 fp_add(sim_cpu *cpu,
1271 address_word cia,
1272 uint64_t op1,
1273 uint64_t op2,
1274 FP_formats fmt)
1275 {
1276 return fp_binary(cpu, cia, &sim_fpu_add, op1, op2, fmt);
1277 }
1278
1279 uint64_t
1280 fp_sub(sim_cpu *cpu,
1281 address_word cia,
1282 uint64_t op1,
1283 uint64_t op2,
1284 FP_formats fmt)
1285 {
1286 return fp_binary(cpu, cia, &sim_fpu_sub, op1, op2, fmt);
1287 }
1288
1289 uint64_t
1290 fp_mul(sim_cpu *cpu,
1291 address_word cia,
1292 uint64_t op1,
1293 uint64_t op2,
1294 FP_formats fmt)
1295 {
1296 return fp_binary(cpu, cia, &sim_fpu_mul, op1, op2, fmt);
1297 }
1298
1299 uint64_t
1300 fp_div(sim_cpu *cpu,
1301 address_word cia,
1302 uint64_t op1,
1303 uint64_t op2,
1304 FP_formats fmt)
1305 {
1306 return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt);
1307 }
1308
1309 uint64_t
1310 fp_min (sim_cpu *cpu,
1311 address_word cia,
1312 uint64_t op1,
1313 uint64_t op2,
1314 FP_formats fmt)
1315 {
1316 return fp_binary (cpu, cia, &sim_fpu_min, op1, op2, fmt);
1317 }
1318
1319 uint64_t
1320 fp_max (sim_cpu *cpu,
1321 address_word cia,
1322 uint64_t op1,
1323 uint64_t op2,
1324 FP_formats fmt)
1325 {
1326 return fp_binary (cpu, cia, &sim_fpu_max, op1, op2, fmt);
1327 }
1328
1329 uint64_t
1330 fp_mina (sim_cpu *cpu,
1331 address_word cia,
1332 uint64_t op1,
1333 uint64_t op2,
1334 FP_formats fmt)
1335 {
1336 uint64_t ret;
1337 sim_fpu wop1 = {0}, wop2 = {0}, waop1, waop2, wans;
1338 sim_fpu_status status = 0;
1339
1340 switch (fmt)
1341 {
1342 case fmt_single:
1343 sim_fpu_32to (&wop1, op1);
1344 sim_fpu_32to (&wop2, op2);
1345 break;
1346 case fmt_double:
1347 sim_fpu_64to (&wop1, op1);
1348 sim_fpu_64to (&wop2, op2);
1349 break;
1350 default:
1351 sim_io_error (SD, "Bad switch\n");
1352 }
1353
1354 status |= sim_fpu_abs (&waop1, &wop1);
1355 status |= sim_fpu_abs (&waop2, &wop2);
1356 status |= sim_fpu_min (&wans, &waop1, &waop2);
1357 ret = (sim_fpu_is_eq (&wans, &waop1)) ? op1 : op2;
1358
1359 update_fcsr (cpu, cia, status);
1360 return ret;
1361 }
1362
1363 uint64_t
1364 fp_maxa (sim_cpu *cpu,
1365 address_word cia,
1366 uint64_t op1,
1367 uint64_t op2,
1368 FP_formats fmt)
1369 {
1370 uint64_t ret;
1371 sim_fpu wop1 = {0}, wop2 = {0}, waop1, waop2, wans;
1372 sim_fpu_status status = 0;
1373
1374 switch (fmt)
1375 {
1376 case fmt_single:
1377 sim_fpu_32to (&wop1, op1);
1378 sim_fpu_32to (&wop2, op2);
1379 break;
1380 case fmt_double:
1381 sim_fpu_64to (&wop1, op1);
1382 sim_fpu_64to (&wop2, op2);
1383 break;
1384 default:
1385 sim_io_error (SD, "Bad switch\n");
1386 }
1387
1388 status |= sim_fpu_abs (&waop1, &wop1);
1389 status |= sim_fpu_abs (&waop2, &wop2);
1390 status |= sim_fpu_max (&wans, &waop1, &waop2);
1391 ret = (sim_fpu_is_eq (&wans, &waop1)) ? op1 : op2;
1392
1393 update_fcsr (cpu, cia, status);
1394 return ret;
1395 }
1396
1397 uint64_t
1398 fp_recip(sim_cpu *cpu,
1399 address_word cia,
1400 uint64_t op,
1401 FP_formats fmt)
1402 {
1403 return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt);
1404 }
1405
1406 uint64_t
1407 fp_sqrt(sim_cpu *cpu,
1408 address_word cia,
1409 uint64_t op,
1410 FP_formats fmt)
1411 {
1412 return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
1413 }
1414
1415 uint64_t
1416 fp_rsqrt(sim_cpu *cpu,
1417 address_word cia,
1418 uint64_t op,
1419 FP_formats fmt)
1420 {
1421 return fp_inv_sqrt(cpu, cia, op, fmt);
1422 }
1423
1424 uint64_t
1425 fp_madd(sim_cpu *cpu,
1426 address_word cia,
1427 uint64_t op1,
1428 uint64_t op2,
1429 uint64_t op3,
1430 FP_formats fmt)
1431 {
1432 return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 0, fmt);
1433 }
1434
1435 uint64_t
1436 fp_msub(sim_cpu *cpu,
1437 address_word cia,
1438 uint64_t op1,
1439 uint64_t op2,
1440 uint64_t op3,
1441 FP_formats fmt)
1442 {
1443 return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 0, fmt);
1444 }
1445
1446 uint64_t
1447 fp_fmadd (sim_cpu *cpu,
1448 address_word cia,
1449 uint64_t op1,
1450 uint64_t op2,
1451 uint64_t op3,
1452 FP_formats fmt)
1453 {
1454 return fp_fmac (cpu, cia, &sim_fpu_add, op1, op2, op3, fmt);
1455 }
1456
1457 uint64_t
1458 fp_fmsub (sim_cpu *cpu,
1459 address_word cia,
1460 uint64_t op1,
1461 uint64_t op2,
1462 uint64_t op3,
1463 FP_formats fmt)
1464 {
1465 return fp_fmac (cpu, cia, &sim_fpu_sub, op1, op2, op3, fmt);
1466 }
1467
1468 uint64_t
1469 fp_nmadd(sim_cpu *cpu,
1470 address_word cia,
1471 uint64_t op1,
1472 uint64_t op2,
1473 uint64_t op3,
1474 FP_formats fmt)
1475 {
1476 return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 1, fmt);
1477 }
1478
1479 uint64_t
1480 fp_nmsub(sim_cpu *cpu,
1481 address_word cia,
1482 uint64_t op1,
1483 uint64_t op2,
1484 uint64_t op3,
1485 FP_formats fmt)
1486 {
1487 return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 1, fmt);
1488 }
1489
1490
1491 /* MIPS-3D ASE operations. */
1492
1493 /* Variant of fp_binary for *r.ps MIPS-3D operations. */
1494 static uint64_t
1495 fp_binary_r(sim_cpu *cpu,
1496 address_word cia,
1497 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
1498 uint64_t op1,
1499 uint64_t op2)
1500 {
1501 sim_fpu wop1;
1502 sim_fpu wop2;
1503 sim_fpu ans;
1504 sim_fpu_round round = rounding_mode (GETRM ());
1505 sim_fpu_denorm denorm = denorm_mode (cpu);
1506 sim_fpu_status status_u, status_l;
1507 uint64_t result;
1508 uint32_t res_u, res_l;
1509
1510 /* The format must be fmt_ps. */
1511 status_u = 0;
1512 sim_fpu_32to (&wop1, FP_PS_upper (op1));
1513 sim_fpu_32to (&wop2, FP_PS_lower (op1));
1514 status_u |= (*sim_fpu_op) (&ans, &wop1, &wop2);
1515 status_u |= sim_fpu_round_32 (&ans, round, denorm);
1516 sim_fpu_to32 (&res_u, &ans);
1517 status_l = 0;
1518 sim_fpu_32to (&wop1, FP_PS_upper (op2));
1519 sim_fpu_32to (&wop2, FP_PS_lower (op2));
1520 status_l |= (*sim_fpu_op) (&ans, &wop1, &wop2);
1521 status_l |= sim_fpu_round_32 (&ans, round, denorm);
1522 sim_fpu_to32 (&res_l, &ans);
1523 result = FP_PS_cat (res_u, res_l);
1524
1525 update_fcsr (cpu, cia, status_u | status_l);
1526 return result;
1527 }
1528
1529 uint64_t
1530 fp_add_r(sim_cpu *cpu,
1531 address_word cia,
1532 uint64_t op1,
1533 uint64_t op2,
1534 FP_formats fmt)
1535 {
1536 return fp_binary_r (cpu, cia, &sim_fpu_add, op1, op2);
1537 }
1538
1539 uint64_t
1540 fp_mul_r(sim_cpu *cpu,
1541 address_word cia,
1542 uint64_t op1,
1543 uint64_t op2,
1544 FP_formats fmt)
1545 {
1546 return fp_binary_r (cpu, cia, &sim_fpu_mul, op1, op2);
1547 }
1548
1549 #define NR_FRAC_GUARD (60)
1550 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
1551
1552 static int
1553 fpu_inv1(sim_fpu *f, const sim_fpu *l)
1554 {
1555 static const sim_fpu sim_fpu_one = {
1556 sim_fpu_class_number, 0, IMPLICIT_1, 0
1557 };
1558 int status = 0;
1559 sim_fpu t;
1560
1561 if (sim_fpu_is_zero (l))
1562 {
1563 *f = sim_fpu_maxfp;
1564 f->sign = l->sign;
1565 return sim_fpu_status_invalid_div0;
1566 }
1567 if (sim_fpu_is_infinity (l))
1568 {
1569 *f = sim_fpu_zero;
1570 f->sign = l->sign;
1571 return status;
1572 }
1573 status |= sim_fpu_div (f, &sim_fpu_one, l);
1574 return status;
1575 }
1576
1577 static int
1578 fpu_inv1_32(sim_fpu *f, const sim_fpu *l)
1579 {
1580 if (sim_fpu_is_zero (l))
1581 {
1582 *f = sim_fpu_max32;
1583 f->sign = l->sign;
1584 return sim_fpu_status_invalid_div0;
1585 }
1586 return fpu_inv1 (f, l);
1587 }
1588
1589 static int
1590 fpu_inv1_64(sim_fpu *f, const sim_fpu *l)
1591 {
1592 if (sim_fpu_is_zero (l))
1593 {
1594 *f = sim_fpu_max64;
1595 f->sign = l->sign;
1596 return sim_fpu_status_invalid_div0;
1597 }
1598 return fpu_inv1 (f, l);
1599 }
1600
1601 uint64_t
1602 fp_recip1(sim_cpu *cpu,
1603 address_word cia,
1604 uint64_t op,
1605 FP_formats fmt)
1606 {
1607 switch (fmt)
1608 {
1609 case fmt_single:
1610 case fmt_ps:
1611 return fp_unary (cpu, cia, &fpu_inv1_32, op, fmt);
1612 case fmt_double:
1613 return fp_unary (cpu, cia, &fpu_inv1_64, op, fmt);
1614 }
1615 return 0;
1616 }
1617
1618 uint64_t
1619 fp_recip2(sim_cpu *cpu,
1620 address_word cia,
1621 uint64_t op1,
1622 uint64_t op2,
1623 FP_formats fmt)
1624 {
1625 static const uint64_t one_single = UNSIGNED64 (0x3F800000);
1626 static const uint64_t one_double = UNSIGNED64 (0x3FF0000000000000);
1627 static const uint64_t one_ps = (UNSIGNED64 (0x3F800000) << 32 | UNSIGNED64 (0x3F800000));
1628 uint64_t one;
1629
1630 /* Implemented as nmsub fd, 1, fs, ft. */
1631 switch (fmt)
1632 {
1633 case fmt_single: one = one_single; break;
1634 case fmt_double: one = one_double; break;
1635 case fmt_ps: one = one_ps; break;
1636 default: one = 0; abort ();
1637 }
1638 return fp_mac (cpu, cia, &sim_fpu_sub, op1, op2, one, 0, 1, fmt);
1639 }
1640
1641 static int
1642 fpu_inv_sqrt1(sim_fpu *f, const sim_fpu *l)
1643 {
1644 static const sim_fpu sim_fpu_one = {
1645 sim_fpu_class_number, 0, IMPLICIT_1, 0
1646 };
1647 int status = 0;
1648 sim_fpu t;
1649
1650 if (sim_fpu_is_zero (l))
1651 {
1652 *f = sim_fpu_maxfp;
1653 f->sign = l->sign;
1654 return sim_fpu_status_invalid_div0;
1655 }
1656 if (sim_fpu_is_infinity (l))
1657 {
1658 if (!l->sign)
1659 {
1660 f->class = sim_fpu_class_zero;
1661 f->sign = 0;
1662 }
1663 else
1664 {
1665 *f = sim_fpu_qnan;
1666 status = sim_fpu_status_invalid_sqrt;
1667 }
1668 return status;
1669 }
1670 status |= sim_fpu_sqrt (&t, l);
1671 status |= sim_fpu_div (f, &sim_fpu_one, &t);
1672 return status;
1673 }
1674
1675 static int
1676 fpu_inv_sqrt1_32(sim_fpu *f, const sim_fpu *l)
1677 {
1678 if (sim_fpu_is_zero (l))
1679 {
1680 *f = sim_fpu_max32;
1681 f->sign = l->sign;
1682 return sim_fpu_status_invalid_div0;
1683 }
1684 return fpu_inv_sqrt1 (f, l);
1685 }
1686
1687 static int
1688 fpu_inv_sqrt1_64(sim_fpu *f, const sim_fpu *l)
1689 {
1690 if (sim_fpu_is_zero (l))
1691 {
1692 *f = sim_fpu_max64;
1693 f->sign = l->sign;
1694 return sim_fpu_status_invalid_div0;
1695 }
1696 return fpu_inv_sqrt1 (f, l);
1697 }
1698
1699 uint64_t
1700 fp_rsqrt1(sim_cpu *cpu,
1701 address_word cia,
1702 uint64_t op,
1703 FP_formats fmt)
1704 {
1705 switch (fmt)
1706 {
1707 case fmt_single:
1708 case fmt_ps:
1709 return fp_unary (cpu, cia, &fpu_inv_sqrt1_32, op, fmt);
1710 case fmt_double:
1711 return fp_unary (cpu, cia, &fpu_inv_sqrt1_64, op, fmt);
1712 }
1713 return 0;
1714 }
1715
1716 uint64_t
1717 fp_rsqrt2(sim_cpu *cpu,
1718 address_word cia,
1719 uint64_t op1,
1720 uint64_t op2,
1721 FP_formats fmt)
1722 {
1723 static const uint64_t half_single = UNSIGNED64 (0x3F000000);
1724 static const uint64_t half_double = UNSIGNED64 (0x3FE0000000000000);
1725 static const uint64_t half_ps = (UNSIGNED64 (0x3F000000) << 32 | UNSIGNED64 (0x3F000000));
1726 uint64_t half;
1727
1728 /* Implemented as (nmsub fd, 0.5, fs, ft)/2, where the divide is
1729 done by scaling the exponent during multiply. */
1730 switch (fmt)
1731 {
1732 case fmt_single: half = half_single; break;
1733 case fmt_double: half = half_double; break;
1734 case fmt_ps: half = half_ps; break;
1735 default: half = 0; abort ();
1736 }
1737 return fp_mac (cpu, cia, &sim_fpu_sub, op1, op2, half, -1, 1, fmt);
1738 }
1739
1740
1741 /* Conversion operations. */
1742
1743 uword64
1744 convert (sim_cpu *cpu,
1745 address_word cia,
1746 int rm,
1747 uword64 op,
1748 FP_formats from,
1749 FP_formats to)
1750 {
1751 sim_fpu wop;
1752 sim_fpu_round round = rounding_mode (rm);
1753 sim_fpu_denorm denorm = denorm_mode (cpu);
1754 uint32_t result32;
1755 uint64_t result64;
1756 sim_fpu_status status = 0;
1757
1758 /* Convert the input to sim_fpu internal format */
1759 switch (from)
1760 {
1761 case fmt_double:
1762 sim_fpu_64to (&wop, op);
1763 break;
1764 case fmt_single:
1765 sim_fpu_32to (&wop, op);
1766 break;
1767 case fmt_word:
1768 status = sim_fpu_i32to (&wop, op, round);
1769 break;
1770 case fmt_long:
1771 status = sim_fpu_i64to (&wop, op, round);
1772 break;
1773 default:
1774 sim_io_error (SD, "Bad switch\n");
1775 }
1776
1777 /* Convert sim_fpu format into the output */
1778 /* The value WOP is converted to the destination format, rounding
1779 using mode RM. When the destination is a fixed-point format, then
1780 a source value of Infinity, NaN or one which would round to an
1781 integer outside the fixed point range then an IEEE Invalid Operation
1782 condition is raised. Not used if destination format is PS. */
1783 switch (to)
1784 {
1785 case fmt_single:
1786 status |= sim_fpu_round_32 (&wop, round, denorm);
1787 /* For a NaN, normalize mantissa bits (cvt.s.d can't preserve them) */
1788 if (sim_fpu_is_qnan (&wop))
1789 wop = sim_fpu_qnan;
1790 sim_fpu_to32 (&result32, &wop);
1791 result64 = result32;
1792 break;
1793 case fmt_double:
1794 status |= sim_fpu_round_64 (&wop, round, denorm);
1795 /* For a NaN, normalize mantissa bits (make cvt.d.s consistent) */
1796 if (sim_fpu_is_qnan (&wop))
1797 wop = sim_fpu_qnan;
1798 sim_fpu_to64 (&result64, &wop);
1799 break;
1800 case fmt_word:
1801 status |= sim_fpu_to32u (&result32, &wop, round);
1802 result64 = result32;
1803 break;
1804 case fmt_long:
1805 status |= sim_fpu_to64u (&result64, &wop, round);
1806 break;
1807 default:
1808 result64 = 0;
1809 sim_io_error (SD, "Bad switch\n");
1810 }
1811
1812 update_fcsr (cpu, cia, status);
1813 return result64;
1814 }
1815
1816 uint64_t
1817 ps_lower(sim_cpu *cpu,
1818 address_word cia,
1819 uint64_t op)
1820 {
1821 return FP_PS_lower (op);
1822 }
1823
1824 uint64_t
1825 ps_upper(sim_cpu *cpu,
1826 address_word cia,
1827 uint64_t op)
1828 {
1829 return FP_PS_upper(op);
1830 }
1831
1832 uint64_t
1833 pack_ps(sim_cpu *cpu,
1834 address_word cia,
1835 uint64_t op1,
1836 uint64_t op2,
1837 FP_formats fmt)
1838 {
1839 uint64_t result = 0;
1840
1841 /* The registers must specify FPRs valid for operands of type
1842 "fmt". If they are not valid, the result is undefined. */
1843
1844 /* The format type should already have been checked: */
1845 switch (fmt)
1846 {
1847 case fmt_single:
1848 {
1849 sim_fpu wop;
1850 uint32_t res_u, res_l;
1851 sim_fpu_32to (&wop, op1);
1852 sim_fpu_to32 (&res_u, &wop);
1853 sim_fpu_32to (&wop, op2);
1854 sim_fpu_to32 (&res_l, &wop);
1855 result = FP_PS_cat(res_u, res_l);
1856 break;
1857 }
1858 default:
1859 sim_io_error (SD, "Bad switch\n");
1860 }
1861
1862 return result;
1863 }
1864
1865 uint64_t
1866 convert_ps (sim_cpu *cpu,
1867 address_word cia,
1868 int rm,
1869 uint64_t op,
1870 FP_formats from,
1871 FP_formats to)
1872 {
1873 sim_fpu wop_u, wop_l;
1874 sim_fpu_round round = rounding_mode (rm);
1875 sim_fpu_denorm denorm = denorm_mode (cpu);
1876 uint32_t res_u, res_l;
1877 uint64_t result;
1878 sim_fpu_status status_u = 0, status_l = 0;
1879
1880 /* As convert, but used only for paired values (formats PS, PW) */
1881
1882 /* Convert the input to sim_fpu internal format */
1883 switch (from)
1884 {
1885 case fmt_word: /* fmt_pw */
1886 sim_fpu_i32to (&wop_u, (op >> 32) & (unsigned)0xFFFFFFFF, round);
1887 sim_fpu_i32to (&wop_l, op & (unsigned)0xFFFFFFFF, round);
1888 break;
1889 case fmt_ps:
1890 sim_fpu_32to (&wop_u, FP_PS_upper(op));
1891 sim_fpu_32to (&wop_l, FP_PS_lower(op));
1892 break;
1893 default:
1894 sim_io_error (SD, "Bad switch\n");
1895 }
1896
1897 /* Convert sim_fpu format into the output */
1898 switch (to)
1899 {
1900 case fmt_word: /* fmt_pw */
1901 status_u |= sim_fpu_to32u (&res_u, &wop_u, round);
1902 status_l |= sim_fpu_to32u (&res_l, &wop_l, round);
1903 result = (((uint64_t)res_u) << 32) | (uint64_t)res_l;
1904 break;
1905 case fmt_ps:
1906 status_u |= sim_fpu_round_32 (&wop_u, 0, round);
1907 status_l |= sim_fpu_round_32 (&wop_l, 0, round);
1908 sim_fpu_to32 (&res_u, &wop_u);
1909 sim_fpu_to32 (&res_l, &wop_l);
1910 result = FP_PS_cat(res_u, res_l);
1911 break;
1912 default:
1913 result = 0;
1914 sim_io_error (SD, "Bad switch\n");
1915 }
1916
1917 update_fcsr (cpu, cia, status_u | status_l);
1918 return result;
1919 }
1920
1921 static const char *
1922 fpu_format_name (FP_formats fmt)
1923 {
1924 switch (fmt)
1925 {
1926 case fmt_single:
1927 return "single";
1928 case fmt_double:
1929 return "double";
1930 case fmt_word:
1931 return "word";
1932 case fmt_long:
1933 return "long";
1934 case fmt_ps:
1935 return "ps";
1936 case fmt_unknown:
1937 return "<unknown>";
1938 case fmt_uninterpreted:
1939 return "<uninterpreted>";
1940 case fmt_uninterpreted_32:
1941 return "<uninterpreted_32>";
1942 case fmt_uninterpreted_64:
1943 return "<uninterpreted_64>";
1944 default:
1945 return "<format error>";
1946 }
1947 }
1948
1949 #ifdef DEBUG
1950 static const char *
1951 fpu_rounding_mode_name (int rm)
1952 {
1953 switch (rm)
1954 {
1955 case FP_RM_NEAREST:
1956 return "Round";
1957 case FP_RM_TOZERO:
1958 return "Trunc";
1959 case FP_RM_TOPINF:
1960 return "Ceil";
1961 case FP_RM_TOMINF:
1962 return "Floor";
1963 default:
1964 return "<rounding mode error>";
1965 }
1966 }
1967 #endif /* DEBUG */