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