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