diff options
author | John Ericson <git@JohnEricson.me> | 2019-10-19 18:59:48 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-05-06 02:30:54 -0400 |
commit | c4f4193a13f751380e4cedbc2688a339f69325c9 (patch) | |
tree | e9cf1fb7f05d99dbbe1dcec7c1e526932220d9c5 /libraries | |
parent | a5e9e5b601fecef421ec4bfa28e135404986ded0 (diff) | |
download | haskell-c4f4193a13f751380e4cedbc2688a339f69325c9.tar.gz |
Use fix-sized arithmetic primops for fixed size boxed types
We think the compiler is ready, so we can do this for all over the 8-,
16-, and 32-bit boxed types.
We are holding off on doing all the primops at once so things are easier
to investigate.
Metric Decrease:
T12545
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/base/GHC/Int.hs | 84 | ||||
-rw-r--r-- | libraries/base/GHC/Word.hs | 61 | ||||
-rw-r--r-- | libraries/ghc-prim/GHC/Classes.hs | 202 |
3 files changed, 239 insertions, 108 deletions
diff --git a/libraries/base/GHC/Int.hs b/libraries/base/GHC/Int.hs index a9feb3d890..fa5aa3f8e5 100644 --- a/libraries/base/GHC/Int.hs +++ b/libraries/base/GHC/Int.hs @@ -100,10 +100,10 @@ instance Show Int8 where -- | @since 2.01 instance Num Int8 where - (I8# x#) + (I8# y#) = I8# (intToInt8# ((int8ToInt# x#) +# (int8ToInt# y#))) - (I8# x#) - (I8# y#) = I8# (intToInt8# ((int8ToInt# x#) -# (int8ToInt# y#))) - (I8# x#) * (I8# y#) = I8# (intToInt8# ((int8ToInt# x#) *# (int8ToInt# y#))) - negate (I8# x#) = I8# (intToInt8# (negateInt# (int8ToInt# x#))) + (I8# x#) + (I8# y#) = I8# (x# `plusInt8#` y#) + (I8# x#) - (I8# y#) = I8# (x# `subInt8#` y#) + (I8# x#) * (I8# y#) = I8# (x# `timesInt8#` y#) + negate (I8# x#) = I8# (negateInt8# x#) abs x | x >= 0 = x | otherwise = negate x signum x | x > 0 = 1 @@ -136,7 +136,7 @@ instance Integral Int8 where quot x@(I8# x#) y@(I8# y#) | y == 0 = divZeroError | y == (-1) && x == minBound = overflowError -- Note [Order of tests] - | otherwise = I8# (intToInt8# ((int8ToInt# x#) `quotInt#` (int8ToInt# y#))) + | otherwise = I8# (x# `quotInt8#` y#) rem (I8# x#) y@(I8# y#) | y == 0 = divZeroError -- The quotRem CPU instruction might fail for 'minBound @@ -144,11 +144,11 @@ instance Integral Int8 where -- width of signed integer. But, 'minBound `rem` -1' is -- well-defined (0). We therefore special-case it. | y == (-1) = 0 - | otherwise = I8# (intToInt8# ((int8ToInt# x#) `remInt#` (int8ToInt# y#))) + | otherwise = I8# (x# `remInt8#` y#) div x@(I8# x#) y@(I8# y#) | y == 0 = divZeroError | y == (-1) && x == minBound = overflowError -- Note [Order of tests] - | otherwise = I8# (intToInt8# ((int8ToInt# x#) `divInt#` (int8ToInt# y#))) + | otherwise = I8# (x# `divInt8#` y#) mod (I8# x#) y@(I8# y#) | y == 0 = divZeroError -- The divMod CPU instruction might fail for 'minBound @@ -156,23 +156,19 @@ instance Integral Int8 where -- width of signed integer. But, 'minBound `mod` -1' is -- well-defined (0). We therefore special-case it. | y == (-1) = 0 - | otherwise = I8# (intToInt8# ((int8ToInt# x#) `modInt#` (int8ToInt# y#))) + | otherwise = I8# (x# `modInt8#` y#) quotRem x@(I8# x#) y@(I8# y#) | y == 0 = divZeroError -- Note [Order of tests] | y == (-1) && x == minBound = (overflowError, 0) - | otherwise = case (int8ToInt# x#) `quotRemInt#` (int8ToInt# y#) of - (# q, r #) -> - (I8# (intToInt8# q), - I8# (intToInt8# r)) + | otherwise = case x# `quotRemInt8#` y# of + (# q, r #) -> (I8# q, I8# r) divMod x@(I8# x#) y@(I8# y#) | y == 0 = divZeroError -- Note [Order of tests] | y == (-1) && x == minBound = (overflowError, 0) - | otherwise = case (int8ToInt# x#) `divModInt#` (int8ToInt# y#) of - (# d, m #) -> - (I8# (intToInt8# d), - I8# (intToInt8# m)) + | otherwise = case x# `divModInt8#` y# of + (# d, m #) -> (I8# d, I8# m) toInteger (I8# x#) = IS (int8ToInt# x#) -- | @since 2.01 @@ -317,10 +313,10 @@ instance Show Int16 where -- | @since 2.01 instance Num Int16 where - (I16# x#) + (I16# y#) = I16# (intToInt16# ((int16ToInt# x#) +# (int16ToInt# y#))) - (I16# x#) - (I16# y#) = I16# (intToInt16# ((int16ToInt# x#) -# (int16ToInt# y#))) - (I16# x#) * (I16# y#) = I16# (intToInt16# ((int16ToInt# x#) *# (int16ToInt# y#))) - negate (I16# x#) = I16# (intToInt16# (negateInt# (int16ToInt# x#))) + (I16# x#) + (I16# y#) = I16# (x# `plusInt16#` y#) + (I16# x#) - (I16# y#) = I16# (x# `subInt16#` y#) + (I16# x#) * (I16# y#) = I16# (x# `timesInt16#` y#) + negate (I16# x#) = I16# (negateInt16# x#) abs x | x >= 0 = x | otherwise = negate x signum x | x > 0 = 1 @@ -353,7 +349,7 @@ instance Integral Int16 where quot x@(I16# x#) y@(I16# y#) | y == 0 = divZeroError | y == (-1) && x == minBound = overflowError -- Note [Order of tests] - | otherwise = I16# (intToInt16# ((int16ToInt# x#) `quotInt#` (int16ToInt# y#))) + | otherwise = I16# (x# `quotInt16#` y#) rem (I16# x#) y@(I16# y#) | y == 0 = divZeroError -- The quotRem CPU instruction might fail for 'minBound @@ -361,11 +357,11 @@ instance Integral Int16 where -- width of signed integer. But, 'minBound `rem` -1' is -- well-defined (0). We therefore special-case it. | y == (-1) = 0 - | otherwise = I16# (intToInt16# ((int16ToInt# x#) `remInt#` (int16ToInt# y#))) + | otherwise = I16# (x# `remInt16#` y#) div x@(I16# x#) y@(I16# y#) | y == 0 = divZeroError | y == (-1) && x == minBound = overflowError -- Note [Order of tests] - | otherwise = I16# (intToInt16# ((int16ToInt# x#) `divInt#` (int16ToInt# y#))) + | otherwise = I16# (x# `divInt16#` y#) mod (I16# x#) y@(I16# y#) | y == 0 = divZeroError -- The divMod CPU instruction might fail for 'minBound @@ -373,23 +369,19 @@ instance Integral Int16 where -- width of signed integer. But, 'minBound `mod` -1' is -- well-defined (0). We therefore special-case it. | y == (-1) = 0 - | otherwise = I16# (intToInt16# ((int16ToInt# x#) `modInt#` (int16ToInt# y#))) + | otherwise = I16# (x# `modInt16#` y#) quotRem x@(I16# x#) y@(I16# y#) | y == 0 = divZeroError -- Note [Order of tests] | y == (-1) && x == minBound = (overflowError, 0) - | otherwise = case (int16ToInt# x#) `quotRemInt#` (int16ToInt# y#) of - (# q, r #) -> - (I16# (intToInt16# q), - I16# (intToInt16# r)) + | otherwise = case x# `quotRemInt16#` y# of + (# q, r #) -> (I16# q, I16# r) divMod x@(I16# x#) y@(I16# y#) | y == 0 = divZeroError -- Note [Order of tests] | y == (-1) && x == minBound = (overflowError, 0) - | otherwise = case (int16ToInt# x#) `divModInt#` (int16ToInt# y#) of - (# d, m #) -> - (I16# (intToInt16# d), - I16# (intToInt16# m)) + | otherwise = case x# `divModInt16#` y# of + (# d, m #) -> (I16# d, I16# m) toInteger (I16# x#) = IS (int16ToInt# x#) -- | @since 2.01 @@ -539,10 +531,10 @@ instance Show Int32 where -- | @since 2.01 instance Num Int32 where - (I32# x#) + (I32# y#) = I32# (intToInt32# ((int32ToInt# x#) +# (int32ToInt# y#))) - (I32# x#) - (I32# y#) = I32# (intToInt32# ((int32ToInt# x#) -# (int32ToInt# y#))) - (I32# x#) * (I32# y#) = I32# (intToInt32# ((int32ToInt# x#) *# (int32ToInt# y#))) - negate (I32# x#) = I32# (intToInt32# (negateInt# (int32ToInt# x#))) + (I32# x#) + (I32# y#) = I32# (x# `plusInt32#` y#) + (I32# x#) - (I32# y#) = I32# (x# `subInt32#` y#) + (I32# x#) * (I32# y#) = I32# (x# `timesInt32#` y#) + negate (I32# x#) = I32# (negateInt32# x#) abs x | x >= 0 = x | otherwise = negate x signum x | x > 0 = 1 @@ -575,7 +567,7 @@ instance Integral Int32 where quot x@(I32# x#) y@(I32# y#) | y == 0 = divZeroError | y == (-1) && x == minBound = overflowError -- Note [Order of tests] - | otherwise = I32# (intToInt32# ((int32ToInt# x#) `quotInt#` (int32ToInt# y#))) + | otherwise = I32# (x# `quotInt32#` y#) rem (I32# x#) y@(I32# y#) | y == 0 = divZeroError -- The quotRem CPU instruction might fail for 'minBound @@ -583,11 +575,11 @@ instance Integral Int32 where -- width of signed integer. But, 'minBound `rem` -1' is -- well-defined (0). We therefore special-case it. | y == (-1) = 0 - | otherwise = I32# (intToInt32# ((int32ToInt# x#) `remInt#` (int32ToInt# y#))) + | otherwise = I32# (x# `remInt32#` y#) div x@(I32# x#) y@(I32# y#) | y == 0 = divZeroError | y == (-1) && x == minBound = overflowError -- Note [Order of tests] - | otherwise = I32# (intToInt32# ((int32ToInt# x#) `divInt#` (int32ToInt# y#))) + | otherwise = I32# (x# `divInt32#` y#) mod (I32# x#) y@(I32# y#) | y == 0 = divZeroError -- The divMod CPU instruction might fail for 'minBound @@ -595,23 +587,19 @@ instance Integral Int32 where -- width of signed integer. But, 'minBound `mod` -1' is -- well-defined (0). We therefore special-case it. | y == (-1) = 0 - | otherwise = I32# (intToInt32# ((int32ToInt# x#) `modInt#` (int32ToInt# y#))) + | otherwise = I32# (x# `modInt32#` y#) quotRem x@(I32# x#) y@(I32# y#) | y == 0 = divZeroError -- Note [Order of tests] | y == (-1) && x == minBound = (overflowError, 0) - | otherwise = case (int32ToInt# x#) `quotRemInt#` (int32ToInt# y#) of - (# q, r #) -> - (I32# (intToInt32# q), - I32# (intToInt32# r)) + | otherwise = case x# `quotRemInt32#` y# of + (# q, r #) -> (I32# q, I32# r) divMod x@(I32# x#) y@(I32# y#) | y == 0 = divZeroError -- Note [Order of tests] | y == (-1) && x == minBound = (overflowError, 0) - | otherwise = case (int32ToInt# x#) `divModInt#` (int32ToInt# y#) of - (# d, m #) -> - (I32# (intToInt32# d), - I32# (intToInt32# m)) + | otherwise = case x# `divModInt32#` y# of + (# d, m #) -> (I32# d, I32# m) toInteger (I32# x#) = IS (int32ToInt# x#) -- | @since 2.01 diff --git a/libraries/base/GHC/Word.hs b/libraries/base/GHC/Word.hs index c704f3afc7..b75d24359b 100644 --- a/libraries/base/GHC/Word.hs +++ b/libraries/base/GHC/Word.hs @@ -108,10 +108,10 @@ instance Show Word8 where -- | @since 2.01 instance Num Word8 where - (W8# x#) + (W8# y#) = W8# (wordToWord8# ((word8ToWord# x#) `plusWord#` (word8ToWord# y#))) - (W8# x#) - (W8# y#) = W8# (wordToWord8# ((word8ToWord# x#) `minusWord#` (word8ToWord# y#))) - (W8# x#) * (W8# y#) = W8# (wordToWord8# ((word8ToWord# x#) `timesWord#` (word8ToWord# y#))) - negate (W8# x#) = W8# (wordToWord8# (int2Word# (negateInt# (word2Int# ((word8ToWord# x#)))))) + (W8# x#) + (W8# y#) = W8# (x# `plusWord8#` y#) + (W8# x#) - (W8# y#) = W8# (x# `subWord8#` y#) + (W8# x#) * (W8# y#) = W8# (x# `timesWord8#` y#) + negate (W8# x#) = W8# (int8ToWord8# (negateInt8# (word8ToInt8# x#))) abs x = x signum 0 = 0 signum _ = 1 @@ -140,25 +140,24 @@ instance Enum Word8 where -- | @since 2.01 instance Integral Word8 where quot (W8# x#) y@(W8# y#) - | y /= 0 = W8# (wordToWord8# ((word8ToWord# x#) `quotWord#` (word8ToWord# y#))) + | y /= 0 = W8# (x# `quotWord8#` y#) | otherwise = divZeroError rem (W8# x#) y@(W8# y#) - | y /= 0 = W8# (wordToWord8# ((word8ToWord# x#) `remWord#` (word8ToWord# y#))) + | y /= 0 = W8# (x# `remWord8#` y#) | otherwise = divZeroError div (W8# x#) y@(W8# y#) - | y /= 0 = W8# (wordToWord8# ((word8ToWord# x#) `quotWord#` (word8ToWord# y#))) + | y /= 0 = W8# (x# `quotWord8#` y#) | otherwise = divZeroError mod (W8# x#) y@(W8# y#) - | y /= 0 = W8# (wordToWord8# ((word8ToWord# x#) `remWord#` (word8ToWord# y#))) + | y /= 0 = W8# (x# `remWord8#` y#) | otherwise = divZeroError quotRem (W8# x#) y@(W8# y#) - | y /= 0 = case (word8ToWord# x#) `quotRemWord#` (word8ToWord# y#) of - (# q, r #) -> - (W8# (wordToWord8# q), W8# (wordToWord8# r)) + | y /= 0 = case x# `quotRemWord8#` y# of + (# q, r #) -> (W8# q, W8# r) | otherwise = divZeroError divMod (W8# x#) y@(W8# y#) - | y /= 0 = (W8# (wordToWord8# ((word8ToWord# x#) `quotWord#` (word8ToWord# y#))) - ,W8# (wordToWord8# ((word8ToWord# x#) `remWord#` (word8ToWord# y#)))) + | y /= 0 = (W8# (x# `quotWord8#` y#) + ,W8# (x# `remWord8#` y#)) | otherwise = divZeroError toInteger (W8# x#) = IS (word2Int# (word8ToWord# x#)) @@ -299,10 +298,10 @@ instance Show Word16 where -- | @since 2.01 instance Num Word16 where - (W16# x#) + (W16# y#) = W16# (wordToWord16# ((word16ToWord# x#) `plusWord#` (word16ToWord# y#))) - (W16# x#) - (W16# y#) = W16# (wordToWord16# ((word16ToWord# x#) `minusWord#` (word16ToWord# y#))) - (W16# x#) * (W16# y#) = W16# (wordToWord16# ((word16ToWord# x#) `timesWord#` (word16ToWord# y#))) - negate (W16# x#) = W16# (wordToWord16# (int2Word# (negateInt# (word2Int# (word16ToWord# x#))))) + (W16# x#) + (W16# y#) = W16# (x# `plusWord16#` y#) + (W16# x#) - (W16# y#) = W16# (x# `subWord16#` y#) + (W16# x#) * (W16# y#) = W16# (x# `timesWord16#` y#) + negate (W16# x#) = W16# (int16ToWord16# (negateInt16# (word16ToInt16# x#))) abs x = x signum 0 = 0 signum _ = 1 @@ -528,10 +527,10 @@ gtWord32, geWord32, ltWord32, leWord32 :: Word32 -> Word32 -> Bool -- | @since 2.01 instance Num Word32 where - (W32# x#) + (W32# y#) = W32# (wordToWord32# ((word32ToWord# x#) `plusWord#` (word32ToWord# y#))) - (W32# x#) - (W32# y#) = W32# (wordToWord32# ((word32ToWord# x#) `minusWord#` (word32ToWord# y#))) - (W32# x#) * (W32# y#) = W32# (wordToWord32# ((word32ToWord# x#) `timesWord#` (word32ToWord# y#))) - negate (W32# x#) = W32# (wordToWord32# (int2Word# (negateInt# (word2Int# (word32ToWord# x#))))) + (W32# x#) + (W32# y#) = W32# (x# `plusWord32#` y#) + (W32# x#) - (W32# y#) = W32# (x# `subWord32#` y#) + (W32# x#) * (W32# y#) = W32# (x# `timesWord32#` y#) + negate (W32# x#) = W32# (int32ToWord32# (negateInt32# (word32ToInt32# x#))) abs x = x signum 0 = 0 signum _ = 1 @@ -570,25 +569,24 @@ instance Enum Word32 where -- | @since 2.01 instance Integral Word32 where quot (W32# x#) y@(W32# y#) - | y /= 0 = W32# (wordToWord32# ((word32ToWord# x#) `quotWord#` (word32ToWord# y#))) + | y /= 0 = W32# (x# `quotWord32#` y#) | otherwise = divZeroError rem (W32# x#) y@(W32# y#) - | y /= 0 = W32# (wordToWord32# ((word32ToWord# x#) `remWord#` (word32ToWord# y#))) + | y /= 0 = W32# (x# `remWord32#` y#) | otherwise = divZeroError div (W32# x#) y@(W32# y#) - | y /= 0 = W32# (wordToWord32# ((word32ToWord# x#) `quotWord#` (word32ToWord# y#))) + | y /= 0 = W32# (x# `quotWord32#` y#) | otherwise = divZeroError mod (W32# x#) y@(W32# y#) - | y /= 0 = W32# (wordToWord32# ((word32ToWord# x#) `remWord#` (word32ToWord# y#))) + | y /= 0 = W32# (x# `remWord32#` y#) | otherwise = divZeroError quotRem (W32# x#) y@(W32# y#) - | y /= 0 = case (word32ToWord# x#) `quotRemWord#` (word32ToWord# y#) of - (# q, r #) -> - (W32# (wordToWord32# q), W32# (wordToWord32# r)) + | y /= 0 = case x# `quotRemWord32#` y# of + (# q, r #) -> (W32# q, W32# r) | otherwise = divZeroError divMod (W32# x#) y@(W32# y#) - | y /= 0 = (W32# (wordToWord32# ((word32ToWord# x#) `quotWord#` (word32ToWord# y#))) - ,W32# (wordToWord32# ((word32ToWord# x#) `remWord#` (word32ToWord# y#)))) + | y /= 0 = (W32# (x# `quotWord32#` y#) + ,W32# (x# `remWord32#` y#)) | otherwise = divZeroError toInteger (W32# x#) #if WORD_SIZE_IN_BITS == 32 @@ -949,8 +947,7 @@ instance Integral Word64 where | otherwise = divZeroError quotRem (W64# x#) y@(W64# y#) | y /= 0 = case x# `quotRemWord#` y# of - (# q, r #) -> - (W64# q, W64# r) + (# q, r #) -> (W64# q, W64# r) | otherwise = divZeroError divMod (W64# x#) y@(W64# y#) | y /= 0 = (W64# (x# `quotWord#` y#), W64# (x# `remWord#` y#)) diff --git a/libraries/ghc-prim/GHC/Classes.hs b/libraries/ghc-prim/GHC/Classes.hs index 29a57afd91..dfd707bd8c 100644 --- a/libraries/ghc-prim/GHC/Classes.hs +++ b/libraries/ghc-prim/GHC/Classes.hs @@ -51,7 +51,9 @@ module GHC.Classes( (&&), (||), not, -- * Integer arithmetic - divInt#, modInt#, divModInt# + divInt#, divInt8#, divInt16#, divInt32#, + modInt#, modInt8#, modInt16#, modInt32#, + divModInt#, divModInt8#, divModInt16#, divModInt32# ) where -- GHC.Magic is used in some derived instances @@ -542,9 +544,6 @@ not False = True -- These functions have built-in rules. {-# INLINE [0] divInt# #-} -{-# INLINE [0] modInt# #-} -{-# INLINE [0] divModInt# #-} - divInt# :: Int# -> Int# -> Int# x# `divInt#` y# = ((x# +# bias#) `quotInt#` y#) -# hard# where @@ -555,30 +554,50 @@ x# `divInt#` y# = ((x# +# bias#) `quotInt#` y#) -# hard# !bias# = c0# -# c1# !hard# = c0# `orI#` c1# -modInt# :: Int# -> Int# -> Int# -x# `modInt#` y# = r# +# k# - where - -- See Note [modInt# implementation] - !yn# = y# <# 0# - !c0# = (x# <# 0#) `andI#` (notI# yn#) - !c1# = (x# ># 0#) `andI#` yn# - !s# = 0# -# ((c0# `orI#` c1#) `andI#` (r# /=# 0#)) - !k# = s# `andI#` y# - !r# = x# `remInt#` y# - -divModInt# :: Int# -> Int# -> (# Int#, Int# #) -x# `divModInt#` y# = case (x# +# bias#) `quotRemInt#` y# of - (# q#, r# #) -> (# q# -# hard#, r# +# k# #) - where - -- See Note [divModInt# implementation] - !yn# = y# <# 0# - !c0# = (x# <# 0#) `andI#` (notI# yn#) - !c1# = (x# ># 0#) `andI#` yn# - !bias# = c0# -# c1# - !hard# = c0# `orI#` c1# - !s# = 0# -# hard# - !k# = (s# `andI#` y#) -# bias# - +{-# INLINE [0] divInt8# #-} +divInt8# :: Int8# -> Int8# -> Int8# +x# `divInt8#` y# = ((x# `plusInt8#` bias#) `quotInt8#` y#) `subInt8#` hard# + where + zero# = intToInt8# 0# + x `andInt8#` y = word8ToInt8# (int8ToWord8# x `andWord8#` int8ToWord8# y) + x `orInt8#` y = word8ToInt8# (int8ToWord8# x `orWord8#` int8ToWord8# y) + notInt8# x = word8ToInt8# (notWord8# (int8ToWord8# x)) + -- See Note [divInt# implementation] + !yn# = intToInt8# (y# `ltInt8#` zero#) + !c0# = intToInt8# (x# `ltInt8#` zero#) `andInt8#` (notInt8# yn#) + !c1# = intToInt8# (x# `gtInt8#` zero#) `andInt8#` yn# + !bias# = c0# `subInt8#` c1# + !hard# = c0# `orInt8#` c1# + +{-# INLINE [0] divInt16# #-} +divInt16# :: Int16# -> Int16# -> Int16# +x# `divInt16#` y# = ((x# `plusInt16#` bias#) `quotInt16#` y#) `subInt16#` hard# + where + zero# = intToInt16# 0# + x `andInt16#` y = word16ToInt16# (int16ToWord16# x `andWord16#` int16ToWord16# y) + x `orInt16#` y = word16ToInt16# (int16ToWord16# x `orWord16#` int16ToWord16# y) + notInt16# x = word16ToInt16# (notWord16# (int16ToWord16# x)) + -- See Note [divInt# implementation] + !yn# = intToInt16# (y# `ltInt16#` zero#) + !c0# = intToInt16# (x# `ltInt16#` zero#) `andInt16#` (notInt16# yn#) + !c1# = intToInt16# (x# `gtInt16#` zero#) `andInt16#` yn# + !bias# = c0# `subInt16#` c1# + !hard# = c0# `orInt16#` c1# + +{-# INLINE [0] divInt32# #-} +divInt32# :: Int32# -> Int32# -> Int32# +x# `divInt32#` y# = ((x# `plusInt32#` bias#) `quotInt32#` y#) `subInt32#` hard# + where + zero# = intToInt32# 0# + x `andInt32#` y = word32ToInt32# (int32ToWord32# x `andWord32#` int32ToWord32# y) + x `orInt32#` y = word32ToInt32# (int32ToWord32# x `orWord32#` int32ToWord32# y) + notInt32# x = word32ToInt32# (notWord32# (int32ToWord32# x)) + -- See Note [divInt# implementation] + !yn# = intToInt32# (y# `ltInt32#` zero#) + !c0# = intToInt32# (x# `ltInt32#` zero#) `andInt32#` (notInt32# yn#) + !c1# = intToInt32# (x# `gtInt32#` zero#) `andInt32#` yn# + !bias# = c0# `subInt32#` c1# + !hard# = c0# `orInt32#` c1# -- See Note [divInt# implementation] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -638,6 +657,65 @@ x# `divModInt#` y# = case (x# +# bias#) `quotRemInt#` y# of -- | (x# ># 0#) && (y# <# 0#) = ((x# -# y#) -# 1#) `quotInt#` y# -- | (x# <# 0#) && (y# ># 0#) = ((x# -# y#) +# 1#) `quotInt#` y# +{-# INLINE [0] modInt# #-} +modInt# :: Int# -> Int# -> Int# +x# `modInt#` y# = r# +# k# + where + -- See Note [modInt# implementation] + !yn# = y# <# 0# + !c0# = (x# <# 0#) `andI#` (notI# yn#) + !c1# = (x# ># 0#) `andI#` yn# + !s# = 0# -# ((c0# `orI#` c1#) `andI#` (r# /=# 0#)) + !k# = s# `andI#` y# + !r# = x# `remInt#` y# + +{-# INLINE [0] modInt8# #-} +modInt8# :: Int8# -> Int8# -> Int8# +x# `modInt8#` y# = r# `plusInt8#` k# + where + zero# = intToInt8# 0# + x `andInt8#` y = word8ToInt8# (int8ToWord8# x `andWord8#` int8ToWord8# y) + x `orInt8#` y = word8ToInt8# (int8ToWord8# x `orWord8#` int8ToWord8# y) + notInt8# x = word8ToInt8# (notWord8# (int8ToWord8# x)) + -- See Note [modInt# implementation] + !yn# = intToInt8# (y# `ltInt8#` zero#) + !c0# = intToInt8# (x# `ltInt8#` zero#) `andInt8#` (notInt8# yn#) + !c1# = intToInt8# (x# `gtInt8#` zero#) `andInt8#` yn# + !s# = zero# `subInt8#` ((c0# `orInt8#` c1#) `andInt8#` (intToInt8# (r# `neInt8#` zero#))) + !k# = s# `andInt8#` y# + !r# = x# `remInt8#` y# + +{-# INLINE [0] modInt16# #-} +modInt16# :: Int16# -> Int16# -> Int16# +x# `modInt16#` y# = r# `plusInt16#` k# + where + zero# = intToInt16# 0# + x `andInt16#` y = word16ToInt16# (int16ToWord16# x `andWord16#` int16ToWord16# y) + x `orInt16#` y = word16ToInt16# (int16ToWord16# x `orWord16#` int16ToWord16# y) + notInt16# x = word16ToInt16# (notWord16# (int16ToWord16# x)) + -- See Note [modInt# implementation] + !yn# = intToInt16# (y# `ltInt16#` zero#) + !c0# = intToInt16# (x# `ltInt16#` zero#) `andInt16#` (notInt16# yn#) + !c1# = intToInt16# (x# `gtInt16#` zero#) `andInt16#` yn# + !s# = zero# `subInt16#` ((c0# `orInt16#` c1#) `andInt16#` (intToInt16# (r# `neInt16#` zero#))) + !k# = s# `andInt16#` y# + !r# = x# `remInt16#` y# + +{-# INLINE [0] modInt32# #-} +modInt32# :: Int32# -> Int32# -> Int32# +x# `modInt32#` y# = r# `plusInt32#` k# + where + zero# = intToInt32# 0# + x `andInt32#` y = word32ToInt32# (int32ToWord32# x `andWord32#` int32ToWord32# y) + x `orInt32#` y = word32ToInt32# (int32ToWord32# x `orWord32#` int32ToWord32# y) + notInt32# x = word32ToInt32# (notWord32# (int32ToWord32# x)) + -- See Note [modInt# implementation] + !yn# = intToInt32# (y# `ltInt32#` zero#) + !c0# = intToInt32# (x# `ltInt32#` zero#) `andInt32#` (notInt32# yn#) + !c1# = intToInt32# (x# `gtInt32#` zero#) `andInt32#` yn# + !s# = zero# `subInt32#` ((c0# `orInt32#` c1#) `andInt32#` (intToInt32# (r# `neInt32#` zero#))) + !k# = s# `andInt32#` y# + !r# = x# `remInt32#` y# -- Note [modInt# implementation] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -689,6 +767,74 @@ x# `divModInt#` y# = case (x# +# bias#) `quotRemInt#` y# of -- k# = s# &&# y# -- r# = x# `remInt#` y# +{-# INLINE [0] divModInt# #-} +divModInt# :: Int# -> Int# -> (# Int#, Int# #) +x# `divModInt#` y# = case (x# +# bias#) `quotRemInt#` y# of + (# q#, r# #) -> (# q# -# hard#, r# +# k# #) + where + -- See Note [divModInt# implementation] + !yn# = y# <# 0# + !c0# = (x# <# 0#) `andI#` (notI# yn#) + !c1# = (x# ># 0#) `andI#` yn# + !bias# = c0# -# c1# + !hard# = c0# `orI#` c1# + !s# = 0# -# hard# + !k# = (s# `andI#` y#) -# bias# + +{-# INLINE [0] divModInt8# #-} +divModInt8# :: Int8# -> Int8# -> (# Int8#, Int8# #) +x# `divModInt8#` y# = case (x# `plusInt8#` bias#) `quotRemInt8#` y# of + (# q#, r# #) -> (# q# `subInt8#` hard#, r# `plusInt8#` k# #) + where + zero# = intToInt8# 0# + x `andInt8#` y = word8ToInt8# (int8ToWord8# x `andWord8#` int8ToWord8# y) + x `orInt8#` y = word8ToInt8# (int8ToWord8# x `orWord8#` int8ToWord8# y) + notInt8# x = word8ToInt8# (notWord8# (int8ToWord8# x)) + -- See Note [divModInt# implementation] + !yn# = intToInt8# (y# `ltInt8#` zero#) + !c0# = intToInt8# (x# `ltInt8#` zero#) `andInt8#` (notInt8# yn#) + !c1# = intToInt8# (x# `gtInt8#` zero#) `andInt8#` yn# + !bias# = c0# `subInt8#` c1# + !hard# = c0# `orInt8#` c1# + !s# = zero# `subInt8#` hard# + !k# = (s# `andInt8#` y#) `subInt8#` bias# + +{-# INLINE [0] divModInt16# #-} +divModInt16# :: Int16# -> Int16# -> (# Int16#, Int16# #) +x# `divModInt16#` y# = case (x# `plusInt16#` bias#) `quotRemInt16#` y# of + (# q#, r# #) -> (# q# `subInt16#` hard#, r# `plusInt16#` k# #) + where + zero# = intToInt16# 0# + x `andInt16#` y = word16ToInt16# (int16ToWord16# x `andWord16#` int16ToWord16# y) + x `orInt16#` y = word16ToInt16# (int16ToWord16# x `orWord16#` int16ToWord16# y) + notInt16# x = word16ToInt16# (notWord16# (int16ToWord16# x)) + -- See Note [divModInt# implementation] + !yn# = intToInt16# (y# `ltInt16#` zero#) + !c0# = intToInt16# (x# `ltInt16#` zero#) `andInt16#` (notInt16# yn#) + !c1# = intToInt16# (x# `gtInt16#` zero#) `andInt16#` yn# + !bias# = c0# `subInt16#` c1# + !hard# = c0# `orInt16#` c1# + !s# = zero# `subInt16#` hard# + !k# = (s# `andInt16#` y#) `subInt16#` bias# + +{-# INLINE [0] divModInt32# #-} +divModInt32# :: Int32# -> Int32# -> (# Int32#, Int32# #) +x# `divModInt32#` y# = case (x# `plusInt32#` bias#) `quotRemInt32#` y# of + (# q#, r# #) -> (# q# `subInt32#` hard#, r# `plusInt32#` k# #) + where + zero# = intToInt32# 0# + x `andInt32#` y = word32ToInt32# (int32ToWord32# x `andWord32#` int32ToWord32# y) + x `orInt32#` y = word32ToInt32# (int32ToWord32# x `orWord32#` int32ToWord32# y) + notInt32# x = word32ToInt32# (notWord32# (int32ToWord32# x)) + -- See Note [divModInt# implementation] + !yn# = intToInt32# (y# `ltInt32#` zero#) + !c0# = intToInt32# (x# `ltInt32#` zero#) `andInt32#` (notInt32# yn#) + !c1# = intToInt32# (x# `gtInt32#` zero#) `andInt32#` yn# + !bias# = c0# `subInt32#` c1# + !hard# = c0# `orInt32#` c1# + !s# = zero# `subInt32#` hard# + !k# = (s# `andInt32#` y#) `subInt32#` bias# + -- Note [divModInt# implementation] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- |