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 | #include "fp_test.h" |
8 | #include "int_lib.h" |
9 | |
10 | // The testcase currently assumes IEEE TF format, once that has been |
11 | // fixed the defined(CRT_HAS_IEEE_TF) guard can be removed to enable it for |
12 | // IBM 128 floats as well. |
13 | #if defined(CRT_HAS_IEEE_TF) |
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(result: x, expectedHi, expectedLo); |
22 | |
23 | if (ret) { |
24 | printf(format: "error in test__addtf3(%.20Lf, %.20Lf) = %.20Lf, " |
25 | "expected %.20Lf\n" , |
26 | a, b, x, fromRep128(hi: expectedHi, lo: 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(a: makeQNaN128(), b: 0x1.23456789abcdefp+5L, |
40 | UINT64_C(0x7fff800000000000), UINT64_C(0x0))) |
41 | return 1; |
42 | // NaN + any = NaN |
43 | if (test__addtf3(a: 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(a: makeInf128(), b: makeInf128(), UINT64_C(0x7fff000000000000), |
49 | UINT64_C(0x0))) |
50 | return 1; |
51 | // inf + any = inf |
52 | if (test__addtf3(a: 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 | // Use explicit values because the binary representation of long double |
66 | // is platform dependent. Intended values: |
67 | // m = 1234.0L, n = 0.01L (where L is a literal for 128 bit long double) |
68 | const tf_float m = |
69 | fromRep128(UINT64_C(0x4009348000000000), UINT64_C(0x0000000000000000)); |
70 | const tf_float n = |
71 | fromRep128(UINT64_C(0x3FF847AE147AE147), UINT64_C(0xAE147AE147AE147B)); |
72 | |
73 | fesetround(FE_UPWARD); |
74 | if (test__addtf3(a: m, b: n, UINT64_C(0x40093480a3d70a3d), |
75 | UINT64_C(0x70a3d70a3d70a3d8))) |
76 | return 1; |
77 | |
78 | fesetround(FE_DOWNWARD); |
79 | if (test__addtf3(a: m, b: n, UINT64_C(0x40093480a3d70a3d), |
80 | UINT64_C(0x70a3d70a3d70a3d7))) |
81 | return 1; |
82 | |
83 | fesetround(FE_TOWARDZERO); |
84 | if (test__addtf3(a: m, b: n, UINT64_C(0x40093480a3d70a3d), |
85 | UINT64_C(0x70a3d70a3d70a3d7))) |
86 | return 1; |
87 | |
88 | fesetround(FE_TONEAREST); |
89 | if (test__addtf3(a: m, b: n, UINT64_C(0x40093480a3d70a3d), |
90 | UINT64_C(0x70a3d70a3d70a3d7))) |
91 | return 1; |
92 | # endif |
93 | |
94 | #else |
95 | printf("skipped\n" ); |
96 | |
97 | #endif |
98 | return 0; |
99 | } |
100 | |