{-|
Copyright  :  (C) 2013-2016, University of Twente,
                  2016     , Myrtle Software Ltd
License    :  BSD2 (see the file LICENSE)
Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>
-}

{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# 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 GHC.Generics                   (Generic)
import GHC.TypeLits                   (KnownNat, Nat, type (+), natVal)
import GHC.TypeLits.Extra             (Max)
import Language.Haskell.TH            (TypeQ, appT, conT, litT, numTyLit, sigE)
import Language.Haskell.TH.Syntax     (Lift(..))
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.Prelude.BitIndex         ((!), msb, replaceBit, split)
import Clash.Prelude.BitReduction     (reduceAnd, reduceOr)
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)

-- | 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]
--
-- __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
newtype Signed (n :: Nat) =
    -- | The constructor, 'S', and the field, 'unsafeToInteger', are not
    -- synthesizable.
    S { Signed n -> Integer
unsafeToInteger :: Integer}
  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# bv :: 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 i :: Integer
i) = Integer -> ()
forall a. NFData a => a -> ()
rnf Integer
i () -> () -> ()
forall a b. a -> b -> b
`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 i :: 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 i :: Integer
i) = let m :: Integer
m = 1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` 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
< 0 then Integer -> Integer -> BitVector n
forall (n :: Nat). Integer -> Integer -> BitVector n
BV 0 (Integer
m Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
i) else Integer -> Integer -> BitVector n
forall (n :: Nat). Integer -> Integer -> BitVector n
BV 0 Integer
i

{-# NOINLINE unpack# #-}
unpack# :: forall n . KnownNat n => BitVector n -> Signed n
unpack# :: BitVector n -> Signed n
unpack# (BV 0 i :: Integer
i) =
  let m :: Integer
m = 1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` 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
- 1)
  in  if Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
m then Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer
iInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
m) else Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
i
unpack# bv :: BitVector n
bv = String -> [BitVector n] -> Signed n
forall (n :: Nat) a.
(HasCallStack, KnownNat n) =>
String -> [BitVector n] -> a
undefError "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 v1 :: Integer
v1) (S v2 :: 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 v1 :: Integer
v1) (S v2 :: 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 n :: Integer
n) (S m :: 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 n :: Integer
n) (S m :: 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 n :: Integer
n) (S m :: 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 n :: Integer
n) (S m :: 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 -> 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# 1)
  pred :: Signed n -> Signed n
pred           = (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# 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). 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). Signed n -> Signed n -> Signed n -> [Signed n]
enumFromThenTo#

{-# NOINLINE enumFrom# #-}
{-# NOINLINE enumFromThen# #-}
{-# NOINLINE enumFromTo# #-}
{-# NOINLINE enumFromThenTo# #-}
enumFrom#       :: forall n. KnownNat n => Signed n -> [Signed n]
enumFromThen#   :: forall n. KnownNat n => Signed n -> Signed n -> [Signed n]
enumFromTo#     :: Signed n -> Signed n -> [Signed n]
enumFromThenTo# :: Signed n -> Signed n -> Signed n -> [Signed n]
enumFrom# :: Signed n -> [Signed n]
enumFrom# x :: Signed n
x             = (Integer -> Signed n) -> [Integer] -> [Signed n]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger_INLINE [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)]
enumFromThen# :: Signed n -> Signed n -> [Signed n]
enumFromThen# x :: Signed n
x y :: Signed n
y       = (Integer -> Signed n) -> [Integer] -> [Signed n]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger_INLINE [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
forall a. Bounded a => a
maxBound :: Signed n)]
enumFromTo# :: Signed n -> Signed n -> [Signed n]
enumFromTo# x :: Signed n
x y :: Signed n
y         = (Integer -> Signed n) -> [Integer] -> [Signed n]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S [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]
enumFromThenTo# :: Signed n -> Signed n -> Signed n -> [Signed n]
enumFromThenTo# x1 :: Signed n
x1 x2 :: Signed n
x2 y :: Signed n
y = (Integer -> Signed n) -> [Integer] -> [Signed n]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S [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]


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#,maxBound# :: KnownNat n => Signed n
{-# NOINLINE minBound# #-}
minBound# :: Signed n
minBound# = let res :: Signed n
res = Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer -> Signed n) -> Integer -> Signed n
forall a b. (a -> b) -> a -> b
$ Integer -> Integer
forall a. Num a => a -> a
negate (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ 2 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Signed n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal Signed n
res Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- 1) in Signed n
res
{-# NOINLINE maxBound# #-}
maxBound# :: Signed n
maxBound# = let res :: Signed n
res = Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S (Integer -> Signed n) -> Integer -> Signed n
forall a b. (a -> b) -> a -> b
$ 2 Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Signed n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal Signed n
res Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- 1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- 1 in Signed n
res

-- | 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 s :: Signed n
s    = if Signed n
s Signed n -> Signed n -> Bool
forall a. Ord a => a -> a -> Bool
< 0 then (-1) else
                   if Signed n
s Signed n -> Signed n -> Bool
forall a. Ord a => a -> a -> Bool
> 0 then 1 else 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 (+#) #-}
(S a :: Integer
a) +# :: Signed n -> Signed n -> Signed n
+# (S b :: Integer
b) = let m :: Integer
m  = 1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` 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
-1)
                     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
- 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
+ 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

{-# NOINLINE (-#) #-}
(S a :: Integer
a) -# :: Signed n -> Signed n -> Signed n
-# (S b :: Integer
b) = let m :: Integer
m  = 1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` 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
-1)
                     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
+ 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
- 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

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

negate#,abs# :: forall n . KnownNat n => Signed n -> Signed n
{-# NOINLINE negate# #-}
negate# :: Signed n -> Signed n
negate# (S n :: Integer
n) = let m :: Integer
m = 1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` 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
-1)
                    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

{-# NOINLINE abs# #-}
abs# :: Signed n -> Signed n
abs# (S n :: Integer
n) = let m :: Integer
m = 1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` 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
-1)
                 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

{-# NOINLINE fromInteger# #-}
fromInteger# :: KnownNat n => Integer -> Signed (n :: Nat)
fromInteger# :: Integer -> Signed n
fromInteger# = Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger_INLINE

{-# INLINE fromInteger_INLINE #-}
fromInteger_INLINE :: forall n . KnownNat n => Integer -> Signed n
fromInteger_INLINE :: Integer -> Signed n
fromInteger_INLINE i :: Integer
i = if Integer
mask Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== 0 then Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S 0 else Integer -> Signed n
forall (n :: Nat). Integer -> Signed n
S Integer
res
  where
    mask :: Integer
mask = 1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` 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
-1)
    res :: Integer
res  = case Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
divMod Integer
i Integer
mask of
             (s :: Integer
s,i' :: Integer
i') | Integer -> Bool
forall a. Parity a => a -> Bool
even Integer
s    -> Integer
i'
                    | Bool
otherwise -> Integer
i' Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
mask

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 a :: Integer
a) (S b :: 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 a :: Integer
a) (S b :: 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 a :: Integer
a) (S b :: 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). 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). 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 n :: Signed n
n d :: Signed n
d = (Signed n
n Signed n -> Signed n -> Signed n
forall (n :: Nat). 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  n :: Signed n
n d :: Signed n
d = (Signed n
n Signed n -> Signed n -> Signed n
forall (n :: Nat). 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#

quot#,rem# :: Signed n -> Signed n -> Signed n
{-# NOINLINE quot# #-}
quot# :: Signed n -> Signed n -> Signed n
quot# (S a :: Integer
a) (S b :: Integer
b) = 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)
{-# NOINLINE rem# #-}
rem# :: Signed n -> Signed n -> Signed n
rem# (S a :: Integer
a) (S b :: 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)

div#,mod# :: Signed n -> Signed n -> Signed n
{-# NOINLINE div# #-}
div# :: Signed n -> Signed n -> Signed n
div# (S a :: Integer
a) (S b :: Integer
b) = 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)
{-# NOINLINE mod# #-}
mod# :: Signed n -> Signed n -> Signed n
mod# (S a :: Integer
a) (S b :: 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 n :: Integer
n) = Integer
n

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          = 0
  bit :: Int -> Signed n
bit i :: Int
i             = Int -> Bit -> Signed n -> Signed n
forall a i. (BitPack a, Enum i) => i -> Bit -> a -> a
replaceBit Int
i Bit
high 0
  setBit :: Signed n -> Int -> Signed n
setBit v :: Signed n
v i :: 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 v :: Signed n
v i :: 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 v :: Signed n
v i :: 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 v :: Signed n
v i :: 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
== 1
  bitSizeMaybe :: Signed n -> Maybe Int
bitSizeMaybe v :: 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 _        = Bool
True
  shiftL :: Signed n -> Int -> Signed n
shiftL v :: Signed n
v i :: 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 v :: Signed n
v i :: 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 v :: Signed n
v i :: 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 v :: Signed n
v i :: 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 s :: 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# :: KnownNat n => Signed n -> Signed n -> Signed n
{-# NOINLINE and# #-}
and# :: Signed n -> Signed n -> Signed n
and# (S a :: Integer
a) (S b :: Integer
b) = Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger_INLINE (Integer
a Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
b)
{-# NOINLINE or# #-}
or# :: Signed n -> Signed n -> Signed n
or# (S a :: Integer
a) (S b :: Integer
b)  = Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger_INLINE (Integer
a Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.|. Integer
b)
{-# NOINLINE xor# #-}
xor# :: Signed n -> Signed n -> Signed n
xor# (S a :: Integer
a) (S b :: Integer
b) = Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger_INLINE (Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
xor Integer
a Integer
b)

{-# NOINLINE complement# #-}
complement# :: KnownNat n => Signed n -> Signed n
complement# :: Signed n -> Signed n
complement# (S a :: Integer
a) = Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger_INLINE (Integer -> Integer
forall a. Bits a => a -> a
complement Integer
a)

shiftL#,shiftR#,rotateL#,rotateR# :: KnownNat n => Signed n -> Int -> Signed n
{-# NOINLINE shiftL# #-}
shiftL# :: Signed n -> Int -> Signed n
shiftL# _ b :: Int
b | Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0  = String -> Signed n
forall a. HasCallStack => String -> a
error "'shiftL undefined for negative numbers"
shiftL# (S n :: Integer
n) b :: Int
b      = Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger_INLINE (Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftL Integer
n Int
b)
{-# NOINLINE shiftR# #-}
shiftR# :: Signed n -> Int -> Signed n
shiftR# _ b :: Int
b | Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0  = String -> Signed n
forall a. HasCallStack => String -> a
error "'shiftR undefined for negative numbers"
shiftR# (S n :: Integer
n) b :: Int
b      = Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger_INLINE (Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftR Integer
n Int
b)
{-# NOINLINE rotateL# #-}
rotateL# :: Signed n -> Int -> Signed n
rotateL# _ b :: Int
b | Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = String -> Signed n
forall a. HasCallStack => String -> a
error "'shiftL undefined for negative numbers"
rotateL# s :: Signed n
s@(S n :: Integer
n) b :: Int
b   = Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger_INLINE (Integer
l Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.|. Integer
r)
  where
    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 = 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
- 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'
    sz :: Int
sz   = 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)

{-# NOINLINE rotateR# #-}
rotateR# :: Signed n -> Int -> Signed n
rotateR# _ b :: Int
b | Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = String -> Signed n
forall a. HasCallStack => String -> a
error "'shiftR undefined for negative numbers"
rotateR# s :: Signed n
s@(S n :: Integer
n) b :: Int
b   = Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger_INLINE (Integer
l Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.|. Integer
r)
  where
    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 = 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
- 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'
    sz :: Int
sz  = 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)

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  s :: 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 s :: 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 s :: Signed a
s = BitVector (b + a) -> Signed (b + a)
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# (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 i :: Integer
i) | 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 1 Int
n
    m' :: Integer
m' = Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftL Integer
mask 1
    extended :: Signed m
extended = Integer -> Signed m
forall (n :: Nat). Integer -> Signed n
S Integer
i

    mask :: Integer
mask      = 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
-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
-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# :: KnownNat m => Signed (m + n) -> Signed m
truncateB# :: Signed (m + n) -> Signed m
truncateB# (S n :: Integer
n) = Integer -> Signed m
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger_INLINE Integer
n

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

instance KnownNat n => Lift (Signed n) where
  lift :: Signed n -> Q Exp
lift s :: Signed n
s@(S i :: 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 #-}

decSigned :: Integer -> TypeQ
decSigned :: Integer -> TypeQ
decSigned n :: 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 SatWrap  a :: Signed n
a b :: 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 SatBound a :: Signed n
a b :: 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
        (_,r' :: 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
          0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          _ -> 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
            0 -> Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#
            _ -> Signed n
forall (n :: Nat). KnownNat n => Signed n
minBound#
  satAdd SatZero a :: Signed n
a b :: 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
        (_,r' :: 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
          0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          _ -> Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# 0
  satAdd SatSymmetric a :: Signed n
a b :: 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
        (_,r' :: 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
          0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          _ -> 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
            0 -> Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#
            _ -> Signed n
forall (n :: Nat). KnownNat n => Signed n
minBoundSym#

  satSub :: SaturationMode -> Signed n -> Signed n -> Signed n
satSub SatWrap a :: Signed n
a b :: 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 SatBound a :: Signed n
a b :: 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
        (_,r' :: 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
          0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          _ -> 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
            2 -> Signed n
forall (n :: Nat). KnownNat n => Signed n
minBound#
            _ -> Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#
  satSub SatZero a :: Signed n
a b :: 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
        (_,r' :: 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
          0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          _ -> Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# 0
  satSub SatSymmetric a :: Signed n
a b :: 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
        (_,r' :: 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
          0 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
r'
          _ -> 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
            2 -> Signed n
forall (n :: Nat). KnownNat n => Signed n
minBoundSym#
            _ -> Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#

  satMul :: SaturationMode -> Signed n -> Signed n -> Signed n
satMul SatWrap a :: Signed n
a b :: 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 SatBound a :: Signed n
a b :: 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
        (rL :: BitVector n
rL,rR :: 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
          1 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
rR
          _ -> case BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
rL of
            0 -> Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#
            _ -> Signed n
forall (n :: Nat). KnownNat n => Signed n
minBound#
  satMul SatZero a :: Signed n
a b :: 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
        (rL :: BitVector n
rL,rR :: 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
          1 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
rR
          _ -> Integer -> Signed n
forall (n :: Nat). KnownNat n => Integer -> Signed n
fromInteger# 0
  satMul SatSymmetric a :: Signed n
a b :: 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
        (rL :: BitVector n
rL,rR :: 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
          1 -> BitVector n -> Signed n
forall (n :: Nat). KnownNat n => BitVector n -> Signed n
unpack# BitVector n
rR
          _ -> case BitVector n -> Bit
forall a. BitPack a => a -> Bit
msb BitVector n
rL of
            0 -> Signed n
forall (n :: Nat). KnownNat n => Signed n
maxBound#
            _ -> Signed n
forall (n :: Nat). KnownNat n => Signed n
minBoundSym#

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# 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 x :: 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
< 2 = case p n -> Integer
forall a. Integral a => a -> Integer
toInteger p n
x of
                                       0 -> []
                                       _ -> [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 i :: Index (Signed n)
i f :: IxValue (Signed n) -> f (IxValue (Signed n))
f s :: 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)