Revision fab7fe42 target-ppc/fpu_helper.c
b/target-ppc/fpu_helper.c | ||
---|---|---|
600 | 600 |
return farg1.ll; |
601 | 601 |
} |
602 | 602 |
|
603 |
/* fctiw - fctiw. */ |
|
604 |
uint64_t helper_fctiw(CPUPPCState *env, uint64_t arg) |
|
605 |
{ |
|
606 |
CPU_DoubleU farg; |
|
607 |
|
|
608 |
farg.ll = arg; |
|
609 |
|
|
610 |
if (unlikely(float64_is_signaling_nan(farg.d))) { |
|
611 |
/* sNaN conversion */ |
|
612 |
farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN | |
|
613 |
POWERPC_EXCP_FP_VXCVI, 1); |
|
614 |
} else if (unlikely(float64_is_quiet_nan(farg.d) || |
|
615 |
float64_is_infinity(farg.d))) { |
|
616 |
/* qNan / infinity conversion */ |
|
617 |
farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); |
|
618 |
} else { |
|
619 |
farg.ll = float64_to_int32(farg.d, &env->fp_status); |
|
620 |
/* XXX: higher bits are not supposed to be significant. |
|
621 |
* to make tests easier, return the same as a real PowerPC 750 |
|
622 |
*/ |
|
623 |
farg.ll |= 0xFFF80000ULL << 32; |
|
624 |
} |
|
625 |
return farg.ll; |
|
626 |
} |
|
627 |
|
|
628 |
/* fctiwz - fctiwz. */ |
|
629 |
uint64_t helper_fctiwz(CPUPPCState *env, uint64_t arg) |
|
630 |
{ |
|
631 |
CPU_DoubleU farg; |
|
632 | 603 |
|
633 |
farg.ll = arg; |
|
604 |
#define FPU_FCTI(op, cvt, nanval) \ |
|
605 |
uint64_t helper_##op(CPUPPCState *env, uint64_t arg) \ |
|
606 |
{ \ |
|
607 |
CPU_DoubleU farg; \ |
|
608 |
\ |
|
609 |
farg.ll = arg; \ |
|
610 |
farg.ll = float64_to_##cvt(farg.d, &env->fp_status); \ |
|
611 |
\ |
|
612 |
if (unlikely(env->fp_status.float_exception_flags)) { \ |
|
613 |
if (float64_is_any_nan(arg)) { \ |
|
614 |
fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \ |
|
615 |
if (float64_is_signaling_nan(arg)) { \ |
|
616 |
fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); \ |
|
617 |
} \ |
|
618 |
farg.ll = nanval; \ |
|
619 |
} else if (env->fp_status.float_exception_flags & \ |
|
620 |
float_flag_invalid) { \ |
|
621 |
fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \ |
|
622 |
} \ |
|
623 |
helper_float_check_status(env); \ |
|
624 |
} \ |
|
625 |
return farg.ll; \ |
|
626 |
} |
|
634 | 627 |
|
635 |
if (unlikely(float64_is_signaling_nan(farg.d))) { |
|
636 |
/* sNaN conversion */ |
|
637 |
farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN | |
|
638 |
POWERPC_EXCP_FP_VXCVI, 1); |
|
639 |
} else if (unlikely(float64_is_quiet_nan(farg.d) || |
|
640 |
float64_is_infinity(farg.d))) { |
|
641 |
/* qNan / infinity conversion */ |
|
642 |
farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); |
|
643 |
} else { |
|
644 |
farg.ll = float64_to_int32_round_to_zero(farg.d, &env->fp_status); |
|
645 |
/* XXX: higher bits are not supposed to be significant. |
|
646 |
* to make tests easier, return the same as a real PowerPC 750 |
|
647 |
*/ |
|
648 |
farg.ll |= 0xFFF80000ULL << 32; |
|
649 |
} |
|
650 |
return farg.ll; |
|
651 |
} |
|
628 |
FPU_FCTI(fctiw, int32, 0x80000000) |
|
629 |
FPU_FCTI(fctiwz, int32_round_to_zero, 0x80000000) |
|
630 |
FPU_FCTI(fctiwu, uint32, 0x00000000) |
|
631 |
FPU_FCTI(fctiwuz, uint32_round_to_zero, 0x00000000) |
|
632 |
#if defined(TARGET_PPC64) |
|
633 |
FPU_FCTI(fctid, int64, 0x8000000000000000) |
|
634 |
FPU_FCTI(fctidz, int64_round_to_zero, 0x8000000000000000) |
|
635 |
FPU_FCTI(fctidu, uint64, 0x0000000000000000) |
|
636 |
FPU_FCTI(fctiduz, uint64_round_to_zero, 0x0000000000000000) |
|
637 |
#endif |
|
652 | 638 |
|
653 | 639 |
#if defined(TARGET_PPC64) |
654 | 640 |
/* fcfid - fcfid. */ |
... | ... | |
660 | 646 |
return farg.ll; |
661 | 647 |
} |
662 | 648 |
|
663 |
/* fctid - fctid. */ |
|
664 |
uint64_t helper_fctid(CPUPPCState *env, uint64_t arg) |
|
665 |
{ |
|
666 |
CPU_DoubleU farg; |
|
667 | 649 |
|
668 |
farg.ll = arg; |
|
669 |
|
|
670 |
if (unlikely(float64_is_signaling_nan(farg.d))) { |
|
671 |
/* sNaN conversion */ |
|
672 |
farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN | |
|
673 |
POWERPC_EXCP_FP_VXCVI, 1); |
|
674 |
} else if (unlikely(float64_is_quiet_nan(farg.d) || |
|
675 |
float64_is_infinity(farg.d))) { |
|
676 |
/* qNan / infinity conversion */ |
|
677 |
farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); |
|
678 |
} else { |
|
679 |
farg.ll = float64_to_int64(farg.d, &env->fp_status); |
|
680 |
} |
|
681 |
return farg.ll; |
|
682 |
} |
|
683 |
|
|
684 |
/* fctidz - fctidz. */ |
|
685 |
uint64_t helper_fctidz(CPUPPCState *env, uint64_t arg) |
|
686 |
{ |
|
687 |
CPU_DoubleU farg; |
|
688 |
|
|
689 |
farg.ll = arg; |
|
690 |
|
|
691 |
if (unlikely(float64_is_signaling_nan(farg.d))) { |
|
692 |
/* sNaN conversion */ |
|
693 |
farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN | |
|
694 |
POWERPC_EXCP_FP_VXCVI, 1); |
|
695 |
} else if (unlikely(float64_is_quiet_nan(farg.d) || |
|
696 |
float64_is_infinity(farg.d))) { |
|
697 |
/* qNan / infinity conversion */ |
|
698 |
farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); |
|
699 |
} else { |
|
700 |
farg.ll = float64_to_int64_round_to_zero(farg.d, &env->fp_status); |
|
701 |
} |
|
702 |
return farg.ll; |
|
703 |
} |
|
704 | 650 |
|
705 | 651 |
#endif |
706 | 652 |
|
Also available in: Unified diff