1 /*
2 * QEMU float support
3 *
4 * The code in this source file is derived from release 2a of the SoftFloat
5 * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
6 * some later contributions) are provided under that license, as detailed below.
7 * It has subsequently been modified by contributors to the QEMU Project,
8 * so some portions are provided under:
9 * the SoftFloat-2a license
10 * the BSD license
11 * GPL-v2-or-later
12 *
13 * Any future contributions to this file after December 1st 2014 will be
14 * taken to be licensed under the Softfloat-2a license unless specifically
15 * indicated otherwise.
16 */
17
18 /*
19 ===============================================================================
20 This C source file is part of the SoftFloat IEC/IEEE Floating-point
21 Arithmetic Package, Release 2a.
22
23 Written by John R. Hauser. This work was made possible in part by the
24 International Computer Science Institute, located at Suite 600, 1947 Center
25 Street, Berkeley, California 94704. Funding was partially provided by the
26 National Science Foundation under grant MIP-9311980. The original version
27 of this code was written as part of a project to build a fixed-point vector
28 processor in collaboration with the University of California at Berkeley,
29 overseen by Profs. Nelson Morgan and John Wawrzynek. More information
30 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
31 arithmetic/SoftFloat.html'.
32
33 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
34 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
35 TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
36 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
37 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
38
39 Derivative works are acceptable, even for commercial purposes, so long as
40 (1) they include prominent notice that the work is derivative, and (2) they
41 include prominent notice akin to these four paragraphs for those parts of
42 this code that are retained.
43
44 ===============================================================================
45 */
46
47 /* BSD licensing:
48 * Copyright (c) 2006, Fabrice Bellard
49 * All rights reserved.
50 *
51 * Redistribution and use in source and binary forms, with or without
52 * modification, are permitted provided that the following conditions are met:
53 *
54 * 1. Redistributions of source code must retain the above copyright notice,
55 * this list of conditions and the following disclaimer.
56 *
57 * 2. Redistributions in binary form must reproduce the above copyright notice,
58 * this list of conditions and the following disclaimer in the documentation
59 * and/or other materials provided with the distribution.
60 *
61 * 3. Neither the name of the copyright holder nor the names of its contributors
62 * may be used to endorse or promote products derived from this software without
63 * specific prior written permission.
64 *
65 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
66 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
67 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
68 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
69 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
70 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
71 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
72 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
73 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
74 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
75 * THE POSSIBILITY OF SUCH DAMAGE.
76 */
77
78 /* Portions of this work are licensed under the terms of the GNU GPL,
79 * version 2 or later. See the COPYING file in the top-level directory.
80 */
81
82 /* softfloat (and in particular the code in softfloat-specialize.h) is
83 * target-dependent and needs the TARGET_* macros.
84 */
85 #include "qemu/osdep.h"
86 #include <math.h>
87 #include "qemu/bitops.h"
88 #include "fpu/softfloat.h"
89
90 /* We only need stdlib for abort() */
91
92 /*----------------------------------------------------------------------------
93 | Primitive arithmetic functions, including multi-word arithmetic, and
94 | division and square root approximations. (Can be specialized to target if
95 | desired.)
96 *----------------------------------------------------------------------------*/
97 #include "fpu/softfloat-macros.h"
98
99 /*
100 * Hardfloat
101 *
102 * Fast emulation of guest FP instructions is challenging for two reasons.
103 * First, FP instruction semantics are similar but not identical, particularly
104 * when handling NaNs. Second, emulating at reasonable speed the guest FP
105 * exception flags is not trivial: reading the host's flags register with a
106 * feclearexcept & fetestexcept pair is slow [slightly slower than soft-fp],
107 * and trapping on every FP exception is not fast nor pleasant to work with.
108 *
109 * We address these challenges by leveraging the host FPU for a subset of the
110 * operations. To do this we expand on the idea presented in this paper:
111 *
112 * Guo, Yu-Chuan, et al. "Translating the ARM Neon and VFP instructions in a
113 * binary translator." Software: Practice and Experience 46.12 (2016):1591-1615.
114 *
115 * The idea is thus to leverage the host FPU to (1) compute FP operations
116 * and (2) identify whether FP exceptions occurred while avoiding
117 * expensive exception flag register accesses.
118 *
119 * An important optimization shown in the paper is that given that exception
120 * flags are rarely cleared by the guest, we can avoid recomputing some flags.
121 * This is particularly useful for the inexact flag, which is very frequently
122 * raised in floating-point workloads.
123 *
124 * We optimize the code further by deferring to soft-fp whenever FP exception
125 * detection might get hairy. Two examples: (1) when at least one operand is
126 * denormal/inf/NaN; (2) when operands are not guaranteed to lead to a 0 result
127 * and the result is < the minimum normal.
128 */
129 #define GEN_INPUT_FLUSH__NOCHECK(name, soft_t) \
130 static inline void name(soft_t *a, float_status *s) \
131 { \
132 if (unlikely(soft_t ## _is_denormal(*a))) { \
133 *a = soft_t ## _set_sign(soft_t ## _zero, \
134 soft_t ## _is_neg(*a)); \
135 float_raise(float_flag_input_denormal, s); \
136 } \
137 }
138
GEN_INPUT_FLUSH__NOCHECK(float32_input_flush__nocheck,float32)139 GEN_INPUT_FLUSH__NOCHECK(float32_input_flush__nocheck, float32)
140 GEN_INPUT_FLUSH__NOCHECK(float64_input_flush__nocheck, float64)
141 #undef GEN_INPUT_FLUSH__NOCHECK
142
143 #define GEN_INPUT_FLUSH1(name, soft_t) \
144 static inline void name(soft_t *a, float_status *s) \
145 { \
146 if (likely(!s->flush_inputs_to_zero)) { \
147 return; \
148 } \
149 soft_t ## _input_flush__nocheck(a, s); \
150 }
151
152 GEN_INPUT_FLUSH1(float32_input_flush1, float32)
153 GEN_INPUT_FLUSH1(float64_input_flush1, float64)
154 #undef GEN_INPUT_FLUSH1
155
156 #define GEN_INPUT_FLUSH2(name, soft_t) \
157 static inline void name(soft_t *a, soft_t *b, float_status *s) \
158 { \
159 if (likely(!s->flush_inputs_to_zero)) { \
160 return; \
161 } \
162 soft_t ## _input_flush__nocheck(a, s); \
163 soft_t ## _input_flush__nocheck(b, s); \
164 }
165
166 GEN_INPUT_FLUSH2(float32_input_flush2, float32)
167 GEN_INPUT_FLUSH2(float64_input_flush2, float64)
168 #undef GEN_INPUT_FLUSH2
169
170 #define GEN_INPUT_FLUSH3(name, soft_t) \
171 static inline void name(soft_t *a, soft_t *b, soft_t *c, float_status *s) \
172 { \
173 if (likely(!s->flush_inputs_to_zero)) { \
174 return; \
175 } \
176 soft_t ## _input_flush__nocheck(a, s); \
177 soft_t ## _input_flush__nocheck(b, s); \
178 soft_t ## _input_flush__nocheck(c, s); \
179 }
180
181 GEN_INPUT_FLUSH3(float32_input_flush3, float32)
182 GEN_INPUT_FLUSH3(float64_input_flush3, float64)
183 #undef GEN_INPUT_FLUSH3
184
185 /*
186 * Choose whether to use fpclassify or float32/64_* primitives in the generated
187 * hardfloat functions. Each combination of number of inputs and float size
188 * gets its own value.
189 */
190 #if defined(__x86_64__)
191 # define QEMU_HARDFLOAT_1F32_USE_FP 0
192 # define QEMU_HARDFLOAT_1F64_USE_FP 1
193 # define QEMU_HARDFLOAT_2F32_USE_FP 0
194 # define QEMU_HARDFLOAT_2F64_USE_FP 1
195 # define QEMU_HARDFLOAT_3F32_USE_FP 0
196 # define QEMU_HARDFLOAT_3F64_USE_FP 1
197 #else
198 # define QEMU_HARDFLOAT_1F32_USE_FP 0
199 # define QEMU_HARDFLOAT_1F64_USE_FP 0
200 # define QEMU_HARDFLOAT_2F32_USE_FP 0
201 # define QEMU_HARDFLOAT_2F64_USE_FP 0
202 # define QEMU_HARDFLOAT_3F32_USE_FP 0
203 # define QEMU_HARDFLOAT_3F64_USE_FP 0
204 #endif
205
206 /*
207 * QEMU_HARDFLOAT_USE_ISINF chooses whether to use isinf() over
208 * float{32,64}_is_infinity when !USE_FP.
209 * On x86_64/aarch64, using the former over the latter can yield a ~6% speedup.
210 * On power64 however, using isinf() reduces fp-bench performance by up to 50%.
211 */
212 #if defined(__x86_64__) || defined(__aarch64__)
213 # define QEMU_HARDFLOAT_USE_ISINF 1
214 #else
215 # define QEMU_HARDFLOAT_USE_ISINF 0
216 #endif
217
218 /*
219 * Some targets clear the FP flags before most FP operations. This prevents
220 * the use of hardfloat, since hardfloat relies on the inexact flag being
221 * already set.
222 */
223 #if defined(TARGET_PPC) || defined(__FAST_MATH__)
224 # if defined(__FAST_MATH__)
225 # warning disabling hardfloat due to -ffast-math: hardfloat requires an exact \
226 IEEE implementation
227 # endif
228 # define QEMU_NO_HARDFLOAT 1
229 # define QEMU_SOFTFLOAT_ATTR QEMU_FLATTEN
230 #else
231 # define QEMU_NO_HARDFLOAT 0
232 # define QEMU_SOFTFLOAT_ATTR QEMU_FLATTEN __attribute__((noinline))
233 #endif
234
235 static inline bool can_use_fpu(const float_status *s)
236 {
237 if (QEMU_NO_HARDFLOAT) {
238 return false;
239 }
240 return likely(s->float_exception_flags & float_flag_inexact &&
241 s->float_rounding_mode == float_round_nearest_even);
242 }
243
244 /*
245 * Hardfloat generation functions. Each operation can have two flavors:
246 * either using softfloat primitives (e.g. float32_is_zero_or_normal) for
247 * most condition checks, or native ones (e.g. fpclassify).
248 *
249 * The flavor is chosen by the callers. Instead of using macros, we rely on the
250 * compiler to propagate constants and inline everything into the callers.
251 *
252 * We only generate functions for operations with two inputs, since only
253 * these are common enough to justify consolidating them into common code.
254 */
255
256 typedef union {
257 float32 s;
258 float h;
259 } union_float32;
260
261 typedef union {
262 float64 s;
263 double h;
264 } union_float64;
265
266 typedef bool (*f32_check_fn)(union_float32 a, union_float32 b);
267 typedef bool (*f64_check_fn)(union_float64 a, union_float64 b);
268
269 typedef float32 (*soft_f32_op2_fn)(float32 a, float32 b, float_status *s);
270 typedef float64 (*soft_f64_op2_fn)(float64 a, float64 b, float_status *s);
271 typedef float (*hard_f32_op2_fn)(float a, float b);
272 typedef double (*hard_f64_op2_fn)(double a, double b);
273
274 /* 2-input is-zero-or-normal */
f32_is_zon2(union_float32 a,union_float32 b)275 static inline bool f32_is_zon2(union_float32 a, union_float32 b)
276 {
277 if (QEMU_HARDFLOAT_2F32_USE_FP) {
278 /*
279 * Not using a temp variable for consecutive fpclassify calls ends up
280 * generating faster code.
281 */
282 return (fpclassify(a.h) == FP_NORMAL || fpclassify(a.h) == FP_ZERO) &&
283 (fpclassify(b.h) == FP_NORMAL || fpclassify(b.h) == FP_ZERO);
284 }
285 return float32_is_zero_or_normal(a.s) &&
286 float32_is_zero_or_normal(b.s);
287 }
288
f64_is_zon2(union_float64 a,union_float64 b)289 static inline bool f64_is_zon2(union_float64 a, union_float64 b)
290 {
291 if (QEMU_HARDFLOAT_2F64_USE_FP) {
292 return (fpclassify(a.h) == FP_NORMAL || fpclassify(a.h) == FP_ZERO) &&
293 (fpclassify(b.h) == FP_NORMAL || fpclassify(b.h) == FP_ZERO);
294 }
295 return float64_is_zero_or_normal(a.s) &&
296 float64_is_zero_or_normal(b.s);
297 }
298
299 /* 3-input is-zero-or-normal */
300 static inline
f32_is_zon3(union_float32 a,union_float32 b,union_float32 c)301 bool f32_is_zon3(union_float32 a, union_float32 b, union_float32 c)
302 {
303 if (QEMU_HARDFLOAT_3F32_USE_FP) {
304 return (fpclassify(a.h) == FP_NORMAL || fpclassify(a.h) == FP_ZERO) &&
305 (fpclassify(b.h) == FP_NORMAL || fpclassify(b.h) == FP_ZERO) &&
306 (fpclassify(c.h) == FP_NORMAL || fpclassify(c.h) == FP_ZERO);
307 }
308 return float32_is_zero_or_normal(a.s) &&
309 float32_is_zero_or_normal(b.s) &&
310 float32_is_zero_or_normal(c.s);
311 }
312
313 static inline
f64_is_zon3(union_float64 a,union_float64 b,union_float64 c)314 bool f64_is_zon3(union_float64 a, union_float64 b, union_float64 c)
315 {
316 if (QEMU_HARDFLOAT_3F64_USE_FP) {
317 return (fpclassify(a.h) == FP_NORMAL || fpclassify(a.h) == FP_ZERO) &&
318 (fpclassify(b.h) == FP_NORMAL || fpclassify(b.h) == FP_ZERO) &&
319 (fpclassify(c.h) == FP_NORMAL || fpclassify(c.h) == FP_ZERO);
320 }
321 return float64_is_zero_or_normal(a.s) &&
322 float64_is_zero_or_normal(b.s) &&
323 float64_is_zero_or_normal(c.s);
324 }
325
f32_is_inf(union_float32 a)326 static inline bool f32_is_inf(union_float32 a)
327 {
328 if (QEMU_HARDFLOAT_USE_ISINF) {
329 return isinf(a.h);
330 }
331 return float32_is_infinity(a.s);
332 }
333
f64_is_inf(union_float64 a)334 static inline bool f64_is_inf(union_float64 a)
335 {
336 if (QEMU_HARDFLOAT_USE_ISINF) {
337 return isinf(a.h);
338 }
339 return float64_is_infinity(a.s);
340 }
341
342 static inline float32
float32_gen2(float32 xa,float32 xb,float_status * s,hard_f32_op2_fn hard,soft_f32_op2_fn soft,f32_check_fn pre,f32_check_fn post)343 float32_gen2(float32 xa, float32 xb, float_status *s,
344 hard_f32_op2_fn hard, soft_f32_op2_fn soft,
345 f32_check_fn pre, f32_check_fn post)
346 {
347 union_float32 ua, ub, ur;
348
349 ua.s = xa;
350 ub.s = xb;
351
352 if (unlikely(!can_use_fpu(s))) {
353 goto soft;
354 }
355
356 float32_input_flush2(&ua.s, &ub.s, s);
357 if (unlikely(!pre(ua, ub))) {
358 goto soft;
359 }
360
361 ur.h = hard(ua.h, ub.h);
362 if (unlikely(f32_is_inf(ur))) {
363 float_raise(float_flag_overflow, s);
364 } else if (unlikely(fabsf(ur.h) <= FLT_MIN) && post(ua, ub)) {
365 goto soft;
366 }
367 return ur.s;
368
369 soft:
370 return soft(ua.s, ub.s, s);
371 }
372
373 static inline float64
float64_gen2(float64 xa,float64 xb,float_status * s,hard_f64_op2_fn hard,soft_f64_op2_fn soft,f64_check_fn pre,f64_check_fn post)374 float64_gen2(float64 xa, float64 xb, float_status *s,
375 hard_f64_op2_fn hard, soft_f64_op2_fn soft,
376 f64_check_fn pre, f64_check_fn post)
377 {
378 union_float64 ua, ub, ur;
379
380 ua.s = xa;
381 ub.s = xb;
382
383 if (unlikely(!can_use_fpu(s))) {
384 goto soft;
385 }
386
387 float64_input_flush2(&ua.s, &ub.s, s);
388 if (unlikely(!pre(ua, ub))) {
389 goto soft;
390 }
391
392 ur.h = hard(ua.h, ub.h);
393 if (unlikely(f64_is_inf(ur))) {
394 float_raise(float_flag_overflow, s);
395 } else if (unlikely(fabs(ur.h) <= DBL_MIN) && post(ua, ub)) {
396 goto soft;
397 }
398 return ur.s;
399
400 soft:
401 return soft(ua.s, ub.s, s);
402 }
403
404 /*
405 * Classify a floating point number. Everything above float_class_qnan
406 * is a NaN so cls >= float_class_qnan is any NaN.
407 */
408
409 typedef enum __attribute__ ((__packed__)) {
410 float_class_unclassified,
411 float_class_zero,
412 float_class_normal,
413 float_class_inf,
414 float_class_qnan, /* all NaNs from here */
415 float_class_snan,
416 } FloatClass;
417
418 #define float_cmask(bit) (1u << (bit))
419
420 enum {
421 float_cmask_zero = float_cmask(float_class_zero),
422 float_cmask_normal = float_cmask(float_class_normal),
423 float_cmask_inf = float_cmask(float_class_inf),
424 float_cmask_qnan = float_cmask(float_class_qnan),
425 float_cmask_snan = float_cmask(float_class_snan),
426
427 float_cmask_infzero = float_cmask_zero | float_cmask_inf,
428 float_cmask_anynan = float_cmask_qnan | float_cmask_snan,
429 };
430
431 /* Flags for parts_minmax. */
432 enum {
433 /* Set for minimum; clear for maximum. */
434 minmax_ismin = 1,
435 /* Set for the IEEE 754-2008 minNum() and maxNum() operations. */
436 minmax_isnum = 2,
437 /* Set for the IEEE 754-2008 minNumMag() and minNumMag() operations. */
438 minmax_ismag = 4,
439 /*
440 * Set for the IEEE 754-2019 minimumNumber() and maximumNumber()
441 * operations.
442 */
443 minmax_isnumber = 8,
444 };
445
446 /* Simple helpers for checking if, or what kind of, NaN we have */
is_nan(FloatClass c)447 static inline __attribute__((unused)) bool is_nan(FloatClass c)
448 {
449 return unlikely(c >= float_class_qnan);
450 }
451
is_snan(FloatClass c)452 static inline __attribute__((unused)) bool is_snan(FloatClass c)
453 {
454 return c == float_class_snan;
455 }
456
is_qnan(FloatClass c)457 static inline __attribute__((unused)) bool is_qnan(FloatClass c)
458 {
459 return c == float_class_qnan;
460 }
461
462 /*
463 * Structure holding all of the decomposed parts of a float.
464 * The exponent is unbiased and the fraction is normalized.
465 *
466 * The fraction words are stored in big-endian word ordering,
467 * so that truncation from a larger format to a smaller format
468 * can be done simply by ignoring subsequent elements.
469 */
470
471 typedef struct {
472 FloatClass cls;
473 bool sign;
474 int32_t exp;
475 union {
476 /* Routines that know the structure may reference the singular name. */
477 uint64_t frac;
478 /*
479 * Routines expanded with multiple structures reference "hi" and "lo"
480 * depending on the operation. In FloatParts64, "hi" and "lo" are
481 * both the same word and aliased here.
482 */
483 uint64_t frac_hi;
484 uint64_t frac_lo;
485 };
486 } FloatParts64;
487
488 typedef struct {
489 FloatClass cls;
490 bool sign;
491 int32_t exp;
492 uint64_t frac_hi;
493 uint64_t frac_lo;
494 } FloatParts128;
495
496 typedef struct {
497 FloatClass cls;
498 bool sign;
499 int32_t exp;
500 uint64_t frac_hi;
501 uint64_t frac_hm; /* high-middle */
502 uint64_t frac_lm; /* low-middle */
503 uint64_t frac_lo;
504 } FloatParts256;
505
506 /* These apply to the most significant word of each FloatPartsN. */
507 #define DECOMPOSED_BINARY_POINT 63
508 #define DECOMPOSED_IMPLICIT_BIT (1ull << DECOMPOSED_BINARY_POINT)
509
510 /* Structure holding all of the relevant parameters for a format.
511 * exp_size: the size of the exponent field
512 * exp_bias: the offset applied to the exponent field
513 * exp_max: the maximum normalised exponent
514 * frac_size: the size of the fraction field
515 * frac_shift: shift to normalise the fraction with DECOMPOSED_BINARY_POINT
516 * The following are computed based the size of fraction
517 * round_mask: bits below lsb which must be rounded
518 * The following optional modifiers are available:
519 * arm_althp: handle ARM Alternative Half Precision
520 * m68k_denormal: explicit integer bit for extended precision may be 1
521 */
522 typedef struct {
523 int exp_size;
524 int exp_bias;
525 int exp_re_bias;
526 int exp_max;
527 int frac_size;
528 int frac_shift;
529 bool arm_althp;
530 bool m68k_denormal;
531 uint64_t round_mask;
532 } FloatFmt;
533
534 /* Expand fields based on the size of exponent and fraction */
535 #define FLOAT_PARAMS_(E) \
536 .exp_size = E, \
537 .exp_bias = ((1 << E) - 1) >> 1, \
538 .exp_re_bias = (1 << (E - 1)) + (1 << (E - 2)), \
539 .exp_max = (1 << E) - 1
540
541 #define FLOAT_PARAMS(E, F) \
542 FLOAT_PARAMS_(E), \
543 .frac_size = F, \
544 .frac_shift = (-F - 1) & 63, \
545 .round_mask = (1ull << ((-F - 1) & 63)) - 1
546
547 static const FloatFmt float16_params = {
548 FLOAT_PARAMS(5, 10)
549 };
550
551 static const FloatFmt float16_params_ahp = {
552 FLOAT_PARAMS(5, 10),
553 .arm_althp = true
554 };
555
556 static const FloatFmt bfloat16_params = {
557 FLOAT_PARAMS(8, 7)
558 };
559
560 static const FloatFmt float32_params = {
561 FLOAT_PARAMS(8, 23)
562 };
563
564 static const FloatFmt float64_params = {
565 FLOAT_PARAMS(11, 52)
566 };
567
568 static const FloatFmt float128_params = {
569 FLOAT_PARAMS(15, 112)
570 };
571
572 #define FLOATX80_PARAMS(R) \
573 FLOAT_PARAMS_(15), \
574 .frac_size = R == 64 ? 63 : R, \
575 .frac_shift = 0, \
576 .round_mask = R == 64 ? -1 : (1ull << ((-R - 1) & 63)) - 1
577
578 static const FloatFmt floatx80_params[3] = {
579 [floatx80_precision_s] = { FLOATX80_PARAMS(23) },
580 [floatx80_precision_d] = { FLOATX80_PARAMS(52) },
581 [floatx80_precision_x] = {
582 FLOATX80_PARAMS(64),
583 #ifdef TARGET_M68K
584 .m68k_denormal = true,
585 #endif
586 },
587 };
588
589 /* Unpack a float to parts, but do not canonicalize. */
unpack_raw64(FloatParts64 * r,const FloatFmt * fmt,uint64_t raw)590 static void unpack_raw64(FloatParts64 *r, const FloatFmt *fmt, uint64_t raw)
591 {
592 const int f_size = fmt->frac_size;
593 const int e_size = fmt->exp_size;
594
595 *r = (FloatParts64) {
596 .cls = float_class_unclassified,
597 .sign = extract64(raw, f_size + e_size, 1),
598 .exp = extract64(raw, f_size, e_size),
599 .frac = extract64(raw, 0, f_size)
600 };
601 }
602
float16_unpack_raw(FloatParts64 * p,float16 f)603 static void QEMU_FLATTEN float16_unpack_raw(FloatParts64 *p, float16 f)
604 {
605 unpack_raw64(p, &float16_params, f);
606 }
607
bfloat16_unpack_raw(FloatParts64 * p,bfloat16 f)608 static void QEMU_FLATTEN bfloat16_unpack_raw(FloatParts64 *p, bfloat16 f)
609 {
610 unpack_raw64(p, &bfloat16_params, f);
611 }
612
float32_unpack_raw(FloatParts64 * p,float32 f)613 static void QEMU_FLATTEN float32_unpack_raw(FloatParts64 *p, float32 f)
614 {
615 unpack_raw64(p, &float32_params, f);
616 }
617
float64_unpack_raw(FloatParts64 * p,float64 f)618 static void QEMU_FLATTEN float64_unpack_raw(FloatParts64 *p, float64 f)
619 {
620 unpack_raw64(p, &float64_params, f);
621 }
622
floatx80_unpack_raw(FloatParts128 * p,floatx80 f)623 static void QEMU_FLATTEN floatx80_unpack_raw(FloatParts128 *p, floatx80 f)
624 {
625 *p = (FloatParts128) {
626 .cls = float_class_unclassified,
627 .sign = extract32(f.high, 15, 1),
628 .exp = extract32(f.high, 0, 15),
629 .frac_hi = f.low
630 };
631 }
632
float128_unpack_raw(FloatParts128 * p,float128 f)633 static void QEMU_FLATTEN float128_unpack_raw(FloatParts128 *p, float128 f)
634 {
635 const int f_size = float128_params.frac_size - 64;
636 const int e_size = float128_params.exp_size;
637
638 *p = (FloatParts128) {
639 .cls = float_class_unclassified,
640 .sign = extract64(f.high, f_size + e_size, 1),
641 .exp = extract64(f.high, f_size, e_size),
642 .frac_hi = extract64(f.high, 0, f_size),
643 .frac_lo = f.low,
644 };
645 }
646
647 /* Pack a float from parts, but do not canonicalize. */
pack_raw64(const FloatParts64 * p,const FloatFmt * fmt)648 static uint64_t pack_raw64(const FloatParts64 *p, const FloatFmt *fmt)
649 {
650 const int f_size = fmt->frac_size;
651 const int e_size = fmt->exp_size;
652 uint64_t ret;
653
654 ret = (uint64_t)p->sign << (f_size + e_size);
655 ret = deposit64(ret, f_size, e_size, p->exp);
656 ret = deposit64(ret, 0, f_size, p->frac);
657 return ret;
658 }
659
float16_pack_raw(const FloatParts64 * p)660 static float16 QEMU_FLATTEN float16_pack_raw(const FloatParts64 *p)
661 {
662 return make_float16(pack_raw64(p, &float16_params));
663 }
664
bfloat16_pack_raw(const FloatParts64 * p)665 static bfloat16 QEMU_FLATTEN bfloat16_pack_raw(const FloatParts64 *p)
666 {
667 return pack_raw64(p, &bfloat16_params);
668 }
669
float32_pack_raw(const FloatParts64 * p)670 static float32 QEMU_FLATTEN float32_pack_raw(const FloatParts64 *p)
671 {
672 return make_float32(pack_raw64(p, &float32_params));
673 }
674
float64_pack_raw(const FloatParts64 * p)675 static float64 QEMU_FLATTEN float64_pack_raw(const FloatParts64 *p)
676 {
677 return make_float64(pack_raw64(p, &float64_params));
678 }
679
float128_pack_raw(const FloatParts128 * p)680 static float128 QEMU_FLATTEN float128_pack_raw(const FloatParts128 *p)
681 {
682 const int f_size = float128_params.frac_size - 64;
683 const int e_size = float128_params.exp_size;
684 uint64_t hi;
685
686 hi = (uint64_t)p->sign << (f_size + e_size);
687 hi = deposit64(hi, f_size, e_size, p->exp);
688 hi = deposit64(hi, 0, f_size, p->frac_hi);
689 return make_float128(hi, p->frac_lo);
690 }
691
692 /*----------------------------------------------------------------------------
693 | Functions and definitions to determine: (1) whether tininess for underflow
694 | is detected before or after rounding by default, (2) what (if anything)
695 | happens when exceptions are raised, (3) how signaling NaNs are distinguished
696 | from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
697 | are propagated from function inputs to output. These details are target-
698 | specific.
699 *----------------------------------------------------------------------------*/
700 #include "softfloat-specialize.c.inc"
701
702 #define PARTS_GENERIC_64_128(NAME, P) \
703 _Generic((P), FloatParts64 *: parts64_##NAME, \
704 FloatParts128 *: parts128_##NAME)
705
706 #define PARTS_GENERIC_64_128_256(NAME, P) \
707 _Generic((P), FloatParts64 *: parts64_##NAME, \
708 FloatParts128 *: parts128_##NAME, \
709 FloatParts256 *: parts256_##NAME)
710
711 #define parts_default_nan(P, S) PARTS_GENERIC_64_128(default_nan, P)(P, S)
712 #define parts_silence_nan(P, S) PARTS_GENERIC_64_128(silence_nan, P)(P, S)
713
714 static void parts64_return_nan(FloatParts64 *a, float_status *s);
715 static void parts128_return_nan(FloatParts128 *a, float_status *s);
716
717 #define parts_return_nan(P, S) PARTS_GENERIC_64_128(return_nan, P)(P, S)
718
719 static FloatParts64 *parts64_pick_nan(FloatParts64 *a, FloatParts64 *b,
720 float_status *s);
721 static FloatParts128 *parts128_pick_nan(FloatParts128 *a, FloatParts128 *b,
722 float_status *s);
723
724 #define parts_pick_nan(A, B, S) PARTS_GENERIC_64_128(pick_nan, A)(A, B, S)
725
726 static FloatParts64 *parts64_pick_nan_muladd(FloatParts64 *a, FloatParts64 *b,
727 FloatParts64 *c, float_status *s,
728 int ab_mask, int abc_mask);
729 static FloatParts128 *parts128_pick_nan_muladd(FloatParts128 *a,
730 FloatParts128 *b,
731 FloatParts128 *c,
732 float_status *s,
733 int ab_mask, int abc_mask);
734
735 #define parts_pick_nan_muladd(A, B, C, S, ABM, ABCM) \
736 PARTS_GENERIC_64_128(pick_nan_muladd, A)(A, B, C, S, ABM, ABCM)
737
738 static void parts64_canonicalize(FloatParts64 *p, float_status *status,
739 const FloatFmt *fmt);
740 static void parts128_canonicalize(FloatParts128 *p, float_status *status,
741 const FloatFmt *fmt);
742
743 #define parts_canonicalize(A, S, F) \
744 PARTS_GENERIC_64_128(canonicalize, A)(A, S, F)
745
746 static void parts64_uncanon_normal(FloatParts64 *p, float_status *status,
747 const FloatFmt *fmt);
748 static void parts128_uncanon_normal(FloatParts128 *p, float_status *status,
749 const FloatFmt *fmt);
750
751 #define parts_uncanon_normal(A, S, F) \
752 PARTS_GENERIC_64_128(uncanon_normal, A)(A, S, F)
753
754 static void parts64_uncanon(FloatParts64 *p, float_status *status,
755 const FloatFmt *fmt);
756 static void parts128_uncanon(FloatParts128 *p, float_status *status,
757 const FloatFmt *fmt);
758
759 #define parts_uncanon(A, S, F) \
760 PARTS_GENERIC_64_128(uncanon, A)(A, S, F)
761
762 static void parts64_add_normal(FloatParts64 *a, FloatParts64 *b);
763 static void parts128_add_normal(FloatParts128 *a, FloatParts128 *b);
764 static void parts256_add_normal(FloatParts256 *a, FloatParts256 *b);
765
766 #define parts_add_normal(A, B) \
767 PARTS_GENERIC_64_128_256(add_normal, A)(A, B)
768
769 static bool parts64_sub_normal(FloatParts64 *a, FloatParts64 *b);
770 static bool parts128_sub_normal(FloatParts128 *a, FloatParts128 *b);
771 static bool parts256_sub_normal(FloatParts256 *a, FloatParts256 *b);
772
773 #define parts_sub_normal(A, B) \
774 PARTS_GENERIC_64_128_256(sub_normal, A)(A, B)
775
776 static FloatParts64 *parts64_addsub(FloatParts64 *a, FloatParts64 *b,
777 float_status *s, bool subtract);
778 static FloatParts128 *parts128_addsub(FloatParts128 *a, FloatParts128 *b,
779 float_status *s, bool subtract);
780
781 #define parts_addsub(A, B, S, Z) \
782 PARTS_GENERIC_64_128(addsub, A)(A, B, S, Z)
783
784 static FloatParts64 *parts64_mul(FloatParts64 *a, FloatParts64 *b,
785 float_status *s);
786 static FloatParts128 *parts128_mul(FloatParts128 *a, FloatParts128 *b,
787 float_status *s);
788
789 #define parts_mul(A, B, S) \
790 PARTS_GENERIC_64_128(mul, A)(A, B, S)
791
792 static FloatParts64 *parts64_muladd(FloatParts64 *a, FloatParts64 *b,
793 FloatParts64 *c, int flags,
794 float_status *s);
795 static FloatParts128 *parts128_muladd(FloatParts128 *a, FloatParts128 *b,
796 FloatParts128 *c, int flags,
797 float_status *s);
798
799 #define parts_muladd(A, B, C, Z, S) \
800 PARTS_GENERIC_64_128(muladd, A)(A, B, C, Z, S)
801
802 static FloatParts64 *parts64_div(FloatParts64 *a, FloatParts64 *b,
803 float_status *s);
804 static FloatParts128 *parts128_div(FloatParts128 *a, FloatParts128 *b,
805 float_status *s);
806
807 #define parts_div(A, B, S) \
808 PARTS_GENERIC_64_128(div, A)(A, B, S)
809
810 static FloatParts64 *parts64_modrem(FloatParts64 *a, FloatParts64 *b,
811 uint64_t *mod_quot, float_status *s);
812 static FloatParts128 *parts128_modrem(FloatParts128 *a, FloatParts128 *b,
813 uint64_t *mod_quot, float_status *s);
814
815 #define parts_modrem(A, B, Q, S) \
816 PARTS_GENERIC_64_128(modrem, A)(A, B, Q, S)
817
818 static void parts64_sqrt(FloatParts64 *a, float_status *s, const FloatFmt *f);
819 static void parts128_sqrt(FloatParts128 *a, float_status *s, const FloatFmt *f);
820
821 #define parts_sqrt(A, S, F) \
822 PARTS_GENERIC_64_128(sqrt, A)(A, S, F)
823
824 static bool parts64_round_to_int_normal(FloatParts64 *a, FloatRoundMode rm,
825 int scale, int frac_size);
826 static bool parts128_round_to_int_normal(FloatParts128 *a, FloatRoundMode r,
827 int scale, int frac_size);
828
829 #define parts_round_to_int_normal(A, R, C, F) \
830 PARTS_GENERIC_64_128(round_to_int_normal, A)(A, R, C, F)
831
832 static void parts64_round_to_int(FloatParts64 *a, FloatRoundMode rm,
833 int scale, float_status *s,
834 const FloatFmt *fmt);
835 static void parts128_round_to_int(FloatParts128 *a, FloatRoundMode r,
836 int scale, float_status *s,
837 const FloatFmt *fmt);
838
839 #define parts_round_to_int(A, R, C, S, F) \
840 PARTS_GENERIC_64_128(round_to_int, A)(A, R, C, S, F)
841
842 static int64_t parts64_float_to_sint(FloatParts64 *p, FloatRoundMode rmode,
843 int scale, int64_t min, int64_t max,
844 float_status *s);
845 static int64_t parts128_float_to_sint(FloatParts128 *p, FloatRoundMode rmode,
846 int scale, int64_t min, int64_t max,
847 float_status *s);
848
849 #define parts_float_to_sint(P, R, Z, MN, MX, S) \
850 PARTS_GENERIC_64_128(float_to_sint, P)(P, R, Z, MN, MX, S)
851
852 static uint64_t parts64_float_to_uint(FloatParts64 *p, FloatRoundMode rmode,
853 int scale, uint64_t max,
854 float_status *s);
855 static uint64_t parts128_float_to_uint(FloatParts128 *p, FloatRoundMode rmode,
856 int scale, uint64_t max,
857 float_status *s);
858
859 #define parts_float_to_uint(P, R, Z, M, S) \
860 PARTS_GENERIC_64_128(float_to_uint, P)(P, R, Z, M, S)
861
862 static int64_t parts64_float_to_sint_modulo(FloatParts64 *p,
863 FloatRoundMode rmode,
864 int bitsm1, float_status *s);
865 static int64_t parts128_float_to_sint_modulo(FloatParts128 *p,
866 FloatRoundMode rmode,
867 int bitsm1, float_status *s);
868
869 #define parts_float_to_sint_modulo(P, R, M, S) \
870 PARTS_GENERIC_64_128(float_to_sint_modulo, P)(P, R, M, S)
871
872 static void parts64_sint_to_float(FloatParts64 *p, int64_t a,
873 int scale, float_status *s);
874 static void parts128_sint_to_float(FloatParts128 *p, int64_t a,
875 int scale, float_status *s);
876
877 #define parts_float_to_sint(P, R, Z, MN, MX, S) \
878 PARTS_GENERIC_64_128(float_to_sint, P)(P, R, Z, MN, MX, S)
879
880 #define parts_sint_to_float(P, I, Z, S) \
881 PARTS_GENERIC_64_128(sint_to_float, P)(P, I, Z, S)
882
883 static void parts64_uint_to_float(FloatParts64 *p, uint64_t a,
884 int scale, float_status *s);
885 static void parts128_uint_to_float(FloatParts128 *p, uint64_t a,
886 int scale, float_status *s);
887
888 #define parts_uint_to_float(P, I, Z, S) \
889 PARTS_GENERIC_64_128(uint_to_float, P)(P, I, Z, S)
890
891 static FloatParts64 *parts64_minmax(FloatParts64 *a, FloatParts64 *b,
892 float_status *s, int flags);
893 static FloatParts128 *parts128_minmax(FloatParts128 *a, FloatParts128 *b,
894 float_status *s, int flags);
895
896 #define parts_minmax(A, B, S, F) \
897 PARTS_GENERIC_64_128(minmax, A)(A, B, S, F)
898
899 static FloatRelation parts64_compare(FloatParts64 *a, FloatParts64 *b,
900 float_status *s, bool q);
901 static FloatRelation parts128_compare(FloatParts128 *a, FloatParts128 *b,
902 float_status *s, bool q);
903
904 #define parts_compare(A, B, S, Q) \
905 PARTS_GENERIC_64_128(compare, A)(A, B, S, Q)
906
907 static void parts64_scalbn(FloatParts64 *a, int n, float_status *s);
908 static void parts128_scalbn(FloatParts128 *a, int n, float_status *s);
909
910 #define parts_scalbn(A, N, S) \
911 PARTS_GENERIC_64_128(scalbn, A)(A, N, S)
912
913 static void parts64_log2(FloatParts64 *a, float_status *s, const FloatFmt *f);
914 static void parts128_log2(FloatParts128 *a, float_status *s, const FloatFmt *f);
915
916 #define parts_log2(A, S, F) \
917 PARTS_GENERIC_64_128(log2, A)(A, S, F)
918
919 /*
920 * Helper functions for softfloat-parts.c.inc, per-size operations.
921 */
922
923 #define FRAC_GENERIC_64_128(NAME, P) \
924 _Generic((P), FloatParts64 *: frac64_##NAME, \
925 FloatParts128 *: frac128_##NAME)
926
927 #define FRAC_GENERIC_64_128_256(NAME, P) \
928 _Generic((P), FloatParts64 *: frac64_##NAME, \
929 FloatParts128 *: frac128_##NAME, \
930 FloatParts256 *: frac256_##NAME)
931
frac64_add(FloatParts64 * r,FloatParts64 * a,FloatParts64 * b)932 static bool frac64_add(FloatParts64 *r, FloatParts64 *a, FloatParts64 *b)
933 {
934 return uadd64_overflow(a->frac, b->frac, &r->frac);
935 }
936
frac128_add(FloatParts128 * r,FloatParts128 * a,FloatParts128 * b)937 static bool frac128_add(FloatParts128 *r, FloatParts128 *a, FloatParts128 *b)
938 {
939 bool c = 0;
940 r->frac_lo = uadd64_carry(a->frac_lo, b->frac_lo, &c);
941 r->frac_hi = uadd64_carry(a->frac_hi, b->frac_hi, &c);
942 return c;
943 }
944
frac256_add(FloatParts256 * r,FloatParts256 * a,FloatParts256 * b)945 static bool frac256_add(FloatParts256 *r, FloatParts256 *a, FloatParts256 *b)
946 {
947 bool c = 0;
948 r->frac_lo = uadd64_carry(a->frac_lo, b->frac_lo, &c);
949 r->frac_lm = uadd64_carry(a->frac_lm, b->frac_lm, &c);
950 r->frac_hm = uadd64_carry(a->frac_hm, b->frac_hm, &c);
951 r->frac_hi = uadd64_carry(a->frac_hi, b->frac_hi, &c);
952 return c;
953 }
954
955 #define frac_add(R, A, B) FRAC_GENERIC_64_128_256(add, R)(R, A, B)
956
frac64_addi(FloatParts64 * r,FloatParts64 * a,uint64_t c)957 static bool frac64_addi(FloatParts64 *r, FloatParts64 *a, uint64_t c)
958 {
959 return uadd64_overflow(a->frac, c, &r->frac);
960 }
961
frac128_addi(FloatParts128 * r,FloatParts128 * a,uint64_t c)962 static bool frac128_addi(FloatParts128 *r, FloatParts128 *a, uint64_t c)
963 {
964 c = uadd64_overflow(a->frac_lo, c, &r->frac_lo);
965 return uadd64_overflow(a->frac_hi, c, &r->frac_hi);
966 }
967
968 #define frac_addi(R, A, C) FRAC_GENERIC_64_128(addi, R)(R, A, C)
969
frac64_allones(FloatParts64 * a)970 static void frac64_allones(FloatParts64 *a)
971 {
972 a->frac = -1;
973 }
974
frac128_allones(FloatParts128 * a)975 static void frac128_allones(FloatParts128 *a)
976 {
977 a->frac_hi = a->frac_lo = -1;
978 }
979
980 #define frac_allones(A) FRAC_GENERIC_64_128(allones, A)(A)
981
frac64_cmp(FloatParts64 * a,FloatParts64 * b)982 static FloatRelation frac64_cmp(FloatParts64 *a, FloatParts64 *b)
983 {
984 return (a->frac == b->frac ? float_relation_equal
985 : a->frac < b->frac ? float_relation_less
986 : float_relation_greater);
987 }
988
frac128_cmp(FloatParts128 * a,FloatParts128 * b)989 static FloatRelation frac128_cmp(FloatParts128 *a, FloatParts128 *b)
990 {
991 uint64_t ta = a->frac_hi, tb = b->frac_hi;
992 if (ta == tb) {
993 ta = a->frac_lo, tb = b->frac_lo;
994 if (ta == tb) {
995 return float_relation_equal;
996 }
997 }
998 return ta < tb ? float_relation_less : float_relation_greater;
999 }
1000
1001 #define frac_cmp(A, B) FRAC_GENERIC_64_128(cmp, A)(A, B)
1002
frac64_clear(FloatParts64 * a)1003 static void frac64_clear(FloatParts64 *a)
1004 {
1005 a->frac = 0;
1006 }
1007
frac128_clear(FloatParts128 * a)1008 static void frac128_clear(FloatParts128 *a)
1009 {
1010 a->frac_hi = a->frac_lo = 0;
1011 }
1012
1013 #define frac_clear(A) FRAC_GENERIC_64_128(clear, A)(A)
1014
frac64_div(FloatParts64 * a,FloatParts64 * b)1015 static bool frac64_div(FloatParts64 *a, FloatParts64 *b)
1016 {
1017 uint64_t n1, n0, r, q;
1018 bool ret;
1019
1020 /*
1021 * We want a 2*N / N-bit division to produce exactly an N-bit
1022 * result, so that we do not lose any precision and so that we
1023 * do not have to renormalize afterward. If A.frac < B.frac,
1024 * then division would produce an (N-1)-bit result; shift A left
1025 * by one to produce the an N-bit result, and return true to
1026 * decrement the exponent to match.
1027 *
1028 * The udiv_qrnnd algorithm that we're using requires normalization,
1029 * i.e. the msb of the denominator must be set, which is already true.
1030 */
1031 ret = a->frac < b->frac;
1032 if (ret) {
1033 n0 = a->frac;
1034 n1 = 0;
1035 } else {
1036 n0 = a->frac >> 1;
1037 n1 = a->frac << 63;
1038 }
1039 q = udiv_qrnnd(&r, n0, n1, b->frac);
1040
1041 /* Set lsb if there is a remainder, to set inexact. */
1042 a->frac = q | (r != 0);
1043
1044 return ret;
1045 }
1046
frac128_div(FloatParts128 * a,FloatParts128 * b)1047 static bool frac128_div(FloatParts128 *a, FloatParts128 *b)
1048 {
1049 uint64_t q0, q1, a0, a1, b0, b1;
1050 uint64_t r0, r1, r2, r3, t0, t1, t2, t3;
1051 bool ret = false;
1052
1053 a0 = a->frac_hi, a1 = a->frac_lo;
1054 b0 = b->frac_hi, b1 = b->frac_lo;
1055
1056 ret = lt128(a0, a1, b0, b1);
1057 if (!ret) {
1058 a1 = shr_double(a0, a1, 1);
1059 a0 = a0 >> 1;
1060 }
1061
1062 /* Use 128/64 -> 64 division as estimate for 192/128 -> 128 division. */
1063 q0 = estimateDiv128To64(a0, a1, b0);
1064
1065 /*
1066 * Estimate is high because B1 was not included (unless B1 == 0).
1067 * Reduce quotient and increase remainder until remainder is non-negative.
1068 * This loop will execute 0 to 2 times.
1069 */
1070 mul128By64To192(b0, b1, q0, &t0, &t1, &t2);
1071 sub192(a0, a1, 0, t0, t1, t2, &r0, &r1, &r2);
1072 while (r0 != 0) {
1073 q0--;
1074 add192(r0, r1, r2, 0, b0, b1, &r0, &r1, &r2);
1075 }
1076
1077 /* Repeat using the remainder, producing a second word of quotient. */
1078 q1 = estimateDiv128To64(r1, r2, b0);
1079 mul128By64To192(b0, b1, q1, &t1, &t2, &t3);
1080 sub192(r1, r2, 0, t1, t2, t3, &r1, &r2, &r3);
1081 while (r1 != 0) {
1082 q1--;
1083 add192(r1, r2, r3, 0, b0, b1, &r1, &r2, &r3);
1084 }
1085
1086 /* Any remainder indicates inexact; set sticky bit. */
1087 q1 |= (r2 | r3) != 0;
1088
1089 a->frac_hi = q0;
1090 a->frac_lo = q1;
1091 return ret;
1092 }
1093
1094 #define frac_div(A, B) FRAC_GENERIC_64_128(div, A)(A, B)
1095
frac64_eqz(FloatParts64 * a)1096 static bool frac64_eqz(FloatParts64 *a)
1097 {
1098 return a->frac == 0;
1099 }
1100
frac128_eqz(FloatParts128 * a)1101 static bool frac128_eqz(FloatParts128 *a)
1102 {
1103 return (a->frac_hi | a->frac_lo) == 0;
1104 }
1105
1106 #define frac_eqz(A) FRAC_GENERIC_64_128(eqz, A)(A)
1107
frac64_mulw(FloatParts128 * r,FloatParts64 * a,FloatParts64 * b)1108 static void frac64_mulw(FloatParts128 *r, FloatParts64 *a, FloatParts64 *b)
1109 {
1110 mulu64(&r->frac_lo, &r->frac_hi, a->frac, b->frac);
1111 }
1112
frac128_mulw(FloatParts256 * r,FloatParts128 * a,FloatParts128 * b)1113 static void frac128_mulw(FloatParts256 *r, FloatParts128 *a, FloatParts128 *b)
1114 {
1115 mul128To256(a->frac_hi, a->frac_lo, b->frac_hi, b->frac_lo,
1116 &r->frac_hi, &r->frac_hm, &r->frac_lm, &r->frac_lo);
1117 }
1118
1119 #define frac_mulw(R, A, B) FRAC_GENERIC_64_128(mulw, A)(R, A, B)
1120
frac64_neg(FloatParts64 * a)1121 static void frac64_neg(FloatParts64 *a)
1122 {
1123 a->frac = -a->frac;
1124 }
1125
frac128_neg(FloatParts128 * a)1126 static void frac128_neg(FloatParts128 *a)
1127 {
1128 bool c = 0;
1129 a->frac_lo = usub64_borrow(0, a->frac_lo, &c);
1130 a->frac_hi = usub64_borrow(0, a->frac_hi, &c);
1131 }
1132
frac256_neg(FloatParts256 * a)1133 static void frac256_neg(FloatParts256 *a)
1134 {
1135 bool c = 0;
1136 a->frac_lo = usub64_borrow(0, a->frac_lo, &c);
1137 a->frac_lm = usub64_borrow(0, a->frac_lm, &c);
1138 a->frac_hm = usub64_borrow(0, a->frac_hm, &c);
1139 a->frac_hi = usub64_borrow(0, a->frac_hi, &c);
1140 }
1141
1142 #define frac_neg(A) FRAC_GENERIC_64_128_256(neg, A)(A)
1143
frac64_normalize(FloatParts64 * a)1144 static int frac64_normalize(FloatParts64 *a)
1145 {
1146 if (a->frac) {
1147 int shift = clz64(a->frac);
1148 a->frac <<= shift;
1149 return shift;
1150 }
1151 return 64;
1152 }
1153
frac128_normalize(FloatParts128 * a)1154 static int frac128_normalize(FloatParts128 *a)
1155 {
1156 if (a->frac_hi) {
1157 int shl = clz64(a->frac_hi);
1158 a->frac_hi = shl_double(a->frac_hi, a->frac_lo, shl);
1159 a->frac_lo <<= shl;
1160 return shl;
1161 } else if (a->frac_lo) {
1162 int shl = clz64(a->frac_lo);
1163 a->frac_hi = a->frac_lo << shl;
1164 a->frac_lo = 0;
1165 return shl + 64;
1166 }
1167 return 128;
1168 }
1169
frac256_normalize(FloatParts256 * a)1170 static int frac256_normalize(FloatParts256 *a)
1171 {
1172 uint64_t a0 = a->frac_hi, a1 = a->frac_hm;
1173 uint64_t a2 = a->frac_lm, a3 = a->frac_lo;
1174 int ret, shl;
1175
1176 if (likely(a0)) {
1177 shl = clz64(a0);
1178 if (shl == 0) {
1179 return 0;
1180 }
1181 ret = shl;
1182 } else {
1183 if (a1) {
1184 ret = 64;
1185 a0 = a1, a1 = a2, a2 = a3, a3 = 0;
1186 } else if (a2) {
1187 ret = 128;
1188 a0 = a2, a1 = a3, a2 = 0, a3 = 0;
1189 } else if (a3) {
1190 ret = 192;
1191 a0 = a3, a1 = 0, a2 = 0, a3 = 0;
1192 } else {
1193 ret = 256;
1194 a0 = 0, a1 = 0, a2 = 0, a3 = 0;
1195 goto done;
1196 }
1197 shl = clz64(a0);
1198 if (shl == 0) {
1199 goto done;
1200 }
1201 ret += shl;
1202 }
1203
1204 a0 = shl_double(a0, a1, shl);
1205 a1 = shl_double(a1, a2, shl);
1206 a2 = shl_double(a2, a3, shl);
1207 a3 <<= shl;
1208
1209 done:
1210 a->frac_hi = a0;
1211 a->frac_hm = a1;
1212 a->frac_lm = a2;
1213 a->frac_lo = a3;
1214 return ret;
1215 }
1216
1217 #define frac_normalize(A) FRAC_GENERIC_64_128_256(normalize, A)(A)
1218
frac64_modrem(FloatParts64 * a,FloatParts64 * b,uint64_t * mod_quot)1219 static void frac64_modrem(FloatParts64 *a, FloatParts64 *b, uint64_t *mod_quot)
1220 {
1221 uint64_t a0, a1, b0, t0, t1, q, quot;
1222 int exp_diff = a->exp - b->exp;
1223 int shift;
1224
1225 a0 = a->frac;
1226 a1 = 0;
1227
1228 if (exp_diff < -1) {
1229 if (mod_quot) {
1230 *mod_quot = 0;
1231 }
1232 return;
1233 }
1234 if (exp_diff == -1) {
1235 a0 >>= 1;
1236 exp_diff = 0;
1237 }
1238
1239 b0 = b->frac;
1240 quot = q = b0 <= a0;
1241 if (q) {
1242 a0 -= b0;
1243 }
1244
1245 exp_diff -= 64;
1246 while (exp_diff > 0) {
1247 q = estimateDiv128To64(a0, a1, b0);
1248 q = q > 2 ? q - 2 : 0;
1249 mul64To128(b0, q, &t0, &t1);
1250 sub128(a0, a1, t0, t1, &a0, &a1);
1251 shortShift128Left(a0, a1, 62, &a0, &a1);
1252 exp_diff -= 62;
1253 quot = (quot << 62) + q;
1254 }
1255
1256 exp_diff += 64;
1257 if (exp_diff > 0) {
1258 q = estimateDiv128To64(a0, a1, b0);
1259 q = q > 2 ? (q - 2) >> (64 - exp_diff) : 0;
1260 mul64To128(b0, q << (64 - exp_diff), &t0, &t1);
1261 sub128(a0, a1, t0, t1, &a0, &a1);
1262 shortShift128Left(0, b0, 64 - exp_diff, &t0, &t1);
1263 while (le128(t0, t1, a0, a1)) {
1264 ++q;
1265 sub128(a0, a1, t0, t1, &a0, &a1);
1266 }
1267 quot = (exp_diff < 64 ? quot << exp_diff : 0) + q;
1268 } else {
1269 t0 = b0;
1270 t1 = 0;
1271 }
1272
1273 if (mod_quot) {
1274 *mod_quot = quot;
1275 } else {
1276 sub128(t0, t1, a0, a1, &t0, &t1);
1277 if (lt128(t0, t1, a0, a1) ||
1278 (eq128(t0, t1, a0, a1) && (q & 1))) {
1279 a0 = t0;
1280 a1 = t1;
1281 a->sign = !a->sign;
1282 }
1283 }
1284
1285 if (likely(a0)) {
1286 shift = clz64(a0);
1287 shortShift128Left(a0, a1, shift, &a0, &a1);
1288 } else if (likely(a1)) {
1289 shift = clz64(a1);
1290 a0 = a1 << shift;
1291 a1 = 0;
1292 shift += 64;
1293 } else {
1294 a->cls = float_class_zero;
1295 return;
1296 }
1297
1298 a->exp = b->exp + exp_diff - shift;
1299 a->frac = a0 | (a1 != 0);
1300 }
1301
frac128_modrem(FloatParts128 * a,FloatParts128 * b,uint64_t * mod_quot)1302 static void frac128_modrem(FloatParts128 *a, FloatParts128 *b,
1303 uint64_t *mod_quot)
1304 {
1305 uint64_t a0, a1, a2, b0, b1, t0, t1, t2, q, quot;
1306 int exp_diff = a->exp - b->exp;
1307 int shift;
1308
1309 a0 = a->frac_hi;
1310 a1 = a->frac_lo;
1311 a2 = 0;
1312
1313 if (exp_diff < -1) {
1314 if (mod_quot) {
1315 *mod_quot = 0;
1316 }
1317 return;
1318 }
1319 if (exp_diff == -1) {
1320 shift128Right(a0, a1, 1, &a0, &a1);
1321 exp_diff = 0;
1322 }
1323
1324 b0 = b->frac_hi;
1325 b1 = b->frac_lo;
1326
1327 quot = q = le128(b0, b1, a0, a1);
1328 if (q) {
1329 sub128(a0, a1, b0, b1, &a0, &a1);
1330 }
1331
1332 exp_diff -= 64;
1333 while (exp_diff > 0) {
1334 q = estimateDiv128To64(a0, a1, b0);
1335 q = q > 4 ? q - 4 : 0;
1336 mul128By64To192(b0, b1, q, &t0, &t1, &t2);
1337 sub192(a0, a1, a2, t0, t1, t2, &a0, &a1, &a2);
1338 shortShift192Left(a0, a1, a2, 61, &a0, &a1, &a2);
1339 exp_diff -= 61;
1340 quot = (quot << 61) + q;
1341 }
1342
1343 exp_diff += 64;
1344 if (exp_diff > 0) {
1345 q = estimateDiv128To64(a0, a1, b0);
1346 q = q > 4 ? (q - 4) >> (64 - exp_diff) : 0;
1347 mul128By64To192(b0, b1, q << (64 - exp_diff), &t0, &t1, &t2);
1348 sub192(a0, a1, a2, t0, t1, t2, &a0, &a1, &a2);
1349 shortShift192Left(0, b0, b1, 64 - exp_diff, &t0, &t1, &t2);
1350 while (le192(t0, t1, t2, a0, a1, a2)) {
1351 ++q;
1352 sub192(a0, a1, a2, t0, t1, t2, &a0, &a1, &a2);
1353 }
1354 quot = (exp_diff < 64 ? quot << exp_diff : 0) + q;
1355 } else {
1356 t0 = b0;
1357 t1 = b1;
1358 t2 = 0;
1359 }
1360
1361 if (mod_quot) {
1362 *mod_quot = quot;
1363 } else {
1364 sub192(t0, t1, t2, a0, a1, a2, &t0, &t1, &t2);
1365 if (lt192(t0, t1, t2, a0, a1, a2) ||
1366 (eq192(t0, t1, t2, a0, a1, a2) && (q & 1))) {
1367 a0 = t0;
1368 a1 = t1;
1369 a2 = t2;
1370 a->sign = !a->sign;
1371 }
1372 }
1373
1374 if (likely(a0)) {
1375 shift = clz64(a0);
1376 shortShift192Left(a0, a1, a2, shift, &a0, &a1, &a2);
1377 } else if (likely(a1)) {
1378 shift = clz64(a1);
1379 shortShift128Left(a1, a2, shift, &a0, &a1);
1380 a2 = 0;
1381 shift += 64;
1382 } else if (likely(a2)) {
1383 shift = clz64(a2);
1384 a0 = a2 << shift;
1385 a1 = a2 = 0;
1386 shift += 128;
1387 } else {
1388 a->cls = float_class_zero;
1389 return;
1390 }
1391
1392 a->exp = b->exp + exp_diff - shift;
1393 a->frac_hi = a0;
1394 a->frac_lo = a1 | (a2 != 0);
1395 }
1396
1397 #define frac_modrem(A, B, Q) FRAC_GENERIC_64_128(modrem, A)(A, B, Q)
1398
frac64_shl(FloatParts64 * a,int c)1399 static void frac64_shl(FloatParts64 *a, int c)
1400 {
1401 a->frac <<= c;
1402 }
1403
frac128_shl(FloatParts128 * a,int c)1404 static void frac128_shl(FloatParts128 *a, int c)
1405 {
1406 uint64_t a0 = a->frac_hi, a1 = a->frac_lo;
1407
1408 if (c & 64) {
1409 a0 = a1, a1 = 0;
1410 }
1411
1412 c &= 63;
1413 if (c) {
1414 a0 = shl_double(a0, a1, c);
1415 a1 = a1 << c;
1416 }
1417
1418 a->frac_hi = a0;
1419 a->frac_lo = a1;
1420 }
1421
1422 #define frac_shl(A, C) FRAC_GENERIC_64_128(shl, A)(A, C)
1423
frac64_shr(FloatParts64 * a,int c)1424 static void frac64_shr(FloatParts64 *a, int c)
1425 {
1426 a->frac >>= c;
1427 }
1428
frac128_shr(FloatParts128 * a,int c)1429 static void frac128_shr(FloatParts128 *a, int c)
1430 {
1431 uint64_t a0 = a->frac_hi, a1 = a->frac_lo;
1432
1433 if (c & 64) {
1434 a1 = a0, a0 = 0;
1435 }
1436
1437 c &= 63;
1438 if (c) {
1439 a1 = shr_double(a0, a1, c);
1440 a0 = a0 >> c;
1441 }
1442
1443 a->frac_hi = a0;
1444 a->frac_lo = a1;
1445 }
1446
1447 #define frac_shr(A, C) FRAC_GENERIC_64_128(shr, A)(A, C)
1448
frac64_shrjam(FloatParts64 * a,int c)1449 static void frac64_shrjam(FloatParts64 *a, int c)
1450 {
1451 uint64_t a0 = a->frac;
1452
1453 if (likely(c != 0)) {
1454 if (likely(c < 64)) {
1455 a0 = (a0 >> c) | (shr_double(a0, 0, c) != 0);
1456 } else {
1457 a0 = a0 != 0;
1458 }
1459 a->frac = a0;
1460 }
1461 }
1462
frac128_shrjam(FloatParts128 * a,int c)1463 static void frac128_shrjam(FloatParts128 *a, int c)
1464 {
1465 uint64_t a0 = a->frac_hi, a1 = a->frac_lo;
1466 uint64_t sticky = 0;
1467
1468 if (unlikely(c == 0)) {
1469 return;
1470 } else if (likely(c < 64)) {
1471 /* nothing */
1472 } else if (likely(c < 128)) {
1473 sticky = a1;
1474 a1 = a0;
1475 a0 = 0;
1476 c &= 63;
1477 if (c == 0) {
1478 goto done;
1479 }
1480 } else {
1481 sticky = a0 | a1;
1482 a0 = a1 = 0;
1483 goto done;
1484 }
1485
1486 sticky |= shr_double(a1, 0, c);
1487 a1 = shr_double(a0, a1, c);
1488 a0 = a0 >> c;
1489
1490 done:
1491 a->frac_lo = a1 | (sticky != 0);
1492 a->frac_hi = a0;
1493 }
1494
frac256_shrjam(FloatParts256 * a,int c)1495 static void frac256_shrjam(FloatParts256 *a, int c)
1496 {
1497 uint64_t a0 = a->frac_hi, a1 = a->frac_hm;
1498 uint64_t a2 = a->frac_lm, a3 = a->frac_lo;
1499 uint64_t sticky = 0;
1500
1501 if (unlikely(c == 0)) {
1502 return;
1503 } else if (likely(c < 64)) {
1504 /* nothing */
1505 } else if (likely(c < 256)) {
1506 if (unlikely(c & 128)) {
1507 sticky |= a2 | a3;
1508 a3 = a1, a2 = a0, a1 = 0, a0 = 0;
1509 }
1510 if (unlikely(c & 64)) {
1511 sticky |= a3;
1512 a3 = a2, a2 = a1, a1 = a0, a0 = 0;
1513 }
1514 c &= 63;
1515 if (c == 0) {
1516 goto done;
1517 }
1518 } else {
1519 sticky = a0 | a1 | a2 | a3;
1520 a0 = a1 = a2 = a3 = 0;
1521 goto done;
1522 }
1523
1524 sticky |= shr_double(a3, 0, c);
1525 a3 = shr_double(a2, a3, c);
1526 a2 = shr_double(a1, a2, c);
1527 a1 = shr_double(a0, a1, c);
1528 a0 = a0 >> c;
1529
1530 done:
1531 a->frac_lo = a3 | (sticky != 0);
1532 a->frac_lm = a2;
1533 a->frac_hm = a1;
1534 a->frac_hi = a0;
1535 }
1536
1537 #define frac_shrjam(A, C) FRAC_GENERIC_64_128_256(shrjam, A)(A, C)
1538
frac64_sub(FloatParts64 * r,FloatParts64 * a,FloatParts64 * b)1539 static bool frac64_sub(FloatParts64 *r, FloatParts64 *a, FloatParts64 *b)
1540 {
1541 return usub64_overflow(a->frac, b->frac, &r->frac);
1542 }
1543
frac128_sub(FloatParts128 * r,FloatParts128 * a,FloatParts128 * b)1544 static bool frac128_sub(FloatParts128 *r, FloatParts128 *a, FloatParts128 *b)
1545 {
1546 bool c = 0;
1547 r->frac_lo = usub64_borrow(a->frac_lo, b->frac_lo, &c);
1548 r->frac_hi = usub64_borrow(a->frac_hi, b->frac_hi, &c);
1549 return c;
1550 }
1551
frac256_sub(FloatParts256 * r,FloatParts256 * a,FloatParts256 * b)1552 static bool frac256_sub(FloatParts256 *r, FloatParts256 *a, FloatParts256 *b)
1553 {
1554 bool c = 0;
1555 r->frac_lo = usub64_borrow(a->frac_lo, b->frac_lo, &c);
1556 r->frac_lm = usub64_borrow(a->frac_lm, b->frac_lm, &c);
1557 r->frac_hm = usub64_borrow(a->frac_hm, b->frac_hm, &c);
1558 r->frac_hi = usub64_borrow(a->frac_hi, b->frac_hi, &c);
1559 return c;
1560 }
1561
1562 #define frac_sub(R, A, B) FRAC_GENERIC_64_128_256(sub, R)(R, A, B)
1563
frac64_truncjam(FloatParts64 * r,FloatParts128 * a)1564 static void frac64_truncjam(FloatParts64 *r, FloatParts128 *a)
1565 {
1566 r->frac = a->frac_hi | (a->frac_lo != 0);
1567 }
1568
frac128_truncjam(FloatParts128 * r,FloatParts256 * a)1569 static void frac128_truncjam(FloatParts128 *r, FloatParts256 *a)
1570 {
1571 r->frac_hi = a->frac_hi;
1572 r->frac_lo = a->frac_hm | ((a->frac_lm | a->frac_lo) != 0);
1573 }
1574
1575 #define frac_truncjam(R, A) FRAC_GENERIC_64_128(truncjam, R)(R, A)
1576
frac64_widen(FloatParts128 * r,FloatParts64 * a)1577 static void frac64_widen(FloatParts128 *r, FloatParts64 *a)
1578 {
1579 r->frac_hi = a->frac;
1580 r->frac_lo = 0;
1581 }
1582
frac128_widen(FloatParts256 * r,FloatParts128 * a)1583 static void frac128_widen(FloatParts256 *r, FloatParts128 *a)
1584 {
1585 r->frac_hi = a->frac_hi;
1586 r->frac_hm = a->frac_lo;
1587 r->frac_lm = 0;
1588 r->frac_lo = 0;
1589 }
1590
1591 #define frac_widen(A, B) FRAC_GENERIC_64_128(widen, B)(A, B)
1592
1593 /*
1594 * Reciprocal sqrt table. 1 bit of exponent, 6-bits of mantessa.
1595 * From https://git.musl-libc.org/cgit/musl/tree/src/math/sqrt_data.c
1596 * and thus MIT licenced.
1597 */
1598 static const uint16_t rsqrt_tab[128] = {
1599 0xb451, 0xb2f0, 0xb196, 0xb044, 0xaef9, 0xadb6, 0xac79, 0xab43,
1600 0xaa14, 0xa8eb, 0xa7c8, 0xa6aa, 0xa592, 0xa480, 0xa373, 0xa26b,
1601 0xa168, 0xa06a, 0x9f70, 0x9e7b, 0x9d8a, 0x9c9d, 0x9bb5, 0x9ad1,
1602 0x99f0, 0x9913, 0x983a, 0x9765, 0x9693, 0x95c4, 0x94f8, 0x9430,
1603 0x936b, 0x92a9, 0x91ea, 0x912e, 0x9075, 0x8fbe, 0x8f0a, 0x8e59,
1604 0x8daa, 0x8cfe, 0x8c54, 0x8bac, 0x8b07, 0x8a64, 0x89c4, 0x8925,
1605 0x8889, 0x87ee, 0x8756, 0x86c0, 0x862b, 0x8599, 0x8508, 0x8479,
1606 0x83ec, 0x8361, 0x82d8, 0x8250, 0x81c9, 0x8145, 0x80c2, 0x8040,
1607 0xff02, 0xfd0e, 0xfb25, 0xf947, 0xf773, 0xf5aa, 0xf3ea, 0xf234,
1608 0xf087, 0xeee3, 0xed47, 0xebb3, 0xea27, 0xe8a3, 0xe727, 0xe5b2,
1609 0xe443, 0xe2dc, 0xe17a, 0xe020, 0xdecb, 0xdd7d, 0xdc34, 0xdaf1,
1610 0xd9b3, 0xd87b, 0xd748, 0xd61a, 0xd4f1, 0xd3cd, 0xd2ad, 0xd192,
1611 0xd07b, 0xcf69, 0xce5b, 0xcd51, 0xcc4a, 0xcb48, 0xca4a, 0xc94f,
1612 0xc858, 0xc764, 0xc674, 0xc587, 0xc49d, 0xc3b7, 0xc2d4, 0xc1f4,
1613 0xc116, 0xc03c, 0xbf65, 0xbe90, 0xbdbe, 0xbcef, 0xbc23, 0xbb59,
1614 0xba91, 0xb9cc, 0xb90a, 0xb84a, 0xb78c, 0xb6d0, 0xb617, 0xb560,
1615 };
1616
1617 #define partsN(NAME) glue(glue(glue(parts,N),_),NAME)
1618 #define FloatPartsN glue(FloatParts,N)
1619 #define FloatPartsW glue(FloatParts,W)
1620
1621 #define N 64
1622 #define W 128
1623
1624 #include "softfloat-parts-addsub.c.inc"
1625 #include "softfloat-parts.c.inc"
1626
1627 #undef N
1628 #undef W
1629 #define N 128
1630 #define W 256
1631
1632 #include "softfloat-parts-addsub.c.inc"
1633 #include "softfloat-parts.c.inc"
1634
1635 #undef N
1636 #undef W
1637 #define N 256
1638
1639 #include "softfloat-parts-addsub.c.inc"
1640
1641 #undef N
1642 #undef W
1643 #undef partsN
1644 #undef FloatPartsN
1645 #undef FloatPartsW
1646
1647 /*
1648 * Pack/unpack routines with a specific FloatFmt.
1649 */
1650
float16a_unpack_canonical(FloatParts64 * p,float16 f,float_status * s,const FloatFmt * params)1651 static void float16a_unpack_canonical(FloatParts64 *p, float16 f,
1652 float_status *s, const FloatFmt *params)
1653 {
1654 float16_unpack_raw(p, f);
1655 parts_canonicalize(p, s, params);
1656 }
1657
float16_unpack_canonical(FloatParts64 * p,float16 f,float_status * s)1658 static void float16_unpack_canonical(FloatParts64 *p, float16 f,
1659 float_status *s)
1660 {
1661 float16a_unpack_canonical(p, f, s, &float16_params);
1662 }
1663
bfloat16_unpack_canonical(FloatParts64 * p,bfloat16 f,float_status * s)1664 static void bfloat16_unpack_canonical(FloatParts64 *p, bfloat16 f,
1665 float_status *s)
1666 {
1667 bfloat16_unpack_raw(p, f);
1668 parts_canonicalize(p, s, &bfloat16_params);
1669 }
1670
float16a_round_pack_canonical(FloatParts64 * p,float_status * s,const FloatFmt * params)1671 static float16 float16a_round_pack_canonical(FloatParts64 *p,
1672 float_status *s,
1673 const FloatFmt *params)
1674 {
1675 parts_uncanon(p, s, params);
1676 return float16_pack_raw(p);
1677 }
1678
float16_round_pack_canonical(FloatParts64 * p,float_status * s)1679 static float16 float16_round_pack_canonical(FloatParts64 *p,
1680 float_status *s)
1681 {
1682 return float16a_round_pack_canonical(p, s, &float16_params);
1683 }
1684
bfloat16_round_pack_canonical(FloatParts64 * p,float_status * s)1685 static bfloat16 bfloat16_round_pack_canonical(FloatParts64 *p,
1686 float_status *s)
1687 {
1688 parts_uncanon(p, s, &bfloat16_params);
1689 return bfloat16_pack_raw(p);
1690 }
1691
float32_unpack_canonical(FloatParts64 * p,float32 f,float_status * s)1692 static void float32_unpack_canonical(FloatParts64 *p, float32 f,
1693 float_status *s)
1694 {
1695 float32_unpack_raw(p, f);
1696 parts_canonicalize(p, s, &float32_params);
1697 }
1698
float32_round_pack_canonical(FloatParts64 * p,float_status * s)1699 static float32 float32_round_pack_canonical(FloatParts64 *p,
1700 float_status *s)
1701 {
1702 parts_uncanon(p, s, &float32_params);
1703 return float32_pack_raw(p);
1704 }
1705
float64_unpack_canonical(FloatParts64 * p,float64 f,float_status * s)1706 static void float64_unpack_canonical(FloatParts64 *p, float64 f,
1707 float_status *s)
1708 {
1709 float64_unpack_raw(p, f);
1710 parts_canonicalize(p, s, &float64_params);
1711 }
1712
float64_round_pack_canonical(FloatParts64 * p,float_status * s)1713 static float64 float64_round_pack_canonical(FloatParts64 *p,
1714 float_status *s)
1715 {
1716 parts_uncanon(p, s, &float64_params);
1717 return float64_pack_raw(p);
1718 }
1719
float64r32_round_pack_canonical(FloatParts64 * p,float_status * s)1720 static float64 float64r32_round_pack_canonical(FloatParts64 *p,
1721 float_status *s)
1722 {
1723 parts_uncanon(p, s, &float32_params);
1724
1725 /*
1726 * In parts_uncanon, we placed the fraction for float32 at the lsb.
1727 * We need to adjust the fraction higher so that the least N bits are
1728 * zero, and the fraction is adjacent to the float64 implicit bit.
1729 */
1730 switch (p->cls) {
1731 case float_class_normal:
1732 if (unlikely(p->exp == 0)) {
1733 /*
1734 * The result is denormal for float32, but can be represented
1735 * in normalized form for float64. Adjust, per canonicalize.
1736 */
1737 int shift = frac_normalize(p);
1738 p->exp = (float32_params.frac_shift -
1739 float32_params.exp_bias - shift + 1 +
1740 float64_params.exp_bias);
1741 frac_shr(p, float64_params.frac_shift);
1742 } else {
1743 frac_shl(p, float32_params.frac_shift - float64_params.frac_shift);
1744 p->exp += float64_params.exp_bias - float32_params.exp_bias;
1745 }
1746 break;
1747 case float_class_snan:
1748 case float_class_qnan:
1749 frac_shl(p, float32_params.frac_shift - float64_params.frac_shift);
1750 p->exp = float64_params.exp_max;
1751 break;
1752 case float_class_inf:
1753 p->exp = float64_params.exp_max;
1754 break;
1755 case float_class_zero:
1756 break;
1757 default:
1758 g_assert_not_reached();
1759 }
1760
1761 return float64_pack_raw(p);
1762 }
1763
float128_unpack_canonical(FloatParts128 * p,float128 f,float_status * s)1764 static void float128_unpack_canonical(FloatParts128 *p, float128 f,
1765 float_status *s)
1766 {
1767 float128_unpack_raw(p, f);
1768 parts_canonicalize(p, s, &float128_params);
1769 }
1770
float128_round_pack_canonical(FloatParts128 * p,float_status * s)1771 static float128 float128_round_pack_canonical(FloatParts128 *p,
1772 float_status *s)
1773 {
1774 parts_uncanon(p, s, &float128_params);
1775 return float128_pack_raw(p);
1776 }
1777
1778 /* Returns false if the encoding is invalid. */
floatx80_unpack_canonical(FloatParts128 * p,floatx80 f,float_status * s)1779 static bool floatx80_unpack_canonical(FloatParts128 *p, floatx80 f,
1780 float_status *s)
1781 {
1782 /* Ensure rounding precision is set before beginning. */
1783 switch (s->floatx80_rounding_precision) {
1784 case floatx80_precision_x:
1785 case floatx80_precision_d:
1786 case floatx80_precision_s:
1787 break;
1788 default:
1789 g_assert_not_reached();
1790 }
1791
1792 if (unlikely(floatx80_invalid_encoding(f))) {
1793 float_raise(float_flag_invalid, s);
1794 return false;
1795 }
1796
1797 floatx80_unpack_raw(p, f);
1798
1799 if (likely(p->exp != floatx80_params[floatx80_precision_x].exp_max)) {
1800 parts_canonicalize(p, s, &floatx80_params[floatx80_precision_x]);
1801 } else {
1802 /* The explicit integer bit is ignored, after invalid checks. */
1803 p->frac_hi &= MAKE_64BIT_MASK(0, 63);
1804 p->cls = (p->frac_hi == 0 ? float_class_inf
1805 : parts_is_snan_frac(p->frac_hi, s)
1806 ? float_class_snan : float_class_qnan);
1807 }
1808 return true;
1809 }
1810
floatx80_round_pack_canonical(FloatParts128 * p,float_status * s)1811 static floatx80 floatx80_round_pack_canonical(FloatParts128 *p,
1812 float_status *s)
1813 {
1814 const FloatFmt *fmt = &floatx80_params[s->floatx80_rounding_precision];
1815 uint64_t frac;
1816 int exp;
1817
1818 switch (p->cls) {
1819 case float_class_normal:
1820 if (s->floatx80_rounding_precision == floatx80_precision_x) {
1821 parts_uncanon_normal(p, s, fmt);
1822 frac = p->frac_hi;
1823 exp = p->exp;
1824 } else {
1825 FloatParts64 p64;
1826
1827 p64.sign = p->sign;
1828 p64.exp = p->exp;
1829 frac_truncjam(&p64, p);
1830 parts_uncanon_normal(&p64, s, fmt);
1831 frac = p64.frac;
1832 exp = p64.exp;
1833 }
1834 if (exp != fmt->exp_max) {
1835 break;
1836 }
1837 /* rounded to inf -- fall through to set frac correctly */
1838
1839 case float_class_inf:
1840 /* x86 and m68k differ in the setting of the integer bit. */
1841 frac = floatx80_infinity_low;
1842 exp = fmt->exp_max;
1843 break;
1844
1845 case float_class_zero:
1846 frac = 0;
1847 exp = 0;
1848 break;
1849
1850 case float_class_snan:
1851 case float_class_qnan:
1852 /* NaNs have the integer bit set. */
1853 frac = p->frac_hi | (1ull << 63);
1854 exp = fmt->exp_max;
1855 break;
1856
1857 default:
1858 g_assert_not_reached();
1859 }
1860
1861 return packFloatx80(p->sign, exp, frac);
1862 }
1863
1864 /*
1865 * Addition and subtraction
1866 */
1867
1868 static float16 QEMU_FLATTEN
float16_addsub(float16 a,float16 b,float_status * status,bool subtract)1869 float16_addsub(float16 a, float16 b, float_status *status, bool subtract)
1870 {
1871 FloatParts64 pa, pb, *pr;
1872
1873 float16_unpack_canonical(&pa, a, status);
1874 float16_unpack_canonical(&pb, b, status);
1875 pr = parts_addsub(&pa, &pb, status, subtract);
1876
1877 return float16_round_pack_canonical(pr, status);
1878 }
1879
float16_add(float16 a,float16 b,float_status * status)1880 float16 float16_add(float16 a, float16 b, float_status *status)
1881 {
1882 return float16_addsub(a, b, status, false);
1883 }
1884
float16_sub(float16 a,float16 b,float_status * status)1885 float16 float16_sub(float16 a, float16 b, float_status *status)
1886 {
1887 return float16_addsub(a, b, status, true);
1888 }
1889
1890 static float32 QEMU_SOFTFLOAT_ATTR
soft_f32_addsub(float32 a,float32 b,float_status * status,bool subtract)1891 soft_f32_addsub(float32 a, float32 b, float_status *status, bool subtract)
1892 {
1893 FloatParts64 pa, pb, *pr;
1894
1895 float32_unpack_canonical(&pa, a, status);
1896 float32_unpack_canonical(&pb, b, status);
1897 pr = parts_addsub(&pa, &pb, status, subtract);
1898
1899 return float32_round_pack_canonical(pr, status);
1900 }
1901
soft_f32_add(float32 a,float32 b,float_status * status)1902 static float32 soft_f32_add(float32 a, float32 b, float_status *status)
1903 {
1904 return soft_f32_addsub(a, b, status, false);
1905 }
1906
soft_f32_sub(float32 a,float32 b,float_status * status)1907 static float32 soft_f32_sub(float32 a, float32 b, float_status *status)
1908 {
1909 return soft_f32_addsub(a, b, status, true);
1910 }
1911
1912 static float64 QEMU_SOFTFLOAT_ATTR
soft_f64_addsub(float64 a,float64 b,float_status * status,bool subtract)1913 soft_f64_addsub(float64 a, float64 b, float_status *status, bool subtract)
1914 {
1915 FloatParts64 pa, pb, *pr;
1916
1917 float64_unpack_canonical(&pa, a, status);
1918 float64_unpack_canonical(&pb, b, status);
1919 pr = parts_addsub(&pa, &pb, status, subtract);
1920
1921 return float64_round_pack_canonical(pr, status);
1922 }
1923
soft_f64_add(float64 a,float64 b,float_status * status)1924 static float64 soft_f64_add(float64 a, float64 b, float_status *status)
1925 {
1926 return soft_f64_addsub(a, b, status, false);
1927 }
1928
soft_f64_sub(float64 a,float64 b,float_status * status)1929 static float64 soft_f64_sub(float64 a, float64 b, float_status *status)
1930 {
1931 return soft_f64_addsub(a, b, status, true);
1932 }
1933
hard_f32_add(float a,float b)1934 static float hard_f32_add(float a, float b)
1935 {
1936 return a + b;
1937 }
1938
hard_f32_sub(float a,float b)1939 static float hard_f32_sub(float a, float b)
1940 {
1941 return a - b;
1942 }
1943
hard_f64_add(double a,double b)1944 static double hard_f64_add(double a, double b)
1945 {
1946 return a + b;
1947 }
1948
hard_f64_sub(double a,double b)1949 static double hard_f64_sub(double a, double b)
1950 {
1951 return a - b;
1952 }
1953
f32_addsubmul_post(union_float32 a,union_float32 b)1954 static bool f32_addsubmul_post(union_float32 a, union_float32 b)
1955 {
1956 if (QEMU_HARDFLOAT_2F32_USE_FP) {
1957 return !(fpclassify(a.h) == FP_ZERO && fpclassify(b.h) == FP_ZERO);
1958 }
1959 return !(float32_is_zero(a.s) && float32_is_zero(b.s));
1960 }
1961
f64_addsubmul_post(union_float64 a,union_float64 b)1962 static bool f64_addsubmul_post(union_float64 a, union_float64 b)
1963 {
1964 if (QEMU_HARDFLOAT_2F64_USE_FP) {
1965 return !(fpclassify(a.h) == FP_ZERO && fpclassify(b.h) == FP_ZERO);
1966 } else {
1967 return !(float64_is_zero(a.s) && float64_is_zero(b.s));
1968 }
1969 }
1970
float32_addsub(float32 a,float32 b,float_status * s,hard_f32_op2_fn hard,soft_f32_op2_fn soft)1971 static float32 float32_addsub(float32 a, float32 b, float_status *s,
1972 hard_f32_op2_fn hard, soft_f32_op2_fn soft)
1973 {
1974 return float32_gen2(a, b, s, hard, soft,
1975 f32_is_zon2, f32_addsubmul_post);
1976 }
1977
float64_addsub(float64 a,float64 b,float_status * s,hard_f64_op2_fn hard,soft_f64_op2_fn soft)1978 static float64 float64_addsub(float64 a, float64 b, float_status *s,
1979 hard_f64_op2_fn hard, soft_f64_op2_fn soft)
1980 {
1981 return float64_gen2(a, b, s, hard, soft,
1982 f64_is_zon2, f64_addsubmul_post);
1983 }
1984
1985 float32 QEMU_FLATTEN
float32_add(float32 a,float32 b,float_status * s)1986 float32_add(float32 a, float32 b, float_status *s)
1987 {
1988 return float32_addsub(a, b, s, hard_f32_add, soft_f32_add);
1989 }
1990
1991 float32 QEMU_FLATTEN
float32_sub(float32 a,float32 b,float_status * s)1992 float32_sub(float32 a, float32 b, float_status *s)
1993 {
1994 return float32_addsub(a, b, s, hard_f32_sub, soft_f32_sub);
1995 }
1996
1997 float64 QEMU_FLATTEN
float64_add(float64 a,float64 b,float_status * s)1998 float64_add(float64 a, float64 b, float_status *s)
1999 {
2000 return float64_addsub(a, b, s, hard_f64_add, soft_f64_add);
2001 }
2002
2003 float64 QEMU_FLATTEN
float64_sub(float64 a,float64 b,float_status * s)2004 float64_sub(float64 a, float64 b, float_status *s)
2005 {
2006 return float64_addsub(a, b, s, hard_f64_sub, soft_f64_sub);
2007 }
2008
float64r32_addsub(float64 a,float64 b,float_status * status,bool subtract)2009 static float64 float64r32_addsub(float64 a, float64 b, float_status *status,
2010 bool subtract)
2011 {
2012 FloatParts64 pa, pb, *pr;
2013
2014 float64_unpack_canonical(&pa, a, status);
2015 float64_unpack_canonical(&pb, b, status);
2016 pr = parts_addsub(&pa, &pb, status, subtract);
2017
2018 return float64r32_round_pack_canonical(pr, status);
2019 }
2020
float64r32_add(float64 a,float64 b,float_status * status)2021 float64 float64r32_add(float64 a, float64 b, float_status *status)
2022 {
2023 return float64r32_addsub(a, b, status, false);
2024 }
2025
float64r32_sub(float64 a,float64 b,float_status * status)2026 float64 float64r32_sub(float64 a, float64 b, float_status *status)
2027 {
2028 return float64r32_addsub(a, b, status, true);
2029 }
2030
2031 static bfloat16 QEMU_FLATTEN
bfloat16_addsub(bfloat16 a,bfloat16 b,float_status * status,bool subtract)2032 bfloat16_addsub(bfloat16 a, bfloat16 b, float_status *status, bool subtract)
2033 {
2034 FloatParts64 pa, pb, *pr;
2035
2036 bfloat16_unpack_canonical(&pa, a, status);
2037 bfloat16_unpack_canonical(&pb, b, status);
2038 pr = parts_addsub(&pa, &pb, status, subtract);
2039
2040 return bfloat16_round_pack_canonical(pr, status);
2041 }
2042
bfloat16_add(bfloat16 a,bfloat16 b,float_status * status)2043 bfloat16 bfloat16_add(bfloat16 a, bfloat16 b, float_status *status)
2044 {
2045 return bfloat16_addsub(a, b, status, false);
2046 }
2047
bfloat16_sub(bfloat16 a,bfloat16 b,float_status * status)2048 bfloat16 bfloat16_sub(bfloat16 a, bfloat16 b, float_status *status)
2049 {
2050 return bfloat16_addsub(a, b, status, true);
2051 }
2052
2053 static float128 QEMU_FLATTEN
float128_addsub(float128 a,float128 b,float_status * status,bool subtract)2054 float128_addsub(float128 a, float128 b, float_status *status, bool subtract)
2055 {
2056 FloatParts128 pa, pb, *pr;
2057
2058 float128_unpack_canonical(&pa, a, status);
2059 float128_unpack_canonical(&pb, b, status);
2060 pr = parts_addsub(&pa, &pb, status, subtract);
2061
2062 return float128_round_pack_canonical(pr, status);
2063 }
2064
float128_add(float128 a,float128 b,float_status * status)2065 float128 float128_add(float128 a, float128 b, float_status *status)
2066 {
2067 return float128_addsub(a, b, status, false);
2068 }
2069
float128_sub(float128 a,float128 b,float_status * status)2070 float128 float128_sub(float128 a, float128 b, float_status *status)
2071 {
2072 return float128_addsub(a, b, status, true);
2073 }
2074
2075 static floatx80 QEMU_FLATTEN
floatx80_addsub(floatx80 a,floatx80 b,float_status * status,bool subtract)2076 floatx80_addsub(floatx80 a, floatx80 b, float_status *status, bool subtract)
2077 {
2078 FloatParts128 pa, pb, *pr;
2079
2080 if (!floatx80_unpack_canonical(&pa, a, status) ||
2081 !floatx80_unpack_canonical(&pb, b, status)) {
2082 return floatx80_default_nan(status);
2083 }
2084
2085 pr = parts_addsub(&pa, &pb, status, subtract);
2086 return floatx80_round_pack_canonical(pr, status);
2087 }
2088
floatx80_add(floatx80 a,floatx80 b,float_status * status)2089 floatx80 floatx80_add(floatx80 a, floatx80 b, float_status *status)
2090 {
2091 return floatx80_addsub(a, b, status, false);
2092 }
2093
floatx80_sub(floatx80 a,floatx80 b,float_status * status)2094 floatx80 floatx80_sub(floatx80 a, floatx80 b, float_status *status)
2095 {
2096 return floatx80_addsub(a, b, status, true);
2097 }
2098
2099 /*
2100 * Multiplication
2101 */
2102
float16_mul(float16 a,float16 b,float_status * status)2103 float16 QEMU_FLATTEN float16_mul(float16 a, float16 b, float_status *status)
2104 {
2105 FloatParts64 pa, pb, *pr;
2106
2107 float16_unpack_canonical(&pa, a, status);
2108 float16_unpack_canonical(&pb, b, status);
2109 pr = parts_mul(&pa, &pb, status);
2110
2111 return float16_round_pack_canonical(pr, status);
2112 }
2113
2114 static float32 QEMU_SOFTFLOAT_ATTR
soft_f32_mul(float32 a,float32 b,float_status * status)2115 soft_f32_mul(float32 a, float32 b, float_status *status)
2116 {
2117 FloatParts64 pa, pb, *pr;
2118
2119 float32_unpack_canonical(&pa, a, status);
2120 float32_unpack_canonical(&pb, b, status);
2121 pr = parts_mul(&pa, &pb, status);
2122
2123 return float32_round_pack_canonical(pr, status);
2124 }
2125
2126 static float64 QEMU_SOFTFLOAT_ATTR
soft_f64_mul(float64 a,float64 b,float_status * status)2127 soft_f64_mul(float64 a, float64 b, float_status *status)
2128 {
2129 FloatParts64 pa, pb, *pr;
2130
2131 float64_unpack_canonical(&pa, a, status);
2132 float64_unpack_canonical(&pb, b, status);
2133 pr = parts_mul(&pa, &pb, status);
2134
2135 return float64_round_pack_canonical(pr, status);
2136 }
2137
hard_f32_mul(float a,float b)2138 static float hard_f32_mul(float a, float b)
2139 {
2140 return a * b;
2141 }
2142
hard_f64_mul(double a,double b)2143 static double hard_f64_mul(double a, double b)
2144 {
2145 return a * b;
2146 }
2147
2148 float32 QEMU_FLATTEN
float32_mul(float32 a,float32 b,float_status * s)2149 float32_mul(float32 a, float32 b, float_status *s)
2150 {
2151 return float32_gen2(a, b, s, hard_f32_mul, soft_f32_mul,
2152 f32_is_zon2, f32_addsubmul_post);
2153 }
2154
2155 float64 QEMU_FLATTEN
float64_mul(float64 a,float64 b,float_status * s)2156 float64_mul(float64 a, float64 b, float_status *s)
2157 {
2158 return float64_gen2(a, b, s, hard_f64_mul, soft_f64_mul,
2159 f64_is_zon2, f64_addsubmul_post);
2160 }
2161
float64r32_mul(float64 a,float64 b,float_status * status)2162 float64 float64r32_mul(float64 a, float64 b, float_status *status)
2163 {
2164 FloatParts64 pa, pb, *pr;
2165
2166 float64_unpack_canonical(&pa, a, status);
2167 float64_unpack_canonical(&pb, b, status);
2168 pr = parts_mul(&pa, &pb, status);
2169
2170 return float64r32_round_pack_canonical(pr, status);
2171 }
2172
2173 bfloat16 QEMU_FLATTEN
bfloat16_mul(bfloat16 a,bfloat16 b,float_status * status)2174 bfloat16_mul(bfloat16 a, bfloat16 b, float_status *status)
2175 {
2176 FloatParts64 pa, pb, *pr;
2177
2178 bfloat16_unpack_canonical(&pa, a, status);
2179 bfloat16_unpack_canonical(&pb, b, status);
2180 pr = parts_mul(&pa, &pb, status);
2181
2182 return bfloat16_round_pack_canonical(pr, status);
2183 }
2184
2185 float128 QEMU_FLATTEN
float128_mul(float128 a,float128 b,float_status * status)2186 float128_mul(float128 a, float128 b, float_status *status)
2187 {
2188 FloatParts128 pa, pb, *pr;
2189
2190 float128_unpack_canonical(&pa, a, status);
2191 float128_unpack_canonical(&pb, b, status);
2192 pr = parts_mul(&pa, &pb, status);
2193
2194 return float128_round_pack_canonical(pr, status);
2195 }
2196
2197 floatx80 QEMU_FLATTEN
floatx80_mul(floatx80 a,floatx80 b,float_status * status)2198 floatx80_mul(floatx80 a, floatx80 b, float_status *status)
2199 {
2200 FloatParts128 pa, pb, *pr;
2201
2202 if (!floatx80_unpack_canonical(&pa, a, status) ||
2203 !floatx80_unpack_canonical(&pb, b, status)) {
2204 return floatx80_default_nan(status);
2205 }
2206
2207 pr = parts_mul(&pa, &pb, status);
2208 return floatx80_round_pack_canonical(pr, status);
2209 }
2210
2211 /*
2212 * Fused multiply-add
2213 */
2214
float16_muladd(float16 a,float16 b,float16 c,int flags,float_status * status)2215 float16 QEMU_FLATTEN float16_muladd(float16 a, float16 b, float16 c,
2216 int flags, float_status *status)
2217 {
2218 FloatParts64 pa, pb, pc, *pr;
2219
2220 float16_unpack_canonical(&pa, a, status);
2221 float16_unpack_canonical(&pb, b, status);
2222 float16_unpack_canonical(&pc, c, status);
2223 pr = parts_muladd(&pa, &pb, &pc, flags, status);
2224
2225 return float16_round_pack_canonical(pr, status);
2226 }
2227
2228 static float32 QEMU_SOFTFLOAT_ATTR
soft_f32_muladd(float32 a,float32 b,float32 c,int flags,float_status * status)2229 soft_f32_muladd(float32 a, float32 b, float32 c, int flags,
2230 float_status *status)
2231 {
2232 FloatParts64 pa, pb, pc, *pr;
2233
2234 float32_unpack_canonical(&pa, a, status);
2235 float32_unpack_canonical(&pb, b, status);
2236 float32_unpack_canonical(&pc, c, status);
2237 pr = parts_muladd(&pa, &pb, &pc, flags, status);
2238
2239 return float32_round_pack_canonical(pr, status);
2240 }
2241
2242 static float64 QEMU_SOFTFLOAT_ATTR
soft_f64_muladd(float64 a,float64 b,float64 c,int flags,float_status * status)2243 soft_f64_muladd(float64 a, float64 b, float64 c, int flags,
2244 float_status *status)
2245 {
2246 FloatParts64 pa, pb, pc, *pr;
2247
2248 float64_unpack_canonical(&pa, a, status);
2249 float64_unpack_canonical(&pb, b, status);
2250 float64_unpack_canonical(&pc, c, status);
2251 pr = parts_muladd(&pa, &pb, &pc, flags, status);
2252
2253 return float64_round_pack_canonical(pr, status);
2254 }
2255
2256 static bool force_soft_fma;
2257
2258 float32 QEMU_FLATTEN
float32_muladd(float32 xa,float32 xb,float32 xc,int flags,float_status * s)2259 float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
2260 {
2261 union_float32 ua, ub, uc, ur;
2262
2263 ua.s = xa;
2264 ub.s = xb;
2265 uc.s = xc;
2266
2267 if (unlikely(!can_use_fpu(s))) {
2268 goto soft;
2269 }
2270 if (unlikely(flags & float_muladd_halve_result)) {
2271 goto soft;
2272 }
2273
2274 float32_input_flush3(&ua.s, &ub.s, &uc.s, s);
2275 if (unlikely(!f32_is_zon3(ua, ub, uc))) {
2276 goto soft;
2277 }
2278
2279 if (unlikely(force_soft_fma)) {
2280 goto soft;
2281 }
2282
2283 /*
2284 * When (a || b) == 0, there's no need to check for under/over flow,
2285 * since we know the addend is (normal || 0) and the product is 0.
2286 */
2287 if (float32_is_zero(ua.s) || float32_is_zero(ub.s)) {
2288 union_float32 up;
2289 bool prod_sign;
2290
2291 prod_sign = float32_is_neg(ua.s) ^ float32_is_neg(ub.s);
2292 prod_sign ^= !!(flags & float_muladd_negate_product);
2293 up.s = float32_set_sign(float32_zero, prod_sign);
2294
2295 if (flags & float_muladd_negate_c) {
2296 uc.h = -uc.h;
2297 }
2298 ur.h = up.h + uc.h;
2299 } else {
2300 union_float32 ua_orig = ua;
2301 union_float32 uc_orig = uc;
2302
2303 if (flags & float_muladd_negate_product) {
2304 ua.h = -ua.h;
2305 }
2306 if (flags & float_muladd_negate_c) {
2307 uc.h = -uc.h;
2308 }
2309
2310 ur.h = fmaf(ua.h, ub.h, uc.h);
2311
2312 if (unlikely(f32_is_inf(ur))) {
2313 float_raise(float_flag_overflow, s);
2314 } else if (unlikely(fabsf(ur.h) <= FLT_MIN)) {
2315 ua = ua_orig;
2316 uc = uc_orig;
2317 goto soft;
2318 }
2319 }
2320 if (flags & float_muladd_negate_result) {
2321 return float32_chs(ur.s);
2322 }
2323 return ur.s;
2324
2325 soft:
2326 return soft_f32_muladd(ua.s, ub.s, uc.s, flags, s);
2327 }
2328
2329 float64 QEMU_FLATTEN
float64_muladd(float64 xa,float64 xb,float64 xc,int flags,float_status * s)2330 float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s)
2331 {
2332 union_float64 ua, ub, uc, ur;
2333
2334 ua.s = xa;
2335 ub.s = xb;
2336 uc.s = xc;
2337
2338 if (unlikely(!can_use_fpu(s))) {
2339 goto soft;
2340 }
2341 if (unlikely(flags & float_muladd_halve_result)) {
2342 goto soft;
2343 }
2344
2345 float64_input_flush3(&ua.s, &ub.s, &uc.s, s);
2346 if (unlikely(!f64_is_zon3(ua, ub, uc))) {
2347 goto soft;
2348 }
2349
2350 if (unlikely(force_soft_fma)) {
2351 goto soft;
2352 }
2353
2354 /*
2355 * When (a || b) == 0, there's no need to check for under/over flow,
2356 * since we know the addend is (normal || 0) and the product is 0.
2357 */
2358 if (float64_is_zero(ua.s) || float64_is_zero(ub.s)) {
2359 union_float64 up;
2360 bool prod_sign;
2361
2362 prod_sign = float64_is_neg(ua.s) ^ float64_is_neg(ub.s);
2363 prod_sign ^= !!(flags & float_muladd_negate_product);
2364 up.s = float64_set_sign(float64_zero, prod_sign);
2365
2366 if (flags & float_muladd_negate_c) {
2367 uc.h = -uc.h;
2368 }
2369 ur.h = up.h + uc.h;
2370 } else {
2371 union_float64 ua_orig = ua;
2372 union_float64 uc_orig = uc;
2373
2374 if (flags & float_muladd_negate_product) {
2375 ua.h = -ua.h;
2376 }
2377 if (flags & float_muladd_negate_c) {
2378 uc.h = -uc.h;
2379 }
2380
2381 ur.h = fma(ua.h, ub.h, uc.h);
2382
2383 if (unlikely(f64_is_inf(ur))) {
2384 float_raise(float_flag_overflow, s);
2385 } else if (unlikely(fabs(ur.h) <= FLT_MIN)) {
2386 ua = ua_orig;
2387 uc = uc_orig;
2388 goto soft;
2389 }
2390 }
2391 if (flags & float_muladd_negate_result) {
2392 return float64_chs(ur.s);
2393 }
2394 return ur.s;
2395
2396 soft:
2397 return soft_f64_muladd(ua.s, ub.s, uc.s, flags, s);
2398 }
2399
float64r32_muladd(float64 a,float64 b,float64 c,int flags,float_status * status)2400 float64 float64r32_muladd(float64 a, float64 b, float64 c,
2401 int flags, float_status *status)
2402 {
2403 FloatParts64 pa, pb, pc, *pr;
2404
2405 float64_unpack_canonical(&pa, a, status);
2406 float64_unpack_canonical(&pb, b, status);
2407 float64_unpack_canonical(&pc, c, status);
2408 pr = parts_muladd(&pa, &pb, &pc, flags, status);
2409
2410 return float64r32_round_pack_canonical(pr, status);
2411 }
2412
bfloat16_muladd(bfloat16 a,bfloat16 b,bfloat16 c,int flags,float_status * status)2413 bfloat16 QEMU_FLATTEN bfloat16_muladd(bfloat16 a, bfloat16 b, bfloat16 c,
2414 int flags, float_status *status)
2415 {
2416 FloatParts64 pa, pb, pc, *pr;
2417
2418 bfloat16_unpack_canonical(&pa, a, status);
2419 bfloat16_unpack_canonical(&pb, b, status);
2420 bfloat16_unpack_canonical(&pc, c, status);
2421 pr = parts_muladd(&pa, &pb, &pc, flags, status);
2422
2423 return bfloat16_round_pack_canonical(pr, status);
2424 }
2425
float128_muladd(float128 a,float128 b,float128 c,int flags,float_status * status)2426 float128 QEMU_FLATTEN float128_muladd(float128 a, float128 b, float128 c,
2427 int flags, float_status *status)
2428 {
2429 FloatParts128 pa, pb, pc, *pr;
2430
2431 float128_unpack_canonical(&pa, a, status);
2432 float128_unpack_canonical(&pb, b, status);
2433 float128_unpack_canonical(&pc, c, status);
2434 pr = parts_muladd(&pa, &pb, &pc, flags, status);
2435
2436 return float128_round_pack_canonical(pr, status);
2437 }
2438
2439 /*
2440 * Division
2441 */
2442
float16_div(float16 a,float16 b,float_status * status)2443 float16 float16_div(float16 a, float16 b, float_status *status)
2444 {
2445 FloatParts64 pa, pb, *pr;
2446
2447 float16_unpack_canonical(&pa, a, status);
2448 float16_unpack_canonical(&pb, b, status);
2449 pr = parts_div(&pa, &pb, status);
2450
2451 return float16_round_pack_canonical(pr, status);
2452 }
2453
2454 static float32 QEMU_SOFTFLOAT_ATTR
soft_f32_div(float32 a,float32 b,float_status * status)2455 soft_f32_div(float32 a, float32 b, float_status *status)
2456 {
2457 FloatParts64 pa, pb, *pr;
2458
2459 float32_unpack_canonical(&pa, a, status);
2460 float32_unpack_canonical(&pb, b, status);
2461 pr = parts_div(&pa, &pb, status);
2462
2463 return float32_round_pack_canonical(pr, status);
2464 }
2465
2466 static float64 QEMU_SOFTFLOAT_ATTR
soft_f64_div(float64 a,float64 b,float_status * status)2467 soft_f64_div(float64 a, float64 b, float_status *status)
2468 {
2469 FloatParts64 pa, pb, *pr;
2470
2471 float64_unpack_canonical(&pa, a, status);
2472 float64_unpack_canonical(&pb, b, status);
2473 pr = parts_div(&pa, &pb, status);
2474
2475 return float64_round_pack_canonical(pr, status);
2476 }
2477
hard_f32_div(float a,float b)2478 static float hard_f32_div(float a, float b)
2479 {
2480 return a / b;
2481 }
2482
hard_f64_div(double a,double b)2483 static double hard_f64_div(double a, double b)
2484 {
2485 return a / b;
2486 }
2487
f32_div_pre(union_float32 a,union_float32 b)2488 static bool f32_div_pre(union_float32 a, union_float32 b)
2489 {
2490 if (QEMU_HARDFLOAT_2F32_USE_FP) {
2491 return (fpclassify(a.h) == FP_NORMAL || fpclassify(a.h) == FP_ZERO) &&
2492 fpclassify(b.h) == FP_NORMAL;
2493 }
2494 return float32_is_zero_or_normal(a.s) && float32_is_normal(b.s);
2495 }
2496
f64_div_pre(union_float64 a,union_float64 b)2497 static bool f64_div_pre(union_float64 a, union_float64 b)
2498 {
2499 if (QEMU_HARDFLOAT_2F64_USE_FP) {
2500 return (fpclassify(a.h) == FP_NORMAL || fpclassify(a.h) == FP_ZERO) &&
2501 fpclassify(b.h) == FP_NORMAL;
2502 }
2503 return float64_is_zero_or_normal(a.s) && float64_is_normal(b.s);
2504 }
2505
f32_div_post(union_float32 a,union_float32 b)2506 static bool f32_div_post(union_float32 a, union_float32 b)
2507 {
2508 if (QEMU_HARDFLOAT_2F32_USE_FP) {
2509 return fpclassify(a.h) != FP_ZERO;
2510 }
2511 return !float32_is_zero(a.s);
2512 }
2513
f64_div_post(union_float64 a,union_float64 b)2514 static bool f64_div_post(union_float64 a, union_float64 b)
2515 {
2516 if (QEMU_HARDFLOAT_2F64_USE_FP) {
2517 return fpclassify(a.h) != FP_ZERO;
2518 }
2519 return !float64_is_zero(a.s);
2520 }
2521
2522 float32 QEMU_FLATTEN
float32_div(float32 a,float32 b,float_status * s)2523 float32_div(float32 a, float32 b, float_status *s)
2524 {
2525 return float32_gen2(a, b, s, hard_f32_div, soft_f32_div,
2526 f32_div_pre, f32_div_post);
2527 }
2528
2529 float64 QEMU_FLATTEN
float64_div(float64 a,float64 b,float_status * s)2530 float64_div(float64 a, float64 b, float_status *s)
2531 {
2532 return float64_gen2(a, b, s, hard_f64_div, soft_f64_div,
2533 f64_div_pre, f64_div_post);
2534 }
2535
float64r32_div(float64 a,float64 b,float_status * status)2536 float64 float64r32_div(float64 a, float64 b, float_status *status)
2537 {
2538 FloatParts64 pa, pb, *pr;
2539
2540 float64_unpack_canonical(&pa, a, status);
2541 float64_unpack_canonical(&pb, b, status);
2542 pr = parts_div(&pa, &pb, status);
2543
2544 return float64r32_round_pack_canonical(pr, status);
2545 }
2546
2547 bfloat16 QEMU_FLATTEN
bfloat16_div(bfloat16 a,bfloat16 b,float_status * status)2548 bfloat16_div(bfloat16 a, bfloat16 b, float_status *status)
2549 {
2550 FloatParts64 pa, pb, *pr;
2551
2552 bfloat16_unpack_canonical(&pa, a, status);
2553 bfloat16_unpack_canonical(&pb, b, status);
2554 pr = parts_div(&pa, &pb, status);
2555
2556 return bfloat16_round_pack_canonical(pr, status);
2557 }
2558
2559 float128 QEMU_FLATTEN
float128_div(float128 a,float128 b,float_status * status)2560 float128_div(float128 a, float128 b, float_status *status)
2561 {
2562 FloatParts128 pa, pb, *pr;
2563
2564 float128_unpack_canonical(&pa, a, status);
2565 float128_unpack_canonical(&pb, b, status);
2566 pr = parts_div(&pa, &pb, status);
2567
2568 return float128_round_pack_canonical(pr, status);
2569 }
2570
floatx80_div(floatx80 a,floatx80 b,float_status * status)2571 floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status)
2572 {
2573 FloatParts128 pa, pb, *pr;
2574
2575 if (!floatx80_unpack_canonical(&pa, a, status) ||
2576 !floatx80_unpack_canonical(&pb, b, status)) {
2577 return floatx80_default_nan(status);
2578 }
2579
2580 pr = parts_div(&pa, &pb, status);
2581 return floatx80_round_pack_canonical(pr, status);
2582 }
2583
2584 /*
2585 * Remainder
2586 */
2587
float32_rem(float32 a,float32 b,float_status * status)2588 float32 float32_rem(float32 a, float32 b, float_status *status)
2589 {
2590 FloatParts64 pa, pb, *pr;
2591
2592 float32_unpack_canonical(&pa, a, status);
2593 float32_unpack_canonical(&pb, b, status);
2594 pr = parts_modrem(&pa, &pb, NULL, status);
2595
2596 return float32_round_pack_canonical(pr, status);
2597 }
2598
float64_rem(float64 a,float64 b,float_status * status)2599 float64 float64_rem(float64 a, float64 b, float_status *status)
2600 {
2601 FloatParts64 pa, pb, *pr;
2602
2603 float64_unpack_canonical(&pa, a, status);
2604 float64_unpack_canonical(&pb, b, status);
2605 pr = parts_modrem(&pa, &pb, NULL, status);
2606
2607 return float64_round_pack_canonical(pr, status);
2608 }
2609
float128_rem(float128 a,float128 b,float_status * status)2610 float128 float128_rem(float128 a, float128 b, float_status *status)
2611 {
2612 FloatParts128 pa, pb, *pr;
2613
2614 float128_unpack_canonical(&pa, a, status);
2615 float128_unpack_canonical(&pb, b, status);
2616 pr = parts_modrem(&pa, &pb, NULL, status);
2617
2618 return float128_round_pack_canonical(pr, status);
2619 }
2620
2621 /*
2622 * Returns the remainder of the extended double-precision floating-point value
2623 * `a' with respect to the corresponding value `b'.
2624 * If 'mod' is false, the operation is performed according to the IEC/IEEE
2625 * Standard for Binary Floating-Point Arithmetic. If 'mod' is true, return
2626 * the remainder based on truncating the quotient toward zero instead and
2627 * *quotient is set to the low 64 bits of the absolute value of the integer
2628 * quotient.
2629 */
floatx80_modrem(floatx80 a,floatx80 b,bool mod,uint64_t * quotient,float_status * status)2630 floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod,
2631 uint64_t *quotient, float_status *status)
2632 {
2633 FloatParts128 pa, pb, *pr;
2634
2635 *quotient = 0;
2636 if (!floatx80_unpack_canonical(&pa, a, status) ||
2637 !floatx80_unpack_canonical(&pb, b, status)) {
2638 return floatx80_default_nan(status);
2639 }
2640 pr = parts_modrem(&pa, &pb, mod ? quotient : NULL, status);
2641
2642 return floatx80_round_pack_canonical(pr, status);
2643 }
2644
floatx80_rem(floatx80 a,floatx80 b,float_status * status)2645 floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
2646 {
2647 uint64_t quotient;
2648 return floatx80_modrem(a, b, false, "ient, status);
2649 }
2650
floatx80_mod(floatx80 a,floatx80 b,float_status * status)2651 floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
2652 {
2653 uint64_t quotient;
2654 return floatx80_modrem(a, b, true, "ient, status);
2655 }
2656
2657 /*
2658 * Float to Float conversions
2659 *
2660 * Returns the result of converting one float format to another. The
2661 * conversion is performed according to the IEC/IEEE Standard for
2662 * Binary Floating-Point Arithmetic.
2663 *
2664 * Usually this only needs to take care of raising invalid exceptions
2665 * and handling the conversion on NaNs.
2666 */
2667
parts_float_to_ahp(FloatParts64 * a,float_status * s)2668 static void parts_float_to_ahp(FloatParts64 *a, float_status *s)
2669 {
2670 switch (a->cls) {
2671 case float_class_snan:
2672 float_raise(float_flag_invalid_snan, s);
2673 /* fall through */
2674 case float_class_qnan:
2675 /*
2676 * There is no NaN in the destination format. Raise Invalid
2677 * and return a zero with the sign of the input NaN.
2678 */
2679 float_raise(float_flag_invalid, s);
2680 a->cls = float_class_zero;
2681 break;
2682
2683 case float_class_inf:
2684 /*
2685 * There is no Inf in the destination format. Raise Invalid
2686 * and return the maximum normal with the correct sign.
2687 */
2688 float_raise(float_flag_invalid, s);
2689 a->cls = float_class_normal;
2690 a->exp = float16_params_ahp.exp_max;
2691 a->frac = MAKE_64BIT_MASK(float16_params_ahp.frac_shift,
2692 float16_params_ahp.frac_size + 1);
2693 break;
2694
2695 case float_class_normal:
2696 case float_class_zero:
2697 break;
2698
2699 default:
2700 g_assert_not_reached();
2701 }
2702 }
2703
parts64_float_to_float(FloatParts64 * a,float_status * s)2704 static void parts64_float_to_float(FloatParts64 *a, float_status *s)
2705 {
2706 if (is_nan(a->cls)) {
2707 parts_return_nan(a, s);
2708 }
2709 }
2710
parts128_float_to_float(FloatParts128 * a,float_status * s)2711 static void parts128_float_to_float(FloatParts128 *a, float_status *s)
2712 {
2713 if (is_nan(a->cls)) {
2714 parts_return_nan(a, s);
2715 }
2716 }
2717
2718 #define parts_float_to_float(P, S) \
2719 PARTS_GENERIC_64_128(float_to_float, P)(P, S)
2720
parts_float_to_float_narrow(FloatParts64 * a,FloatParts128 * b,float_status * s)2721 static void parts_float_to_float_narrow(FloatParts64 *a, FloatParts128 *b,
2722 float_status *s)
2723 {
2724 a->cls = b->cls;
2725 a->sign = b->sign;
2726 a->exp = b->exp;
2727
2728 if (a->cls == float_class_normal) {
2729 frac_truncjam(a, b);
2730 } else if (is_nan(a->cls)) {
2731 /* Discard the low bits of the NaN. */
2732 a->frac = b->frac_hi;
2733 parts_return_nan(a, s);
2734 }
2735 }
2736
parts_float_to_float_widen(FloatParts128 * a,FloatParts64 * b,float_status * s)2737 static void parts_float_to_float_widen(FloatParts128 *a, FloatParts64 *b,
2738 float_status *s)
2739 {
2740 a->cls = b->cls;
2741 a->sign = b->sign;
2742 a->exp = b->exp;
2743 frac_widen(a, b);
2744
2745 if (is_nan(a->cls)) {
2746 parts_return_nan(a, s);
2747 }
2748 }
2749
float16_to_float32(float16 a,bool ieee,float_status * s)2750 float32 float16_to_float32(float16 a, bool ieee, float_status *s)
2751 {
2752 const FloatFmt *fmt16 = ieee ? &float16_params : &float16_params_ahp;
2753 FloatParts64 p;
2754
2755 float16a_unpack_canonical(&p, a, s, fmt16);
2756 parts_float_to_float(&p, s);
2757 return float32_round_pack_canonical(&p, s);
2758 }
2759
float16_to_float64(float16 a,bool ieee,float_status * s)2760 float64 float16_to_float64(float16 a, bool ieee, float_status *s)
2761 {
2762 const FloatFmt *fmt16 = ieee ? &float16_params : &float16_params_ahp;
2763 FloatParts64 p;
2764
2765 float16a_unpack_canonical(&p, a, s, fmt16);
2766 parts_float_to_float(&p, s);
2767 return float64_round_pack_canonical(&p, s);
2768 }
2769
float32_to_float16(float32 a,bool ieee,float_status * s)2770 float16 float32_to_float16(float32 a, bool ieee, float_status *s)
2771 {
2772 FloatParts64 p;
2773 const FloatFmt *fmt;
2774
2775 float32_unpack_canonical(&p, a, s);
2776 if (ieee) {
2777 parts_float_to_float(&p, s);
2778 fmt = &float16_params;
2779 } else {
2780 parts_float_to_ahp(&p, s);
2781 fmt = &float16_params_ahp;
2782 }
2783 return float16a_round_pack_canonical(&p, s, fmt);
2784 }
2785
2786 static float64 QEMU_SOFTFLOAT_ATTR
soft_float32_to_float64(float32 a,float_status * s)2787 soft_float32_to_float64(float32 a, float_status *s)
2788 {
2789 FloatParts64 p;
2790
2791 float32_unpack_canonical(&p, a, s);
2792 parts_float_to_float(&p, s);
2793 return float64_round_pack_canonical(&p, s);
2794 }
2795
float32_to_float64(float32 a,float_status * s)2796 float64 float32_to_float64(float32 a, float_status *s)
2797 {
2798 if (likely(float32_is_normal(a))) {
2799 /* Widening conversion can never produce inexact results. */
2800 union_float32 uf;
2801 union_float64 ud;
2802 uf.s = a;
2803 ud.h = uf.h;
2804 return ud.s;
2805 } else if (float32_is_zero(a)) {
2806 return float64_set_sign(float64_zero, float32_is_neg(a));
2807 } else {
2808 return soft_float32_to_float64(a, s);
2809 }
2810 }
2811
float64_to_float16(float64 a,bool ieee,float_status * s)2812 float16 float64_to_float16(float64 a, bool ieee, float_status *s)
2813 {
2814 FloatParts64 p;
2815 const FloatFmt *fmt;
2816
2817 float64_unpack_canonical(&p, a, s);
2818 if (ieee) {
2819 parts_float_to_float(&p, s);
2820 fmt = &float16_params;
2821 } else {
2822 parts_float_to_ahp(&p, s);
2823 fmt = &float16_params_ahp;
2824 }
2825 return float16a_round_pack_canonical(&p, s, fmt);
2826 }
2827
float64_to_float32(float64 a,float_status * s)2828 float32 float64_to_float32(float64 a, float_status *s)
2829 {
2830 FloatParts64 p;
2831
2832 float64_unpack_canonical(&p, a, s);
2833 parts_float_to_float(&p, s);
2834 return float32_round_pack_canonical(&p, s);
2835 }
2836
bfloat16_to_float32(bfloat16 a,float_status * s)2837 float32 bfloat16_to_float32(bfloat16 a, float_status *s)
2838 {
2839 FloatParts64 p;
2840
2841 bfloat16_unpack_canonical(&p, a, s);
2842 parts_float_to_float(&p, s);
2843 return float32_round_pack_canonical(&p, s);
2844 }
2845
bfloat16_to_float64(bfloat16 a,float_status * s)2846 float64 bfloat16_to_float64(bfloat16 a, float_status *s)
2847 {
2848 FloatParts64 p;
2849
2850 bfloat16_unpack_canonical(&p, a, s);
2851 parts_float_to_float(&p, s);
2852 return float64_round_pack_canonical(&p, s);
2853 }
2854
float32_to_bfloat16(float32 a,float_status * s)2855 bfloat16 float32_to_bfloat16(float32 a, float_status *s)
2856 {
2857 FloatParts64 p;
2858
2859 float32_unpack_canonical(&p, a, s);
2860 parts_float_to_float(&p, s);
2861 return bfloat16_round_pack_canonical(&p, s);
2862 }
2863
float64_to_bfloat16(float64 a,float_status * s)2864 bfloat16 float64_to_bfloat16(float64 a, float_status *s)
2865 {
2866 FloatParts64 p;
2867
2868 float64_unpack_canonical(&p, a, s);
2869 parts_float_to_float(&p, s);
2870 return bfloat16_round_pack_canonical(&p, s);
2871 }
2872
float128_to_float32(float128 a,float_status * s)2873 float32 float128_to_float32(float128 a, float_status *s)
2874 {
2875 FloatParts64 p64;
2876 FloatParts128 p128;
2877
2878 float128_unpack_canonical(&p128, a, s);
2879 parts_float_to_float_narrow(&p64, &p128, s);
2880 return float32_round_pack_canonical(&p64, s);
2881 }
2882
float128_to_float64(float128 a,float_status * s)2883 float64 float128_to_float64(float128 a, float_status *s)
2884 {
2885 FloatParts64 p64;
2886 FloatParts128 p128;
2887
2888 float128_unpack_canonical(&p128, a, s);
2889 parts_float_to_float_narrow(&p64, &p128, s);
2890 return float64_round_pack_canonical(&p64, s);
2891 }
2892
float32_to_float128(float32 a,float_status * s)2893 float128 float32_to_float128(float32 a, float_status *s)
2894 {
2895 FloatParts64 p64;
2896 FloatParts128 p128;
2897
2898 float32_unpack_canonical(&p64, a, s);
2899 parts_float_to_float_widen(&p128, &p64, s);
2900 return float128_round_pack_canonical(&p128, s);
2901 }
2902
float64_to_float128(float64 a,float_status * s)2903 float128 float64_to_float128(float64 a, float_status *s)
2904 {
2905 FloatParts64 p64;
2906 FloatParts128 p128;
2907
2908 float64_unpack_canonical(&p64, a, s);
2909 parts_float_to_float_widen(&p128, &p64, s);
2910 return float128_round_pack_canonical(&p128, s);
2911 }
2912
floatx80_to_float32(floatx80 a,float_status * s)2913 float32 floatx80_to_float32(floatx80 a, float_status *s)
2914 {
2915 FloatParts64 p64;
2916 FloatParts128 p128;
2917
2918 if (floatx80_unpack_canonical(&p128, a, s)) {
2919 parts_float_to_float_narrow(&p64, &p128, s);
2920 } else {
2921 parts_default_nan(&p64, s);
2922 }
2923 return float32_round_pack_canonical(&p64, s);
2924 }
2925
floatx80_to_float64(floatx80 a,float_status * s)2926 float64 floatx80_to_float64(floatx80 a, float_status *s)
2927 {
2928 FloatParts64 p64;
2929 FloatParts128 p128;
2930
2931 if (floatx80_unpack_canonical(&p128, a, s)) {
2932 parts_float_to_float_narrow(&p64, &p128, s);
2933 } else {
2934 parts_default_nan(&p64, s);
2935 }
2936 return float64_round_pack_canonical(&p64, s);
2937 }
2938
floatx80_to_float128(floatx80 a,float_status * s)2939 float128 floatx80_to_float128(floatx80 a, float_status *s)
2940 {
2941 FloatParts128 p;
2942
2943 if (floatx80_unpack_canonical(&p, a, s)) {
2944 parts_float_to_float(&p, s);
2945 } else {
2946 parts_default_nan(&p, s);
2947 }
2948 return float128_round_pack_canonical(&p, s);
2949 }
2950
float32_to_floatx80(float32 a,float_status * s)2951 floatx80 float32_to_floatx80(float32 a, float_status *s)
2952 {
2953 FloatParts64 p64;
2954 FloatParts128 p128;
2955
2956 float32_unpack_canonical(&p64, a, s);
2957 parts_float_to_float_widen(&p128, &p64, s);
2958 return floatx80_round_pack_canonical(&p128, s);
2959 }
2960
float64_to_floatx80(float64 a,float_status * s)2961 floatx80 float64_to_floatx80(float64 a, float_status *s)
2962 {
2963 FloatParts64 p64;
2964 FloatParts128 p128;
2965
2966 float64_unpack_canonical(&p64, a, s);
2967 parts_float_to_float_widen(&p128, &p64, s);
2968 return floatx80_round_pack_canonical(&p128, s);
2969 }
2970
float128_to_floatx80(float128 a,float_status * s)2971 floatx80 float128_to_floatx80(float128 a, float_status *s)
2972 {
2973 FloatParts128 p;
2974
2975 float128_unpack_canonical(&p, a, s);
2976 parts_float_to_float(&p, s);
2977 return floatx80_round_pack_canonical(&p, s);
2978 }
2979
2980 /*
2981 * Round to integral value
2982 */
2983
float16_round_to_int(float16 a,float_status * s)2984 float16 float16_round_to_int(float16 a, float_status *s)
2985 {
2986 FloatParts64 p;
2987
2988 float16_unpack_canonical(&p, a, s);
2989 parts_round_to_int(&p, s->float_rounding_mode, 0, s, &float16_params);
2990 return float16_round_pack_canonical(&p, s);
2991 }
2992
float32_round_to_int(float32 a,float_status * s)2993 float32 float32_round_to_int(float32 a, float_status *s)
2994 {
2995 FloatParts64 p;
2996
2997 float32_unpack_canonical(&p, a, s);
2998 parts_round_to_int(&p, s->float_rounding_mode, 0, s, &float32_params);
2999 return float32_round_pack_canonical(&p, s);
3000 }
3001
float64_round_to_int(float64 a,float_status * s)3002 float64 float64_round_to_int(float64 a, float_status *s)
3003 {
3004 FloatParts64 p;
3005
3006 float64_unpack_canonical(&p, a, s);
3007 parts_round_to_int(&p, s->float_rounding_mode, 0, s, &float64_params);
3008 return float64_round_pack_canonical(&p, s);
3009 }
3010
bfloat16_round_to_int(bfloat16 a,float_status * s)3011 bfloat16 bfloat16_round_to_int(bfloat16 a, float_status *s)
3012 {
3013 FloatParts64 p;
3014
3015 bfloat16_unpack_canonical(&p, a, s);
3016 parts_round_to_int(&p, s->float_rounding_mode, 0, s, &bfloat16_params);
3017 return bfloat16_round_pack_canonical(&p, s);
3018 }
3019
float128_round_to_int(float128 a,float_status * s)3020 float128 float128_round_to_int(float128 a, float_status *s)
3021 {
3022 FloatParts128 p;
3023
3024 float128_unpack_canonical(&p, a, s);
3025 parts_round_to_int(&p, s->float_rounding_mode, 0, s, &float128_params);
3026 return float128_round_pack_canonical(&p, s);
3027 }
3028
floatx80_round_to_int(floatx80 a,float_status * status)3029 floatx80 floatx80_round_to_int(floatx80 a, float_status *status)
3030 {
3031 FloatParts128 p;
3032
3033 if (!floatx80_unpack_canonical(&p, a, status)) {
3034 return floatx80_default_nan(status);
3035 }
3036
3037 parts_round_to_int(&p, status->float_rounding_mode, 0, status,
3038 &floatx80_params[status->floatx80_rounding_precision]);
3039 return floatx80_round_pack_canonical(&p, status);
3040 }
3041
3042 /*
3043 * Floating-point to signed integer conversions
3044 */
3045
float16_to_int8_scalbn(float16 a,FloatRoundMode rmode,int scale,float_status * s)3046 int8_t float16_to_int8_scalbn(float16 a, FloatRoundMode rmode, int scale,
3047 float_status *s)
3048 {
3049 FloatParts64 p;
3050
3051 float16_unpack_canonical(&p, a, s);
3052 return parts_float_to_sint(&p, rmode, scale, INT8_MIN, INT8_MAX, s);
3053 }
3054
float16_to_int16_scalbn(float16 a,FloatRoundMode rmode,int scale,float_status * s)3055 int16_t float16_to_int16_scalbn(float16 a, FloatRoundMode rmode, int scale,
3056 float_status *s)
3057 {
3058 FloatParts64 p;
3059
3060 float16_unpack_canonical(&p, a, s);
3061 return parts_float_to_sint(&p, rmode, scale, INT16_MIN, INT16_MAX, s);
3062 }
3063
float16_to_int32_scalbn(float16 a,FloatRoundMode rmode,int scale,float_status * s)3064 int32_t float16_to_int32_scalbn(float16 a, FloatRoundMode rmode, int scale,
3065 float_status *s)
3066 {
3067 FloatParts64 p;
3068
3069 float16_unpack_canonical(&p, a, s);
3070 return parts_float_to_sint(&p, rmode, scale, INT32_MIN, INT32_MAX, s);
3071 }
3072
float16_to_int64_scalbn(float16 a,FloatRoundMode rmode,int scale,float_status * s)3073 int64_t float16_to_int64_scalbn(float16 a, FloatRoundMode rmode, int scale,
3074 float_status *s)
3075 {
3076 FloatParts64 p;
3077
3078 float16_unpack_canonical(&p, a, s);
3079 return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s);
3080 }
3081
float32_to_int16_scalbn(float32 a,FloatRoundMode rmode,int scale,float_status * s)3082 int16_t float32_to_int16_scalbn(float32 a, FloatRoundMode rmode, int scale,
3083 float_status *s)
3084 {
3085 FloatParts64 p;
3086
3087 float32_unpack_canonical(&p, a, s);
3088 return parts_float_to_sint(&p, rmode, scale, INT16_MIN, INT16_MAX, s);
3089 }
3090
float32_to_int32_scalbn(float32 a,FloatRoundMode rmode,int scale,float_status * s)3091 int32_t float32_to_int32_scalbn(float32 a, FloatRoundMode rmode, int scale,
3092 float_status *s)
3093 {
3094 FloatParts64 p;
3095
3096 float32_unpack_canonical(&p, a, s);
3097 return parts_float_to_sint(&p, rmode, scale, INT32_MIN, INT32_MAX, s);
3098 }
3099
float32_to_int64_scalbn(float32 a,FloatRoundMode rmode,int scale,float_status * s)3100 int64_t float32_to_int64_scalbn(float32 a, FloatRoundMode rmode, int scale,
3101 float_status *s)
3102 {
3103 FloatParts64 p;
3104
3105 float32_unpack_canonical(&p, a, s);
3106 return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s);
3107 }
3108
float64_to_int16_scalbn(float64 a,FloatRoundMode rmode,int scale,float_status * s)3109 int16_t float64_to_int16_scalbn(float64 a, FloatRoundMode rmode, int scale,
3110 float_status *s)
3111 {
3112 FloatParts64 p;
3113
3114 float64_unpack_canonical(&p, a, s);
3115 return parts_float_to_sint(&p, rmode, scale, INT16_MIN, INT16_MAX, s);
3116 }
3117
float64_to_int32_scalbn(float64 a,FloatRoundMode rmode,int scale,float_status * s)3118 int32_t float64_to_int32_scalbn(float64 a, FloatRoundMode rmode, int scale,
3119 float_status *s)
3120 {
3121 FloatParts64 p;
3122
3123 float64_unpack_canonical(&p, a, s);
3124 return parts_float_to_sint(&p, rmode, scale, INT32_MIN, INT32_MAX, s);
3125 }
3126
float64_to_int64_scalbn(float64 a,FloatRoundMode rmode,int scale,float_status * s)3127 int64_t float64_to_int64_scalbn(float64 a, FloatRoundMode rmode, int scale,
3128 float_status *s)
3129 {
3130 FloatParts64 p;
3131
3132 float64_unpack_canonical(&p, a, s);
3133 return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s);
3134 }
3135
bfloat16_to_int8_scalbn(bfloat16 a,FloatRoundMode rmode,int scale,float_status * s)3136 int8_t bfloat16_to_int8_scalbn(bfloat16 a, FloatRoundMode rmode, int scale,
3137 float_status *s)
3138 {
3139 FloatParts64 p;
3140
3141 bfloat16_unpack_canonical(&p, a, s);
3142 return parts_float_to_sint(&p, rmode, scale, INT8_MIN, INT8_MAX, s);
3143 }
3144
bfloat16_to_int16_scalbn(bfloat16 a,FloatRoundMode rmode,int scale,float_status * s)3145 int16_t bfloat16_to_int16_scalbn(bfloat16 a, FloatRoundMode rmode, int scale,
3146 float_status *s)
3147 {
3148 FloatParts64 p;
3149
3150 bfloat16_unpack_canonical(&p, a, s);
3151 return parts_float_to_sint(&p, rmode, scale, INT16_MIN, INT16_MAX, s);
3152 }
3153
bfloat16_to_int32_scalbn(bfloat16 a,FloatRoundMode rmode,int scale,float_status * s)3154 int32_t bfloat16_to_int32_scalbn(bfloat16 a, FloatRoundMode rmode, int scale,
3155 float_status *s)
3156 {
3157 FloatParts64 p;
3158
3159 bfloat16_unpack_canonical(&p, a, s);
3160 return parts_float_to_sint(&p, rmode, scale, INT32_MIN, INT32_MAX, s);
3161 }
3162
bfloat16_to_int64_scalbn(bfloat16 a,FloatRoundMode rmode,int scale,float_status * s)3163 int64_t bfloat16_to_int64_scalbn(bfloat16 a, FloatRoundMode rmode, int scale,
3164 float_status *s)
3165 {
3166 FloatParts64 p;
3167
3168 bfloat16_unpack_canonical(&p, a, s);
3169 return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s);
3170 }
3171
float128_to_int32_scalbn(float128 a,FloatRoundMode rmode,int scale,float_status * s)3172 static int32_t float128_to_int32_scalbn(float128 a, FloatRoundMode rmode,
3173 int scale, float_status *s)
3174 {
3175 FloatParts128 p;
3176
3177 float128_unpack_canonical(&p, a, s);
3178 return parts_float_to_sint(&p, rmode, scale, INT32_MIN, INT32_MAX, s);
3179 }
3180
float128_to_int64_scalbn(float128 a,FloatRoundMode rmode,int scale,float_status * s)3181 static int64_t float128_to_int64_scalbn(float128 a, FloatRoundMode rmode,
3182 int scale, float_status *s)
3183 {
3184 FloatParts128 p;
3185
3186 float128_unpack_canonical(&p, a, s);
3187 return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s);
3188 }
3189
float128_to_int128_scalbn(float128 a,FloatRoundMode rmode,int scale,float_status * s)3190 static Int128 float128_to_int128_scalbn(float128 a, FloatRoundMode rmode,
3191 int scale, float_status *s)
3192 {
3193 int flags = 0;
3194 Int128 r;
3195 FloatParts128 p;
3196
3197 float128_unpack_canonical(&p, a, s);
3198
3199 switch (p.cls) {
3200 case float_class_snan:
3201 flags |= float_flag_invalid_snan;
3202 /* fall through */
3203 case float_class_qnan:
3204 flags |= float_flag_invalid;
3205 r = UINT128_MAX;
3206 break;
3207
3208 case float_class_inf:
3209 flags = float_flag_invalid | float_flag_invalid_cvti;
3210 r = p.sign ? INT128_MIN : INT128_MAX;
3211 break;
3212
3213 case float_class_zero:
3214 return int128_zero();
3215
3216 case float_class_normal:
3217 if (parts_round_to_int_normal(&p, rmode, scale, 128 - 2)) {
3218 flags = float_flag_inexact;
3219 }
3220
3221 if (p.exp < 127) {
3222 int shift = 127 - p.exp;
3223 r = int128_urshift(int128_make128(p.frac_lo, p.frac_hi), shift);
3224 if (p.sign) {
3225 r = int128_neg(r);
3226 }
3227 } else if (p.exp == 127 && p.sign && p.frac_lo == 0 &&
3228 p.frac_hi == DECOMPOSED_IMPLICIT_BIT) {
3229 r = INT128_MIN;
3230 } else {
3231 flags = float_flag_invalid | float_flag_invalid_cvti;
3232 r = p.sign ? INT128_MIN : INT128_MAX;
3233 }
3234 break;
3235
3236 default:
3237 g_assert_not_reached();
3238 }
3239
3240 float_raise(flags, s);
3241 return r;
3242 }
3243
floatx80_to_int32_scalbn(floatx80 a,FloatRoundMode rmode,int scale,float_status * s)3244 static int32_t floatx80_to_int32_scalbn(floatx80 a, FloatRoundMode rmode,
3245 int scale, float_status *s)
3246 {
3247 FloatParts128 p;
3248
3249 if (!floatx80_unpack_canonical(&p, a, s)) {
3250 parts_default_nan(&p, s);
3251 }
3252 return parts_float_to_sint(&p, rmode, scale, INT32_MIN, INT32_MAX, s);
3253 }
3254
floatx80_to_int64_scalbn(floatx80 a,FloatRoundMode rmode,int scale,float_status * s)3255 static int64_t floatx80_to_int64_scalbn(floatx80 a, FloatRoundMode rmode,
3256 int scale, float_status *s)
3257 {
3258 FloatParts128 p;
3259
3260 if (!floatx80_unpack_canonical(&p, a, s)) {
3261 parts_default_nan(&p, s);
3262 }
3263 return parts_float_to_sint(&p, rmode, scale, INT64_MIN, INT64_MAX, s);
3264 }
3265
float16_to_int8(float16 a,float_status * s)3266 int8_t float16_to_int8(float16 a, float_status *s)
3267 {
3268 return float16_to_int8_scalbn(a, s->float_rounding_mode, 0, s);
3269 }
3270
float16_to_int16(float16 a,float_status * s)3271 int16_t float16_to_int16(float16 a, float_status *s)
3272 {
3273 return float16_to_int16_scalbn(a, s->float_rounding_mode, 0, s);
3274 }
3275
float16_to_int32(float16 a,float_status * s)3276 int32_t float16_to_int32(float16 a, float_status *s)
3277 {
3278 return float16_to_int32_scalbn(a, s->float_rounding_mode, 0, s);
3279 }
3280
float16_to_int64(float16 a,float_status * s)3281 int64_t float16_to_int64(float16 a, float_status *s)
3282 {
3283 return float16_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
3284 }
3285
float32_to_int16(float32 a,float_status * s)3286 int16_t float32_to_int16(float32 a, float_status *s)
3287 {
3288 return float32_to_int16_scalbn(a, s->float_rounding_mode, 0, s);
3289 }
3290
float32_to_int32(float32 a,float_status * s)3291 int32_t float32_to_int32(float32 a, float_status *s)
3292 {
3293 return float32_to_int32_scalbn(a, s->float_rounding_mode, 0, s);
3294 }
3295
float32_to_int64(float32 a,float_status * s)3296 int64_t float32_to_int64(float32 a, float_status *s)
3297 {
3298 return float32_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
3299 }
3300
float64_to_int16(float64 a,float_status * s)3301 int16_t float64_to_int16(float64 a, float_status *s)
3302 {
3303 return float64_to_int16_scalbn(a, s->float_rounding_mode, 0, s);
3304 }
3305
float64_to_int32(float64 a,float_status * s)3306 int32_t float64_to_int32(float64 a, float_status *s)
3307 {
3308 return float64_to_int32_scalbn(a, s->float_rounding_mode, 0, s);
3309 }
3310
float64_to_int64(float64 a,float_status * s)3311 int64_t float64_to_int64(float64 a, float_status *s)
3312 {
3313 return float64_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
3314 }
3315
float128_to_int32(float128 a,float_status * s)3316 int32_t float128_to_int32(float128 a, float_status *s)
3317 {
3318 return float128_to_int32_scalbn(a, s->float_rounding_mode, 0, s);
3319 }
3320
float128_to_int64(float128 a,float_status * s)3321 int64_t float128_to_int64(float128 a, float_status *s)
3322 {
3323 return float128_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
3324 }
3325
float128_to_int128(float128 a,float_status * s)3326 Int128 float128_to_int128(float128 a, float_status *s)
3327 {
3328 return float128_to_int128_scalbn(a, s->float_rounding_mode, 0, s);
3329 }
3330
floatx80_to_int32(floatx80 a,float_status * s)3331 int32_t floatx80_to_int32(floatx80 a, float_status *s)
3332 {
3333 return floatx80_to_int32_scalbn(a, s->float_rounding_mode, 0, s);
3334 }
3335
floatx80_to_int64(floatx80 a,float_status * s)3336 int64_t floatx80_to_int64(floatx80 a, float_status *s)
3337 {
3338 return floatx80_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
3339 }
3340
float16_to_int16_round_to_zero(float16 a,float_status * s)3341 int16_t float16_to_int16_round_to_zero(float16 a, float_status *s)
3342 {
3343 return float16_to_int16_scalbn(a, float_round_to_zero, 0, s);
3344 }
3345
float16_to_int32_round_to_zero(float16 a,float_status * s)3346 int32_t float16_to_int32_round_to_zero(float16 a, float_status *s)
3347 {
3348 return float16_to_int32_scalbn(a, float_round_to_zero, 0, s);
3349 }
3350
float16_to_int64_round_to_zero(float16 a,float_status * s)3351 int64_t float16_to_int64_round_to_zero(float16 a, float_status *s)
3352 {
3353 return float16_to_int64_scalbn(a, float_round_to_zero, 0, s);
3354 }
3355
float32_to_int16_round_to_zero(float32 a,float_status * s)3356 int16_t float32_to_int16_round_to_zero(float32 a, float_status *s)
3357 {
3358 return float32_to_int16_scalbn(a, float_round_to_zero, 0, s);
3359 }
3360
float32_to_int32_round_to_zero(float32 a,float_status * s)3361 int32_t float32_to_int32_round_to_zero(float32 a, float_status *s)
3362 {
3363 return float32_to_int32_scalbn(a, float_round_to_zero, 0, s);
3364 }
3365
float32_to_int64_round_to_zero(float32 a,float_status * s)3366 int64_t float32_to_int64_round_to_zero(float32 a, float_status *s)
3367 {
3368 return float32_to_int64_scalbn(a, float_round_to_zero, 0, s);
3369 }
3370
float64_to_int16_round_to_zero(float64 a,float_status * s)3371 int16_t float64_to_int16_round_to_zero(float64 a, float_status *s)
3372 {
3373 return float64_to_int16_scalbn(a, float_round_to_zero, 0, s);
3374 }
3375
float64_to_int32_round_to_zero(float64 a,float_status * s)3376 int32_t float64_to_int32_round_to_zero(float64 a, float_status *s)
3377 {
3378 return float64_to_int32_scalbn(a, float_round_to_zero, 0, s);
3379 }
3380
float64_to_int64_round_to_zero(float64 a,float_status * s)3381 int64_t float64_to_int64_round_to_zero(float64 a, float_status *s)
3382 {
3383 return float64_to_int64_scalbn(a, float_round_to_zero, 0, s);
3384 }
3385
float128_to_int32_round_to_zero(float128 a,float_status * s)3386 int32_t float128_to_int32_round_to_zero(float128 a, float_status *s)
3387 {
3388 return float128_to_int32_scalbn(a, float_round_to_zero, 0, s);
3389 }
3390
float128_to_int64_round_to_zero(float128 a,float_status * s)3391 int64_t float128_to_int64_round_to_zero(float128 a, float_status *s)
3392 {
3393 return float128_to_int64_scalbn(a, float_round_to_zero, 0, s);
3394 }
3395
float128_to_int128_round_to_zero(float128 a,float_status * s)3396 Int128 float128_to_int128_round_to_zero(float128 a, float_status *s)
3397 {
3398 return float128_to_int128_scalbn(a, float_round_to_zero, 0, s);
3399 }
3400
floatx80_to_int32_round_to_zero(floatx80 a,float_status * s)3401 int32_t floatx80_to_int32_round_to_zero(floatx80 a, float_status *s)
3402 {
3403 return floatx80_to_int32_scalbn(a, float_round_to_zero, 0, s);
3404 }
3405
floatx80_to_int64_round_to_zero(floatx80 a,float_status * s)3406 int64_t floatx80_to_int64_round_to_zero(floatx80 a, float_status *s)
3407 {
3408 return floatx80_to_int64_scalbn(a, float_round_to_zero, 0, s);
3409 }
3410
bfloat16_to_int8(bfloat16 a,float_status * s)3411 int8_t bfloat16_to_int8(bfloat16 a, float_status *s)
3412 {
3413 return bfloat16_to_int8_scalbn(a, s->float_rounding_mode, 0, s);
3414 }
3415
bfloat16_to_int16(bfloat16 a,float_status * s)3416 int16_t bfloat16_to_int16(bfloat16 a, float_status *s)
3417 {
3418 return bfloat16_to_int16_scalbn(a, s->float_rounding_mode, 0, s);
3419 }
3420
bfloat16_to_int32(bfloat16 a,float_status * s)3421 int32_t bfloat16_to_int32(bfloat16 a, float_status *s)
3422 {
3423 return bfloat16_to_int32_scalbn(a, s->float_rounding_mode, 0, s);
3424 }
3425
bfloat16_to_int64(bfloat16 a,float_status * s)3426 int64_t bfloat16_to_int64(bfloat16 a, float_status *s)
3427 {
3428 return bfloat16_to_int64_scalbn(a, s->float_rounding_mode, 0, s);
3429 }
3430
bfloat16_to_int8_round_to_zero(bfloat16 a,float_status * s)3431 int8_t bfloat16_to_int8_round_to_zero(bfloat16 a, float_status *s)
3432 {
3433 return bfloat16_to_int8_scalbn(a, float_round_to_zero, 0, s);
3434 }
3435
bfloat16_to_int16_round_to_zero(bfloat16 a,float_status * s)3436 int16_t bfloat16_to_int16_round_to_zero(bfloat16 a, float_status *s)
3437 {
3438 return bfloat16_to_int16_scalbn(a, float_round_to_zero, 0, s);
3439 }
3440
bfloat16_to_int32_round_to_zero(bfloat16 a,float_status * s)3441 int32_t bfloat16_to_int32_round_to_zero(bfloat16 a, float_status *s)
3442 {
3443 return bfloat16_to_int32_scalbn(a, float_round_to_zero, 0, s);
3444 }
3445
bfloat16_to_int64_round_to_zero(bfloat16 a,float_status * s)3446 int64_t bfloat16_to_int64_round_to_zero(bfloat16 a, float_status *s)
3447 {
3448 return bfloat16_to_int64_scalbn(a, float_round_to_zero, 0, s);
3449 }
3450
float64_to_int32_modulo(float64 a,FloatRoundMode rmode,float_status * s)3451 int32_t float64_to_int32_modulo(float64 a, FloatRoundMode rmode,
3452 float_status *s)
3453 {
3454 FloatParts64 p;
3455
3456 float64_unpack_canonical(&p, a, s);
3457 return parts_float_to_sint_modulo(&p, rmode, 31, s);
3458 }
3459
float64_to_int64_modulo(float64 a,FloatRoundMode rmode,float_status * s)3460 int64_t float64_to_int64_modulo(float64 a, FloatRoundMode rmode,
3461 float_status *s)
3462 {
3463 FloatParts64 p;
3464
3465 float64_unpack_canonical(&p, a, s);
3466 return parts_float_to_sint_modulo(&p, rmode, 63, s);
3467 }
3468
3469 /*
3470 * Floating-point to unsigned integer conversions
3471 */
3472
float16_to_uint8_scalbn(float16 a,FloatRoundMode rmode,int scale,float_status * s)3473 uint8_t float16_to_uint8_scalbn(float16 a, FloatRoundMode rmode, int scale,
3474 float_status *s)
3475 {
3476 FloatParts64 p;
3477
3478 float16_unpack_canonical(&p, a, s);
3479 return parts_float_to_uint(&p, rmode, scale, UINT8_MAX, s);
3480 }
3481
float16_to_uint16_scalbn(float16 a,FloatRoundMode rmode,int scale,float_status * s)3482 uint16_t float16_to_uint16_scalbn(float16 a, FloatRoundMode rmode, int scale,
3483 float_status *s)
3484 {
3485 FloatParts64 p;
3486
3487 float16_unpack_canonical(&p, a, s);
3488 return parts_float_to_uint(&p, rmode, scale, UINT16_MAX, s);
3489 }
3490
float16_to_uint32_scalbn(float16 a,FloatRoundMode rmode,int scale,float_status * s)3491 uint32_t float16_to_uint32_scalbn(float16 a, FloatRoundMode rmode, int scale,
3492 float_status *s)
3493 {
3494 FloatParts64 p;
3495
3496 float16_unpack_canonical(&p, a, s);
3497 return parts_float_to_uint(&p, rmode, scale, UINT32_MAX, s);
3498 }
3499
float16_to_uint64_scalbn(float16 a,FloatRoundMode rmode,int scale,float_status * s)3500 uint64_t float16_to_uint64_scalbn(float16 a, FloatRoundMode rmode, int scale,
3501 float_status *s)
3502 {
3503 FloatParts64 p;
3504
3505 float16_unpack_canonical(&p, a, s);
3506 return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s);
3507 }
3508
float32_to_uint16_scalbn(float32 a,FloatRoundMode rmode,int scale,float_status * s)3509 uint16_t float32_to_uint16_scalbn(float32 a, FloatRoundMode rmode, int scale,
3510 float_status *s)
3511 {
3512 FloatParts64 p;
3513
3514 float32_unpack_canonical(&p, a, s);
3515 return parts_float_to_uint(&p, rmode, scale, UINT16_MAX, s);
3516 }
3517
float32_to_uint32_scalbn(float32 a,FloatRoundMode rmode,int scale,float_status * s)3518 uint32_t float32_to_uint32_scalbn(float32 a, FloatRoundMode rmode, int scale,
3519 float_status *s)
3520 {
3521 FloatParts64 p;
3522
3523 float32_unpack_canonical(&p, a, s);
3524 return parts_float_to_uint(&p, rmode, scale, UINT32_MAX, s);
3525 }
3526
float32_to_uint64_scalbn(float32 a,FloatRoundMode rmode,int scale,float_status * s)3527 uint64_t float32_to_uint64_scalbn(float32 a, FloatRoundMode rmode, int scale,
3528 float_status *s)
3529 {
3530 FloatParts64 p;
3531
3532 float32_unpack_canonical(&p, a, s);
3533 return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s);
3534 }
3535
float64_to_uint16_scalbn(float64 a,FloatRoundMode rmode,int scale,float_status * s)3536 uint16_t float64_to_uint16_scalbn(float64 a, FloatRoundMode rmode, int scale,
3537 float_status *s)
3538 {
3539 FloatParts64 p;
3540
3541 float64_unpack_canonical(&p, a, s);
3542 return parts_float_to_uint(&p, rmode, scale, UINT16_MAX, s);
3543 }
3544
float64_to_uint32_scalbn(float64 a,FloatRoundMode rmode,int scale,float_status * s)3545 uint32_t float64_to_uint32_scalbn(float64 a, FloatRoundMode rmode, int scale,
3546 float_status *s)
3547 {
3548 FloatParts64 p;
3549
3550 float64_unpack_canonical(&p, a, s);
3551 return parts_float_to_uint(&p, rmode, scale, UINT32_MAX, s);
3552 }
3553
float64_to_uint64_scalbn(float64 a,FloatRoundMode rmode,int scale,float_status * s)3554 uint64_t float64_to_uint64_scalbn(float64 a, FloatRoundMode rmode, int scale,
3555 float_status *s)
3556 {
3557 FloatParts64 p;
3558
3559 float64_unpack_canonical(&p, a, s);
3560 return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s);
3561 }
3562
bfloat16_to_uint8_scalbn(bfloat16 a,FloatRoundMode rmode,int scale,float_status * s)3563 uint8_t bfloat16_to_uint8_scalbn(bfloat16 a, FloatRoundMode rmode,
3564 int scale, float_status *s)
3565 {
3566 FloatParts64 p;
3567
3568 bfloat16_unpack_canonical(&p, a, s);
3569 return parts_float_to_uint(&p, rmode, scale, UINT8_MAX, s);
3570 }
3571
bfloat16_to_uint16_scalbn(bfloat16 a,FloatRoundMode rmode,int scale,float_status * s)3572 uint16_t bfloat16_to_uint16_scalbn(bfloat16 a, FloatRoundMode rmode,
3573 int scale, float_status *s)
3574 {
3575 FloatParts64 p;
3576
3577 bfloat16_unpack_canonical(&p, a, s);
3578 return parts_float_to_uint(&p, rmode, scale, UINT16_MAX, s);
3579 }
3580
bfloat16_to_uint32_scalbn(bfloat16 a,FloatRoundMode rmode,int scale,float_status * s)3581 uint32_t bfloat16_to_uint32_scalbn(bfloat16 a, FloatRoundMode rmode,
3582 int scale, float_status *s)
3583 {
3584 FloatParts64 p;
3585
3586 bfloat16_unpack_canonical(&p, a, s);
3587 return parts_float_to_uint(&p, rmode, scale, UINT32_MAX, s);
3588 }
3589
bfloat16_to_uint64_scalbn(bfloat16 a,FloatRoundMode rmode,int scale,float_status * s)3590 uint64_t bfloat16_to_uint64_scalbn(bfloat16 a, FloatRoundMode rmode,
3591 int scale, float_status *s)
3592 {
3593 FloatParts64 p;
3594
3595 bfloat16_unpack_canonical(&p, a, s);
3596 return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s);
3597 }
3598
float128_to_uint32_scalbn(float128 a,FloatRoundMode rmode,int scale,float_status * s)3599 static uint32_t float128_to_uint32_scalbn(float128 a, FloatRoundMode rmode,
3600 int scale, float_status *s)
3601 {
3602 FloatParts128 p;
3603
3604 float128_unpack_canonical(&p, a, s);
3605 return parts_float_to_uint(&p, rmode, scale, UINT32_MAX, s);
3606 }
3607
float128_to_uint64_scalbn(float128 a,FloatRoundMode rmode,int scale,float_status * s)3608 static uint64_t float128_to_uint64_scalbn(float128 a, FloatRoundMode rmode,
3609 int scale, float_status *s)
3610 {
3611 FloatParts128 p;
3612
3613 float128_unpack_canonical(&p, a, s);
3614 return parts_float_to_uint(&p, rmode, scale, UINT64_MAX, s);
3615 }
3616
float128_to_uint128_scalbn(float128 a,FloatRoundMode rmode,int scale,float_status * s)3617 static Int128 float128_to_uint128_scalbn(float128 a, FloatRoundMode rmode,
3618 int scale, float_status *s)
3619 {
3620 int flags = 0;
3621 Int128 r;
3622 FloatParts128 p;
3623
3624 float128_unpack_canonical(&p, a, s);
3625
3626 switch (p.cls) {
3627 case float_class_snan:
3628 flags |= float_flag_invalid_snan;
3629 /* fall through */
3630 case float_class_qnan:
3631 flags |= float_flag_invalid;
3632 r = UINT128_MAX;
3633 break;
3634
3635 case float_class_inf:
3636 flags = float_flag_invalid | float_flag_invalid_cvti;
3637 r = p.sign ? int128_zero() : UINT128_MAX;
3638 break;
3639
3640 case float_class_zero:
3641 return int128_zero();
3642
3643 case float_class_normal:
3644 if (parts_round_to_int_normal(&p, rmode, scale, 128 - 2)) {
3645 flags = float_flag_inexact;
3646 if (p.cls == float_class_zero) {
3647 r = int128_zero();
3648 break;
3649 }
3650 }
3651
3652 if (p.sign) {
3653 flags = float_flag_invalid | float_flag_invalid_cvti;
3654 r = int128_zero();
3655 } else if (p.exp <= 127) {
3656 int shift = 127 - p.exp;
3657 r = int128_urshift(int128_make128(p.frac_lo, p.frac_hi), shift);
3658 } else {
3659 flags = float_flag_invalid | float_flag_invalid_cvti;
3660 r = UINT128_MAX;
3661 }
3662 break;
3663
3664 default:
3665 g_assert_not_reached();
3666 }
3667
3668 float_raise(flags, s);
3669 return r;
3670 }
3671
float16_to_uint8(float16 a,float_status * s)3672 uint8_t float16_to_uint8(float16 a, float_status *s)
3673 {
3674 return float16_to_uint8_scalbn(a, s->float_rounding_mode, 0, s);
3675 }
3676
float16_to_uint16(float16 a,float_status * s)3677 uint16_t float16_to_uint16(float16 a, float_status *s)
3678 {
3679 return float16_to_uint16_scalbn(a, s->float_rounding_mode, 0, s);
3680 }
3681
float16_to_uint32(float16 a,float_status * s)3682 uint32_t float16_to_uint32(float16 a, float_status *s)
3683 {
3684 return float16_to_uint32_scalbn(a, s->float_rounding_mode, 0, s);
3685 }
3686
float16_to_uint64(float16 a,float_status * s)3687 uint64_t float16_to_uint64(float16 a, float_status *s)
3688 {
3689 return float16_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
3690 }
3691
float32_to_uint16(float32 a,float_status * s)3692 uint16_t float32_to_uint16(float32 a, float_status *s)
3693 {
3694 return float32_to_uint16_scalbn(a, s->float_rounding_mode, 0, s);
3695 }
3696
float32_to_uint32(float32 a,float_status * s)3697 uint32_t float32_to_uint32(float32 a, float_status *s)
3698 {
3699 return float32_to_uint32_scalbn(a, s->float_rounding_mode, 0, s);
3700 }
3701
float32_to_uint64(float32 a,float_status * s)3702 uint64_t float32_to_uint64(float32 a, float_status *s)
3703 {
3704 return float32_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
3705 }
3706
float64_to_uint16(float64 a,float_status * s)3707 uint16_t float64_to_uint16(float64 a, float_status *s)
3708 {
3709 return float64_to_uint16_scalbn(a, s->float_rounding_mode, 0, s);
3710 }
3711
float64_to_uint32(float64 a,float_status * s)3712 uint32_t float64_to_uint32(float64 a, float_status *s)
3713 {
3714 return float64_to_uint32_scalbn(a, s->float_rounding_mode, 0, s);
3715 }
3716
float64_to_uint64(float64 a,float_status * s)3717 uint64_t float64_to_uint64(float64 a, float_status *s)
3718 {
3719 return float64_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
3720 }
3721
float128_to_uint32(float128 a,float_status * s)3722 uint32_t float128_to_uint32(float128 a, float_status *s)
3723 {
3724 return float128_to_uint32_scalbn(a, s->float_rounding_mode, 0, s);
3725 }
3726
float128_to_uint64(float128 a,float_status * s)3727 uint64_t float128_to_uint64(float128 a, float_status *s)
3728 {
3729 return float128_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
3730 }
3731
float128_to_uint128(float128 a,float_status * s)3732 Int128 float128_to_uint128(float128 a, float_status *s)
3733 {
3734 return float128_to_uint128_scalbn(a, s->float_rounding_mode, 0, s);
3735 }
3736
float16_to_uint16_round_to_zero(float16 a,float_status * s)3737 uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *s)
3738 {
3739 return float16_to_uint16_scalbn(a, float_round_to_zero, 0, s);
3740 }
3741
float16_to_uint32_round_to_zero(float16 a,float_status * s)3742 uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *s)
3743 {
3744 return float16_to_uint32_scalbn(a, float_round_to_zero, 0, s);
3745 }
3746
float16_to_uint64_round_to_zero(float16 a,float_status * s)3747 uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *s)
3748 {
3749 return float16_to_uint64_scalbn(a, float_round_to_zero, 0, s);
3750 }
3751
float32_to_uint16_round_to_zero(float32 a,float_status * s)3752 uint16_t float32_to_uint16_round_to_zero(float32 a, float_status *s)
3753 {
3754 return float32_to_uint16_scalbn(a, float_round_to_zero, 0, s);
3755 }
3756
float32_to_uint32_round_to_zero(float32 a,float_status * s)3757 uint32_t float32_to_uint32_round_to_zero(float32 a, float_status *s)
3758 {
3759 return float32_to_uint32_scalbn(a, float_round_to_zero, 0, s);
3760 }
3761
float32_to_uint64_round_to_zero(float32 a,float_status * s)3762 uint64_t float32_to_uint64_round_to_zero(float32 a, float_status *s)
3763 {
3764 return float32_to_uint64_scalbn(a, float_round_to_zero, 0, s);
3765 }
3766
float64_to_uint16_round_to_zero(float64 a,float_status * s)3767 uint16_t float64_to_uint16_round_to_zero(float64 a, float_status *s)
3768 {
3769 return float64_to_uint16_scalbn(a, float_round_to_zero, 0, s);
3770 }
3771
float64_to_uint32_round_to_zero(float64 a,float_status * s)3772 uint32_t float64_to_uint32_round_to_zero(float64 a, float_status *s)
3773 {
3774 return float64_to_uint32_scalbn(a, float_round_to_zero, 0, s);
3775 }
3776
float64_to_uint64_round_to_zero(float64 a,float_status * s)3777 uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *s)
3778 {
3779 return float64_to_uint64_scalbn(a, float_round_to_zero, 0, s);
3780 }
3781
float128_to_uint32_round_to_zero(float128 a,float_status * s)3782 uint32_t float128_to_uint32_round_to_zero(float128 a, float_status *s)
3783 {
3784 return float128_to_uint32_scalbn(a, float_round_to_zero, 0, s);
3785 }
3786
float128_to_uint64_round_to_zero(float128 a,float_status * s)3787 uint64_t float128_to_uint64_round_to_zero(float128 a, float_status *s)
3788 {
3789 return float128_to_uint64_scalbn(a, float_round_to_zero, 0, s);
3790 }
3791
float128_to_uint128_round_to_zero(float128 a,float_status * s)3792 Int128 float128_to_uint128_round_to_zero(float128 a, float_status *s)
3793 {
3794 return float128_to_uint128_scalbn(a, float_round_to_zero, 0, s);
3795 }
3796
bfloat16_to_uint8(bfloat16 a,float_status * s)3797 uint8_t bfloat16_to_uint8(bfloat16 a, float_status *s)
3798 {
3799 return bfloat16_to_uint8_scalbn(a, s->float_rounding_mode, 0, s);
3800 }
3801
bfloat16_to_uint16(bfloat16 a,float_status * s)3802 uint16_t bfloat16_to_uint16(bfloat16 a, float_status *s)
3803 {
3804 return bfloat16_to_uint16_scalbn(a, s->float_rounding_mode, 0, s);
3805 }
3806
bfloat16_to_uint32(bfloat16 a,float_status * s)3807 uint32_t bfloat16_to_uint32(bfloat16 a, float_status *s)
3808 {
3809 return bfloat16_to_uint32_scalbn(a, s->float_rounding_mode, 0, s);
3810 }
3811
bfloat16_to_uint64(bfloat16 a,float_status * s)3812 uint64_t bfloat16_to_uint64(bfloat16 a, float_status *s)
3813 {
3814 return bfloat16_to_uint64_scalbn(a, s->float_rounding_mode, 0, s);
3815 }
3816
bfloat16_to_uint8_round_to_zero(bfloat16 a,float_status * s)3817 uint8_t bfloat16_to_uint8_round_to_zero(bfloat16 a, float_status *s)
3818 {
3819 return bfloat16_to_uint8_scalbn(a, float_round_to_zero, 0, s);
3820 }
3821
bfloat16_to_uint16_round_to_zero(bfloat16 a,float_status * s)3822 uint16_t bfloat16_to_uint16_round_to_zero(bfloat16 a, float_status *s)
3823 {
3824 return bfloat16_to_uint16_scalbn(a, float_round_to_zero, 0, s);
3825 }
3826
bfloat16_to_uint32_round_to_zero(bfloat16 a,float_status * s)3827 uint32_t bfloat16_to_uint32_round_to_zero(bfloat16 a, float_status *s)
3828 {
3829 return bfloat16_to_uint32_scalbn(a, float_round_to_zero, 0, s);
3830 }
3831
bfloat16_to_uint64_round_to_zero(bfloat16 a,float_status * s)3832 uint64_t bfloat16_to_uint64_round_to_zero(bfloat16 a, float_status *s)
3833 {
3834 return bfloat16_to_uint64_scalbn(a, float_round_to_zero, 0, s);
3835 }
3836
3837 /*
3838 * Signed integer to floating-point conversions
3839 */
3840
int64_to_float16_scalbn(int64_t a,int scale,float_status * status)3841 float16 int64_to_float16_scalbn(int64_t a, int scale, float_status *status)
3842 {
3843 FloatParts64 p;
3844
3845 parts_sint_to_float(&p, a, scale, status);
3846 return float16_round_pack_canonical(&p, status);
3847 }
3848
int32_to_float16_scalbn(int32_t a,int scale,float_status * status)3849 float16 int32_to_float16_scalbn(int32_t a, int scale, float_status *status)
3850 {
3851 return int64_to_float16_scalbn(a, scale, status);
3852 }
3853
int16_to_float16_scalbn(int16_t a,int scale,float_status * status)3854 float16 int16_to_float16_scalbn(int16_t a, int scale, float_status *status)
3855 {
3856 return int64_to_float16_scalbn(a, scale, status);
3857 }
3858
int64_to_float16(int64_t a,float_status * status)3859 float16 int64_to_float16(int64_t a, float_status *status)
3860 {
3861 return int64_to_float16_scalbn(a, 0, status);
3862 }
3863
int32_to_float16(int32_t a,float_status * status)3864 float16 int32_to_float16(int32_t a, float_status *status)
3865 {
3866 return int64_to_float16_scalbn(a, 0, status);
3867 }
3868
int16_to_float16(int16_t a,float_status * status)3869 float16 int16_to_float16(int16_t a, float_status *status)
3870 {
3871 return int64_to_float16_scalbn(a, 0, status);
3872 }
3873
int8_to_float16(int8_t a,float_status * status)3874 float16 int8_to_float16(int8_t a, float_status *status)
3875 {
3876 return int64_to_float16_scalbn(a, 0, status);
3877 }
3878
int64_to_float32_scalbn(int64_t a,int scale,float_status * status)3879 float32 int64_to_float32_scalbn(int64_t a, int scale, float_status *status)
3880 {
3881 FloatParts64 p;
3882
3883 /* Without scaling, there are no overflow concerns. */
3884 if (likely(scale == 0) && can_use_fpu(status)) {
3885 union_float32 ur;
3886 ur.h = a;
3887 return ur.s;
3888 }
3889
3890 parts64_sint_to_float(&p, a, scale, status);
3891 return float32_round_pack_canonical(&p, status);
3892 }
3893
int32_to_float32_scalbn(int32_t a,int scale,float_status * status)3894 float32 int32_to_float32_scalbn(int32_t a, int scale, float_status *status)
3895 {
3896 return int64_to_float32_scalbn(a, scale, status);
3897 }
3898
int16_to_float32_scalbn(int16_t a,int scale,float_status * status)3899 float32 int16_to_float32_scalbn(int16_t a, int scale, float_status *status)
3900 {
3901 return int64_to_float32_scalbn(a, scale, status);
3902 }
3903
int64_to_float32(int64_t a,float_status * status)3904 float32 int64_to_float32(int64_t a, float_status *status)
3905 {
3906 return int64_to_float32_scalbn(a, 0, status);
3907 }
3908
int32_to_float32(int32_t a,float_status * status)3909 float32 int32_to_float32(int32_t a, float_status *status)
3910 {
3911 return int64_to_float32_scalbn(a, 0, status);
3912 }
3913
int16_to_float32(int16_t a,float_status * status)3914 float32 int16_to_float32(int16_t a, float_status *status)
3915 {
3916 return int64_to_float32_scalbn(a, 0, status);
3917 }
3918
int64_to_float64_scalbn(int64_t a,int scale,float_status * status)3919 float64 int64_to_float64_scalbn(int64_t a, int scale, float_status *status)
3920 {
3921 FloatParts64 p;
3922
3923 /* Without scaling, there are no overflow concerns. */
3924 if (likely(scale == 0) && can_use_fpu(status)) {
3925 union_float64 ur;
3926 ur.h = a;
3927 return ur.s;
3928 }
3929
3930 parts_sint_to_float(&p, a, scale, status);
3931 return float64_round_pack_canonical(&p, status);
3932 }
3933
int32_to_float64_scalbn(int32_t a,int scale,float_status * status)3934 float64 int32_to_float64_scalbn(int32_t a, int scale, float_status *status)
3935 {
3936 return int64_to_float64_scalbn(a, scale, status);
3937 }
3938
int16_to_float64_scalbn(int16_t a,int scale,float_status * status)3939 float64 int16_to_float64_scalbn(int16_t a, int scale, float_status *status)
3940 {
3941 return int64_to_float64_scalbn(a, scale, status);
3942 }
3943
int64_to_float64(int64_t a,float_status * status)3944 float64 int64_to_float64(int64_t a, float_status *status)
3945 {
3946 return int64_to_float64_scalbn(a, 0, status);
3947 }
3948
int32_to_float64(int32_t a,float_status * status)3949 float64 int32_to_float64(int32_t a, float_status *status)
3950 {
3951 return int64_to_float64_scalbn(a, 0, status);
3952 }
3953
int16_to_float64(int16_t a,float_status * status)3954 float64 int16_to_float64(int16_t a, float_status *status)
3955 {
3956 return int64_to_float64_scalbn(a, 0, status);
3957 }
3958
int64_to_bfloat16_scalbn(int64_t a,int scale,float_status * status)3959 bfloat16 int64_to_bfloat16_scalbn(int64_t a, int scale, float_status *status)
3960 {
3961 FloatParts64 p;
3962
3963 parts_sint_to_float(&p, a, scale, status);
3964 return bfloat16_round_pack_canonical(&p, status);
3965 }
3966
int32_to_bfloat16_scalbn(int32_t a,int scale,float_status * status)3967 bfloat16 int32_to_bfloat16_scalbn(int32_t a, int scale, float_status *status)
3968 {
3969 return int64_to_bfloat16_scalbn(a, scale, status);
3970 }
3971
int16_to_bfloat16_scalbn(int16_t a,int scale,float_status * status)3972 bfloat16 int16_to_bfloat16_scalbn(int16_t a, int scale, float_status *status)
3973 {
3974 return int64_to_bfloat16_scalbn(a, scale, status);
3975 }
3976
int8_to_bfloat16_scalbn(int8_t a,int scale,float_status * status)3977 bfloat16 int8_to_bfloat16_scalbn(int8_t a, int scale, float_status *status)
3978 {
3979 return int64_to_bfloat16_scalbn(a, scale, status);
3980 }
3981
int64_to_bfloat16(int64_t a,float_status * status)3982 bfloat16 int64_to_bfloat16(int64_t a, float_status *status)
3983 {
3984 return int64_to_bfloat16_scalbn(a, 0, status);
3985 }
3986
int32_to_bfloat16(int32_t a,float_status * status)3987 bfloat16 int32_to_bfloat16(int32_t a, float_status *status)
3988 {
3989 return int64_to_bfloat16_scalbn(a, 0, status);
3990 }
3991
int16_to_bfloat16(int16_t a,float_status * status)3992 bfloat16 int16_to_bfloat16(int16_t a, float_status *status)
3993 {
3994 return int64_to_bfloat16_scalbn(a, 0, status);
3995 }
3996
int8_to_bfloat16(int8_t a,float_status * status)3997 bfloat16 int8_to_bfloat16(int8_t a, float_status *status)
3998 {
3999 return int64_to_bfloat16_scalbn(a, 0, status);
4000 }
4001
int128_to_float128(Int128 a,float_status * status)4002 float128 int128_to_float128(Int128 a, float_status *status)
4003 {
4004 FloatParts128 p = { };
4005 int shift;
4006
4007 if (int128_nz(a)) {
4008 p.cls = float_class_normal;
4009 if (!int128_nonneg(a)) {
4010 p.sign = true;
4011 a = int128_neg(a);
4012 }
4013
4014 shift = clz64(int128_gethi(a));
4015 if (shift == 64) {
4016 shift += clz64(int128_getlo(a));
4017 }
4018
4019 p.exp = 127 - shift;
4020 a = int128_lshift(a, shift);
4021
4022 p.frac_hi = int128_gethi(a);
4023 p.frac_lo = int128_getlo(a);
4024 } else {
4025 p.cls = float_class_zero;
4026 }
4027
4028 return float128_round_pack_canonical(&p, status);
4029 }
4030
int64_to_float128(int64_t a,float_status * status)4031 float128 int64_to_float128(int64_t a, float_status *status)
4032 {
4033 FloatParts128 p;
4034
4035 parts_sint_to_float(&p, a, 0, status);
4036 return float128_round_pack_canonical(&p, status);
4037 }
4038
int32_to_float128(int32_t a,float_status * status)4039 float128 int32_to_float128(int32_t a, float_status *status)
4040 {
4041 return int64_to_float128(a, status);
4042 }
4043
int64_to_floatx80(int64_t a,float_status * status)4044 floatx80 int64_to_floatx80(int64_t a, float_status *status)
4045 {
4046 FloatParts128 p;
4047
4048 parts_sint_to_float(&p, a, 0, status);
4049 return floatx80_round_pack_canonical(&p, status);
4050 }
4051
int32_to_floatx80(int32_t a,float_status * status)4052 floatx80 int32_to_floatx80(int32_t a, float_status *status)
4053 {
4054 return int64_to_floatx80(a, status);
4055 }
4056
4057 /*
4058 * Unsigned Integer to floating-point conversions
4059 */
4060
uint64_to_float16_scalbn(uint64_t a,int scale,float_status * status)4061 float16 uint64_to_float16_scalbn(uint64_t a, int scale, float_status *status)
4062 {
4063 FloatParts64 p;
4064
4065 parts_uint_to_float(&p, a, scale, status);
4066 return float16_round_pack_canonical(&p, status);
4067 }
4068
uint32_to_float16_scalbn(uint32_t a,int scale,float_status * status)4069 float16 uint32_to_float16_scalbn(uint32_t a, int scale, float_status *status)
4070 {
4071 return uint64_to_float16_scalbn(a, scale, status);
4072 }
4073
uint16_to_float16_scalbn(uint16_t a,int scale,float_status * status)4074 float16 uint16_to_float16_scalbn(uint16_t a, int scale, float_status *status)
4075 {
4076 return uint64_to_float16_scalbn(a, scale, status);
4077 }
4078
uint64_to_float16(uint64_t a,float_status * status)4079 float16 uint64_to_float16(uint64_t a, float_status *status)
4080 {
4081 return uint64_to_float16_scalbn(a, 0, status);
4082 }
4083
uint32_to_float16(uint32_t a,float_status * status)4084 float16 uint32_to_float16(uint32_t a, float_status *status)
4085 {
4086 return uint64_to_float16_scalbn(a, 0, status);
4087 }
4088
uint16_to_float16(uint16_t a,float_status * status)4089 float16 uint16_to_float16(uint16_t a, float_status *status)
4090 {
4091 return uint64_to_float16_scalbn(a, 0, status);
4092 }
4093
uint8_to_float16(uint8_t a,float_status * status)4094 float16 uint8_to_float16(uint8_t a, float_status *status)
4095 {
4096 return uint64_to_float16_scalbn(a, 0, status);
4097 }
4098
uint64_to_float32_scalbn(uint64_t a,int scale,float_status * status)4099 float32 uint64_to_float32_scalbn(uint64_t a, int scale, float_status *status)
4100 {
4101 FloatParts64 p;
4102
4103 /* Without scaling, there are no overflow concerns. */
4104 if (likely(scale == 0) && can_use_fpu(status)) {
4105 union_float32 ur;
4106 ur.h = a;
4107 return ur.s;
4108 }
4109
4110 parts_uint_to_float(&p, a, scale, status);
4111 return float32_round_pack_canonical(&p, status);
4112 }
4113
uint32_to_float32_scalbn(uint32_t a,int scale,float_status * status)4114 float32 uint32_to_float32_scalbn(uint32_t a, int scale, float_status *status)
4115 {
4116 return uint64_to_float32_scalbn(a, scale, status);
4117 }
4118
uint16_to_float32_scalbn(uint16_t a,int scale,float_status * status)4119 float32 uint16_to_float32_scalbn(uint16_t a, int scale, float_status *status)
4120 {
4121 return uint64_to_float32_scalbn(a, scale, status);
4122 }
4123
uint64_to_float32(uint64_t a,float_status * status)4124 float32 uint64_to_float32(uint64_t a, float_status *status)
4125 {
4126 return uint64_to_float32_scalbn(a, 0, status);
4127 }
4128
uint32_to_float32(uint32_t a,float_status * status)4129 float32 uint32_to_float32(uint32_t a, float_status *status)
4130 {
4131 return uint64_to_float32_scalbn(a, 0, status);
4132 }
4133
uint16_to_float32(uint16_t a,float_status * status)4134 float32 uint16_to_float32(uint16_t a, float_status *status)
4135 {
4136 return uint64_to_float32_scalbn(a, 0, status);
4137 }
4138
uint64_to_float64_scalbn(uint64_t a,int scale,float_status * status)4139 float64 uint64_to_float64_scalbn(uint64_t a, int scale, float_status *status)
4140 {
4141 FloatParts64 p;
4142
4143 /* Without scaling, there are no overflow concerns. */
4144 if (likely(scale == 0) && can_use_fpu(status)) {
4145 union_float64 ur;
4146 ur.h = a;
4147 return ur.s;
4148 }
4149
4150 parts_uint_to_float(&p, a, scale, status);
4151 return float64_round_pack_canonical(&p, status);
4152 }
4153
uint32_to_float64_scalbn(uint32_t a,int scale,float_status * status)4154 float64 uint32_to_float64_scalbn(uint32_t a, int scale, float_status *status)
4155 {
4156 return uint64_to_float64_scalbn(a, scale, status);
4157 }
4158
uint16_to_float64_scalbn(uint16_t a,int scale,float_status * status)4159 float64 uint16_to_float64_scalbn(uint16_t a, int scale, float_status *status)
4160 {
4161 return uint64_to_float64_scalbn(a, scale, status);
4162 }
4163
uint64_to_float64(uint64_t a,float_status * status)4164 float64 uint64_to_float64(uint64_t a, float_status *status)
4165 {
4166 return uint64_to_float64_scalbn(a, 0, status);
4167 }
4168
uint32_to_float64(uint32_t a,float_status * status)4169 float64 uint32_to_float64(uint32_t a, float_status *status)
4170 {
4171 return uint64_to_float64_scalbn(a, 0, status);
4172 }
4173
uint16_to_float64(uint16_t a,float_status * status)4174 float64 uint16_to_float64(uint16_t a, float_status *status)
4175 {
4176 return uint64_to_float64_scalbn(a, 0, status);
4177 }
4178
uint64_to_bfloat16_scalbn(uint64_t a,int scale,float_status * status)4179 bfloat16 uint64_to_bfloat16_scalbn(uint64_t a, int scale, float_status *status)
4180 {
4181 FloatParts64 p;
4182
4183 parts_uint_to_float(&p, a, scale, status);
4184 return bfloat16_round_pack_canonical(&p, status);
4185 }
4186
uint32_to_bfloat16_scalbn(uint32_t a,int scale,float_status * status)4187 bfloat16 uint32_to_bfloat16_scalbn(uint32_t a, int scale, float_status *status)
4188 {
4189 return uint64_to_bfloat16_scalbn(a, scale, status);
4190 }
4191
uint16_to_bfloat16_scalbn(uint16_t a,int scale,float_status * status)4192 bfloat16 uint16_to_bfloat16_scalbn(uint16_t a, int scale, float_status *status)
4193 {
4194 return uint64_to_bfloat16_scalbn(a, scale, status);
4195 }
4196
uint8_to_bfloat16_scalbn(uint8_t a,int scale,float_status * status)4197 bfloat16 uint8_to_bfloat16_scalbn(uint8_t a, int scale, float_status *status)
4198 {
4199 return uint64_to_bfloat16_scalbn(a, scale, status);
4200 }
4201
uint64_to_bfloat16(uint64_t a,float_status * status)4202 bfloat16 uint64_to_bfloat16(uint64_t a, float_status *status)
4203 {
4204 return uint64_to_bfloat16_scalbn(a, 0, status);
4205 }
4206
uint32_to_bfloat16(uint32_t a,float_status * status)4207 bfloat16 uint32_to_bfloat16(uint32_t a, float_status *status)
4208 {
4209 return uint64_to_bfloat16_scalbn(a, 0, status);
4210 }
4211
uint16_to_bfloat16(uint16_t a,float_status * status)4212 bfloat16 uint16_to_bfloat16(uint16_t a, float_status *status)
4213 {
4214 return uint64_to_bfloat16_scalbn(a, 0, status);
4215 }
4216
uint8_to_bfloat16(uint8_t a,float_status * status)4217 bfloat16 uint8_to_bfloat16(uint8_t a, float_status *status)
4218 {
4219 return uint64_to_bfloat16_scalbn(a, 0, status);
4220 }
4221
uint64_to_float128(uint64_t a,float_status * status)4222 float128 uint64_to_float128(uint64_t a, float_status *status)
4223 {
4224 FloatParts128 p;
4225
4226 parts_uint_to_float(&p, a, 0, status);
4227 return float128_round_pack_canonical(&p, status);
4228 }
4229
uint128_to_float128(Int128 a,float_status * status)4230 float128 uint128_to_float128(Int128 a, float_status *status)
4231 {
4232 FloatParts128 p = { };
4233 int shift;
4234
4235 if (int128_nz(a)) {
4236 p.cls = float_class_normal;
4237
4238 shift = clz64(int128_gethi(a));
4239 if (shift == 64) {
4240 shift += clz64(int128_getlo(a));
4241 }
4242
4243 p.exp = 127 - shift;
4244 a = int128_lshift(a, shift);
4245
4246 p.frac_hi = int128_gethi(a);
4247 p.frac_lo = int128_getlo(a);
4248 } else {
4249 p.cls = float_class_zero;
4250 }
4251
4252 return float128_round_pack_canonical(&p, status);
4253 }
4254
4255 /*
4256 * Minimum and maximum
4257 */
4258
float16_minmax(float16 a,float16 b,float_status * s,int flags)4259 static float16 float16_minmax(float16 a, float16 b, float_status *s, int flags)
4260 {
4261 FloatParts64 pa, pb, *pr;
4262
4263 float16_unpack_canonical(&pa, a, s);
4264 float16_unpack_canonical(&pb, b, s);
4265 pr = parts_minmax(&pa, &pb, s, flags);
4266
4267 return float16_round_pack_canonical(pr, s);
4268 }
4269
bfloat16_minmax(bfloat16 a,bfloat16 b,float_status * s,int flags)4270 static bfloat16 bfloat16_minmax(bfloat16 a, bfloat16 b,
4271 float_status *s, int flags)
4272 {
4273 FloatParts64 pa, pb, *pr;
4274
4275 bfloat16_unpack_canonical(&pa, a, s);
4276 bfloat16_unpack_canonical(&pb, b, s);
4277 pr = parts_minmax(&pa, &pb, s, flags);
4278
4279 return bfloat16_round_pack_canonical(pr, s);
4280 }
4281
float32_minmax(float32 a,float32 b,float_status * s,int flags)4282 static float32 float32_minmax(float32 a, float32 b, float_status *s, int flags)
4283 {
4284 FloatParts64 pa, pb, *pr;
4285
4286 float32_unpack_canonical(&pa, a, s);
4287 float32_unpack_canonical(&pb, b, s);
4288 pr = parts_minmax(&pa, &pb, s, flags);
4289
4290 return float32_round_pack_canonical(pr, s);
4291 }
4292
float64_minmax(float64 a,float64 b,float_status * s,int flags)4293 static float64 float64_minmax(float64 a, float64 b, float_status *s, int flags)
4294 {
4295 FloatParts64 pa, pb, *pr;
4296
4297 float64_unpack_canonical(&pa, a, s);
4298 float64_unpack_canonical(&pb, b, s);
4299 pr = parts_minmax(&pa, &pb, s, flags);
4300
4301 return float64_round_pack_canonical(pr, s);
4302 }
4303
float128_minmax(float128 a,float128 b,float_status * s,int flags)4304 static float128 float128_minmax(float128 a, float128 b,
4305 float_status *s, int flags)
4306 {
4307 FloatParts128 pa, pb, *pr;
4308
4309 float128_unpack_canonical(&pa, a, s);
4310 float128_unpack_canonical(&pb, b, s);
4311 pr = parts_minmax(&pa, &pb, s, flags);
4312
4313 return float128_round_pack_canonical(pr, s);
4314 }
4315
4316 #define MINMAX_1(type, name, flags) \
4317 type type##_##name(type a, type b, float_status *s) \
4318 { return type##_minmax(a, b, s, flags); }
4319
4320 #define MINMAX_2(type) \
4321 MINMAX_1(type, max, 0) \
4322 MINMAX_1(type, maxnum, minmax_isnum) \
4323 MINMAX_1(type, maxnummag, minmax_isnum | minmax_ismag) \
4324 MINMAX_1(type, maximum_number, minmax_isnumber) \
4325 MINMAX_1(type, min, minmax_ismin) \
4326 MINMAX_1(type, minnum, minmax_ismin | minmax_isnum) \
4327 MINMAX_1(type, minnummag, minmax_ismin | minmax_isnum | minmax_ismag) \
4328 MINMAX_1(type, minimum_number, minmax_ismin | minmax_isnumber) \
4329
4330 MINMAX_2(float16)
MINMAX_2(bfloat16)4331 MINMAX_2(bfloat16)
4332 MINMAX_2(float32)
4333 MINMAX_2(float64)
4334 MINMAX_2(float128)
4335
4336 #undef MINMAX_1
4337 #undef MINMAX_2
4338
4339 /*
4340 * Floating point compare
4341 */
4342
4343 static FloatRelation QEMU_FLATTEN
4344 float16_do_compare(float16 a, float16 b, float_status *s, bool is_quiet)
4345 {
4346 FloatParts64 pa, pb;
4347
4348 float16_unpack_canonical(&pa, a, s);
4349 float16_unpack_canonical(&pb, b, s);
4350 return parts_compare(&pa, &pb, s, is_quiet);
4351 }
4352
float16_compare(float16 a,float16 b,float_status * s)4353 FloatRelation float16_compare(float16 a, float16 b, float_status *s)
4354 {
4355 return float16_do_compare(a, b, s, false);
4356 }
4357
float16_compare_quiet(float16 a,float16 b,float_status * s)4358 FloatRelation float16_compare_quiet(float16 a, float16 b, float_status *s)
4359 {
4360 return float16_do_compare(a, b, s, true);
4361 }
4362
4363 static FloatRelation QEMU_SOFTFLOAT_ATTR
float32_do_compare(float32 a,float32 b,float_status * s,bool is_quiet)4364 float32_do_compare(float32 a, float32 b, float_status *s, bool is_quiet)
4365 {
4366 FloatParts64 pa, pb;
4367
4368 float32_unpack_canonical(&pa, a, s);
4369 float32_unpack_canonical(&pb, b, s);
4370 return parts_compare(&pa, &pb, s, is_quiet);
4371 }
4372
4373 static FloatRelation QEMU_FLATTEN
float32_hs_compare(float32 xa,float32 xb,float_status * s,bool is_quiet)4374 float32_hs_compare(float32 xa, float32 xb, float_status *s, bool is_quiet)
4375 {
4376 union_float32 ua, ub;
4377
4378 ua.s = xa;
4379 ub.s = xb;
4380
4381 if (QEMU_NO_HARDFLOAT) {
4382 goto soft;
4383 }
4384
4385 float32_input_flush2(&ua.s, &ub.s, s);
4386 if (isgreaterequal(ua.h, ub.h)) {
4387 if (isgreater(ua.h, ub.h)) {
4388 return float_relation_greater;
4389 }
4390 return float_relation_equal;
4391 }
4392 if (likely(isless(ua.h, ub.h))) {
4393 return float_relation_less;
4394 }
4395 /*
4396 * The only condition remaining is unordered.
4397 * Fall through to set flags.
4398 */
4399 soft:
4400 return float32_do_compare(ua.s, ub.s, s, is_quiet);
4401 }
4402
float32_compare(float32 a,float32 b,float_status * s)4403 FloatRelation float32_compare(float32 a, float32 b, float_status *s)
4404 {
4405 return float32_hs_compare(a, b, s, false);
4406 }
4407
float32_compare_quiet(float32 a,float32 b,float_status * s)4408 FloatRelation float32_compare_quiet(float32 a, float32 b, float_status *s)
4409 {
4410 return float32_hs_compare(a, b, s, true);
4411 }
4412
4413 static FloatRelation QEMU_SOFTFLOAT_ATTR
float64_do_compare(float64 a,float64 b,float_status * s,bool is_quiet)4414 float64_do_compare(float64 a, float64 b, float_status *s, bool is_quiet)
4415 {
4416 FloatParts64 pa, pb;
4417
4418 float64_unpack_canonical(&pa, a, s);
4419 float64_unpack_canonical(&pb, b, s);
4420 return parts_compare(&pa, &pb, s, is_quiet);
4421 }
4422
4423 static FloatRelation QEMU_FLATTEN
float64_hs_compare(float64 xa,float64 xb,float_status * s,bool is_quiet)4424 float64_hs_compare(float64 xa, float64 xb, float_status *s, bool is_quiet)
4425 {
4426 union_float64 ua, ub;
4427
4428 ua.s = xa;
4429 ub.s = xb;
4430
4431 if (QEMU_NO_HARDFLOAT) {
4432 goto soft;
4433 }
4434
4435 float64_input_flush2(&ua.s, &ub.s, s);
4436 if (isgreaterequal(ua.h, ub.h)) {
4437 if (isgreater(ua.h, ub.h)) {
4438 return float_relation_greater;
4439 }
4440 return float_relation_equal;
4441 }
4442 if (likely(isless(ua.h, ub.h))) {
4443 return float_relation_less;
4444 }
4445 /*
4446 * The only condition remaining is unordered.
4447 * Fall through to set flags.
4448 */
4449 soft:
4450 return float64_do_compare(ua.s, ub.s, s, is_quiet);
4451 }
4452
float64_compare(float64 a,float64 b,float_status * s)4453 FloatRelation float64_compare(float64 a, float64 b, float_status *s)
4454 {
4455 return float64_hs_compare(a, b, s, false);
4456 }
4457
float64_compare_quiet(float64 a,float64 b,float_status * s)4458 FloatRelation float64_compare_quiet(float64 a, float64 b, float_status *s)
4459 {
4460 return float64_hs_compare(a, b, s, true);
4461 }
4462
4463 static FloatRelation QEMU_FLATTEN
bfloat16_do_compare(bfloat16 a,bfloat16 b,float_status * s,bool is_quiet)4464 bfloat16_do_compare(bfloat16 a, bfloat16 b, float_status *s, bool is_quiet)
4465 {
4466 FloatParts64 pa, pb;
4467
4468 bfloat16_unpack_canonical(&pa, a, s);
4469 bfloat16_unpack_canonical(&pb, b, s);
4470 return parts_compare(&pa, &pb, s, is_quiet);
4471 }
4472
bfloat16_compare(bfloat16 a,bfloat16 b,float_status * s)4473 FloatRelation bfloat16_compare(bfloat16 a, bfloat16 b, float_status *s)
4474 {
4475 return bfloat16_do_compare(a, b, s, false);
4476 }
4477
bfloat16_compare_quiet(bfloat16 a,bfloat16 b,float_status * s)4478 FloatRelation bfloat16_compare_quiet(bfloat16 a, bfloat16 b, float_status *s)
4479 {
4480 return bfloat16_do_compare(a, b, s, true);
4481 }
4482
4483 static FloatRelation QEMU_FLATTEN
float128_do_compare(float128 a,float128 b,float_status * s,bool is_quiet)4484 float128_do_compare(float128 a, float128 b, float_status *s, bool is_quiet)
4485 {
4486 FloatParts128 pa, pb;
4487
4488 float128_unpack_canonical(&pa, a, s);
4489 float128_unpack_canonical(&pb, b, s);
4490 return parts_compare(&pa, &pb, s, is_quiet);
4491 }
4492
float128_compare(float128 a,float128 b,float_status * s)4493 FloatRelation float128_compare(float128 a, float128 b, float_status *s)
4494 {
4495 return float128_do_compare(a, b, s, false);
4496 }
4497
float128_compare_quiet(float128 a,float128 b,float_status * s)4498 FloatRelation float128_compare_quiet(float128 a, float128 b, float_status *s)
4499 {
4500 return float128_do_compare(a, b, s, true);
4501 }
4502
4503 static FloatRelation QEMU_FLATTEN
floatx80_do_compare(floatx80 a,floatx80 b,float_status * s,bool is_quiet)4504 floatx80_do_compare(floatx80 a, floatx80 b, float_status *s, bool is_quiet)
4505 {
4506 FloatParts128 pa, pb;
4507
4508 if (!floatx80_unpack_canonical(&pa, a, s) ||
4509 !floatx80_unpack_canonical(&pb, b, s)) {
4510 return float_relation_unordered;
4511 }
4512 return parts_compare(&pa, &pb, s, is_quiet);
4513 }
4514
floatx80_compare(floatx80 a,floatx80 b,float_status * s)4515 FloatRelation floatx80_compare(floatx80 a, floatx80 b, float_status *s)
4516 {
4517 return floatx80_do_compare(a, b, s, false);
4518 }
4519
floatx80_compare_quiet(floatx80 a,floatx80 b,float_status * s)4520 FloatRelation floatx80_compare_quiet(floatx80 a, floatx80 b, float_status *s)
4521 {
4522 return floatx80_do_compare(a, b, s, true);
4523 }
4524
4525 /*
4526 * Scale by 2**N
4527 */
4528
float16_scalbn(float16 a,int n,float_status * status)4529 float16 float16_scalbn(float16 a, int n, float_status *status)
4530 {
4531 FloatParts64 p;
4532
4533 float16_unpack_canonical(&p, a, status);
4534 parts_scalbn(&p, n, status);
4535 return float16_round_pack_canonical(&p, status);
4536 }
4537
float32_scalbn(float32 a,int n,float_status * status)4538 float32 float32_scalbn(float32 a, int n, float_status *status)
4539 {
4540 FloatParts64 p;
4541
4542 float32_unpack_canonical(&p, a, status);
4543 parts_scalbn(&p, n, status);
4544 return float32_round_pack_canonical(&p, status);
4545 }
4546
float64_scalbn(float64 a,int n,float_status * status)4547 float64 float64_scalbn(float64 a, int n, float_status *status)
4548 {
4549 FloatParts64 p;
4550
4551 float64_unpack_canonical(&p, a, status);
4552 parts_scalbn(&p, n, status);
4553 return float64_round_pack_canonical(&p, status);
4554 }
4555
bfloat16_scalbn(bfloat16 a,int n,float_status * status)4556 bfloat16 bfloat16_scalbn(bfloat16 a, int n, float_status *status)
4557 {
4558 FloatParts64 p;
4559
4560 bfloat16_unpack_canonical(&p, a, status);
4561 parts_scalbn(&p, n, status);
4562 return bfloat16_round_pack_canonical(&p, status);
4563 }
4564
float128_scalbn(float128 a,int n,float_status * status)4565 float128 float128_scalbn(float128 a, int n, float_status *status)
4566 {
4567 FloatParts128 p;
4568
4569 float128_unpack_canonical(&p, a, status);
4570 parts_scalbn(&p, n, status);
4571 return float128_round_pack_canonical(&p, status);
4572 }
4573
floatx80_scalbn(floatx80 a,int n,float_status * status)4574 floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status)
4575 {
4576 FloatParts128 p;
4577
4578 if (!floatx80_unpack_canonical(&p, a, status)) {
4579 return floatx80_default_nan(status);
4580 }
4581 parts_scalbn(&p, n, status);
4582 return floatx80_round_pack_canonical(&p, status);
4583 }
4584
4585 /*
4586 * Square Root
4587 */
4588
float16_sqrt(float16 a,float_status * status)4589 float16 QEMU_FLATTEN float16_sqrt(float16 a, float_status *status)
4590 {
4591 FloatParts64 p;
4592
4593 float16_unpack_canonical(&p, a, status);
4594 parts_sqrt(&p, status, &float16_params);
4595 return float16_round_pack_canonical(&p, status);
4596 }
4597
4598 static float32 QEMU_SOFTFLOAT_ATTR
soft_f32_sqrt(float32 a,float_status * status)4599 soft_f32_sqrt(float32 a, float_status *status)
4600 {
4601 FloatParts64 p;
4602
4603 float32_unpack_canonical(&p, a, status);
4604 parts_sqrt(&p, status, &float32_params);
4605 return float32_round_pack_canonical(&p, status);
4606 }
4607
4608 static float64 QEMU_SOFTFLOAT_ATTR
soft_f64_sqrt(float64 a,float_status * status)4609 soft_f64_sqrt(float64 a, float_status *status)
4610 {
4611 FloatParts64 p;
4612
4613 float64_unpack_canonical(&p, a, status);
4614 parts_sqrt(&p, status, &float64_params);
4615 return float64_round_pack_canonical(&p, status);
4616 }
4617
float32_sqrt(float32 xa,float_status * s)4618 float32 QEMU_FLATTEN float32_sqrt(float32 xa, float_status *s)
4619 {
4620 union_float32 ua, ur;
4621
4622 ua.s = xa;
4623 if (unlikely(!can_use_fpu(s))) {
4624 goto soft;
4625 }
4626
4627 float32_input_flush1(&ua.s, s);
4628 if (QEMU_HARDFLOAT_1F32_USE_FP) {
4629 if (unlikely(!(fpclassify(ua.h) == FP_NORMAL ||
4630 fpclassify(ua.h) == FP_ZERO) ||
4631 signbit(ua.h))) {
4632 goto soft;
4633 }
4634 } else if (unlikely(!float32_is_zero_or_normal(ua.s) ||
4635 float32_is_neg(ua.s))) {
4636 goto soft;
4637 }
4638 ur.h = sqrtf(ua.h);
4639 return ur.s;
4640
4641 soft:
4642 return soft_f32_sqrt(ua.s, s);
4643 }
4644
float64_sqrt(float64 xa,float_status * s)4645 float64 QEMU_FLATTEN float64_sqrt(float64 xa, float_status *s)
4646 {
4647 union_float64 ua, ur;
4648
4649 ua.s = xa;
4650 if (unlikely(!can_use_fpu(s))) {
4651 goto soft;
4652 }
4653
4654 float64_input_flush1(&ua.s, s);
4655 if (QEMU_HARDFLOAT_1F64_USE_FP) {
4656 if (unlikely(!(fpclassify(ua.h) == FP_NORMAL ||
4657 fpclassify(ua.h) == FP_ZERO) ||
4658 signbit(ua.h))) {
4659 goto soft;
4660 }
4661 } else if (unlikely(!float64_is_zero_or_normal(ua.s) ||
4662 float64_is_neg(ua.s))) {
4663 goto soft;
4664 }
4665 ur.h = sqrt(ua.h);
4666 return ur.s;
4667
4668 soft:
4669 return soft_f64_sqrt(ua.s, s);
4670 }
4671
float64r32_sqrt(float64 a,float_status * status)4672 float64 float64r32_sqrt(float64 a, float_status *status)
4673 {
4674 FloatParts64 p;
4675
4676 float64_unpack_canonical(&p, a, status);
4677 parts_sqrt(&p, status, &float64_params);
4678 return float64r32_round_pack_canonical(&p, status);
4679 }
4680
bfloat16_sqrt(bfloat16 a,float_status * status)4681 bfloat16 QEMU_FLATTEN bfloat16_sqrt(bfloat16 a, float_status *status)
4682 {
4683 FloatParts64 p;
4684
4685 bfloat16_unpack_canonical(&p, a, status);
4686 parts_sqrt(&p, status, &bfloat16_params);
4687 return bfloat16_round_pack_canonical(&p, status);
4688 }
4689
float128_sqrt(float128 a,float_status * status)4690 float128 QEMU_FLATTEN float128_sqrt(float128 a, float_status *status)
4691 {
4692 FloatParts128 p;
4693
4694 float128_unpack_canonical(&p, a, status);
4695 parts_sqrt(&p, status, &float128_params);
4696 return float128_round_pack_canonical(&p, status);
4697 }
4698
floatx80_sqrt(floatx80 a,float_status * s)4699 floatx80 floatx80_sqrt(floatx80 a, float_status *s)
4700 {
4701 FloatParts128 p;
4702
4703 if (!floatx80_unpack_canonical(&p, a, s)) {
4704 return floatx80_default_nan(s);
4705 }
4706 parts_sqrt(&p, s, &floatx80_params[s->floatx80_rounding_precision]);
4707 return floatx80_round_pack_canonical(&p, s);
4708 }
4709
4710 /*
4711 * log2
4712 */
float32_log2(float32 a,float_status * status)4713 float32 float32_log2(float32 a, float_status *status)
4714 {
4715 FloatParts64 p;
4716
4717 float32_unpack_canonical(&p, a, status);
4718 parts_log2(&p, status, &float32_params);
4719 return float32_round_pack_canonical(&p, status);
4720 }
4721
float64_log2(float64 a,float_status * status)4722 float64 float64_log2(float64 a, float_status *status)
4723 {
4724 FloatParts64 p;
4725
4726 float64_unpack_canonical(&p, a, status);
4727 parts_log2(&p, status, &float64_params);
4728 return float64_round_pack_canonical(&p, status);
4729 }
4730
4731 /*----------------------------------------------------------------------------
4732 | The pattern for a default generated NaN.
4733 *----------------------------------------------------------------------------*/
4734
float16_default_nan(float_status * status)4735 float16 float16_default_nan(float_status *status)
4736 {
4737 FloatParts64 p;
4738
4739 parts_default_nan(&p, status);
4740 p.frac >>= float16_params.frac_shift;
4741 return float16_pack_raw(&p);
4742 }
4743
float32_default_nan(float_status * status)4744 float32 float32_default_nan(float_status *status)
4745 {
4746 FloatParts64 p;
4747
4748 parts_default_nan(&p, status);
4749 p.frac >>= float32_params.frac_shift;
4750 return float32_pack_raw(&p);
4751 }
4752
float64_default_nan(float_status * status)4753 float64 float64_default_nan(float_status *status)
4754 {
4755 FloatParts64 p;
4756
4757 parts_default_nan(&p, status);
4758 p.frac >>= float64_params.frac_shift;
4759 return float64_pack_raw(&p);
4760 }
4761
float128_default_nan(float_status * status)4762 float128 float128_default_nan(float_status *status)
4763 {
4764 FloatParts128 p;
4765
4766 parts_default_nan(&p, status);
4767 frac_shr(&p, float128_params.frac_shift);
4768 return float128_pack_raw(&p);
4769 }
4770
bfloat16_default_nan(float_status * status)4771 bfloat16 bfloat16_default_nan(float_status *status)
4772 {
4773 FloatParts64 p;
4774
4775 parts_default_nan(&p, status);
4776 p.frac >>= bfloat16_params.frac_shift;
4777 return bfloat16_pack_raw(&p);
4778 }
4779
4780 /*----------------------------------------------------------------------------
4781 | Returns a quiet NaN from a signalling NaN for the floating point value `a'.
4782 *----------------------------------------------------------------------------*/
4783
float16_silence_nan(float16 a,float_status * status)4784 float16 float16_silence_nan(float16 a, float_status *status)
4785 {
4786 FloatParts64 p;
4787
4788 float16_unpack_raw(&p, a);
4789 p.frac <<= float16_params.frac_shift;
4790 parts_silence_nan(&p, status);
4791 p.frac >>= float16_params.frac_shift;
4792 return float16_pack_raw(&p);
4793 }
4794
float32_silence_nan(float32 a,float_status * status)4795 float32 float32_silence_nan(float32 a, float_status *status)
4796 {
4797 FloatParts64 p;
4798
4799 float32_unpack_raw(&p, a);
4800 p.frac <<= float32_params.frac_shift;
4801 parts_silence_nan(&p, status);
4802 p.frac >>= float32_params.frac_shift;
4803 return float32_pack_raw(&p);
4804 }
4805
float64_silence_nan(float64 a,float_status * status)4806 float64 float64_silence_nan(float64 a, float_status *status)
4807 {
4808 FloatParts64 p;
4809
4810 float64_unpack_raw(&p, a);
4811 p.frac <<= float64_params.frac_shift;
4812 parts_silence_nan(&p, status);
4813 p.frac >>= float64_params.frac_shift;
4814 return float64_pack_raw(&p);
4815 }
4816
bfloat16_silence_nan(bfloat16 a,float_status * status)4817 bfloat16 bfloat16_silence_nan(bfloat16 a, float_status *status)
4818 {
4819 FloatParts64 p;
4820
4821 bfloat16_unpack_raw(&p, a);
4822 p.frac <<= bfloat16_params.frac_shift;
4823 parts_silence_nan(&p, status);
4824 p.frac >>= bfloat16_params.frac_shift;
4825 return bfloat16_pack_raw(&p);
4826 }
4827
float128_silence_nan(float128 a,float_status * status)4828 float128 float128_silence_nan(float128 a, float_status *status)
4829 {
4830 FloatParts128 p;
4831
4832 float128_unpack_raw(&p, a);
4833 frac_shl(&p, float128_params.frac_shift);
4834 parts_silence_nan(&p, status);
4835 frac_shr(&p, float128_params.frac_shift);
4836 return float128_pack_raw(&p);
4837 }
4838
4839 /*----------------------------------------------------------------------------
4840 | If `a' is denormal and we are in flush-to-zero mode then set the
4841 | input-denormal exception and return zero. Otherwise just return the value.
4842 *----------------------------------------------------------------------------*/
4843
parts_squash_denormal(FloatParts64 p,float_status * status)4844 static bool parts_squash_denormal(FloatParts64 p, float_status *status)
4845 {
4846 if (p.exp == 0 && p.frac != 0) {
4847 float_raise(float_flag_input_denormal, status);
4848 return true;
4849 }
4850
4851 return false;
4852 }
4853
float16_squash_input_denormal(float16 a,float_status * status)4854 float16 float16_squash_input_denormal(float16 a, float_status *status)
4855 {
4856 if (status->flush_inputs_to_zero) {
4857 FloatParts64 p;
4858
4859 float16_unpack_raw(&p, a);
4860 if (parts_squash_denormal(p, status)) {
4861 return float16_set_sign(float16_zero, p.sign);
4862 }
4863 }
4864 return a;
4865 }
4866
float32_squash_input_denormal(float32 a,float_status * status)4867 float32 float32_squash_input_denormal(float32 a, float_status *status)
4868 {
4869 if (status->flush_inputs_to_zero) {
4870 FloatParts64 p;
4871
4872 float32_unpack_raw(&p, a);
4873 if (parts_squash_denormal(p, status)) {
4874 return float32_set_sign(float32_zero, p.sign);
4875 }
4876 }
4877 return a;
4878 }
4879
float64_squash_input_denormal(float64 a,float_status * status)4880 float64 float64_squash_input_denormal(float64 a, float_status *status)
4881 {
4882 if (status->flush_inputs_to_zero) {
4883 FloatParts64 p;
4884
4885 float64_unpack_raw(&p, a);
4886 if (parts_squash_denormal(p, status)) {
4887 return float64_set_sign(float64_zero, p.sign);
4888 }
4889 }
4890 return a;
4891 }
4892
bfloat16_squash_input_denormal(bfloat16 a,float_status * status)4893 bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status)
4894 {
4895 if (status->flush_inputs_to_zero) {
4896 FloatParts64 p;
4897
4898 bfloat16_unpack_raw(&p, a);
4899 if (parts_squash_denormal(p, status)) {
4900 return bfloat16_set_sign(bfloat16_zero, p.sign);
4901 }
4902 }
4903 return a;
4904 }
4905
4906 /*----------------------------------------------------------------------------
4907 | Normalizes the subnormal extended double-precision floating-point value
4908 | represented by the denormalized significand `aSig'. The normalized exponent
4909 | and significand are stored at the locations pointed to by `zExpPtr' and
4910 | `zSigPtr', respectively.
4911 *----------------------------------------------------------------------------*/
4912
normalizeFloatx80Subnormal(uint64_t aSig,int32_t * zExpPtr,uint64_t * zSigPtr)4913 void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
4914 uint64_t *zSigPtr)
4915 {
4916 int8_t shiftCount;
4917
4918 shiftCount = clz64(aSig);
4919 *zSigPtr = aSig<<shiftCount;
4920 *zExpPtr = 1 - shiftCount;
4921 }
4922
4923 /*----------------------------------------------------------------------------
4924 | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
4925 | and extended significand formed by the concatenation of `zSig0' and `zSig1',
4926 | and returns the proper extended double-precision floating-point value
4927 | corresponding to the abstract input. Ordinarily, the abstract value is
4928 | rounded and packed into the extended double-precision format, with the
4929 | inexact exception raised if the abstract input cannot be represented
4930 | exactly. However, if the abstract value is too large, the overflow and
4931 | inexact exceptions are raised and an infinity or maximal finite value is
4932 | returned. If the abstract value is too small, the input value is rounded to
4933 | a subnormal number, and the underflow and inexact exceptions are raised if
4934 | the abstract input cannot be represented exactly as a subnormal extended
4935 | double-precision floating-point number.
4936 | If `roundingPrecision' is floatx80_precision_s or floatx80_precision_d,
4937 | the result is rounded to the same number of bits as single or double
4938 | precision, respectively. Otherwise, the result is rounded to the full
4939 | precision of the extended double-precision format.
4940 | The input significand must be normalized or smaller. If the input
4941 | significand is not normalized, `zExp' must be 0; in that case, the result
4942 | returned is a subnormal number, and it must not require rounding. The
4943 | handling of underflow and overflow follows the IEC/IEEE Standard for Binary
4944 | Floating-Point Arithmetic.
4945 *----------------------------------------------------------------------------*/
4946
roundAndPackFloatx80(FloatX80RoundPrec roundingPrecision,bool zSign,int32_t zExp,uint64_t zSig0,uint64_t zSig1,float_status * status)4947 floatx80 roundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign,
4948 int32_t zExp, uint64_t zSig0, uint64_t zSig1,
4949 float_status *status)
4950 {
4951 FloatRoundMode roundingMode;
4952 bool roundNearestEven, increment, isTiny;
4953 int64_t roundIncrement, roundMask, roundBits;
4954
4955 roundingMode = status->float_rounding_mode;
4956 roundNearestEven = ( roundingMode == float_round_nearest_even );
4957 switch (roundingPrecision) {
4958 case floatx80_precision_x:
4959 goto precision80;
4960 case floatx80_precision_d:
4961 roundIncrement = UINT64_C(0x0000000000000400);
4962 roundMask = UINT64_C(0x00000000000007FF);
4963 break;
4964 case floatx80_precision_s:
4965 roundIncrement = UINT64_C(0x0000008000000000);
4966 roundMask = UINT64_C(0x000000FFFFFFFFFF);
4967 break;
4968 default:
4969 g_assert_not_reached();
4970 }
4971 zSig0 |= ( zSig1 != 0 );
4972 switch (roundingMode) {
4973 case float_round_nearest_even:
4974 case float_round_ties_away:
4975 break;
4976 case float_round_to_zero:
4977 roundIncrement = 0;
4978 break;
4979 case float_round_up:
4980 roundIncrement = zSign ? 0 : roundMask;
4981 break;
4982 case float_round_down:
4983 roundIncrement = zSign ? roundMask : 0;
4984 break;
4985 default:
4986 abort();
4987 }
4988 roundBits = zSig0 & roundMask;
4989 if ( 0x7FFD <= (uint32_t) ( zExp - 1 ) ) {
4990 if ( ( 0x7FFE < zExp )
4991 || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
4992 ) {
4993 goto overflow;
4994 }
4995 if ( zExp <= 0 ) {
4996 if (status->flush_to_zero) {
4997 float_raise(float_flag_output_denormal, status);
4998 return packFloatx80(zSign, 0, 0);
4999 }
5000 isTiny = status->tininess_before_rounding
5001 || (zExp < 0 )
5002 || (zSig0 <= zSig0 + roundIncrement);
5003 shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
5004 zExp = 0;
5005 roundBits = zSig0 & roundMask;
5006 if (isTiny && roundBits) {
5007 float_raise(float_flag_underflow, status);
5008 }
5009 if (roundBits) {
5010 float_raise(float_flag_inexact, status);
5011 }
5012 zSig0 += roundIncrement;
5013 if ( (int64_t) zSig0 < 0 ) zExp = 1;
5014 roundIncrement = roundMask + 1;
5015 if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
5016 roundMask |= roundIncrement;
5017 }
5018 zSig0 &= ~ roundMask;
5019 return packFloatx80( zSign, zExp, zSig0 );
5020 }
5021 }
5022 if (roundBits) {
5023 float_raise(float_flag_inexact, status);
5024 }
5025 zSig0 += roundIncrement;
5026 if ( zSig0 < roundIncrement ) {
5027 ++zExp;
5028 zSig0 = UINT64_C(0x8000000000000000);
5029 }
5030 roundIncrement = roundMask + 1;
5031 if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
5032 roundMask |= roundIncrement;
5033 }
5034 zSig0 &= ~ roundMask;
5035 if ( zSig0 == 0 ) zExp = 0;
5036 return packFloatx80( zSign, zExp, zSig0 );
5037 precision80:
5038 switch (roundingMode) {
5039 case float_round_nearest_even:
5040 case float_round_ties_away:
5041 increment = ((int64_t)zSig1 < 0);
5042 break;
5043 case float_round_to_zero:
5044 increment = 0;
5045 break;
5046 case float_round_up:
5047 increment = !zSign && zSig1;
5048 break;
5049 case float_round_down:
5050 increment = zSign && zSig1;
5051 break;
5052 default:
5053 abort();
5054 }
5055 if ( 0x7FFD <= (uint32_t) ( zExp - 1 ) ) {
5056 if ( ( 0x7FFE < zExp )
5057 || ( ( zExp == 0x7FFE )
5058 && ( zSig0 == UINT64_C(0xFFFFFFFFFFFFFFFF) )
5059 && increment
5060 )
5061 ) {
5062 roundMask = 0;
5063 overflow:
5064 float_raise(float_flag_overflow | float_flag_inexact, status);
5065 if ( ( roundingMode == float_round_to_zero )
5066 || ( zSign && ( roundingMode == float_round_up ) )
5067 || ( ! zSign && ( roundingMode == float_round_down ) )
5068 ) {
5069 return packFloatx80( zSign, 0x7FFE, ~ roundMask );
5070 }
5071 return packFloatx80(zSign,
5072 floatx80_infinity_high,
5073 floatx80_infinity_low);
5074 }
5075 if ( zExp <= 0 ) {
5076 isTiny = status->tininess_before_rounding
5077 || (zExp < 0)
5078 || !increment
5079 || (zSig0 < UINT64_C(0xFFFFFFFFFFFFFFFF));
5080 shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
5081 zExp = 0;
5082 if (isTiny && zSig1) {
5083 float_raise(float_flag_underflow, status);
5084 }
5085 if (zSig1) {
5086 float_raise(float_flag_inexact, status);
5087 }
5088 switch (roundingMode) {
5089 case float_round_nearest_even:
5090 case float_round_ties_away:
5091 increment = ((int64_t)zSig1 < 0);
5092 break;
5093 case float_round_to_zero:
5094 increment = 0;
5095 break;
5096 case float_round_up:
5097 increment = !zSign && zSig1;
5098 break;
5099 case float_round_down:
5100 increment = zSign && zSig1;
5101 break;
5102 default:
5103 abort();
5104 }
5105 if ( increment ) {
5106 ++zSig0;
5107 if (!(zSig1 << 1) && roundNearestEven) {
5108 zSig0 &= ~1;
5109 }
5110 if ( (int64_t) zSig0 < 0 ) zExp = 1;
5111 }
5112 return packFloatx80( zSign, zExp, zSig0 );
5113 }
5114 }
5115 if (zSig1) {
5116 float_raise(float_flag_inexact, status);
5117 }
5118 if ( increment ) {
5119 ++zSig0;
5120 if ( zSig0 == 0 ) {
5121 ++zExp;
5122 zSig0 = UINT64_C(0x8000000000000000);
5123 }
5124 else {
5125 if (!(zSig1 << 1) && roundNearestEven) {
5126 zSig0 &= ~1;
5127 }
5128 }
5129 }
5130 else {
5131 if ( zSig0 == 0 ) zExp = 0;
5132 }
5133 return packFloatx80( zSign, zExp, zSig0 );
5134
5135 }
5136
5137 /*----------------------------------------------------------------------------
5138 | Takes an abstract floating-point value having sign `zSign', exponent
5139 | `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
5140 | and returns the proper extended double-precision floating-point value
5141 | corresponding to the abstract input. This routine is just like
5142 | `roundAndPackFloatx80' except that the input significand does not have to be
5143 | normalized.
5144 *----------------------------------------------------------------------------*/
5145
normalizeRoundAndPackFloatx80(FloatX80RoundPrec roundingPrecision,bool zSign,int32_t zExp,uint64_t zSig0,uint64_t zSig1,float_status * status)5146 floatx80 normalizeRoundAndPackFloatx80(FloatX80RoundPrec roundingPrecision,
5147 bool zSign, int32_t zExp,
5148 uint64_t zSig0, uint64_t zSig1,
5149 float_status *status)
5150 {
5151 int8_t shiftCount;
5152
5153 if ( zSig0 == 0 ) {
5154 zSig0 = zSig1;
5155 zSig1 = 0;
5156 zExp -= 64;
5157 }
5158 shiftCount = clz64(zSig0);
5159 shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
5160 zExp -= shiftCount;
5161 return roundAndPackFloatx80(roundingPrecision, zSign, zExp,
5162 zSig0, zSig1, status);
5163
5164 }
5165
5166 /*----------------------------------------------------------------------------
5167 | Returns the binary exponential of the single-precision floating-point value
5168 | `a'. The operation is performed according to the IEC/IEEE Standard for
5169 | Binary Floating-Point Arithmetic.
5170 |
5171 | Uses the following identities:
5172 |
5173 | 1. -------------------------------------------------------------------------
5174 | x x*ln(2)
5175 | 2 = e
5176 |
5177 | 2. -------------------------------------------------------------------------
5178 | 2 3 4 5 n
5179 | x x x x x x x
5180 | e = 1 + --- + --- + --- + --- + --- + ... + --- + ...
5181 | 1! 2! 3! 4! 5! n!
5182 *----------------------------------------------------------------------------*/
5183
5184 static const float64 float32_exp2_coefficients[15] =
5185 {
5186 const_float64( 0x3ff0000000000000ll ), /* 1 */
5187 const_float64( 0x3fe0000000000000ll ), /* 2 */
5188 const_float64( 0x3fc5555555555555ll ), /* 3 */
5189 const_float64( 0x3fa5555555555555ll ), /* 4 */
5190 const_float64( 0x3f81111111111111ll ), /* 5 */
5191 const_float64( 0x3f56c16c16c16c17ll ), /* 6 */
5192 const_float64( 0x3f2a01a01a01a01all ), /* 7 */
5193 const_float64( 0x3efa01a01a01a01all ), /* 8 */
5194 const_float64( 0x3ec71de3a556c734ll ), /* 9 */
5195 const_float64( 0x3e927e4fb7789f5cll ), /* 10 */
5196 const_float64( 0x3e5ae64567f544e4ll ), /* 11 */
5197 const_float64( 0x3e21eed8eff8d898ll ), /* 12 */
5198 const_float64( 0x3de6124613a86d09ll ), /* 13 */
5199 const_float64( 0x3da93974a8c07c9dll ), /* 14 */
5200 const_float64( 0x3d6ae7f3e733b81fll ), /* 15 */
5201 };
5202
float32_exp2(float32 a,float_status * status)5203 float32 float32_exp2(float32 a, float_status *status)
5204 {
5205 FloatParts64 xp, xnp, tp, rp;
5206 int i;
5207
5208 float32_unpack_canonical(&xp, a, status);
5209 if (unlikely(xp.cls != float_class_normal)) {
5210 switch (xp.cls) {
5211 case float_class_snan:
5212 case float_class_qnan:
5213 parts_return_nan(&xp, status);
5214 return float32_round_pack_canonical(&xp, status);
5215 case float_class_inf:
5216 return xp.sign ? float32_zero : a;
5217 case float_class_zero:
5218 return float32_one;
5219 default:
5220 break;
5221 }
5222 g_assert_not_reached();
5223 }
5224
5225 float_raise(float_flag_inexact, status);
5226
5227 float64_unpack_canonical(&tp, float64_ln2, status);
5228 xp = *parts_mul(&xp, &tp, status);
5229 xnp = xp;
5230
5231 float64_unpack_canonical(&rp, float64_one, status);
5232 for (i = 0 ; i < 15 ; i++) {
5233 float64_unpack_canonical(&tp, float32_exp2_coefficients[i], status);
5234 rp = *parts_muladd(&tp, &xnp, &rp, 0, status);
5235 xnp = *parts_mul(&xnp, &xp, status);
5236 }
5237
5238 return float32_round_pack_canonical(&rp, status);
5239 }
5240
5241 /*----------------------------------------------------------------------------
5242 | Rounds the extended double-precision floating-point value `a'
5243 | to the precision provided by floatx80_rounding_precision and returns the
5244 | result as an extended double-precision floating-point value.
5245 | The operation is performed according to the IEC/IEEE Standard for Binary
5246 | Floating-Point Arithmetic.
5247 *----------------------------------------------------------------------------*/
5248
floatx80_round(floatx80 a,float_status * status)5249 floatx80 floatx80_round(floatx80 a, float_status *status)
5250 {
5251 FloatParts128 p;
5252
5253 if (!floatx80_unpack_canonical(&p, a, status)) {
5254 return floatx80_default_nan(status);
5255 }
5256 return floatx80_round_pack_canonical(&p, status);
5257 }
5258
softfloat_init(void)5259 static void __attribute__((constructor)) softfloat_init(void)
5260 {
5261 union_float64 ua, ub, uc, ur;
5262
5263 if (QEMU_NO_HARDFLOAT) {
5264 return;
5265 }
5266 /*
5267 * Test that the host's FMA is not obviously broken. For example,
5268 * glibc < 2.23 can perform an incorrect FMA on certain hosts; see
5269 * https://sourceware.org/bugzilla/show_bug.cgi?id=13304
5270 */
5271 ua.s = 0x0020000000000001ULL;
5272 ub.s = 0x3ca0000000000000ULL;
5273 uc.s = 0x0020000000000000ULL;
5274 ur.h = fma(ua.h, ub.h, uc.h);
5275 if (ur.s != 0x0020000000000001ULL) {
5276 force_soft_fma = true;
5277 }
5278 }
5279