1 // SPDX-License-Identifier: MIT
3 // Copyright 2024 Advanced Micro Devices, Inc.
6 #include "spl_custom_float.h"
8 static bool spl_build_custom_float(struct spl_fixed31_32 value,
9 const struct spl_custom_float_format *format,
14 uint32_t exp_offset = (1 << (format->exponenta_bits - 1)) - 1;
16 const struct spl_fixed31_32 mantissa_constant_plus_max_fraction =
17 spl_fixpt_from_fraction((1LL << (format->mantissa_bits + 1)) - 1,
18 1LL << format->mantissa_bits);
20 struct spl_fixed31_32 mantiss;
22 if (spl_fixpt_eq(value, spl_fixpt_zero)) {
29 if (spl_fixpt_lt(value, spl_fixpt_zero)) {
30 *negative = format->sign;
31 value = spl_fixpt_neg(value);
36 if (spl_fixpt_lt(value, spl_fixpt_one)) {
40 value = spl_fixpt_shl(value, 1);
42 } while (spl_fixpt_lt(value, spl_fixpt_one));
46 if (exp_offset <= i) {
52 *exponenta = exp_offset - i;
53 } else if (spl_fixpt_le(mantissa_constant_plus_max_fraction, value)) {
57 value = spl_fixpt_shr(value, 1);
59 } while (spl_fixpt_lt(mantissa_constant_plus_max_fraction, value));
61 *exponenta = exp_offset + i - 1;
63 *exponenta = exp_offset;
66 mantiss = spl_fixpt_sub(value, spl_fixpt_one);
68 if (spl_fixpt_lt(mantiss, spl_fixpt_zero) ||
69 spl_fixpt_lt(spl_fixpt_one, mantiss))
70 mantiss = spl_fixpt_zero;
72 mantiss = spl_fixpt_shl(mantiss, format->mantissa_bits);
74 *mantissa = spl_fixpt_floor(mantiss);
79 static bool spl_setup_custom_float(const struct spl_custom_float_format *format,
90 * once calculation is ok we can remove it
93 const uint32_t mantissa_mask =
94 (1 << (format->mantissa_bits + 1)) - 1;
96 const uint32_t exponenta_mask =
97 (1 << (format->exponenta_bits + 1)) - 1;
99 if (mantissa & ~mantissa_mask) {
100 SPL_BREAK_TO_DEBUGGER();
101 mantissa = mantissa_mask;
104 if (exponenta & ~exponenta_mask) {
105 SPL_BREAK_TO_DEBUGGER();
106 exponenta = exponenta_mask;
109 /* end of verification code */
111 while (i < format->mantissa_bits) {
112 uint32_t mask = 1 << i;
120 while (j < format->exponenta_bits) {
121 uint32_t mask = 1 << j;
123 if (exponenta & mask)
129 if (negative && format->sign)
130 value |= 1 << (i + j);
137 bool spl_convert_to_custom_float_format(struct spl_fixed31_32 value,
138 const struct spl_custom_float_format *format,
145 return spl_build_custom_float(value, format, &negative, &mantissa, &exponenta) &&
146 spl_setup_custom_float(format,