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" },
33 { FE_TOWARDZERO
, "to zero" }
38 static void print_inputs(float a
, float b
, float c
)
40 char *a_fmt
, *b_fmt
, *c_fmt
;
46 printf("op : %s * %s + %s\n", a_fmt
, b_fmt
, c_fmt
);
53 static void print_result(float r
, int j
, int k
)
55 char *r_fmt
, *flag_fmt
;
58 flag_fmt
= fmt_flags();
60 printf("res: %s flags=%s (%d/%d)\n", r_fmt
, flag_fmt
, j
, k
);
66 static void do_madds(float a
, float b
, float c
, int j
, int k
)
70 print_inputs(a
, b
, c
);
72 feclearexcept(FE_ALL_EXCEPT
);
73 r
= __builtin_fmaf(a
, b
, c
);
75 print_result(r
, j
, k
);
78 int main(int argc
, char *argv
[argc
])
80 int i
, j
, k
, nums
= get_num_f32();
83 for (i
= 0; i
< ARRAY_SIZE(round_flags
); ++i
) {
84 if (fesetround(round_flags
[i
].flag
) != 0) {
85 printf("### Rounding %s skipped\n", round_flags
[i
].desc
);
88 printf("### Rounding %s\n", round_flags
[i
].desc
);
89 for (j
= 0; j
< nums
; j
++) {
90 for (k
= 0; k
< 3; k
++) {
91 a
= get_f32(j
+ ((k
)%3));
92 b
= get_f32(j
+ ((k
+1)%3));
93 c
= get_f32(j
+ ((k
+2)%3));
94 do_madds(a
, b
, c
, j
, k
);
98 /* From https://bugs.launchpad.net/qemu/+bug/1841491 */
99 printf("# LP184149\n");
100 do_madds(0x1.ffffffffffffcp
-1022, 0x1.0000000000001p
-1, 0x0.0000000000001p
-1022, j
, 0);
101 do_madds(0x8p
-152, 0x8p
-152, 0x8p
-152, j
+1, 0);