in-place add/sub fix + Add note that native x86 division is flawed:

SIGFPE on quotient that don't fit in a word size
This commit is contained in:
Mamy André-Ratsimbazafy 2020-02-09 23:00:21 +01:00
parent 216ed9bdc1
commit a389e5c38c
No known key found for this signature in database
GPG Key ID: 7B88AD1FE79492E1
2 changed files with 33 additions and 2 deletions

View File

@ -85,9 +85,11 @@ template `not`*[T: Ct](x: T): T =
T(not T.T(x))
func `+`*[T: Ct](x, y: T): T {.magic: "AddU".}
func `+=`*[T: Ct](x: var T, y: T) {.magic: "Inc".}
func `+=`*[T: Ct](x: var T, y: T) =
T.T(x) += (T.T)(y)
func `-`*[T: Ct](x, y: T): T {.magic: "SubU".}
func `-=`*[T: Ct](x: var T, y: T) {.magic: "Dec".}
func `-=`*[T: Ct](x: var T, y: T) =
T.T(x) -= (T.T)(y)
func `shr`*[T: Ct](x: T, y: SomeInteger): T {.magic: "ShrI".}
func `shl`*[T: Ct](x: T, y: SomeInteger): T {.magic: "ShlI".}

View File

@ -139,6 +139,35 @@ when isMainModule:
doAssert q == 6148914691236517205'u64
doAssert r == 1
block: # TODO - support Quotient that doesn't fit in the result
# The usual way with normalization by the bitSize difference
# is fundamentally non constant-time
# it is probable that division is not constant-time at the hardware level as well
# as it throws sigfpe when the quotient doesn't fit in the result size
var q, r: uint64
let n_hi = 1'u64
let n_lo = 0'u64
let d = 1'u64
asm_x86_64_div2n1n(q, r, n_hi, n_lo, d)
echo "quotient: ", q
echo "remainder: ", r
block:
var q, r: uint64
let n_hi = 4186590388502004879'u64
let n_lo = 17852795547484522084'u64
let d = 327340459940166448'u64
asm_x86_64_div2n1n(q, r, n_hi, n_lo, d)
echo "quotient: ", q
echo "remainder: ", r
# ##############################################################
#
# Non-constant-time portable extended precision multiplication