1 /* { dg-do run { target { powerpc*-*-linux* } } } */
2 /* { dg-require-effective-target ppc_float128_sw } */
3 /* { dg-require-effective-target vsx_hw } */
4 /* { dg-options "-mvsx -O2" } */
5
6 #ifdef DEBUG
7 #include <stdio.h>
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <inttypes.h>
11 #endif
12
13 #if !defined(__FLOAT128__) || !defined(_ARCH_PPC)
14 static __float128
pass_through(__float128 x)15 pass_through (__float128 x)
16 {
17 return x;
18 }
19
20 __float128 (*no_optimize) (__float128) = pass_through;
21 #endif
22
23 #ifdef DEBUG
24 __attribute__((__noinline__))
25 static void
print_f128(__float128 x)26 print_f128 (__float128 x)
27 {
28 unsigned sign;
29 unsigned exponent;
30 uint64_t mantissa1;
31 uint64_t mantissa2;
32 uint64_t upper;
33 uint64_t lower;
34
35 #if defined(_ARCH_PPC) && defined(__BIG_ENDIAN__)
36 struct ieee128 {
37 uint64_t upper;
38 uint64_t lower;
39 };
40
41 #elif (defined(_ARCH_PPC) && defined(__LITTLE_ENDIAN__)) || defined(__x86_64__)
42 struct ieee128 {
43 uint64_t lower;
44 uint64_t upper;
45 };
46
47 #else
48 #error "Unknown system"
49 #endif
50
51 union {
52 __float128 f128;
53 struct ieee128 s128;
54 } u;
55
56 u.f128 = x;
57 upper = u.s128.upper;
58 lower = u.s128.lower;
59
60 sign = (unsigned)((upper >> 63) & 1);
61 exponent = (unsigned)((upper >> 48) & ((((uint64_t)1) << 16) - 1));
62 mantissa1 = (upper & ((((uint64_t)1) << 48) - 1));
63 mantissa2 = lower;
64
65 printf ("%c 0x%.4x 0x%.12" PRIx64 " 0x%.16" PRIx64,
66 sign ? '-' : '+',
67 exponent,
68 mantissa1,
69 mantissa2);
70 }
71 #endif
72
73 __attribute__((__noinline__))
74 static void
do_test(__float128 expected,__float128 got,const char * name)75 do_test (__float128 expected, __float128 got, const char *name)
76 {
77 int equal_p = (expected == got);
78
79 #ifdef DEBUG
80 printf ("Test %s, expected: ", name);
81 print_f128 (expected);
82 printf (" %5g, got: ", (double) expected);
83 print_f128 (got);
84 printf (" %5g, result %s\n",
85 (double) got,
86 (equal_p) ? "equal" : "not equal");
87 #endif
88
89 if (!equal_p)
90 __builtin_abort ();
91 }
92
93
94 int
main(void)95 main (void)
96 {
97 __float128 one = 1.0q;
98 __float128 two = 2.0q;
99 __float128 three = 3.0q;
100 __float128 four = 4.0q;
101 __float128 five = 5.0q;
102 __float128 add_result = (1.0q + 2.0q);
103 __float128 mul_result = ((1.0q + 2.0q) * 3.0q);
104 __float128 div_result = (((1.0q + 2.0q) * 3.0q) / 4.0q);
105 __float128 sub_result = ((((1.0q + 2.0q) * 3.0q) / 4.0q) - 5.0q);
106 __float128 neg_result = - sub_result;
107 __float128 add_xresult;
108 __float128 mul_xresult;
109 __float128 div_xresult;
110 __float128 sub_xresult;
111 __float128 neg_xresult;
112
113 #if defined(__FLOAT128__) && defined(_ARCH_PPC)
114 __asm__ (" #prevent constant folding, %x0" : "+wa" (one));
115 __asm__ (" #prevent constant folding, %x0" : "+wa" (two));
116 __asm__ (" #prevent constant folding, %x0" : "+wa" (three));
117 __asm__ (" #prevent constant folding, %x0" : "+wa" (four));
118 __asm__ (" #prevent constant folding, %x0" : "+wa" (five));
119
120 #else
121 one = no_optimize (one);
122 two = no_optimize (two);
123 three = no_optimize (three);
124 four = no_optimize (four);
125 five = no_optimize (five);
126 #endif
127
128 add_xresult = (one + two);
129 do_test (add_result, add_xresult, "add");
130
131 mul_xresult = add_xresult * three;
132 do_test (mul_result, mul_xresult, "mul");
133
134 div_xresult = mul_xresult / four;
135 do_test (div_result, div_xresult, "div");
136
137 sub_xresult = div_xresult - five;
138 do_test (sub_result, sub_xresult, "sub");
139
140 neg_xresult = - sub_xresult;
141 do_test (neg_result, neg_xresult, "neg");
142
143 #ifdef DEBUG
144 printf ("Passed\n");
145 #endif
146
147 return 0;
148 }
149