2 * Fused Multiply Add (Single)
4 * Copyright (c) 2019 Linaro
6 * SPDX-License-Identifier: GPL-3.0-or-later
15 #include "float_helpers.h"
17 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
24 float_mapping round_flags
[] = {
25 { FE_TONEAREST
, "to nearest" },
27 { FE_UPWARD
, "upwards" },
30 { FE_DOWNWARD
, "downwards" },
32 { FE_TOWARDZERO
, "to zero" }
36 static void print_inputs(float a
, float b
, float c
)
38 char *a_fmt
, *b_fmt
, *c_fmt
;
44 printf("op : %s * %s + %s\n", a_fmt
, b_fmt
, c_fmt
);
51 static void print_result(float r
, int j
, int k
)
53 char *r_fmt
, *flag_fmt
;
56 flag_fmt
= fmt_flags();
58 printf("res: %s flags=%s (%d/%d)\n", r_fmt
, flag_fmt
, j
, k
);
64 static void do_madds(float a
, float b
, float c
, int j
, int k
)
68 print_inputs(a
, b
, c
);
70 feclearexcept(FE_ALL_EXCEPT
);
71 r
= __builtin_fmaf(a
, b
, c
);
73 print_result(r
, j
, k
);
76 int main(int argc
, char *argv
[argc
])
78 int i
, j
, k
, nums
= get_num_f32();
81 for (i
= 0; i
< ARRAY_SIZE(round_flags
); ++i
) {
82 if (fesetround(round_flags
[i
].flag
) != 0) {
83 printf("### Rounding %s skipped\n", round_flags
[i
].desc
);
86 printf("### Rounding %s\n", round_flags
[i
].desc
);
87 for (j
= 0; j
< nums
; j
++) {
88 for (k
= 0; k
< 3; k
++) {
89 a
= get_f32(j
+ ((k
)%3));
90 b
= get_f32(j
+ ((k
+1)%3));
91 c
= get_f32(j
+ ((k
+2)%3));
92 do_madds(a
, b
, c
, j
, k
);
96 /* From https://bugs.launchpad.net/qemu/+bug/1841491 */
97 printf("# LP184149\n");
98 do_madds(0x1.ffffffffffffcp
-1022, 0x1.0000000000001p
-1, 0x0.0000000000001p
-1022, j
, 0);
99 do_madds(0x8p
-152, 0x8p
-152, 0x8p
-152, j
+1, 0);