Force checking sizes at compile-time
This commit is contained in:
parent
49b3ee1006
commit
2b47647019
|
@ -0,0 +1,36 @@
|
|||
# Copyright 2018 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
#
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
#
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import ./uint_type, macros
|
||||
|
||||
|
||||
proc size_mpuintimpl*(x: NimNode): static[int] =
|
||||
|
||||
# Size of doesn't always work at compile-time, pending PR https://github.com/nim-lang/Nim/pull/5664
|
||||
|
||||
var multiplier = 1
|
||||
var node = x.getTypeInst
|
||||
|
||||
while node.kind == nnkBracketExpr:
|
||||
assert eqIdent(node[0], "MpuintImpl")
|
||||
multiplier *= 2
|
||||
node = node[1]
|
||||
|
||||
# node[1] has the type
|
||||
# size(node[1]) * multiplier is the size in byte
|
||||
|
||||
# For optimization we cast to the biggest possible uint
|
||||
result = if eqIdent(node, "uint64"): multiplier * 64
|
||||
elif eqIdent(node, "uint32"): multiplier * 32
|
||||
elif eqIdent(node, "uint16"): multiplier * 16
|
||||
else: multiplier * 8
|
||||
|
||||
macro size_mpuintimpl*(x: typed): untyped =
|
||||
let size = size_mpuintimpl(x)
|
||||
result = quote do:
|
||||
`size`
|
|
@ -78,8 +78,8 @@ proc naiveMulImpl[T: MpUintImpl](x, y: T): MpUintImpl[T] {.noSideEffect, noInit,
|
|||
# and introduce branching
|
||||
# - More total operations means more register moves
|
||||
|
||||
const halfSize = x.size_mpuintimpl div 2
|
||||
let
|
||||
halfSize = T.sizeof * 4
|
||||
z0 = naiveMul(x.lo, y.lo)
|
||||
tmp = naiveMul(x.hi, y.lo)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import ./uint_type
|
||||
import ./uint_type, size_mpuintimpl
|
||||
|
||||
|
||||
proc `not`*(x: MpUintImpl): MpUintImpl {.noInit, noSideEffect, inline.}=
|
||||
|
@ -33,8 +33,7 @@ proc `xor`*(x, y: MpUintImpl): MpUintImpl {.noInit, noSideEffect, inline.}=
|
|||
proc `shl`*[T: MpUintImpl](x: T, y: SomeInteger): T {.noInit, inline, noSideEffect.}=
|
||||
## Compute the `shift left` operation of x and y
|
||||
# Note: inlining this poses codegen/aliasing issue when doing `x = x shl 1`
|
||||
let
|
||||
halfSize = T.sizeof * 4
|
||||
const halfSize = size_mpuintimpl(x) div 2
|
||||
|
||||
type SubTy = type x.lo
|
||||
|
||||
|
@ -46,8 +45,7 @@ proc `shl`*[T: MpUintImpl](x: T, y: SomeInteger): T {.noInit, inline, noSideEffe
|
|||
proc `shr`*[T: MpUintImpl](x: T, y: SomeInteger): T {.noInit, inline, noSideEffect.}=
|
||||
## Compute the `shift right` operation of x and y
|
||||
# Note: inlining this poses codegen/aliasing issue when doing `x = x shl 1`
|
||||
let
|
||||
halfSize = T.sizeof * 4
|
||||
const halfSize = size_mpuintimpl(x) div 2
|
||||
|
||||
type SubTy = type x.lo
|
||||
|
||||
|
|
|
@ -7,27 +7,10 @@
|
|||
#
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import ./uint_type, macros
|
||||
import ./uint_type, ./size_mpuintimpl, macros
|
||||
|
||||
macro cast_optim(x: typed): untyped =
|
||||
# Size of doesn't always work at compile-time, pending PR https://github.com/nim-lang/Nim/pull/5664
|
||||
|
||||
var multiplier = 1
|
||||
var node = x.getTypeInst
|
||||
|
||||
while node.kind == nnkBracketExpr:
|
||||
assert eqIdent(node[0], "MpuintImpl")
|
||||
multiplier *= 2
|
||||
node = node[1]
|
||||
|
||||
# node[1] has the type
|
||||
# size(node[1]) * multiplier is the size in byte
|
||||
|
||||
# For optimization we cast to the biggest possible uint
|
||||
let size = if eqIdent(node, "uint64"): multiplier * 64
|
||||
elif eqIdent(node, "uint32"): multiplier * 32
|
||||
elif eqIdent(node, "uint16"): multiplier * 16
|
||||
else: multiplier * 8
|
||||
let size = size_mpuintimpl(x)
|
||||
|
||||
if size > 64:
|
||||
result = quote do:
|
||||
|
|
Loading…
Reference in New Issue