diff options
author | Tom Musta <tommusta@gmail.com> | 2014-01-07 10:05:59 -0600 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2014-03-05 03:06:41 +0100 |
commit | fab7fe426fa5325f93c931ffbe25f4e024b1ced4 (patch) | |
tree | 821ece26f95ded45065281ef5785538ee90bdf33 /target-ppc/fpu_helper.c | |
parent | 1b0bd0029f16649a7f3d8ba021191bc6ca3a471f (diff) |
target-ppc: Add ISA2.06 Float to Integer Instructions
This patch adds the four floating point to integer conversion instructions
introduced by Power ISA V2.06:
- Floating Convert to Integer Word Unsigned (fctiwu)
- Floating Convert to Integer Word Unsigned with Round Toward
Zero (fctiwuz)
- Floating Convert to Integer Doubleword Unsigned (fctidu)
- Floating Convert to Integer Doubleword Unsigned with Round
Toward Zero (fctiduz)
A common macro is developed to eliminate repetitious code. Existing instructions
are also refactoried to use this macro (fctiw, fctiwz, fctid, fctidz).
Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc/fpu_helper.c')
-rw-r--r-- | target-ppc/fpu_helper.c | 120 |
1 files changed, 33 insertions, 87 deletions
diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index dfd9b8001e..2f9f4dcc78 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -600,55 +600,41 @@ uint64_t helper_fdiv(CPUPPCState *env, uint64_t arg1, uint64_t arg2) return farg1.ll; } -/* fctiw - fctiw. */ -uint64_t helper_fctiw(CPUPPCState *env, uint64_t arg) -{ - CPU_DoubleU farg; - - farg.ll = arg; - - if (unlikely(float64_is_signaling_nan(farg.d))) { - /* sNaN conversion */ - farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN | - POWERPC_EXCP_FP_VXCVI, 1); - } else if (unlikely(float64_is_quiet_nan(farg.d) || - float64_is_infinity(farg.d))) { - /* qNan / infinity conversion */ - farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); - } else { - farg.ll = float64_to_int32(farg.d, &env->fp_status); - /* XXX: higher bits are not supposed to be significant. - * to make tests easier, return the same as a real PowerPC 750 - */ - farg.ll |= 0xFFF80000ULL << 32; - } - return farg.ll; -} - -/* fctiwz - fctiwz. */ -uint64_t helper_fctiwz(CPUPPCState *env, uint64_t arg) -{ - CPU_DoubleU farg; - farg.ll = arg; +#define FPU_FCTI(op, cvt, nanval) \ +uint64_t helper_##op(CPUPPCState *env, uint64_t arg) \ +{ \ + CPU_DoubleU farg; \ + \ + farg.ll = arg; \ + farg.ll = float64_to_##cvt(farg.d, &env->fp_status); \ + \ + if (unlikely(env->fp_status.float_exception_flags)) { \ + if (float64_is_any_nan(arg)) { \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \ + if (float64_is_signaling_nan(arg)) { \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); \ + } \ + farg.ll = nanval; \ + } else if (env->fp_status.float_exception_flags & \ + float_flag_invalid) { \ + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \ + } \ + helper_float_check_status(env); \ + } \ + return farg.ll; \ + } - if (unlikely(float64_is_signaling_nan(farg.d))) { - /* sNaN conversion */ - farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN | - POWERPC_EXCP_FP_VXCVI, 1); - } else if (unlikely(float64_is_quiet_nan(farg.d) || - float64_is_infinity(farg.d))) { - /* qNan / infinity conversion */ - farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); - } else { - farg.ll = float64_to_int32_round_to_zero(farg.d, &env->fp_status); - /* XXX: higher bits are not supposed to be significant. - * to make tests easier, return the same as a real PowerPC 750 - */ - farg.ll |= 0xFFF80000ULL << 32; - } - return farg.ll; -} +FPU_FCTI(fctiw, int32, 0x80000000) +FPU_FCTI(fctiwz, int32_round_to_zero, 0x80000000) +FPU_FCTI(fctiwu, uint32, 0x00000000) +FPU_FCTI(fctiwuz, uint32_round_to_zero, 0x00000000) +#if defined(TARGET_PPC64) +FPU_FCTI(fctid, int64, 0x8000000000000000) +FPU_FCTI(fctidz, int64_round_to_zero, 0x8000000000000000) +FPU_FCTI(fctidu, uint64, 0x0000000000000000) +FPU_FCTI(fctiduz, uint64_round_to_zero, 0x0000000000000000) +#endif #if defined(TARGET_PPC64) /* fcfid - fcfid. */ @@ -660,47 +646,7 @@ uint64_t helper_fcfid(CPUPPCState *env, uint64_t arg) return farg.ll; } -/* fctid - fctid. */ -uint64_t helper_fctid(CPUPPCState *env, uint64_t arg) -{ - CPU_DoubleU farg; - farg.ll = arg; - - if (unlikely(float64_is_signaling_nan(farg.d))) { - /* sNaN conversion */ - farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN | - POWERPC_EXCP_FP_VXCVI, 1); - } else if (unlikely(float64_is_quiet_nan(farg.d) || - float64_is_infinity(farg.d))) { - /* qNan / infinity conversion */ - farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); - } else { - farg.ll = float64_to_int64(farg.d, &env->fp_status); - } - return farg.ll; -} - -/* fctidz - fctidz. */ -uint64_t helper_fctidz(CPUPPCState *env, uint64_t arg) -{ - CPU_DoubleU farg; - - farg.ll = arg; - - if (unlikely(float64_is_signaling_nan(farg.d))) { - /* sNaN conversion */ - farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN | - POWERPC_EXCP_FP_VXCVI, 1); - } else if (unlikely(float64_is_quiet_nan(farg.d) || - float64_is_infinity(farg.d))) { - /* qNan / infinity conversion */ - farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); - } else { - farg.ll = float64_to_int64_round_to_zero(farg.d, &env->fp_status); - } - return farg.ll; -} #endif |