Crash on reserved rounding modes in fcsr
Sail crashes when executing a floating point instruction that specifies dynamic (meaning look at fcsr) rounding mode, when the rounding mode specified by fcsr is one of the two reserved encodings. For example:
li t0, 0x2000
csrw mstatus, t0 # enable floating point
li t1, 0xc0
csrw fcsr, t1 # set frm to 0b110 (invalid)
fmsub.s f22, f23, f27, f29, rdyn
This code snippet sets the rounding in fcsr to an invalid encoding, then runs an instruction that depends on the rounding mode. The spec defines that this should be an illegal instruction.
Sail crashes: Pattern match failure in encdec_rounding_mode_backwards because https://github.com/riscv/sail-riscv/blob/50f4bbaa5bd397ff5a71b7b39fa543d656934b80/model/riscv_insts_fext.sail#L88-L95 doesn't have cases for the illegal encodings (0b101 and 0b110).
Looks like encdec_rounding_mode has about 60 uses but only in one of two ways:
- in the encdec clauses for instruction decoding. I can't remember what the semantics are for an incomplete mapping here. Perhaps it will already fall back to RI in this case. Your example is not triggering this case.
- in the execute clauses on the result of
select_instr_or_fcsr_rm(which itself callsencdec_rounding_modein the RM_DYN case). Probablyselect_instr_or_fcsr_rmshould returnoption(rounding_mode)and return None ifinstr_rm == RM_DYNand fcsr.FRM is invalid. In the None case callers would have to callhandle_illegalthen returnRETIRE_FAIL.
Note that it's a bit strange that the rounding mode goes from bits -> rounding_mode -> bits. I suppose this is because the extern functions need bits. I wonder what they do with the unused modes?!
On the last point I would like to see the conversion from rounding_mode -> bits moved into the wrapper functions (e.g. riscv_f32Add).
I'm try to use this fcsr encoding in the C simulator, and sail was able to recognize it normally. It seems that there is some other configuration that causes sail to crash?
I'm a little confused... This issue is 2 years old, but seems to have a fix by me from 3 years ago... https://github.com/riscv/sail-riscv/pull/103. Anyway, testing now it seems to behave correctly, so closing the issue.