isaspec: decode: manually print the sign when printing NaN float values

The IEEE754-2019 standard declaring the preceding sign "optional" when
converting NaN values to strings because the standard tries to not
regulate how sign bits in NaNs are interpreted.

In the real world, when using printf-series function to print a number
with type `float` on RISC-V, the sign of NaNs is wiped during the
conversion from `float` to `double` (defined as part of the default
argument promotions rule for variable arguments in the C spec).

Change the code to stop relying on isa_print() to print the negative
sign, instead parse it from the highest bit of value and manually print
it before "nan" string.

This fixes the `etnaviv_isa_disasm` unit test on RISC-V.

Suggested-by: Christian Gmeiner <cgmeiner@igalia.com>
Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com>
Reviewed-by: Rob Clark <rob.clark@oss.qualcomm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40887>
This commit is contained in:
Icenowy Zheng 2026-04-10 17:48:58 +08:00 committed by Marge Bot
parent 120bd20e49
commit 2bffc653ec

View file

@ -649,10 +649,18 @@ display_field(struct decode_scope *scope, const char *field_name)
f = uif(val);
fmt = "%.9g";
}
if (f == truncf(f) && isfinite(f))
if (isnan(f)) {
/* IEEE 754 declares the sign optional when converting
* NaN to strings, so manually extract it from the raw
* value and print it instead of relying on printf().
*/
bool negative = (width == 16) ? (val >> 15) & 1 : (val >> 31) & 1;
isa_print(print, "%snan", negative ? "-" : "");
} else if (f == truncf(f) && isfinite(f)) {
isa_print(print, "%.1f", f);
else
} else {
isa_print(print, fmt, f);
}
break;
}
case TYPE_BOOL: