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