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();