diff options
author | Frank Chang <frank.chang@sifive.com> | 2021-12-10 15:56:03 +0800 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2021-12-20 14:51:36 +1000 |
commit | 9b4a40a78603956344404c53cc355c2ea1ee70c3 (patch) | |
tree | 3dcf277b3c487f674c7f064024f813719cd1dde0 | |
parent | ff64fc91d1fdf8fe71394d81ba35f33410731d8e (diff) |
target/riscv: rvv:1.0: add translation-time nan-box helper function
* Add fp16 nan-box check generator function, if a 16-bit input is not
properly nanboxed, then the input is replaced with the default qnan.
* Add do_nanbox() helper function to utilize gen_check_nanbox_X() to
generate the NaN-boxed floating-point values based on SEW setting.
* Apply nanbox helper in opfvf_trans().
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20211210075704.23951-18-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
-rw-r--r-- | target/riscv/insn_trans/trans_rvv.c.inc | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc index 66273afb53..f9ace6ae41 100644 --- a/target/riscv/insn_trans/trans_rvv.c.inc +++ b/target/riscv/insn_trans/trans_rvv.c.inc @@ -2098,6 +2098,33 @@ GEN_OPIVI_NARROW_TRANS(vnclip_vi, IMM_ZX, vnclip_vx) /* *** Vector Float Point Arithmetic Instructions */ + +/* + * As RVF-only cpus always have values NaN-boxed to 64-bits, + * RVF and RVD can be treated equally. + * We don't have to deal with the cases of: SEW > FLEN. + * + * If SEW < FLEN, check whether input fp register is a valid + * NaN-boxed value, in which case the least-significant SEW bits + * of the f regsiter are used, else the canonical NaN value is used. + */ +static void do_nanbox(DisasContext *s, TCGv_i64 out, TCGv_i64 in) +{ + switch (s->sew) { + case 1: + gen_check_nanbox_h(out, in); + break; + case 2: + gen_check_nanbox_s(out, in); + break; + case 3: + tcg_gen_mov_i64(out, in); + break; + default: + g_assert_not_reached(); + } +} + /* Vector Single-Width Floating-Point Add/Subtract Instructions */ /* @@ -2151,6 +2178,7 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, { TCGv_ptr dest, src2, mask; TCGv_i32 desc; + TCGv_i64 t1; TCGLabel *over = gen_new_label(); tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); @@ -2164,11 +2192,16 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2)); tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0)); - fn(dest, mask, cpu_fpr[rs1], src2, cpu_env, desc); + /* NaN-box f[rs1] */ + t1 = tcg_temp_new_i64(); + do_nanbox(s, t1, cpu_fpr[rs1]); + + fn(dest, mask, t1, src2, cpu_env, desc); tcg_temp_free_ptr(dest); tcg_temp_free_ptr(mask); tcg_temp_free_ptr(src2); + tcg_temp_free_i64(t1); mark_vs_dirty(s); gen_set_label(over); return true; |