diff --git a/src/private/bithacks.nim b/src/private/bithacks.nim index a92c498..7735608 100644 --- a/src/private/bithacks.nim +++ b/src/private/bithacks.nim @@ -44,6 +44,9 @@ proc bit_length*[T: MpUint](n: T): int {.noSideEffect.}= const maxHalfRepr = n.lo.type.sizeof * 8 - 1 + # Changing the following to an if expression somehow transform the whole ASM to 5 branches + # instead of the 4 expected (with the inline ASM from bit_length_impl) + # Also there does not seems to be a way to generate a conditional mov if n.hi.bit_length == 0: n.lo.bit_length else: diff --git a/src/uint_binary_ops.nim b/src/uint_binary_ops.nim index 6f5cf2b..b4e927f 100644 --- a/src/uint_binary_ops.nim +++ b/src/uint_binary_ops.nim @@ -114,16 +114,11 @@ proc divmod*[T: BaseUint](x, y: T): tuple[quot, rem: T] {.noSideEffect.}= when x.lo is MpUInt: const one = T(lo: getSubType(T)(1)) - const mpOne = one else: const one: getSubType(T) = 1 - const mpOne = T(lo: getSubType(T)(1)) - if y == zero: + if unlikely(y.isZero): raise newException(DivByZeroError, "You attempted to divide by zero") - elif y == mpOne: - result.quot = x - return var shift = x.bit_length - y.bit_length diff --git a/src/uint_comparison.nim b/src/uint_comparison.nim index 6206d4a..58783f5 100644 --- a/src/uint_comparison.nim +++ b/src/uint_comparison.nim @@ -11,3 +11,9 @@ proc `<=`*[T: MpUint](x, y: T): bool {.noSideEffect, noInit, inline.}= if x == y: return true x < y + +proc isZero[T: SomeUnsignedInt](n: T): bool {.noSideEffect,inline.} = + n == 0.T + +proc isZero*(n: MpUint): bool {.noSideEffect,inline.} = + n.lo.isZero and n.hi.isZero