1 // RUN: %clang_builtins %s %librt -o %t && %run %t 2 //===-- multc3_test.c - Test __multc3 -------------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 // 11 // This file tests __multc3 for the compiler_rt library. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include <stdio.h> 16 17 #if _ARCH_PPC || __aarch64__ 18 19 #include "int_lib.h" 20 #include <math.h> 21 #include <complex.h> 22 23 // Returns: the product of a + ib and c + id 24 25 COMPILER_RT_ABI long double _Complex 26 __multc3(long double __a, long double __b, long double __c, long double __d); 27 28 enum {zero, non_zero, inf, NaN, non_zero_nan}; 29 30 int 31 classify(long double _Complex x) 32 { 33 if (x == 0) 34 return zero; 35 if (isinf(creall(x)) || isinf(cimagl(x))) 36 return inf; 37 if (isnan(creall(x)) && isnan(cimagl(x))) 38 return NaN; 39 if (isnan(creall(x))) 40 { 41 if (cimagl(x) == 0) 42 return NaN; 43 return non_zero_nan; 44 } 45 if (isnan(cimagl(x))) 46 { 47 if (creall(x) == 0) 48 return NaN; 49 return non_zero_nan; 50 } 51 return non_zero; 52 } 53 54 int test__multc3(long double a, long double b, long double c, long double d) 55 { 56 long double _Complex r = __multc3(a, b, c, d); 57 // printf("test__multc3(%Lf, %Lf, %Lf, %Lf) = %Lf + I%Lf\n", 58 // a, b, c, d, creall(r), cimagl(r)); 59 long double _Complex dividend; 60 long double _Complex divisor; 61 62 __real__ dividend = a; 63 __imag__ dividend = b; 64 __real__ divisor = c; 65 __imag__ divisor = d; 66 67 switch (classify(dividend)) 68 { 69 case zero: 70 switch (classify(divisor)) 71 { 72 case zero: 73 if (classify(r) != zero) 74 return 1; 75 break; 76 case non_zero: 77 if (classify(r) != zero) 78 return 1; 79 break; 80 case inf: 81 if (classify(r) != NaN) 82 return 1; 83 break; 84 case NaN: 85 if (classify(r) != NaN) 86 return 1; 87 break; 88 case non_zero_nan: 89 if (classify(r) != NaN) 90 return 1; 91 break; 92 } 93 break; 94 case non_zero: 95 switch (classify(divisor)) 96 { 97 case zero: 98 if (classify(r) != zero) 99 return 1; 100 break; 101 case non_zero: 102 if (classify(r) != non_zero) 103 return 1; 104 if (r != a * c - b * d + _Complex_I*(a * d + b * c)) 105 return 1; 106 break; 107 case inf: 108 if (classify(r) != inf) 109 return 1; 110 break; 111 case NaN: 112 if (classify(r) != NaN) 113 return 1; 114 break; 115 case non_zero_nan: 116 if (classify(r) != NaN) 117 return 1; 118 break; 119 } 120 break; 121 case inf: 122 switch (classify(divisor)) 123 { 124 case zero: 125 if (classify(r) != NaN) 126 return 1; 127 break; 128 case non_zero: 129 if (classify(r) != inf) 130 return 1; 131 break; 132 case inf: 133 if (classify(r) != inf) 134 return 1; 135 break; 136 case NaN: 137 if (classify(r) != NaN) 138 return 1; 139 break; 140 case non_zero_nan: 141 if (classify(r) != inf) 142 return 1; 143 break; 144 } 145 break; 146 case NaN: 147 switch (classify(divisor)) 148 { 149 case zero: 150 if (classify(r) != NaN) 151 return 1; 152 break; 153 case non_zero: 154 if (classify(r) != NaN) 155 return 1; 156 break; 157 case inf: 158 if (classify(r) != NaN) 159 return 1; 160 break; 161 case NaN: 162 if (classify(r) != NaN) 163 return 1; 164 break; 165 case non_zero_nan: 166 if (classify(r) != NaN) 167 return 1; 168 break; 169 } 170 break; 171 case non_zero_nan: 172 switch (classify(divisor)) 173 { 174 case zero: 175 if (classify(r) != NaN) 176 return 1; 177 break; 178 case non_zero: 179 if (classify(r) != NaN) 180 return 1; 181 break; 182 case inf: 183 if (classify(r) != inf) 184 return 1; 185 break; 186 case NaN: 187 if (classify(r) != NaN) 188 return 1; 189 break; 190 case non_zero_nan: 191 if (classify(r) != NaN) 192 return 1; 193 break; 194 } 195 break; 196 } 197 198 return 0; 199 } 200 201 long double x[][2] = 202 { 203 { 1.e-6, 1.e-6}, 204 {-1.e-6, 1.e-6}, 205 {-1.e-6, -1.e-6}, 206 { 1.e-6, -1.e-6}, 207 208 { 1.e+6, 1.e-6}, 209 {-1.e+6, 1.e-6}, 210 {-1.e+6, -1.e-6}, 211 { 1.e+6, -1.e-6}, 212 213 { 1.e-6, 1.e+6}, 214 {-1.e-6, 1.e+6}, 215 {-1.e-6, -1.e+6}, 216 { 1.e-6, -1.e+6}, 217 218 { 1.e+6, 1.e+6}, 219 {-1.e+6, 1.e+6}, 220 {-1.e+6, -1.e+6}, 221 { 1.e+6, -1.e+6}, 222 223 {NAN, NAN}, 224 {-INFINITY, NAN}, 225 {-2, NAN}, 226 {-1, NAN}, 227 {-0.5, NAN}, 228 {-0., NAN}, 229 {+0., NAN}, 230 {0.5, NAN}, 231 {1, NAN}, 232 {2, NAN}, 233 {INFINITY, NAN}, 234 235 {NAN, -INFINITY}, 236 {-INFINITY, -INFINITY}, 237 {-2, -INFINITY}, 238 {-1, -INFINITY}, 239 {-0.5, -INFINITY}, 240 {-0., -INFINITY}, 241 {+0., -INFINITY}, 242 {0.5, -INFINITY}, 243 {1, -INFINITY}, 244 {2, -INFINITY}, 245 {INFINITY, -INFINITY}, 246 247 {NAN, -2}, 248 {-INFINITY, -2}, 249 {-2, -2}, 250 {-1, -2}, 251 {-0.5, -2}, 252 {-0., -2}, 253 {+0., -2}, 254 {0.5, -2}, 255 {1, -2}, 256 {2, -2}, 257 {INFINITY, -2}, 258 259 {NAN, -1}, 260 {-INFINITY, -1}, 261 {-2, -1}, 262 {-1, -1}, 263 {-0.5, -1}, 264 {-0., -1}, 265 {+0., -1}, 266 {0.5, -1}, 267 {1, -1}, 268 {2, -1}, 269 {INFINITY, -1}, 270 271 {NAN, -0.5}, 272 {-INFINITY, -0.5}, 273 {-2, -0.5}, 274 {-1, -0.5}, 275 {-0.5, -0.5}, 276 {-0., -0.5}, 277 {+0., -0.5}, 278 {0.5, -0.5}, 279 {1, -0.5}, 280 {2, -0.5}, 281 {INFINITY, -0.5}, 282 283 {NAN, -0.}, 284 {-INFINITY, -0.}, 285 {-2, -0.}, 286 {-1, -0.}, 287 {-0.5, -0.}, 288 {-0., -0.}, 289 {+0., -0.}, 290 {0.5, -0.}, 291 {1, -0.}, 292 {2, -0.}, 293 {INFINITY, -0.}, 294 295 {NAN, 0.}, 296 {-INFINITY, 0.}, 297 {-2, 0.}, 298 {-1, 0.}, 299 {-0.5, 0.}, 300 {-0., 0.}, 301 {+0., 0.}, 302 {0.5, 0.}, 303 {1, 0.}, 304 {2, 0.}, 305 {INFINITY, 0.}, 306 307 {NAN, 0.5}, 308 {-INFINITY, 0.5}, 309 {-2, 0.5}, 310 {-1, 0.5}, 311 {-0.5, 0.5}, 312 {-0., 0.5}, 313 {+0., 0.5}, 314 {0.5, 0.5}, 315 {1, 0.5}, 316 {2, 0.5}, 317 {INFINITY, 0.5}, 318 319 {NAN, 1}, 320 {-INFINITY, 1}, 321 {-2, 1}, 322 {-1, 1}, 323 {-0.5, 1}, 324 {-0., 1}, 325 {+0., 1}, 326 {0.5, 1}, 327 {1, 1}, 328 {2, 1}, 329 {INFINITY, 1}, 330 331 {NAN, 2}, 332 {-INFINITY, 2}, 333 {-2, 2}, 334 {-1, 2}, 335 {-0.5, 2}, 336 {-0., 2}, 337 {+0., 2}, 338 {0.5, 2}, 339 {1, 2}, 340 {2, 2}, 341 {INFINITY, 2}, 342 343 {NAN, INFINITY}, 344 {-INFINITY, INFINITY}, 345 {-2, INFINITY}, 346 {-1, INFINITY}, 347 {-0.5, INFINITY}, 348 {-0., INFINITY}, 349 {+0., INFINITY}, 350 {0.5, INFINITY}, 351 {1, INFINITY}, 352 {2, INFINITY}, 353 {INFINITY, INFINITY} 354 355 }; 356 357 #endif 358 359 int main() 360 { 361 #if _ARCH_PPC || __aarch64__ 362 const unsigned N = sizeof(x) / sizeof(x[0]); 363 unsigned i, j; 364 for (i = 0; i < N; ++i) 365 { 366 for (j = 0; j < N; ++j) 367 { 368 if (test__multc3(x[i][0], x[i][1], x[j][0], x[j][1])) 369 return 1; 370 } 371 } 372 #else 373 printf("skipped\n"); 374 #endif 375 return 0; 376 } 377