comparison packages/hal/mips/arch/current/src/mipsfp.c @ 92:08ffab08d2ee ecos-sw-2000-05-26

Merge from eCos master repository on 2000-05-26-07:47:03-BST
author jlarmour
date Fri, 26 May 2000 13:46:34 +0000
parents bf00f99aec69
children e0c0827131d1
comparison
equal deleted inserted replaced
91:86f6a8b98920 92:08ffab08d2ee
65 65
66 // The following types were taken from <sys/ieeefp.h> from libm. 66 // The following types were taken from <sys/ieeefp.h> from libm.
67 67
68 #if (CYG_BYTEORDER == CYG_MSBFIRST) // Big endian 68 #if (CYG_BYTEORDER == CYG_MSBFIRST) // Big endian
69 69
70 // Note: there do not seem to be any current machines which are Big Endian but
71 // have a mixed up double layout.
72
73 typedef union 70 typedef union
74 { 71 {
75 cyg_int32 asi32[2]; 72 cyg_int32 asi32[2];
76 73
77 cyg_int64 asi64; 74 cyg_int64 asi64;
78 75
79 double value; 76 double value;
80 77
81 struct 78 struct
82 { 79 {
80 #if (CYG_DOUBLE_BYTEORDER == CYG_MSBFIRST)
83 unsigned int sign : 1; 81 unsigned int sign : 1;
84 unsigned int exponent: 11; 82 unsigned int exponent: 11;
85 unsigned int fraction0:4; 83 unsigned int fraction0:4;
86 unsigned int fraction1:16; 84 unsigned int fraction1:16;
87 unsigned int fraction2:16; 85 unsigned int fraction2:16;
88 unsigned int fraction3:16; 86 unsigned int fraction3:16;
89 87 #else
88 unsigned int fraction2:16;
89 unsigned int fraction3:16;
90 unsigned int sign : 1;
91 unsigned int exponent: 11;
92 unsigned int fraction0:4;
93 unsigned int fraction1:16;
94 #endif
90 } number; 95 } number;
91 96
92 struct 97 struct
93 { 98 {
99 #if (CYG_DOUBLE_BYTEORDER == CYG_MSBFIRST)
94 unsigned int sign : 1; 100 unsigned int sign : 1;
95 unsigned int exponent: 11; 101 unsigned int exponent: 11;
96 unsigned int quiet:1; 102 unsigned int quiet:1;
97 unsigned int function0:3; 103 unsigned int function0:3;
98 unsigned int function1:16; 104 unsigned int function1:16;
99 unsigned int function2:16; 105 unsigned int function2:16;
100 unsigned int function3:16; 106 unsigned int function3:16;
107 #else
108 unsigned int function2:16;
109 unsigned int function3:16;
110 unsigned int sign : 1;
111 unsigned int exponent: 11;
112 unsigned int quiet:1;
113 unsigned int function0:3;
114 unsigned int function1:16;
115 #endif
101 } nan; 116 } nan;
102 117
103 struct 118 struct
104 { 119 {
120 #if (CYG_DOUBLE_BYTEORDER == CYG_MSBFIRST)
105 cyg_uint32 msw; 121 cyg_uint32 msw;
106 cyg_uint32 lsw; 122 cyg_uint32 lsw;
123 #else
124 cyg_uint32 lsw;
125 cyg_uint32 msw;
126 #endif
107 } parts; 127 } parts;
108 128
109 129
110 } Cyg_libm_ieee_double_shape_type; 130 } Cyg_libm_ieee_double_shape_type;
111 131
282 } // reg2flt() 302 } // reg2flt()
283 303
284 static __inline__ void 304 static __inline__ void
285 flt2reg( Cyg_libm_ieee_float_shape_type *flt, CYG_HAL_FPU_REG *fpu_reg_p ) 305 flt2reg( Cyg_libm_ieee_float_shape_type *flt, CYG_HAL_FPU_REG *fpu_reg_p )
286 { 306 {
287 *fpu_reg_p = flt->asi32; 307 #if defined(CYGHWR_HAL_MIPS_FPU_32BIT) || (CYG_BYTEORDER == CYG_LSBFIRST)
308 *(cyg_int32 *)fpu_reg_p = flt->asi32;
309 #else
310 *((cyg_int32 *)fpu_reg_p + 1) = flt->asi32;
311 # endif
288 } // flt2reg() 312 } // flt2reg()
313
314 static __inline__ void
315 reg2dbl( CYG_HAL_FPU_REG *fpu_reg_p, Cyg_libm_ieee_double_shape_type *flt)
316 {
317 flt->asi64 = *(cyg_int64 *)fpu_reg_p;
318 } // reg2dbl()
319
320 static __inline__ void
321 dbl2reg( Cyg_libm_ieee_double_shape_type *flt, CYG_HAL_FPU_REG *fpu_reg_p )
322 {
323 *(cyg_uint64*)fpu_reg_p = flt->asi64;
324 } // dbl2reg()
325
289 326
290 // This function returns non-zero if the exception has been handled 327 // This function returns non-zero if the exception has been handled
291 // successfully. 328 // successfully.
292 329
293 // FIXME: Arguably we should raise underflow exceptions in some of the cases 330 // FIXME: Arguably we should raise underflow exceptions in some of the cases
377 case DIV_INSN: 414 case DIV_INSN:
378 415
379 if (fp64bit) { 416 if (fp64bit) {
380 Cyg_libm_ieee_double_shape_type s1, s2; 417 Cyg_libm_ieee_double_shape_type s1, s2;
381 418
382 s1.asi64 = *srcreg1; 419 reg2dbl( srcreg1, &s1 );
383 s2.asi64 = *srcreg2; 420 reg2dbl( srcreg2, &s2 );
384 421
385 if ( issubnormal( s1 ) ) { // flush to 0 and restart 422 if ( issubnormal( s1 ) ) { // flush to 0 and restart
386 // but preserve sign 423 // but preserve sign
387 if (s1.number.sign) 424 if (s1.number.sign)
388 s1.value = -0.0; 425 s1.value = -0.0;
389 else 426 else
390 s1.value = 0.0; 427 s1.value = 0.0;
391 *srcreg1 = s1.asi64; 428 dbl2reg( &s1, srcreg1 );
392 handled++; 429 handled++;
393 } 430 }
394 431
395 // We could try flushing both to 0 at the same time, but 432 // We could try flushing both to 0 at the same time, but
396 // that's inadvisable if both numbers are very small. 433 // that's inadvisable if both numbers are very small.
402 // but preserve sign 439 // but preserve sign
403 if (s2.number.sign) 440 if (s2.number.sign)
404 s2.value = -0.0; 441 s2.value = -0.0;
405 else 442 else
406 s2.value = 0.0; 443 s2.value = 0.0;
407 *srcreg2 = s2.asi64; 444 dbl2reg( &s2, srcreg2 );
408 handled++; 445 handled++;
409 } 446 }
410 447
411 } else { // 32-bit 448 } else { // 32-bit
412 Cyg_libm_ieee_float_shape_type s1, s2; 449 Cyg_libm_ieee_float_shape_type s1, s2;
437 474
438 case SQRT_INSN: 475 case SQRT_INSN:
439 if ( fp64bit ) { 476 if ( fp64bit ) {
440 Cyg_libm_ieee_double_shape_type d, s; 477 Cyg_libm_ieee_double_shape_type d, s;
441 478
442 d.asi64 = *dstreg; 479 reg2dbl( dstreg, &d );
443 s.asi64 = *srcreg1; 480 reg2dbl( srcreg1, &s );
444 481
445 if ( issubnormal( s ) ) { // Sqrt of something tiny is 0 482 if ( issubnormal( s ) ) { // Sqrt of something tiny is 0
446 // if this is a delay slot, we can't restart properly 483 // if this is a delay slot, we can't restart properly
447 // so if it is subnormal, clear the source register instead 484 // so if it is subnormal, clear the source register instead
448 if ( delay_slot ) { 485 if ( delay_slot ) {
449 // but preserve sign 486 // but preserve sign
450 if (s.number.sign) 487 if (s.number.sign)
451 s.value = -0.0; 488 s.value = -0.0;
452 else 489 else
453 s.value = 0.0; 490 s.value = 0.0;
454 *srcreg1 = s.asi64; 491 dbl2reg( &s, srcreg1 );
455 } else { 492 } else {
456 // but preserve sign 493 // but preserve sign
457 if (s.number.sign) 494 if (s.number.sign)
458 d.value = -0.0; 495 d.value = -0.0;
459 else 496 else
460 d.value = 0.0; 497 d.value = 0.0;
461 *dstreg = d.asi64; 498 dbl2reg( &d, dstreg );
462 regs->pc += 4; // We've dealt with this so move on 499 regs->pc += 4; // We've dealt with this so move on
463 } 500 }
464 handled++; 501 handled++;
465 } 502 }
466 503
497 case ABS_INSN: 534 case ABS_INSN:
498 // We may as well do this right if we can 535 // We may as well do this right if we can
499 if ( fp64bit ) { 536 if ( fp64bit ) {
500 Cyg_libm_ieee_double_shape_type d, s; 537 Cyg_libm_ieee_double_shape_type d, s;
501 538
502 d.asi64 = *dstreg; 539 reg2dbl( dstreg, &d );
503 s.asi64 = *srcreg1; 540 reg2dbl( srcreg1, &s );
504 541
505 // if this is a delay slot, we can't restart properly 542 // if this is a delay slot, we can't restart properly
506 // so if it is subnormal, clear the source register instead 543 // so if it is subnormal, clear the source register instead
507 if ( delay_slot ) { 544 if ( delay_slot ) {
508 if ( issubnormal( s ) ) { 545 if ( issubnormal( s ) ) {
511 // register 548 // register
512 if (s.number.sign) 549 if (s.number.sign)
513 s.value = -0.0; 550 s.value = -0.0;
514 else 551 else
515 s.value = 0.0; 552 s.value = 0.0;
516 *srcreg1 = s.asi64; 553 dbl2reg( &s, srcreg1 );
517 handled++; 554 handled++;
518 } 555 }
519 } else { 556 } else {
520 d.asi64 = s.asi64; 557 d.asi64 = s.asi64;
521 d.number.sign = 0; 558 d.number.sign = 0;
522 *dstreg = d.asi64; 559 dbl2reg( &d, dstreg );
523 regs->pc += 4; 560 regs->pc += 4;
524 handled++; 561 handled++;
525 } 562 }
526 } else { // 32-bit 563 } else { // 32-bit
527 Cyg_libm_ieee_float_shape_type d, s; 564 Cyg_libm_ieee_float_shape_type d, s;
556 case MOV_INSN: 593 case MOV_INSN:
557 // We may as well do this right if we can 594 // We may as well do this right if we can
558 if ( fp64bit ) { 595 if ( fp64bit ) {
559 Cyg_libm_ieee_double_shape_type d, s; 596 Cyg_libm_ieee_double_shape_type d, s;
560 597
561 d.asi64 = *dstreg; 598 reg2dbl( dstreg, &d );
562 s.asi64 = *srcreg1; 599 reg2dbl( srcreg1, &s );
563 600
564 // if this is a delay slot, we can't restart properly 601 // if this is a delay slot, we can't restart properly
565 // so if it is subnormal, clear the source register instead 602 // so if it is subnormal, clear the source register instead
566 if ( delay_slot ) { 603 if ( delay_slot ) {
567 if ( issubnormal( s ) ) { 604 if ( issubnormal( s ) ) {
568 // but preserve sign 605 // but preserve sign
569 if (s.number.sign) 606 if (s.number.sign)
570 s.value = -0.0; 607 s.value = -0.0;
571 else 608 else
572 s.value = 0.0; 609 s.value = 0.0;
573 *srcreg1 = s.asi64; 610 dbl2reg( &s, srcreg1 );
574 handled++; 611 handled++;
575 } 612 }
576 } else { 613 } else {
577 d.asi64 = s.asi64; 614 d.asi64 = s.asi64;
578 *dstreg = d.asi64; 615 dbl2reg( &d, dstreg );
579 regs->pc += 4; 616 regs->pc += 4;
580 handled++; 617 handled++;
581 } 618 }
582 } else { // 32-bit 619 } else { // 32-bit
583 Cyg_libm_ieee_float_shape_type d, s; 620 Cyg_libm_ieee_float_shape_type d, s;
611 case NEG_INSN: 648 case NEG_INSN:
612 // We may as well do this right if we can 649 // We may as well do this right if we can
613 if ( fp64bit ) { 650 if ( fp64bit ) {
614 Cyg_libm_ieee_double_shape_type d, s; 651 Cyg_libm_ieee_double_shape_type d, s;
615 652
616 d.asi64 = *dstreg; 653 reg2dbl( dstreg, &d );
617 s.asi64 = *srcreg1; 654 reg2dbl( srcreg1, &s );
618 655
619 // if this is a delay slot, we can't restart properly 656 // if this is a delay slot, we can't restart properly
620 // so if it is subnormal, clear the source register instead 657 // so if it is subnormal, clear the source register instead
621 if ( delay_slot ) { 658 if ( delay_slot ) {
622 if ( issubnormal( s ) ) { 659 if ( issubnormal( s ) ) {
623 // but preserve sign 660 // but preserve sign
624 if (s.number.sign) 661 if (s.number.sign)
625 s.value = -0.0; 662 s.value = -0.0;
626 else 663 else
627 s.value = 0.0; 664 s.value = 0.0;
628 *srcreg1 = s.asi64; 665 dbl2reg( &s, srcreg1 );
629 handled++; 666 handled++;
630 } 667 }
631 } else { 668 } else {
632 d.asi64 = s.asi64; 669 d.asi64 = s.asi64;
633 d.number.sign = s.number.sign ? 0 : 1; 670 d.number.sign = s.number.sign ? 0 : 1;
634 *dstreg = d.asi64; 671 dbl2reg( &d, dstreg );
635 regs->pc += 4; 672 regs->pc += 4;
636 handled++; 673 handled++;
637 } 674 }
638 } else { // 32-bit 675 } else { // 32-bit
639 Cyg_libm_ieee_float_shape_type d, s; 676 Cyg_libm_ieee_float_shape_type d, s;
680 case CVTL_INSN: 717 case CVTL_INSN:
681 718
682 if ( fp64bit ) { 719 if ( fp64bit ) {
683 Cyg_libm_ieee_double_shape_type s; 720 Cyg_libm_ieee_double_shape_type s;
684 721
685 s.asi64 = *srcreg1; 722 reg2dbl( srcreg1, &s );
686 723
687 // just try and 0 the source register if it is subnormal 724 // just try and 0 the source register if it is subnormal
688 if ( issubnormal( s ) ) { 725 if ( issubnormal( s ) ) {
689 // but preserve sign 726 // but preserve sign
690 if (s.number.sign) 727 if (s.number.sign)
691 s.value = -0.0; 728 s.value = -0.0;
692 else 729 else
693 s.value = 0.0; 730 s.value = 0.0;
694 *srcreg1 = s.asi64; 731 dbl2reg( &s, srcreg1 );
695 handled++; 732 handled++;
696 } 733 }
697 } else { // 32-bit 734 } else { // 32-bit
698 Cyg_libm_ieee_float_shape_type s; 735 Cyg_libm_ieee_float_shape_type s;
699 736
716 // check for floating-point compare (C.cond.fmt) 753 // check for floating-point compare (C.cond.fmt)
717 if ( (insn & 0x30) == 0x30 ) { 754 if ( (insn & 0x30) == 0x30 ) {
718 if (fp64bit) { 755 if (fp64bit) {
719 Cyg_libm_ieee_double_shape_type s1, s2; 756 Cyg_libm_ieee_double_shape_type s1, s2;
720 757
721 s1.asi64 = *srcreg1; 758 reg2dbl( srcreg1, &s1 );
722 s2.asi64 = *srcreg2; 759 reg2dbl( srcreg2, &s2 );
723 760
724 if ( issubnormal( s1 ) ) { // flush to 0 and restart 761 if ( issubnormal( s1 ) ) { // flush to 0 and restart
725 // but preserve sign 762 // but preserve sign
726 if (s1.number.sign) 763 if (s1.number.sign)
727 s1.value = -0.0; 764 s1.value = -0.0;
728 else 765 else
729 s1.value = 0.0; 766 s1.value = 0.0;
730 *srcreg1 = s1.asi64; 767 dbl2reg( &s1, srcreg1 );
731 handled++; 768 handled++;
732 } 769 }
733 770
734 if ( issubnormal( s2 ) ) { // flush to 0 and restart 771 if ( issubnormal( s2 ) ) { // flush to 0 and restart
735 // but preserve sign 772 // but preserve sign
736 if (s2.number.sign) 773 if (s2.number.sign)
737 s2.value = -0.0; 774 s2.value = -0.0;
738 else 775 else
739 s2.value = 0.0; 776 s2.value = 0.0;
740 *srcreg2 = s2.asi64; 777 dbl2reg( &s2, srcreg2 );
741 handled++; 778 handled++;
742 } 779 }
743 780
744 } else { // 32-bit 781 } else { // 32-bit
745 Cyg_libm_ieee_float_shape_type s1, s2; 782 Cyg_libm_ieee_float_shape_type s1, s2;