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