Use the new timesInt2# primop in integer-gmp (#9431)
authorSylvain Henry <sylvain@haskus.fr>
Mon, 7 Oct 2019 16:43:47 +0000 (18:43 +0200)
committerMarge Bot <ben+marge-bot@smart-cactus.org>
Tue, 3 Dec 2019 04:59:29 +0000 (23:59 -0500)
libraries/integer-gmp/src/GHC/Integer/Type.hs

index 333d8e9..1b7d6ca 100644 (file)
@@ -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