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