aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Rugg <pdr32@cam.ac.uk>2021-08-09 20:17:11 +0100
committerPeter Rugg <pdr32@cam.ac.uk>2021-08-09 20:17:11 +0100
commitba7ff8020d5f3ca4ab52e6bdc51bf66dbab8ebfb (patch)
treeb13ff5213f0a840c6aba991b1a3e2c25410f4fb9
parentcf099be2a1aff1f326dc855875d5732607e28752 (diff)
downloadsail-riscv-ba7ff8020d5f3ca4ab52e6bdc51bf66dbab8ebfb.zip
sail-riscv-ba7ff8020d5f3ca4ab52e6bdc51bf66dbab8ebfb.tar.gz
sail-riscv-ba7ff8020d5f3ca4ab52e6bdc51bf66dbab8ebfb.tar.bz2
Fix crash when fcsr.frm is invalid
-rw-r--r--model/riscv_insts_dext.sail230
-rw-r--r--model/riscv_insts_fext.sail231
2 files changed, 284 insertions, 177 deletions
diff --git a/model/riscv_insts_dext.sail b/model/riscv_insts_dext.sail
index 5f5dc94..1619a51 100644
--- a/model/riscv_insts_dext.sail
+++ b/model/riscv_insts_dext.sail
@@ -323,17 +323,22 @@ function clause execute (F_MADD_TYPE_D(rs3, rs2, rs1, rm, rd, op)) = {
let rs1_val_64b = F(rs1);
let rs2_val_64b = F(rs2);
let rs3_val_64b = F(rs3);
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
- let (fflags, rd_val_64b) : (bits(5), bits(64)) =
- match op {
- FMADD_D => riscv_f64MulAdd (rm_3b, rs1_val_64b, rs2_val_64b, rs3_val_64b),
- FMSUB_D => riscv_f64MulAdd (rm_3b, rs1_val_64b, rs2_val_64b, negate_D (rs3_val_64b)),
- FNMSUB_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, rs3_val_64b),
- FNMADD_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, negate_D (rs3_val_64b))
- };
- write_fflags(fflags);
- F(rd) = rd_val_64b;
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_64b) : (bits(5), bits(64)) =
+ match op {
+ FMADD_D => riscv_f64MulAdd (rm_3b, rs1_val_64b, rs2_val_64b, rs3_val_64b),
+ FMSUB_D => riscv_f64MulAdd (rm_3b, rs1_val_64b, rs2_val_64b, negate_D (rs3_val_64b)),
+ FNMSUB_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, rs3_val_64b),
+ FNMADD_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, negate_D (rs3_val_64b))
+ };
+ write_fflags(fflags);
+ F(rd) = rd_val_64b;
+ RETIRE_SUCCESS
+ }
+ }
}
/* AST -> Assembly notation ================================ */
@@ -383,16 +388,21 @@ mapping clause encdec =
function clause execute (F_BIN_RM_TYPE_D(rs2, rs1, rm, rd, op)) = {
let rs1_val_64b = F(rs1);
let rs2_val_64b = F(rs2);
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
- let (fflags, rd_val_64b) : (bits(5), bits(64)) = match op {
- FADD_D => riscv_f64Add (rm_3b, rs1_val_64b, rs2_val_64b),
- FSUB_D => riscv_f64Sub (rm_3b, rs1_val_64b, rs2_val_64b),
- FMUL_D => riscv_f64Mul (rm_3b, rs1_val_64b, rs2_val_64b),
- FDIV_D => riscv_f64Div (rm_3b, rs1_val_64b, rs2_val_64b)
- };
- write_fflags(fflags);
- F(rd) = rd_val_64b;
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_64b) : (bits(5), bits(64)) = match op {
+ FADD_D => riscv_f64Add (rm_3b, rs1_val_64b, rs2_val_64b),
+ FSUB_D => riscv_f64Sub (rm_3b, rs1_val_64b, rs2_val_64b),
+ FMUL_D => riscv_f64Mul (rm_3b, rs1_val_64b, rs2_val_64b),
+ FDIV_D => riscv_f64Div (rm_3b, rs1_val_64b, rs2_val_64b)
+ };
+ write_fflags(fflags);
+ F(rd) = rd_val_64b;
+ RETIRE_SUCCESS
+ }
+ }
}
/* AST -> Assembly notation ================================ */
@@ -470,123 +480,167 @@ mapping clause encdec =
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FSQRT_D)) = {
let rs1_val_D = F(rs1);
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_D) = riscv_f64Sqrt (rm_3b, rs1_val_D);
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_D) = riscv_f64Sqrt (rm_3b, rs1_val_D);
- write_fflags(fflags);
- F(rd) = rd_val_D;
- RETIRE_SUCCESS
+ write_fflags(fflags);
+ F(rd) = rd_val_D;
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_W_D)) = {
let rs1_val_D = F(rs1);
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_W) = riscv_f64ToI32 (rm_3b, rs1_val_D);
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_W) = riscv_f64ToI32 (rm_3b, rs1_val_D);
- write_fflags(fflags);
- X(rd) = EXTS (rd_val_W);
- RETIRE_SUCCESS
+ write_fflags(fflags);
+ X(rd) = EXTS (rd_val_W);
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_WU_D)) = {
let rs1_val_D = F(rs1);
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_WU) = riscv_f64ToUi32 (rm_3b, rs1_val_D);
- let (fflags, rd_val_WU) = riscv_f64ToUi32 (rm_3b, rs1_val_D);
-
- write_fflags(fflags);
- X(rd) = EXTS (rd_val_WU);
- RETIRE_SUCCESS
+ write_fflags(fflags);
+ X(rd) = EXTS (rd_val_WU);
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_W)) = {
let rs1_val_W = X(rs1) [31..0];
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_D) = riscv_i32ToF64 (rm_3b, rs1_val_W);
- let (fflags, rd_val_D) = riscv_i32ToF64 (rm_3b, rs1_val_W);
-
- write_fflags(fflags);
- F(rd) = rd_val_D;
- RETIRE_SUCCESS
+ write_fflags(fflags);
+ F(rd) = rd_val_D;
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_WU)) = {
let rs1_val_WU = X(rs1) [31..0];
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_D) = riscv_ui32ToF64 (rm_3b, rs1_val_WU);
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_D) = riscv_ui32ToF64 (rm_3b, rs1_val_WU);
- write_fflags(fflags);
- F(rd) = rd_val_D;
- RETIRE_SUCCESS
+ write_fflags(fflags);
+ F(rd) = rd_val_D;
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_S_D)) = {
let rs1_val_D = F(rs1);
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_S) = riscv_f64ToF32 (rm_3b, rs1_val_D);
- let (fflags, rd_val_S) = riscv_f64ToF32 (rm_3b, rs1_val_D);
-
- write_fflags(fflags);
- F(rd) = nan_box (rd_val_S);
- RETIRE_SUCCESS
+ write_fflags(fflags);
+ F(rd) = nan_box (rd_val_S);
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_S)) = {
let rs1_val_S = nan_unbox (F(rs1));
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_D) = riscv_f32ToF64 (rm_3b, rs1_val_S);
- let (fflags, rd_val_D) = riscv_f32ToF64 (rm_3b, rs1_val_S);
-
- write_fflags(fflags);
- F(rd) = rd_val_D;
- RETIRE_SUCCESS
+ write_fflags(fflags);
+ F(rd) = rd_val_D;
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_L_D)) = {
let rs1_val_D = F(rs1);
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_L) = riscv_f64ToI64 (rm_3b, rs1_val_D);
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_L) = riscv_f64ToI64 (rm_3b, rs1_val_D);
- write_fflags(fflags);
- X(rd) = rd_val_L;
- RETIRE_SUCCESS
+ write_fflags(fflags);
+ X(rd) = rd_val_L;
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_LU_D)) = {
let rs1_val_D = F(rs1);
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_LU) = riscv_f64ToUi64 (rm_3b, rs1_val_D);
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_LU) = riscv_f64ToUi64 (rm_3b, rs1_val_D);
- write_fflags(fflags);
- X(rd) = rd_val_LU;
- RETIRE_SUCCESS
+ write_fflags(fflags);
+ X(rd) = rd_val_LU;
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_L)) = {
let rs1_val_L = X(rs1);
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_D) = riscv_i64ToF64 (rm_3b, rs1_val_L);
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_D) = riscv_i64ToF64 (rm_3b, rs1_val_L);
- write_fflags(fflags);
- F(rd) = rd_val_D;
- RETIRE_SUCCESS
+ write_fflags(fflags);
+ F(rd) = rd_val_D;
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_LU)) = {
let rs1_val_LU = X(rs1);
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);
-
- write_fflags(fflags);
- F(rd) = rd_val_D;
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);
+
+ write_fflags(fflags);
+ F(rd) = rd_val_D;
+ RETIRE_SUCCESS
+ }
+ }
}
/* AST -> Assembly notation ================================ */
diff --git a/model/riscv_insts_fext.sail b/model/riscv_insts_fext.sail
index 41a8975..42d797a 100644
--- a/model/riscv_insts_fext.sail
+++ b/model/riscv_insts_fext.sail
@@ -102,11 +102,18 @@ mapping frm_mnemonic : rounding_mode <-> string = {
RM_DYN <-> "dyn"
}
-val select_instr_or_fcsr_rm : rounding_mode -> rounding_mode effect {rreg}
-function select_instr_or_fcsr_rm instr_rm =
- if (instr_rm == RM_DYN)
- then encdec_rounding_mode (fcsr.FRM())
- else instr_rm
+val valid_rounding_mode : bits(3) -> bool
+function valid_rounding_mode rm = (rm != 0b101 & rm != 0b110)
+
+val select_instr_or_fcsr_rm : rounding_mode -> option(rounding_mode) effect {rreg}
+function select_instr_or_fcsr_rm instr_rm =
+ if (instr_rm == RM_DYN)
+ then {
+ let fcsr_rm = fcsr.FRM();
+ if (valid_rounding_mode(fcsr_rm) & fcsr_rm != encdec_rounding_mode(RM_DYN))
+ then Some(encdec_rounding_mode(fcsr_rm)) else None()
+ }
+ else Some(instr_rm)
/* **************************************************************** */
/* Floating point accrued exception flags */
@@ -518,17 +525,22 @@ function clause execute (F_MADD_TYPE_S(rs3, rs2, rs1, rm, rd, op)) = {
let rs1_val_32b = nan_unbox (F(rs1));
let rs2_val_32b = nan_unbox (F(rs2));
let rs3_val_32b = nan_unbox (F(rs3));
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
- let (fflags, rd_val_32b) : (bits(5), bits(32)) =
- match op {
- FMADD_S => riscv_f32MulAdd (rm_3b, rs1_val_32b, rs2_val_32b, rs3_val_32b),
- FMSUB_S => riscv_f32MulAdd (rm_3b, rs1_val_32b, rs2_val_32b, negate_S (rs3_val_32b)),
- FNMSUB_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, rs3_val_32b),
- FNMADD_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, negate_S (rs3_val_32b))
- };
- write_fflags(fflags);
- F(rd) = nan_box (rd_val_32b);
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_32b) : (bits(5), bits(32)) =
+ match op {
+ FMADD_S => riscv_f32MulAdd (rm_3b, rs1_val_32b, rs2_val_32b, rs3_val_32b),
+ FMSUB_S => riscv_f32MulAdd (rm_3b, rs1_val_32b, rs2_val_32b, negate_S (rs3_val_32b)),
+ FNMSUB_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, rs3_val_32b),
+ FNMADD_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, negate_S (rs3_val_32b))
+ };
+ write_fflags(fflags);
+ F(rd) = nan_box (rd_val_32b);
+ RETIRE_SUCCESS
+ }
+ }
}
/* AST -> Assembly notation ================================ */
@@ -578,16 +590,21 @@ mapping clause encdec =
function clause execute (F_BIN_RM_TYPE_S(rs2, rs1, rm, rd, op)) = {
let rs1_val_32b = nan_unbox (F(rs1));
let rs2_val_32b = nan_unbox (F(rs2));
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
- let (fflags, rd_val_32b) : (bits(5), bits(32)) = match op {
- FADD_S => riscv_f32Add (rm_3b, rs1_val_32b, rs2_val_32b),
- FSUB_S => riscv_f32Sub (rm_3b, rs1_val_32b, rs2_val_32b),
- FMUL_S => riscv_f32Mul (rm_3b, rs1_val_32b, rs2_val_32b),
- FDIV_S => riscv_f32Div (rm_3b, rs1_val_32b, rs2_val_32b)
- };
- write_fflags(fflags);
- F(rd) = nan_box (rd_val_32b);
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_32b) : (bits(5), bits(32)) = match op {
+ FADD_S => riscv_f32Add (rm_3b, rs1_val_32b, rs2_val_32b),
+ FSUB_S => riscv_f32Sub (rm_3b, rs1_val_32b, rs2_val_32b),
+ FMUL_S => riscv_f32Mul (rm_3b, rs1_val_32b, rs2_val_32b),
+ FDIV_S => riscv_f32Div (rm_3b, rs1_val_32b, rs2_val_32b)
+ };
+ write_fflags(fflags);
+ F(rd) = nan_box (rd_val_32b);
+ RETIRE_SUCCESS
+ }
+ }
}
/* AST -> Assembly notation ================================ */
@@ -657,70 +674,94 @@ mapping clause encdec =
function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FSQRT_S)) = {
let rs1_val_S = nan_unbox (F(rs1));
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_S) = riscv_f32Sqrt (rm_3b, rs1_val_S);
-
- write_fflags(fflags);
- F(rd) = nan_box (rd_val_S);
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_S) = riscv_f32Sqrt (rm_3b, rs1_val_S);
+
+ write_fflags(fflags);
+ F(rd) = nan_box (rd_val_S);
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_W_S)) = {
let rs1_val_S = nan_unbox (F(rs1));
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_W) = riscv_f32ToI32 (rm_3b, rs1_val_S);
-
- write_fflags(fflags);
- X(rd) = EXTS (rd_val_W);
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_W) = riscv_f32ToI32 (rm_3b, rs1_val_S);
+
+ write_fflags(fflags);
+ X(rd) = EXTS (rd_val_W);
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_WU_S)) = {
let rs1_val_S = nan_unbox (F(rs1));
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_WU) = riscv_f32ToUi32 (rm_3b, rs1_val_S);
-
- write_fflags(fflags);
- X(rd) = EXTS (rd_val_WU);
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_WU) = riscv_f32ToUi32 (rm_3b, rs1_val_S);
+
+ write_fflags(fflags);
+ X(rd) = EXTS (rd_val_WU);
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_W)) = {
let rs1_val_W = X(rs1) [31..0];
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_S) = riscv_i32ToF32 (rm_3b, rs1_val_W);
-
- write_fflags(fflags);
- F(rd) = nan_box (rd_val_S);
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_S) = riscv_i32ToF32 (rm_3b, rs1_val_W);
+
+ write_fflags(fflags);
+ F(rd) = nan_box (rd_val_S);
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_WU)) = {
let rs1_val_WU = X(rs1) [31..0];
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_S) = riscv_ui32ToF32 (rm_3b, rs1_val_WU);
-
- write_fflags(fflags);
- F(rd) = nan_box (rd_val_S);
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_S) = riscv_ui32ToF32 (rm_3b, rs1_val_WU);
+
+ write_fflags(fflags);
+ F(rd) = nan_box (rd_val_S);
+ RETIRE_SUCCESS
+ }
+ }
}
function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_L_S)) = {
if sizeof(flen) == 64
then {
let rs1_val_S = nan_unbox (F(rs1));
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_L) = riscv_f32ToI64 (rm_3b, rs1_val_S);
-
- write_fflags(fflags);
- X(rd) = rd_val_L;
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_L) = riscv_f32ToI64 (rm_3b, rs1_val_S);
+
+ write_fflags(fflags);
+ X(rd) = rd_val_L;
+ RETIRE_SUCCESS
+ }
+ }
} else {
/* this would not decode on RV32 */
RETIRE_FAIL
@@ -731,13 +772,17 @@ function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_LU_S)) = {
if sizeof(flen) == 64
then {
let rs1_val_S = nan_unbox (F(rs1));
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_LU) = riscv_f32ToUi64 (rm_3b, rs1_val_S);
-
- write_fflags(fflags);
- X(rd) = rd_val_LU;
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_LU) = riscv_f32ToUi64 (rm_3b, rs1_val_S);
+
+ write_fflags(fflags);
+ X(rd) = rd_val_LU;
+ RETIRE_SUCCESS
+ }
+ }
} else {
/* this would not decode on RV32 */
RETIRE_FAIL
@@ -748,13 +793,17 @@ function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_L)) = {
if sizeof(flen) == 64
then {
let rs1_val_L = X(rs1);
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_S) = riscv_i64ToF32 (rm_3b, rs1_val_L);
-
- write_fflags(fflags);
- F(rd) = nan_box (rd_val_S);
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_S) = riscv_i64ToF32 (rm_3b, rs1_val_L);
+
+ write_fflags(fflags);
+ F(rd) = nan_box (rd_val_S);
+ RETIRE_SUCCESS
+ }
+ }
} else {
/* this would not decode on RV32 */
RETIRE_FAIL
@@ -765,13 +814,17 @@ function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_LU)) = {
if sizeof(flen) == 64
then {
let rs1_val_LU = X(rs1);
- let rm_3b = encdec_rounding_mode (select_instr_or_fcsr_rm (rm));
-
- let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU);
-
- write_fflags(fflags);
- F(rd) = nan_box (rd_val_S);
- RETIRE_SUCCESS
+ match (select_instr_or_fcsr_rm (rm)) {
+ None() => { handle_illegal(); RETIRE_FAIL },
+ Some(rm') => {
+ let rm_3b = encdec_rounding_mode(rm');
+ let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU);
+
+ write_fflags(fflags);
+ F(rd) = nan_box (rd_val_S);
+ RETIRE_SUCCESS
+ }
+ }
} else {
/* this would not decode on RV32 */
RETIRE_FAIL