summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ericson <git@JohnEricson.me>2019-10-19 18:59:48 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-05-06 02:30:54 -0400
commitc4f4193a13f751380e4cedbc2688a339f69325c9 (patch)
treee9cf1fb7f05d99dbbe1dcec7c1e526932220d9c5
parenta5e9e5b601fecef421ec4bfa28e135404986ded0 (diff)
downloadhaskell-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
-rw-r--r--libraries/base/GHC/Int.hs84
-rw-r--r--libraries/base/GHC/Word.hs61
-rw-r--r--libraries/ghc-prim/GHC/Classes.hs202
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]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--