11638Srgrimes// RUN: %clang_builtins %s %librt -o %t && %run %t 21638Srgrimes//===-- multc3_test.c - Test __multc3 -------------------------------------===// 31638Srgrimes// 41638Srgrimes// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 51638Srgrimes// See https://llvm.org/LICENSE.txt for license information. 61638Srgrimes// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 71638Srgrimes// 81638Srgrimes//===----------------------------------------------------------------------===// 91638Srgrimes// 101638Srgrimes// This file tests __multc3 for the compiler_rt library. 111638Srgrimes// 121638Srgrimes//===----------------------------------------------------------------------===// 131638Srgrimes 141638Srgrimes#include <stdio.h> 151638Srgrimes 161638Srgrimes#if _ARCH_PPC || __aarch64__ 171638Srgrimes 181638Srgrimes#include "int_lib.h" 191638Srgrimes#include <math.h> 201638Srgrimes#include <complex.h> 211638Srgrimes 221638Srgrimes// Returns: the product of a + ib and c + id 231638Srgrimes 241638SrgrimesCOMPILER_RT_ABI long double _Complex 251638Srgrimes__multc3(long double __a, long double __b, long double __c, long double __d); 261638Srgrimes 271638Srgrimesenum {zero, non_zero, inf, NaN, non_zero_nan}; 281638Srgrimes 291638Srgrimesint 301638Srgrimesclassify(long double _Complex x) 311638Srgrimes{ 321638Srgrimes if (x == 0) 331638Srgrimes return zero; 341638Srgrimes if (isinf(creall(x)) || isinf(cimagl(x))) 351638Srgrimes return inf; 361638Srgrimes if (isnan(creall(x)) && isnan(cimagl(x))) 371638Srgrimes return NaN; 381638Srgrimes if (isnan(creall(x))) 391638Srgrimes { 401638Srgrimes if (cimagl(x) == 0) 411638Srgrimes return NaN; 421638Srgrimes return non_zero_nan; 431638Srgrimes } 441638Srgrimes if (isnan(cimagl(x))) 451638Srgrimes { 461638Srgrimes if (creall(x) == 0) 471638Srgrimes return NaN; 481638Srgrimes return non_zero_nan; 491638Srgrimes } 501638Srgrimes return non_zero; 511638Srgrimes} 521638Srgrimes 531638Srgrimesint test__multc3(long double a, long double b, long double c, long double d) 541638Srgrimes{ 551638Srgrimes long double _Complex r = __multc3(a, b, c, d); 561638Srgrimes// printf("test__multc3(%Lf, %Lf, %Lf, %Lf) = %Lf + I%Lf\n", 571638Srgrimes// a, b, c, d, creall(r), cimagl(r)); 581638Srgrimes long double _Complex dividend; 591638Srgrimes long double _Complex divisor; 601638Srgrimes 611638Srgrimes __real__ dividend = a; 621638Srgrimes __imag__ dividend = b; 631638Srgrimes __real__ divisor = c; 641638Srgrimes __imag__ divisor = d; 651638Srgrimes 661638Srgrimes switch (classify(dividend)) 671638Srgrimes { 681638Srgrimes case zero: 691638Srgrimes switch (classify(divisor)) 701638Srgrimes { 711638Srgrimes case zero: 721638Srgrimes if (classify(r) != zero) 731638Srgrimes return 1; 741638Srgrimes break; 751638Srgrimes case non_zero: 761638Srgrimes if (classify(r) != zero) 771638Srgrimes return 1; 781638Srgrimes break; 791638Srgrimes case inf: 801638Srgrimes if (classify(r) != NaN) 811638Srgrimes return 1; 821638Srgrimes break; 831638Srgrimes case NaN: 841638Srgrimes if (classify(r) != NaN) 851638Srgrimes return 1; 861638Srgrimes break; 871638Srgrimes case non_zero_nan: 881638Srgrimes if (classify(r) != NaN) 891638Srgrimes return 1; 901638Srgrimes break; 911638Srgrimes } 921638Srgrimes break; 931638Srgrimes case non_zero: 94 switch (classify(divisor)) 95 { 96 case zero: 97 if (classify(r) != zero) 98 return 1; 99 break; 100 case non_zero: 101 if (classify(r) != non_zero) 102 return 1; 103 if (r != a * c - b * d + _Complex_I*(a * d + b * c)) 104 return 1; 105 break; 106 case inf: 107 if (classify(r) != inf) 108 return 1; 109 break; 110 case NaN: 111 if (classify(r) != NaN) 112 return 1; 113 break; 114 case non_zero_nan: 115 if (classify(r) != NaN) 116 return 1; 117 break; 118 } 119 break; 120 case inf: 121 switch (classify(divisor)) 122 { 123 case zero: 124 if (classify(r) != NaN) 125 return 1; 126 break; 127 case non_zero: 128 if (classify(r) != inf) 129 return 1; 130 break; 131 case inf: 132 if (classify(r) != inf) 133 return 1; 134 break; 135 case NaN: 136 if (classify(r) != NaN) 137 return 1; 138 break; 139 case non_zero_nan: 140 if (classify(r) != inf) 141 return 1; 142 break; 143 } 144 break; 145 case NaN: 146 switch (classify(divisor)) 147 { 148 case zero: 149 if (classify(r) != NaN) 150 return 1; 151 break; 152 case non_zero: 153 if (classify(r) != NaN) 154 return 1; 155 break; 156 case inf: 157 if (classify(r) != NaN) 158 return 1; 159 break; 160 case NaN: 161 if (classify(r) != NaN) 162 return 1; 163 break; 164 case non_zero_nan: 165 if (classify(r) != NaN) 166 return 1; 167 break; 168 } 169 break; 170 case non_zero_nan: 171 switch (classify(divisor)) 172 { 173 case zero: 174 if (classify(r) != NaN) 175 return 1; 176 break; 177 case non_zero: 178 if (classify(r) != NaN) 179 return 1; 180 break; 181 case inf: 182 if (classify(r) != inf) 183 return 1; 184 break; 185 case NaN: 186 if (classify(r) != NaN) 187 return 1; 188 break; 189 case non_zero_nan: 190 if (classify(r) != NaN) 191 return 1; 192 break; 193 } 194 break; 195 } 196 197 return 0; 198} 199 200long double x[][2] = 201{ 202 { 1.e-6, 1.e-6}, 203 {-1.e-6, 1.e-6}, 204 {-1.e-6, -1.e-6}, 205 { 1.e-6, -1.e-6}, 206 207 { 1.e+6, 1.e-6}, 208 {-1.e+6, 1.e-6}, 209 {-1.e+6, -1.e-6}, 210 { 1.e+6, -1.e-6}, 211 212 { 1.e-6, 1.e+6}, 213 {-1.e-6, 1.e+6}, 214 {-1.e-6, -1.e+6}, 215 { 1.e-6, -1.e+6}, 216 217 { 1.e+6, 1.e+6}, 218 {-1.e+6, 1.e+6}, 219 {-1.e+6, -1.e+6}, 220 { 1.e+6, -1.e+6}, 221 222 {NAN, NAN}, 223 {-INFINITY, NAN}, 224 {-2, NAN}, 225 {-1, NAN}, 226 {-0.5, NAN}, 227 {-0., NAN}, 228 {+0., NAN}, 229 {0.5, NAN}, 230 {1, NAN}, 231 {2, NAN}, 232 {INFINITY, NAN}, 233 234 {NAN, -INFINITY}, 235 {-INFINITY, -INFINITY}, 236 {-2, -INFINITY}, 237 {-1, -INFINITY}, 238 {-0.5, -INFINITY}, 239 {-0., -INFINITY}, 240 {+0., -INFINITY}, 241 {0.5, -INFINITY}, 242 {1, -INFINITY}, 243 {2, -INFINITY}, 244 {INFINITY, -INFINITY}, 245 246 {NAN, -2}, 247 {-INFINITY, -2}, 248 {-2, -2}, 249 {-1, -2}, 250 {-0.5, -2}, 251 {-0., -2}, 252 {+0., -2}, 253 {0.5, -2}, 254 {1, -2}, 255 {2, -2}, 256 {INFINITY, -2}, 257 258 {NAN, -1}, 259 {-INFINITY, -1}, 260 {-2, -1}, 261 {-1, -1}, 262 {-0.5, -1}, 263 {-0., -1}, 264 {+0., -1}, 265 {0.5, -1}, 266 {1, -1}, 267 {2, -1}, 268 {INFINITY, -1}, 269 270 {NAN, -0.5}, 271 {-INFINITY, -0.5}, 272 {-2, -0.5}, 273 {-1, -0.5}, 274 {-0.5, -0.5}, 275 {-0., -0.5}, 276 {+0., -0.5}, 277 {0.5, -0.5}, 278 {1, -0.5}, 279 {2, -0.5}, 280 {INFINITY, -0.5}, 281 282 {NAN, -0.}, 283 {-INFINITY, -0.}, 284 {-2, -0.}, 285 {-1, -0.}, 286 {-0.5, -0.}, 287 {-0., -0.}, 288 {+0., -0.}, 289 {0.5, -0.}, 290 {1, -0.}, 291 {2, -0.}, 292 {INFINITY, -0.}, 293 294 {NAN, 0.}, 295 {-INFINITY, 0.}, 296 {-2, 0.}, 297 {-1, 0.}, 298 {-0.5, 0.}, 299 {-0., 0.}, 300 {+0., 0.}, 301 {0.5, 0.}, 302 {1, 0.}, 303 {2, 0.}, 304 {INFINITY, 0.}, 305 306 {NAN, 0.5}, 307 {-INFINITY, 0.5}, 308 {-2, 0.5}, 309 {-1, 0.5}, 310 {-0.5, 0.5}, 311 {-0., 0.5}, 312 {+0., 0.5}, 313 {0.5, 0.5}, 314 {1, 0.5}, 315 {2, 0.5}, 316 {INFINITY, 0.5}, 317 318 {NAN, 1}, 319 {-INFINITY, 1}, 320 {-2, 1}, 321 {-1, 1}, 322 {-0.5, 1}, 323 {-0., 1}, 324 {+0., 1}, 325 {0.5, 1}, 326 {1, 1}, 327 {2, 1}, 328 {INFINITY, 1}, 329 330 {NAN, 2}, 331 {-INFINITY, 2}, 332 {-2, 2}, 333 {-1, 2}, 334 {-0.5, 2}, 335 {-0., 2}, 336 {+0., 2}, 337 {0.5, 2}, 338 {1, 2}, 339 {2, 2}, 340 {INFINITY, 2}, 341 342 {NAN, INFINITY}, 343 {-INFINITY, INFINITY}, 344 {-2, INFINITY}, 345 {-1, INFINITY}, 346 {-0.5, INFINITY}, 347 {-0., INFINITY}, 348 {+0., INFINITY}, 349 {0.5, INFINITY}, 350 {1, INFINITY}, 351 {2, INFINITY}, 352 {INFINITY, INFINITY} 353 354}; 355 356#endif 357 358int main() 359{ 360#if _ARCH_PPC || __aarch64__ 361 const unsigned N = sizeof(x) / sizeof(x[0]); 362 unsigned i, j; 363 for (i = 0; i < N; ++i) 364 { 365 for (j = 0; j < N; ++j) 366 { 367 if (test__multc3(x[i][0], x[i][1], x[j][0], x[j][1])) 368 return 1; 369 } 370 } 371#else 372 printf("skipped\n"); 373#endif 374 return 0; 375} 376