nimvm bug workaround

This commit is contained in:
jangko 2023-06-14 17:41:02 +07:00
parent ddcb2111e4
commit 21eeee72df
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
5 changed files with 32 additions and 24 deletions

View File

@ -113,13 +113,6 @@ func mulmod*(a, b, m: StUint): StUint =
func powmod*(a, b, m: StUint): StUint = func powmod*(a, b, m: StUint): StUint =
## Modular exponentiation ## Modular exponentiation
when nimvm:
doAssert false, "cannot use powmod at compile-time"
else:
# we need this ugly branch
# because of nim-lang/Nim#12517
discard
let a_m = if a < m: a let a_m = if a < m: a
else: a mod m else: a mod m

View File

@ -47,7 +47,7 @@ func shlAddMod_multi(a: var openArray[Word], c: Word,
M: openArray[Word], mBits: int): Word = M: openArray[Word], mBits: int): Word =
## Fused modular left-shift + add ## Fused modular left-shift + add
## Shift input `a` by a word and add `c` modulo `M` ## Shift input `a` by a word and add `c` modulo `M`
## ##
## Specialized for M being a multi-precision integer. ## Specialized for M being a multi-precision integer.
## ##
## With a word W = 2^WordBitWidth and a modulus M ## With a word W = 2^WordBitWidth and a modulus M
@ -55,7 +55,7 @@ func shlAddMod_multi(a: var openArray[Word], c: Word,
## and returns q = (a * W + c ) / M ## and returns q = (a * W + c ) / M
## ##
## The modulus `M` most-significant bit at `mBits` MUST be set. ## The modulus `M` most-significant bit at `mBits` MUST be set.
# Assuming 64-bit words # Assuming 64-bit words
let hi = a[^1] # Save the high word to detect carries let hi = a[^1] # Save the high word to detect carries
let R = mBits and (WordBitWidth - 1) # R = mBits mod 64 let R = mBits and (WordBitWidth - 1) # R = mBits mod 64
@ -128,7 +128,7 @@ func shlAddMod(a: var openArray[Word], c: Word,
M: openArray[Word], mBits: int): Word {.inline.}= M: openArray[Word], mBits: int): Word {.inline.}=
## Fused modular left-shift + add ## Fused modular left-shift + add
## Shift input `a` by a word and add `c` modulo `M` ## Shift input `a` by a word and add `c` modulo `M`
## ##
## With a word W = 2^WordBitWidth and a modulus M ## With a word W = 2^WordBitWidth and a modulus M
## Does a <- a * W + c (mod M) ## Does a <- a * W + c (mod M)
## and returns q = (a * W + c ) / M ## and returns q = (a * W + c ) / M
@ -182,13 +182,28 @@ func divRem*(
copyWords(r, 0, a, aOffset+1, bLen-1) copyWords(r, 0, a, aOffset+1, bLen-1)
r[rLen-1] = 0 r[rLen-1] = 0
# Now shift-left the copied words while adding the new word mod b # Now shift-left the copied words while adding the new word mod b
for i in countdown(aOffset, 0):
q[i] = shlAddMod( when nimvm:
r.toOpenArray(0, rLen-1), # workaround nim bug #22095
a[i], var rr = @(r.toOpenArray(0, rLen-1))
b.toOpenArray(0, bLen-1), var bb = @(b.toOpenArray(0, bLen-1))
bBits for i in countdown(aOffset, 0):
) q[i] = shlAddMod(
rr,
a[i],
bb,
bBits
)
for i in 0..rLen-1:
r[i] = rr[i]
else:
for i in countdown(aOffset, 0):
q[i] = shlAddMod(
r.toOpenArray(0, rLen-1),
a[i],
b.toOpenArray(0, bLen-1),
bBits
)
# Clean up extra words # Clean up extra words
for i in aOffset+1 ..< q.len: for i in aOffset+1 ..< q.len:
@ -229,7 +244,7 @@ func divRem*(
# - An Efficient Multiple-Precision Division Algorithm, # - An Efficient Multiple-Precision Division Algorithm,
# Liusheng Huang, Hong Zhong, Hong Shen, Yonglong Luo, 2005 # Liusheng Huang, Hong Zhong, Hong Shen, Yonglong Luo, 2005
# https://ieeexplore.ieee.org/document/1579076 # https://ieeexplore.ieee.org/document/1579076
# #
# - Efficient multiple-precision integer division algorithm # - Efficient multiple-precision integer division algorithm
# Debapriyay Mukhopadhyaya, Subhas C.Nandy, 2014 # Debapriyay Mukhopadhyaya, Subhas C.Nandy, 2014
# https://www.sciencedirect.com/science/article/abs/pii/S0020019013002627 # https://www.sciencedirect.com/science/article/abs/pii/S0020019013002627

View File

@ -116,8 +116,8 @@ template testMuldiv(chk, tst: untyped) =
chkMod(chk, 2, -5, 2, 64) chkMod(chk, 2, -5, 2, 64)
chkMod(chk, -2, -5, -2, 64) chkMod(chk, -2, -5, -2, 64)
#static: static:
#testMuldiv(ctCheck, ctTest) testMuldiv(ctCheck, ctTest)
suite "Wider signed int muldiv coverage": suite "Wider signed int muldiv coverage":
testMuldiv(check, test) testMuldiv(check, test)

View File

@ -60,8 +60,8 @@ template testdivmod(chk, tst: untyped) =
chkDivMod(chk, "FFFFFFFFFFFFFFFF", "27", "690690690690690", "F", 128) chkDivMod(chk, "FFFFFFFFFFFFFFFF", "27", "690690690690690", "F", 128)
chkDivMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "27", "6906906906906906906906906906906", "15", 128) chkDivMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "27", "6906906906906906906906906906906", "15", 128)
#static: static:
#testdivmod(ctCheck, ctTest) testdivmod(ctCheck, ctTest)
suite "Wider unsigned int muldiv coverage": suite "Wider unsigned int muldiv coverage":
testdivmod(check, test) testdivmod(check, test)

View File

@ -56,8 +56,8 @@ template testModArith(chk, tst: untyped) =
chkPowMod(chk, "FFFFFFFFFFFFFFFF", "3", "C", "3", 128) chkPowMod(chk, "FFFFFFFFFFFFFFFF", "3", "C", "3", 128)
chkPowMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "3", "C", "3", 128) chkPowMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "3", "C", "3", 128)
#static: static:
#testModArith(ctCheck, ctTest) testModArith(ctCheck, ctTest)
suite "Wider unsigned Modular arithmetic coverage": suite "Wider unsigned Modular arithmetic coverage":
testModArith(check, test) testModArith(check, test)