From: Frank Chang <frank.ch...@sifive.com> For floating-point operations, the scalar can be taken from a scalar f register. If FLEN > SEW, the value in the f registers is checked for a valid NaN-boxed value, in which case the least-significant SEW bits of the f register are used, else the canonical NaN value is used.
Add helper to generate the correspond NaN-boxed value or the SEW-bit canonical NaN for floating-point operations. Signed-off-by: Frank Chang <frank.ch...@sifive.com> --- target/riscv/helper.h | 2 ++ target/riscv/vector_helper.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index acc298219d..3cbd66a887 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1150,3 +1150,5 @@ DEF_HELPER_6(vcompress_vm_b, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vcompress_vm_h, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vcompress_vm_w, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vcompress_vm_d, void, ptr, ptr, ptr, ptr, env, i32) + +DEF_HELPER_3(narrower_nanbox_fpr, i64, i64, i32, env) diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 83e317c500..fb689ab3f9 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -3207,6 +3207,38 @@ GEN_VEXT_VX_RM(vnclipu_vx_w, 4, 4, clearl) /* *** Vector Float Point Arithmetic Instructions */ + +/* + * For SEW < FLEN, + * if f is not correctly NaN-boxed for SEW bits, + * canonical SEW-bit NaN is returned. + * Otherwise, original f is returned. + */ +static uint64_t narrower_nanbox_fpr(uint64_t f, uint32_t sew, float_status *s) +{ + uint64_t mask = MAKE_64BIT_MASK(sew, 64 - sew); + if ((f & mask) == mask) { + return f; + } else { + switch (sew) { + case 16: + return float16_default_nan(s); + case 32: + return float32_default_nan(s); + case 64: + return float64_default_nan(s); + default: + g_assert_not_reached(); + } + } +} + +uint64_t HELPER(narrower_nanbox_fpr)(uint64_t f, uint32_t sew, + CPURISCVState *env) +{ + return narrower_nanbox_fpr(f, sew, &env->fp_status); +} + /* Vector Single-Width Floating-Point Add/Subtract Instructions */ #define OPFVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \ static void do_##NAME(void *vd, void *vs1, void *vs2, int i, \ -- 2.17.1