On 5/19/26 05:06, Peter Maydell wrote:
This doesn't quite do the right thing for an input SNaN, which is supposed to set the Invalid Operation bit. This I think is because the parts_canonicalize code in fpu/ isn't handling the "only one NaN" case quite right:case float_expmax_e4m3: if (p->frac_hi == 0b111) { fracN(shl)(p, fmt->frac_shift); p->cls = (parts_is_snan_frac(p->frac_hi, status) ? float_class_snan : float_class_qnan); return; } This tries to use parts_is_snan_frac() to determine whether the FP8 NaN is an SNaN or a QNaN. But for Arm at least in E4M3 the NaN is always an SNaN, and parts_is_snan_frac() gives the wrong answer because it's looking at the MSB of the fraction and for Arm snan_bit_is_one() is false. The upshot is that later on when processing this value we don't recognize that it was an SNaN and don't set Invalid. Unfortunately the OCP OFP8 specification doesn't say whether the E4M3 NaN should be signaling or not, which is thus leaving it up to the implementation to decide. If Arm is the only user of the E4M3 code at the moment (looks like maybe we are?) then we can hard-code "always SNaN":
Sadly not. There are patches for riscv that haven't been merged, and riscv wants the solo nan encoding for e4m3 to be qnan.
I could fix this up locally in fp8_input_fmt[OFP8_E4M3], but perhaps it's clearer for the generic code to add another bit to float_status: e4m3_nan_is_snan?
r~
