qemu-riscv
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] riscv: Add support for the Zfa extension


From: Richard Henderson
Subject: Re: [PATCH] riscv: Add support for the Zfa extension
Date: Mon, 27 Mar 2023 10:18:05 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.8.0

On 3/27/23 01:00, Christoph Muellner wrote:
+uint64_t helper_fminm_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
+{
+    float32 frs1 = check_nanbox_s(env, rs1);
+    float32 frs2 = check_nanbox_s(env, rs2);
+
+    if (float32_is_any_nan(frs1) || float32_is_any_nan(frs2)) {
+        return float32_default_nan(&env->fp_status);
+    }
+
+    return nanbox_s(env, float32_minimum_number(frs1, frs2, &env->fp_status));
+}

Better to set and clear fp_status->default_nan_mode around the operation.

+uint64_t helper_fround_s(CPURISCVState *env, uint64_t frs1)
+{
+    if (float32_is_zero(frs1) ||
+        float32_is_infinity(frs1)) {
+        return frs1;
+    }
+
+    if (float32_is_any_nan(frs1)) {
+        riscv_cpu_set_fflags(env, FPEXC_NV);
+        return frs1;
+    }
+
+    int32_t tmp = float32_to_int32(frs1, &env->fp_status);
+    return nanbox_s(env, int32_to_float32(tmp, &env->fp_status));
+}

Very much incorrect, since int32_t does not have the range for the intermediate result. In any case, the function you want is float32_round_to_int, which eliminates the zero/inf/nan special cases. It will raise inexact, so perfect for froundnx, but you'll need to save/restore float_flag_inexact around the function.

+uint64_t helper_fli_s(CPURISCVState *env, uint32_t rs1)
+{
+    const uint32_t fli_s_table[] = {

static const. You don't need to use float32_default_nan, use the correct architected constant. This entire operation should be done at translation time.

+target_ulong helper_fcvtmod_w_d(CPURISCVState *env, uint64_t frs1)
+{
+    if (float64_is_any_nan(frs1) ||
+        float64_is_infinity(frs1)) {
+        return 0;
+    }
+
+    return float64_to_int32(frs1, &env->fp_status);
+}

Incorrect, as float64_to_int32 will saturate the result, whereas you need the 
modular result.

There is code to do the conversion mod 2**64 in target/alpha/ (do_cvttq). We should move this to generic code if it is to be used by more than one target.

+bool trans_fmvp_d_x(DisasContext *ctx, arg_fmvp_d_x *a)
+{
+    REQUIRE_FPU;
+    REQUIRE_ZFA(ctx);
+    REQUIRE_EXT(ctx, RVD);
+    REQUIRE_32BIT(ctx);
+
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
+    TCGv_i64 t1 = tcg_temp_new_i64();
+
+    tcg_gen_extu_tl_i64(t1, src1);
+    tcg_gen_deposit_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], t1, 32, 32);
+    mark_fs_dirty(ctx);
+    return true;
+}

This does not match the linked document, which says that this insn has two inputs and sets the complete fpr.


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]