OSDN Git Service

Update the copyright notice of some of the files I missed
[pf3gnuchains/pf3gnuchains3x.git] / sim / mips / cp1.c
1 /*> cp1.c <*/
2 /* MIPS Simulator FPU (CoProcessor 1) support.
3    Copyright (C) 2002, 2007, 2008, 2009 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 */