mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
zig.h: get no int128 path working on non-msvc
This commit is contained in:
parent
1a1598daf0
commit
b76fed8206
1 changed files with 36 additions and 54 deletions
90
lib/zig.h
90
lib/zig.h
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue