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