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