zig.h: get no int128 path working on non-msvc

This commit is contained in:
Jacob Young 2023-01-03 00:22:39 -05:00
parent 1a1598daf0
commit b76fed8206

View file

@ -1357,10 +1357,10 @@ typedef struct { zig_align(16) int64_t hi; uint64_t lo; } zig_i128;
#define zig_make_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) }) #define zig_make_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) })
#define zig_make_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) }) #define zig_make_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) })
#if _MSC_VER #if _MSC_VER /* MSVC doesn't allow struct literals in constant expressions */
#define zig_make_constant_u128(hi, lo) { .h##i = (hi), .l##o = (lo) } #define zig_make_constant_u128(hi, lo) { .h##i = (hi), .l##o = (lo) }
#define zig_make_constant_i128(hi, lo) { .h##i = (hi), .l##o = (lo) } #define zig_make_constant_i128(hi, lo) { .h##i = (hi), .l##o = (lo) }
#else #else /* But non-MSVC doesn't like the unprotected commas */
#define zig_make_constant_u128(hi, lo) zig_make_u128(hi, lo) #define zig_make_constant_u128(hi, lo) zig_make_u128(hi, lo)
#define zig_make_constant_i128(hi, lo) zig_make_i128(hi, lo) #define zig_make_constant_i128(hi, lo) zig_make_i128(hi, lo)
#endif #endif
@ -1421,6 +1421,11 @@ static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
return lhs << rhs; return lhs << rhs;
} }
static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0);
return ((lhs ^ sign_mask) >> rhs) ^ sign_mask;
}
static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
return lhs << rhs; return lhs << rhs;
} }
@ -1496,6 +1501,12 @@ static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs }; return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
} }
static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
if (rhs == UINT8_C(0)) return lhs;
if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = zig_shr_i64(lhs.hi, 63), .lo = zig_shr_i64(lhs.hi, (rhs - UINT8_C(64))) };
return (zig_i128){ .hi = zig_shr_i64(lhs.hi, rhs), .lo = lhs.lo >> rhs | (uint64_t)lhs.hi << (UINT8_C(64) - rhs) };
}
static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) { static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
if (rhs == UINT8_C(0)) return lhs; if (rhs == UINT8_C(0)) return lhs;
if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 }; if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
@ -1527,14 +1538,14 @@ static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {
} }
zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs); zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs);
static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
return zig_bitcast_u128(__multi3(zig_bitcast_i128(lhs), zig_bitcast_i128(rhs)));
}
static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) { static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
return __multi3(lhs, rhs); return __multi3(lhs, rhs);
} }
static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
return zig_bitcast_u128(zig_mul_i128(zig_bitcast_i128(lhs), zig_bitcast_i128(rhs)));
}
zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs); zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs);
static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) { static zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) {
return __udivti3(lhs, rhs); return __udivti3(lhs, rhs);
@ -1557,7 +1568,7 @@ static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {
static inline zig_i128 zig_mod_i128(zig_i128 lhs, zig_i128 rhs) { static inline zig_i128 zig_mod_i128(zig_i128 lhs, zig_i128 rhs) {
zig_i128 rem = zig_rem_i128(lhs, rhs); zig_i128 rem = zig_rem_i128(lhs, rhs);
return zig_add_i128(rem, (((lhs.hi ^ rhs.hi) & rem.hi) < INT64_C(0) ? rhs : zig_make_i128(0, 0))); return zig_add_i128(rem, ((lhs.hi ^ rhs.hi) & rem.hi) < INT64_C(0) ? rhs : zig_make_i128(0, 0));
} }
static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) { static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) {
@ -1589,11 +1600,6 @@ static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) {
return zig_cmp_i128(lhs, rhs) > INT32_C(0) ? lhs : rhs; return zig_cmp_i128(lhs, rhs) > INT32_C(0) ? lhs : rhs;
} }
static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
zig_i128 sign_mask = zig_cmp_i128(lhs, zig_make_i128(0, 0)) < INT32_C(0) ? zig_sub_i128(zig_make_i128(0, 0), zig_make_i128(0, 1)) : zig_make_i128(0, 0);
return zig_xor_i128(zig_bitcast_i128(zig_shr_u128(zig_bitcast_u128(zig_xor_i128(lhs, sign_mask)), rhs)), sign_mask);
}
static inline zig_u128 zig_wrap_u128(zig_u128 val, uint8_t bits) { static inline zig_u128 zig_wrap_u128(zig_u128 val, uint8_t bits) {
return zig_and_u128(val, zig_maxInt_u(128, bits)); return zig_and_u128(val, zig_maxInt_u(128, bits));
} }
@ -1716,50 +1722,28 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint
#else /* zig_has_int128 */ #else /* zig_has_int128 */
static inline bool zig_overflow_u128(bool overflow, zig_u128 full_res, uint8_t bits) {
return overflow ||
zig_cmp_u128(full_res, zig_minInt_u(128, bits)) < INT32_C(0) ||
zig_cmp_u128(full_res, zig_maxInt_u(128, bits)) > INT32_C(0);
}
static inline bool zig_overflow_i128(bool overflow, zig_i128 full_res, uint8_t bits) {
return overflow ||
zig_cmp_i128(full_res, zig_minInt_i(128, bits)) < INT32_C(0) ||
zig_cmp_i128(full_res, zig_maxInt_i(128, bits)) > INT32_C(0);
}
static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
zig_u128 full_res; uint64_t hi;
bool overflow = bool overflow = zig_addo_u64(&hi, lhs.hi, rhs.hi, bits - 64);
zig_addo_u64(&full_res.hi, lhs.hi, rhs.hi, 64) | return overflow ^ zig_addo_u64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);
zig_addo_u64(&full_res.hi, full_res.hi, zig_addo_u64(&full_res.lo, lhs.lo, rhs.lo, 64), 64);
*res = zig_wrap_u128(full_res, bits);
return zig_overflow_u128(overflow, full_res, bits);
} }
zig_extern zig_i128 __addoti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
int overflow_int; int64_t hi;
zig_i128 full_res = __addoti4(lhs, rhs, &overflow_int); bool overflow = zig_addo_i64(&hi, lhs.hi, rhs.hi, bits - 64);
*res = zig_wrap_i128(full_res, bits); return overflow ^ zig_addo_i64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);
return zig_overflow_i128(overflow_int, full_res, bits);
} }
static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
zig_u128 full_res; uint64_t hi;
bool overflow = bool overflow = zig_subo_u64(&hi, lhs.hi, rhs.hi, bits - 64);
zig_subo_u64(&full_res.hi, lhs.hi, rhs.hi, 64) | return overflow ^ zig_subo_u64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);
zig_subo_u64(&full_res.hi, full_res.hi, zig_subo_u64(&full_res.lo, lhs.lo, rhs.lo, 64), 64);
*res = zig_wrap_u128(full_res, bits);
return zig_overflow_u128(overflow, full_res, bits);
} }
zig_extern zig_i128 __suboti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
int overflow_int; int64_t hi;
zig_i128 full_res = __suboti4(lhs, rhs, &overflow_int); bool overflow = zig_subo_i64(&hi, lhs.hi, rhs.hi, bits - 64);
*res = zig_wrap_i128(full_res, bits); return overflow ^ zig_subo_i64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, 64), bits - 64);
return zig_overflow_i128(overflow_int, full_res, bits);
} }
static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) { static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
@ -1772,8 +1756,11 @@ zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) { static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
int overflow_int; int overflow_int;
zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int); zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);
bool overflow = overflow_int != 0 ||
zig_cmp_i128(full_res, zig_minInt_i(128, bits)) < INT32_C(0) ||
zig_cmp_i128(full_res, zig_maxInt_i(128, bits)) > INT32_C(0);
*res = zig_wrap_i128(full_res, bits); *res = zig_wrap_i128(full_res, bits);
return zig_overflow_i128(overflow_int, full_res, bits); return overflow;
} }
#endif /* zig_has_int128 */ #endif /* zig_has_int128 */
@ -1794,17 +1781,12 @@ static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
zig_u128 res; zig_u128 res;
if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) >= INT32_C(0)) if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) >= INT32_C(0))
return zig_cmp_u128(lhs, zig_make_u128(0, 0)) != INT32_C(0) ? zig_maxInt_u(128, bits) : lhs; return zig_cmp_u128(lhs, zig_make_u128(0, 0)) != INT32_C(0) ? zig_maxInt_u(128, bits) : lhs;
return zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits) ? zig_maxInt_u(128, bits) : res;
#if zig_has_int128
return zig_shlo_u128(&res, lhs, (uint8_t)rhs, bits) ? zig_maxInt_u(128, bits) : res;
#else
return zig_shlo_u128(&res, lhs, (uint8_t)rhs.lo, bits) ? zig_maxInt_u(128, bits) : res;
#endif
} }
static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) { static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
zig_i128 res; zig_i128 res;
if (zig_cmp_u128(zig_bitcast_u128(rhs), zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, zig_lo_i128(rhs), bits)) return res; if (zig_cmp_u128(zig_bitcast_u128(rhs), zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_i128(rhs), bits)) return res;
return zig_cmp_i128(lhs, zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits); return zig_cmp_i128(lhs, zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);
} }