diff options
-rw-r--r-- | libraries/integer-gmp/src/GHC/Integer/Type.hs | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/libraries/integer-gmp/src/GHC/Integer/Type.hs b/libraries/integer-gmp/src/GHC/Integer/Type.hs index 333d8e9295..1b7d6cafba 100644 --- a/libraries/integer-gmp/src/GHC/Integer/Type.hs +++ b/libraries/integer-gmp/src/GHC/Integer/Type.hs @@ -478,10 +478,9 @@ timesInteger x (S# 1#) = x timesInteger (S# 1#) y = y timesInteger x (S# -1#) = negateInteger x timesInteger (S# -1#) y = negateInteger y -timesInteger (S# x#) (S# y#) - = case mulIntMayOflo# x# y# of - 0# -> S# (x# *# y#) - _ -> timesInt2Integer x# y# +timesInteger (S# x#) (S# y#) = case timesInt2# x# y# of + (# 0#, _h, l #) -> S# l + (# _ , h, l #) -> int2ToInteger h l timesInteger x@(S# _) y = timesInteger y x -- no S# as first arg from here on timesInteger (Jp# x) (Jp# y) = Jp# (timesBigNat x y) @@ -504,6 +503,22 @@ sqrInteger (S# j#) = timesInt2Integer j# j# sqrInteger (Jp# bn) = Jp# (sqrBigNat bn) sqrInteger (Jn# bn) = Jp# (sqrBigNat bn) +-- | Convert two Int# (resp. high and low bits of a double-word Int#) into an +-- Integer +-- +-- Warning: currently it doesn't handle the case where high=minBound and low=0 +-- (i.e. high:low = 100......00 = minBound for a double-word Int) +int2ToInteger :: Int# -> Int# -> Integer +int2ToInteger h l + | isTrue# (h <# 0#) = + case addWordC# (not# (int2Word# l)) 1## of -- two's complement... + (# lw,c #) -> Jn# (wordToBigNat2 + -- add the carry to the high word + (int2Word# c `plusWord#` not# (int2Word# h)) + lw + ) + | True = Jp# (wordToBigNat2 (int2Word# h) (int2Word# l)) + -- | Construct 'Integer' from the product of two 'Int#'s timesInt2Integer :: Int# -> Int# -> Integer timesInt2Integer x# y# = case (# isTrue# (x# >=# 0#), isTrue# (y# >=# 0#) #) of |