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