{-# 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 :: FastMathFlags -> IO FastMathFlags
encodeM f :: FastMathFlags
f = FastMathFlags -> IO FastMathFlags
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 (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 0
               | (a :: FastMathFlags -> Bool
a,b :: 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 :: FastMathFlags -> EncodeAST ()
encodeM f :: FastMathFlags
f = do 
    FastMathFlags
f <- IO FastMathFlags -> EncodeAST FastMathFlags
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 => 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 (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 0)

instance Monad m => DecodeM m A.FastMathFlags FFI.FastMathFlags where
  decodeM :: FastMathFlags -> m FastMathFlags
decodeM f :: FastMathFlags
f = FastMathFlags -> m FastMathFlags
forall (m :: * -> *) a. Monad m => a -> m a
return FastMathFlags :: Bool
-> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> FastMathFlags
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
/= 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
/= 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
/= 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
/= 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
/= 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
/= 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
/= 0
              }