sail-riscv
sail-riscv copied to clipboard
Add configurability of floating point dirty bit behaviour
mstatus
as a dirty bit that says when the floating point flags are dirty or might be dirty.
The Sail model currently is 100% precise, in that it only sets the dirty bit to 1 exactly when fflags
have been modified, however there are an unlimited number of other valid behaviours. Some reasonable options that are more likely in real chips are:
- Set the dirty flag whenever an instruction that could cause it to be set is executed, even if actually doesn't.
- Set the dirty flag whenever any floating point instruction is executed, including ones that can't generate any flags ever.
- Set the dirty flag whenever an instruction is executed that generates a flag bit, even if that bit was already set in
fflags
so the value offflags
doesn't change. - Hard code it to 1.
This will probably apply to the VS (vector state) dirty flag too.
I don’t think that’s what might means. Doesn’t might just mean that an instruction dirtied it in the past but later instructions could have made it no longer dirty, ie it’s a sticky status bit? What you’re proposing does not sound right to me.
mstatus.fs is dirty when " the corresponding state has potentially been modified since the last context save." where FP state is both fregs, and fflags/fcsr/frm CSRs. Other than that, it is cleared only manually (
(more quoting and paraphrasing- sorry)
Implementations may choose to track the dirtiness ... imprecisely by reporting ... dirty even when it [is un]modified. [some] instructions that do not mutate... state may cause [a] transition f[to] to Dirty. Other implementations, may [ only allow] Off and Dirty, states... setting FS to Initial or Clean causes it to be set to Dirty.
If an instruction explicitly or implicitly writes a [FP state] but does not alter its contents, and FS=Initial or FS=Clean, it is implementation-defined whether FS transitions to Dirty.
So I would conclude that 1, 2, and 3 are legal (3 sounds like a subset of 1). I don't believe #4 is legal. It may be hardcoded to 0 if F-ext is not implemented, but must be RW if it is. or may be hardcoded to 0 if there is no S-mode (but could be implemented as well for e.g. an RTOS w/o VM) . It must be hardcoded to 0 if neither F-ext nor S-mode are implemented
VS is handled identically with exactly the same options, as far as I can tell.
I don't know if the behavior can vary between FP instructions that don't modify state, e.g. Fstore vs Feq vs Fmv.s.x, etc. An implementation could avoid setting dirty on an Fadd with zero, but I suspect that case will never be implemented.
I don’t think that’s what might means. Doesn’t might just mean that an instruction dirtied it in the past but later instructions could have made it no longer dirty, ie it’s a sticky status bit? What you’re proposing does not sound right to me.
Yes, you're correct that it is a sticky bit. But implementations are allow to set it pessimistically. They can say the state is dirty even if it technically isn't. That's because it won't break functionality - it will only lead to unnecessary state saving/restoration.
The Sail model currently sets it as late as it possibly can - only when the state actually is dirty. But real implementations are likely to set it earlier than that.
I don't believe 4 is legal.
Ah yes you're probably right. I just put that in as a rather extreme example - what I should have said is "set it to 1 whenever any instruction is executed". That is legal. Not very likely behaviour though.
I think 1 and 3 are quite likely, and also very easy to implement in the Sail model so maybe it is sufficient to add those two options.