diff options
author | Peter Rugg <pdr32@cam.ac.uk> | 2021-08-09 20:17:11 +0100 |
---|---|---|
committer | Peter Rugg <pdr32@cam.ac.uk> | 2021-08-09 20:17:11 +0100 |
commit | ba7ff8020d5f3ca4ab52e6bdc51bf66dbab8ebfb (patch) | |
tree | b13ff5213f0a840c6aba991b1a3e2c25410f4fb9 | |
parent | cf099be2a1aff1f326dc855875d5732607e28752 (diff) | |
download | sail-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.sail | 230 | ||||
-rw-r--r-- | model/riscv_insts_fext.sail | 231 |
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 |