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