daily update
[deliverable/binutils-gdb.git] / sim / mips / cp1.c
CommitLineData
487f79b7 1/*> cp1.c <*/
d3eb724f
CD
2/* MIPS Simulator FPU (CoProcessor 1) support.
3 Copyright (C) 2002 Free Software Foundation, Inc.
4 Originally created by Cygnus Solutions, modified substially
5 by Broadcom Corporation (SiByte).
6
7This file is part of GDB, the GNU debugger.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License along
20with this program; if not, write to the Free Software Foundation, Inc.,
2159 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23/* XXX: The following notice should be removed as soon as is practical: */
487f79b7
CD
24/* Floating Point Support for gdb MIPS simulators
25
26 This file is part of the MIPS sim
27
28 THIS SOFTWARE IS NOT COPYRIGHTED
d3eb724f 29 (by Cygnus.)
487f79b7
CD
30
31 Cygnus offers the following for use in the public domain. Cygnus
32 makes no warranty with regard to the software or it's performance
33 and the user accepts the software "AS IS" with all faults.
34
35 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
36 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
38
39 (Originally, this code was in interp.c)
40*/
41
42#include "sim-main.h"
43#include "sim-fpu.h"
44
45/* Within cp1.c we refer to sim_cpu directly. */
46#define CPU cpu
18d8a52d 47#define SD CPU_STATE(cpu)
487f79b7
CD
48
49/*-- FPU support routines ---------------------------------------------------*/
50
51/* Numbers are held in normalized form. The SINGLE and DOUBLE binary
bad673a9
CD
52 formats conform to ANSI/IEEE Std 754-1985.
53
54 SINGLE precision floating:
55 seeeeeeeefffffffffffffffffffffff
56 s = 1bit = sign
57 e = 8bits = exponent
58 f = 23bits = fraction
59
60 SINGLE precision fixed:
61 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
62 s = 1bit = sign
63 i = 31bits = integer
64
65 DOUBLE precision floating:
66 seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
67 s = 1bit = sign
68 e = 11bits = exponent
69 f = 52bits = fraction
70
71 DOUBLE precision fixed:
72 siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
73 s = 1bit = sign
74 i = 63bits = integer
487f79b7
CD
75 */
76
37d146fa 77/* Explicit QNaN values used when value required: */
487f79b7
CD
78#define FPQNaN_SINGLE (0x7FBFFFFF)
79#define FPQNaN_WORD (0x7FFFFFFF)
bad673a9
CD
80#define FPQNaN_DOUBLE (UNSIGNED64 (0x7FF7FFFFFFFFFFFF))
81#define FPQNaN_LONG (UNSIGNED64 (0x7FFFFFFFFFFFFFFF))
487f79b7 82
07892c0b
CD
83static const char *fpu_format_name (FP_formats fmt);
84#ifdef DEBUG
85static const char *fpu_rounding_mode_name (int rm);
86#endif
487f79b7
CD
87
88uword64
18d8a52d 89value_fpr (sim_cpu *cpu,
487f79b7
CD
90 address_word cia,
91 int fpr,
92 FP_formats fmt)
93{
94 uword64 value = 0;
95 int err = 0;
96
37d146fa 97 /* Treat unused register values, as fixed-point 64bit values: */
487f79b7 98 if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
37d146fa 99 {
487f79b7 100#if 1
37d146fa
CD
101 /* If request to read data as "uninterpreted", then use the current
102 encoding: */
103 fmt = FPR_STATE[fpr];
487f79b7 104#else
37d146fa 105 fmt = fmt_long;
487f79b7 106#endif
37d146fa 107 }
487f79b7 108
37d146fa
CD
109 /* For values not yet accessed, set to the desired format: */
110 if (FPR_STATE[fpr] == fmt_uninterpreted)
111 {
112 FPR_STATE[fpr] = fmt;
487f79b7 113#ifdef DEBUG
37d146fa
CD
114 printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,
115 fpu_format_name (fmt));
487f79b7 116#endif /* DEBUG */
487f79b7 117 }
37d146fa
CD
118 if (fmt != FPR_STATE[fpr])
119 {
18d8a52d 120 sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",
37d146fa
CD
121 fpr, fpu_format_name (FPR_STATE[fpr]),
122 fpu_format_name (fmt), pr_addr (cia));
123 FPR_STATE[fpr] = fmt_unknown;
124 }
487f79b7 125
37d146fa
CD
126 if (FPR_STATE[fpr] == fmt_unknown)
127 {
128 /* Set QNaN value: */
129 switch (fmt)
130 {
131 case fmt_single:
132 value = FPQNaN_SINGLE;
133 break;
134
135 case fmt_double:
136 value = FPQNaN_DOUBLE;
137 break;
138
139 case fmt_word:
140 value = FPQNaN_WORD;
141 break;
142
143 case fmt_long:
144 value = FPQNaN_LONG;
145 break;
146
147 default:
148 err = -1;
149 break;
150 }
151 }
152 else if (SizeFGR () == 64)
153 {
154 switch (fmt)
155 {
156 case fmt_single:
157 case fmt_word:
158 value = (FGR[fpr] & 0xFFFFFFFF);
159 break;
160
161 case fmt_uninterpreted:
162 case fmt_double:
163 case fmt_long:
164 value = FGR[fpr];
165 break;
166
167 default:
168 err = -1;
169 break;
170 }
171 }
172 else
173 {
174 switch (fmt)
175 {
176 case fmt_single:
177 case fmt_word:
178 value = (FGR[fpr] & 0xFFFFFFFF);
179 break;
180
181 case fmt_uninterpreted:
182 case fmt_double:
183 case fmt_long:
184 if ((fpr & 1) == 0)
185 {
186 /* even registers only */
487f79b7 187#ifdef DEBUG
37d146fa
CD
188 printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",
189 fpr + 1, pr_uword64 ((uword64) FGR[fpr+1]),
190 fpr, pr_uword64 ((uword64) FGR[fpr]));
487f79b7 191#endif
37d146fa
CD
192 value = ((((uword64) FGR[fpr+1]) << 32)
193 | (FGR[fpr] & 0xFFFFFFFF));
194 }
195 else
196 {
197 SignalException (ReservedInstruction, 0);
198 }
199 break;
200
e80fc152 201 default:
37d146fa
CD
202 err = -1;
203 break;
204 }
487f79b7 205 }
487f79b7
CD
206
207 if (err)
37d146fa 208 SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");
487f79b7
CD
209
210#ifdef DEBUG
37d146fa
CD
211 printf ("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d\n",
212 fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
213 SizeFGR ());
487f79b7
CD
214#endif /* DEBUG */
215
37d146fa 216 return (value);
487f79b7
CD
217}
218
219void
18d8a52d 220store_fpr (sim_cpu *cpu,
487f79b7
CD
221 address_word cia,
222 int fpr,
223 FP_formats fmt,
224 uword64 value)
225{
226 int err = 0;
227
228#ifdef DEBUG
37d146fa
CD
229 printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",
230 fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),
231 SizeFGR ());
487f79b7
CD
232#endif /* DEBUG */
233
37d146fa
CD
234 if (SizeFGR () == 64)
235 {
236 switch (fmt)
237 {
238 case fmt_uninterpreted_32:
239 fmt = fmt_uninterpreted;
e80fc152
CD
240 case fmt_single:
241 case fmt_word:
37d146fa
CD
242 if (STATE_VERBOSE_P (SD))
243 sim_io_eprintf (SD,
244 "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",
245 pr_addr (cia));
246 FGR[fpr] = (((uword64) 0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
247 FPR_STATE[fpr] = fmt;
248 break;
249
250 case fmt_uninterpreted_64:
251 fmt = fmt_uninterpreted;
252 case fmt_uninterpreted:
e80fc152
CD
253 case fmt_double:
254 case fmt_long:
37d146fa
CD
255 FGR[fpr] = value;
256 FPR_STATE[fpr] = fmt;
257 break;
258
e80fc152 259 default:
37d146fa
CD
260 FPR_STATE[fpr] = fmt_unknown;
261 err = -1;
262 break;
263 }
487f79b7 264 }
37d146fa
CD
265 else
266 {
267 switch (fmt)
268 {
269 case fmt_uninterpreted_32:
270 fmt = fmt_uninterpreted;
e80fc152
CD
271 case fmt_single:
272 case fmt_word:
487f79b7 273 FGR[fpr] = (value & 0xFFFFFFFF);
487f79b7 274 FPR_STATE[fpr] = fmt;
37d146fa
CD
275 break;
276
277 case fmt_uninterpreted_64:
278 fmt = fmt_uninterpreted;
279 case fmt_uninterpreted:
e80fc152
CD
280 case fmt_double:
281 case fmt_long:
37d146fa
CD
282 if ((fpr & 1) == 0)
283 {
284 /* even register number only */
285 FGR[fpr+1] = (value >> 32);
286 FGR[fpr] = (value & 0xFFFFFFFF);
287 FPR_STATE[fpr + 1] = fmt;
288 FPR_STATE[fpr] = fmt;
289 }
290 else
291 {
292 FPR_STATE[fpr] = fmt_unknown;
293 FPR_STATE[fpr + 1] = fmt_unknown;
294 SignalException (ReservedInstruction, 0);
295 }
296 break;
297
e80fc152 298 default:
487f79b7 299 FPR_STATE[fpr] = fmt_unknown;
37d146fa
CD
300 err = -1;
301 break;
487f79b7 302 }
487f79b7 303 }
487f79b7
CD
304
305 if (err)
37d146fa 306 SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");
487f79b7
CD
307
308#ifdef DEBUG
37d146fa
CD
309 printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",
310 fpr, pr_uword64 (FGR[fpr]), fpu_format_name (fmt));
487f79b7
CD
311#endif /* DEBUG */
312
313 return;
314}
315
316int
37d146fa 317NaN (op, fmt)
487f79b7 318 uword64 op;
37d146fa 319 FP_formats fmt;
487f79b7
CD
320{
321 int boolean = 0;
37d146fa 322 switch (fmt)
487f79b7 323 {
37d146fa
CD
324 case fmt_single:
325 case fmt_word:
326 {
327 sim_fpu wop;
328 sim_fpu_32to (&wop, op);
329 boolean = sim_fpu_is_nan (&wop);
330 break;
331 }
332 case fmt_double:
333 case fmt_long:
334 {
335 sim_fpu wop;
336 sim_fpu_64to (&wop, op);
337 boolean = sim_fpu_is_nan (&wop);
338 break;
339 }
340 default:
341 fprintf (stderr, "Bad switch\n");
342 abort ();
487f79b7 343 }
487f79b7
CD
344
345#ifdef DEBUG
37d146fa
CD
346 printf ("DBG: NaN: returning %d for 0x%s (format = %s)\n",
347 boolean, pr_addr (op), fpu_format_name (fmt));
487f79b7
CD
348#endif /* DEBUG */
349
37d146fa 350 return (boolean);
487f79b7
CD
351}
352
487f79b7 353int
37d146fa 354Less (op1, op2, fmt)
487f79b7
CD
355 uword64 op1;
356 uword64 op2;
37d146fa 357 FP_formats fmt;
487f79b7
CD
358{
359 int boolean = 0;
360
361 /* Argument checking already performed by the FPCOMPARE code */
362
363#ifdef DEBUG
37d146fa
CD
364 printf ("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",
365 fpu_format_name (fmt), pr_addr (op1), pr_addr (op2));
487f79b7
CD
366#endif /* DEBUG */
367
37d146fa
CD
368 /* The format type should already have been checked: */
369 switch (fmt)
487f79b7 370 {
37d146fa
CD
371 case fmt_single:
372 {
373 sim_fpu wop1;
374 sim_fpu wop2;
375 sim_fpu_32to (&wop1, op1);
376 sim_fpu_32to (&wop2, op2);
377 boolean = sim_fpu_is_lt (&wop1, &wop2);
378 break;
379 }
380 case fmt_double:
381 {
382 sim_fpu wop1;
383 sim_fpu wop2;
384 sim_fpu_64to (&wop1, op1);
385 sim_fpu_64to (&wop2, op2);
386 boolean = sim_fpu_is_lt (&wop1, &wop2);
387 break;
388 }
389 default:
390 fprintf (stderr, "Bad switch\n");
391 abort ();
487f79b7 392 }
487f79b7
CD
393
394#ifdef DEBUG
37d146fa
CD
395 printf ("DBG: Less: returning %d (format = %s)\n",
396 boolean, fpu_format_name (fmt));
487f79b7
CD
397#endif /* DEBUG */
398
37d146fa 399 return (boolean);
487f79b7
CD
400}
401
402int
37d146fa 403Equal (op1, op2, fmt)
487f79b7
CD
404 uword64 op1;
405 uword64 op2;
37d146fa 406 FP_formats fmt;
487f79b7
CD
407{
408 int boolean = 0;
409
410 /* Argument checking already performed by the FPCOMPARE code */
411
412#ifdef DEBUG
37d146fa
CD
413 printf ("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",
414 fpu_format_name (fmt), pr_addr (op1), pr_addr (op2));
487f79b7
CD
415#endif /* DEBUG */
416
37d146fa
CD
417 /* The format type should already have been checked: */
418 switch (fmt)
487f79b7 419 {
37d146fa
CD
420 case fmt_single:
421 {
422 sim_fpu wop1;
423 sim_fpu wop2;
424 sim_fpu_32to (&wop1, op1);
425 sim_fpu_32to (&wop2, op2);
426 boolean = sim_fpu_is_eq (&wop1, &wop2);
427 break;
428 }
429 case fmt_double:
430 {
431 sim_fpu wop1;
432 sim_fpu wop2;
433 sim_fpu_64to (&wop1, op1);
434 sim_fpu_64to (&wop2, op2);
435 boolean = sim_fpu_is_eq (&wop1, &wop2);
436 break;
437 }
438 default:
439 fprintf (stderr, "Bad switch\n");
440 abort ();
487f79b7 441 }
487f79b7
CD
442
443#ifdef DEBUG
37d146fa
CD
444 printf ("DBG: Equal: returning %d (format = %s)\n",
445 boolean, fpu_format_name (fmt));
487f79b7
CD
446#endif /* DEBUG */
447
37d146fa 448 return (boolean);
487f79b7
CD
449}
450
487f79b7 451
ba46ddd0 452/* Basic arithmetic operations. */
487f79b7 453
ba46ddd0
CD
454static unsigned64
455fp_unary(sim_cpu *cpu,
456 address_word cia,
457 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *),
458 unsigned64 op,
459 FP_formats fmt)
487f79b7 460{
ba46ddd0
CD
461 sim_fpu wop;
462 sim_fpu ans;
463 unsigned64 result = 0;
487f79b7 464
ba46ddd0 465 /* The format type has already been checked: */
37d146fa 466 switch (fmt)
487f79b7 467 {
37d146fa
CD
468 case fmt_single:
469 {
37d146fa 470 unsigned32 res;
ba46ddd0
CD
471 sim_fpu_32to (&wop, op);
472 (*sim_fpu_op) (&ans, &wop);
37d146fa
CD
473 sim_fpu_to32 (&res, &ans);
474 result = res;
475 break;
476 }
477 case fmt_double:
478 {
37d146fa 479 unsigned64 res;
ba46ddd0
CD
480 sim_fpu_64to (&wop, op);
481 (*sim_fpu_op) (&ans, &wop);
37d146fa
CD
482 sim_fpu_to64 (&res, &ans);
483 result = res;
484 break;
485 }
486 default:
ba46ddd0 487 sim_io_eprintf (SD, "Bad switch\n");
37d146fa 488 abort ();
487f79b7 489 }
487f79b7 490
ba46ddd0 491 return result;
487f79b7
CD
492}
493
ba46ddd0
CD
494static unsigned64
495fp_binary(sim_cpu *cpu,
496 address_word cia,
497 int (*sim_fpu_op)(sim_fpu *, const sim_fpu *, const sim_fpu *),
498 unsigned64 op1,
499 unsigned64 op2,
500 FP_formats fmt)
487f79b7 501{
ba46ddd0
CD
502 sim_fpu wop1;
503 sim_fpu wop2;
504 sim_fpu ans;
505 unsigned64 result = 0;
487f79b7 506
ba46ddd0 507 /* The format type has already been checked: */
37d146fa 508 switch (fmt)
487f79b7 509 {
37d146fa
CD
510 case fmt_single:
511 {
37d146fa
CD
512 unsigned32 res;
513 sim_fpu_32to (&wop1, op1);
514 sim_fpu_32to (&wop2, op2);
ba46ddd0 515 (*sim_fpu_op) (&ans, &wop1, &wop2);
37d146fa
CD
516 sim_fpu_to32 (&res, &ans);
517 result = res;
518 break;
519 }
520 case fmt_double:
521 {
37d146fa
CD
522 unsigned64 res;
523 sim_fpu_64to (&wop1, op1);
524 sim_fpu_64to (&wop2, op2);
ba46ddd0 525 (*sim_fpu_op) (&ans, &wop1, &wop2);
37d146fa
CD
526 sim_fpu_to64 (&res, &ans);
527 result = res;
528 break;
529 }
530 default:
ba46ddd0 531 sim_io_eprintf (SD, "Bad switch\n");
37d146fa 532 abort ();
487f79b7 533 }
487f79b7 534
ba46ddd0 535 return result;
487f79b7
CD
536}
537
487f79b7 538
ba46ddd0
CD
539unsigned64
540fp_abs(sim_cpu *cpu,
541 address_word cia,
542 unsigned64 op,
543 FP_formats fmt)
544{
545 return fp_unary(cpu, cia, &sim_fpu_abs, op, fmt);
487f79b7
CD
546}
547
ba46ddd0
CD
548unsigned64
549fp_neg(sim_cpu *cpu,
550 address_word cia,
551 unsigned64 op,
552 FP_formats fmt)
487f79b7 553{
ba46ddd0 554 return fp_unary(cpu, cia, &sim_fpu_neg, op, fmt);
487f79b7
CD
555}
556
ba46ddd0
CD
557unsigned64
558fp_add(sim_cpu *cpu,
559 address_word cia,
560 unsigned64 op1,
561 unsigned64 op2,
562 FP_formats fmt)
487f79b7 563{
ba46ddd0
CD
564 return fp_binary(cpu, cia, &sim_fpu_add, op1, op2, fmt);
565}
487f79b7 566
ba46ddd0
CD
567unsigned64
568fp_sub(sim_cpu *cpu,
569 address_word cia,
570 unsigned64 op1,
571 unsigned64 op2,
572 FP_formats fmt)
573{
574 return fp_binary(cpu, cia, &sim_fpu_sub, op1, op2, fmt);
575}
487f79b7 576
ba46ddd0
CD
577unsigned64
578fp_mul(sim_cpu *cpu,
579 address_word cia,
580 unsigned64 op1,
581 unsigned64 op2,
582 FP_formats fmt)
583{
584 return fp_binary(cpu, cia, &sim_fpu_mul, op1, op2, fmt);
585}
487f79b7 586
ba46ddd0
CD
587unsigned64
588fp_div(sim_cpu *cpu,
589 address_word cia,
590 unsigned64 op1,
591 unsigned64 op2,
592 FP_formats fmt)
593{
594 return fp_binary(cpu, cia, &sim_fpu_div, op1, op2, fmt);
595}
487f79b7 596
ba46ddd0
CD
597unsigned64
598fp_recip(sim_cpu *cpu,
599 address_word cia,
600 unsigned64 op,
601 FP_formats fmt)
602{
603 return fp_unary(cpu, cia, &sim_fpu_inv, op, fmt);
604}
487f79b7 605
ba46ddd0
CD
606unsigned64
607fp_sqrt(sim_cpu *cpu,
608 address_word cia,
609 unsigned64 op,
610 FP_formats fmt)
611{
612 return fp_unary(cpu, cia, &sim_fpu_sqrt, op, fmt);
487f79b7
CD
613}
614
ba46ddd0 615
487f79b7 616uword64
18d8a52d 617convert (sim_cpu *cpu,
487f79b7
CD
618 address_word cia,
619 int rm,
620 uword64 op,
621 FP_formats from,
622 FP_formats to)
623{
624 sim_fpu wop;
625 sim_fpu_round round;
626 unsigned32 result32;
627 unsigned64 result64;
628
629#ifdef DEBUG
630#if 0 /* FIXME: doesn't compile */
37d146fa
CD
631 printf ("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",
632 fpu_rounding_mode_name (rm), pr_addr (op), fpu_format_name (from),
633 fpu_format_name (to), pr_addr (IPC));
487f79b7
CD
634#endif
635#endif /* DEBUG */
636
637 switch (rm)
638 {
639 case FP_RM_NEAREST:
640 /* Round result to nearest representable value. When two
641 representable values are equally near, round to the value
37d146fa 642 that has a least significant bit of zero (i.e. is even). */
487f79b7
CD
643 round = sim_fpu_round_near;
644 break;
645 case FP_RM_TOZERO:
646 /* Round result to the value closest to, and not greater in
37d146fa 647 magnitude than, the result. */
487f79b7
CD
648 round = sim_fpu_round_zero;
649 break;
650 case FP_RM_TOPINF:
651 /* Round result to the value closest to, and not less than,
37d146fa 652 the result. */
487f79b7
CD
653 round = sim_fpu_round_up;
654 break;
37d146fa 655
487f79b7
CD
656 case FP_RM_TOMINF:
657 /* Round result to the value closest to, and not greater than,
37d146fa 658 the result. */
487f79b7
CD
659 round = sim_fpu_round_down;
660 break;
661 default:
662 round = 0;
663 fprintf (stderr, "Bad switch\n");
664 abort ();
665 }
37d146fa 666
487f79b7
CD
667 /* Convert the input to sim_fpu internal format */
668 switch (from)
669 {
670 case fmt_double:
671 sim_fpu_64to (&wop, op);
672 break;
673 case fmt_single:
674 sim_fpu_32to (&wop, op);
675 break;
676 case fmt_word:
677 sim_fpu_i32to (&wop, op, round);
678 break;
679 case fmt_long:
680 sim_fpu_i64to (&wop, op, round);
681 break;
682 default:
683 fprintf (stderr, "Bad switch\n");
684 abort ();
685 }
686
687 /* Convert sim_fpu format into the output */
688 /* The value WOP is converted to the destination format, rounding
689 using mode RM. When the destination is a fixed-point format, then
690 a source value of Infinity, NaN or one which would round to an
691 integer outside the fixed point range then an IEEE Invalid
37d146fa 692 Operation condition is raised. */
487f79b7
CD
693 switch (to)
694 {
695 case fmt_single:
696 sim_fpu_round_32 (&wop, round, 0);
697 sim_fpu_to32 (&result32, &wop);
698 result64 = result32;
699 break;
700 case fmt_double:
701 sim_fpu_round_64 (&wop, round, 0);
702 sim_fpu_to64 (&result64, &wop);
703 break;
704 case fmt_word:
705 sim_fpu_to32i (&result32, &wop, round);
706 result64 = result32;
707 break;
708 case fmt_long:
709 sim_fpu_to64i (&result64, &wop, round);
710 break;
711 default:
712 result64 = 0;
713 fprintf (stderr, "Bad switch\n");
714 abort ();
715 }
37d146fa 716
487f79b7 717#ifdef DEBUG
37d146fa
CD
718 printf ("DBG: Convert: returning 0x%s (to format = %s)\n",
719 pr_addr (result64), fpu_format_name (to));
487f79b7
CD
720#endif /* DEBUG */
721
37d146fa 722 return (result64);
487f79b7
CD
723}
724
07892c0b
CD
725static const char *
726fpu_format_name (FP_formats fmt)
727{
728 switch (fmt)
729 {
730 case fmt_single:
731 return "single";
732 case fmt_double:
733 return "double";
734 case fmt_word:
735 return "word";
736 case fmt_long:
737 return "long";
738 case fmt_unknown:
739 return "<unknown>";
740 case fmt_uninterpreted:
741 return "<uninterpreted>";
742 case fmt_uninterpreted_32:
743 return "<uninterpreted_32>";
744 case fmt_uninterpreted_64:
745 return "<uninterpreted_64>";
746 default:
747 return "<format error>";
748 }
749}
487f79b7 750
07892c0b
CD
751#ifdef DEBUG
752static const char *
753fpu_rounding_mode_name (int rm)
754{
755 switch (rm)
756 {
757 case FP_RM_NEAREST:
758 return "Round";
759 case FP_RM_TOZERO:
760 return "Trunc";
761 case FP_RM_TOPINF:
762 return "Ceil";
763 case FP_RM_TOMINF:
764 return "Floor";
765 default:
766 return "<rounding mode error>";
767 }
768}
769#endif /* DEBUG */
This page took 0.06751 seconds and 4 git commands to generate.