content: {-# LANGUAGE OverloadedStrings #-}
  module LLVM.Test.InlineAssembly where
  
  import Test.Tasty
  import Test.Tasty.HUnit
  
  import LLVM.Test.Support
  
  import LLVM.Context
  import LLVM.Module
  
  import LLVM.AST
  import LLVM.AST.Type
  import LLVM.AST.InlineAssembly as IA
  import qualified LLVM.AST.Linkage as L
  import qualified LLVM.AST.Visibility as V
  import qualified LLVM.AST.CallingConvention as CC
  import qualified LLVM.AST.Constant as C
  import qualified LLVM.AST.Global as G
  
  tests = testGroup "InlineAssembly" [
    testCase "expression" $ do
      let ast = Module "<string>" "<string>" Nothing Nothing [
                  GlobalDefinition $ 
                    functionDefaults {
                      G.returnType = i32,
                      G.name = Name "foo",
                      G.parameters = ([Parameter i32 (Name "x") []],False),
                      G.basicBlocks = [
                        BasicBlock (UnName 0) [
                          UnName 1 := Call {
                            tailCallKind = Nothing,
                            callingConvention = CC.C,
                            returnAttributes = [],
                            function = Left $ InlineAssembly {
                                         IA.type' = FunctionType i32 [i32] False,
                                         assembly = "bswap $0",
                                         constraints = "=r,r",
                                         hasSideEffects = False,
                                         alignStack = False,
                                         dialect = ATTDialect
                                       },
                            arguments = [
                              (LocalReference i32 (Name "x"), [])
                             ],
                            functionAttributes = [],
                            metadata = []
                          }
                        ] (
                          Do $ Ret (Just (LocalReference i32 (UnName 1))) []
                        )
                      ]
                  }
  
                ]
          s = "; ModuleID = '<string>'\n\
               \source_filename = \"<string>\"\n\
               \\n\
               \define i32 @foo(i32 %x) {\n\
               \  %1 = call i32 asm \"bswap $0\", \"=r,r\"(i32 %x)\n\
               \  ret i32 %1\n\
               \}\n"
      strCheck ast s,
  
    testCase "module" $ do
      let ast = Module "<string>" "<string>" Nothing Nothing [
                  ModuleInlineAssembly "foo",
                  ModuleInlineAssembly "bar",
                  GlobalDefinition $ globalVariableDefaults {
                    G.name = UnName 0,
                    G.type' = i32
                  }
                ]
          s = "; ModuleID = '<string>'\n\
               \source_filename = \"<string>\"\n\
               \\n\
               \module asm \"foo\"\n\
               \module asm \"bar\"\n\
               \\n\
               \@0 = external global i32\n"
      strCheck ast s
   ]
  