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