1 | // RUN: %clang_builtins %s %librt -o %t && %run %t |
2 | // REQUIRES: librt_has_addtf3 |
3 | |
4 | #include <fenv.h> |
5 | #include <stdio.h> |
6 | |
7 | // The testcase currently assumes IEEE TF format, once that has been |
8 | // fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for |
9 | // IBM 128 floats as well. |
10 | #if defined(CRT_HAS_IEEE_TF) |
11 | |
12 | # include "fp_test.h" |
13 | # include "int_lib.h" |
14 | |
15 | // Returns: a + b |
16 | COMPILER_RT_ABI tf_float __addtf3(tf_float a, tf_float b); |
17 | |
18 | int test__addtf3(tf_float a, tf_float b, uint64_t expectedHi, |
19 | uint64_t expectedLo) { |
20 | tf_float x = __addtf3(a, b); |
21 | int ret = compareResultF128(x, expectedHi, expectedLo); |
22 | |
23 | if (ret) { |
24 | printf("error in test__addtf3(%.20Lf, %.20Lf) = %.20Lf, " |
25 | "expected %.20Lf\n" , |
26 | a, b, x, fromRep128(expectedHi, expectedLo)); |
27 | } |
28 | |
29 | return ret; |
30 | } |
31 | |
32 | char assumption_1[sizeof(tf_float) * CHAR_BIT == 128] = {0}; |
33 | |
34 | #endif |
35 | |
36 | int main() { |
37 | #if defined(CRT_HAS_IEEE_TF) |
38 | // qNaN + any = qNaN |
39 | if (test__addtf3(makeQNaN128(), 0x1.23456789abcdefp+5L, |
40 | UINT64_C(0x7fff800000000000), UINT64_C(0x0))) |
41 | return 1; |
42 | // NaN + any = NaN |
43 | if (test__addtf3(makeNaN128(UINT64_C(0x800030000000)), |
44 | TF_C(0x1.23456789abcdefp+5), UINT64_C(0x7fff800000000000), |
45 | UINT64_C(0x0))) |
46 | return 1; |
47 | // inf + inf = inf |
48 | if (test__addtf3(makeInf128(), makeInf128(), UINT64_C(0x7fff000000000000), |
49 | UINT64_C(0x0))) |
50 | return 1; |
51 | // inf + any = inf |
52 | if (test__addtf3(makeInf128(), TF_C(0x1.2335653452436234723489432abcdefp+5), |
53 | UINT64_C(0x7fff000000000000), UINT64_C(0x0))) |
54 | return 1; |
55 | // any + any |
56 | if (test__addtf3(TF_C(0x1.23456734245345543849abcdefp+5), |
57 | TF_C(0x1.edcba52449872455634654321fp-1), |
58 | UINT64_C(0x40042afc95c8b579), UINT64_C(0x61e58dd6c51eb77c))) |
59 | return 1; |
60 | |
61 | # if (defined(__arm__) || defined(__aarch64__)) && defined(__ARM_FP) || \ |
62 | defined(i386) || defined(__x86_64__) || \ |
63 | (defined(__loongarch__) && __loongarch_frlen != 0) |
64 | // Rounding mode tests on supported architectures |
65 | const tf_float m = 1234.0L, n = 0.01L; |
66 | |
67 | fesetround(FE_UPWARD); |
68 | if (test__addtf3(m, n, UINT64_C(0x40093480a3d70a3d), |
69 | UINT64_C(0x70a3d70a3d70a3d8))) |
70 | return 1; |
71 | |
72 | fesetround(FE_DOWNWARD); |
73 | if (test__addtf3(m, n, UINT64_C(0x40093480a3d70a3d), |
74 | UINT64_C(0x70a3d70a3d70a3d7))) |
75 | return 1; |
76 | |
77 | fesetround(FE_TOWARDZERO); |
78 | if (test__addtf3(m, n, UINT64_C(0x40093480a3d70a3d), |
79 | UINT64_C(0x70a3d70a3d70a3d7))) |
80 | return 1; |
81 | |
82 | fesetround(FE_TONEAREST); |
83 | if (test__addtf3(m, n, UINT64_C(0x40093480a3d70a3d), |
84 | UINT64_C(0x70a3d70a3d70a3d7))) |
85 | return 1; |
86 | # endif |
87 | |
88 | #else |
89 | printf(format: "skipped\n" ); |
90 | |
91 | #endif |
92 | return 0; |
93 | } |
94 | |