Fix test step-and-next-inline.cc
[binutils-gdb.git] / sim / mips / cp1.c
1 /*> cp1.c <*/
2 /* MIPS Simulator FPU (CoProcessor 1) support.
3 Copyright (C) 2002-2021 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) (((unsigned64)((u) & (unsigned)0xFFFFFFFF) << 32) \
94 | (unsigned64)((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 const char *fpu_format_name (FP_formats fmt);
104 #ifdef DEBUG
105 static const char *fpu_rounding_mode_name (int rm);
106 #endif
107
108 uword64
109 value_fpr (sim_cpu *cpu,
110 address_word cia,
111 int fpr,
112 FP_formats fmt)
113 {
114 uword64 value = 0;
115 int err = 0;
116
117 /* Treat unused register values, as fixed-point 64bit values. */
118 if (fmt == fmt_unknown)
119 {
120 #if 1
121 /* If request to read data as "unknown", then use the current
122 encoding: */
123 fmt = FPR_STATE[fpr];
124 #else
125 fmt = fmt_long;
126 #endif
127 }
128
129 /* For values not yet accessed, set to the desired format. */
130 if (fmt < fmt_uninterpreted)
131 {
132 if (FPR_STATE[fpr] == fmt_uninterpreted)
133 {
134 FPR_STATE[fpr] = fmt;
135 #ifdef DEBUG
136 printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
137 fpu_format_name (fmt));
138 #endif /* DEBUG */
139 }
140 else if (fmt != FPR_STATE[fpr])
141 {
142 sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
143 fpr, fpu_format_name (FPR_STATE[fpr]),
144 fpu_format_name (fmt), pr_addr (cia));
145 FPR_STATE[fpr] = fmt_unknown;
146 }
147 }
148
149 if (FPR_STATE[fpr] == fmt_unknown)
150 {
151 /* Set QNaN value: */
152 switch (fmt)
153 {
154 case fmt_single: value = FPQNaN_SINGLE; break;
155 case fmt_double: value = FPQNaN_DOUBLE; break;
156 case fmt_word: value = FPQNaN_WORD; break;
157 case fmt_long: value = FPQNaN_LONG; break;
158 case fmt_ps: value = FPQNaN_PS; break;
159 default: err = -1; break;
160 }
161 }
162 else if (SizeFGR () == 64)
163 {
164 switch (fmt)
165 {
166 case fmt_uninterpreted_32:
167 case fmt_single:
168 case fmt_word:
169 value = (FGR[fpr] & 0xFFFFFFFF);
170 break;
171
172 case fmt_uninterpreted_64:
173 case fmt_uninterpreted:
174 case fmt_double:
175 case fmt_long:
176 case fmt_ps:
177 value = FGR[fpr];
178 break;
179
180 default:
181 err = -1;
182 break;
183 }
184 }
185 else
186 {
187 switch (fmt)
188 {
189 case fmt_uninterpreted_32:
190 case fmt_single:
191 case fmt_word:
192 value = (FGR[fpr] & 0xFFFFFFFF);
193 break;
194
195 case fmt_uninterpreted_64:
196 case fmt_uninterpreted:
197 case fmt_double:
198 case fmt_long:
199 if ((fpr & 1) == 0)
200 {
201 /* Even register numbers only. */
202 #ifdef DEBUG
203 printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
204 fpr + 1, pr_uword64 ((uword64) FGR[fpr+1]),
205 fpr, pr_uword64 ((uword64) FGR[fpr]));
206 #endif
207 value = ((((uword64) FGR[fpr+1]) << 32)
208 | (FGR[fpr] & 0xFFFFFFFF));
209 }
210 else
211 {
212 SignalException (ReservedInstruction, 0);
213 }
214 break;
215
216 case fmt_ps:
217 SignalException (ReservedInstruction, 0);
218 break;
219
220 default:
221 err = -1;
222 break;
223 }
224 }
225
226 if (err)
227 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
228
229 #ifdef DEBUG
230 printf ("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d\n",
231 fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
232 SizeFGR ());
233 #endif /* DEBUG */
234
235 return (value);
236 }
237
238 void
239 store_fpr (sim_cpu *cpu,
240 address_word cia,
241 int fpr,
242 FP_formats fmt,
243 uword64 value)
244 {
245 int err = 0;
246
247 #ifdef DEBUG
248 printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
249 fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
250 SizeFGR ());
251 #endif /* DEBUG */
252
253 if (SizeFGR () == 64)
254 {
255 switch (fmt)
256 {
257 case fmt_uninterpreted_32:
258 fmt = fmt_uninterpreted;
259 case fmt_single:
260 case fmt_word:
261 if (STATE_VERBOSE_P (SD))
262 sim_io_eprintf (SD,
263 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
264 pr_addr (cia));
265 FGR[fpr] = (((uword64) 0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
266 FPR_STATE[fpr] = fmt;
267 break;
268
269 case fmt_uninterpreted_64:
270 fmt = fmt_uninterpreted;
271 case fmt_uninterpreted:
272 case fmt_double:
273 case fmt_long:
274 case fmt_ps:
275 FGR[fpr] = value;
276 FPR_STATE[fpr] = fmt;
277 break;
278
279 default:
280 FPR_STATE[fpr] = fmt_unknown;
281 err = -1;
282 break;
283 }
284 }
285 else
286 {
287 switch (fmt)
288 {
289 case fmt_uninterpreted_32:
290 fmt = fmt_uninterpreted;
291 case fmt_single:
292 case fmt_word:
293 FGR[fpr] = (value & 0xFFFFFFFF);
294 FPR_STATE[fpr] = fmt;
295 break;
296
297 case fmt_uninterpreted_64:
298 fmt = fmt_uninterpreted;
299 case fmt_uninterpreted:
300 case fmt_double:
301 case fmt_long:
302 if ((fpr & 1) == 0)
303 {
304 /* Even register numbers only. */
305 FGR[fpr+1] = (value >> 32);
306 FGR[fpr] = (value & 0xFFFFFFFF);
307 FPR_STATE[fpr + 1] = fmt;
308 FPR_STATE[fpr] = fmt;
309 }
310 else
311 {
312 FPR_STATE[fpr] = fmt_unknown;
313 FPR_STATE[fpr ^ 1] = fmt_unknown;
314 SignalException (ReservedInstruction, 0);
315 }
316 break;
317
318 case fmt_ps:
319 FPR_STATE[fpr] = fmt_unknown;
320 SignalException (ReservedInstruction, 0);
321 break;
322
323 default:
324 FPR_STATE[fpr] = fmt_unknown;
325 err = -1;
326 break;
327 }
328 }
329
330 if (err)
331 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
332
333 #ifdef DEBUG
334 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
335 fpr, pr_uword64 (FGR[fpr]), fpu_format_name (fmt));
336 #endif /* DEBUG */
337
338 return;
339 }
340
341
342 /* CP1 control/status register access functions. */
343
344 void
345 test_fcsr (sim_cpu *cpu,
346 address_word cia)
347 {
348 unsigned int cause;
349
350 cause = (FCSR & fcsr_CAUSE_mask) >> fcsr_CAUSE_shift;
351 if ((cause & ((FCSR & fcsr_ENABLES_mask) >> fcsr_ENABLES_shift)) != 0
352 || (cause & (1 << UO)))
353 {
354 SignalExceptionFPE();
355 }
356 }
357
358 unsigned_word
359 value_fcr(sim_cpu *cpu,
360 address_word cia,
361 int fcr)
362 {
363 unsigned32 value = 0;
364
365 switch (fcr)
366 {
367 case 0: /* FP Implementation and Revision Register. */
368 value = FCR0;
369 break;
370 case 25: /* FP Condition Codes Register (derived from FCSR). */
371 value = (FCR31 & fcsr_FCC_mask) >> fcsr_FCC_shift;
372 value = (value & 0x1) | (value >> 1); /* Close FCC gap. */
373 break;
374 case 26: /* FP Exceptions Register (derived from FCSR). */
375 value = FCR31 & (fcsr_CAUSE_mask | fcsr_FLAGS_mask);
376 break;
377 case 28: /* FP Enables Register (derived from FCSR). */
378 value = FCR31 & (fcsr_ENABLES_mask | fcsr_RM_mask);
379 if ((FCR31 & fcsr_FS) != 0)
380 value |= fenr_FS;
381 break;
382 case 31: /* FP Control/Status Register (FCSR). */
383 value = FCR31 & ~fcsr_ZERO_mask;
384 break;
385 }
386
387 return (EXTEND32 (value));
388 }
389
390 void
391 store_fcr(sim_cpu *cpu,
392 address_word cia,
393 int fcr,
394 unsigned_word value)
395 {
396 unsigned32 v;
397
398 v = VL4_8(value);
399 switch (fcr)
400 {
401 case 25: /* FP Condition Codes Register (stored into FCSR). */
402 v = (v << 1) | (v & 0x1); /* Adjust for FCC gap. */
403 FCR31 &= ~fcsr_FCC_mask;
404 FCR31 |= ((v << fcsr_FCC_shift) & fcsr_FCC_mask);
405 break;
406 case 26: /* FP Exceptions Register (stored into FCSR). */
407 FCR31 &= ~(fcsr_CAUSE_mask | fcsr_FLAGS_mask);
408 FCR31 |= (v & (fcsr_CAUSE_mask | fcsr_FLAGS_mask));
409 test_fcsr(cpu, cia);
410 break;
411 case 28: /* FP Enables Register (stored into FCSR). */
412 if ((v & fenr_FS) != 0)
413 v |= fcsr_FS;
414 else
415 v &= ~fcsr_FS;
416 FCR31 &= (fcsr_FCC_mask | fcsr_CAUSE_mask | fcsr_FLAGS_mask);
417 FCR31 |= (v & (fcsr_FS | fcsr_ENABLES_mask | fcsr_RM_mask));
418 test_fcsr(cpu, cia);
419 break;
420 case 31: /* FP Control/Status Register (FCSR). */
421 FCR31 = v & ~fcsr_ZERO_mask;
422 test_fcsr(cpu, cia);
423 break;
424 }
425 }
426
427 static void
428 update_fcsr (sim_cpu *cpu,
429 address_word cia,
430 sim_fpu_status status)
431 {
432 FCSR &= ~fcsr_CAUSE_mask;
433
434 if (status != 0)
435 {
436 unsigned int cause = 0;
437
438 /* map between sim_fpu codes and MIPS FCSR */
439 if (status & (sim_fpu_status_invalid_snan
440 | sim_fpu_status_invalid_isi
441 | sim_fpu_status_invalid_idi
442 | sim_fpu_status_invalid_zdz
443 | sim_fpu_status_invalid_imz
444 | sim_fpu_status_invalid_cmp
445 | sim_fpu_status_invalid_sqrt
446 | sim_fpu_status_invalid_cvi))
447 cause |= (1 << IO);
448 if (status & sim_fpu_status_invalid_div0)
449 cause |= (1 << DZ);
450 if (status & sim_fpu_status_overflow)
451 cause |= (1 << OF);
452 if (status & sim_fpu_status_underflow)
453 cause |= (1 << UF);
454 if (status & sim_fpu_status_inexact)
455 cause |= (1 << IR);
456 #if 0 /* Not yet. */
457 /* Implicit clearing of other bits by unimplemented done by callers. */
458 if (status & sim_fpu_status_unimplemented)
459 cause |= (1 << UO);
460 #endif
461
462 FCSR |= (cause << fcsr_CAUSE_shift);
463 test_fcsr (cpu, cia);
464 FCSR |= ((cause & ~(1 << UO)) << fcsr_FLAGS_shift);
465 }
466 return;
467 }
468
469 static sim_fpu_round
470 rounding_mode(int rm)
471 {
472 sim_fpu_round round;
473
474 switch (rm)
475 {
476 case FP_RM_NEAREST:
477 /* Round result to nearest representable value. When two
478 representable values are equally near, round to the value
479 that has a least significant bit of zero (i.e. is even). */
480 round = sim_fpu_round_near;
481 break;
482 case FP_RM_TOZERO:
483 /* Round result to the value closest to, and not greater in
484 magnitude than, the result. */
485 round = sim_fpu_round_zero;
486 break;
487 case FP_RM_TOPINF:
488 /* Round result to the value closest to, and not less than,
489 the result. */
490 round = sim_fpu_round_up;
491 break;
492 case FP_RM_TOMINF:
493 /* Round result to the value closest to, and not greater than,
494 the result. */
495 round = sim_fpu_round_down;
496 break;
497 default:
498 round = 0;
499 fprintf (stderr, "Bad switch\n");
500 abort ();
501 }
502 return round;
503 }
504
505 /* When the FS bit is set, MIPS processors return zero for
506 denormalized results and optionally replace denormalized inputs
507 with zero. When FS is clear, some implementation trap on input
508 and/or output, while other perform the operation in hardware. */
509 static sim_fpu_denorm
510 denorm_mode(sim_cpu *cpu)
511 {
512 sim_fpu_denorm denorm;
513
514 /* XXX: FIXME: Eventually should be CPU model dependent. */
515 if (GETFS())
516 denorm = sim_fpu_denorm_zero;
517 else
518 denorm = 0;
519 return denorm;
520 }
521
522
523 /* Comparison operations. */
524
525 static sim_fpu_status
526 fp_test(unsigned64 op1,
527 unsigned64 op2,
528 FP_formats fmt,
529 int abs,
530 int cond,
531 int *condition)
532 {
533 sim_fpu wop1;
534 sim_fpu wop2;
535 sim_fpu_status status = 0;
536 int less, equal, unordered;
537
538 /* The format type has already been checked: */
539 switch (fmt)
540 {
541 case fmt_single:
542 {
543 sim_fpu_32to (&wop1, op1);
544 sim_fpu_32to (&wop2, op2);
545 break;
546 }
547 case fmt_double:
548 {
549 sim_fpu_64to (&wop1, op1);
550 sim_fpu_64to (&wop2, op2);
551 break;
552 }
553 default:
554 fprintf (stderr, "Bad switch\n");
555 abort ();
556 }
557
558 if (sim_fpu_is_nan (&wop1) || sim_fpu_is_nan (&wop2))
559 {
560 if ((cond & (1 << 3)) ||
561 sim_fpu_is_snan (&wop1) || sim_fpu_is_snan (&wop2))
562 status = sim_fpu_status_invalid_snan;
563 less = 0;
564 equal = 0;
565 unordered = 1;
566 }
567 else
568 {
569 if (abs)
570 {
571 status |= sim_fpu_abs (&wop1, &wop1);
572 status |= sim_fpu_abs (&wop2, &wop2);
573 }
574 equal = sim_fpu_is_eq (&wop1, &wop2);
575 less = !equal && sim_fpu_is_lt (&wop1, &wop2);
576 unordered = 0;
577 }
578 *condition = (((cond & (1 << 2)) && less)
579 || ((cond & (1 << 1)) && equal)
580 || ((cond & (1 << 0)) && unordered));
581 return status;
582 }
583
584 void
585 fp_cmp(sim_cpu *cpu,
586 address_word cia,
587 unsigned64 op1,
588 unsigned64 op2,
589 FP_formats fmt,
590 int abs,
591 int cond,
592 int cc)
593 {
594 sim_fpu_status status = 0;
595
596 /* The format type should already have been checked. The FCSR is
597 updated before the condition codes so that any exceptions will
598 be signalled before the condition codes are changed. */
599 switch (fmt)
600 {
601 case fmt_single:
602 case fmt_double:
603 {
604 int result;
605 status = fp_test(op1, op2, fmt, abs, cond, &result);
606 update_fcsr (cpu, cia, status);
607 SETFCC (cc, result);
608 break;
609 }
610 case fmt_ps:
611 {
612 int result0, result1;
613 status = fp_test(FP_PS_lower (op1), FP_PS_lower (op2), fmt_single,
614 abs, cond, &result0);
615 status |= fp_test(FP_PS_upper (op1), FP_PS_upper (op2), fmt_single,
616 abs, cond, &result1);
617 update_fcsr (cpu, cia, status);
618 SETFCC (cc, result0);
619 SETFCC (cc+1, result1);
620 break;
621 }
622 default:
623 sim_io_eprintf (SD, "Bad switch\n");
624 abort ();
625 }
626 }
627
628
629 /* Basic arithmetic operations. */
630
631 static unsigned64
632 fp_unary(sim_cpu *cpu,
633 address_word cia,
634 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *),
635 unsigned64 op,
636 FP_formats fmt)
637 {
638 sim_fpu wop;
639 sim_fpu ans;
640 sim_fpu_round round = rounding_mode (GETRM());
641 sim_fpu_denorm denorm = denorm_mode (cpu);
642 sim_fpu_status status = 0;
643 unsigned64 result = 0;
644
645 /* The format type has already been checked: */
646 switch (fmt)
647 {
648 case fmt_single:
649 {
650 unsigned32 res;
651 sim_fpu_32to (&wop, op);
652 status |= (*sim_fpu_op) (&ans, &wop);
653 status |= sim_fpu_round_32 (&ans, round, denorm);
654 sim_fpu_to32 (&res, &ans);
655 result = res;
656 break;
657 }
658 case fmt_double:
659 {
660 unsigned64 res;
661 sim_fpu_64to (&wop, op);
662 status |= (*sim_fpu_op) (&ans, &wop);
663 status |= sim_fpu_round_64 (&ans, round, denorm);
664 sim_fpu_to64 (&res, &ans);
665 result = res;
666 break;
667 }
668 case fmt_ps:
669 {
670 int status_u = 0, status_l = 0;
671 unsigned32 res_u, res_l;
672 sim_fpu_32to (&wop, FP_PS_upper(op));
673 status_u |= (*sim_fpu_op) (&ans, &wop);
674 sim_fpu_to32 (&res_u, &ans);
675 sim_fpu_32to (&wop, FP_PS_lower(op));
676 status_l |= (*sim_fpu_op) (&ans, &wop);
677 sim_fpu_to32 (&res_l, &ans);
678 result = FP_PS_cat(res_u, res_l);
679 status = status_u | status_l;
680 break;
681 }
682 default:
683 sim_io_eprintf (SD, "Bad switch\n");
684 abort ();
685 }
686
687 update_fcsr (cpu, cia, status);
688 return result;
689 }
690
691 static unsigned64
692 fp_binary(sim_cpu *cpu,
693 address_word cia,
694 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
695 unsigned64 op1,
696 unsigned64 op2,
697 FP_formats fmt)
698 {
699 sim_fpu wop1;
700 sim_fpu wop2;
701 sim_fpu ans;
702 sim_fpu_round round = rounding_mode (GETRM());
703 sim_fpu_denorm denorm = denorm_mode (cpu);
704 sim_fpu_status status = 0;
705 unsigned64 result = 0;
706
707 /* The format type has already been checked: */
708 switch (fmt)
709 {
710 case fmt_single:
711 {
712 unsigned32 res;
713 sim_fpu_32to (&wop1, op1);
714 sim_fpu_32to (&wop2, op2);
715 status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
716 status |= sim_fpu_round_32 (&ans, round, denorm);
717 sim_fpu_to32 (&res, &ans);
718 result = res;
719 break;
720 }
721 case fmt_double:
722 {
723 unsigned64 res;
724 sim_fpu_64to (&wop1, op1);
725 sim_fpu_64to (&wop2, op2);
726 status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
727 status |= sim_fpu_round_64 (&ans, round, denorm);
728 sim_fpu_to64 (&res, &ans);
729 result = res;
730 break;
731 }
732 case fmt_ps:
733 {
734 int status_u = 0, status_l = 0;
735 unsigned32 res_u, res_l;
736 sim_fpu_32to (&wop1, FP_PS_upper(op1));
737 sim_fpu_32to (&wop2, FP_PS_upper(op2));
738 status_u |= (*sim_fpu_op) (&ans, &wop1, &wop2);
739 sim_fpu_to32 (&res_u, &ans);
740 sim_fpu_32to (&wop1, FP_PS_lower(op1));
741 sim_fpu_32to (&wop2, FP_PS_lower(op2));
742 status_l |= (*sim_fpu_op) (&ans, &wop1, &wop2);
743 sim_fpu_to32 (&res_l, &ans);
744 result = FP_PS_cat(res_u, res_l);
745 status = status_u | status_l;
746 break;
747 }
748 default:
749 sim_io_eprintf (SD, "Bad switch\n");
750 abort ();
751 }
752
753 update_fcsr (cpu, cia, status);
754 return result;
755 }
756
757 /* Common MAC code for single operands (.s or .d), defers setting FCSR. */
758 static sim_fpu_status
759 inner_mac(int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
760 unsigned64 op1,
761 unsigned64 op2,
762 unsigned64 op3,
763 int scale,
764 int negate,
765 FP_formats fmt,
766 sim_fpu_round round,
767 sim_fpu_denorm denorm,
768 unsigned64 *result)
769 {
770 sim_fpu wop1;
771 sim_fpu wop2;
772 sim_fpu ans;
773 sim_fpu_status status = 0;
774 sim_fpu_status op_status;
775 unsigned64 temp = 0;
776
777 switch (fmt)
778 {
779 case fmt_single:
780 {
781 unsigned32 res;
782 sim_fpu_32to (&wop1, op1);
783 sim_fpu_32to (&wop2, op2);
784 status |= sim_fpu_mul (&ans, &wop1, &wop2);
785 if (scale != 0 && sim_fpu_is_number (&ans)) /* number or denorm */
786 ans.normal_exp += scale;
787 status |= sim_fpu_round_32 (&ans, round, denorm);
788 wop1 = ans;
789 op_status = 0;
790 sim_fpu_32to (&wop2, op3);
791 op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
792 op_status |= sim_fpu_round_32 (&ans, round, denorm);
793 status |= op_status;
794 if (negate)
795 {
796 wop1 = ans;
797 op_status = sim_fpu_neg (&ans, &wop1);
798 op_status |= sim_fpu_round_32 (&ans, round, denorm);
799 status |= op_status;
800 }
801 sim_fpu_to32 (&res, &ans);
802 temp = res;
803 break;
804 }
805 case fmt_double:
806 {
807 unsigned64 res;
808 sim_fpu_64to (&wop1, op1);
809 sim_fpu_64to (&wop2, op2);
810 status |= sim_fpu_mul (&ans, &wop1, &wop2);
811 if (scale != 0 && sim_fpu_is_number (&ans)) /* number or denorm */
812 ans.normal_exp += scale;
813 status |= sim_fpu_round_64 (&ans, round, denorm);
814 wop1 = ans;
815 op_status = 0;
816 sim_fpu_64to (&wop2, op3);
817 op_status |= (*sim_fpu_op) (&ans, &wop1, &wop2);
818 op_status |= sim_fpu_round_64 (&ans, round, denorm);
819 status |= op_status;
820 if (negate)
821 {
822 wop1 = ans;
823 op_status = sim_fpu_neg (&ans, &wop1);
824 op_status |= sim_fpu_round_64 (&ans, round, denorm);
825 status |= op_status;
826 }
827 sim_fpu_to64 (&res, &ans);
828 temp = res;
829 break;
830 }
831 default:
832 fprintf (stderr, "Bad switch\n");
833 abort ();
834 }
835 *result = temp;
836 return status;
837 }
838
839 /* Common implementation of madd, nmadd, msub, nmsub that does
840 intermediate rounding per spec. Also used for recip2 and rsqrt2,
841 which are transformed into equivalent nmsub operations. The scale
842 argument is an adjustment to the exponent of the intermediate
843 product op1*op2. It is currently non-zero for rsqrt2 (-1), which
844 requires an effective division by 2. */
845 static unsigned64
846 fp_mac(sim_cpu *cpu,
847 address_word cia,
848 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
849 unsigned64 op1,
850 unsigned64 op2,
851 unsigned64 op3,
852 int scale,
853 int negate,
854 FP_formats fmt)
855 {
856 sim_fpu_round round = rounding_mode (GETRM());
857 sim_fpu_denorm denorm = denorm_mode (cpu);
858 sim_fpu_status status = 0;
859 unsigned64 result = 0;
860
861 /* The format type has already been checked: */
862 switch (fmt)
863 {
864 case fmt_single:
865 case fmt_double:
866 status = inner_mac(sim_fpu_op, op1, op2, op3, scale,
867 negate, fmt, round, denorm, &result);
868 break;
869 case fmt_ps:
870 {
871 int status_u, status_l;
872 unsigned64 result_u, result_l;
873 status_u = inner_mac(sim_fpu_op, FP_PS_upper(op1), FP_PS_upper(op2),
874 FP_PS_upper(op3), scale, negate, fmt_single,
875 round, denorm, &result_u);
876 status_l = inner_mac(sim_fpu_op, FP_PS_lower(op1), FP_PS_lower(op2),
877 FP_PS_lower(op3), scale, negate, fmt_single,
878 round, denorm, &result_l);
879 result = FP_PS_cat(result_u, result_l);
880 status = status_u | status_l;
881 break;
882 }
883 default:
884 sim_io_eprintf (SD, "Bad switch\n");
885 abort ();
886 }
887
888 update_fcsr (cpu, cia, status);
889 return result;
890 }
891
892 /* Common rsqrt code for single operands (.s or .d), intermediate rounding. */
893 static sim_fpu_status
894 inner_rsqrt(unsigned64 op1,
895 FP_formats fmt,
896 sim_fpu_round round,
897 sim_fpu_denorm denorm,
898 unsigned64 *result)
899 {
900 sim_fpu wop1;
901 sim_fpu ans;
902 sim_fpu_status status = 0;
903 sim_fpu_status op_status;
904 unsigned64 temp = 0;
905
906 switch (fmt)
907 {
908 case fmt_single:
909 {
910 unsigned32 res;
911 sim_fpu_32to (&wop1, op1);
912 status |= sim_fpu_sqrt (&ans, &wop1);
913 status |= sim_fpu_round_32 (&ans, status, round);
914 wop1 = ans;
915 op_status = sim_fpu_inv (&ans, &wop1);
916 op_status |= sim_fpu_round_32 (&ans, round, denorm);
917 sim_fpu_to32 (&res, &ans);
918 temp = res;
919 status |= op_status;
920 break;
921 }
922 case fmt_double:
923 {
924 unsigned64 res;
925 sim_fpu_64to (&wop1, op1);
926 status |= sim_fpu_sqrt (&ans, &wop1);
927 status |= sim_fpu_round_64 (&ans, round, denorm);
928 wop1 = ans;
929 op_status = sim_fpu_inv (&ans, &wop1);
930 op_status |= sim_fpu_round_64 (&ans, round, denorm);
931 sim_fpu_to64 (&res, &ans);
932 temp = res;
933 status |= op_status;
934 break;
935 }
936 default:
937 fprintf (stderr, "Bad switch\n");
938 abort ();
939 }
940 *result = temp;
941 return status;
942 }
943
944 static unsigned64
945 fp_inv_sqrt(sim_cpu *cpu,
946 address_word cia,
947 unsigned64 op1,
948 FP_formats fmt)
949 {
950 sim_fpu_round round = rounding_mode (GETRM());
951 sim_fpu_round denorm = denorm_mode (cpu);
952 sim_fpu_status status = 0;
953 unsigned64 result = 0;
954
955 /* The format type has already been checked: */
956 switch (fmt)
957 {
958 case fmt_single:
959 case fmt_double:
960 status = inner_rsqrt (op1, fmt, round, denorm, &result);
961 break;
962 case fmt_ps:
963 {
964 int status_u, status_l;
965 unsigned64 result_u, result_l;
966 status_u = inner_rsqrt (FP_PS_upper(op1), fmt_single, round, denorm,
967 &result_u);
968 status_l = inner_rsqrt (FP_PS_lower(op1), fmt_single, round, denorm,
969 &result_l);
970 result = FP_PS_cat(result_u, result_l);
971 status = status_u | status_l;
972 break;
973 }
974 default:
975 sim_io_eprintf (SD, "Bad switch\n");
976 abort ();
977 }
978
979 update_fcsr (cpu, cia, status);
980 return result;
981 }
982
983
984 unsigned64
985 fp_abs(sim_cpu *cpu,
986 address_word cia,
987 unsigned64 op,
988 FP_formats fmt)
989 {
990 return fp_unary(cpu, cia, &sim_fpu_abs, op, fmt);
991 }
992
993 unsigned64
994 fp_neg(sim_cpu *cpu,
995 address_word cia,
996 unsigned64 op,
997 FP_formats fmt)
998 {
999 return fp_unary(cpu, cia, &sim_fpu_neg, op, fmt);
1000 }
1001
1002 unsigned64
1003 fp_add(sim_cpu *cpu,
1004 address_word cia,
1005 unsigned64 op1,
1006 unsigned64 op2,
1007 FP_formats fmt)
1008 {
1009 return fp_binary(cpu, cia, &sim_fpu_add, op1, op2, fmt);
1010 }
1011
1012 unsigned64
1013 fp_sub(sim_cpu *cpu,
1014 address_word cia,
1015 unsigned64 op1,
1016 unsigned64 op2,
1017 FP_formats fmt)
1018 {
1019 return fp_binary(cpu, cia, &sim_fpu_sub, op1, op2, fmt);
1020 }
1021
1022 unsigned64
1023 fp_mul(sim_cpu *cpu,
1024 address_word cia,
1025 unsigned64 op1,
1026 unsigned64 op2,
1027 FP_formats fmt)
1028 {
1029 return fp_binary(cpu, cia, &sim_fpu_mul, op1, op2, fmt);
1030 }
1031
1032 unsigned64
1033 fp_div(sim_cpu *cpu,
1034 address_word cia,
1035 unsigned64 op1,
1036 unsigned64 op2,
1037 FP_formats fmt)
1038 {
1039 return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt);
1040 }
1041
1042 unsigned64
1043 fp_recip(sim_cpu *cpu,
1044 address_word cia,
1045 unsigned64 op,
1046 FP_formats fmt)
1047 {
1048 return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt);
1049 }
1050
1051 unsigned64
1052 fp_sqrt(sim_cpu *cpu,
1053 address_word cia,
1054 unsigned64 op,
1055 FP_formats fmt)
1056 {
1057 return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
1058 }
1059
1060 unsigned64
1061 fp_rsqrt(sim_cpu *cpu,
1062 address_word cia,
1063 unsigned64 op,
1064 FP_formats fmt)
1065 {
1066 return fp_inv_sqrt(cpu, cia, op, fmt);
1067 }
1068
1069 unsigned64
1070 fp_madd(sim_cpu *cpu,
1071 address_word cia,
1072 unsigned64 op1,
1073 unsigned64 op2,
1074 unsigned64 op3,
1075 FP_formats fmt)
1076 {
1077 return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 0, fmt);
1078 }
1079
1080 unsigned64
1081 fp_msub(sim_cpu *cpu,
1082 address_word cia,
1083 unsigned64 op1,
1084 unsigned64 op2,
1085 unsigned64 op3,
1086 FP_formats fmt)
1087 {
1088 return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 0, fmt);
1089 }
1090
1091 unsigned64
1092 fp_nmadd(sim_cpu *cpu,
1093 address_word cia,
1094 unsigned64 op1,
1095 unsigned64 op2,
1096 unsigned64 op3,
1097 FP_formats fmt)
1098 {
1099 return fp_mac(cpu, cia, &sim_fpu_add, op1, op2, op3, 0, 1, fmt);
1100 }
1101
1102 unsigned64
1103 fp_nmsub(sim_cpu *cpu,
1104 address_word cia,
1105 unsigned64 op1,
1106 unsigned64 op2,
1107 unsigned64 op3,
1108 FP_formats fmt)
1109 {
1110 return fp_mac(cpu, cia, &sim_fpu_sub, op1, op2, op3, 0, 1, fmt);
1111 }
1112
1113
1114 /* MIPS-3D ASE operations. */
1115
1116 /* Variant of fp_binary for *r.ps MIPS-3D operations. */
1117 static unsigned64
1118 fp_binary_r(sim_cpu *cpu,
1119 address_word cia,
1120 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
1121 unsigned64 op1,
1122 unsigned64 op2)
1123 {
1124 sim_fpu wop1;
1125 sim_fpu wop2;
1126 sim_fpu ans;
1127 sim_fpu_round round = rounding_mode (GETRM ());
1128 sim_fpu_denorm denorm = denorm_mode (cpu);
1129 sim_fpu_status status_u, status_l;
1130 unsigned64 result;
1131 unsigned32 res_u, res_l;
1132
1133 /* The format must be fmt_ps. */
1134 status_u = 0;
1135 sim_fpu_32to (&wop1, FP_PS_upper (op1));
1136 sim_fpu_32to (&wop2, FP_PS_lower (op1));
1137 status_u |= (*sim_fpu_op) (&ans, &wop1, &wop2);
1138 status_u |= sim_fpu_round_32 (&ans, round, denorm);
1139 sim_fpu_to32 (&res_u, &ans);
1140 status_l = 0;
1141 sim_fpu_32to (&wop1, FP_PS_upper (op2));
1142 sim_fpu_32to (&wop2, FP_PS_lower (op2));
1143 status_l |= (*sim_fpu_op) (&ans, &wop1, &wop2);
1144 status_l |= sim_fpu_round_32 (&ans, round, denorm);
1145 sim_fpu_to32 (&res_l, &ans);
1146 result = FP_PS_cat (res_u, res_l);
1147
1148 update_fcsr (cpu, cia, status_u | status_l);
1149 return result;
1150 }
1151
1152 unsigned64
1153 fp_add_r(sim_cpu *cpu,
1154 address_word cia,
1155 unsigned64 op1,
1156 unsigned64 op2,
1157 FP_formats fmt)
1158 {
1159 return fp_binary_r (cpu, cia, &sim_fpu_add, op1, op2);
1160 }
1161
1162 unsigned64
1163 fp_mul_r(sim_cpu *cpu,
1164 address_word cia,
1165 unsigned64 op1,
1166 unsigned64 op2,
1167 FP_formats fmt)
1168 {
1169 return fp_binary_r (cpu, cia, &sim_fpu_mul, op1, op2);
1170 }
1171
1172 #define NR_FRAC_GUARD (60)
1173 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
1174
1175 static int
1176 fpu_inv1(sim_fpu *f, const sim_fpu *l)
1177 {
1178 static const sim_fpu sim_fpu_one = {
1179 sim_fpu_class_number, 0, IMPLICIT_1, 0
1180 };
1181 int status = 0;
1182 sim_fpu t;
1183
1184 if (sim_fpu_is_zero (l))
1185 {
1186 *f = sim_fpu_maxfp;
1187 f->sign = l->sign;
1188 return sim_fpu_status_invalid_div0;
1189 }
1190 if (sim_fpu_is_infinity (l))
1191 {
1192 *f = sim_fpu_zero;
1193 f->sign = l->sign;
1194 return status;
1195 }
1196 status |= sim_fpu_div (f, &sim_fpu_one, l);
1197 return status;
1198 }
1199
1200 static int
1201 fpu_inv1_32(sim_fpu *f, const sim_fpu *l)
1202 {
1203 if (sim_fpu_is_zero (l))
1204 {
1205 *f = sim_fpu_max32;
1206 f->sign = l->sign;
1207 return sim_fpu_status_invalid_div0;
1208 }
1209 return fpu_inv1 (f, l);
1210 }
1211
1212 static int
1213 fpu_inv1_64(sim_fpu *f, const sim_fpu *l)
1214 {
1215 if (sim_fpu_is_zero (l))
1216 {
1217 *f = sim_fpu_max64;
1218 f->sign = l->sign;
1219 return sim_fpu_status_invalid_div0;
1220 }
1221 return fpu_inv1 (f, l);
1222 }
1223
1224 unsigned64
1225 fp_recip1(sim_cpu *cpu,
1226 address_word cia,
1227 unsigned64 op,
1228 FP_formats fmt)
1229 {
1230 switch (fmt)
1231 {
1232 case fmt_single:
1233 case fmt_ps:
1234 return fp_unary (cpu, cia, &fpu_inv1_32, op, fmt);
1235 case fmt_double:
1236 return fp_unary (cpu, cia, &fpu_inv1_64, op, fmt);
1237 }
1238 return 0;
1239 }
1240
1241 unsigned64
1242 fp_recip2(sim_cpu *cpu,
1243 address_word cia,
1244 unsigned64 op1,
1245 unsigned64 op2,
1246 FP_formats fmt)
1247 {
1248 static const unsigned64 one_single = UNSIGNED64 (0x3F800000);
1249 static const unsigned64 one_double = UNSIGNED64 (0x3FF0000000000000);
1250 static const unsigned64 one_ps = (UNSIGNED64 (0x3F800000) << 32 | UNSIGNED64 (0x3F800000));
1251 unsigned64 one;
1252
1253 /* Implemented as nmsub fd, 1, fs, ft. */
1254 switch (fmt)
1255 {
1256 case fmt_single: one = one_single; break;
1257 case fmt_double: one = one_double; break;
1258 case fmt_ps: one = one_ps; break;
1259 default: one = 0; abort ();
1260 }
1261 return fp_mac (cpu, cia, &sim_fpu_sub, op1, op2, one, 0, 1, fmt);
1262 }
1263
1264 static int
1265 fpu_inv_sqrt1(sim_fpu *f, const sim_fpu *l)
1266 {
1267 static const sim_fpu sim_fpu_one = {
1268 sim_fpu_class_number, 0, IMPLICIT_1, 0
1269 };
1270 int status = 0;
1271 sim_fpu t;
1272
1273 if (sim_fpu_is_zero (l))
1274 {
1275 *f = sim_fpu_maxfp;
1276 f->sign = l->sign;
1277 return sim_fpu_status_invalid_div0;
1278 }
1279 if (sim_fpu_is_infinity (l))
1280 {
1281 if (!l->sign)
1282 {
1283 f->class = sim_fpu_class_zero;
1284 f->sign = 0;
1285 }
1286 else
1287 {
1288 *f = sim_fpu_qnan;
1289 status = sim_fpu_status_invalid_sqrt;
1290 }
1291 return status;
1292 }
1293 status |= sim_fpu_sqrt (&t, l);
1294 status |= sim_fpu_div (f, &sim_fpu_one, &t);
1295 return status;
1296 }
1297
1298 static int
1299 fpu_inv_sqrt1_32(sim_fpu *f, const sim_fpu *l)
1300 {
1301 if (sim_fpu_is_zero (l))
1302 {
1303 *f = sim_fpu_max32;
1304 f->sign = l->sign;
1305 return sim_fpu_status_invalid_div0;
1306 }
1307 return fpu_inv_sqrt1 (f, l);
1308 }
1309
1310 static int
1311 fpu_inv_sqrt1_64(sim_fpu *f, const sim_fpu *l)
1312 {
1313 if (sim_fpu_is_zero (l))
1314 {
1315 *f = sim_fpu_max64;
1316 f->sign = l->sign;
1317 return sim_fpu_status_invalid_div0;
1318 }
1319 return fpu_inv_sqrt1 (f, l);
1320 }
1321
1322 unsigned64
1323 fp_rsqrt1(sim_cpu *cpu,
1324 address_word cia,
1325 unsigned64 op,
1326 FP_formats fmt)
1327 {
1328 switch (fmt)
1329 {
1330 case fmt_single:
1331 case fmt_ps:
1332 return fp_unary (cpu, cia, &fpu_inv_sqrt1_32, op, fmt);
1333 case fmt_double:
1334 return fp_unary (cpu, cia, &fpu_inv_sqrt1_64, op, fmt);
1335 }
1336 return 0;
1337 }
1338
1339 unsigned64
1340 fp_rsqrt2(sim_cpu *cpu,
1341 address_word cia,
1342 unsigned64 op1,
1343 unsigned64 op2,
1344 FP_formats fmt)
1345 {
1346 static const unsigned64 half_single = UNSIGNED64 (0x3F000000);
1347 static const unsigned64 half_double = UNSIGNED64 (0x3FE0000000000000);
1348 static const unsigned64 half_ps = (UNSIGNED64 (0x3F000000) << 32 | UNSIGNED64 (0x3F000000));
1349 unsigned64 half;
1350
1351 /* Implemented as (nmsub fd, 0.5, fs, ft)/2, where the divide is
1352 done by scaling the exponent during multiply. */
1353 switch (fmt)
1354 {
1355 case fmt_single: half = half_single; break;
1356 case fmt_double: half = half_double; break;
1357 case fmt_ps: half = half_ps; break;
1358 default: half = 0; abort ();
1359 }
1360 return fp_mac (cpu, cia, &sim_fpu_sub, op1, op2, half, -1, 1, fmt);
1361 }
1362
1363
1364 /* Conversion operations. */
1365
1366 uword64
1367 convert (sim_cpu *cpu,
1368 address_word cia,
1369 int rm,
1370 uword64 op,
1371 FP_formats from,
1372 FP_formats to)
1373 {
1374 sim_fpu wop;
1375 sim_fpu_round round = rounding_mode (rm);
1376 sim_fpu_denorm denorm = denorm_mode (cpu);
1377 unsigned32 result32;
1378 unsigned64 result64;
1379 sim_fpu_status status = 0;
1380
1381 /* Convert the input to sim_fpu internal format */
1382 switch (from)
1383 {
1384 case fmt_double:
1385 sim_fpu_64to (&wop, op);
1386 break;
1387 case fmt_single:
1388 sim_fpu_32to (&wop, op);
1389 break;
1390 case fmt_word:
1391 status = sim_fpu_i32to (&wop, op, round);
1392 break;
1393 case fmt_long:
1394 status = sim_fpu_i64to (&wop, op, round);
1395 break;
1396 default:
1397 sim_io_eprintf (SD, "Bad switch\n");
1398 abort ();
1399 }
1400
1401 /* Convert sim_fpu format into the output */
1402 /* The value WOP is converted to the destination format, rounding
1403 using mode RM. When the destination is a fixed-point format, then
1404 a source value of Infinity, NaN or one which would round to an
1405 integer outside the fixed point range then an IEEE Invalid Operation
1406 condition is raised. Not used if destination format is PS. */
1407 switch (to)
1408 {
1409 case fmt_single:
1410 status |= sim_fpu_round_32 (&wop, round, denorm);
1411 /* For a NaN, normalize mantissa bits (cvt.s.d can't preserve them) */
1412 if (sim_fpu_is_qnan (&wop))
1413 wop = sim_fpu_qnan;
1414 sim_fpu_to32 (&result32, &wop);
1415 result64 = result32;
1416 break;
1417 case fmt_double:
1418 status |= sim_fpu_round_64 (&wop, round, denorm);
1419 /* For a NaN, normalize mantissa bits (make cvt.d.s consistent) */
1420 if (sim_fpu_is_qnan (&wop))
1421 wop = sim_fpu_qnan;
1422 sim_fpu_to64 (&result64, &wop);
1423 break;
1424 case fmt_word:
1425 status |= sim_fpu_to32i (&result32, &wop, round);
1426 result64 = result32;
1427 break;
1428 case fmt_long:
1429 status |= sim_fpu_to64i (&result64, &wop, round);
1430 break;
1431 default:
1432 result64 = 0;
1433 sim_io_eprintf (SD, "Bad switch\n");
1434 abort ();
1435 }
1436
1437 update_fcsr (cpu, cia, status);
1438 return result64;
1439 }
1440
1441 unsigned64
1442 ps_lower(sim_cpu *cpu,
1443 address_word cia,
1444 unsigned64 op)
1445 {
1446 return FP_PS_lower (op);
1447 }
1448
1449 unsigned64
1450 ps_upper(sim_cpu *cpu,
1451 address_word cia,
1452 unsigned64 op)
1453 {
1454 return FP_PS_upper(op);
1455 }
1456
1457 unsigned64
1458 pack_ps(sim_cpu *cpu,
1459 address_word cia,
1460 unsigned64 op1,
1461 unsigned64 op2,
1462 FP_formats fmt)
1463 {
1464 unsigned64 result = 0;
1465
1466 /* The registers must specify FPRs valid for operands of type
1467 "fmt". If they are not valid, the result is undefined. */
1468
1469 /* The format type should already have been checked: */
1470 switch (fmt)
1471 {
1472 case fmt_single:
1473 {
1474 sim_fpu wop;
1475 unsigned32 res_u, res_l;
1476 sim_fpu_32to (&wop, op1);
1477 sim_fpu_to32 (&res_u, &wop);
1478 sim_fpu_32to (&wop, op2);
1479 sim_fpu_to32 (&res_l, &wop);
1480 result = FP_PS_cat(res_u, res_l);
1481 break;
1482 }
1483 default:
1484 sim_io_eprintf (SD, "Bad switch\n");
1485 abort ();
1486 }
1487
1488 return result;
1489 }
1490
1491 unsigned64
1492 convert_ps (sim_cpu *cpu,
1493 address_word cia,
1494 int rm,
1495 unsigned64 op,
1496 FP_formats from,
1497 FP_formats to)
1498 {
1499 sim_fpu wop_u, wop_l;
1500 sim_fpu_round round = rounding_mode (rm);
1501 sim_fpu_denorm denorm = denorm_mode (cpu);
1502 unsigned32 res_u, res_l;
1503 unsigned64 result;
1504 sim_fpu_status status_u = 0, status_l = 0;
1505
1506 /* As convert, but used only for paired values (formats PS, PW) */
1507
1508 /* Convert the input to sim_fpu internal format */
1509 switch (from)
1510 {
1511 case fmt_word: /* fmt_pw */
1512 sim_fpu_i32to (&wop_u, (op >> 32) & (unsigned)0xFFFFFFFF, round);
1513 sim_fpu_i32to (&wop_l, op & (unsigned)0xFFFFFFFF, round);
1514 break;
1515 case fmt_ps:
1516 sim_fpu_32to (&wop_u, FP_PS_upper(op));
1517 sim_fpu_32to (&wop_l, FP_PS_lower(op));
1518 break;
1519 default:
1520 sim_io_eprintf (SD, "Bad switch\n");
1521 abort ();
1522 }
1523
1524 /* Convert sim_fpu format into the output */
1525 switch (to)
1526 {
1527 case fmt_word: /* fmt_pw */
1528 status_u |= sim_fpu_to32i (&res_u, &wop_u, round);
1529 status_l |= sim_fpu_to32i (&res_l, &wop_l, round);
1530 result = (((unsigned64)res_u) << 32) | (unsigned64)res_l;
1531 break;
1532 case fmt_ps:
1533 status_u |= sim_fpu_round_32 (&wop_u, 0, round);
1534 status_l |= sim_fpu_round_32 (&wop_l, 0, round);
1535 sim_fpu_to32 (&res_u, &wop_u);
1536 sim_fpu_to32 (&res_l, &wop_l);
1537 result = FP_PS_cat(res_u, res_l);
1538 break;
1539 default:
1540 result = 0;
1541 sim_io_eprintf (SD, "Bad switch\n");
1542 abort ();
1543 }
1544
1545 update_fcsr (cpu, cia, status_u | status_l);
1546 return result;
1547 }
1548
1549 static const char *
1550 fpu_format_name (FP_formats fmt)
1551 {
1552 switch (fmt)
1553 {
1554 case fmt_single:
1555 return "single";
1556 case fmt_double:
1557 return "double";
1558 case fmt_word:
1559 return "word";
1560 case fmt_long:
1561 return "long";
1562 case fmt_ps:
1563 return "ps";
1564 case fmt_unknown:
1565 return "<unknown>";
1566 case fmt_uninterpreted:
1567 return "<uninterpreted>";
1568 case fmt_uninterpreted_32:
1569 return "<uninterpreted_32>";
1570 case fmt_uninterpreted_64:
1571 return "<uninterpreted_64>";
1572 default:
1573 return "<format error>";
1574 }
1575 }
1576
1577 #ifdef DEBUG
1578 static const char *
1579 fpu_rounding_mode_name (int rm)
1580 {
1581 switch (rm)
1582 {
1583 case FP_RM_NEAREST:
1584 return "Round";
1585 case FP_RM_TOZERO:
1586 return "Trunc";
1587 case FP_RM_TOPINF:
1588 return "Ceil";
1589 case FP_RM_TOMINF:
1590 return "Floor";
1591 default:
1592 return "<rounding mode error>";
1593 }
1594 }
1595 #endif /* DEBUG */