1 //===-- mulsc3_test.c - Test __mulsc3 -------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file tests __mulsc3 for the compiler_rt library. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "int_lib.h" 15 #include <math.h> 16 #include <complex.h> 17 #include <stdio.h> 18 19 // Returns: the product of a + ib and c + id 20 21 COMPILER_RT_ABI float _Complex 22 __mulsc3(float __a, float __b, float __c, float __d); 23 24 enum {zero, non_zero, inf, NaN, non_zero_nan}; 25 26 int 27 classify(float _Complex x) 28 { 29 if (x == 0) 30 return zero; 31 if (isinf(crealf(x)) || isinf(cimagf(x))) 32 return inf; 33 if (isnan(crealf(x)) && isnan(cimagf(x))) 34 return NaN; 35 if (isnan(crealf(x))) 36 { 37 if (cimagf(x) == 0) 38 return NaN; 39 return non_zero_nan; 40 } 41 if (isnan(cimagf(x))) 42 { 43 if (crealf(x) == 0) 44 return NaN; 45 return non_zero_nan; 46 } 47 return non_zero; 48 } 49 50 int test__mulsc3(float a, float b, float c, float d) 51 { 52 float _Complex r = __mulsc3(a, b, c, d); 53 // printf("test__mulsc3(%f, %f, %f, %f) = %f + I%f\n", 54 // a, b, c, d, crealf(r), cimagf(r)); 55 float _Complex dividend; 56 float _Complex divisor; 57 58 __real__ dividend = a; 59 __imag__ dividend = b; 60 __real__ divisor = c; 61 __imag__ divisor = d; 62 63 switch (classify(dividend)) 64 { 65 case zero: 66 switch (classify(divisor)) 67 { 68 case zero: 69 if (classify(r) != zero) 70 return 1; 71 break; 72 case non_zero: 73 if (classify(r) != zero) 74 return 1; 75 break; 76 case inf: 77 if (classify(r) != NaN) 78 return 1; 79 break; 80 case NaN: 81 if (classify(r) != NaN) 82 return 1; 83 break; 84 case non_zero_nan: 85 if (classify(r) != NaN) 86 return 1; 87 break; 88 } 89 break; 90 case non_zero: 91 switch (classify(divisor)) 92 { 93 case zero: 94 if (classify(r) != zero) 95 return 1; 96 break; 97 case non_zero: 98 if (classify(r) != non_zero) 99 return 1; 100 { 101 float _Complex z = a * c - b * d + _Complex_I*(a * d + b * c); 102 // relaxed tolerance to arbitrary (1.e-6) amount. 103 if (cabsf((r-z)/r) > 1.e-6) 104 return 1; 105 } 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 float 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 int main() 358 { 359 const unsigned N = sizeof(x) / sizeof(x[0]); 360 unsigned i, j; 361 for (i = 0; i < N; ++i) 362 { 363 for (j = 0; j < N; ++j) 364 { 365 if (test__mulsc3(x[i][0], x[i][1], x[j][0], x[j][1])) 366 return 1; 367 } 368 } 369 370 return 0; 371 } 372