{-|
Copyright  :  (C) 2013-2016, University of Twente,
                  2016     , Myrtle Software Ltd,
                  2021-2024, QBayLogic B.V.
License    :  BSD2 (see the file LICENSE)
Maintainer :  QBayLogic B.V. <[email protected]>
-}

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

{-# LANGUAGE Unsafe #-}

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

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

import Prelude hiding                 (even, odd)

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)
#if MIN_VERSION_base(4,16,0)
import GHC.Exts                       (wordToWord8#, wordToWord16#, wordToWord32#)
#else
import GHC.Exts                       (narrow8Word#, narrow16Word#, narrow32Word#)
#endif
import GHC.Generics                   (Generic)
#if MIN_VERSION_base(4,15,0)
import GHC.Num.BigNat                 (bigNatToWord, bigNatToWord#)
import GHC.Num.Integer
  (integerFromNatural, integerShiftL, integerToNatural)
import GHC.Num.Natural
  (Natural (..), naturalShiftL, naturalShiftR, naturalToWord)
#else
import GHC.Integer.GMP.Internals      (bigNatToWord)
import GHC.Natural                    (Natural (..), naturalFromInteger)
#endif
import GHC.Natural                    (naturalToInteger)
import GHC.TypeLits                   (KnownNat, Nat, type (+))
#if MIN_VERSION_base(4,15,0)
import GHC.TypeNats                   (natVal)
#else
import GHC.TypeLits                   (natVal)
#endif
import GHC.TypeLits.Extra             (Max)
import GHC.Word                       (Word (..), Word8 (..), Word16 (..), Word32 (..))
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)

import Clash.Annotations.Primitive (hasBlackBox)
import Clash.Class.BitPack            (BitPack (..), packXWith, bitCoerce)
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 (reduceOr)
import Clash.Promoted.Nat             (natToNum, natToNatural)
import Clash.Sized.Internal.BitVector (BitVector (BV), Bit, high, low, undefError)
import qualified Clash.Sized.Internal.BitVector as BV
import Clash.Sized.Internal.Mod
import Clash.XException
  (ShowX (..), NFDataX (..), errorX, showsPrecXWith, rwhnfX)

{- $setup
>>> :m -Prelude
>>> import Clash.Prelude
-}

#include "MachDeps.h"

type role Unsigned nominal

-- | Arbitrary-width unsigned integer represented by @n@ bits
--
-- Given @n@ bits, an 'Unsigned' @n@ number has a range of: [0 .. 2^@n@-1]
--
-- * __NB__: The usual Haskell method of converting an integral numeric type to
-- another, 'fromIntegral', is not well suited for Clash as it will go through
-- 'Integer' which is arbitrarily bounded in HDL. Instead use
-- 'Clash.Class.BitPack.bitCoerce' and the 'Resize' class.
-- * __NB__: The 'Num' operators perform @wrap-around@ on overflow. If you want
-- saturation on overflow, check out the 'SaturatingNum' class.
--
-- >>> maxBound :: Unsigned 3
-- 7
-- >>> minBound :: Unsigned 3
-- 0
-- >>> read (show (maxBound :: Unsigned 3)) :: Unsigned 3
-- 7
-- >>> 1 + 2 :: Unsigned 3
-- 3
-- >>> 2 + 6 :: Unsigned 3
-- 0
-- >>> 1 - 3 :: Unsigned 3
-- 6
-- >>> 2 * 3 :: Unsigned 3
-- 6
-- >>> 2 * 4 :: Unsigned 3
-- 0
-- >>> (2 :: Unsigned 3) `mul` (4 :: Unsigned 3) :: Unsigned 6
-- 8
-- >>> (2 :: Unsigned 3) `add` (6 :: Unsigned 3) :: Unsigned 4
-- 8
-- >>> satAdd SatSymmetric 2 6 :: Unsigned 3
-- 7
-- >>> satSub SatSymmetric 2 3 :: Unsigned 3
-- 0
--
-- Unsigned has the <https://downloads.haskell.org/ghc/latest/docs/html/users_guide/exts/roles.html type role>
--
-- >>> :i Unsigned
-- type role Unsigned nominal
-- ...
--
-- as it is not safe to coerce between different width Unsigned. To change the
-- width, use the functions in the 'Clash.Class.Resize.Resize' class.
#if MIN_VERSION_base(4,15,0) && !MIN_VERSION_base(4,17,0)
data Unsigned (n :: Nat) =
    -- | The constructor, 'U', and the field, 'unsafeToNatural', are not
    -- synthesizable.
    U { unsafeToNatural :: !Natural }
#else
newtype Unsigned (n :: Nat) =
    -- | The constructor, 'U', and the field, 'unsafeToNatural', are not
    -- synthesizable.
    U { forall (n :: Nat). Unsigned n -> Nat
unsafeToNatural :: Natural }
#endif
  deriving (Typeable (Unsigned n)
Typeable (Unsigned n) =>
(forall (c :: Type -> Type).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Unsigned n -> c (Unsigned n))
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Unsigned n))
-> (Unsigned n -> Constr)
-> (Unsigned n -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Unsigned n)))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Unsigned n)))
-> ((forall b. Data b => b -> b) -> Unsigned n -> Unsigned n)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Unsigned n -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Unsigned n -> r)
-> (forall u. (forall d. Data d => d -> u) -> Unsigned n -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> Unsigned n -> u)
-> (forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n))
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n))
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n))
-> Data (Unsigned n)
Unsigned n -> Constr
Unsigned n -> DataType
(forall b. Data b => b -> b) -> Unsigned n -> Unsigned n
forall (n :: Nat). KnownNat n => Typeable (Unsigned n)
forall (n :: Nat). KnownNat n => Unsigned n -> Constr
forall (n :: Nat). KnownNat n => Unsigned n -> DataType
forall (n :: Nat).
KnownNat n =>
(forall b. Data b => b -> b) -> Unsigned n -> Unsigned n
forall (n :: Nat) u.
KnownNat n =>
Int -> (forall d. Data d => d -> u) -> Unsigned n -> u
forall (n :: Nat) u.
KnownNat n =>
(forall d. Data d => d -> u) -> Unsigned n -> [u]
forall (n :: Nat) r r'.
KnownNat n =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
forall (n :: Nat) r r'.
KnownNat n =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
forall (n :: Nat) (m :: Type -> Type).
(KnownNat n, Monad m) =>
(forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
forall (n :: Nat) (m :: Type -> Type).
(KnownNat n, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned 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 (Unsigned 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) -> Unsigned n -> c (Unsigned n)
forall (n :: Nat) (t :: Type -> Type) (c :: Type -> Type).
(KnownNat n, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Unsigned 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 (Unsigned 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) -> Unsigned n -> u
forall u. (forall d. Data d => d -> u) -> Unsigned n -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Unsigned n)
forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Unsigned n -> c (Unsigned n)
forall (t :: Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Unsigned n))
forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Unsigned 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) -> Unsigned n -> c (Unsigned n)
gfoldl :: forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Unsigned n -> c (Unsigned 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 (Unsigned n)
gunfold :: forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Unsigned n)
$ctoConstr :: forall (n :: Nat). KnownNat n => Unsigned n -> Constr
toConstr :: Unsigned n -> Constr
$cdataTypeOf :: forall (n :: Nat). KnownNat n => Unsigned n -> DataType
dataTypeOf :: Unsigned n -> DataType
$cdataCast1 :: forall (n :: Nat) (t :: Type -> Type) (c :: Type -> Type).
(KnownNat n, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Unsigned n))
dataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Unsigned 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 (Unsigned n))
dataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Unsigned n))
$cgmapT :: forall (n :: Nat).
KnownNat n =>
(forall b. Data b => b -> b) -> Unsigned n -> Unsigned n
gmapT :: (forall b. Data b => b -> b) -> Unsigned n -> Unsigned n
$cgmapQl :: forall (n :: Nat) r r'.
KnownNat n =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
$cgmapQr :: forall (n :: Nat) r r'.
KnownNat n =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Unsigned n -> r
$cgmapQ :: forall (n :: Nat) u.
KnownNat n =>
(forall d. Data d => d -> u) -> Unsigned n -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Unsigned n -> [u]
$cgmapQi :: forall (n :: Nat) u.
KnownNat n =>
Int -> (forall d. Data d => d -> u) -> Unsigned n -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Unsigned n -> u
$cgmapM :: forall (n :: Nat) (m :: Type -> Type).
(KnownNat n, Monad m) =>
(forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
gmapM :: forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
$cgmapMp :: forall (n :: Nat) (m :: Type -> Type).
(KnownNat n, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
gmapMp :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
$cgmapMo :: forall (n :: Nat) (m :: Type -> Type).
(KnownNat n, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
gmapMo :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Unsigned n -> m (Unsigned n)
Data, (forall x. Unsigned n -> Rep (Unsigned n) x)
-> (forall x. Rep (Unsigned n) x -> Unsigned n)
-> Generic (Unsigned n)
forall (n :: Nat) x. Rep (Unsigned n) x -> Unsigned n
forall (n :: Nat) x. Unsigned n -> Rep (Unsigned n) x
forall x. Rep (Unsigned n) x -> Unsigned n
forall x. Unsigned n -> Rep (Unsigned n) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall (n :: Nat) x. Unsigned n -> Rep (Unsigned n) x
from :: forall x. Unsigned n -> Rep (Unsigned n) x
$cto :: forall (n :: Nat) x. Rep (Unsigned n) x -> Unsigned n
to :: forall x. Rep (Unsigned n) x -> Unsigned n
Generic)

{-# ANN U hasBlackBox #-}

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE size# #-}
{-# ANN size# hasBlackBox #-}
size# :: KnownNat n => Unsigned n -> Int
#if MIN_VERSION_base(4,15,0)
size# :: forall (n :: Nat). KnownNat n => Unsigned n -> Int
size# Unsigned n
u = Nat -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Unsigned n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal Unsigned n
u)
#else
size# u = fromInteger (natVal u)
#endif

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

instance Show (Unsigned n) where
  show :: Unsigned n -> String
show (U Nat
i) = Nat -> String
forall a. Show a => a -> String
show Nat
i
  {-# NOINLINE show #-}

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

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

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

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

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE pack# #-}
{-# ANN pack# hasBlackBox #-}
pack# :: Unsigned n -> BitVector n
pack# :: forall (n :: Nat). Unsigned n -> BitVector n
pack# (U Nat
i) = Nat -> Nat -> BitVector n
forall (n :: Nat). Nat -> Nat -> BitVector n
BV Nat
0 Nat
i

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE unpack# #-}
{-# ANN unpack# hasBlackBox #-}
unpack# :: KnownNat n => BitVector n -> Unsigned n
unpack# :: forall (n :: Nat). KnownNat n => BitVector n -> Unsigned n
unpack# (BV Nat
0 Nat
i) = Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U Nat
i
unpack# BitVector n
bv = String -> [BitVector n] -> Unsigned n
forall (n :: Nat) a. KnownNat n => String -> [BitVector n] -> a
undefError String
"Unsigned.unpack" [BitVector n
bv]

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

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE eq# #-}
{-# ANN eq# hasBlackBox #-}
eq# :: Unsigned n -> Unsigned n -> Bool
eq# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
eq# (U Nat
v1) (U Nat
v2) = Nat
v1 Nat -> Nat -> Bool
forall a. Eq a => a -> a -> Bool
== Nat
v2

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE neq# #-}
{-# ANN neq# hasBlackBox #-}
neq# :: Unsigned n -> Unsigned n -> Bool
neq# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
neq# (U Nat
v1) (U Nat
v2) = Nat
v1 Nat -> Nat -> Bool
forall a. Eq a => a -> a -> Bool
/= Nat
v2

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

lt#,ge#,gt#,le# :: Unsigned n -> Unsigned n -> Bool
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE lt# #-}
{-# ANN lt# hasBlackBox #-}
lt# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
lt# (U Nat
n) (U Nat
m) = Nat
n Nat -> Nat -> Bool
forall a. Ord a => a -> a -> Bool
< Nat
m
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE ge# #-}
{-# ANN ge# hasBlackBox #-}
ge# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
ge# (U Nat
n) (U Nat
m) = Nat
n Nat -> Nat -> Bool
forall a. Ord a => a -> a -> Bool
>= Nat
m
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE gt# #-}
{-# ANN gt# hasBlackBox #-}
gt# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
gt# (U Nat
n) (U Nat
m) = Nat
n Nat -> Nat -> Bool
forall a. Ord a => a -> a -> Bool
> Nat
m
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE le# #-}
{-# ANN le# hasBlackBox #-}
le# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Bool
le# (U Nat
n) (U Nat
m) = Nat
n Nat -> Nat -> Bool
forall a. Ord a => a -> a -> Bool
<= Nat
m

-- | The functions: 'enumFrom', 'enumFromThen', 'enumFromTo', and
-- 'enumFromThenTo', are not synthesizable.
instance KnownNat n => Enum (Unsigned n) where
  succ :: Unsigned n -> Unsigned n
succ Unsigned n
n
    | Unsigned n
n Unsigned n -> Unsigned n -> Bool
forall a. Eq a => a -> a -> Bool
== Unsigned n
forall a. Bounded a => a
maxBound =
        String -> Unsigned n
forall a. HasCallStack => String -> a
error (String -> Unsigned n) -> String -> Unsigned n
forall a b. (a -> b) -> a -> b
$ String
"'succ' was called on (" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show @(Unsigned n) Unsigned 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
"Unsigned " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Nat -> String
forall a. Show a => a -> String
show (forall (n :: Nat). KnownNat n => Nat
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 = Unsigned n
n Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> Unsigned n
+# Integer -> Unsigned n
forall (n :: Nat). KnownNat n => Integer -> Unsigned n
fromInteger# Integer
1

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

  toEnum :: Int -> Unsigned n
toEnum         = Int -> Unsigned n
forall (n :: Nat). KnownNat n => Int -> Unsigned n
toEnum#
  fromEnum :: Unsigned n -> Int
fromEnum       = Unsigned n -> Int
forall (n :: Nat). KnownNat n => Unsigned n -> Int
fromEnum#
  enumFrom :: Unsigned n -> [Unsigned n]
enumFrom       = Unsigned n -> [Unsigned n]
forall (n :: Nat). KnownNat n => Unsigned n -> [Unsigned n]
enumFrom#
  enumFromThen :: Unsigned n -> Unsigned n -> [Unsigned n]
enumFromThen   = Unsigned n -> Unsigned n -> [Unsigned n]
forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> [Unsigned n]
enumFromThen#
  enumFromTo :: Unsigned n -> Unsigned n -> [Unsigned n]
enumFromTo     = Unsigned n -> Unsigned n -> [Unsigned n]
forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> [Unsigned n]
enumFromTo#
  enumFromThenTo :: Unsigned n -> Unsigned n -> Unsigned n -> [Unsigned n]
enumFromThenTo = Unsigned n -> Unsigned n -> Unsigned n -> [Unsigned n]
forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> Unsigned n -> [Unsigned n]
enumFromThenTo#

toEnum# :: forall n. KnownNat n => Int -> Unsigned n
toEnum# :: forall (n :: Nat). KnownNat n => Int -> Unsigned n
toEnum# = Integer -> Unsigned n
forall (n :: Nat). KnownNat n => Integer -> Unsigned n
fromInteger# (Integer -> Unsigned n) -> (Int -> Integer) -> Int -> Unsigned n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a. Integral a => a -> Integer
toInteger
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE toEnum# #-}
{-# ANN toEnum# hasBlackBox #-}

fromEnum# :: forall n. KnownNat n => Unsigned n -> Int
fromEnum# :: forall (n :: Nat). KnownNat n => Unsigned n -> Int
fromEnum# = Integer -> Int
forall a. Enum a => a -> Int
fromEnum (Integer -> Int) -> (Unsigned n -> Integer) -> Unsigned n -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Unsigned n -> Integer
forall (n :: Nat). Unsigned n -> Integer
toInteger#
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE fromEnum# #-}
{-# ANN fromEnum# hasBlackBox #-}

enumFrom# :: forall n. KnownNat n => Unsigned n -> [Unsigned n]
enumFrom# :: forall (n :: Nat). KnownNat n => Unsigned n -> [Unsigned n]
enumFrom# = \Unsigned n
x -> (Nat -> Unsigned n) -> [Nat] -> [Unsigned n]
forall a b. (a -> b) -> [a] -> [b]
map (Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat -> Unsigned n) -> (Nat -> Nat) -> Nat -> Unsigned n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Nat -> Nat -> Nat
forall a. Integral a => a -> a -> a
`mod` Nat
m)) [Unsigned n -> Nat
forall (n :: Nat). Unsigned n -> Nat
unsafeToNatural Unsigned n
x .. Unsigned n -> Nat
forall (n :: Nat). Unsigned n -> Nat
unsafeToNatural (Unsigned n
forall a. Bounded a => a
maxBound :: Unsigned n)]
#if MIN_VERSION_base(4,15,0)
  where m :: Nat
m = Nat
1 Nat -> Word -> Nat
`naturalShiftL` Nat -> Word
naturalToWord (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))
#else
  where m = 1 `shiftL` fromInteger (natVal (Proxy @n))
#endif
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE enumFrom# #-}

enumFromThen# :: forall n. KnownNat n => Unsigned n -> Unsigned n -> [Unsigned n]
enumFromThen# :: forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> [Unsigned n]
enumFromThen# = \Unsigned n
x Unsigned n
y -> [Nat] -> [Unsigned n]
toUnsigneds [Unsigned n -> Nat
forall (n :: Nat). Unsigned n -> Nat
unsafeToNatural Unsigned n
x, Unsigned n -> Nat
forall (n :: Nat). Unsigned n -> Nat
unsafeToNatural Unsigned n
y .. Unsigned n -> Unsigned n -> Nat
bound Unsigned n
x Unsigned n
y]
 where
  toUnsigneds :: [Nat] -> [Unsigned n]
toUnsigneds = (Nat -> Unsigned n) -> [Nat] -> [Unsigned n]
forall a b. (a -> b) -> [a] -> [b]
map (Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat -> Unsigned n) -> (Nat -> Nat) -> Nat -> Unsigned n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Nat -> Nat -> Nat
forall a. Integral a => a -> a -> a
`mod` Nat
m))
  bound :: Unsigned n -> Unsigned n -> Nat
bound Unsigned n
x Unsigned n
y = Unsigned n -> Nat
forall (n :: Nat). Unsigned n -> Nat
unsafeToNatural (if Unsigned n
x Unsigned n -> Unsigned n -> Bool
forall a. Ord a => a -> a -> Bool
<= Unsigned n
y then Unsigned n
forall a. Bounded a => a
maxBound else Unsigned n
forall a. Bounded a => a
minBound :: Unsigned n)
#if MIN_VERSION_base(4,15,0)
  m :: Nat
m = Nat
1 Nat -> Word -> Nat
`naturalShiftL` Nat -> Word
naturalToWord (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))
#else
  m = 1 `shiftL` fromInteger (natVal (Proxy @n))
#endif
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE enumFromThen# #-}

enumFromTo# :: forall n. KnownNat n => Unsigned n -> Unsigned n -> [Unsigned n]
enumFromTo# :: forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> [Unsigned n]
enumFromTo# = \Unsigned n
x Unsigned n
y -> (Nat -> Unsigned n) -> [Nat] -> [Unsigned n]
forall a b. (a -> b) -> [a] -> [b]
map (Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat -> Unsigned n) -> (Nat -> Nat) -> Nat -> Unsigned n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Nat -> Nat -> Nat
forall a. Integral a => a -> a -> a
`mod` Nat
m)) [Unsigned n -> Nat
forall (n :: Nat). Unsigned n -> Nat
unsafeToNatural Unsigned n
x .. Unsigned n -> Nat
forall (n :: Nat). Unsigned n -> Nat
unsafeToNatural Unsigned n
y]
#if MIN_VERSION_base(4,15,0)
  where m :: Nat
m = Nat
1 Nat -> Word -> Nat
`naturalShiftL` Nat -> Word
naturalToWord (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))
#else
  where m = 1 `shiftL` fromInteger (natVal (Proxy @n))
#endif
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE enumFromTo# #-}

enumFromThenTo# :: forall n. KnownNat n => Unsigned n -> Unsigned n -> Unsigned n -> [Unsigned n]
enumFromThenTo# :: forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> Unsigned n -> [Unsigned n]
enumFromThenTo# = \Unsigned n
x1 Unsigned n
x2 Unsigned n
y -> (Nat -> Unsigned n) -> [Nat] -> [Unsigned n]
forall a b. (a -> b) -> [a] -> [b]
map (Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat -> Unsigned n) -> (Nat -> Nat) -> Nat -> Unsigned n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Nat -> Nat -> Nat
forall a. Integral a => a -> a -> a
`mod` Nat
m)) [Unsigned n -> Nat
forall (n :: Nat). Unsigned n -> Nat
unsafeToNatural Unsigned n
x1, Unsigned n -> Nat
forall (n :: Nat). Unsigned n -> Nat
unsafeToNatural Unsigned n
x2 .. Unsigned n -> Nat
forall (n :: Nat). Unsigned n -> Nat
unsafeToNatural Unsigned n
y]
#if MIN_VERSION_base(4,15,0)
  where m :: Nat
m = Nat
1 Nat -> Word -> Nat
`naturalShiftL` Nat -> Word
naturalToWord (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))
#else
  where m = 1 `shiftL` fromInteger (natVal (Proxy @n))
#endif
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE enumFromThenTo# #-}

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

minBound# :: Unsigned n
minBound# :: forall (n :: Nat). Unsigned n
minBound# = Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U Nat
0
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE minBound# #-}
{-# ANN minBound# hasBlackBox #-}

maxBound# :: forall n. KnownNat n => Unsigned n
maxBound# :: forall (n :: Nat). KnownNat n => Unsigned n
maxBound# = let m :: Nat
m = Nat
1 Nat -> Int -> Nat
forall a. Bits a => a -> Int -> a
`shiftL` (forall (n :: Nat) a. (Num a, KnownNat n) => a
natToNum @n) in  Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat
m Nat -> Nat -> Nat
forall a. Num a => a -> a -> a
- Nat
1)
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE maxBound# #-}
{-# ANN maxBound# hasBlackBox #-}

-- | __NB__: 'fromInteger'/'fromIntegral' can cause unexpected truncation, as
-- 'Integer' is arbitrarily bounded during synthesis.  Prefer
-- 'Clash.Class.BitPack.bitCoerce' and the 'Resize' class.
instance KnownNat n => Num (Unsigned n) where
  + :: Unsigned n -> Unsigned n -> Unsigned n
(+)         = Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> Unsigned n
(+#)
  (-)         = Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> Unsigned n
(-#)
  * :: Unsigned n -> Unsigned n -> Unsigned n
(*)         = Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> Unsigned n
(*#)
  negate :: Unsigned n -> Unsigned n
negate      = Unsigned n -> Unsigned n
forall (n :: Nat). KnownNat n => Unsigned n -> Unsigned n
negate#
  abs :: Unsigned n -> Unsigned n
abs         = Unsigned n -> Unsigned n
forall a. a -> a
id
  signum :: Unsigned n -> Unsigned n
signum Unsigned n
bv   = Unsigned 1 -> Unsigned n
forall (n :: Nat) (m :: Nat).
KnownNat m =>
Unsigned n -> Unsigned m
resize# (BitVector 1 -> Unsigned 1
forall (n :: Nat). KnownNat n => BitVector n -> Unsigned n
unpack# (Bit -> BitVector 1
BV.pack# (Unsigned n -> Bit
forall a. BitPack a => a -> Bit
reduceOr Unsigned n
bv)))
  fromInteger :: Integer -> Unsigned n
fromInteger = Integer -> Unsigned n
forall (n :: Nat). KnownNat n => Integer -> Unsigned n
fromInteger#

(+#),(-#),(*#) :: forall n . KnownNat n => Unsigned n -> Unsigned n -> Unsigned n
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE (+#) #-}
{-# ANN (+#) hasBlackBox #-}
+# :: forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> Unsigned n
(+#) = \(U Nat
i) (U Nat
j) -> Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat -> Nat -> Nat -> Nat
addMod Nat
m Nat
i Nat
j)
#if MIN_VERSION_base(4,15,0)
  where m :: Nat
m = Nat
1 Nat -> Word -> Nat
`naturalShiftL` Nat -> Word
naturalToWord (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))
#else
  where m = 1 `shiftL` fromInteger (natVal (Proxy @n))
#endif

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE (-#) #-}
{-# ANN (-#) hasBlackBox #-}
-# :: forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> Unsigned n
(-#) = \(U Nat
i) (U Nat
j) -> Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat -> Nat -> Nat -> Nat
subMod Nat
m Nat
i Nat
j)
#if MIN_VERSION_base(4,15,0)
  where m :: Nat
m = Nat
1 Nat -> Word -> Nat
`naturalShiftL` Nat -> Word
naturalToWord (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))
#else
  where m = 1 `shiftL` fromInteger (natVal (Proxy @n))
#endif

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE (*#) #-}
{-# ANN (*#) hasBlackBox #-}
*# :: forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> Unsigned n
(*#) = \(U Nat
i) (U Nat
j) -> Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat -> Nat -> Nat -> Nat
mulMod2 Nat
m Nat
i Nat
j)
#if MIN_VERSION_base(4,15,0)
  where m :: Nat
m = (Nat
1 Nat -> Word -> Nat
`naturalShiftL` Nat -> Word
naturalToWord (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))) Nat -> Nat -> Nat
forall a. Num a => a -> a -> a
- Nat
1
#else
  where m = (1 `shiftL` fromInteger (natVal (Proxy @n))) - 1
#endif

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE negate# #-}
{-# ANN negate# hasBlackBox #-}
negate# :: forall n . KnownNat n => Unsigned n -> Unsigned n
negate# :: forall (n :: Nat). KnownNat n => Unsigned n -> Unsigned n
negate# = \(U Nat
i) -> Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat -> Nat -> Nat
negateMod Nat
m Nat
i)
#if MIN_VERSION_base(4,15,0)
  where m :: Nat
m = Nat
1 Nat -> Word -> Nat
`naturalShiftL` Nat -> Word
naturalToWord (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))
#else
  where m = 1 `shiftL` fromInteger (natVal (Proxy @n))
#endif

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE fromInteger# #-}
{-# ANN fromInteger# hasBlackBox #-}
fromInteger# :: forall n . KnownNat n => Integer -> Unsigned n
#if MIN_VERSION_base(4,15,0)
fromInteger# :: forall (n :: Nat). KnownNat n => Integer -> Unsigned n
fromInteger# = \Integer
x -> Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Integer -> Nat
integerToNatural (Integer
x Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`mod` Integer
m))
 where
  m :: Integer
m = Integer
1 Integer -> Word -> Integer
`integerShiftL` Nat -> Word
naturalToWord (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))
#else
fromInteger# = \x -> U (naturalFromInteger (x `mod` m))
 where
  m = 1 `shiftL` fromInteger (natVal (Proxy @n))
#endif

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

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE plus# #-}
{-# ANN plus# hasBlackBox #-}
plus# :: Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
plus# :: forall (m :: Nat) (n :: Nat).
Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
plus# (U Nat
a) (U Nat
b) = Nat -> Unsigned (Max m n + 1)
forall (n :: Nat). Nat -> Unsigned n
U (Nat
a Nat -> Nat -> Nat
forall a. Num a => a -> a -> a
+ Nat
b)

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE minus# #-}
{-# ANN minus# hasBlackBox #-}
minus# :: forall m n . (KnownNat m, KnownNat n) => Unsigned m -> Unsigned n
                                                -> Unsigned (Max m n + 1)
minus# :: forall (m :: Nat) (n :: Nat).
(KnownNat m, KnownNat n) =>
Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
minus# = \(U Nat
a) (U Nat
b) -> Nat -> Unsigned (Max m n + 1)
forall (n :: Nat). Nat -> Unsigned n
U (Nat -> Nat -> Nat -> Nat
subMod Nat
mask Nat
a Nat
b)
 where
#if MIN_VERSION_base(4,15,0)
  sz :: Word
sz   = Nat -> Word
naturalToWord (Proxy (Max m n + 1) -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @(Max m n + 1)))
  mask :: Nat
mask = Nat
1 Nat -> Word -> Nat
`naturalShiftL` Word
sz
#else
  sz   = fromInteger (natVal (Proxy @(Max m n + 1)))
  mask = 1 `shiftL` sz
#endif

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE times# #-}
{-# ANN times# hasBlackBox #-}
times# :: Unsigned m -> Unsigned n -> Unsigned (m + n)
times# :: forall (m :: Nat) (n :: Nat).
Unsigned m -> Unsigned n -> Unsigned (m + n)
times# (U Nat
a) (U Nat
b) = Nat -> Unsigned (m + n)
forall (n :: Nat). Nat -> Unsigned n
U (Nat
a Nat -> Nat -> Nat
forall a. Num a => a -> a -> a
* Nat
b)

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

-- | __NB__: 'toInteger'/'fromIntegral' can cause unexpected truncation, as
-- 'Integer' is arbitrarily bounded during synthesis.  Prefer
-- 'Clash.Class.BitPack.bitCoerce' and the 'Resize' class.
instance KnownNat n => Integral (Unsigned n) where
  quot :: Unsigned n -> Unsigned n -> Unsigned n
quot        = Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
quot#
  rem :: Unsigned n -> Unsigned n -> Unsigned n
rem         = Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
rem#
  div :: Unsigned n -> Unsigned n -> Unsigned n
div         = Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
quot#
  mod :: Unsigned n -> Unsigned n -> Unsigned n
mod         = Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
rem#
  quotRem :: Unsigned n -> Unsigned n -> (Unsigned n, Unsigned n)
quotRem Unsigned n
n Unsigned n
d = (Unsigned n
n Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
`quot#` Unsigned n
d,Unsigned n
n Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
`rem#` Unsigned n
d)
  divMod :: Unsigned n -> Unsigned n -> (Unsigned n, Unsigned n)
divMod  Unsigned n
n Unsigned n
d = (Unsigned n
n Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
`quot#` Unsigned n
d,Unsigned n
n Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
`rem#` Unsigned n
d)
  toInteger :: Unsigned n -> Integer
toInteger   = Unsigned n -> Integer
forall (n :: Nat). Unsigned n -> Integer
toInteger#

quot#,rem# :: Unsigned n -> Unsigned n -> Unsigned n
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE quot# #-}
{-# ANN quot# hasBlackBox #-}
quot# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
quot# (U Nat
i) (U Nat
j) = Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat
i Nat -> Nat -> Nat
forall a. Integral a => a -> a -> a
`quot` Nat
j)
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE rem# #-}
{-# ANN rem# hasBlackBox #-}
rem# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
rem# (U Nat
i) (U Nat
j) = Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat
i Nat -> Nat -> Nat
forall a. Integral a => a -> a -> a
`rem` Nat
j)

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE toInteger# #-}
{-# ANN toInteger# hasBlackBox #-}
toInteger# :: Unsigned n -> Integer
toInteger# :: forall (n :: Nat). Unsigned n -> Integer
toInteger# (U Nat
i) = Nat -> Integer
naturalToInteger Nat
i

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

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

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

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE and# #-}
{-# ANN and# hasBlackBox #-}
and# :: Unsigned n -> Unsigned n -> Unsigned n
and# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
and# (U Nat
v1) (U Nat
v2) = Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat
v1 Nat -> Nat -> Nat
forall a. Bits a => a -> a -> a
.&. Nat
v2)

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE or# #-}
{-# ANN or# hasBlackBox #-}
or# :: Unsigned n -> Unsigned n -> Unsigned n
or# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
or# (U Nat
v1) (U Nat
v2) = Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat
v1 Nat -> Nat -> Nat
forall a. Bits a => a -> a -> a
.|. Nat
v2)

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE xor# #-}
{-# ANN xor# hasBlackBox #-}
xor# :: Unsigned n -> Unsigned n -> Unsigned n
xor# :: forall (n :: Nat). Unsigned n -> Unsigned n -> Unsigned n
xor# (U Nat
v1) (U Nat
v2) = Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat
v1 Nat -> Nat -> Nat
forall a. Bits a => a -> a -> a
`xor` Nat
v2)

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE complement# #-}
{-# ANN complement# hasBlackBox #-}
complement# :: forall n . KnownNat n => Unsigned n -> Unsigned n
complement# :: forall (n :: Nat). KnownNat n => Unsigned n -> Unsigned n
complement# = \(U Nat
i) -> Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat -> Nat
complementN Nat
i)
  where complementN :: Nat -> Nat
complementN = Nat -> Nat -> Nat
complementMod (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))

shiftL#, shiftR#, rotateL#, rotateR# :: forall n .KnownNat n => Unsigned n -> Int -> Unsigned n
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE shiftL# #-}
{-# ANN shiftL# hasBlackBox #-}
shiftL# :: forall (n :: Nat). KnownNat n => Unsigned n -> Int -> Unsigned n
shiftL# = \(U Nat
v) Int
i ->
#if MIN_VERSION_base(4,15,0)
  let i' :: Word
i' = Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i in
  if | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0     -> String -> Unsigned n
forall a. HasCallStack => String -> a
error (String -> Unsigned n) -> String -> Unsigned 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
i
     | Word
i' Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
>= Word
sz  -> Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U Nat
0
     | Bool
otherwise -> Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U ((Nat -> Word -> Nat
naturalShiftL Nat
v Word
i') Nat -> Nat -> Nat
forall a. Integral a => a -> a -> a
`mod` Nat
m)
 where
  sz :: Word
sz = Nat -> Word
naturalToWord (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))
  m :: Nat
m  = Nat
1 Nat -> Word -> Nat
`naturalShiftL` Word
sz
#else
  if | i < 0     -> error $ "'shiftL' undefined for negative number: " ++ show i
     | i >= sz   -> U 0
     | otherwise -> U ((shiftL v i) `mod` m)
 where
  sz = fromInteger (natVal (Proxy @n))
  m  = 1 `shiftL` sz
#endif

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE shiftR# #-}
{-# ANN shiftR# hasBlackBox #-}
-- shiftR# doesn't need the KnownNat constraint
-- But having the same type signature for all shift and rotate functions
-- makes implementing the Evaluator easier.
shiftR# :: forall (n :: Nat). KnownNat n => Unsigned n -> Int -> Unsigned n
shiftR# (U Nat
v) Int
i
  | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0     = String -> Unsigned n
forall a. HasCallStack => String -> a
error
              (String -> Unsigned n) -> String -> Unsigned 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
i
  | Bool
otherwise = Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U (Nat -> Int -> Nat
forall a. Bits a => a -> Int -> a
shiftR Nat
v Int
i)

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE rotateL# #-}
{-# ANN rotateL# hasBlackBox #-}
rotateL# :: forall (n :: Nat). KnownNat n => Unsigned n -> Int -> Unsigned n
rotateL# =
  \(U Nat
n) Int
b ->
    if Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then
#if MIN_VERSION_base(4,15,0)
      let l :: Nat
l   = Nat -> Word -> Nat
naturalShiftL Nat
n Word
b'
          r :: Nat
r   = Nat -> Word -> Nat
naturalShiftR Nat
n Word
b''
          b' :: Word
b'  = Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b Word -> Word -> Word
forall a. Integral a => a -> a -> a
`mod` Word
sz
#else
      let l   = shiftL n b'
          r   = shiftR n b''
          b'  = b `mod` sz
#endif
          b'' :: Word
b'' = Word
sz Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
b'
      in  Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U ((Nat
l Nat -> Nat -> Nat
forall a. Bits a => a -> a -> a
.|. Nat
r) Nat -> Nat -> Nat
forall a. Integral a => a -> a -> a
`mod` Nat
m)
    else
      String -> Unsigned n
forall a. HasCallStack => String -> a
error (String -> Unsigned n) -> String -> Unsigned 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
#if MIN_VERSION_base(4,15,0)
    sz :: Word
sz = Nat -> Word
naturalToWord (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))
    m :: Nat
m  = Nat
1 Nat -> Word -> Nat
`naturalShiftL` Word
sz
#else
    sz = fromInteger (natVal (Proxy @n)) :: Int
    m  = 1 `shiftL` sz
#endif

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE rotateR# #-}
{-# ANN rotateR# hasBlackBox #-}
rotateR# :: forall (n :: Nat). KnownNat n => Unsigned n -> Int -> Unsigned n
rotateR# =
  \(U Nat
n) Int
b ->
    if Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 then
#if MIN_VERSION_base(4,15,0)
      let l :: Nat
l   = Nat -> Word -> Nat
naturalShiftR Nat
n Word
b'
          r :: Nat
r   = Nat -> Word -> Nat
naturalShiftL Nat
n Word
b''
          b' :: Word
b'  = Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b Word -> Word -> Word
forall a. Integral a => a -> a -> a
`mod` Word
sz
#else
      let l   = shiftR n b'
          r   = shiftL n b''
          b'  = b `mod` sz
#endif
          b'' :: Word
b'' = Word
sz Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
b'
      in  Nat -> Unsigned n
forall (n :: Nat). Nat -> Unsigned n
U ((Nat
l Nat -> Nat -> Nat
forall a. Bits a => a -> a -> a
.|. Nat
r) Nat -> Nat -> Nat
forall a. Integral a => a -> a -> a
`mod` Nat
m)
    else
      String -> Unsigned n
forall a. HasCallStack => String -> a
error (String -> Unsigned n) -> String -> Unsigned 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
#if MIN_VERSION_base(4,15,0)
    sz :: Word
sz = Nat -> Word
naturalToWord (Proxy n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n))
    m :: Nat
m  = Nat
1 Nat -> Word -> Nat
`naturalShiftL` Word
sz
#else
    sz = fromInteger (natVal (Proxy @n)) :: Int
    m  = 1 `shiftL` sz
#endif


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

instance Resize Unsigned where
  resize :: forall (a :: Nat) (b :: Nat).
(KnownNat a, KnownNat b) =>
Unsigned a -> Unsigned b
resize     = Unsigned a -> Unsigned b
forall (n :: Nat) (m :: Nat).
KnownNat m =>
Unsigned n -> Unsigned m
resize#
  zeroExtend :: forall (a :: Nat) (b :: Nat).
(KnownNat a, KnownNat b) =>
Unsigned a -> Unsigned (b + a)
zeroExtend = Unsigned a -> Unsigned (b + a)
forall (a :: Nat) (b :: Nat).
(KnownNat a, KnownNat b) =>
Unsigned a -> Unsigned (b + a)
forall (f :: Nat -> Type) (a :: Nat) (b :: Nat).
(Resize f, KnownNat a, KnownNat b) =>
f a -> f (b + a)
extend
  truncateB :: forall (a :: Nat) (b :: Nat).
KnownNat a =>
Unsigned (a + b) -> Unsigned a
truncateB  = Unsigned (a + b) -> Unsigned a
forall (n :: Nat) (m :: Nat).
KnownNat m =>
Unsigned n -> Unsigned m
resize#

-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE resize# #-}
{-# ANN resize# hasBlackBox #-}
resize# :: forall n m . KnownNat m => Unsigned n -> Unsigned m
resize# :: forall (n :: Nat) (m :: Nat).
KnownNat m =>
Unsigned n -> Unsigned m
resize# = \(U Nat
i) -> if Nat
i Nat -> Nat -> Bool
forall a. Ord a => a -> a -> Bool
>= Nat
m then Nat -> Unsigned m
forall (n :: Nat). Nat -> Unsigned n
U (Nat
i Nat -> Nat -> Nat
forall a. Integral a => a -> a -> a
`mod` Nat
m) else Nat -> Unsigned m
forall (n :: Nat). Nat -> Unsigned n
U Nat
i
#if MIN_VERSION_base(4,15,0)
  where m :: Nat
m = Nat
1 Nat -> Word -> Nat
`naturalShiftL` Nat -> Word
naturalToWord (Proxy m -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @m))
#else
  where m = 1 `shiftL` fromInteger (natVal (Proxy @m))
#endif

instance Default (Unsigned n) where
  def :: Unsigned n
def = Unsigned n
forall (n :: Nat). Unsigned n
minBound#

instance KnownNat n => Lift (Unsigned n) where
  lift :: forall (m :: Type -> Type). Quote m => Unsigned n -> m Exp
lift u :: Unsigned n
u@(U Nat
i) = m Exp -> m Type -> m Exp
forall (m :: Type -> Type). Quote m => m Exp -> m Type -> m Exp
sigE [| fromInteger# i |] (Nat -> m Type
forall (m :: Type -> Type). Quote m => Nat -> m Type
decUnsigned (Unsigned n -> Nat
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Nat
natVal Unsigned n
u))
  {-# NOINLINE lift #-}
#if MIN_VERSION_template_haskell(2,16,0)
  liftTyped :: forall (m :: Type -> Type).
Quote m =>
Unsigned n -> Code m (Unsigned n)
liftTyped = Unsigned n -> Code m (Unsigned n)
forall a (m :: Type -> Type). (Lift a, Quote m) => a -> Code m a
liftTypedFromUntyped
#endif

#if MIN_VERSION_template_haskell(2,17,0)
decUnsigned :: Quote m => Natural -> m Type
decUnsigned :: forall (m :: Type -> Type). Quote m => Nat -> m Type
decUnsigned Nat
n = m Type -> m Type -> m Type
forall (m :: Type -> Type). Quote m => m Type -> m Type -> m Type
appT (Name -> m Type
forall (m :: Type -> Type). Quote m => Name -> m Type
conT ''Unsigned) (m TyLit -> m Type
forall (m :: Type -> Type). Quote m => m TyLit -> m Type
litT (m TyLit -> m Type) -> m TyLit -> m Type
forall a b. (a -> b) -> a -> b
$ Integer -> m TyLit
forall (m :: Type -> Type). Quote m => Integer -> m TyLit
numTyLit (Nat -> Integer
integerFromNatural Nat
n))
#else
decUnsigned :: Integer -> TypeQ
decUnsigned n = appT (conT ''Unsigned) (litT $ numTyLit n)
#endif

instance KnownNat n => SaturatingNum (Unsigned n) where
  satAdd :: SaturationMode -> Unsigned n -> Unsigned n -> Unsigned n
satAdd SaturationMode
SatWrap Unsigned n
a Unsigned n
b = Unsigned n
a Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> Unsigned n
+# Unsigned n
b
  satAdd SaturationMode
SatZero Unsigned n
a Unsigned n
b =
    let r :: Unsigned (Max n n + 1)
r = Unsigned n -> Unsigned n -> Unsigned (Max n n + 1)
forall (m :: Nat) (n :: Nat).
Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
plus# Unsigned n
a Unsigned n
b
    in  case Unsigned (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Unsigned (n + 1)
Unsigned (Max n n + 1)
r of
          Bit
0 -> Unsigned (n + 1) -> Unsigned n
forall (n :: Nat) (m :: Nat).
KnownNat m =>
Unsigned n -> Unsigned m
resize# Unsigned (n + 1)
Unsigned (Max n n + 1)
r
          Bit
_ -> Unsigned n
forall (n :: Nat). Unsigned n
minBound#
  satAdd SaturationMode
SatError Unsigned n
a Unsigned n
b =
    let r :: Unsigned (Max n n + 1)
r = Unsigned n -> Unsigned n -> Unsigned (Max n n + 1)
forall (m :: Nat) (n :: Nat).
Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
plus# Unsigned n
a Unsigned n
b
    in  case Unsigned (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Unsigned (n + 1)
Unsigned (Max n n + 1)
r of
          Bit
0 -> Unsigned (n + 1) -> Unsigned n
forall (n :: Nat) (m :: Nat).
KnownNat m =>
Unsigned n -> Unsigned m
resize# Unsigned (n + 1)
Unsigned (Max n n + 1)
r
          Bit
_ -> String -> Unsigned n
forall a. HasCallStack => String -> a
errorX String
"Unsigned.satAdd: overflow"
  satAdd SaturationMode
_ Unsigned n
a Unsigned n
b =
    let r :: Unsigned (Max n n + 1)
r  = Unsigned n -> Unsigned n -> Unsigned (Max n n + 1)
forall (m :: Nat) (n :: Nat).
Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
plus# Unsigned n
a Unsigned n
b
    in  case Unsigned (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Unsigned (n + 1)
Unsigned (Max n n + 1)
r of
          Bit
0 -> Unsigned (n + 1) -> Unsigned n
forall (n :: Nat) (m :: Nat).
KnownNat m =>
Unsigned n -> Unsigned m
resize# Unsigned (n + 1)
Unsigned (Max n n + 1)
r
          Bit
_ -> Unsigned n
forall (n :: Nat). KnownNat n => Unsigned n
maxBound#

  satSub :: SaturationMode -> Unsigned n -> Unsigned n -> Unsigned n
satSub SaturationMode
SatWrap Unsigned n
a Unsigned n
b = Unsigned n
a Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> Unsigned n
-# Unsigned n
b
  satSub SaturationMode
SatError Unsigned n
a Unsigned n
b =
    let r :: Unsigned (Max n n + 1)
r = Unsigned n -> Unsigned n -> Unsigned (Max n n + 1)
forall (m :: Nat) (n :: Nat).
(KnownNat m, KnownNat n) =>
Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
minus# Unsigned n
a Unsigned n
b
    in  case Unsigned (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Unsigned (n + 1)
Unsigned (Max n n + 1)
r of
          Bit
0 -> Unsigned (n + 1) -> Unsigned n
forall (n :: Nat) (m :: Nat).
KnownNat m =>
Unsigned n -> Unsigned m
resize# Unsigned (n + 1)
Unsigned (Max n n + 1)
r
          Bit
_ -> String -> Unsigned n
forall a. HasCallStack => String -> a
errorX String
"Unsigned.satSub: overflow"
  satSub SaturationMode
_ Unsigned n
a Unsigned n
b =
    let r :: Unsigned (Max n n + 1)
r = Unsigned n -> Unsigned n -> Unsigned (Max n n + 1)
forall (m :: Nat) (n :: Nat).
(KnownNat m, KnownNat n) =>
Unsigned m -> Unsigned n -> Unsigned (Max m n + 1)
minus# Unsigned n
a Unsigned n
b
    in  case Unsigned (n + 1) -> Bit
forall a. BitPack a => a -> Bit
msb Unsigned (n + 1)
Unsigned (Max n n + 1)
r of
          Bit
0 -> Unsigned (n + 1) -> Unsigned n
forall (n :: Nat) (m :: Nat).
KnownNat m =>
Unsigned n -> Unsigned m
resize# Unsigned (n + 1)
Unsigned (Max n n + 1)
r
          Bit
_ -> Unsigned n
forall (n :: Nat). Unsigned n
minBound#

  satMul :: SaturationMode -> Unsigned n -> Unsigned n -> Unsigned n
satMul SaturationMode
SatWrap Unsigned n
a Unsigned n
b = Unsigned n
a Unsigned n -> Unsigned n -> Unsigned n
forall (n :: Nat).
KnownNat n =>
Unsigned n -> Unsigned n -> Unsigned n
*# Unsigned n
b
  satMul SaturationMode
SatZero Unsigned n
a Unsigned n
b =
    let r :: Unsigned (n + n)
r       = Unsigned n -> Unsigned n -> Unsigned (n + n)
forall (m :: Nat) (n :: Nat).
Unsigned m -> Unsigned n -> Unsigned (m + n)
times# Unsigned n
a Unsigned n
b
        (BitVector n
rL,BitVector n
rR) = Unsigned (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 Unsigned (n + n)
r
    in  case BitVector n
rL of
          BitVector n
0 -> BitVector n -> Unsigned n
forall (n :: Nat). KnownNat n => BitVector n -> Unsigned n
unpack# BitVector n
rR
          BitVector n
_ -> Unsigned n
forall (n :: Nat). Unsigned n
minBound#
  satMul SaturationMode
SatError Unsigned n
a Unsigned n
b =
    let r :: Unsigned (n + n)
r       = Unsigned n -> Unsigned n -> Unsigned (n + n)
forall (m :: Nat) (n :: Nat).
Unsigned m -> Unsigned n -> Unsigned (m + n)
times# Unsigned n
a Unsigned n
b
        (BitVector n
rL,BitVector n
rR) = Unsigned (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 Unsigned (n + n)
r
    in  case BitVector n
rL of
          BitVector n
0 -> BitVector n -> Unsigned n
forall (n :: Nat). KnownNat n => BitVector n -> Unsigned n
unpack# BitVector n
rR
          BitVector n
_ -> String -> Unsigned n
forall a. HasCallStack => String -> a
errorX String
"Unsigned.satMul: overflow"
  satMul SaturationMode
_ Unsigned n
a Unsigned n
b =
    let r :: Unsigned (n + n)
r       = Unsigned n -> Unsigned n -> Unsigned (n + n)
forall (m :: Nat) (n :: Nat).
Unsigned m -> Unsigned n -> Unsigned (m + n)
times# Unsigned n
a Unsigned n
b
        (BitVector n
rL,BitVector n
rR) = Unsigned (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 Unsigned (n + n)
r
    in  case BitVector n
rL of
          BitVector n
0 -> BitVector n -> Unsigned n
forall (n :: Nat). KnownNat n => BitVector n -> Unsigned n
unpack# BitVector n
rR
          BitVector n
_ -> Unsigned n
forall (n :: Nat). KnownNat n => Unsigned n
maxBound#

  -- Implementations for satSucc and satPred are needed because 1 :: Unsigned 0
  -- overflows to 0, meaning without the first check SatError would return 0.

  satSucc :: SaturationMode -> Unsigned n -> Unsigned n
satSucc SaturationMode
SatError Unsigned n
a
    | Unsigned n
a Unsigned n -> Unsigned n -> Bool
forall a. Eq a => a -> a -> Bool
== Unsigned n
forall a. Bounded a => a
maxBound = String -> Unsigned n
forall a. HasCallStack => String -> a
errorX String
"Unsigned.satSucc: overflow"
  satSucc SaturationMode
satMode Unsigned n
a = SaturationMode -> Unsigned n -> Unsigned n -> Unsigned n
forall a. SaturatingNum a => SaturationMode -> a -> a -> a
satAdd SaturationMode
satMode Unsigned n
a Unsigned n
1
  {-# INLINE satSucc #-}

  satPred :: SaturationMode -> Unsigned n -> Unsigned n
satPred SaturationMode
SatError Unsigned n
a
    | Unsigned n
a Unsigned n -> Unsigned n -> Bool
forall a. Eq a => a -> a -> Bool
== Unsigned n
forall a. Bounded a => a
minBound = String -> Unsigned n
forall a. HasCallStack => String -> a
errorX String
"Unsigned.satPred: overflow"
  satPred SaturationMode
satMode Unsigned n
a = SaturationMode -> Unsigned n -> Unsigned n -> Unsigned n
forall a. SaturatingNum a => SaturationMode -> a -> a -> a
satSub SaturationMode
satMode Unsigned n
a Unsigned n
1
  {-# INLINE satPred #-}

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

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

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

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

unsignedToWord :: Unsigned WORD_SIZE_IN_BITS -> Word
#if MIN_VERSION_base(4,15,0)
unsignedToWord :: Unsigned 64 -> Word
unsignedToWord (U (NS Word#
u#)) = Word# -> Word
W# Word#
u#
unsignedToWord (U (NB ByteArray#
u#)) = ByteArray# -> Word
bigNatToWord ByteArray#
u#
#else
unsignedToWord (U (NatS# u#)) = W# u#
unsignedToWord (U (NatJ# u#)) = W# (bigNatToWord u#)
#endif
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE unsignedToWord #-}
{-# ANN unsignedToWord hasBlackBox #-}

unsigned8toWord8 :: Unsigned 8 -> Word8
#if MIN_VERSION_base(4,16,0)
unsigned8toWord8 :: Unsigned 8 -> Word8
unsigned8toWord8 (U (NS Word#
u#)) = Word8# -> Word8
W8# (Word# -> Word8#
wordToWord8# Word#
u#)
unsigned8toWord8 (U (NB ByteArray#
u#)) = Word8# -> Word8
W8# (Word# -> Word8#
wordToWord8# (ByteArray# -> Word#
bigNatToWord# ByteArray#
u#))
#elif MIN_VERSION_base(4,15,0)
unsigned8toWord8 (U (NS u#)) = W8# (narrow8Word# u#)
unsigned8toWord8 (U (NB u#)) = W8# (narrow8Word# (bigNatToWord# u#))
#else
unsigned8toWord8 (U (NatS# u#)) = W8# (narrow8Word# u#)
unsigned8toWord8 (U (NatJ# u#)) = W8# (narrow8Word# (bigNatToWord u#))
#endif
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE unsigned8toWord8 #-}
{-# ANN unsigned8toWord8 hasBlackBox #-}

unsigned16toWord16 :: Unsigned 16 -> Word16
#if MIN_VERSION_base(4,16,0)
unsigned16toWord16 :: Unsigned 16 -> Word16
unsigned16toWord16 (U (NS Word#
u#)) = Word16# -> Word16
W16# (Word# -> Word16#
wordToWord16# Word#
u#)
unsigned16toWord16 (U (NB ByteArray#
u#)) = Word16# -> Word16
W16# (Word# -> Word16#
wordToWord16# (ByteArray# -> Word#
bigNatToWord# ByteArray#
u#))
#elif MIN_VERSION_base(4,15,0)
unsigned16toWord16 (U (NS u#)) = W16# (narrow16Word# u#)
unsigned16toWord16 (U (NB u#)) = W16# (narrow16Word# (bigNatToWord# u#))
#else
unsigned16toWord16 (U (NatS# u#)) = W16# (narrow16Word# u#)
unsigned16toWord16 (U (NatJ# u#)) = W16# (narrow16Word# (bigNatToWord u#))
#endif
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE unsigned16toWord16 #-}
{-# ANN unsigned16toWord16 hasBlackBox #-}

unsigned32toWord32 :: Unsigned 32 -> Word32
#if MIN_VERSION_base(4,16,0)
unsigned32toWord32 :: Unsigned 32 -> Word32
unsigned32toWord32 (U (NS Word#
u#)) = Word32# -> Word32
W32# (Word# -> Word32#
wordToWord32# Word#
u#)
unsigned32toWord32 (U (NB ByteArray#
u#)) = Word32# -> Word32
W32# (Word# -> Word32#
wordToWord32# (ByteArray# -> Word#
bigNatToWord# ByteArray#
u#))
#elif MIN_VERSION_base(4,15,0)
unsigned32toWord32 (U (NS u#)) = W32# (narrow32Word# u#)
unsigned32toWord32 (U (NB u#)) = W32# (narrow32Word# (bigNatToWord# u#))
#else
unsigned32toWord32 (U (NatS# u#)) = W32# (narrow32Word# u#)
unsigned32toWord32 (U (NatJ# u#)) = W32# (narrow32Word# (bigNatToWord u#))
#endif
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE unsigned32toWord32 #-}
{-# ANN unsigned32toWord32 hasBlackBox #-}

{-# RULES
"bitCoerce/Unsigned WORD_SIZE_IN_BITS -> Word" bitCoerce = unsignedToWord
"bitCoerce/Unsigned 8 -> Word8" bitCoerce = unsigned8toWord8
"bitCoerce/Unsigned 16 -> Word16" bitCoerce = unsigned16toWord16
"bitCoerce/Unsigned 32 -> Word32" bitCoerce = unsigned32toWord32
 #-}