small quality of life fix + auto conversion of booleans

This commit is contained in:
mratsim 2018-02-16 21:07:51 +01:00
parent 834ff19a25
commit a8f50c4dbe
5 changed files with 30 additions and 19 deletions

View File

@ -11,4 +11,4 @@ export uint_type,
uint_init,
uint_bitwise_ops,
uint_binary_ops,
uint_comparison
uint_comparison

View File

@ -4,6 +4,11 @@
import ../uint_type,
macros
macro getSubType*(T: typedesc): untyped =
## Returns the subtype of a generic type
## MpUint[uint32] --> uint32
getTypeInst(T)[1][1]
proc bit_length*[T: BaseUint](n: T): int {.noSideEffect.}=
## Calculates how many bits are necessary to represent the number
@ -54,11 +59,6 @@ proc asDoubleUint*[T: BaseUint](n: T): auto {.noSideEffect, inline.} =
n.asUint.Double
macro getSubType*(T: typedesc): untyped =
## Returns the subtype of a generic type
## MpUint[uint32] --> uint32
getTypeInst(T)[1][1]
proc toMpUint*[T: SomeInteger](n: T): auto {.noSideEffect, inline.} =
## Cast an integer to the corresponding size MpUint

View File

@ -10,11 +10,11 @@ proc `+=`*[T: MpUint](x: var T, y: T) {.noSideEffect.}=
#
# Optimized assembly should contain adc instruction (add with carry)
# Clang on MacOS does with the -d:release switch and MpUint[uint32] (uint64)
type Base = type x.lo
type MpBase = type x.lo
let tmp = x.lo
x.lo += y.lo
x.hi += (x.lo < tmp).Base + y.hi
x.hi += MpBase(x.lo < tmp) + y.hi
proc `+`*[T: MpUint](x, y: T): T {.noSideEffect, noInit, inline.}=
# Addition for multi-precision unsigned int
@ -26,11 +26,11 @@ proc `-=`*[T: MpUint](x: var T, y: T) {.noSideEffect.}=
#
# Optimized assembly should contain sbb instruction (substract with borrow)
# Clang on MacOS does with the -d:release switch and MpUint[uint32] (uint64)
type MPBase = type x.lo
type MpBase = type x.lo
let tmp = x.lo
x.lo -= y.lo
x.hi -= (x.lo > tmp).MPBase + y.hi
x.hi -= MpBase(x.lo > tmp) + y.hi
proc `-`*[T: MpUint](x, y: T): T {.noSideEffect, noInit, inline.}=
# Substraction for multi-precision unsigned int
@ -79,7 +79,7 @@ template naiveMulImpl[T: MpUint](x, y: T): MpUint[T] =
# - More total operations means more register moves
let # cannot be const, compile-time sizeof only works for simple types
size = (T.sizeof * 8)
size = T.sizeof * 8
halfSize = size div 2
let
z0 = naiveMul(x.lo, y.lo)
@ -104,4 +104,5 @@ proc naiveMul[T: BaseUint](x, y: T): MpUint[T] {.noSideEffect, noInit, inline.}=
naiveMulImpl(x.toMpUint, y.toMpUint)
else:
# Case: at least uint128 * uint128 --> uint256
naiveMulImpl(x, y)
naiveMulImpl(x, y)

View File

@ -35,10 +35,10 @@ proc `shl`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}=
return x
let # cannot be const, compile-time sizeof only works for simple types
size = (T.sizeof * 8)
size = T.sizeof * 8
halfSize = size div 2
type Sub = getSubType T
type Sub = type x.lo
if y < halfSize:
result.hi = (x.hi shl y) or (x.lo shr (halfSize - y))
@ -54,10 +54,10 @@ proc `shr`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}=
return x
let # cannot be const, compile-time sizeof only works for simple types
size = (T.sizeof * 8)
size = T.sizeof * 8
halfSize = size div 2
type Sub = getSubType T
type Sub = type x.lo
if y < halfSize:
result.lo = (x.lo shr y) or (x.hi shl (halfSize - y))
@ -80,7 +80,7 @@ proc `shr`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}=
# proc `shl`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}=
# ## Compute the `shift left` operation of x and y
# type Sub = getSubType T
# type Sub = type x.lo
#
# let # cannot be const, compile-time sizeof only works for simple types
# size = Sub(T.sizeof * 8)
@ -102,7 +102,7 @@ proc `shr`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}=
# proc `shr`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}=
# ## Compute the `shift right` operation of x and y
# type Sub = getSubType T
# type Sub = type x.lo
#
# let # cannot be const, compile-time sizeof only works for simple types
# size = Sub(T.sizeof * 8)

View File

@ -13,4 +13,14 @@ type
UInt128* = MpUint[uint64]
UInt256* = MpUint[UInt128]
UInt256* = MpUint[UInt128]
template convBool(typ: typedesc): untyped =
converter boolMpUint*(b: bool): MpUint[typ] {.noSideEffect, inline.}=
result.lo = b.typ
convBool(uint8)
convBool(uint16)
convBool(uint32)
convBool(uint64)