authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2022-12-14 00:09:44-05:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2023-01-01 16:44:28-05:00
logf155ef2f4b3243fd31ae910c66587d672402144e
treea36f552390329c47c5044a3d83c9dcc132610e44
parentfbd3459a520f28d32e45a0f8d472a2d0b471e36e

cbe: implementing 128 bit math functions for !zig_has_int128

- Add addo_(i|u)128, subo_(i|u)128, mulo_(i|u)128, - Move zig_shlo_(i|u)128 into common code - Fixup zig_shls_i128 passing rhs as 128

1 files changed, 71 insertions(+), 21 deletions(-)

lib/zig.h+71-21
...@@ -1445,18 +1445,6 @@ static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {...@@ -1445,18 +1445,6 @@ static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
14451445
1446#if zig_has_int1281446#if zig_has_int128
14471447
1448static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, zig_u8 rhs, zig_u8 bits) {
1449 *res = zig_shlw_u128(lhs, rhs, bits);
1450 return zig_cmp_u128(lhs, zig_shr_u128(zig_maxInt(u128, bits), rhs)) > zig_as_i32(0);
1451}
1452
1453static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, zig_u8 rhs, zig_u8 bits) {
1454 *res = zig_shlw_i128(lhs, rhs, bits);
1455 zig_i128 mask = zig_bitcast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - zig_as_u8(1)));
1456 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_as_i128(0, 0)) != zig_as_i32(0) &&
1457 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != zig_as_i32(0);
1458}
1459
1460static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {1448static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1461#if zig_has_builtin(add_overflow)1449#if zig_has_builtin(add_overflow)
1462 zig_u128 full_res;1450 zig_u128 full_res;
...@@ -1537,18 +1525,80 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_...@@ -1537,18 +1525,80 @@ static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_
15371525
1538#else /* zig_has_int128 */1526#else /* zig_has_int128 */
15391527
1540/* static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs) { */1528static inline bool zig_overflow_u128(bool overflow, zig_u128 full_res, zig_u8 bits) {
1541/* return zig_addo_u64(&res->hi, lhs.hi, rhs.hi, UINT64_MAX) | */1529 return overflow ||
1542/* zig_addo_u64(&res->hi, res->hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT64_MAX)); */1530 zig_cmp_u128(full_res, zig_minInt(u128, bits)) < zig_as_i32(0) ||
1543/* } */1531 zig_cmp_u128(full_res, zig_maxInt(u128, bits)) > zig_as_i32(0);
1532}
1533
1534static inline bool zig_overflow_i128(bool overflow, zig_i128 full_res, zig_u8 bits) {
1535 return overflow ||
1536 zig_cmp_i128(full_res, zig_minInt(i128, bits)) < zig_as_i32(0) ||
1537 zig_cmp_i128(full_res, zig_maxInt(i128, bits)) > zig_as_i32(0);
1538}
1539
1540static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1541 zig_u128 full_res;
1542 bool overflow =
1543 zig_addo_u64(&full_res.hi, lhs.hi, rhs.hi, 64) |
1544 zig_addo_u64(&full_res.hi, full_res.hi, zig_addo_u64(&full_res.lo, lhs.lo, rhs.lo, 64), 64);
1545 *res = zig_wrap_u128(full_res, bits);
1546 return zig_overflow_u128(overflow, full_res, bits);
1547}
1548
1549zig_extern zig_i128 __addoti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
1550static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1551 zig_c_int overflow_int;
1552 zig_i128 full_res = __addoti4(lhs, rhs, &overflow_int);
1553 *res = zig_wrap_i128(full_res, bits);
1554 return zig_overflow_i128(overflow_int, full_res, bits);
1555}
1556
1557static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1558 zig_u128 full_res;
1559 bool overflow =
1560 zig_subo_u64(&full_res.hi, lhs.hi, rhs.hi, 64) |
1561 zig_subo_u64(&full_res.hi, full_res.hi, zig_subo_u64(&full_res.lo, lhs.lo, rhs.lo, 64), 64);
1562 *res = zig_wrap_u128(full_res, bits);
1563 return zig_overflow_u128(overflow, full_res, bits);
1564}
1565
1566zig_extern zig_i128 __suboti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
1567static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1568 zig_c_int overflow_int;
1569 zig_i128 full_res = __suboti4(lhs, rhs, &overflow_int);
1570 *res = zig_wrap_i128(full_res, bits);
1571 return zig_overflow_i128(overflow_int, full_res, bits);
1572}
1573
1574static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1575 *res = zig_mulw_u128(lhs, rhs, bits);
1576 return zig_cmp_u128(*res, zig_as_u128(0, 0)) != zig_as_i32(0) &&
1577 zig_cmp_u128(lhs, zig_div_trunc_u128(zig_maxInt(u128, bits), rhs)) > zig_as_i32(0);
1578}
15441579
1545/* static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs) { */1580zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
1546/* return zig_subo_u64(&res->hi, lhs.hi, rhs.hi, UINT64_MAX) | */1581static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1547/* zig_subo_u64(&res->hi, res->hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT64_MAX)); */1582 zig_c_int overflow_int;
1548/* } */1583 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);
1584 *res = zig_wrap_i128(full_res, bits);
1585 return zig_overflow_i128(overflow_int, full_res, bits);
1586}
15491587
1550#endif /* zig_has_int128 */1588#endif /* zig_has_int128 */
15511589
1590static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, zig_u8 rhs, zig_u8 bits) {
1591 *res = zig_shlw_u128(lhs, rhs, bits);
1592 return zig_cmp_u128(lhs, zig_shr_u128(zig_maxInt(u128, bits), rhs)) > zig_as_i32(0);
1593}
1594
1595static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, zig_u8 rhs, zig_u8 bits) {
1596 *res = zig_shlw_i128(lhs, rhs, bits);
1597 zig_i128 mask = zig_bitcast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - zig_as_u8(1)));
1598 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_as_i128(0, 0)) != zig_as_i32(0) &&
1599 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != zig_as_i32(0);
1600}
1601
1552static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {1602static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
1553 zig_u128 res;1603 zig_u128 res;
1554 if (zig_cmp_u128(rhs, zig_as_u128(0, bits)) >= zig_as_i32(0))1604 if (zig_cmp_u128(rhs, zig_as_u128(0, bits)) >= zig_as_i32(0))
...@@ -1563,7 +1613,7 @@ static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {...@@ -1563,7 +1613,7 @@ static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) {
15631613
1564static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {1614static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
1565 zig_i128 res;1615 zig_i128 res;
1566 if (zig_cmp_u128(zig_bitcast_u128(rhs), zig_as_u128(0, bits)) < zig_as_i32(0) && !zig_shlo_i128(&res, lhs, rhs, bits)) return res;1616 if (zig_cmp_u128(zig_bitcast_u128(rhs), zig_as_u128(0, bits)) < zig_as_i32(0) && !zig_shlo_i128(&res, lhs, zig_lo_i128(rhs), bits)) return res;
1567 return zig_cmp_i128(lhs, zig_as_i128(0, 0)) < zig_as_i32(0) ? zig_minInt(i128, bits) : zig_maxInt(i128, bits);1617 return zig_cmp_i128(lhs, zig_as_i128(0, 0)) < zig_as_i32(0) ? zig_minInt(i128, bits) : zig_maxInt(i128, bits);
1568}1618}
15691619