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