LCOV - code coverage report
Current view: top level - src/support - operators.c (source / functions) Hit Total Coverage
Test: [build process] commit ef510b1f346f4c9f9d86eaceace5ca54961a1dbc Lines: 44 137 32.1 %
Date: 2022-07-17 01:01:28 Functions: 7 9 77.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 29 161 18.0 %

           Branch data     Line data    Source code
       1                 :            : // This file is a part of Julia. License is MIT: https://julialang.org/license
       2                 :            : 
       3                 :            : #include <limits.h>
       4                 :            : #include <assert.h>
       5                 :            : #include <stdint.h>
       6                 :            : #include <stddef.h>
       7                 :            : #include "dtypes.h"
       8                 :            : #include "utils.h"
       9                 :            : 
      10                 :            : #ifdef __cplusplus
      11                 :            : extern "C" {
      12                 :            : #endif
      13                 :            : 
      14                 :     458214 : double conv_to_double(void *data, numerictype_t tag)
      15                 :            : {
      16                 :     458214 :     double d=0;
      17   [ -  +  -  +  :     458214 :     switch (tag) {
          -  +  +  +  +  
                   +  - ]
      18                 :          0 :     case T_INT8:   d = (double)*(int8_t*)data; break;
      19                 :       2876 :     case T_UINT8:  d = (double)*(uint8_t*)data; break;
      20                 :          0 :     case T_INT16:  d = (double)*(int16_t*)data; break;
      21                 :       1320 :     case T_UINT16: d = (double)*(uint16_t*)data; break;
      22                 :          0 :     case T_INT32:  d = (double)*(int32_t*)data; break;
      23                 :       1660 :     case T_UINT32: d = (double)*(uint32_t*)data; break;
      24                 :     218080 :     case T_INT64: {
      25                 :     218080 :         int64_t l = (int64_t)jl_load_ptraligned_i64(data);
      26                 :     218080 :         d = (double)l;
      27   [ +  +  -  + ]:     218080 :         if (d > 0 && l < 0)  // can happen!
      28                 :          0 :             d = -d;
      29                 :     218080 :         break;
      30                 :            :     }
      31                 :       4844 :     case T_UINT64: d = (double)jl_load_ptraligned_i64(data); break;
      32                 :       2692 :     case T_FLOAT:  d = (double)*(float*)data; break;
      33                 :     226742 :     case T_DOUBLE: return jl_load_ptraligned_f64(data);
      34                 :            :     }
      35                 :     231472 :     return d;
      36                 :            : }
      37                 :            : 
      38                 :            : #define CONV_TO_INTTYPE(type)                                                  \
      39                 :            : type##_t conv_to_##type(void *data, numerictype_t tag)                         \
      40                 :            : {                                                                              \
      41                 :            :     type##_t i=0;                                                              \
      42                 :            :     switch (tag) {                                                             \
      43                 :            :     case T_INT8:   i = (type##_t)*(int8_t*)data; break;                        \
      44                 :            :     case T_UINT8:  i = (type##_t)*(uint8_t*)data; break;                       \
      45                 :            :     case T_INT16:  i = (type##_t)*(int16_t*)(data); break;                     \
      46                 :            :     case T_UINT16: i = (type##_t)*(uint16_t*)(data); break;                    \
      47                 :            :     case T_INT32:  i = (type##_t)*(int32_t*)(data); break;                     \
      48                 :            :     case T_UINT32: i = (type##_t)*(uint32_t*)(data); break;                    \
      49                 :            :     case T_INT64:  i = (type##_t)(int64_t)jl_load_ptraligned_i64(data); break; \
      50                 :            :     case T_UINT64: i = (type##_t)jl_load_ptraligned_i64(data); break;          \
      51                 :            :     case T_FLOAT:  i = (type##_t)*(float*)data; break;                         \
      52                 :            :     case T_DOUBLE: i = (type##_t)jl_load_ptraligned_f64(data); break;          \
      53                 :            :     }                                                                          \
      54                 :            :     return i;                                                                  \
      55                 :            : }
      56                 :            : 
      57   [ -  -  -  -  :         72 : CONV_TO_INTTYPE(int64)
          -  -  +  -  -  
                   -  - ]
      58   [ #  #  #  #  :          0 : CONV_TO_INTTYPE(int32)
          #  #  #  #  #  
                   #  # ]
      59   [ #  #  #  #  :          0 : CONV_TO_INTTYPE(uint32)
          #  #  #  #  #  
                   #  # ]
      60                 :            : 
      61                 :            : // this is needed to work around a possible compiler bug
      62                 :            : // casting negative floats and doubles to uint64. you need
      63                 :            : // to cast to int64 first.
      64                 :       2328 : uint64_t conv_to_uint64(void *data, numerictype_t tag)
      65                 :            : {
      66                 :       2328 :     uint64_t i=0;
      67   [ -  -  -  -  :       2328 :     switch (tag) {
          -  -  +  +  -  
                   -  - ]
      68                 :          0 :     case T_INT8:   i = (uint64_t)*(int8_t*)data; break;
      69                 :          0 :     case T_UINT8:  i = (uint64_t)*(uint8_t*)data; break;
      70                 :          0 :     case T_INT16:  i = (uint64_t)*(int16_t*)data; break;
      71                 :          0 :     case T_UINT16: i = (uint64_t)*(uint16_t*)data; break;
      72                 :          0 :     case T_INT32:  i = (uint64_t)*(int32_t*)data; break;
      73                 :          0 :     case T_UINT32: i = (uint64_t)*(uint32_t*)data; break;
      74                 :        682 :     case T_INT64:  i = (uint64_t)jl_load_ptraligned_i64(data); break;
      75                 :       1646 :     case T_UINT64: i = (uint64_t)jl_load_ptraligned_i64(data); break;
      76                 :          0 :     case T_FLOAT:
      77         [ #  # ]:          0 :         if (*(float*)data >= 0)
      78                 :          0 :             i = (uint64_t)*(float*)data;
      79                 :            :         else
      80                 :          0 :             i = (uint64_t)(int64_t)*(float*)data;
      81                 :          0 :         break;
      82                 :          0 :     case T_DOUBLE:
      83         [ #  # ]:          0 :         if (jl_load_ptraligned_f64(data) >= 0)
      84                 :          0 :             i = (uint64_t)jl_load_ptraligned_f64(data);
      85                 :            :         else
      86                 :          0 :             i = (uint64_t)(int64_t)jl_load_ptraligned_f64(data);
      87                 :          0 :         break;
      88                 :            :     }
      89                 :       2328 :     return i;
      90                 :            : }
      91                 :            : 
      92                 :     172158 : int cmp_same_lt(void *a, void *b, numerictype_t tag)
      93                 :            : {
      94   [ -  -  -  -  :     172158 :     switch (tag) {
          +  -  +  -  -  
                   -  - ]
      95                 :          0 :     case T_INT8:   return *(int8_t*)a < *(int8_t*)b;
      96                 :          0 :     case T_UINT8:  return *(uint8_t*)a < *(uint8_t*)b;
      97                 :          0 :     case T_INT16:  return *(int16_t*)a < *(int16_t*)b;
      98                 :          0 :     case T_UINT16: return *(uint16_t*)a < *(uint16_t*)b;
      99                 :      70320 :     case T_INT32:  return *(int32_t*)a < *(int32_t*)b;
     100                 :          0 :     case T_UINT32: return *(uint32_t*)a < *(uint32_t*)b;
     101                 :     101838 :     case T_INT64:  return (int64_t)jl_load_ptraligned_i64(a) < (int64_t)jl_load_ptraligned_i64(b);
     102                 :          0 :     case T_UINT64: return jl_load_ptraligned_i64(a) < jl_load_ptraligned_i64(b);
     103                 :          0 :     case T_FLOAT:  return *(float*)a < *(float*)b;
     104                 :          0 :     case T_DOUBLE: return jl_load_ptraligned_f64(a) < jl_load_ptraligned_f64(b);
     105                 :            :     }
     106                 :          0 :     return 0;
     107                 :            : }
     108                 :            : 
     109                 :  149425800 : int cmp_same_eq(void *a, void *b, numerictype_t tag)
     110                 :            : {
     111   [ -  -  -  -  :  149425800 :     switch (tag) {
          +  -  +  -  -  
                   +  - ]
     112                 :          0 :     case T_INT8:   return *(int8_t*)a == *(int8_t*)b;
     113                 :          0 :     case T_UINT8:  return *(uint8_t*)a == *(uint8_t*)b;
     114                 :          0 :     case T_INT16:  return *(int16_t*)a == *(int16_t*)b;
     115                 :          0 :     case T_UINT16: return *(uint16_t*)a == *(uint16_t*)b;
     116                 :  149306200 :     case T_INT32:  return *(int32_t*)a == *(int32_t*)b;
     117                 :          0 :     case T_UINT32: return *(uint32_t*)a == *(uint32_t*)b;
     118                 :     101844 :     case T_INT64:  return jl_load_ptraligned_i64(a) == jl_load_ptraligned_i64(b);
     119                 :          0 :     case T_UINT64: return jl_load_ptraligned_i64(a) == jl_load_ptraligned_i64(b);
     120                 :          0 :     case T_FLOAT:  return *(float*)a == *(float*)b;
     121                 :      17696 :     case T_DOUBLE: return jl_load_ptraligned_f64(a) == jl_load_ptraligned_f64(b);
     122                 :            :     }
     123                 :          0 :     return 0;
     124                 :            : }
     125                 :            : 
     126                 :     172158 : int cmp_lt(void *a, numerictype_t atag, void *b, numerictype_t btag)
     127                 :            : {
     128         [ +  - ]:     172158 :     if (atag==btag)
     129                 :     172158 :         return cmp_same_lt(a, b, atag);
     130                 :            : 
     131                 :          0 :     double da = conv_to_double(a, atag);
     132                 :          0 :     double db = conv_to_double(b, btag);
     133                 :            : 
     134                 :            :     // casting to double will only get the wrong answer for big int64s
     135                 :            :     // that differ in low bits
     136         [ #  # ]:          0 :     if (da < db)
     137                 :          0 :         return 1;
     138         [ #  # ]:          0 :     if (db < da)
     139                 :          0 :         return 0;
     140                 :            : 
     141         [ #  # ]:          0 :     if (atag == T_UINT64) {
     142         [ #  # ]:          0 :         if (btag == T_INT64) {
     143         [ #  # ]:          0 :             if ((int64_t)jl_load_ptraligned_i64(b) >= 0) {
     144                 :          0 :                 return (jl_load_ptraligned_i64(a) < jl_load_ptraligned_i64(b));
     145                 :            :             }
     146                 :          0 :             return ((int64_t)jl_load_ptraligned_i64(a) <
     147                 :          0 :                     (int64_t)jl_load_ptraligned_i64(b));
     148                 :            :         }
     149         [ #  # ]:          0 :         else if (btag == T_DOUBLE) {
     150         [ #  # ]:          0 :             if (db != db) return 0;
     151                 :          0 :             return (jl_load_ptraligned_i64(a) < (uint64_t)jl_load_ptraligned_f64(b));
     152                 :            :         }
     153                 :            :     }
     154         [ #  # ]:          0 :     else if (atag == T_INT64) {
     155         [ #  # ]:          0 :         if (btag == T_UINT64) {
     156         [ #  # ]:          0 :             if ((int64_t)jl_load_ptraligned_i64(a) >= 0) {
     157                 :          0 :                 return (jl_load_ptraligned_i64(a) < jl_load_ptraligned_i64(b));
     158                 :            :             }
     159                 :          0 :             return ((int64_t)jl_load_ptraligned_i64(a) <
     160                 :          0 :                     (int64_t)jl_load_ptraligned_i64(b));
     161                 :            :         }
     162         [ #  # ]:          0 :         else if (btag == T_DOUBLE) {
     163         [ #  # ]:          0 :             if (db != db) return 0;
     164                 :          0 :             return ((int64_t)jl_load_ptraligned_i64(a) < (int64_t)jl_load_ptraligned_f64(b));
     165                 :            :         }
     166                 :            :     }
     167         [ #  # ]:          0 :     if (btag == T_UINT64) {
     168         [ #  # ]:          0 :         if (atag == T_DOUBLE) {
     169         [ #  # ]:          0 :             if (da != da) return 0;
     170                 :          0 :             return (jl_load_ptraligned_i64(b) > (uint64_t)jl_load_ptraligned_f64(a));
     171                 :            :         }
     172                 :            :     }
     173         [ #  # ]:          0 :     else if (btag == T_INT64) {
     174         [ #  # ]:          0 :         if (atag == T_DOUBLE) {
     175         [ #  # ]:          0 :             if (da != da) return 0;
     176                 :          0 :             return ((int64_t)jl_load_ptraligned_i64(b) > (int64_t)jl_load_ptraligned_f64(a));
     177                 :            :         }
     178                 :            :     }
     179                 :          0 :     return 0;
     180                 :            : }
     181                 :            : 
     182                 :  149648400 : int cmp_eq(void *a, numerictype_t atag, void *b, numerictype_t btag,
     183                 :            :            int equalnans)
     184                 :            : {
     185                 :            :     union { double d; int64_t i64; } u, v;
     186   [ +  +  +  +  :  149648400 :     if (atag==btag && (!equalnans || atag < T_FLOAT))
                   +  - ]
     187                 :  149425800 :         return cmp_same_eq(a, b, atag);
     188                 :            : 
     189                 :     222704 :     double da = conv_to_double(a, atag);
     190                 :     222704 :     double db = conv_to_double(b, btag);
     191                 :            : 
     192   [ +  +  +  - ]:     222704 :     if ((int)atag >= T_FLOAT && (int)btag >= T_FLOAT) {
     193         [ -  + ]:       1368 :         if (equalnans) {
     194                 :          0 :             u.d = da; v.d = db;
     195                 :          0 :             return u.i64 == v.i64;
     196                 :            :         }
     197                 :       1368 :         return (da == db);
     198                 :            :     }
     199                 :            : 
     200         [ +  - ]:     221336 :     if (da != db)
     201                 :     221336 :         return 0;
     202                 :            : 
     203         [ #  # ]:          0 :     if (atag == T_UINT64) {
     204                 :            :         // this is safe because if a had been bigger than S64_MAX,
     205                 :            :         // we would already have concluded that it's bigger than b.
     206         [ #  # ]:          0 :         if (btag == T_INT64) {
     207                 :          0 :             return (jl_load_ptraligned_i64(a) == jl_load_ptraligned_i64(b));
     208                 :            :         }
     209         [ #  # ]:          0 :         else if (btag == T_DOUBLE) {
     210                 :          0 :             return (jl_load_ptraligned_i64(a) == (uint64_t)(int64_t)jl_load_ptraligned_f64(b));
     211                 :            :         }
     212                 :            :     }
     213         [ #  # ]:          0 :     else if (atag == T_INT64) {
     214         [ #  # ]:          0 :         if (btag == T_UINT64) {
     215                 :          0 :             return (jl_load_ptraligned_i64(a) == jl_load_ptraligned_i64(b));
     216                 :            :         }
     217         [ #  # ]:          0 :         else if (btag == T_DOUBLE) {
     218                 :          0 :             return ((int64_t)jl_load_ptraligned_i64(a) == (int64_t)jl_load_ptraligned_f64(b));
     219                 :            :         }
     220                 :            :     }
     221         [ #  # ]:          0 :     else if (btag == T_UINT64) {
     222         [ #  # ]:          0 :         assert(atag != T_INT64); // Taken care of above
     223         [ #  # ]:          0 :         if (atag == T_DOUBLE) {
     224                 :          0 :             return (jl_load_ptraligned_i64(b) == (uint64_t)(int64_t)jl_load_ptraligned_f64(a));
     225                 :            :         }
     226                 :            :     }
     227         [ #  # ]:          0 :     else if (btag == T_INT64) {
     228         [ #  # ]:          0 :         assert(atag != T_UINT64); // Taken care of above
     229         [ #  # ]:          0 :         if (atag == T_DOUBLE) {
     230                 :          0 :             return ((int64_t)jl_load_ptraligned_i64(b) == (int64_t)jl_load_ptraligned_f64(a));
     231                 :            :         }
     232                 :            :     }
     233                 :          0 :     return 1;
     234                 :            : }
     235                 :            : 
     236                 :            : #ifdef __cplusplus
     237                 :            : }
     238                 :            : #endif

Generated by: LCOV version 1.14