Re: [Qemu-devel] [PATCH 10/18] target-riscv: Add Single Precision Floating-Point Instructions

2016-09-26 Thread Richard Henderson

On 09/26/2016 03:56 AM, Sagar Karandikar wrote:

+uint64_t helper_fsgnj_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = (frs1 & ~(uint32_t)INT32_MIN) | (frs2 & (uint32_t)INT32_MIN);
+return frs1;
+}
+
+uint64_t helper_fsgnjn_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = (frs1 & ~(uint32_t)INT32_MIN) | ((~frs2) & (uint32_t)INT32_MIN);
+return frs1;
+}
+
+uint64_t helper_fsgnjx_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = frs1 ^ (frs2 & (uint32_t)INT32_MIN);
+return frs1;
+}


These are simple enough to implement inline.


+
+uint64_t helper_fmin_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = float32_is_any_nan(frs2) ||
+   float32_lt_quiet(frs1, frs2, >fp_status) ? frs1 : frs2;
+set_fp_exceptions();
+return frs1;
+}


float32_minnum.


+
+uint64_t helper_fmax_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = float32_is_any_nan(frs2) ||
+   float32_le_quiet(frs2, frs1, >fp_status) ? frs1 : frs2;
+set_fp_exceptions();
+return frs1;
+}


float32_maxnum.


+target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t frs1, uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+frs1 = (int64_t)((int32_t)float32_to_int32(frs1, >fp_status));


You do not need either of these casts.


+target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t frs1, uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+frs1 = (int64_t)((int32_t)float32_to_uint32(frs1, >fp_status));


You do not need the cast to int64_t.  Also, remove the extra parenthesis.


+union ui32_f32 { uint32_t ui; uint32_t f; };


What's the point of this?


+
+uint_fast16_t float32_classify(uint32_t a, float_status *status)


No need for uint_fast16_t.  Just use uint32_t.


+{
+union ui32_f32 uA;
+uint_fast32_t uiA;
+
+uA.f = a;
+uiA = uA.ui;
+
+uint_fast16_t infOrNaN = expF32UI(uiA) == 0xFF;


float32_is_infinity or float32_is_any_nan.


+uint_fast16_t subnormalOrZero = expF32UI(uiA) == 0;


float32_is_zero_or_denormal


+bool sign = signF32UI(uiA);


float32_is_neg.


r~



[Qemu-devel] [PATCH 10/18] target-riscv: Add Single Precision Floating-Point Instructions

2016-09-26 Thread Sagar Karandikar
Signed-off-by: Sagar Karandikar 
---
 target-riscv/fpu_helper.c | 206 ++
 target-riscv/helper.h |  28 +++
 target-riscv/translate.c  | 146 
 3 files changed, 380 insertions(+)

diff --git a/target-riscv/fpu_helper.c b/target-riscv/fpu_helper.c
index 9023d10..8d33fa1 100644
--- a/target-riscv/fpu_helper.c
+++ b/target-riscv/fpu_helper.c
@@ -149,3 +149,209 @@ uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t 
frs1, uint64_t frs2,
 set_fp_exceptions();
 return frs1;
 }
+
+uint64_t helper_fadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
+   uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+frs1 = float32_add(frs1, frs2, >fp_status);
+set_fp_exceptions();
+return frs1;
+}
+
+uint64_t helper_fsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
+   uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+frs1 = float32_sub(frs1, frs2, >fp_status);
+set_fp_exceptions();
+return frs1;
+}
+
+uint64_t helper_fmul_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
+   uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+frs1 = float32_mul(frs1, frs2, >fp_status);
+set_fp_exceptions();
+return frs1;
+}
+
+uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
+   uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+frs1 = float32_div(frs1, frs2, >fp_status);
+set_fp_exceptions();
+return frs1;
+}
+
+uint64_t helper_fsgnj_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = (frs1 & ~(uint32_t)INT32_MIN) | (frs2 & (uint32_t)INT32_MIN);
+return frs1;
+}
+
+uint64_t helper_fsgnjn_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = (frs1 & ~(uint32_t)INT32_MIN) | ((~frs2) & (uint32_t)INT32_MIN);
+return frs1;
+}
+
+uint64_t helper_fsgnjx_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = frs1 ^ (frs2 & (uint32_t)INT32_MIN);
+return frs1;
+}
+
+uint64_t helper_fmin_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = float32_is_any_nan(frs2) ||
+   float32_lt_quiet(frs1, frs2, >fp_status) ? frs1 : frs2;
+set_fp_exceptions();
+return frs1;
+}
+
+uint64_t helper_fmax_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = float32_is_any_nan(frs2) ||
+   float32_le_quiet(frs2, frs1, >fp_status) ? frs1 : frs2;
+set_fp_exceptions();
+return frs1;
+}
+
+uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t frs1, uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+frs1 = float32_sqrt(frs1, >fp_status);
+set_fp_exceptions();
+return frs1;
+}
+
+target_ulong helper_fle_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = float32_le(frs1, frs2, >fp_status);
+set_fp_exceptions();
+return frs1;
+}
+
+target_ulong helper_flt_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = float32_lt(frs1, frs2, >fp_status);
+set_fp_exceptions();
+return frs1;
+}
+
+target_ulong helper_feq_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
+{
+frs1 = float32_eq(frs1, frs2, >fp_status);
+set_fp_exceptions();
+return frs1;
+}
+
+target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t frs1, uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+frs1 = (int64_t)((int32_t)float32_to_int32(frs1, >fp_status));
+set_fp_exceptions();
+return frs1;
+}
+
+target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t frs1, uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+frs1 = (int64_t)((int32_t)float32_to_uint32(frs1, >fp_status));
+set_fp_exceptions();
+return frs1;
+}
+
+#if defined(TARGET_RISCV64)
+uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t frs1, uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+frs1 = float32_to_int64(frs1, >fp_status);
+set_fp_exceptions();
+return frs1;
+}
+
+uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t frs1, uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+frs1 = float32_to_uint64(frs1, >fp_status);
+set_fp_exceptions();
+return frs1;
+}
+#endif
+
+uint64_t helper_fcvt_s_w(CPURISCVState *env, target_ulong rs1, uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+rs1 = int32_to_float32((int32_t)rs1, >fp_status);
+set_fp_exceptions();
+return rs1;
+}
+
+uint64_t helper_fcvt_s_wu(CPURISCVState *env, target_ulong rs1, uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+rs1 = uint32_to_float32((uint32_t)rs1, >fp_status);
+set_fp_exceptions();
+return rs1;
+}
+
+#if defined(TARGET_RISCV64)
+uint64_t helper_fcvt_s_l(CPURISCVState *env, uint64_t rs1, uint64_t rm)
+{
+set_float_rounding_mode(RM, >fp_status);
+rs1 = int64_to_float32(rs1, >fp_status);
+set_fp_exceptions();