{-# LANGUAGE 
  MultiParamTypeClasses
  #-}
module LLVM.Internal.FastMathFlags where

import LLVM.Prelude

import Control.Monad.Trans
import Control.Monad.AnyCont
import Control.Monad.State
import Control.Exception

import Data.Bits

import qualified LLVM.Internal.FFI.Builder as FFI
import qualified LLVM.Internal.FFI.LLVMCTypes as FFI

import LLVM.Internal.Coding
import LLVM.Internal.EncodeAST

import qualified LLVM.AST as A

instance EncodeM IO A.FastMathFlags FFI.FastMathFlags where
  encodeM :: HasCallStack => FastMathFlags -> IO FastMathFlags
encodeM FastMathFlags
f = FastMathFlags -> IO FastMathFlags
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (FastMathFlags -> IO FastMathFlags)
-> FastMathFlags -> IO FastMathFlags
forall a b. (a -> b) -> a -> b
$ (FastMathFlags -> FastMathFlags -> FastMathFlags)
-> [FastMathFlags] -> FastMathFlags
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 FastMathFlags -> FastMathFlags -> FastMathFlags
forall a. Bits a => a -> a -> a
(.|.) [
               if FastMathFlags -> Bool
a FastMathFlags
f then FastMathFlags
b else FastMathFlags
0
               | (FastMathFlags -> Bool
a,FastMathFlags
b) <- [
                (FastMathFlags -> Bool
A.allowReassoc, FastMathFlags
FFI.fastMathFlagsAllowReassoc),
                (FastMathFlags -> Bool
A.noNaNs, FastMathFlags
FFI.fastMathFlagsNoNaNs),
                (FastMathFlags -> Bool
A.noInfs, FastMathFlags
FFI.fastMathFlagsNoInfs),
                (FastMathFlags -> Bool
A.noSignedZeros, FastMathFlags
FFI.fastMathFlagsNoSignedZeros),
                (FastMathFlags -> Bool
A.allowReciprocal, FastMathFlags
FFI.fastMathFlagsAllowReciprocal),
                (FastMathFlags -> Bool
A.allowContract, FastMathFlags
FFI.fastMathFlagsAllowContract),
                (FastMathFlags -> Bool
A.approxFunc, FastMathFlags
FFI.fastMathFlagsApproxFunc)
               ] 
              ]

instance EncodeM EncodeAST A.FastMathFlags () where
  encodeM :: HasCallStack => FastMathFlags -> EncodeAST ()
encodeM FastMathFlags
f = do 
    FastMathFlags
f <- IO FastMathFlags -> EncodeAST FastMathFlags
forall a. IO a -> EncodeAST a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO FastMathFlags -> EncodeAST FastMathFlags)
-> IO FastMathFlags -> EncodeAST FastMathFlags
forall a b. (a -> b) -> a -> b
$ FastMathFlags -> IO FastMathFlags
forall (e :: * -> *) h c. (EncodeM e h c, HasCallStack) => h -> e c
encodeM FastMathFlags
f
    Ptr Builder
builder <- (EncodeState -> Ptr Builder) -> EncodeAST (Ptr Builder)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets EncodeState -> Ptr Builder
encodeStateBuilder
    (forall r. (() -> IO r) -> IO r) -> EncodeAST ()
forall a. (forall r. (a -> IO r) -> IO r) -> EncodeAST a
forall (b :: * -> *) (m :: * -> *) a.
MonadAnyCont b m =>
(forall r. (a -> b r) -> b r) -> m a
anyContToM ((forall r. (() -> IO r) -> IO r) -> EncodeAST ())
-> (forall r. (() -> IO r) -> IO r) -> EncodeAST ()
forall a b. (a -> b) -> a -> b
$ IO () -> (() -> IO ()) -> (() -> IO r) -> IO r
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (Ptr Builder -> FastMathFlags -> IO ()
FFI.setFastMathFlags Ptr Builder
builder FastMathFlags
f) (\() -> Ptr Builder -> FastMathFlags -> IO ()
FFI.setFastMathFlags Ptr Builder
builder FastMathFlags
0)

instance Monad m => DecodeM m A.FastMathFlags FFI.FastMathFlags where
  decodeM :: HasCallStack => FastMathFlags -> m FastMathFlags
decodeM FastMathFlags
f = FastMathFlags -> m FastMathFlags
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return A.FastMathFlags {
                allowReassoc :: Bool
A.allowReassoc = FastMathFlags
FFI.fastMathFlagsAllowReassoc FastMathFlags -> FastMathFlags -> FastMathFlags
forall a. Bits a => a -> a -> a
.&. FastMathFlags
f FastMathFlags -> FastMathFlags -> Bool
forall a. Eq a => a -> a -> Bool
/= FastMathFlags
0,
                noNaNs :: Bool
A.noNaNs = FastMathFlags
FFI.fastMathFlagsNoNaNs FastMathFlags -> FastMathFlags -> FastMathFlags
forall a. Bits a => a -> a -> a
.&. FastMathFlags
f FastMathFlags -> FastMathFlags -> Bool
forall a. Eq a => a -> a -> Bool
/= FastMathFlags
0,
                noInfs :: Bool
A.noInfs = FastMathFlags
FFI.fastMathFlagsNoInfs FastMathFlags -> FastMathFlags -> FastMathFlags
forall a. Bits a => a -> a -> a
.&. FastMathFlags
f FastMathFlags -> FastMathFlags -> Bool
forall a. Eq a => a -> a -> Bool
/= FastMathFlags
0,
                noSignedZeros :: Bool
A.noSignedZeros = FastMathFlags
FFI.fastMathFlagsNoSignedZeros FastMathFlags -> FastMathFlags -> FastMathFlags
forall a. Bits a => a -> a -> a
.&. FastMathFlags
f FastMathFlags -> FastMathFlags -> Bool
forall a. Eq a => a -> a -> Bool
/= FastMathFlags
0,
                allowReciprocal :: Bool
A.allowReciprocal = FastMathFlags
FFI.fastMathFlagsAllowReciprocal FastMathFlags -> FastMathFlags -> FastMathFlags
forall a. Bits a => a -> a -> a
.&. FastMathFlags
f FastMathFlags -> FastMathFlags -> Bool
forall a. Eq a => a -> a -> Bool
/= FastMathFlags
0,
                allowContract :: Bool
A.allowContract = FastMathFlags
FFI.fastMathFlagsAllowContract FastMathFlags -> FastMathFlags -> FastMathFlags
forall a. Bits a => a -> a -> a
.&. FastMathFlags
f FastMathFlags -> FastMathFlags -> Bool
forall a. Eq a => a -> a -> Bool
/= FastMathFlags
0,
                approxFunc :: Bool
A.approxFunc = FastMathFlags
FFI.fastMathFlagsApproxFunc FastMathFlags -> FastMathFlags -> FastMathFlags
forall a. Bits a => a -> a -> a
.&. FastMathFlags
f FastMathFlags -> FastMathFlags -> Bool
forall a. Eq a => a -> a -> Bool
/= FastMathFlags
0
              }