{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fplugin=GHC.TypeLits.KnownNat.Solver #-}
{-# OPTIONS_HADDOCK hide #-}
#include "MachDeps.h"
module Clash.Class.NumConvert.Internal.NumConvert where
import Prelude
import Clash.Class.BitPack
import Clash.Class.NumConvert.Internal.Canonical
import Clash.Class.Resize
import Clash.Sized.BitVector
import Clash.Sized.Index
import Clash.Sized.Signed
import Clash.Sized.Unsigned
import GHC.TypeLits (KnownNat, type (+), type (<=), type (^))
import GHC.TypeLits.Extra (CLogWZ)
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Word (Word16, Word32, Word64, Word8)
class NumConvertCanonical a b where
numConvertCanonical :: a -> b
type NumConvert a b =
( NumConvertCanonical a (Canonical a)
, NumConvertCanonical (Canonical a) (Canonical b)
, NumConvertCanonical (Canonical b) b
)
numConvert :: forall a b. NumConvert a b => a -> b
numConvert =
numConvertCanonical @(Canonical b) @b
. numConvertCanonical @(Canonical a) @(Canonical b)
. numConvertCanonical @a @(Canonical a)
instance (KnownNat n, KnownNat m, n <= m) => NumConvertCanonical (Index n) (Index m) where
numConvertCanonical = resize
instance (KnownNat n, KnownNat m, n <= 2 ^ m) => NumConvertCanonical (Index n) (Unsigned m) where
numConvertCanonical !a = resize $ bitCoerce a
instance (KnownNat n, KnownNat m, CLogWZ 2 n 0 + 1 <= m) => NumConvertCanonical (Index n) (Signed m) where
numConvertCanonical !a = numConvertCanonical $ bitCoerce @_ @(Unsigned (CLogWZ 2 n 0)) a
instance (KnownNat n, KnownNat m, n <= 2 ^ m) => NumConvertCanonical (Index n) (BitVector m) where
numConvertCanonical !a = resize $ pack a
instance (KnownNat n, KnownNat m, 2 ^ n <= m) => NumConvertCanonical (Unsigned n) (Index m) where
numConvertCanonical !a = bitCoerce $ resize a
instance (KnownNat n, KnownNat m, n <= m) => NumConvertCanonical (Unsigned n) (Unsigned m) where
numConvertCanonical = resize
instance (KnownNat n, KnownNat m, n + 1 <= m) => NumConvertCanonical (Unsigned n) (Signed m) where
numConvertCanonical !a = bitCoerce $ resize a
instance (KnownNat n, KnownNat m, n <= m) => NumConvertCanonical (Unsigned n) (BitVector m) where
numConvertCanonical !a = resize $ pack a
instance (KnownNat n, KnownNat m, n <= m) => NumConvertCanonical (Signed n) (Signed m) where
numConvertCanonical !a = resize a
instance (KnownNat n, KnownNat m, 2 ^ n <= m) => NumConvertCanonical (BitVector n) (Index m) where
numConvertCanonical = unpack . resize
instance (KnownNat n, KnownNat m, n <= m) => NumConvertCanonical (BitVector n) (Unsigned m) where
numConvertCanonical = unpack . resize
instance (KnownNat n, KnownNat m, n + 1 <= m) => NumConvertCanonical (BitVector n) (Signed m) where
numConvertCanonical = unpack . resize
instance (KnownNat n, KnownNat m, n <= m) => NumConvertCanonical (BitVector n) (BitVector m) where
numConvertCanonical = resize
instance NumConvertCanonical Word (Unsigned WORD_SIZE_IN_BITS) where
numConvertCanonical = bitCoerce
instance NumConvertCanonical (Unsigned WORD_SIZE_IN_BITS) Word where
numConvertCanonical = bitCoerce
instance NumConvertCanonical Word64 (Unsigned 64) where
numConvertCanonical = bitCoerce
instance NumConvertCanonical (Unsigned 64) Word64 where
numConvertCanonical = bitCoerce
instance NumConvertCanonical Word32 (Unsigned 32) where
numConvertCanonical = bitCoerce
instance NumConvertCanonical (Unsigned 32) Word32 where
numConvertCanonical = bitCoerce
instance NumConvertCanonical Word16 (Unsigned 16) where
numConvertCanonical = bitCoerce
instance NumConvertCanonical (Unsigned 16) Word16 where
numConvertCanonical = bitCoerce
instance NumConvertCanonical Word8 (Unsigned 8) where
numConvertCanonical = bitCoerce
instance NumConvertCanonical (Unsigned 8) Word8 where
numConvertCanonical = bitCoerce
instance NumConvertCanonical Int (Signed WORD_SIZE_IN_BITS) where
numConvertCanonical = bitCoerce
instance NumConvertCanonical (Signed WORD_SIZE_IN_BITS) Int where
numConvertCanonical = bitCoerce
instance NumConvertCanonical Int64 (Signed 64) where
numConvertCanonical = bitCoerce
instance NumConvertCanonical (Signed 64) Int64 where
numConvertCanonical = bitCoerce
instance NumConvertCanonical Int32 (Signed 32) where
numConvertCanonical = bitCoerce
instance NumConvertCanonical (Signed 32) Int32 where
numConvertCanonical = bitCoerce
instance NumConvertCanonical Int16 (Signed 16) where
numConvertCanonical = bitCoerce
instance NumConvertCanonical (Signed 16) Int16 where
numConvertCanonical = bitCoerce
instance NumConvertCanonical Int8 (Signed 8) where
numConvertCanonical = bitCoerce
instance NumConvertCanonical (Signed 8) Int8 where
numConvertCanonical = bitCoerce
instance NumConvertCanonical Bit (BitVector 1) where
numConvertCanonical = pack
instance NumConvertCanonical (BitVector 1) Bit where
numConvertCanonical = unpack