On Mon, Feb 23, 2026 at 07:21:54PM +1100, Richard Henderson wrote: > From: Max Chou <[email protected]> > > Signed-off-by: Max Chou <[email protected]> > [rth: Update for exp_max_kind] > Signed-off-by: Richard Henderson <[email protected]> > --- > include/fpu/softfloat-types.h | 1 + > include/fpu/softfloat.h | 4 +++- > fpu/softfloat.c | 26 ++++++++++++++++++++++++++ > 3 files changed, 30 insertions(+), 1 deletion(-) > > diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h > index 9c84a101e5..ead146c22d 100644 > --- a/include/fpu/softfloat-types.h > +++ b/include/fpu/softfloat-types.h > @@ -122,6 +122,7 @@ typedef uint16_t bfloat16; > /* > * Open Compute Project (OCP) Microscaling Formats > */ > +typedef uint8_t float4_e2m1; > typedef uint8_t float8_e4m3; > typedef uint8_t float8_e5m2; > > diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h > index 31d3f76d3f..8389a07b04 100644 > --- a/include/fpu/softfloat.h > +++ b/include/fpu/softfloat.h > @@ -190,9 +190,11 @@ float128 uint64_to_float128(uint64_t, float_status > *status); > float128 uint128_to_float128(Int128, float_status *status); > > > /*---------------------------------------------------------------------------- > -| OCP FP8 conversion routines. > +| OCP FP{4,8} conversion routines. > > *----------------------------------------------------------------------------*/ > > +float8_e4m3 float4_e2m1_to_float8_e4m3(float4_e2m1, float_status *status); > + > bfloat16 float8_e4m3_to_bfloat16(float8_e4m3, float_status *status); > float8_e4m3 bfloat16_to_float8_e4m3(bfloat16, bool sat, float_status > *status); > float8_e4m3 float32_to_float8_e4m3(float32, bool sat, float_status *status); > diff --git a/fpu/softfloat.c b/fpu/softfloat.c > index 6e21882ab2..91c34307c8 100644 > --- a/fpu/softfloat.c > +++ b/fpu/softfloat.c > @@ -574,6 +574,11 @@ typedef struct { > .frac_shift = (-F - 1) & 63, \ > .round_mask = (1ull << ((-F - 1) & 63)) - 1 > > +static const FloatFmt float4_e2m1_params = { > + FLOAT_PARAMS(2, 1), > + .exp_max_kind = float_expmax_normal, > +}; > + > static const FloatFmt float8_e4m3_params = { > FLOAT_PARAMS(4, 3), > .exp_max_kind = float_expmax_e4m3 > @@ -641,6 +646,11 @@ static void unpack_raw64(FloatParts64 *r, const FloatFmt > *fmt, uint64_t raw) > }; > } > > +static void QEMU_FLATTEN float4_e2m1_unpack_raw(FloatParts64 *p, float4_e2m1 > f) > +{ > + unpack_raw64(p, &float4_e2m1_params, f); > +} > + > static void QEMU_FLATTEN float8_e4m3_unpack_raw(FloatParts64 *p, float8_e4m3 > f) > { > unpack_raw64(p, &float8_e4m3_params, f); > @@ -1709,6 +1719,13 @@ static const uint16_t rsqrt_tab[128] = { > * Pack/unpack routines with a specific FloatFmt. > */ > > +static void float4_e2m1_unpack_canonical(FloatParts64 *p, float4_e2m1 f, > + float_status *s) > +{ > + float4_e2m1_unpack_raw(p, f); > + parts_canonicalize(p, s, &float4_e2m1_params); > +} > + > static void float8_e4m3_unpack_canonical(FloatParts64 *p, float8_e4m3 f, > float_status *s) > { > @@ -2929,6 +2946,15 @@ static void parts_float_to_float_widen(FloatParts128 > *a, FloatParts64 *b, > } > } > > +float8_e4m3 float4_e2m1_to_float8_e4m3(float4_e2m1 a, float_status *s) > +{ > + FloatParts64 p; > + > + float4_e2m1_unpack_canonical(&p, a, s); > + parts_float_to_float(&p, s); > + return float8_e4m3_round_pack_canonical(&p, s, false); > +} > + > bfloat16 float8_e4m3_to_bfloat16(float8_e4m3 a, float_status *s) > { > FloatParts64 p; > -- > 2.43.0 >
Reviewed-by: Chao Liu <[email protected]> Thanks, Chao
