authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-13 21:06:53-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-16 13:55:26-07:00
loga84be7e988c91606bc42e1e1c8a34bbdcdb8a3f1
tree325f36e011eb81c7a2955100fb4654ff652156a7
parent160aa4c11dcb0413796d08fd623ce7bbeabaf04b

zig.h: improve overflow shl

* zig_addo_u128: fix type-o * redo the shift-left overflow inline functions. no need to depend on compiler-rt.

1 files changed, 73 insertions(+), 125 deletions(-)

src/link/C/zig.h+73-125
...@@ -633,13 +633,13 @@ static inline uint64_t zig_addo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, u...@@ -633,13 +633,13 @@ static inline uint64_t zig_addo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, u
633}633}
634634
635static inline uint128_t zig_addo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) {635static inline uint128_t zig_addo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) {
636 bool overflow;636 int overflow;
637 *res = __uaddoti4(lhs, rhs, &overflow);637 *res = __uaddoti4(lhs, rhs, &overflow);
638 if (*res > max && !overflow) {638 if (*res > max && overflow == 0) {
639 *res -= max - 1;639 *res -= max - 1;
640 return true;640 return true;
641 }641 }
642 return overflow;642 return overflow != 0;
643}643}
644644
645static inline bool zig_subo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) {645static inline bool zig_subo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) {
...@@ -1095,128 +1095,6 @@ static inline uint128_t zig_mulo_u128(uint128_t lhs, uint128_t rhs, uint128_t *r...@@ -1095,128 +1095,6 @@ static inline uint128_t zig_mulo_u128(uint128_t lhs, uint128_t rhs, uint128_t *r
1095 return overflow != 0;1095 return overflow != 0;
1096}1096}
10971097
1098static inline bool zig_shlo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) {
1099 int16_t big_result = (int16_t)lhs << (int16_t)rhs;
1100 if (big_result > max) {
1101 *res = big_result - ((int16_t)max - (int16_t)min);
1102 return true;
1103 }
1104 if (big_result < min) {
1105 *res = big_result + ((int16_t)max - (int16_t)min);
1106 return true;
1107 }
1108 *res = big_result;
1109 return false;
1110}
1111
1112static inline bool zig_shlo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) {
1113 int32_t big_result = (int32_t)lhs << (int32_t)rhs;
1114 if (big_result > max) {
1115 *res = big_result - ((int32_t)max - (int32_t)min);
1116 return true;
1117 }
1118 if (big_result < min) {
1119 *res = big_result + ((int32_t)max - (int32_t)min);
1120 return true;
1121 }
1122 *res = big_result;
1123 return false;
1124}
1125
1126static inline bool zig_shlo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) {
1127 int64_t big_result = (int64_t)lhs << (int64_t)rhs;
1128 if (big_result > max) {
1129 *res = big_result - ((int64_t)max - (int64_t)min);
1130 return true;
1131 }
1132 if (big_result < min) {
1133 *res = big_result + ((int64_t)max - (int64_t)min);
1134 return true;
1135 }
1136 *res = big_result;
1137 return false;
1138}
1139
1140static inline bool zig_shlo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) {
1141 int overflow;
1142 *res = __shlodi4(lhs, rhs, &overflow);
1143 if (overflow == 0) {
1144 if (*res > max) {
1145 // TODO adjust the result to be the truncated bits
1146 return true;
1147 } else if (*res < min) {
1148 // TODO adjust the result to be the truncated bits
1149 return true;
1150 }
1151 }
1152 return overflow != 0;
1153}
1154
1155static inline bool zig_shlo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) {
1156 int overflow;
1157 *res = __shloti4(lhs, rhs, &overflow);
1158 if (overflow == 0) {
1159 if (*res > max) {
1160 // TODO adjust the result to be the truncated bits
1161 return true;
1162 } else if (*res < min) {
1163 // TODO adjust the result to be the truncated bits
1164 return true;
1165 }
1166 }
1167 return overflow != 0;
1168}
1169
1170static inline bool zig_shlo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) {
1171 uint16_t big_result = (uint16_t)lhs << (uint16_t)rhs;
1172 if (big_result > max) {
1173 *res = big_result - max - 1;
1174 return true;
1175 }
1176 *res = big_result;
1177 return false;
1178}
1179
1180static inline uint16_t zig_shlo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) {
1181 uint32_t big_result = (uint32_t)lhs << (uint32_t)rhs;
1182 if (big_result > max) {
1183 *res = big_result - max - 1;
1184 return true;
1185 }
1186 *res = big_result;
1187 return false;
1188}
1189
1190static inline uint32_t zig_shlo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) {
1191 uint64_t big_result = (uint64_t)lhs << (uint64_t)rhs;
1192 if (big_result > max) {
1193 *res = big_result - max - 1;
1194 return true;
1195 }
1196 *res = big_result;
1197 return false;
1198}
1199
1200static inline uint64_t zig_shlo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) {
1201 int overflow;
1202 *res = __ushlodi4(lhs, rhs, &overflow);
1203 if (*res > max && overflow == 0) {
1204 *res -= max - 1;
1205 return true;
1206 }
1207 return overflow != 0;
1208}
1209
1210static inline uint128_t zig_shlo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) {
1211 int overflow;
1212 *res = __ushloti4(lhs, rhs, &overflow);
1213 if (*res > max && overflow == 0) {
1214 *res -= max - 1;
1215 return true;
1216 }
1217 return overflow != 0;
1218}
1219
1220static inline float zig_bitcast_f32_u32(uint32_t arg) {1098static inline float zig_bitcast_f32_u32(uint32_t arg) {
1221 float dest;1099 float dest;
1222 memcpy(&dest, &arg, sizeof dest);1100 memcpy(&dest, &arg, sizeof dest);
...@@ -1429,6 +1307,76 @@ static inline int zig_popcount_u128(uint128_t value, uint8_t zig_type_bit_width)...@@ -1429,6 +1307,76 @@ static inline int zig_popcount_u128(uint128_t value, uint8_t zig_type_bit_width)
14291307
1430#define zig_popcount_i128 zig_popcount_u1281308#define zig_popcount_i128 zig_popcount_u128
14311309
1310static inline bool zig_shlo_i8(int8_t lhs, int8_t rhs, int8_t *res, uint8_t bits) {
1311 *res = lhs << rhs;
1312 if (zig_clz_i8(lhs, bits) >= rhs) return false;
1313 *res &= UINT8_MAX >> (8 - bits);
1314 return true;
1315}
1316
1317static inline bool zig_shlo_i16(int16_t lhs, int16_t rhs, int16_t *res, uint8_t bits) {
1318 *res = lhs << rhs;
1319 if (zig_clz_i16(lhs, bits) >= rhs) return false;
1320 *res &= UINT16_MAX >> (16 - bits);
1321 return true;
1322}
1323
1324static inline bool zig_shlo_i32(int32_t lhs, int32_t rhs, int32_t *res, uint8_t bits) {
1325 *res = lhs << rhs;
1326 if (zig_clz_i32(lhs, bits) >= rhs) return false;
1327 *res &= UINT32_MAX >> (32 - bits);
1328 return true;
1329}
1330
1331static inline bool zig_shlo_i64(int64_t lhs, int64_t rhs, int64_t *res, uint8_t bits) {
1332 *res = lhs << rhs;
1333 if (zig_clz_i64(lhs, bits) >= rhs) return false;
1334 *res &= UINT64_MAX >> (64 - bits);
1335 return true;
1336}
1337
1338static inline bool zig_shlo_i128(int128_t lhs, int128_t rhs, int128_t *res, uint8_t bits) {
1339 *res = lhs << rhs;
1340 if (zig_clz_i128(lhs, bits) >= rhs) return false;
1341 *res &= UINT128_MAX >> (128 - bits);
1342 return true;
1343}
1344
1345static inline bool zig_shlo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t bits) {
1346 *res = lhs << rhs;
1347 if (zig_clz_u8(lhs, bits) >= rhs) return false;
1348 *res &= UINT8_MAX >> (8 - bits);
1349 return true;
1350}
1351
1352static inline uint16_t zig_shlo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint8_t bits) {
1353 *res = lhs << rhs;
1354 if (zig_clz_u16(lhs, bits) >= rhs) return false;
1355 *res &= UINT16_MAX >> (16 - bits);
1356 return true;
1357}
1358
1359static inline uint32_t zig_shlo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint8_t bits) {
1360 *res = lhs << rhs;
1361 if (zig_clz_u32(lhs, bits) >= rhs) return false;
1362 *res &= UINT32_MAX >> (32 - bits);
1363 return true;
1364}
1365
1366static inline uint64_t zig_shlo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint8_t bits) {
1367 *res = lhs << rhs;
1368 if (zig_clz_u64(lhs, bits) >= rhs) return false;
1369 *res &= UINT64_MAX >> (64 - bits);
1370 return true;
1371}
1372
1373static inline uint128_t zig_shlo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint8_t bits) {
1374 *res = lhs << rhs;
1375 if (zig_clz_u128(lhs, bits) >= rhs) return false;
1376 *res &= UINT128_MAX >> (128 - bits);
1377 return true;
1378}
1379
1432#define zig_sign_extend(T) \1380#define zig_sign_extend(T) \
1433 static inline T zig_sign_extend_##T(T value, uint8_t zig_type_bit_width) { \1381 static inline T zig_sign_extend_##T(T value, uint8_t zig_type_bit_width) { \
1434 const T m = (T)1 << (T)(zig_type_bit_width - 1); \1382 const T m = (T)1 << (T)(zig_type_bit_width - 1); \