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