diff --git a/stint/private/primitives/addcarry_subborrow.nim b/stint/private/primitives/addcarry_subborrow.nim index 75aa21a..3751602 100644 --- a/stint/private/primitives/addcarry_subborrow.nim +++ b/stint/private/primitives/addcarry_subborrow.nim @@ -107,14 +107,14 @@ func addC*(cOut: var Carry, sum: var uint32, a, b: uint32, cIn: Carry) {.inline. ## (CarryOut, Sum) <- a + b + CarryIn when nimvm: let dblPrec = uint64(cIn) + uint64(a) + uint64(b) - sum = (uint32)(dblPrec) + sum = uint32(dblPrec and uint32.high) cOut = Carry(dblPrec shr 32) else: when X86: cOut = addcarry_u32(cIn, a, b, sum) else: let dblPrec = uint64(cIn) + uint64(a) + uint64(b) - sum = (uint32)(dblPrec) + sum = uint32(dblPrec) cOut = Carry(dblPrec shr 32) func subB*(bOut: var Borrow, diff: var uint32, a, b: uint32, bIn: Borrow) {.inline.} = @@ -122,7 +122,7 @@ func subB*(bOut: var Borrow, diff: var uint32, a, b: uint32, bIn: Borrow) {.inli ## (BorrowOut, Diff) <- a - b - borrowIn when nimvm: let dblPrec = uint64(a) - uint64(b) - uint64(bIn) - diff = (uint32)(dblPrec) + diff = uint32(dblPrec and uint32.high) # On borrow the high word will be 0b1111...1111 and needs to be masked bOut = Borrow((dblPrec shr 32) and 1) else: @@ -130,7 +130,7 @@ func subB*(bOut: var Borrow, diff: var uint32, a, b: uint32, bIn: Borrow) {.inli bOut = subborrow_u32(bIn, a, b, diff) else: let dblPrec = uint64(a) - uint64(b) - uint64(bIn) - diff = (uint32)(dblPrec) + diff = uint32(dblPrec) # On borrow the high word will be 0b1111...1111 and needs to be masked bOut = Borrow((dblPrec shr 32) and 1) diff --git a/stint/private/primitives/extended_precision.nim b/stint/private/primitives/extended_precision.nim index cd04828..4f58e65 100644 --- a/stint/private/primitives/extended_precision.nim +++ b/stint/private/primitives/extended_precision.nim @@ -41,7 +41,10 @@ func mul*(hi, lo: var uint32, a, b: uint32) {.inline.} = ## Extended precision multiplication ## (hi, lo) <- a*b let dblPrec = uint64(a) * uint64(b) - lo = uint32(dblPrec) + when nimvm: + lo = uint32(dblPrec and uint32.high) + else: + lo = uint32(dblPrec) hi = uint32(dblPrec shr 32) func muladd1*(hi, lo: var uint32, a, b, c: uint32) {.inline.} = @@ -51,7 +54,10 @@ func muladd1*(hi, lo: var uint32, a, b, c: uint32) {.inline.} = ## Note: 0xFFFFFFFF² -> (hi: 0xFFFFFFFE, lo: 0x00000001) ## so adding any c cannot overflow let dblPrec = uint64(a) * uint64(b) + uint64(c) - lo = uint32(dblPrec) + when nimvm: + lo = uint32(dblPrec and uint32.high) + else: + lo = uint32(dblPrec) hi = uint32(dblPrec shr 32) func muladd2*(hi, lo: var uint32, a, b, c1, c2: uint32) {.inline.}= @@ -63,7 +69,10 @@ func muladd2*(hi, lo: var uint32, a, b, c1, c2: uint32) {.inline.}= ## so adding 0xFFFFFFFF leads to (hi: 0xFFFFFFFF, lo: 0x00000000) ## and we have enough space to add again 0xFFFFFFFF without overflowing let dblPrec = uint64(a) * uint64(b) + uint64(c1) + uint64(c2) - lo = uint32(dblPrec) + when nimvm: + lo = uint32(dblPrec and uint32.high) + else: + lo = uint32(dblPrec) hi = uint32(dblPrec shr 32) # ############################################################