diff mbox series

[v2,4/7] target/riscv: Check nanboxed inputs to fp helpers

Message ID 20200724002807.441147-5-richard.henderson@linaro.org
State New
Headers show
Series target/riscv: NaN-boxing for multiple precison | expand

Commit Message

Richard Henderson July 24, 2020, 12:28 a.m. UTC
If a 32-bit input is not properly nanboxed, then the input is
replaced with the default qnan.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 target/riscv/internals.h  | 11 +++++++
 target/riscv/fpu_helper.c | 64 ++++++++++++++++++++++++++++-----------
 2 files changed, 57 insertions(+), 18 deletions(-)

-- 
2.25.1

Comments

LIU Zhiwei July 24, 2020, 2:47 a.m. UTC | #1
On 2020/7/24 8:28, Richard Henderson wrote:
> If a 32-bit input is not properly nanboxed, then the input is

> replaced with the default qnan.

>

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> ---

>   target/riscv/internals.h  | 11 +++++++

>   target/riscv/fpu_helper.c | 64 ++++++++++++++++++++++++++++-----------

>   2 files changed, 57 insertions(+), 18 deletions(-)

>

> diff --git a/target/riscv/internals.h b/target/riscv/internals.h

> index 9f4ba7d617..f1a546dba6 100644

> --- a/target/riscv/internals.h

> +++ b/target/riscv/internals.h

> @@ -43,4 +43,15 @@ static inline uint64_t nanbox_s(float32 f)

>       return f | MAKE_64BIT_MASK(32, 32);

>   }

>   

> +static inline float32 check_nanbox_s(uint64_t f)

> +{

> +    uint64_t mask = MAKE_64BIT_MASK(32, 32);

> +

> +    if (likely((f & mask) == mask)) {

> +        return (uint32_t)f;

> +    } else {

> +        return 0x7fc00000u; /* default qnan */

> +    }

> +}

> +

If possible,

+static inline float32 check_nanbox(uint64_t f, uint32_t flen)
+{
+    uint64_t mask = MAKE_64BIT_MASK(flen, 64 - flen);
+
+    if (likely((f & mask) == mask)) {
+        return (uint32_t)f;
+    } else {
+        return (flen == 32) ? 0x7fc00000u : 0x7e00u; /* default qnan */
+    }
+}
+

Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>


Zhiwei
>   #endif

> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c

> index 72541958a7..bb346a8249 100644

> --- a/target/riscv/fpu_helper.c

> +++ b/target/riscv/fpu_helper.c

> @@ -81,9 +81,12 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)

>       set_float_rounding_mode(softrm, &env->fp_status);

>   }

>   

> -static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,

> -                           uint64_t frs3, int flags)

> +static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2,

> +                           uint64_t rs3, int flags)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

> +    float32 frs3 = check_nanbox_s(rs3);

>       return nanbox_s(float32_muladd(frs1, frs2, frs3, flags, &env->fp_status));

>   }

>   

> @@ -139,74 +142,97 @@ uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,

>                             float_muladd_negate_product, &env->fp_status);

>   }

>   

> -uint64_t helper_fadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>       return nanbox_s(float32_add(frs1, frs2, &env->fp_status));

>   }

>   

> -uint64_t helper_fsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +uint64_t helper_fsub_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>       return nanbox_s(float32_sub(frs1, frs2, &env->fp_status));

>   }

>   

> -uint64_t helper_fmul_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +uint64_t helper_fmul_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>       return nanbox_s(float32_mul(frs1, frs2, &env->fp_status));

>   }

>   

> -uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>       return nanbox_s(float32_div(frs1, frs2, &env->fp_status));

>   }

>   

> -uint64_t helper_fmin_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>       return nanbox_s(float32_minnum(frs1, frs2, &env->fp_status));

>   }

>   

> -uint64_t helper_fmax_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>       return nanbox_s(float32_maxnum(frs1, frs2, &env->fp_status));

>   }

>   

> -uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t frs1)

> +uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

>       return nanbox_s(float32_sqrt(frs1, &env->fp_status));

>   }

>   

> -target_ulong helper_fle_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +target_ulong helper_fle_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>       return float32_le(frs1, frs2, &env->fp_status);

>   }

>   

> -target_ulong helper_flt_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +target_ulong helper_flt_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>       return float32_lt(frs1, frs2, &env->fp_status);

>   }

>   

> -target_ulong helper_feq_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +target_ulong helper_feq_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>       return float32_eq_quiet(frs1, frs2, &env->fp_status);

>   }

>   

> -target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t frs1)

> +target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t rs1)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

>       return float32_to_int32(frs1, &env->fp_status);

>   }

>   

> -target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t frs1)

> +target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t rs1)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

>       return (int32_t)float32_to_uint32(frs1, &env->fp_status);

>   }

>   

>   #if defined(TARGET_RISCV64)

> -uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t frs1)

> +uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t rs1)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

>       return float32_to_int64(frs1, &env->fp_status);

>   }

>   

> -uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t frs1)

> +uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t rs1)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

>       return float32_to_uint64(frs1, &env->fp_status);

>   }

>   #endif

> @@ -233,8 +259,9 @@ uint64_t helper_fcvt_s_lu(CPURISCVState *env, uint64_t rs1)

>   }

>   #endif

>   

> -target_ulong helper_fclass_s(uint64_t frs1)

> +target_ulong helper_fclass_s(uint64_t rs1)

>   {

> +    float32 frs1 = check_nanbox_s(rs1);

>       return fclass_s(frs1);

>   }

>   

> @@ -275,7 +302,8 @@ uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)

>   

>   uint64_t helper_fcvt_d_s(CPURISCVState *env, uint64_t rs1)

>   {

> -    return float32_to_float64(rs1, &env->fp_status);

> +    float32 frs1 = check_nanbox_s(rs1);

> +    return float32_to_float64(frs1, &env->fp_status);

>   }

>   

>   uint64_t helper_fsqrt_d(CPURISCVState *env, uint64_t frs1)
Richard Henderson July 24, 2020, 3:59 a.m. UTC | #2
On 7/23/20 7:47 PM, LIU Zhiwei wrote:
> 

> 

> On 2020/7/24 8:28, Richard Henderson wrote:

>> If a 32-bit input is not properly nanboxed, then the input is

>> replaced with the default qnan.

>>

>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

>> ---

>>   target/riscv/internals.h  | 11 +++++++

>>   target/riscv/fpu_helper.c | 64 ++++++++++++++++++++++++++++-----------

>>   2 files changed, 57 insertions(+), 18 deletions(-)

>>

>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h

>> index 9f4ba7d617..f1a546dba6 100644

>> --- a/target/riscv/internals.h

>> +++ b/target/riscv/internals.h

>> @@ -43,4 +43,15 @@ static inline uint64_t nanbox_s(float32 f)

>>       return f | MAKE_64BIT_MASK(32, 32);

>>   }

>>   +static inline float32 check_nanbox_s(uint64_t f)

>> +{

>> +    uint64_t mask = MAKE_64BIT_MASK(32, 32);

>> +

>> +    if (likely((f & mask) == mask)) {

>> +        return (uint32_t)f;

>> +    } else {

>> +        return 0x7fc00000u; /* default qnan */

>> +    }

>> +}

>> +

> If possible,

> 

> +static inline float32 check_nanbox(uint64_t f, uint32_t flen)

> +{

> +    uint64_t mask = MAKE_64BIT_MASK(flen, 64 - flen);

> +

> +    if (likely((f & mask) == mask)) {

> +        return (uint32_t)f;

> +    } else {

> +        return (flen == 32) ? 0x7fc00000u : 0x7e00u; /* default qnan */

> +    }

> +}


The difficulty of choosing the proper default qnan is an example of why we
should *not* attempt to make this function fully general, but should instead
define separate functions for each type.  E.g.

static inline float16 check_nanbox_h(uint64_t f);
static inline bfloat16 check_nanbox_b(uint64_t f);


r~
Chih-Min Chao Aug. 6, 2020, 6:26 a.m. UTC | #3
On Fri, Jul 24, 2020 at 8:29 AM Richard Henderson <
richard.henderson@linaro.org> wrote:

> If a 32-bit input is not properly nanboxed, then the input is

> replaced with the default qnan.

>

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> ---

>  target/riscv/internals.h  | 11 +++++++

>  target/riscv/fpu_helper.c | 64 ++++++++++++++++++++++++++++-----------

>  2 files changed, 57 insertions(+), 18 deletions(-)

>

> diff --git a/target/riscv/internals.h b/target/riscv/internals.h

> index 9f4ba7d617..f1a546dba6 100644

> --- a/target/riscv/internals.h

> +++ b/target/riscv/internals.h

> @@ -43,4 +43,15 @@ static inline uint64_t nanbox_s(float32 f)

>      return f | MAKE_64BIT_MASK(32, 32);

>  }

>

> +static inline float32 check_nanbox_s(uint64_t f)

> +{

> +    uint64_t mask = MAKE_64BIT_MASK(32, 32);

> +

> +    if (likely((f & mask) == mask)) {

> +        return (uint32_t)f;

> +    } else {

> +        return 0x7fc00000u; /* default qnan */

> +    }

> +}

> +

>  #endif

> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c

> index 72541958a7..bb346a8249 100644

> --- a/target/riscv/fpu_helper.c

> +++ b/target/riscv/fpu_helper.c

> @@ -81,9 +81,12 @@ void helper_set_rounding_mode(CPURISCVState *env,

> uint32_t rm)

>      set_float_rounding_mode(softrm, &env->fp_status);

>  }

>

> -static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t

> frs2,

> -                           uint64_t frs3, int flags)

> +static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2,

> +                           uint64_t rs3, int flags)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

> +    float32 frs3 = check_nanbox_s(rs3);

>      return nanbox_s(float32_muladd(frs1, frs2, frs3, flags,

> &env->fp_status));

>  }

>

> @@ -139,74 +142,97 @@ uint64_t helper_fnmadd_d(CPURISCVState *env,

> uint64_t frs1, uint64_t frs2,

>                            float_muladd_negate_product, &env->fp_status);

>  }

>

> -uint64_t helper_fadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>      return nanbox_s(float32_add(frs1, frs2, &env->fp_status));

>  }

>

> -uint64_t helper_fsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +uint64_t helper_fsub_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>      return nanbox_s(float32_sub(frs1, frs2, &env->fp_status));

>  }

>

> -uint64_t helper_fmul_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +uint64_t helper_fmul_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>      return nanbox_s(float32_mul(frs1, frs2, &env->fp_status));

>  }

>

> -uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>      return nanbox_s(float32_div(frs1, frs2, &env->fp_status));

>  }

>

> -uint64_t helper_fmin_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>      return nanbox_s(float32_minnum(frs1, frs2, &env->fp_status));

>  }

>

> -uint64_t helper_fmax_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)

> +uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>      return nanbox_s(float32_maxnum(frs1, frs2, &env->fp_status));

>  }

>

> -uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t frs1)

> +uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

>      return nanbox_s(float32_sqrt(frs1, &env->fp_status));

>  }

>

> -target_ulong helper_fle_s(CPURISCVState *env, uint64_t frs1, uint64_t

> frs2)

> +target_ulong helper_fle_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>      return float32_le(frs1, frs2, &env->fp_status);

>  }

>

> -target_ulong helper_flt_s(CPURISCVState *env, uint64_t frs1, uint64_t

> frs2)

> +target_ulong helper_flt_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>      return float32_lt(frs1, frs2, &env->fp_status);

>  }

>

> -target_ulong helper_feq_s(CPURISCVState *env, uint64_t frs1, uint64_t

> frs2)

> +target_ulong helper_feq_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

> +    float32 frs2 = check_nanbox_s(rs2);

>      return float32_eq_quiet(frs1, frs2, &env->fp_status);

>  }

>

> -target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t frs1)

> +target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t rs1)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

>      return float32_to_int32(frs1, &env->fp_status);

>  }

>

> -target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t frs1)

> +target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t rs1)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

>      return (int32_t)float32_to_uint32(frs1, &env->fp_status);

>  }

>

>  #if defined(TARGET_RISCV64)

> -uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t frs1)

> +uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t rs1)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

>      return float32_to_int64(frs1, &env->fp_status);

>  }

>

> -uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t frs1)

> +uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t rs1)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

>      return float32_to_uint64(frs1, &env->fp_status);

>  }

>  #endif

> @@ -233,8 +259,9 @@ uint64_t helper_fcvt_s_lu(CPURISCVState *env, uint64_t

> rs1)

>  }

>  #endif

>

> -target_ulong helper_fclass_s(uint64_t frs1)

> +target_ulong helper_fclass_s(uint64_t rs1)

>  {

> +    float32 frs1 = check_nanbox_s(rs1);

>      return fclass_s(frs1);

>  }

>

> @@ -275,7 +302,8 @@ uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t

> rs1)

>

>  uint64_t helper_fcvt_d_s(CPURISCVState *env, uint64_t rs1)

>  {

> -    return float32_to_float64(rs1, &env->fp_status);

> +    float32 frs1 = check_nanbox_s(rs1);

> +    return float32_to_float64(frs1, &env->fp_status);

>  }

>

>  uint64_t helper_fsqrt_d(CPURISCVState *env, uint64_t frs1)

> --

> 2.25.1

>

>

>

Reviewed-by: Chih-Min Chao <chihmin.chao@sifive.com>


Chih-Min Chao
<div dir="ltr"><div dir="ltr"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr">On Fri, Jul 24, 2020 at 8:29 AM Richard Henderson &lt;<a href="mailto:richard.henderson@linaro.org">richard.henderson@linaro.org</a>&gt; wrote:<br></div></div></div></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">If a 32-bit input is not properly nanboxed, then the input is<br>
replaced with the default qnan.<br>
<br>
Signed-off-by: Richard Henderson &lt;<a href="mailto:richard.henderson@linaro.org" target="_blank">richard.henderson@linaro.org</a>&gt;<br>

---<br>
 target/riscv/internals.h  | 11 +++++++<br>
 target/riscv/fpu_helper.c | 64 ++++++++++++++++++++++++++++-----------<br>
 2 files changed, 57 insertions(+), 18 deletions(-)<br>
<br>
diff --git a/target/riscv/internals.h b/target/riscv/internals.h<br>
index 9f4ba7d617..f1a546dba6 100644<br>
--- a/target/riscv/internals.h<br>
+++ b/target/riscv/internals.h<br>
@@ -43,4 +43,15 @@ static inline uint64_t nanbox_s(float32 f)<br>
     return f | MAKE_64BIT_MASK(32, 32);<br>
 }<br>
<br>
+static inline float32 check_nanbox_s(uint64_t f)<br>
+{<br>
+    uint64_t mask = MAKE_64BIT_MASK(32, 32);<br>
+<br>
+    if (likely((f &amp; mask) == mask)) {<br>
+        return (uint32_t)f;<br>
+    } else {<br>
+        return 0x7fc00000u; /* default qnan */<br>
+    }<br>
+}<br>
+<br>
 #endif<br>
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c<br>
index 72541958a7..bb346a8249 100644<br>
--- a/target/riscv/fpu_helper.c<br>
+++ b/target/riscv/fpu_helper.c<br>
@@ -81,9 +81,12 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)<br>
     set_float_rounding_mode(softrm, &amp;env-&gt;fp_status);<br>
 }<br>
<br>
-static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,<br>
-                           uint64_t frs3, int flags)<br>
+static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2,<br>
+                           uint64_t rs3, int flags)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
+    float32 frs2 = check_nanbox_s(rs2);<br>
+    float32 frs3 = check_nanbox_s(rs3);<br>
     return nanbox_s(float32_muladd(frs1, frs2, frs3, flags, &amp;env-&gt;fp_status));<br>
 }<br>
<br>
@@ -139,74 +142,97 @@ uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,<br>
                           float_muladd_negate_product, &amp;env-&gt;fp_status);<br>
 }<br>
<br>
-uint64_t helper_fadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)<br>
+uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
+    float32 frs2 = check_nanbox_s(rs2);<br>
     return nanbox_s(float32_add(frs1, frs2, &amp;env-&gt;fp_status));<br>
 }<br>
<br>
-uint64_t helper_fsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)<br>
+uint64_t helper_fsub_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
+    float32 frs2 = check_nanbox_s(rs2);<br>
     return nanbox_s(float32_sub(frs1, frs2, &amp;env-&gt;fp_status));<br>
 }<br>
<br>
-uint64_t helper_fmul_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)<br>
+uint64_t helper_fmul_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
+    float32 frs2 = check_nanbox_s(rs2);<br>
     return nanbox_s(float32_mul(frs1, frs2, &amp;env-&gt;fp_status));<br>
 }<br>
<br>
-uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)<br>
+uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
+    float32 frs2 = check_nanbox_s(rs2);<br>
     return nanbox_s(float32_div(frs1, frs2, &amp;env-&gt;fp_status));<br>
 }<br>
<br>
-uint64_t helper_fmin_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)<br>
+uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
+    float32 frs2 = check_nanbox_s(rs2);<br>
     return nanbox_s(float32_minnum(frs1, frs2, &amp;env-&gt;fp_status));<br>
 }<br>
<br>
-uint64_t helper_fmax_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)<br>
+uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
+    float32 frs2 = check_nanbox_s(rs2);<br>
     return nanbox_s(float32_maxnum(frs1, frs2, &amp;env-&gt;fp_status));<br>
 }<br>
<br>
-uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t frs1)<br>
+uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
     return nanbox_s(float32_sqrt(frs1, &amp;env-&gt;fp_status));<br>
 }<br>
<br>
-target_ulong helper_fle_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)<br>
+target_ulong helper_fle_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
+    float32 frs2 = check_nanbox_s(rs2);<br>
     return float32_le(frs1, frs2, &amp;env-&gt;fp_status);<br>
 }<br>
<br>
-target_ulong helper_flt_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)<br>
+target_ulong helper_flt_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
+    float32 frs2 = check_nanbox_s(rs2);<br>
     return float32_lt(frs1, frs2, &amp;env-&gt;fp_status);<br>
 }<br>
<br>
-target_ulong helper_feq_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)<br>
+target_ulong helper_feq_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
+    float32 frs2 = check_nanbox_s(rs2);<br>
     return float32_eq_quiet(frs1, frs2, &amp;env-&gt;fp_status);<br>
 }<br>
<br>
-target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t frs1)<br>
+target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t rs1)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
     return float32_to_int32(frs1, &amp;env-&gt;fp_status);<br>
 }<br>
<br>
-target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t frs1)<br>
+target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t rs1)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
     return (int32_t)float32_to_uint32(frs1, &amp;env-&gt;fp_status);<br>
 }<br>
<br>
 #if defined(TARGET_RISCV64)<br>
-uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t frs1)<br>
+uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t rs1)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
     return float32_to_int64(frs1, &amp;env-&gt;fp_status);<br>
 }<br>
<br>
-uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t frs1)<br>
+uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t rs1)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
     return float32_to_uint64(frs1, &amp;env-&gt;fp_status);<br>
 }<br>
 #endif<br>
@@ -233,8 +259,9 @@ uint64_t helper_fcvt_s_lu(CPURISCVState *env, uint64_t rs1)<br>
 }<br>
 #endif<br>
<br>
-target_ulong helper_fclass_s(uint64_t frs1)<br>
+target_ulong helper_fclass_s(uint64_t rs1)<br>
 {<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
     return fclass_s(frs1);<br>
 }<br>
<br>
@@ -275,7 +302,8 @@ uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)<br>
<br>
 uint64_t helper_fcvt_d_s(CPURISCVState *env, uint64_t rs1)<br>
 {<br>
-    return float32_to_float64(rs1, &amp;env-&gt;fp_status);<br>
+    float32 frs1 = check_nanbox_s(rs1);<br>
+    return float32_to_float64(frs1, &amp;env-&gt;fp_status);<br>
 }<br>
<br>
 uint64_t helper_fsqrt_d(CPURISCVState *env, uint64_t frs1)<br>
-- <br>
2.25.1<br>
<br>
<br></blockquote><div><br></div><div>Reviewed-by: Chih-Min Chao &lt;<a href="mailto:chihmin.chao@sifive.com">chihmin.chao@sifive.com</a>&gt;</div><div><br></div><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><span style="color:rgb(136,136,136)">Chih-Min Chao</span><div style="color:rgb(136,136,136)"></div></div></div></div><div> </div></div></div>
diff mbox series

Patch

diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 9f4ba7d617..f1a546dba6 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -43,4 +43,15 @@  static inline uint64_t nanbox_s(float32 f)
     return f | MAKE_64BIT_MASK(32, 32);
 }
 
+static inline float32 check_nanbox_s(uint64_t f)
+{
+    uint64_t mask = MAKE_64BIT_MASK(32, 32);
+
+    if (likely((f & mask) == mask)) {
+        return (uint32_t)f;
+    } else {
+        return 0x7fc00000u; /* default qnan */
+    }
+}
+
 #endif
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index 72541958a7..bb346a8249 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -81,9 +81,12 @@  void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
     set_float_rounding_mode(softrm, &env->fp_status);
 }
 
-static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
-                           uint64_t frs3, int flags)
+static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
+                           uint64_t rs3, int flags)
 {
+    float32 frs1 = check_nanbox_s(rs1);
+    float32 frs2 = check_nanbox_s(rs2);
+    float32 frs3 = check_nanbox_s(rs3);
     return nanbox_s(float32_muladd(frs1, frs2, frs3, flags, &env->fp_status));
 }
 
@@ -139,74 +142,97 @@  uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
                           float_muladd_negate_product, &env->fp_status);
 }
 
-uint64_t helper_fadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
+    float32 frs1 = check_nanbox_s(rs1);
+    float32 frs2 = check_nanbox_s(rs2);
     return nanbox_s(float32_add(frs1, frs2, &env->fp_status));
 }
 
-uint64_t helper_fsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+uint64_t helper_fsub_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
+    float32 frs1 = check_nanbox_s(rs1);
+    float32 frs2 = check_nanbox_s(rs2);
     return nanbox_s(float32_sub(frs1, frs2, &env->fp_status));
 }
 
-uint64_t helper_fmul_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+uint64_t helper_fmul_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
+    float32 frs1 = check_nanbox_s(rs1);
+    float32 frs2 = check_nanbox_s(rs2);
     return nanbox_s(float32_mul(frs1, frs2, &env->fp_status));
 }
 
-uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
+    float32 frs1 = check_nanbox_s(rs1);
+    float32 frs2 = check_nanbox_s(rs2);
     return nanbox_s(float32_div(frs1, frs2, &env->fp_status));
 }
 
-uint64_t helper_fmin_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
+    float32 frs1 = check_nanbox_s(rs1);
+    float32 frs2 = check_nanbox_s(rs2);
     return nanbox_s(float32_minnum(frs1, frs2, &env->fp_status));
 }
 
-uint64_t helper_fmax_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
+    float32 frs1 = check_nanbox_s(rs1);
+    float32 frs2 = check_nanbox_s(rs2);
     return nanbox_s(float32_maxnum(frs1, frs2, &env->fp_status));
 }
 
-uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t frs1)
+uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)
 {
+    float32 frs1 = check_nanbox_s(rs1);
     return nanbox_s(float32_sqrt(frs1, &env->fp_status));
 }
 
-target_ulong helper_fle_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+target_ulong helper_fle_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
+    float32 frs1 = check_nanbox_s(rs1);
+    float32 frs2 = check_nanbox_s(rs2);
     return float32_le(frs1, frs2, &env->fp_status);
 }
 
-target_ulong helper_flt_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+target_ulong helper_flt_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
+    float32 frs1 = check_nanbox_s(rs1);
+    float32 frs2 = check_nanbox_s(rs2);
     return float32_lt(frs1, frs2, &env->fp_status);
 }
 
-target_ulong helper_feq_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+target_ulong helper_feq_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
+    float32 frs1 = check_nanbox_s(rs1);
+    float32 frs2 = check_nanbox_s(rs2);
     return float32_eq_quiet(frs1, frs2, &env->fp_status);
 }
 
-target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t frs1)
+target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t rs1)
 {
+    float32 frs1 = check_nanbox_s(rs1);
     return float32_to_int32(frs1, &env->fp_status);
 }
 
-target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t frs1)
+target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t rs1)
 {
+    float32 frs1 = check_nanbox_s(rs1);
     return (int32_t)float32_to_uint32(frs1, &env->fp_status);
 }
 
 #if defined(TARGET_RISCV64)
-uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t frs1)
+uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t rs1)
 {
+    float32 frs1 = check_nanbox_s(rs1);
     return float32_to_int64(frs1, &env->fp_status);
 }
 
-uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t frs1)
+uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t rs1)
 {
+    float32 frs1 = check_nanbox_s(rs1);
     return float32_to_uint64(frs1, &env->fp_status);
 }
 #endif
@@ -233,8 +259,9 @@  uint64_t helper_fcvt_s_lu(CPURISCVState *env, uint64_t rs1)
 }
 #endif
 
-target_ulong helper_fclass_s(uint64_t frs1)
+target_ulong helper_fclass_s(uint64_t rs1)
 {
+    float32 frs1 = check_nanbox_s(rs1);
     return fclass_s(frs1);
 }
 
@@ -275,7 +302,8 @@  uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
 
 uint64_t helper_fcvt_d_s(CPURISCVState *env, uint64_t rs1)
 {
-    return float32_to_float64(rs1, &env->fp_status);
+    float32 frs1 = check_nanbox_s(rs1);
+    return float32_to_float64(frs1, &env->fp_status);
 }
 
 uint64_t helper_fsqrt_d(CPURISCVState *env, uint64_t frs1)