Home | History | Annotate | Download | only in Unit
      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