target/riscv: introduce floating-point rounding mode enum

Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20211210075704.23951-61-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Frank Chang 2021-12-10 15:56:46 +08:00 committed by Alistair Francis
parent 49c5611a97
commit 986c895de1
3 changed files with 24 additions and 15 deletions

View File

@ -55,23 +55,23 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
{ {
int softrm; int softrm;
if (rm == 7) { if (rm == RISCV_FRM_DYN) {
rm = env->frm; rm = env->frm;
} }
switch (rm) { switch (rm) {
case 0: case RISCV_FRM_RNE:
softrm = float_round_nearest_even; softrm = float_round_nearest_even;
break; break;
case 1: case RISCV_FRM_RTZ:
softrm = float_round_to_zero; softrm = float_round_to_zero;
break; break;
case 2: case RISCV_FRM_RDN:
softrm = float_round_down; softrm = float_round_down;
break; break;
case 3: case RISCV_FRM_RUP:
softrm = float_round_up; softrm = float_round_up;
break; break;
case 4: case RISCV_FRM_RMM:
softrm = float_round_ties_away; softrm = float_round_ties_away;
break; break;
default: default:

View File

@ -2088,7 +2088,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
gen_helper_##NAME##_d, \ gen_helper_##NAME##_d, \
}; \ }; \
TCGLabel *over = gen_new_label(); \ TCGLabel *over = gen_new_label(); \
gen_set_rm(s, 7); \ gen_set_rm(s, RISCV_FRM_DYN); \
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
\ \
data = FIELD_DP32(data, VDATA, VM, a->vm); \ data = FIELD_DP32(data, VDATA, VM, a->vm); \
@ -2167,7 +2167,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
gen_helper_##NAME##_w, \ gen_helper_##NAME##_w, \
gen_helper_##NAME##_d, \ gen_helper_##NAME##_d, \
}; \ }; \
gen_set_rm(s, 7); \ gen_set_rm(s, RISCV_FRM_DYN); \
data = FIELD_DP32(data, VDATA, VM, a->vm); \ data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
return opfvf_trans(a->rd, a->rs1, a->rs2, data, \ return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
@ -2199,7 +2199,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
gen_helper_##NAME##_h, gen_helper_##NAME##_w, \ gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
}; \ }; \
TCGLabel *over = gen_new_label(); \ TCGLabel *over = gen_new_label(); \
gen_set_rm(s, 7); \ gen_set_rm(s, RISCV_FRM_DYN); \
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
\ \
data = FIELD_DP32(data, VDATA, VM, a->vm); \ data = FIELD_DP32(data, VDATA, VM, a->vm); \
@ -2236,7 +2236,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
static gen_helper_opfvf *const fns[2] = { \ static gen_helper_opfvf *const fns[2] = { \
gen_helper_##NAME##_h, gen_helper_##NAME##_w, \ gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
}; \ }; \
gen_set_rm(s, 7); \ gen_set_rm(s, RISCV_FRM_DYN); \
data = FIELD_DP32(data, VDATA, VM, a->vm); \ data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
return opfvf_trans(a->rd, a->rs1, a->rs2, data, \ return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
@ -2266,7 +2266,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
gen_helper_##NAME##_h, gen_helper_##NAME##_w, \ gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
}; \ }; \
TCGLabel *over = gen_new_label(); \ TCGLabel *over = gen_new_label(); \
gen_set_rm(s, 7); \ gen_set_rm(s, RISCV_FRM_DYN); \
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
\ \
data = FIELD_DP32(data, VDATA, VM, a->vm); \ data = FIELD_DP32(data, VDATA, VM, a->vm); \
@ -2303,7 +2303,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
static gen_helper_opfvf *const fns[2] = { \ static gen_helper_opfvf *const fns[2] = { \
gen_helper_##NAME##_h, gen_helper_##NAME##_w, \ gen_helper_##NAME##_h, gen_helper_##NAME##_w, \
}; \ }; \
gen_set_rm(s, 7); \ gen_set_rm(s, RISCV_FRM_DYN); \
data = FIELD_DP32(data, VDATA, VM, a->vm); \ data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
return opfvf_trans(a->rd, a->rs1, a->rs2, data, \ return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
@ -2380,7 +2380,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
gen_helper_##NAME##_d, \ gen_helper_##NAME##_d, \
}; \ }; \
TCGLabel *over = gen_new_label(); \ TCGLabel *over = gen_new_label(); \
gen_set_rm(s, 7); \ gen_set_rm(s, RISCV_FRM_DYN); \
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
\ \
data = FIELD_DP32(data, VDATA, VM, a->vm); \ data = FIELD_DP32(data, VDATA, VM, a->vm); \
@ -2526,7 +2526,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
gen_helper_##NAME##_w, \ gen_helper_##NAME##_w, \
}; \ }; \
TCGLabel *over = gen_new_label(); \ TCGLabel *over = gen_new_label(); \
gen_set_rm(s, 7); \ gen_set_rm(s, RISCV_FRM_DYN); \
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
\ \
data = FIELD_DP32(data, VDATA, VM, a->vm); \ data = FIELD_DP32(data, VDATA, VM, a->vm); \
@ -2574,7 +2574,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
gen_helper_##NAME##_w, \ gen_helper_##NAME##_w, \
}; \ }; \
TCGLabel *over = gen_new_label(); \ TCGLabel *over = gen_new_label(); \
gen_set_rm(s, 7); \ gen_set_rm(s, RISCV_FRM_DYN); \
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
\ \
data = FIELD_DP32(data, VDATA, VM, a->vm); \ data = FIELD_DP32(data, VDATA, VM, a->vm); \

View File

@ -36,6 +36,15 @@ target_ulong fclass_d(uint64_t frs1);
extern const VMStateDescription vmstate_riscv_cpu; extern const VMStateDescription vmstate_riscv_cpu;
#endif #endif
enum {
RISCV_FRM_RNE = 0, /* Round to Nearest, ties to Even */
RISCV_FRM_RTZ = 1, /* Round towards Zero */
RISCV_FRM_RDN = 2, /* Round Down */
RISCV_FRM_RUP = 3, /* Round Up */
RISCV_FRM_RMM = 4, /* Round to Nearest, ties to Max Magnitude */
RISCV_FRM_DYN = 7, /* Dynamic rounding mode */
};
static inline uint64_t nanbox_s(float32 f) static inline uint64_t nanbox_s(float32 f)
{ {
return f | MAKE_64BIT_MASK(32, 32); return f | MAKE_64BIT_MASK(32, 32);