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