diff --git a/config/config.json.in b/config/config.json.in index d10ad962f5..6b06c25e8c 100644 --- a/config/config.json.in +++ b/config/config.json.in @@ -32,6 +32,14 @@ // "AMOCAS_Fatal" – raise a Sail exception, stopping execution. // "AMOCAS_Illegal" – treat it as an illegal instruction. "amocas_odd_register": "AMOCAS_Illegal", + // The configuration option determines how to handle execution of a floating-point + // instruction with DYN (dynamic) rounding mode when `fcsr.FRM` contains a + // reserved value (0b101, 0b110, 0b111). + // This does not affect the execution of floating-point instructions that have a + // reserved rounding mode statically encoded in the instruction. + // "Fcsr_RM_Fatal" – raise a Sail exception, stopping execution. + // "Fcsr_RM_Illegal" – treat it as an illegal instruction. + "fcsr_rm": "Fcsr_RM_Illegal", // The configuration option determines how to handle the reserved behavior `pmpcfg_with_R0W1`. // "PMP_Fatal" – raise a Sail exception, stopping execution. // "PMP_ClearPermissions" – convert a PMP entry with R=0, W=1 to R=0, W=0, X=0. diff --git a/model/core/platform_config.sail b/model/core/platform_config.sail index dea881560d..8a5a23a896 100644 --- a/model/core/platform_config.sail +++ b/model/core/platform_config.sail @@ -71,6 +71,17 @@ mapping AmocasOddRegisterReservedBehavior_str : AmocasOddRegisterReservedBehavio } overload to_str = {AmocasOddRegisterReservedBehavior_str} +enum FcsrRmReservedBehavior = { + Fcsr_RM_Fatal, + Fcsr_RM_Illegal, +} + +mapping FcsrRmReservedBehavior_str : FcsrRmReservedBehavior <-> string = { + Fcsr_RM_Fatal <-> "Fcsr_RM_Fatal", + Fcsr_RM_Illegal <-> "Fcsr_RM_Illegal", +} +overload to_str = {FcsrRmReservedBehavior_str} + enum PmpWriteOnlyReservedBehavior = { PMP_Fatal, PMP_ClearPermissions, @@ -105,6 +116,7 @@ mapping RV32ZdinxOddRegisterReservedBehavior_str : RV32ZdinxOddRegisterReservedB overload to_str = {RV32ZdinxOddRegisterReservedBehavior_str} let amocas_odd_register_reserved_behavior : AmocasOddRegisterReservedBehavior = config base.reserved_behavior.amocas_odd_register +let fcsr_rm_reserved_behavior : FcsrRmReservedBehavior = config base.reserved_behavior.fcsr_rm let pmp_write_only_reserved_behavior : PmpWriteOnlyReservedBehavior = config base.reserved_behavior.pmpcfg_write_only let xenvcfg_cbie_reserved_behavior : XenvcfgCbieReservedBehavior = config base.reserved_behavior.xenvcfg_cbie let rv32zdinx_odd_register_reserved_behavior : RV32ZdinxOddRegisterReservedBehavior = config base.reserved_behavior.rv32zdinx_odd_register diff --git a/model/extensions/FD/fext_insts.sail b/model/extensions/FD/fext_insts.sail index 4ff7b677db..25bcfb1430 100644 --- a/model/extensions/FD/fext_insts.sail +++ b/model/extensions/FD/fext_insts.sail @@ -53,7 +53,12 @@ function select_instr_or_fcsr_rm(instr_rm : rounding_mode) -> option(rounding_mo 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() + then Some(encdec_rounding_mode(fcsr_rm)) + else match fcsr_rm_reserved_behavior { + Fcsr_RM_Fatal => reserved_behavior("Dynamic floating-point rounding mode reserved behavior: fcsr.FRM contains reserved value " ^ bits_str(fcsr_rm)), + // Note: None() will be caught and converted into Illegal_Instruction() when this function is called. + Fcsr_RM_Illegal => None(), + } } else Some(instr_rm)