On Tue, Jan 12, 2021 at 1:55 AM <frank.ch...@sifive.com> wrote: > > From: Frank Chang <frank.ch...@sifive.com> > > * 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.ch...@sifive.com> > Reviewed-by: Richard Henderson <richard.hender...@linaro.org>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > target/riscv/insn_trans/trans_rvv.c.inc | 35 ++++++++++++++++++++++++- > target/riscv/translate.c | 10 +++++++ > 2 files changed, 44 insertions(+), 1 deletion(-) > > diff --git a/target/riscv/insn_trans/trans_rvv.c.inc > b/target/riscv/insn_trans/trans_rvv.c.inc > index 18a1c409fcf..ccfa93cf2f8 100644 > --- a/target/riscv/insn_trans/trans_rvv.c.inc > +++ b/target/riscv/insn_trans/trans_rvv.c.inc > @@ -2100,6 +2100,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 */ > > /* > @@ -2152,6 +2179,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); > @@ -2165,12 +2193,17 @@ 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_i32(desc); > + tcg_temp_free_i64(t1); > mark_vs_dirty(s); > gen_set_label(over); > return true; > diff --git a/target/riscv/translate.c b/target/riscv/translate.c > index d9b3b37f698..511b7b868f5 100644 > --- a/target/riscv/translate.c > +++ b/target/riscv/translate.c > @@ -122,6 +122,16 @@ static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in) > * > * Here, the result is always nan-boxed, even the canonical nan. > */ > +static void gen_check_nanbox_h(TCGv_i64 out, TCGv_i64 in) > +{ > + TCGv_i64 t_max = tcg_const_i64(0xffffffffffff0000ull); > + TCGv_i64 t_nan = tcg_const_i64(0xffffffffffff7e00ull); > + > + tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan); > + tcg_temp_free_i64(t_max); > + tcg_temp_free_i64(t_nan); > +} > + > static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in) > { > TCGv_i64 t_max = tcg_const_i64(0xffffffff00000000ull); > -- > 2.17.1 > >