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