[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-ppc] [PATCH 7/7] target/ppc: Use non-arithmetic conversions fo
From: |
Programmingkid |
Subject: |
Re: [Qemu-ppc] [PATCH 7/7] target/ppc: Use non-arithmetic conversions for fp load/store |
Date: |
Thu, 5 Jul 2018 12:31:06 -0400 |
> On Jul 3, 2018, at 11:17 AM, Richard Henderson <address@hidden> wrote:
>
> Memory operations have no side effects on fp state.
> The use of a "real" conversions between float64 and float32
> would raise exceptions for SNaN and out-of-range inputs.
Would you have any documentation that tells us about converting
between 64 bit and 32 bit floating points?
>
> Signed-off-by: Richard Henderson <address@hidden>
> ---
> target/ppc/helper.h | 4 +-
> target/ppc/fpu_helper.c | 63 ++++++++++++++++++++++++------
> target/ppc/translate/fp-impl.inc.c | 26 +++++-------
> 3 files changed, 62 insertions(+), 31 deletions(-)
>
> diff --git a/target/ppc/helper.h b/target/ppc/helper.h
> index cc3d031407..33e6e1df60 100644
> --- a/target/ppc/helper.h
> +++ b/target/ppc/helper.h
> @@ -61,8 +61,8 @@ DEF_HELPER_2(compute_fprf_float64, void, env, i64)
> DEF_HELPER_3(store_fpscr, void, env, i64, i32)
> DEF_HELPER_2(fpscr_clrbit, void, env, i32)
> DEF_HELPER_2(fpscr_setbit, void, env, i32)
> -DEF_HELPER_2(float64_to_float32, i32, env, i64)
> -DEF_HELPER_2(float32_to_float64, i64, env, i32)
> +DEF_HELPER_FLAGS_1(todouble, TCG_CALL_NO_RWG_SE, i64, i32)
> +DEF_HELPER_FLAGS_1(tosingle, TCG_CALL_NO_RWG_SE, i32, i64)
>
> DEF_HELPER_4(fcmpo, void, env, i64, i64, i32)
> DEF_HELPER_4(fcmpu, void, env, i64, i64, i32)
> diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
> index 1e195487d3..d4e9e3bccb 100644
> --- a/target/ppc/fpu_helper.c
> +++ b/target/ppc/fpu_helper.c
> @@ -47,24 +47,61 @@ static inline bool fp_exceptions_enabled(CPUPPCState *env)
>
> /*****************************************************************************/
> /* Floating point operations helpers */
> -uint64_t helper_float32_to_float64(CPUPPCState *env, uint32_t arg)
> -{
> - CPU_FloatU f;
> - CPU_DoubleU d;
>
> - f.l = arg;
> - d.d = float32_to_float64(f.f, &env->fp_status);
> - return d.ll;
> +/*
> + * This is the non-arithmatic conversion that happens e.g. on loads.
> + * In the Power ISA pseudocode, this is called DOUBLE.
> + */
> +uint64_t helper_todouble(uint32_t arg)
> +{
> + uint32_t abs_arg = arg & 0x7fffffff;
> + uint64_t ret;
> +
> + if (likely(abs_arg >= 0x00800000)) {
> + /* Normalized operand, or Inf, or NaN. */
> + ret = (uint64_t)extract32(arg, 30, 2) << 62;
> + ret |= ((extract32(arg, 30, 1) ^ 1) * (uint64_t)7) << 59;
> + ret |= (uint64_t)extract32(arg, 0, 29) << 29;
> + } else {
> + /* Zero or Denormalized operand. */
> + ret = (uint64_t)extract32(arg, 31, 1) << 63;
> + if (unlikely(abs_arg != 0)) {
> + /* Denormalized operand. */
> + int shift = clz32(abs_arg) - 9;
> + int exp = -126 - shift + 1023;
> + ret |= (uint64_t)exp << 52;
> + ret |= abs_arg << (shift + 29);
> + }
> + }
> + return ret;
> }
>
> -uint32_t helper_float64_to_float32(CPUPPCState *env, uint64_t arg)
> +/*
> + * This is the non-arithmatic conversion that happens e.g. on stores.
> + * In the Power ISA pseudocode, this is called SINGLE.
> + */
> +uint32_t helper_tosingle(uint64_t arg)
> {
> - CPU_FloatU f;
> - CPU_DoubleU d;
> + int exp = extract64(arg, 52, 11);
> + uint32_t ret;
>
> - d.ll = arg;
> - f.f = float64_to_float32(d.d, &env->fp_status);
> - return f.l;
> + if (likely(exp > 896)) {
> + /* No denormalization required (includes Inf, NaN). */
> + ret = extract64(arg, 62, 2) << 30;
> + ret |= extract64(arg, 29, 29);
> + } else {
> + /* Zero or Denormal result. If the exponent is in bounds for
> + * a single-precision denormal result, extract the proper bits.
> + * If the input is not zero, and the exponent is out of bounds,
> + * then the result is undefined; this underflows to zero.
> + */
> + ret = extract64(arg, 63, 1) << 63;
> + if (unlikely(exp >= 874)) {
> + /* Denormal result. */
> + ret |= ((1ULL << 52) | extract64(arg, 0, 52)) >> (896 + 30 -
> exp);
> + }
> + }
> + return ret;
> }
>
> static inline int ppc_float32_get_unbiased_exp(float32 f)
> diff --git a/target/ppc/translate/fp-impl.inc.c
> b/target/ppc/translate/fp-impl.inc.c
> index 2fbd4d4f38..a6f522b85c 100644
> --- a/target/ppc/translate/fp-impl.inc.c
> +++ b/target/ppc/translate/fp-impl.inc.c
> @@ -660,15 +660,12 @@ GEN_LDUF(name, ldop, op | 0x21, type);
> \
> GEN_LDUXF(name, ldop, op | 0x01, type);
> \
> GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
>
> -static inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv
> arg2)
> +static void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 dest, TCGv addr)
> {
> - TCGv t0 = tcg_temp_new();
> - TCGv_i32 t1 = tcg_temp_new_i32();
> - gen_qemu_ld32u(ctx, t0, arg2);
> - tcg_gen_trunc_tl_i32(t1, t0);
> - tcg_temp_free(t0);
> - gen_helper_float32_to_float64(arg1, cpu_env, t1);
> - tcg_temp_free_i32(t1);
> + TCGv_i32 tmp = tcg_temp_new_i32();
> + tcg_gen_qemu_ld_i32(tmp, addr, ctx->mem_idx, DEF_MEMOP(MO_UL));
> + gen_helper_todouble(dest, tmp);
> + tcg_temp_free_i32(tmp);
> }
>
> /* lfd lfdu lfdux lfdx */
> @@ -836,15 +833,12 @@ GEN_STUF(name, stop, op | 0x21, type);
> \
> GEN_STUXF(name, stop, op | 0x01, type);
> \
> GEN_STXF(name, stop, 0x17, op | 0x00, type)
>
> -static inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv
> arg2)
> +static void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 src, TCGv addr)
> {
> - TCGv_i32 t0 = tcg_temp_new_i32();
> - TCGv t1 = tcg_temp_new();
> - gen_helper_float64_to_float32(t0, cpu_env, arg1);
> - tcg_gen_extu_i32_tl(t1, t0);
> - tcg_temp_free_i32(t0);
> - gen_qemu_st32(ctx, t1, arg2);
> - tcg_temp_free(t1);
> + TCGv_i32 tmp = tcg_temp_new_i32();
> + gen_helper_tosingle(tmp, src);
> + tcg_gen_qemu_st_i32(tmp, addr, ctx->mem_idx, DEF_MEMOP(MO_UL));
> + tcg_temp_free_i32(tmp);
> }
>
> /* stfd stfdu stfdux stfdx */
> --
> 2.17.1
>
- [Qemu-ppc] [PATCH for-3.1 0/7] target/ppc fp cleanups, Richard Henderson, 2018/07/03
- [Qemu-ppc] [PATCH 1/7] target/ppc: Enable fp exceptions for user-only, Richard Henderson, 2018/07/03
- [Qemu-ppc] [PATCH 2/7] target/ppc: Honor fpscr_ze semantics and tidy fdiv, Richard Henderson, 2018/07/03
- [Qemu-ppc] [PATCH 4/7] target/ppc: Tidy helper_fadd, helper_fsub, Richard Henderson, 2018/07/03
- [Qemu-ppc] [PATCH 3/7] target/ppc: Tidy helper_fmul, Richard Henderson, 2018/07/03
- [Qemu-ppc] [PATCH 5/7] target/ppc: Tidy helper_fsqrt, Richard Henderson, 2018/07/03
- [Qemu-ppc] [PATCH 6/7] target/ppc: Honor fpscr_ze semantics and tidy fre, fresqrt, Richard Henderson, 2018/07/03
- [Qemu-ppc] [PATCH 7/7] target/ppc: Use non-arithmetic conversions for fp load/store, Richard Henderson, 2018/07/03
Re: [Qemu-ppc] [PATCH for-3.1 0/7] target/ppc fp cleanups, David Gibson, 2018/07/04
Re: [Qemu-ppc] [Qemu-devel] [PATCH for-3.1 0/7] target/ppc fp cleanups, Alex Bennée, 2018/07/04