content: {-# LANGUAGE
    TemplateHaskell,
    MultiParamTypeClasses,
    OverloadedStrings
    #-}
  module LLVM.Internal.InlineAssembly where
   
  import LLVM.Prelude
  
  import Control.Monad.IO.Class
  
  import qualified Data.ByteString.Char8 as ByteString
  
  import Foreign.C
  import Foreign.Ptr
  
  import qualified LLVM.Internal.FFI.InlineAssembly as FFI
  import qualified LLVM.Internal.FFI.LLVMCTypes as FFI
  import qualified LLVM.Internal.FFI.Module as FFI
  import qualified LLVM.Internal.FFI.PtrHierarchy as FFI
  
  import qualified LLVM.AST as A (Definition(..))
  import qualified LLVM.AST.InlineAssembly as A
  import qualified LLVM.AST.Type as A
  
  import LLVM.Internal.Coding 
  import LLVM.Internal.EncodeAST
  import LLVM.Internal.DecodeAST
  import LLVM.Internal.Value
  
  genCodingInstance [t| A.Dialect |] ''FFI.AsmDialect [
     (FFI.asmDialectATT, A.ATTDialect),
     (FFI.asmDialectIntel, A.IntelDialect)
    ]
  
  instance EncodeM EncodeAST A.InlineAssembly (Ptr FFI.InlineAsm) where
    encodeM (A.InlineAssembly {
               A.type' = t,
               A.assembly = assembly,
               A.constraints = constraints,
               A.hasSideEffects = hasSideEffects,
               A.alignStack = alignStack,
               A.dialect = dialect
             }) = do
      t <- encodeM t
      assembly <- encodeM assembly
      constraints <- encodeM constraints
      hasSideEffects <- encodeM hasSideEffects
      alignStack <- encodeM alignStack
      dialect <- encodeM dialect
      liftIO $ FFI.createInlineAsm t assembly constraints hasSideEffects alignStack dialect
  
  instance DecodeM DecodeAST A.InlineAssembly (Ptr FFI.InlineAsm) where
    decodeM p = do
      return A.InlineAssembly
        `ap` (liftM (\(A.PointerType f _) -> f) (typeOf p))
        `ap` (decodeM =<< liftIO (FFI.getInlineAsmAssemblyString p))
        `ap` (decodeM =<< liftIO (FFI.getInlineAsmConstraintString p))
        `ap` (decodeM =<< liftIO (FFI.inlineAsmHasSideEffects p))
        `ap` (decodeM =<< liftIO (FFI.inlineAsmIsAlignStack p))
        `ap` (decodeM =<< liftIO (FFI.getInlineAsmDialect p))
  
  instance DecodeM DecodeAST [A.Definition] (FFI.ModuleAsm CString) where
    decodeM (FFI.ModuleAsm s) = do
      s' <- decodeM s
      return . map A.ModuleInlineAssembly $ ByteString.lines s'
  