Revision e864cabd

b/target-ppc/exec.h
27 27
#include "cpu.h"
28 28
#include "exec-all.h"
29 29

  
30
/* For normal operations, precise emulation should not be needed */
31
//#define USE_PRECISE_EMULATION 1
32
#define USE_PRECISE_EMULATION 0
33

  
30 34
register struct CPUPPCState *env asm(AREG0);
31 35
#if TARGET_LONG_BITS > HOST_LONG_BITS
32 36
/* no registers can be used */
b/target-ppc/op.c
261 261
    RETURN();
262 262
}
263 263

  
264
PPC_OP(clear_xer_cr)
264
PPC_OP(clear_xer_ov)
265 265
{
266 266
    xer_so = 0;
267 267
    xer_ov = 0;
268
    RETURN();
269
}
270

  
271
PPC_OP(clear_xer_ca)
272
{
268 273
    xer_ca = 0;
269 274
    RETURN();
270 275
}
......
714 719
        xer_so = 1;
715 720
        xer_ov = 1;
716 721
    }
722
    RETURN();
717 723
}
718 724

  
719 725
#if defined(TARGET_PPC64)
......
726 732
        xer_so = 1;
727 733
        xer_ov = 1;
728 734
    }
735
    RETURN();
729 736
}
730 737
#endif
731 738

  
......
1643 1650
/* fmadd - fmadd. */
1644 1651
PPC_OP(fmadd)
1645 1652
{
1653
#if USE_PRECISE_EMULATION
1654
    do_fmadd();
1655
#else
1646 1656
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1647 1657
    FT0 = float64_add(FT0, FT2, &env->fp_status);
1658
#endif
1648 1659
    RETURN();
1649 1660
}
1650 1661

  
1651 1662
/* fmsub - fmsub. */
1652 1663
PPC_OP(fmsub)
1653 1664
{
1665
#if USE_PRECISE_EMULATION
1666
    do_fmsub();
1667
#else
1654 1668
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
1655 1669
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
1670
#endif
1656 1671
    RETURN();
1657 1672
}
1658 1673

  
......
2378 2393
void OPPROTO op_splatw_T1_64 (void)
2379 2394
{
2380 2395
    T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL);
2396
    RETURN();
2381 2397
}
2382 2398

  
2383 2399
void OPPROTO op_splatwi_T0_64 (void)
......
2385 2401
    uint64_t tmp = PARAM1;
2386 2402

  
2387 2403
    T0_64 = (tmp << 32) | tmp;
2404
    RETURN();
2388 2405
}
2389 2406

  
2390 2407
void OPPROTO op_splatwi_T1_64 (void)
......
2392 2409
    uint64_t tmp = PARAM1;
2393 2410

  
2394 2411
    T1_64 = (tmp << 32) | tmp;
2412
    RETURN();
2395 2413
}
2396 2414

  
2397 2415
void OPPROTO op_extsh_T1_64 (void)
b/target-ppc/op_helper.c
615 615
        uint64_t i;
616 616
    } p;
617 617

  
618
    p.i = float64_to_int32(FT0, &env->fp_status);
619
#if USE_PRECISE_EMULATION
618 620
    /* XXX: higher bits are not supposed to be significant.
619 621
     *     to make tests easier, return the same as a real PowerPC 750 (aka G3)
620 622
     */
621
    p.i = float64_to_int32(FT0, &env->fp_status);
622 623
    p.i |= 0xFFF80000ULL << 32;
624
#endif
623 625
    FT0 = p.d;
624 626
}
625 627

  
......
630 632
        uint64_t i;
631 633
    } p;
632 634

  
635
    p.i = float64_to_int32_round_to_zero(FT0, &env->fp_status);
636
#if USE_PRECISE_EMULATION
633 637
    /* XXX: higher bits are not supposed to be significant.
634 638
     *     to make tests easier, return the same as a real PowerPC 750 (aka G3)
635 639
     */
636
    p.i = float64_to_int32_round_to_zero(FT0, &env->fp_status);
637 640
    p.i |= 0xFFF80000ULL << 32;
641
#endif
638 642
    FT0 = p.d;
639 643
}
640 644

  
645
#if USE_PRECISE_EMULATION
646
void do_fmadd (void)
647
{
648
#ifdef FLOAT128
649
    float128 ft0_128, ft1_128;
650

  
651
    ft0_128 = float64_to_float128(FT0, &env->fp_status);
652
    ft1_128 = float64_to_float128(FT1, &env->fp_status);
653
    ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);
654
    ft1_128 = float64_to_float128(FT2, &env->fp_status);
655
    ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status);
656
    FT0 = float128_to_float64(ft0_128, &env->fp_status);
657
#else
658
    /* This is OK on x86 hosts */
659
    FT0 = (FT0 * FT1) + FT2;
660
#endif
661
}
662

  
663
void do_fmsub (void)
664
{
665
#ifdef FLOAT128
666
    float128 ft0_128, ft1_128;
667

  
668
    ft0_128 = float64_to_float128(FT0, &env->fp_status);
669
    ft1_128 = float64_to_float128(FT1, &env->fp_status);
670
    ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);
671
    ft1_128 = float64_to_float128(FT2, &env->fp_status);
672
    ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);
673
    FT0 = float128_to_float64(ft0_128, &env->fp_status);
674
#else
675
    /* This is OK on x86 hosts */
676
    FT0 = (FT0 * FT1) - FT2;
677
#endif
678
}
679
#endif /* USE_PRECISE_EMULATION */
680

  
641 681
void do_fnmadd (void)
642 682
{
683
#if USE_PRECISE_EMULATION
684
#ifdef FLOAT128
685
    float128 ft0_128, ft1_128;
686

  
687
    ft0_128 = float64_to_float128(FT0, &env->fp_status);
688
    ft1_128 = float64_to_float128(FT1, &env->fp_status);
689
    ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);
690
    ft1_128 = float64_to_float128(FT2, &env->fp_status);
691
    ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status);
692
    FT0 = float128_to_float64(ft0_128, &env->fp_status);
693
#else
694
    /* This is OK on x86 hosts */
695
    FT0 = (FT0 * FT1) + FT2;
696
#endif
697
#else
643 698
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
644 699
    FT0 = float64_add(FT0, FT2, &env->fp_status);
700
#endif
645 701
    if (likely(!isnan(FT0)))
646 702
        FT0 = float64_chs(FT0);
647 703
}
648 704

  
649 705
void do_fnmsub (void)
650 706
{
707
#if USE_PRECISE_EMULATION
708
#ifdef FLOAT128
709
    float128 ft0_128, ft1_128;
710

  
711
    ft0_128 = float64_to_float128(FT0, &env->fp_status);
712
    ft1_128 = float64_to_float128(FT1, &env->fp_status);
713
    ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);
714
    ft1_128 = float64_to_float128(FT2, &env->fp_status);
715
    ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);
716
    FT0 = float128_to_float64(ft0_128, &env->fp_status);
717
#else
718
    /* This is OK on x86 hosts */
719
    FT0 = (FT0 * FT1) - FT2;
720
#endif
721
#else
651 722
    FT0 = float64_mul(FT0, FT1, &env->fp_status);
652 723
    FT0 = float64_sub(FT0, FT2, &env->fp_status);
724
#endif
653 725
    if (likely(!isnan(FT0)))
654 726
        FT0 = float64_chs(FT0);
655 727
}
......
667 739
    } p;
668 740

  
669 741
    if (likely(isnormal(FT0))) {
742
#if USE_PRECISE_EMULATION
743
        FT0 = float64_div(1.0, FT0, &env->fp_status);
744
        FT0 = float64_to_float32(FT0, &env->fp_status);
745
#else
670 746
        FT0 = float32_div(1.0, FT0, &env->fp_status);
747
#endif
671 748
    } else {
672 749
        p.d = FT0;
673 750
        if (p.i == 0x8000000000000000ULL) {
b/target-ppc/op_helper.h
93 93
void do_fres (void);
94 94
void do_frsqrte (void);
95 95
void do_fsel (void);
96
#if USE_PRECISE_EMULATION
97
void do_fmadd (void);
98
void do_fmsub (void);
99
#endif
96 100
void do_fnmadd (void);
97 101
void do_fnmsub (void);
98 102
void do_fctiw (void);
b/target-ppc/translate.c
781 781
        else
782 782
#endif
783 783
            gen_op_check_addc();
784
    } else {
785
        gen_op_clear_xer_ca();
784 786
    }
785 787
    gen_op_store_T0_gpr(rD(ctx->opcode));
786 788
}
......
2804 2806
{
2805 2807
    gen_op_load_xer_cr();
2806 2808
    gen_op_store_T0_crf(crfD(ctx->opcode));
2807
    gen_op_clear_xer_cr();
2809
    gen_op_clear_xer_ov();
2810
    gen_op_clear_xer_ca();
2808 2811
}
2809 2812

  
2810 2813
/* mfcr */

Also available in: Unified diff