aboutsummaryrefslogtreecommitdiff
path: root/src/bigint.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-09-14 02:48:16 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-09-14 02:48:16 -0400
commit5989b88352c472cd146f7205cd46927bfded1108 (patch)
treee0d8a7fb75bd6225e9705d34484a8d14ceeccf18 /src/bigint.cpp
parent75b1c71cb300b88625cd93ebf21d41361b65e2c7 (diff)
downloadzig-5989b88352c472cd146f7205cd46927bfded1108.tar.gz
zig-5989b88352c472cd146f7205cd46927bfded1108.zip
do not depend on __int128
closes #477
Diffstat (limited to 'src/bigint.cpp')
-rw-r--r--src/bigint.cpp41
1 files changed, 17 insertions, 24 deletions
diff --git a/src/bigint.cpp b/src/bigint.cpp
index 05a52ec3bc..d12c8d0759 100644
--- a/src/bigint.cpp
+++ b/src/bigint.cpp
@@ -142,21 +142,6 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) {
dest->is_negative = false;
}
-void bigint_init_u128(BigInt *dest, uint128_t x) {
- uint64_t low = (uint64_t)(x & UINT64_MAX);
- uint64_t high = (uint64_t)(x >> 64);
-
- if (high == 0) {
- return bigint_init_unsigned(dest, low);
- }
-
- dest->digit_count = 2;
- dest->data.digits = allocate_nonzero<uint64_t>(2);
- dest->data.digits[0] = low;
- dest->data.digits[1] = high;
- dest->is_negative = false;
-}
-
void bigint_init_signed(BigInt *dest, int64_t x) {
if (x >= 0) {
return bigint_init_unsigned(dest, x);
@@ -580,16 +565,24 @@ void bigint_sub_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t
return bigint_add_wrap(dest, op1, &op2_negated, bit_count, is_signed);
}
-static void mul_overflow(uint64_t x, uint64_t y, uint64_t *result, uint64_t *carry) {
- if (!mul_u64_overflow(x, y, result)) {
- *carry = 0;
- return;
- }
+static void mul_overflow(uint64_t op1, uint64_t op2, uint64_t *lo, uint64_t *hi) {
+ uint64_t u1 = (op1 & 0xffffffff);
+ uint64_t v1 = (op2 & 0xffffffff);
+ uint64_t t = (u1 * v1);
+ uint64_t w3 = (t & 0xffffffff);
+ uint64_t k = (t >> 32);
+
+ op1 >>= 32;
+ t = (op1 * v1) + k;
+ k = (t & 0xffffffff);
+ uint64_t w1 = (t >> 32);
+
+ op2 >>= 32;
+ t = (u1 * op2) + k;
+ k = (t >> 32);
- uint128_t big_x = x;
- uint128_t big_y = y;
- uint128_t big_result = big_x * big_y;
- *carry = big_result >> 64;
+ *hi = (op1 * op2) + w1 + k;
+ *lo = (t << 32) + w3;
}
static void mul_scalar(BigInt *dest, const BigInt *op, uint64_t scalar) {