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