{-|
Copyright  :  (C) 2013-2016, University of Twente,
                  2016     , Myrtle Software Ltd,
                  2021     , QBayLogic B.V.
License    :  BSD2 (see the file LICENSE)
Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>
-}

{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

{-# LANGUAGE Unsafe #-}

{-# OPTIONS_HADDOCK show-extensions not-home #-}
{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}
{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}

module Clash.Sized.Internal.Signed
  ( -- * Datatypes
    Signed (..)
    -- * Accessors
    -- ** Length information
  , size#
    -- * Type classes
    -- ** BitPack
  , pack#
  , unpack#
    -- ** Eq
  , eq#
  , neq#
    -- ** Ord
  , lt#
  , ge#
  , gt#
  , le#
    -- ** Enum (not synthesizable)
  , enumFrom#
  , enumFromThen#
  , enumFromTo#
  , enumFromThenTo#
    -- ** Bounded
  , minBound#
  , maxBound#
    -- ** Num
  , (+#)
  , (-#)
  , (*#)
  , negate#
  , abs#
  , fromInteger#
    -- ** ExtendingNum
  , plus#
  , minus#
  , times#
    -- ** Integral
  , quot#
  , rem#
  , div#
  , mod#
  , toInteger#
    -- ** Bits
  , and#
  , or#
  , xor#
  , complement#
  , shiftL#
  , shiftR#
  , rotateL#
  , rotateR#
    -- ** Resize
  , resize#
  , truncateB#
    -- ** SaturatingNum
  , minBoundSym#
  )
where

import Prelude hiding                 (odd, even)

import Control.DeepSeq                (NFData (..))
import Control.Lens                   (Index, Ixed (..), IxValue)
import Data.Bits                      (Bits (..), FiniteBits (..))
import Data.Data                      (Data)
import Data.Default.Class             (Default (..))
import Data.Proxy                     (Proxy (..))
import Text.Read                      (Read (..), ReadPrec)
import Text.Printf                    (PrintfArg (..), printf)
import GHC.Generics                   (Generic)
import GHC.Natural                    (naturalFromInteger, naturalToInteger)

import GHC.TypeLits                   (KnownNat, Nat, type (+), natVal)
import GHC.TypeLits.Extra             (Max)
import Data.Ix                        (Ix(..))
import Language.Haskell.TH            (appT, conT, litT, numTyLit, sigE)
import Language.Haskell.TH.Syntax     (Lift(..))
#if MIN_VERSION_template_haskell(2,16,0)
import Language.Haskell.TH.Compat
#endif
#if MIN_VERSION_template_haskell(2,17,0)
import Language.Haskell.TH            (Quote, Type)
#else
import Language.Haskell.TH            (TypeQ)
#endif
import Test.QuickCheck.Arbitrary      (Arbitrary (..), CoArbitrary (..),
                                       arbitraryBoundedIntegral,
                                       coarbitraryIntegral, shrinkIntegral)

import Clash.Class.BitPack            (BitPack (..), packXWith)
import Clash.Class.Num                (ExtendingNum (..), SaturatingNum (..),
                                       SaturationMode (..))
import Clash.Class.Parity             (Parity (..))
import Clash.Class.Resize             (Resize (..))
import Clash.Class.BitPack.BitIndex   ((!), msb, replaceBit, split)
import Clash.Class.BitPack.BitReduction (reduceAnd, reduceOr)
import Clash.Promoted.Nat             (natToNatural)
import Clash.Sized.Internal.BitVector (BitVector (BV), Bit, (++#), high, low, undefError)
import qualified Clash.Sized.Internal.BitVector as BV
import Clash.XException
  (ShowX (..), NFDataX (..), errorX, showsPrecXWith, rwhnfX)

type role Signed nominal

-- | Arbitrary-width signed integer represented by @n@ bits, including the sign
-- bit.
--
-- Uses standard 2-complements representation. Meaning that, given @n@ bits,
-- a 'Signed' @n@ number has a range of: [-(2^(@n@-1)) .. 2^(@n@-1)-1] for
-- @n > 0@. When @n = 0@, both the min and max bound are 0.
--
-- __NB__: The 'Num' operators perform @wrap-around@ on overflow. If you want
-- saturation on overflow, check out the 'SaturatingNum' class.
--
-- >>>  maxBound :: Signed 3
-- 3
-- >>> minBound :: Signed 3
-- -4
-- >>> read (show (minBound :: Signed 3)) :: Signed 3
-- -4
-- >>> 1 + 2 :: Signed 3
-- 3
-- >>> 2 + 3 :: Signed 3
-- -3
-- >>> (-2) + (-3) :: Signed 3
-- 3
-- >>> 2 * 3 :: Signed 4
-- 6
-- >>> 2 * 4 :: Signed 4
-- -8
-- >>> (2 :: Signed 3) `mul` (4 :: Signed 4) :: Signed 7
-- 8
-- >>> (2 :: Signed 3) `add` (3 :: Signed 3) :: Signed 4
-- 5
-- >>> (-2 :: Signed 3) `add` (-3 :: Signed 3) :: Signed 4
-- -5
-- >>> satAdd SatSymmetric 2 3 :: Signed 3
-- 3
-- >>> satAdd SatSymmetric (-2) (-3) :: Signed 3
-- -3
--
-- Signed has the <https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#roles type role>
--
-- >>> :i Signed
-- type role Signed nominal
-- ...
--
-- as it is not safe to coerce between different width Signed. To change the
-- width, use the functions in the 'Clash.Class.Resize.Resize' class.
#if MIN_VERSION_base(4,15,0)
data Signed (n :: Nat) =
    -- | The constructor, 'S', and the field, 'unsafeToInteger', are not
    -- synthesizable.
    S { unsafeToInteger :: !Integer}
#else
newtype Signed (n :: Nat) =
    -- | The constructor, 'S', and the field, 'unsafeToInteger', are not
    -- synthesizable.
    S { Signed n -> Integer
unsafeToInteger :: Integer}
#endif
  deriving (Typeable (Signed n)
DataType
Constr
Typeable (Signed n)
-> (forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Signed n -> c (Signed n))
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Signed n))
-> (Signed n -> Constr)
-> (Signed n -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Signed n)))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Signed n)))
-> ((forall b. Data b => b -> b) -> Signed n -> Signed n)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Signed n -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Signed n -> r)
-> (forall u. (forall d. Data d => d -> u) -> Signed n -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Signed n -> u)
-> (forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> Signed n -> m (Signed n))
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Signed n -> m (Signed n))
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Signed n -> m (Signed n))
-> Data (Signed n)
Signed n -> DataType
Signed n -> Constr
(forall b. Data b => b -> b) -> Signed n -> Signed n
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Signed n -> c (Signed n)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Signed n)
forall a.
Typeable a
-> (forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Signed n -> u
forall u. (forall d. Data d => d -> u) -> Signed n -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Signed n -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Signed n -> r
forall (n :: Nat). KnownNat n => Typeable (Signed n)
forall (n :: Nat). KnownNat n => Signed n -> DataType
forall (n :: Nat). KnownNat n => Signed n -> Constr
forall (n :: Nat).
KnownNat n =>
(forall b. Data b => b -> b) -> Signed n -> Signed n
forall (n :: Nat) u.
KnownNat n =>
Int -> (forall d. Data d => d -> u) -> Signed n -> u
forall (n :: Nat) u.
KnownNat n =>
(forall d. Data d => d -> u) -> Signed n -> [u]
forall (n :: Nat) r r'.
KnownNat n =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Signed n -> r
forall (n :: Nat) r r'.
KnownNat n =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Signed n -> r
forall (n :: Nat) (m :: Type -> Type).
(KnownNat n, Monad m) =>
(forall d. Data d => d -> m d) -> Signed n -> m (Signed n)
forall (n :: Nat) (m :: Type -> Type).
(KnownNat n, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Signed n -> m (Signed n)
forall (n :: Nat) (c :: Type -> Type).
KnownNat n =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Signed n)
forall (n :: Nat) (c :: Type -> Type).
KnownNat n =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Signed n -> c (Signed n)
forall (n :: Nat) (t :: Type -> Type) (c :: Type -> Type).
(KnownNat n, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Signed n))
forall (n :: Nat) (t :: Type -> Type -> Type) (c :: Type -> Type).
(KnownNat n, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Signed n))
forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> Signed n -> m (Signed n)
forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Signed n -> m (Signed n)
forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Signed n)
forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Signed n -> c (Signed n)
forall (t :: Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Signed n))
forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Signed n))
$cS :: Constr
$tSigned :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Signed n -> m (Signed n)
$cgmapMo :: forall (n :: Nat) (m :: Type -> Type).
(KnownNat n, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Signed n -> m (Signed n)
gmapMp :: (forall d. Data d => d -> m d) -> Signed n -> m (Signed n)
$cgmapMp :: forall (n :: Nat) (m :: Type -> Type).
(KnownNat n, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Signed n -> m (Signed n)
gmapM :: (forall d. Data d => d -> m d) -> Signed n -> m (Signed n)
$cgmapM :: forall (n :: Nat) (m :: Type -> Type).
(KnownNat n, Monad m) =>
(forall d. Data d => d -> m d) -> Signed n -> m (Signed n)
gmapQi :: Int -> (forall d. Data d => d -> u) -> Signed n -> u
$cgmapQi :: forall (n :: Nat) u.
KnownNat n =>
Int -> (forall d. Data d => d -> u) -> Signed n -> u
gmapQ :: (forall d. Data d => d -> u) -> Signed n -> [u]
$cgmapQ :: forall (n :: Nat) u.
KnownNat n =>
(forall d. Data d => d -> u) -> Signed n -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Signed n -> r
$cgmapQr :: forall (n :: Nat) r r'.
KnownNat n =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Signed n -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Signed n -> r
$cgmapQl :: forall (n :: Nat) r r'.
KnownNat n =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Signed n -> r
gmapT :: (forall b. Data b => b -> b) -> Signed n -> Signed n
$cgmapT :: forall (n :: Nat).
KnownNat n =>
(forall b. Data b => b -> b) -> Signed n -> Signed n
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Signed n))
$cdataCast2 :: forall (n :: Nat) (t :: Type -> Type -> Type) (c :: Type -> Type).
(KnownNat n, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Signed n))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (Signed n))
$cdataCast1 :: forall (n :: Nat) (t :: Type -> Type) (c :: Type -> Type).
(KnownNat n, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Signed n))
dataTypeOf :: Signed n -> DataType
$cdataTypeOf :: forall (n :: Nat). KnownNat n => Signed n -> DataType
toConstr :: Signed n -> Constr
$ctoConstr :: forall (n :: Nat). KnownNat n => Signed n -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Signed n)
$cgunfold :: forall (n :: Nat) (c :: Type -> Type).
KnownNat n =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Signed n)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Signed n -> c (Signed n)
$cgfoldl :: forall (n :: Nat) (c :: Type -> Type).
KnownNat n =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Signed n -> c (Signed n)
$cp1Data :: forall (n :: Nat). KnownNat n => Typeable (Signed n)
Data, (forall x. Signed n -> Rep (Signed n) x)
-> (forall x. Rep (Signed n) x -> Signed n) -> Generic (Signed n)
forall x. Rep (Signed n) x -> Signed n
forall x. Signed n -> Rep (Signed n) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (n :: Nat) x. Rep (Signed n) x -> Signed n
forall (n :: Nat) x. Signed n -> Rep (Signed n) x
$cto :: forall (n :: Nat) x. Rep (Signed n) x -> Signed n
$cfrom :: forall (n :: Nat) x. Signed n -> Rep (Signed n) x
Generic)

instance NFDataX (Signed n) where
  deepErrorX :: String -> Signed n
deepErrorX = String -> Signed n
forall a. HasCallStack => String -> a
errorX
  rnfX :: Signed n -> ()
rnfX = Signed n -> ()
forall a. a -> ()
rwhnfX

{-# NOINLINE size# #-}
size# :: KnownNat n => Signed n -> Int
size# :: Signed n -> Int
size# Signed n
bv = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Signed n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal Signed n
bv)

instance NFData (Signed n) where
  rnf :: Signed n -> ()
rnf (S Integer
i) = Integer -> ()
forall a. NFData a => a -> ()
rnf Integer
i () -> () -> ()
`seq` ()
  {-# NOINLINE rnf #-}
  -- NOINLINE is needed so that Clash doesn't trip on the "Signed ~# Integer"
  -- coercion

instance Show (Signed n) where
  show :: Signed n -> String
show (S Integer
i) = Integer -> String
forall a. Show a => a -> String
show Integer
i
  {-# NOINLINE show #-}

instance ShowX (Signed n) where
  showsPrecX :: Int -> Signed n -> ShowS
showsPrecX = (Int -> Signed n -> ShowS) -> Int -> Signed n -> ShowS
forall a. (Int -> a -> ShowS) -> Int -> a -> ShowS
showsPrecXWith Int -> Signed n -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec

-- | None of the 'Read' class' methods are synthesizable.
instance KnownNat n => Read (Signed n) where
  readPrec :: ReadPrec (Signed n)
readPrec = Integer -> Signed n
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Signed n) -> ReadPrec Integer -> ReadPrec (Signed n)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (ReadPrec Integer
forall a. Read a => ReadPrec a
readPrec :: ReadPrec Integer)

instance KnownNat n => BitPack (Signed n) where
  type BitSize (Signed n) = n
  pack :: Signed n -> BitVector (BitSize (Signed n))
pack   = (Signed n -> BitVector n) -> Signed n -> BitVector n
forall (n :: Nat) a.
KnownNat n =>
(a -> BitVector n) -> a -> BitVector n
packXWith Signed n -> BitVector n
forall (n :: Nat). KnownNat n => Signed n -> BitVector n
pack#
  unpack :: BitVector (BitSize (Signed n)) -> Signed n
unpack = BitVector (BitSize (Signed n)) -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack#

{-# NOINLINE pack# #-}
pack# :: forall n . KnownNat n => Signed n -> BitVector n
pack# :: Signed n -> BitVector n
pack# (S Integer
i) = let m :: Integer
m = Integer
1 Integer -> Int -> Integer
`shiftL0` Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n))
              in  if Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 then Natural -> Natural -> BitVector n
forall (n :: Nat). Natural -> Natural -> BitVector n
BV Natural
0 (Integer -> Natural
naturalFromInteger (Integer
m Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
i)) else Natural -> Natural -> BitVector n
forall (n :: Nat). Natural -> Natural -> BitVector n
BV Natural
0 (Integer -> Natural
naturalFromInteger Integer
i)

{-# NOINLINE unpack# #-}
unpack# :: forall n . KnownNat n => BitVector n -> Signed n
unpack# :: BitVector n -> Signed n
unpack# (BV Natural
0 Natural
i) =
  let m :: Integer
m = Integer
1 Integer -> Int -> Integer
`shiftL0` Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1)
      n :: Integer
n = Natural -> Integer
naturalToInteger Natural
i
  in  if Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
m then Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
m) else Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
n
unpack# BitVector n
bv = String -> [BitVector n] -> Signed n
forall (n :: Nat) a.
(HasCallStack, KnownNat n) =>
String -> [BitVector n] -> a
undefError String
"Signed.unpack" [BitVector n
bv]

instance Eq (Signed n) where
  == :: Signed n -> Signed n -> Bool
(==) = Signed n -> Signed n -> Bool
forall (n :: Nat). Signed n -> Signed n -> Bool
eq#
  /= :: Signed n -> Signed n -> Bool
(/=) = Signed n -> Signed n -> Bool
forall (n :: Nat). Signed n -> Signed n -> Bool
neq#

{-# NOINLINE eq# #-}
eq# :: Signed n -> Signed n -> Bool
eq# :: Signed n -> Signed n -> Bool
eq# (S Integer
v1) (S Integer
v2) = Integer
v1 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
v2

{-# NOINLINE neq# #-}
neq# :: Signed n -> Signed n -> Bool
neq# :: Signed n -> Signed n -> Bool
neq# (S Integer
v1) (S Integer
v2) = Integer
v1 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
v2

instance Ord (Signed n) where
  < :: Signed n -> Signed n -> Bool
(<)  = Signed n -> Signed n -> Bool
forall (n :: Nat). Signed n -> Signed n -> Bool
lt#
  >= :: Signed n -> Signed n -> Bool
(>=) = Signed n -> Signed n -> Bool
forall (n :: Nat). Signed n -> Signed n -> Bool
ge#
  > :: Signed n -> Signed n -> Bool
(>)  = Signed n -> Signed n -> Bool
forall (n :: Nat). Signed n -> Signed n -> Bool
gt#
  <= :: Signed n -> Signed n -> Bool
(<=) = Signed n -> Signed n -> Bool
forall (n :: Nat). Signed n -> Signed n -> Bool
le#

lt#,ge#,gt#,le# :: Signed n -> Signed n -> Bool
{-# NOINLINE lt# #-}
lt# :: Signed n -> Signed n -> Bool
lt# (S Integer
n) (S Integer
m) = Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
m
{-# NOINLINE ge# #-}
ge# :: Signed n -> Signed n -> Bool
ge# (S Integer
n) (S Integer
m) = Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
m
{-# NOINLINE gt# #-}
gt# :: Signed n -> Signed n -> Bool
gt# (S Integer
n) (S Integer
m) = Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
m
{-# NOINLINE le# #-}
le# :: Signed n -> Signed n -> Bool
le# (S Integer
n) (S Integer
m) = Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
m

-- | The functions: 'enumFrom', 'enumFromThen', 'enumFromTo', and
-- 'enumFromThenTo', are not synthesizable.
instance KnownNat n => Enum (Signed n) where
  succ :: Signed n -> Signed n
succ Signed n
n
    | Signed n
n Signed n -> Signed n -> Bool
forall a. Eq a => a -> a -> Bool
== Signed n
forall a. Bounded a => a
maxBound =
        String -> Signed n
forall a. HasCallStack => String -> a
error (String -> Signed n) -> String -> Signed n
forall a b. (a -> b) -> a -> b
$ String
"'succ' was called on (" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Signed n -> String
forall a. Show a => a -> String
show @(Signed n) Signed n
forall a. Bounded a => a
maxBound String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" :: "
             String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"Signed " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Natural -> String
forall a. Show a => a -> String
show (KnownNat n => Natural
forall (n :: Nat). KnownNat n => Natural
natToNatural @n) String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
") and caused an "
             String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"overflow. Use 'satSucc' and specify a SaturationMode if you "
             String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"need other behavior."
    | Bool
otherwise = Signed n
n Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
+# Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# Integer
1

  pred :: Signed n -> Signed n
pred Signed n
n
    | Signed n
n Signed n -> Signed n -> Bool
forall a. Eq a => a -> a -> Bool
== Signed n
forall a. Bounded a => a
minBound =
        String -> Signed n
forall a. HasCallStack => String -> a
error (String -> Signed n) -> String -> Signed n
forall a b. (a -> b) -> a -> b
$ String
"'pred' was called on (" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Signed n -> String
forall a. Show a => a -> String
show @(Signed n) Signed n
forall a. Bounded a => a
maxBound String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" :: "
             String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"Signed " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Natural -> String
forall a. Show a => a -> String
show (KnownNat n => Natural
forall (n :: Nat). KnownNat n => Natural
natToNatural @n) String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
") and caused an "
             String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"underflow. Use 'satPred' and specify a SaturationMode if you "
             String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"need other behavior."
    | Bool
otherwise = Signed n
n Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
-# Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# Integer
1

  toEnum :: Int -> Signed n
toEnum         = Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# (Integer -> Signed n) -> (Int -> Integer) -> Int -> Signed n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a. Integral a => a -> Integer
toInteger
  fromEnum :: Signed n -> Int
fromEnum       = Integer -> Int
forall a. Enum a => a -> Int
fromEnum (Integer -> Int) -> (Signed n -> Integer) -> Signed n -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
toInteger#
  enumFrom :: Signed n -> [Signed n]
enumFrom       = Signed n -> [Signed n]
forall (n :: Nat). KnownNat n => Signed n -> [Signed n]
enumFrom#
  enumFromThen :: Signed n -> Signed n -> [Signed n]
enumFromThen   = Signed n -> Signed n -> [Signed n]
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> [Signed n]
enumFromThen#
  enumFromTo :: Signed n -> Signed n -> [Signed n]
enumFromTo     = Signed n -> Signed n -> [Signed n]
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> [Signed n]
enumFromTo#
  enumFromThenTo :: Signed n -> Signed n -> Signed n -> [Signed n]
enumFromThenTo = Signed n -> Signed n -> Signed n -> [Signed n]
forall (n :: Nat).
KnownNat n =>
Signed n -> Signed n -> Signed n -> [Signed n]
enumFromThenTo#


enumFrom# :: forall n. KnownNat n => Signed n -> [Signed n]
enumFrom# :: Signed n -> [Signed n]
enumFrom# Signed n
x = (Integer -> Signed n) -> [Integer] -> [Signed n]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask) [Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
unsafeToInteger Signed n
x .. Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
unsafeToInteger (Signed n
forall a. Bounded a => a
maxBound :: Signed n)]
  where sz :: Int
sz   = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        mB :: Integer
mB   = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
        mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1
{-# NOINLINE enumFrom# #-}

enumFromThen# :: forall n. KnownNat n => Signed n -> Signed n -> [Signed n]
enumFromThen# :: Signed n -> Signed n -> [Signed n]
enumFromThen# Signed n
x Signed n
y =
  [Integer] -> [Signed n]
toSigneds [Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
unsafeToInteger Signed n
x, Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
unsafeToInteger Signed n
y .. Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
unsafeToInteger Signed n
bound]
 where
  bound :: Signed n
bound = if Signed n
x Signed n -> Signed n -> Bool
forall a. Ord a => a -> a -> Bool
<= Signed n
y then Signed n
forall a. Bounded a => a
maxBound else Signed n
forall a. Bounded a => a
minBound :: Signed n
  toSigneds :: [Integer] -> [Signed n]
toSigneds = (Integer -> Signed n) -> [Integer] -> [Signed n]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask)
  sz :: Int
sz = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
  mB :: Integer
mB = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
  mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1
{-# NOINLINE enumFromThen# #-}

enumFromTo# :: forall n. KnownNat n => Signed n -> Signed n -> [Signed n]
enumFromTo# :: Signed n -> Signed n -> [Signed n]
enumFromTo# Signed n
x Signed n
y = (Integer -> Signed n) -> [Integer] -> [Signed n]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask) [Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
unsafeToInteger Signed n
x .. Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
unsafeToInteger Signed n
y]
  where sz :: Int
sz   = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        mB :: Integer
mB   = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
        mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1
{-# NOINLINE enumFromTo# #-}

enumFromThenTo# :: forall n. KnownNat n => Signed n -> Signed n -> Signed n -> [Signed n]
enumFromThenTo# :: Signed n -> Signed n -> Signed n -> [Signed n]
enumFromThenTo# Signed n
x1 Signed n
x2 Signed n
y = (Integer -> Signed n) -> [Integer] -> [Signed n]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask) [Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
unsafeToInteger Signed n
x1, Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
unsafeToInteger Signed n
x2 .. Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
unsafeToInteger Signed n
y]
  where sz :: Int
sz   = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        mB :: Integer
mB   = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
        mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1
{-# NOINLINE enumFromThenTo# #-}


instance KnownNat n => Bounded (Signed n) where
  minBound :: Signed n
minBound = Signed n
forall (n :: Nat). KnownNat n => Signed n
minBound#
  maxBound :: Signed n
maxBound = Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#

minBound# :: forall n. KnownNat n => Signed n
minBound# :: Signed n
minBound# =
  case KnownNat n => Natural
forall (n :: Nat). KnownNat n => Natural
natToNatural @n of
    Natural
0 -> Signed n
0
    Natural
n -> Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer -> Integer
forall a. Num a => a -> a
negate (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ Integer
2 Integer -> Natural -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Natural
n Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
- Natural
1))
{-# NOINLINE minBound# #-}

maxBound# :: forall n. KnownNat n => Signed n
maxBound# :: Signed n
maxBound# =
  case KnownNat n => Natural
forall (n :: Nat). KnownNat n => Natural
natToNatural @n of
    Natural
0 -> Signed n
0
    Natural
n -> Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer
2 Integer -> Natural -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Natural
n Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
- Natural
1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1)
{-# NOINLINE maxBound# #-}

-- | Operators do @wrap-around@ on overflow
instance KnownNat n => Num (Signed n) where
  + :: Signed n -> Signed n -> Signed n
(+)         = Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
(+#)
  (-)         = Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
(-#)
  * :: Signed n -> Signed n -> Signed n
(*)         = Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
(*#)
  negate :: Signed n -> Signed n
negate      = Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n
negate#
  abs :: Signed n -> Signed n
abs         = Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n
abs#
  signum :: Signed n -> Signed n
signum Signed n
s    = if Signed n
s Signed n -> Signed n -> Bool
forall a. Ord a => a -> a -> Bool
< Signed n
0 then (-Signed n
1) else
                   if Signed n
s Signed n -> Signed n -> Bool
forall a. Ord a => a -> a -> Bool
> Signed n
0 then Signed n
1 else Signed n
0
  fromInteger :: Integer -> Signed n
fromInteger = Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger#

(+#), (-#), (*#) :: forall n . KnownNat n => Signed n -> Signed n -> Signed n
{-# NOINLINE (+#) #-}
+# :: Signed n -> Signed n -> Signed n
(+#) =
  \(S Integer
a) (S Integer
b) ->
    let z :: Integer
z = Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
b
    in  if Integer
z Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
m then
          Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer
z Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
m)
        else if Integer
z Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer -> Integer
forall a. Num a => a -> a
negate Integer
m then
          Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer
z Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
m)
        else
          Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
z
 where
  m :: Integer
m = Integer
1 Integer -> Int -> Integer
`shiftL0` Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)

{-# NOINLINE (-#) #-}
-# :: Signed n -> Signed n -> Signed n
(-#) =
  \(S Integer
a) (S Integer
b) ->
    let z :: Integer
z = Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
b
    in  if Integer
z Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer -> Integer
forall a. Num a => a -> a
negate Integer
m then
          Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer
z Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
m)
        else if Integer
z Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
m then
          Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer
z Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
m)
        else
          Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
z
 where
  m :: Integer
m  = Integer
1 Integer -> Int -> Integer
`shiftL0` Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)

{-# NOINLINE (*#) #-}
*# :: Signed n -> Signed n -> Signed n
(*#) = \(S Integer
a) (S Integer
b) -> Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask (Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
b)
  where sz :: Int
sz   = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        mB :: Integer
mB   = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
        mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

negate#,abs# :: forall n . KnownNat n => Signed n -> Signed n
{-# NOINLINE negate# #-}
negate# :: Signed n -> Signed n
negate# =
  \(S Integer
n) ->
    let z :: Integer
z = Integer -> Integer
forall a. Num a => a -> a
negate Integer
n
    in  if Integer
z Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
m then Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
n else Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
z
 where
  m :: Integer
m = Integer
1 Integer -> Int -> Integer
`shiftL0` Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)

{-# NOINLINE abs# #-}
abs# :: Signed n -> Signed n
abs# =
  \(S Integer
n) ->
    let z :: Integer
z = Integer -> Integer
forall a. Num a => a -> a
abs Integer
n
    in  if Integer
z Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
m then Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
n else Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
z
 where
  m :: Integer
m = Integer
1 Integer -> Int -> Integer
`shiftL0` Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)

{-# NOINLINE fromInteger# #-}
fromInteger# :: forall n . KnownNat n => Integer -> Signed (n :: Nat)
fromInteger# :: Integer -> Signed n
fromInteger# = Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask
  where sz :: Int
sz   = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        mB :: Integer
mB   = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
        mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

{-# INLINE fromInteger_INLINE #-}
fromInteger_INLINE :: Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE :: Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mb Integer
mask =
  \Integer
i -> let i1 :: Integer
i1 = Integer
i Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
mask
            i2 :: Integer
i2 = case Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
sz of
                   Integer
q | Integer
q Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
1 Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 -> Integer
i1
                     | Bool
otherwise    -> Integer
i1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
mb
        in  if Int
sz Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
0 else Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
i2

instance ExtendingNum (Signed m) (Signed n) where
  type AResult (Signed m) (Signed n) = Signed (Max m n + 1)
  add :: Signed m -> Signed n -> AResult (Signed m) (Signed n)
add  = Signed m -> Signed n -> AResult (Signed m) (Signed n)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (Max m n + 1)
plus#
  sub :: Signed m -> Signed n -> AResult (Signed m) (Signed n)
sub = Signed m -> Signed n -> AResult (Signed m) (Signed n)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (Max m n + 1)
minus#
  type MResult (Signed m) (Signed n) = Signed (m + n)
  mul :: Signed m -> Signed n -> MResult (Signed m) (Signed n)
mul = Signed m -> Signed n -> MResult (Signed m) (Signed n)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (m + n)
times#

plus#, minus# :: Signed m -> Signed n -> Signed (Max m n + 1)
{-# NOINLINE plus# #-}
plus# :: Signed m -> Signed n -> Signed (Max m n + 1)
plus# (S Integer
a) (S Integer
b) = Integer -> Signed (Max m n + 1)
forall (n :: Nat). Integer -> Signed n
S (Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
b)

{-# NOINLINE minus# #-}
minus# :: Signed m -> Signed n -> Signed (Max m n + 1)
minus# (S Integer
a) (S Integer
b) = Integer -> Signed (Max m n + 1)
forall (n :: Nat). Integer -> Signed n
S (Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
b)

{-# NOINLINE times# #-}
times# :: Signed m -> Signed n -> Signed (m + n)
times# :: Signed m -> Signed n -> Signed (m + n)
times# (S Integer
a) (S Integer
b) = Integer -> Signed (m + n)
forall (n :: Nat). Integer -> Signed n
S (Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
b)

instance KnownNat n => Real (Signed n) where
  toRational :: Signed n -> Rational
toRational = Integer -> Rational
forall a. Real a => a -> Rational
toRational (Integer -> Rational)
-> (Signed n -> Integer) -> Signed n -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
toInteger#

instance KnownNat n => Integral (Signed n) where
  quot :: Signed n -> Signed n -> Signed n
quot        = Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
quot#
  rem :: Signed n -> Signed n -> Signed n
rem         = Signed n -> Signed n -> Signed n
forall (n :: Nat). Signed n -> Signed n -> Signed n
rem#
  div :: Signed n -> Signed n -> Signed n
div         = Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
div#
  mod :: Signed n -> Signed n -> Signed n
mod         = Signed n -> Signed n -> Signed n
forall (n :: Nat). Signed n -> Signed n -> Signed n
mod#
  quotRem :: Signed n -> Signed n -> (Signed n, Signed n)
quotRem Signed n
n Signed n
d = (Signed n
n Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
`quot#` Signed n
d,Signed n
n Signed n -> Signed n -> Signed n
forall (n :: Nat). Signed n -> Signed n -> Signed n
`rem#` Signed n
d)
  divMod :: Signed n -> Signed n -> (Signed n, Signed n)
divMod  Signed n
n Signed n
d = (Signed n
n Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
`div#`  Signed n
d,Signed n
n Signed n -> Signed n -> Signed n
forall (n :: Nat). Signed n -> Signed n -> Signed n
`mod#` Signed n
d)
  toInteger :: Signed n -> Integer
toInteger   = Signed n -> Integer
forall (n :: Nat). Signed n -> Integer
toInteger#

{-# NOINLINE quot# #-}
quot# :: forall n. KnownNat n => Signed n -> Signed n -> Signed n
quot# :: Signed n -> Signed n -> Signed n
quot# (S Integer
a) (S Integer
b)
  | Integer
a Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
minB Bool -> Bool -> Bool
&& Integer
b Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== (-Integer
1) = Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
minB
  | Bool
otherwise = Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer
a Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`quot` Integer
b)
 where
  S Integer
minB = Bounded (Signed n) => Signed n
forall a. Bounded a => a
minBound @(Signed n)

{-# NOINLINE rem# #-}
rem# :: Signed n -> Signed n -> Signed n
rem# :: Signed n -> Signed n -> Signed n
rem# (S Integer
a) (S Integer
b) = Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer
a Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`rem` Integer
b)

{-# NOINLINE div# #-}
div# :: forall n. KnownNat n => Signed n -> Signed n -> Signed n
div# :: Signed n -> Signed n -> Signed n
div# (S Integer
a) (S Integer
b)
  | Integer
a Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
minB Bool -> Bool -> Bool
&& Integer
b Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== (-Integer
1) = Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
minB
  | Bool
otherwise = Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer
a Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
b)
 where
  S Integer
minB = Bounded (Signed n) => Signed n
forall a. Bounded a => a
minBound @(Signed n)

{-# NOINLINE mod# #-}
mod# :: Signed n -> Signed n -> Signed n
mod# :: Signed n -> Signed n -> Signed n
mod# (S Integer
a) (S Integer
b) = Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer
a Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
b)

{-# NOINLINE toInteger# #-}
toInteger# :: Signed n -> Integer
toInteger# :: Signed n -> Integer
toInteger# (S Integer
n) = Integer
n

instance KnownNat n => PrintfArg (Signed n) where
  formatArg :: Signed n -> FieldFormatter
formatArg = Integer -> FieldFormatter
forall a. PrintfArg a => a -> FieldFormatter
formatArg (Integer -> FieldFormatter)
-> (Signed n -> Integer) -> Signed n -> FieldFormatter
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signed n -> Integer
forall a. Integral a => a -> Integer
toInteger

instance KnownNat n => Parity (Signed n) where
  even :: Signed n -> Bool
even = BitVector n -> Bool
forall a. Parity a => a -> Bool
even (BitVector n -> Bool)
-> (Signed n -> BitVector n) -> Signed n -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signed n -> BitVector n
forall a. BitPack a => a -> BitVector (BitSize a)
pack
  odd :: Signed n -> Bool
odd = BitVector n -> Bool
forall a. Parity a => a -> Bool
odd (BitVector n -> Bool)
-> (Signed n -> BitVector n) -> Signed n -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signed n -> BitVector n
forall a. BitPack a => a -> BitVector (BitSize a)
pack

instance KnownNat n => Bits (Signed n) where
  .&. :: Signed n -> Signed n -> Signed n
(.&.)             = Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
and#
  .|. :: Signed n -> Signed n -> Signed n
(.|.)             = Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
or#
  xor :: Signed n -> Signed n -> Signed n
xor               = Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
xor#
  complement :: Signed n -> Signed n
complement        = Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n
complement#
  zeroBits :: Signed n
zeroBits          = Signed n
0
  bit :: Int -> Signed n
bit Int
i             = Int -> Bit -> Signed n -> Signed n
forall a i. (BitPack a, Enum i) => i -> Bit -> a -> a
replaceBit Int
i Bit
high Signed n
0
  setBit :: Signed n -> Int -> Signed n
setBit Signed n
v Int
i        = Int -> Bit -> Signed n -> Signed n
forall a i. (BitPack a, Enum i) => i -> Bit -> a -> a
replaceBit Int
i Bit
high Signed n
v
  clearBit :: Signed n -> Int -> Signed n
clearBit Signed n
v Int
i      = Int -> Bit -> Signed n -> Signed n
forall a i. (BitPack a, Enum i) => i -> Bit -> a -> a
replaceBit Int
i Bit
low  Signed n
v
  complementBit :: Signed n -> Int -> Signed n
complementBit Signed n
v Int
i = Int -> Bit -> Signed n -> Signed n
forall a i. (BitPack a, Enum i) => i -> Bit -> a -> a
replaceBit Int
i (Bit -> Bit
BV.complement## (Signed n
v Signed n -> Int -> Bit
forall a i. (BitPack a, Enum i) => a -> i -> Bit
! Int
i)) Signed n
v
  testBit :: Signed n -> Int -> Bool
testBit Signed n
v Int
i       = Signed n
v Signed n -> Int -> Bit
forall a i. (BitPack a, Enum i) => a -> i -> Bit
! Int
i Bit -> Bit -> Bool
forall a. Eq a => a -> a -> Bool
== Bit
1
  bitSizeMaybe :: Signed n -> Maybe Int
bitSizeMaybe Signed n
v    = Int -> Maybe Int
forall a. a -> Maybe a
Just (Signed n -> Int
forall (n :: Nat). KnownNat n => Signed n -> Int
size# Signed n
v)
  bitSize :: Signed n -> Int
bitSize           = Signed n -> Int
forall (n :: Nat). KnownNat n => Signed n -> Int
size#
  isSigned :: Signed n -> Bool
isSigned Signed n
_        = Bool
True
  shiftL :: Signed n -> Int -> Signed n
shiftL Signed n
v Int
i        = Signed n -> Int -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Int -> Signed n
shiftL# Signed n
v Int
i
  shiftR :: Signed n -> Int -> Signed n
shiftR Signed n
v Int
i        = Signed n -> Int -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Int -> Signed n
shiftR# Signed n
v Int
i
  rotateL :: Signed n -> Int -> Signed n
rotateL Signed n
v Int
i       = Signed n -> Int -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Int -> Signed n
rotateL# Signed n
v Int
i
  rotateR :: Signed n -> Int -> Signed n
rotateR Signed n
v Int
i       = Signed n -> Int -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Int -> Signed n
rotateR# Signed n
v Int
i
  popCount :: Signed n -> Int
popCount Signed n
s        = BitVector n -> Int
forall a. Bits a => a -> Int
popCount (Signed n -> BitVector n
forall (n :: Nat). KnownNat n => Signed n -> BitVector n
pack# Signed n
s)

and#,or#,xor# :: forall n . KnownNat n => Signed n -> Signed n -> Signed n
{-# NOINLINE and# #-}
and# :: Signed n -> Signed n -> Signed n
and# = \(S Integer
a) (S Integer
b) -> Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask (Integer
a Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
b)
  where sz :: Int
sz   = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        mB :: Integer
mB   = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
        mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

{-# NOINLINE or# #-}
or# :: Signed n -> Signed n -> Signed n
or# = \(S Integer
a) (S Integer
b) -> Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask (Integer
a Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.|. Integer
b)
  where sz :: Int
sz   = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        mB :: Integer
mB   = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
        mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

{-# NOINLINE xor# #-}
xor# :: Signed n -> Signed n -> Signed n
xor# = \(S Integer
a) (S Integer
b) -> Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask (Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
xor Integer
a Integer
b)
  where sz :: Int
sz   = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        mB :: Integer
mB   = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
        mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

{-# NOINLINE complement# #-}
complement# :: forall n . KnownNat n => Signed n -> Signed n
complement# :: Signed n -> Signed n
complement# = \(S Integer
a) -> Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask (Integer -> Integer
forall a. Bits a => a -> a
complement Integer
a)
  where sz :: Int
sz   = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        mB :: Integer
mB   = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
        mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

shiftL#,shiftR#,rotateL#,rotateR# :: forall n . KnownNat n => Signed n -> Int -> Signed n
{-# NOINLINE shiftL# #-}
shiftL# :: Signed n -> Int -> Signed n
shiftL# = \(S Integer
n) Int
b ->
  if | Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0     -> String -> Signed n
forall a. HasCallStack => String -> a
error (String -> Signed n) -> String -> Signed n
forall a b. (a -> b) -> a -> b
$ String
"'shiftL' undefined for negative number: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
b
     | Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
sz    -> Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
0
     | Bool
otherwise -> Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask (Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftL Integer
n Int
b)
 where
  sz :: Int
sz   = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
  mB :: Integer
mB   = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
  mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

{-# NOINLINE shiftR# #-}
shiftR# :: Signed n -> Int -> Signed n
shiftR# =
  \(S Integer
n) Int
b ->
    if Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then
      Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask (Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftR Integer
n Int
b)
    else
      String -> Signed n
forall a. HasCallStack => String -> a
error (String -> Signed n) -> String -> Signed n
forall a b. (a -> b) -> a -> b
$ String
"'shiftR' undefined for negative number: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
b
 where
  sz :: Int
sz   = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
  mB :: Integer
mB   = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
  mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

{-# NOINLINE rotateL# #-}
rotateL# :: Signed n -> Int -> Signed n
rotateL# =
  \(S Integer
n) Int
b ->
    if Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then
      let l :: Integer
l    = Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftL Integer
n Int
b'
          r :: Integer
r    = Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftR Integer
n Int
b'' Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
mask
          mask :: Integer
mask = Integer
2 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
b' Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

          b' :: Int
b'   = Int
b Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
sz
          b'' :: Int
b''  = Int
sz Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
b'
      in  Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz1 Integer
mB Integer
maskM (Integer
l Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.|. Integer
r)
    else
      String -> Signed n
forall a. HasCallStack => String -> a
error (String -> Signed n) -> String -> Signed n
forall a b. (a -> b) -> a -> b
$ String
"'rotateL undefined for negative number: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
b
 where
  sz :: Int
sz    = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n))
  sz1 :: Int
sz1   = Int
szInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1
  mB :: Integer
mB    = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz1
  maskM :: Integer
maskM = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

{-# NOINLINE rotateR# #-}
rotateR# :: Signed n -> Int -> Signed n
rotateR# =
  \(S Integer
n) Int
b ->
    if Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then
      let l :: Integer
l    = Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftR Integer
n Int
b' Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
mask
          r :: Integer
r    = Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftL Integer
n Int
b''
          mask :: Integer
mask = Integer
2 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
b'' Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

          b' :: Int
b'  = Int
b Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
sz
          b'' :: Int
b'' = Int
sz Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
b'
      in  Int -> Integer -> Integer -> Integer -> Signed n
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz1 Integer
mB Integer
maskM (Integer
l Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.|. Integer
r)
    else
      String -> Signed n
forall a. HasCallStack => String -> a
error (String -> Signed n) -> String -> Signed n
forall a b. (a -> b) -> a -> b
$ String
"'rotateR' undefined for negative number: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
b
 where
  sz :: Int
sz    = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n))
  sz1 :: Int
sz1   = Int
sz Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
  mB :: Integer
mB    = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz1
  maskM :: Integer
maskM = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

instance KnownNat n => FiniteBits (Signed n) where
  finiteBitSize :: Signed n -> Int
finiteBitSize        = Signed n -> Int
forall (n :: Nat). KnownNat n => Signed n -> Int
size#
  countLeadingZeros :: Signed n -> Int
countLeadingZeros  Signed n
s = BitVector n -> Int
forall b. FiniteBits b => b -> Int
countLeadingZeros  (Signed n -> BitVector n
forall (n :: Nat). KnownNat n => Signed n -> BitVector n
pack# Signed n
s)
  countTrailingZeros :: Signed n -> Int
countTrailingZeros Signed n
s = BitVector n -> Int
forall b. FiniteBits b => b -> Int
countTrailingZeros (Signed n -> BitVector n
forall (n :: Nat). KnownNat n => Signed n -> BitVector n
pack# Signed n
s)

instance Resize Signed where
  resize :: Signed a -> Signed b
resize       = Signed a -> Signed b
forall (m :: Nat) (n :: Nat).
(KnownNat n, KnownNat m) =>
Signed n -> Signed m
resize#
  zeroExtend :: Signed a -> Signed (b + a)
zeroExtend Signed a
s = BitVector (b + a) -> Signed (b + a)
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# (BitVector b
0 BitVector b -> BitVector a -> BitVector (b + a)
forall (m :: Nat) (n :: Nat).
KnownNat m =>
BitVector n -> BitVector m -> BitVector (n + m)
++# Signed a -> BitVector (BitSize (Signed a))
forall a. BitPack a => a -> BitVector (BitSize a)
pack Signed a
s)
  truncateB :: Signed (a + b) -> Signed a
truncateB    = Signed (a + b) -> Signed a
forall (a :: Nat) (b :: Nat).
KnownNat a =>
Signed (a + b) -> Signed a
truncateB#

{-# NOINLINE resize# #-}
resize# :: forall m n . (KnownNat n, KnownNat m) => Signed n -> Signed m
resize# :: Signed n -> Signed m
resize# s :: Signed n
s@(S Integer
i)
  | KnownNat m => Natural
forall (n :: Nat). KnownNat n => Natural
natToNatural @m Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== Natural
0 = Integer -> Signed m
forall (n :: Nat). Integer -> Signed n
S Integer
0
  | Integer
n' Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<= Integer
m'  = Signed m
extended
  | Bool
otherwise = Signed m
truncated
  where
    n :: Int
n  = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Signed n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal Signed n
s)
    n' :: Integer
n' = Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftL Integer
1 Int
n
    m' :: Integer
m' = Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftL Integer
mask Int
1
    extended :: Signed m
extended = Integer -> Signed m
forall (n :: Nat). Integer -> Signed n
S Integer
i

    mask :: Integer
mask      = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy m -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy m
forall k (t :: k). Proxy t
Proxy @m) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)
    i' :: Integer
i'        = Integer
i Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
mask
    truncated :: Signed m
truncated = if Integer -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Integer
i (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
                   then Integer -> Signed m
forall (n :: Nat). Integer -> Signed n
S (Integer
i' Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
mask)
                   else Integer -> Signed m
forall (n :: Nat). Integer -> Signed n
S Integer
i'

{-# NOINLINE truncateB# #-}
truncateB# :: forall m n . KnownNat m => Signed (m + n) -> Signed m
truncateB# :: Signed (m + n) -> Signed m
truncateB# = \(S Integer
n) -> Int -> Integer -> Integer -> Integer -> Signed m
forall (n :: Nat). Int -> Integer -> Integer -> Integer -> Signed n
fromInteger_INLINE Int
sz Integer
mB Integer
mask Integer
n
  where sz :: Int
sz   = Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Proxy m -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy m
forall k (t :: k). Proxy t
Proxy @m)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        mB :: Integer
mB   = Integer
1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
sz
        mask :: Integer
mask = Integer
mB Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1

instance KnownNat n => Default (Signed n) where
  def :: Signed n
def = Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# Integer
0

instance KnownNat n => Lift (Signed n) where
  lift :: Signed n -> Q Exp
lift s :: Signed n
s@(S Integer
i) = Q Exp -> TypeQ -> Q Exp
sigE [| fromInteger# i |] (Integer -> TypeQ
decSigned (Signed n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal Signed n
s))
  {-# NOINLINE lift #-}
#if MIN_VERSION_template_haskell(2,16,0)
  liftTyped :: Signed n -> Q (TExp (Signed n))
liftTyped = Signed n -> Q (TExp (Signed n))
forall a. Lift a => a -> Q (TExp a)
liftTypedFromUntyped
#endif

#if MIN_VERSION_template_haskell(2,17,0)
decSigned :: Quote m => Integer -> m Type
#else
decSigned :: Integer -> TypeQ
#endif
decSigned :: Integer -> TypeQ
decSigned Integer
n = TypeQ -> TypeQ -> TypeQ
appT (Name -> TypeQ
conT ''Signed) (TyLitQ -> TypeQ
litT (TyLitQ -> TypeQ) -> TyLitQ -> TypeQ
forall a b. (a -> b) -> a -> b
$ Integer -> TyLitQ
numTyLit Integer
n)

instance KnownNat n => SaturatingNum (Signed n) where
  satAdd :: SaturationMode -> Signed n -> Signed n -> Signed n
satAdd SaturationMode
SatWrap  Signed n
a Signed n
b = Signed n
a Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
+# Signed n
b
  satAdd SaturationMode
SatBound Signed n
a Signed n
b =
    let r :: Signed (Max n n + 1)
r      = Signed n -> Signed n -> Signed (Max n n + 1)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (Max m n + 1)
plus# Signed n
a Signed n
b
        (BitVector 1
_,BitVector n
r') = Signed (n + 1) -> (BitVector 1, BitVector n)
forall a (m :: Nat) (n :: Nat).
(BitPack a, BitSize a ~ (m + n), KnownNat n) =>
a -> (BitVector m, BitVector n)
split Signed (n + 1)
Signed (Max n n + 1)
r
    in  case Signed (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Signed (n + 1)
Signed (Max n n + 1)
r Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
`xor` BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
r' of
          Bit
0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          Bit
_ -> case Signed n -> Bit
forall a. BitPack a => a -> Bit
msb Signed n
a Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
.&. Signed n -> Bit
forall a. BitPack a => a -> Bit
msb Signed n
b of
            Bit
0 -> Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#
            Bit
_ -> Signed n
forall (n :: Nat). KnownNat n => Signed n
minBound#
  satAdd SaturationMode
SatZero Signed n
a Signed n
b =
    let r :: Signed (Max n n + 1)
r      = Signed n -> Signed n -> Signed (Max n n + 1)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (Max m n + 1)
plus# Signed n
a Signed n
b
        (BitVector 1
_,BitVector n
r') = Signed (n + 1) -> (BitVector 1, BitVector n)
forall a (m :: Nat) (n :: Nat).
(BitPack a, BitSize a ~ (m + n), KnownNat n) =>
a -> (BitVector m, BitVector n)
split Signed (n + 1)
Signed (Max n n + 1)
r
    in  case Signed (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Signed (n + 1)
Signed (Max n n + 1)
r Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
`xor` BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
r' of
          Bit
0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          Bit
_ -> Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# Integer
0
  satAdd SaturationMode
SatError Signed n
a Signed n
b =
    let r :: Signed (Max n n + 1)
r      = Signed n -> Signed n -> Signed (Max n n + 1)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (Max m n + 1)
plus# Signed n
a Signed n
b
        (BitVector 1
_,BitVector n
r') = Signed (n + 1) -> (BitVector 1, BitVector n)
forall a (m :: Nat) (n :: Nat).
(BitPack a, BitSize a ~ (m + n), KnownNat n) =>
a -> (BitVector m, BitVector n)
split Signed (n + 1)
Signed (Max n n + 1)
r
    in  case Signed (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Signed (n + 1)
Signed (Max n n + 1)
r Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
`xor` BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
r' of
          Bit
0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          Bit
_ -> String -> Signed n
forall a. HasCallStack => String -> a
errorX String
"Signed.satAdd: overflow/underflow"
  satAdd SaturationMode
SatSymmetric Signed n
a Signed n
b =
    let r :: Signed (Max n n + 1)
r      = Signed n -> Signed n -> Signed (Max n n + 1)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (Max m n + 1)
plus# Signed n
a Signed n
b
        (BitVector 1
_,BitVector n
r') = Signed (n + 1) -> (BitVector 1, BitVector n)
forall a (m :: Nat) (n :: Nat).
(BitPack a, BitSize a ~ (m + n), KnownNat n) =>
a -> (BitVector m, BitVector n)
split Signed (n + 1)
Signed (Max n n + 1)
r
    in  case Signed (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Signed (n + 1)
Signed (Max n n + 1)
r Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
`xor` BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
r' of
          Bit
0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          Bit
_ -> case Signed n -> Bit
forall a. BitPack a => a -> Bit
msb Signed n
a Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
.&. Signed n -> Bit
forall a. BitPack a => a -> Bit
msb Signed n
b of
            Bit
0 -> Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#
            Bit
_ -> Signed n
forall (n :: Nat). KnownNat n => Signed n
minBoundSym#

  satSub :: SaturationMode -> Signed n -> Signed n -> Signed n
satSub SaturationMode
SatWrap Signed n
a Signed n
b = Signed n
a Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
-# Signed n
b
  satSub SaturationMode
SatBound Signed n
a Signed n
b =
    let r :: Signed (Max n n + 1)
r      = Signed n -> Signed n -> Signed (Max n n + 1)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (Max m n + 1)
minus# Signed n
a Signed n
b
        (BitVector 1
_,BitVector n
r') = Signed (n + 1) -> (BitVector 1, BitVector n)
forall a (m :: Nat) (n :: Nat).
(BitPack a, BitSize a ~ (m + n), KnownNat n) =>
a -> (BitVector m, BitVector n)
split Signed (n + 1)
Signed (Max n n + 1)
r
    in  case Signed (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Signed (n + 1)
Signed (Max n n + 1)
r Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
`xor` BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
r' of
          Bit
0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          Bit
_ -> case Bit -> BitVector 1
BV.pack# (Signed n -> Bit
forall a. BitPack a => a -> Bit
msb Signed n
a) BitVector 1 -> BitVector 1 -> BitVector (1 + 1)
forall (m :: Nat) (n :: Nat).
KnownNat m =>
BitVector n -> BitVector m -> BitVector (n + m)
++# Bit -> BitVector 1
BV.pack# (Signed n -> Bit
forall a. BitPack a => a -> Bit
msb Signed n
b) of
            BitVector (1 + 1)
2 -> Signed n
forall (n :: Nat). KnownNat n => Signed n
minBound#
            BitVector (1 + 1)
_ -> Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#
  satSub SaturationMode
SatZero Signed n
a Signed n
b =
    let r :: Signed (Max n n + 1)
r      = Signed n -> Signed n -> Signed (Max n n + 1)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (Max m n + 1)
minus# Signed n
a Signed n
b
        (BitVector 1
_,BitVector n
r') = Signed (n + 1) -> (BitVector 1, BitVector n)
forall a (m :: Nat) (n :: Nat).
(BitPack a, BitSize a ~ (m + n), KnownNat n) =>
a -> (BitVector m, BitVector n)
split Signed (n + 1)
Signed (Max n n + 1)
r
    in  case Signed (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Signed (n + 1)
Signed (Max n n + 1)
r Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
`xor` BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
r' of
          Bit
0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          Bit
_ -> Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# Integer
0
  satSub SaturationMode
SatError Signed n
a Signed n
b =
    let r :: Signed (Max n n + 1)
r      = Signed n -> Signed n -> Signed (Max n n + 1)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (Max m n + 1)
minus# Signed n
a Signed n
b
        (BitVector 1
_,BitVector n
r') = Signed (n + 1) -> (BitVector 1, BitVector n)
forall a (m :: Nat) (n :: Nat).
(BitPack a, BitSize a ~ (m + n), KnownNat n) =>
a -> (BitVector m, BitVector n)
split Signed (n + 1)
Signed (Max n n + 1)
r
    in  case Signed (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Signed (n + 1)
Signed (Max n n + 1)
r Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
`xor` BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
r' of
          Bit
0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          Bit
_ -> String -> Signed n
forall a. HasCallStack => String -> a
errorX String
"Signed.satSub: overflow/underflow"
  satSub SaturationMode
SatSymmetric Signed n
a Signed n
b =
    let r :: Signed (Max n n + 1)
r      = Signed n -> Signed n -> Signed (Max n n + 1)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (Max m n + 1)
minus# Signed n
a Signed n
b
        (BitVector 1
_,BitVector n
r') = Signed (n + 1) -> (BitVector 1, BitVector n)
forall a (m :: Nat) (n :: Nat).
(BitPack a, BitSize a ~ (m + n), KnownNat n) =>
a -> (BitVector m, BitVector n)
split Signed (n + 1)
Signed (Max n n + 1)
r
    in  case Signed (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Signed (n + 1)
Signed (Max n n + 1)
r Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
`xor` BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
r' of
          Bit
0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          Bit
_ -> case Bit -> BitVector 1
BV.pack# (Signed n -> Bit
forall a. BitPack a => a -> Bit
msb Signed n
a) BitVector 1 -> BitVector 1 -> BitVector (1 + 1)
forall (m :: Nat) (n :: Nat).
KnownNat m =>
BitVector n -> BitVector m -> BitVector (n + m)
++# Bit -> BitVector 1
BV.pack# (Signed n -> Bit
forall a. BitPack a => a -> Bit
msb Signed n
b) of
            BitVector (1 + 1)
2 -> Signed n
forall (n :: Nat). KnownNat n => Signed n
minBoundSym#
            BitVector (1 + 1)
_ -> Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#

  satMul :: SaturationMode -> Signed n -> Signed n -> Signed n
satMul SaturationMode
SatWrap Signed n
a Signed n
b = Signed n
a Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
*# Signed n
b
  satMul SaturationMode
SatBound Signed n
a Signed n
b =
    let r :: Signed (n + n)
r        = Signed n -> Signed n -> Signed (n + n)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (m + n)
times# Signed n
a Signed n
b
        (BitVector n
rL,BitVector n
rR)  = Signed (n + n) -> (BitVector n, BitVector n)
forall a (m :: Nat) (n :: Nat).
(BitPack a, BitSize a ~ (m + n), KnownNat n) =>
a -> (BitVector m, BitVector n)
split Signed (n + n)
r
        overflow :: Bit
overflow = Bit -> Bit
forall a. Bits a => a -> a
complement (BitVector (1 + n) -> Bit
forall a. BitPack a => a -> Bit
reduceOr (Bit -> BitVector 1
BV.pack# (BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
rR) BitVector 1 -> BitVector n -> BitVector (1 + n)
forall (m :: Nat) (n :: Nat).
KnownNat m =>
BitVector n -> BitVector m -> BitVector (n + m)
++# BitVector n -> BitVector (BitSize (BitVector n))
forall a. BitPack a => a -> BitVector (BitSize a)
pack BitVector n
rL)) Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
.|.
                   BitVector (1 + n) -> Bit
forall a. BitPack a => a -> Bit
reduceAnd (Bit -> BitVector 1
BV.pack# (BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
rR) BitVector 1 -> BitVector n -> BitVector (1 + n)
forall (m :: Nat) (n :: Nat).
KnownNat m =>
BitVector n -> BitVector m -> BitVector (n + m)
++# BitVector n -> BitVector (BitSize (BitVector n))
forall a. BitPack a => a -> BitVector (BitSize a)
pack BitVector n
rL)
    in  case Bit
overflow of
          Bit
1 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
rR
          Bit
_ -> case BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
rL of
            Bit
0 -> Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#
            Bit
_ -> Signed n
forall (n :: Nat). KnownNat n => Signed n
minBound#
  satMul SaturationMode
SatZero Signed n
a Signed n
b =
    let r :: Signed (n + n)
r        = Signed n -> Signed n -> Signed (n + n)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (m + n)
times# Signed n
a Signed n
b
        (BitVector n
rL,BitVector n
rR)  = Signed (n + n) -> (BitVector n, BitVector n)
forall a (m :: Nat) (n :: Nat).
(BitPack a, BitSize a ~ (m + n), KnownNat n) =>
a -> (BitVector m, BitVector n)
split Signed (n + n)
r
        overflow :: Bit
overflow = Bit -> Bit
forall a. Bits a => a -> a
complement (BitVector (1 + n) -> Bit
forall a. BitPack a => a -> Bit
reduceOr (Bit -> BitVector 1
BV.pack# (BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
rR) BitVector 1 -> BitVector n -> BitVector (1 + n)
forall (m :: Nat) (n :: Nat).
KnownNat m =>
BitVector n -> BitVector m -> BitVector (n + m)
++# BitVector n -> BitVector (BitSize (BitVector n))
forall a. BitPack a => a -> BitVector (BitSize a)
pack BitVector n
rL)) Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
.|.
                   BitVector (1 + n) -> Bit
forall a. BitPack a => a -> Bit
reduceAnd (Bit -> BitVector 1
BV.pack# (BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
rR) BitVector 1 -> BitVector n -> BitVector (1 + n)
forall (m :: Nat) (n :: Nat).
KnownNat m =>
BitVector n -> BitVector m -> BitVector (n + m)
++# BitVector n -> BitVector (BitSize (BitVector n))
forall a. BitPack a => a -> BitVector (BitSize a)
pack BitVector n
rL)
    in  case Bit
overflow of
          Bit
1 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
rR
          Bit
_ -> Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# Integer
0
  satMul SaturationMode
SatError Signed n
a Signed n
b =
    let r :: Signed (n + n)
r        = Signed n -> Signed n -> Signed (n + n)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (m + n)
times# Signed n
a Signed n
b
        (BitVector n
rL,BitVector n
rR)  = Signed (n + n) -> (BitVector n, BitVector n)
forall a (m :: Nat) (n :: Nat).
(BitPack a, BitSize a ~ (m + n), KnownNat n) =>
a -> (BitVector m, BitVector n)
split Signed (n + n)
r
        overflow :: Bit
overflow = Bit -> Bit
forall a. Bits a => a -> a
complement (BitVector (1 + n) -> Bit
forall a. BitPack a => a -> Bit
reduceOr (Bit -> BitVector 1
BV.pack# (BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
rR) BitVector 1 -> BitVector n -> BitVector (1 + n)
forall (m :: Nat) (n :: Nat).
KnownNat m =>
BitVector n -> BitVector m -> BitVector (n + m)
++# BitVector n -> BitVector (BitSize (BitVector n))
forall a. BitPack a => a -> BitVector (BitSize a)
pack BitVector n
rL)) Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
.|.
                   BitVector (1 + n) -> Bit
forall a. BitPack a => a -> Bit
reduceAnd (Bit -> BitVector 1
BV.pack# (BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
rR) BitVector 1 -> BitVector n -> BitVector (1 + n)
forall (m :: Nat) (n :: Nat).
KnownNat m =>
BitVector n -> BitVector m -> BitVector (n + m)
++# BitVector n -> BitVector (BitSize (BitVector n))
forall a. BitPack a => a -> BitVector (BitSize a)
pack BitVector n
rL)
    in  case Bit
overflow of
          Bit
1 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
rR
          Bit
_ -> String -> Signed n
forall a. HasCallStack => String -> a
errorX String
"Signed.satMul: overflow/underflow"
  satMul SaturationMode
SatSymmetric Signed n
a Signed n
b =
    let r :: Signed (n + n)
r        = Signed n -> Signed n -> Signed (n + n)
forall (m :: Nat) (n :: Nat).
Signed m -> Signed n -> Signed (m + n)
times# Signed n
a Signed n
b
        (BitVector n
rL,BitVector n
rR)  = Signed (n + n) -> (BitVector n, BitVector n)
forall a (m :: Nat) (n :: Nat).
(BitPack a, BitSize a ~ (m + n), KnownNat n) =>
a -> (BitVector m, BitVector n)
split Signed (n + n)
r
        overflow :: Bit
overflow = Bit -> Bit
forall a. Bits a => a -> a
complement (BitVector (1 + n) -> Bit
forall a. BitPack a => a -> Bit
reduceOr (Bit -> BitVector 1
BV.pack# (BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
rR) BitVector 1 -> BitVector n -> BitVector (1 + n)
forall (m :: Nat) (n :: Nat).
KnownNat m =>
BitVector n -> BitVector m -> BitVector (n + m)
++# BitVector n -> BitVector (BitSize (BitVector n))
forall a. BitPack a => a -> BitVector (BitSize a)
pack BitVector n
rL)) Bit -> Bit -> Bit
forall a. Bits a => a -> a -> a
.|.
                   BitVector (1 + n) -> Bit
forall a. BitPack a => a -> Bit
reduceAnd (Bit -> BitVector 1
BV.pack# (BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
rR) BitVector 1 -> BitVector n -> BitVector (1 + n)
forall (m :: Nat) (n :: Nat).
KnownNat m =>
BitVector n -> BitVector m -> BitVector (n + m)
++# BitVector n -> BitVector (BitSize (BitVector n))
forall a. BitPack a => a -> BitVector (BitSize a)
pack BitVector n
rL)
    in  case Bit
overflow of
          Bit
1 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
rR
          Bit
_ -> case BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
rL of
            Bit
0 -> Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#
            Bit
_ -> Signed n
forall (n :: Nat). KnownNat n => Signed n
minBoundSym#

  satSucc :: SaturationMode -> Signed n -> Signed n
satSucc SaturationMode
SatError Signed n
a
    | Signed n
a Signed n -> Signed n -> Bool
forall a. Eq a => a -> a -> Bool
== Signed n
forall a. Bounded a => a
maxBound = String -> Signed n
forall a. HasCallStack => String -> a
errorX String
"Signed.satSucc: overflow"
  satSucc SaturationMode
satMode Signed n
a = SaturationMode -> Signed n -> Signed n -> Signed n
forall a. SaturatingNum a => SaturationMode -> a -> a -> a
satSub SaturationMode
satMode Signed n
a (Signed n -> Signed n) -> Signed n -> Signed n
forall a b. (a -> b) -> a -> b
$ Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# (-Integer
1)
  {-# INLINE satSucc #-}

  satPred :: SaturationMode -> Signed n -> Signed n
satPred SaturationMode
SatError Signed n
a
    | Signed n
a Signed n -> Signed n -> Bool
forall a. Eq a => a -> a -> Bool
== Signed n
forall a. Bounded a => a
minBound = String -> Signed n
forall a. HasCallStack => String -> a
errorX String
"Signed.satPred: underflow"
  satPred SaturationMode
satMode Signed n
a = SaturationMode -> Signed n -> Signed n -> Signed n
forall a. SaturatingNum a => SaturationMode -> a -> a -> a
satAdd SaturationMode
satMode Signed n
a (Signed n -> Signed n) -> Signed n -> Signed n
forall a b. (a -> b) -> a -> b
$ Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# (-Integer
1)
  {-# INLINE satPred #-}

minBoundSym# :: KnownNat n => Signed n
minBoundSym# :: Signed n
minBoundSym# = Signed n
forall (n :: Nat). KnownNat n => Signed n
minBound# Signed n -> Signed n -> Signed n
forall (n :: Nat). KnownNat n => Signed n -> Signed n -> Signed n
+# Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# Integer
1

instance KnownNat n => Arbitrary (Signed n) where
  arbitrary :: Gen (Signed n)
arbitrary = Gen (Signed n)
forall a. (Bounded a, Integral a) => Gen a
arbitraryBoundedIntegral
  shrink :: Signed n -> [Signed n]
shrink    = Signed n -> [Signed n]
forall (n :: Nat) (p :: Nat -> Type).
(KnownNat n, Integral (p n)) =>
p n -> [p n]
shrinkSizedSigned

shrinkSizedSigned :: (KnownNat n, Integral (p n)) => p n -> [p n]
shrinkSizedSigned :: p n -> [p n]
shrinkSizedSigned p n
x | p n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal p n
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
2 = case p n -> Integer
forall a. Integral a => a -> Integer
toInteger p n
x of
                                       Integer
0 -> []
                                       Integer
_ -> [p n
0]
                    -- 'shrinkIntegral' uses "`quot` 2", which for sized types
                    -- less than 2 bits wide results in a division by zero.
                    --
                    -- See: https://github.com/clash-lang/clash-compiler/issues/153
                    | Bool
otherwise    = p n -> [p n]
forall a. Integral a => a -> [a]
shrinkIntegral p n
x
{-# INLINE shrinkSizedSigned #-}

instance KnownNat n => CoArbitrary (Signed n) where
  coarbitrary :: Signed n -> Gen b -> Gen b
coarbitrary = Signed n -> Gen b -> Gen b
forall a b. Integral a => a -> Gen b -> Gen b
coarbitraryIntegral

type instance Index   (Signed n) = Int
type instance IxValue (Signed n) = Bit
instance KnownNat n => Ixed (Signed n) where
  ix :: Index (Signed n) -> Traversal' (Signed n) (IxValue (Signed n))
ix Index (Signed n)
i IxValue (Signed n) -> f (IxValue (Signed n))
f Signed n
s = BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# (BitVector n -> Signed n)
-> (Bit -> BitVector n) -> Bit -> Signed n
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> BitVector n -> Int -> Bit -> BitVector n
forall (n :: Nat).
KnownNat n =>
BitVector n -> Int -> Bit -> BitVector n
BV.replaceBit# (Signed n -> BitVector n
forall (n :: Nat). KnownNat n => Signed n -> BitVector n
pack# Signed n
s) Int
Index (Signed n)
i
                     (Bit -> Signed n) -> f Bit -> f (Signed n)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> IxValue (Signed n) -> f (IxValue (Signed n))
f (BitVector n -> Int -> Bit
forall (n :: Nat). KnownNat n => BitVector n -> Int -> Bit
BV.index# (Signed n -> BitVector n
forall (n :: Nat). KnownNat n => Signed n -> BitVector n
pack# Signed n
s) Int
Index (Signed n)
i)

instance (KnownNat n) => Ix (Signed n) where
  range :: (Signed n, Signed n) -> [Signed n]
range (Signed n
a, Signed n
b) = [Signed n
a..Signed n
b]
  index :: (Signed n, Signed n) -> Signed n -> Int
index ab :: (Signed n, Signed n)
ab@(Signed n
a, Signed n
b) Signed n
x
    | (Signed n, Signed n) -> Signed n -> Bool
forall a. Ix a => (a, a) -> a -> Bool
inRange (Signed n, Signed n)
ab Signed n
x = Signed n -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Signed n -> Int) -> Signed n -> Int
forall a b. (a -> b) -> a -> b
$ Signed n
x Signed n -> Signed n -> Signed n
forall a. Num a => a -> a -> a
- Signed n
a
    | Bool
otherwise = String -> Int
forall a. HasCallStack => String -> a
error (String -> Int) -> String -> Int
forall a b. (a -> b) -> a -> b
$ String -> Signed n -> Signed n -> Signed n -> String
forall r. PrintfType r => String -> r
printf String
"Index %d out of bounds (%d, %d) ab" Signed n
x Signed n
a Signed n
b
  inRange :: (Signed n, Signed n) -> Signed n -> Bool
inRange (Signed n
a, Signed n
b) Signed n
x = Signed n
a Signed n -> Signed n -> Bool
forall a. Ord a => a -> a -> Bool
<= Signed n
x Bool -> Bool -> Bool
&& Signed n
x Signed n -> Signed n -> Bool
forall a. Ord a => a -> a -> Bool
<= Signed n
b

-- | Shift left that ties to zero on negative shifts
shiftL0 :: Integer -> Int -> Integer
#if MIN_VERSION_base(4,15,0)
shiftL0 = \a sh -> if sh >= 0 then shiftL a sh else 0
#else
shiftL0 :: Integer -> Int -> Integer
shiftL0 = Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftL -- True for use with this module
#endif
{-# INLINE shiftL0 #-}