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