crackNum-3.30: src/CrackNum/Types.hs
---------------------------------------------------------------------------
-- |
-- Module : CrackNum.Types
-- Copyright : (c) Levent Erkok
-- License : BSD3
-- Maintainer : erkokl@gmail.com
-- Stability : experimental
--
-- Core types: the formats, kinds, and rounding modes we understand
-----------------------------------------------------------------------------
{-# OPTIONS_GHC -Wall -Werror #-}
module CrackNum.Types(
FP(..), fpSize, NKind(..), kSize, RM(..), toLibBFRM, toSBVRM, Flag(..), isRMode, isLanes, isDebug
) where
-- NB. LibBF's rounding modes (NearEven etc.) are pattern synonyms rather than
-- constructors, so RoundMode(..) does not bring them into scope; import wholesale.
import LibBF
import Data.SBV (SRoundingMode, sRNE, sRNA, sRTP, sRTN, sRTZ)
-- | Various precisions we support
data FP = SP -- Single precision
| DP -- Double precision
| FP Int Int -- Arbitrary precision with given exponent and significand sizes
| E5M2 -- Synonym for FP 5 3 (yes, confusing M2->3, but that's the naming)
| E4M3 -- Custom FP8 format with no infinities and limited NaNs
| FP4 -- NVIDIA FP4 (E2M1) format with no infinities and no NaNs
| FP4E0M3 -- 4-bit sign-magnitude integer format; no exponent at all
| E8M0 -- OCP MX scale format; no sign and no significand at all
deriving (Show, Eq)
-- | How many bits does this float occupy
fpSize :: FP -> Int
fpSize SP = 32
fpSize DP = 64
fpSize (FP i j) = i+j
fpSize E5M2 = 8
fpSize E4M3 = 8
fpSize FP4 = 4
fpSize FP4E0M3 = 4
fpSize E8M0 = 8
-- | Kinds of numbers we understand
data NKind = SInt Int -- ^ Signed integer of n bits
| SWord Int -- ^ Unsigned integer of n bits
| SFloat FP -- ^ Floating point with precision
kSize :: NKind -> Int
kSize (SInt i) = i
kSize (SWord i) = i
kSize (SFloat f) = fpSize f
-- | Rounding modes we support
data RM = RNE -- ^ Round nearest ties to even
| RNA -- ^ Round nearest ties to away
| RTP -- ^ Round towards positive infinity
| RTN -- ^ Round towards negative infinity
| RTZ -- ^ Round towards zero
deriving (Eq, Enum, Bounded)
-- | Show instance for RM, for descriptive purposes
instance Show RM where
show RNE = "RNE: Round nearest ties to even."
show RNA = "RNA: Round nearest ties to away."
show RTP = "RTP: Round towards positive infinity."
show RTN = "RTN: Round towards negative infinity."
show RTZ = "RTZ: Round towards zero."
-- Convert to LibBF rounding mode
toLibBFRM :: RM -> RoundMode
toLibBFRM RNE = NearEven
toLibBFRM RNA = NearAway
toLibBFRM RTP = ToPosInf
toLibBFRM RTN = ToNegInf
toLibBFRM RTZ = ToZero
-- Convert to SBV rounding mode
toSBVRM :: RM -> SRoundingMode
toSBVRM RNE = sRNE
toSBVRM RNA = sRNA
toSBVRM RTP = sRTP
toSBVRM RTN = sRTN
toSBVRM RTZ = sRTZ
-- | Options accepted by the executable
data Flag = Signed Int -- ^ Crack as a signed word with the given number of bits
| Unsigned Int -- ^ Crack as an unsigned word with the given number of bits
| Floating FP -- ^ Crack as the corresponding floating-point type
| RMode RM -- ^ Rounding mode to use
| Lanes Int -- ^ How many lanes to decode?
| BadFlag [String] -- ^ Bad input
| Version -- ^ Version
| Debug -- ^ Run in debug mode. Debugging only.
| GUI -- ^ Launch the graphical interface
| Formats -- ^ List the floating-point formats we support
| Help -- ^ Show help
deriving (Show, Eq)
-- | Is this a rounding flag?
isRMode :: Flag -> Bool
isRMode RMode{} = True
isRMode _ = False
-- | Is this lanes flag
isLanes :: Flag -> Bool
isLanes Lanes{} = True
isLanes _ = False
-- | Is this the debug flag?
isDebug :: Flag -> Bool
isDebug Debug{} = True
isDebug _ = False