{-# LANGUAGE LambdaCase #-}

--------------------------------------------------------------------------------
-- | Pretty print LLVM IR Code.
--

module GHC.Llvm.Ppr (

    -- * Top level LLVM objects.
    ppLlvmModule,
    ppLlvmComments,
    ppLlvmComment,
    ppLlvmGlobals,
    ppLlvmGlobal,
    ppLlvmAliases,
    ppLlvmAlias,
    ppLlvmMetas,
    ppLlvmMeta,
    ppLlvmFunctionDecls,
    ppLlvmFunctionDecl,
    ppLlvmFunctions,
    ppLlvmFunction,

    ppVar,
    ppLit,
    ppTypeLit,
    ppName,
    ppPlainName

    ) where

import GHC.Prelude

import GHC.Llvm.Syntax
import GHC.Llvm.MetaData
import GHC.Llvm.Types

import Data.Int
import Data.List ( intersperse )
import GHC.Utils.Outputable

import GHC.CmmToLlvm.Config
import GHC.Utils.Panic
import GHC.Types.Unique

--------------------------------------------------------------------------------
-- * Top Level Print functions
--------------------------------------------------------------------------------

-- | Print out a whole LLVM module.
ppLlvmModule :: LlvmCgConfig -> LlvmModule -> SDoc
ppLlvmModule :: LlvmCgConfig -> LlvmModule -> SDoc
ppLlvmModule LlvmCgConfig
opts (LlvmModule [LMString]
comments [LlvmAlias]
aliases [MetaDecl]
meta [LMGlobal]
globals LlvmFunctionDecls
decls LlvmFunctions
funcs)
  = [LMString] -> SDoc
ppLlvmComments [LMString]
comments SDoc -> SDoc -> SDoc
$+$ SDoc
newLine
    SDoc -> SDoc -> SDoc
$+$ [LlvmAlias] -> SDoc
ppLlvmAliases [LlvmAlias]
aliases SDoc -> SDoc -> SDoc
$+$ SDoc
newLine
    SDoc -> SDoc -> SDoc
$+$ LlvmCgConfig -> [MetaDecl] -> SDoc
ppLlvmMetas LlvmCgConfig
opts [MetaDecl]
meta SDoc -> SDoc -> SDoc
$+$ SDoc
newLine
    SDoc -> SDoc -> SDoc
$+$ LlvmCgConfig -> [LMGlobal] -> SDoc
ppLlvmGlobals LlvmCgConfig
opts [LMGlobal]
globals SDoc -> SDoc -> SDoc
$+$ SDoc
newLine
    SDoc -> SDoc -> SDoc
$+$ LlvmFunctionDecls -> SDoc
ppLlvmFunctionDecls LlvmFunctionDecls
decls SDoc -> SDoc -> SDoc
$+$ SDoc
newLine
    SDoc -> SDoc -> SDoc
$+$ LlvmCgConfig -> LlvmFunctions -> SDoc
ppLlvmFunctions LlvmCgConfig
opts LlvmFunctions
funcs

-- | Print out a multi-line comment, can be inside a function or on its own
ppLlvmComments :: [LMString] -> SDoc
ppLlvmComments :: [LMString] -> SDoc
ppLlvmComments [LMString]
comments = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (LMString -> SDoc) -> [LMString] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map LMString -> SDoc
ppLlvmComment [LMString]
comments

-- | Print out a comment, can be inside a function or on its own
ppLlvmComment :: LMString -> SDoc
ppLlvmComment :: LMString -> SDoc
ppLlvmComment LMString
com = SDoc
forall doc. IsLine doc => doc
semi SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
com


-- | Print out a list of global mutable variable definitions
ppLlvmGlobals :: LlvmCgConfig -> [LMGlobal] -> SDoc
ppLlvmGlobals :: LlvmCgConfig -> [LMGlobal] -> SDoc
ppLlvmGlobals LlvmCgConfig
opts [LMGlobal]
ls = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (LMGlobal -> SDoc) -> [LMGlobal] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> LMGlobal -> SDoc
ppLlvmGlobal LlvmCgConfig
opts) [LMGlobal]
ls

-- | Print out a global mutable variable definition
ppLlvmGlobal :: LlvmCgConfig -> LMGlobal -> SDoc
ppLlvmGlobal :: LlvmCgConfig -> LMGlobal -> SDoc
ppLlvmGlobal LlvmCgConfig
opts (LMGlobal var :: LlvmVar
var@(LMGlobalVar LMString
_ LlvmType
_ LlvmLinkageType
link LMSection
x LMAlign
a LMConst
c) Maybe LlvmStatic
dat) =
    let sect :: SDoc
sect = case LMSection
x of
            Just LMString
x' -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
", section" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
doubleQuotes (LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
x')
            LMSection
Nothing -> SDoc
forall doc. IsOutput doc => doc
empty

        align :: SDoc
align = case LMAlign
a of
            Just Int
a' -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
", align" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int Int
a'
            LMAlign
Nothing -> SDoc
forall doc. IsOutput doc => doc
empty

        rhs :: SDoc
rhs = case Maybe LlvmStatic
dat of
            Just LlvmStatic
stat -> LlvmCgConfig -> LlvmStatic -> SDoc
pprSpecialStatic LlvmCgConfig
opts LlvmStatic
stat
            Maybe LlvmStatic
Nothing   -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmType -> LlvmType
pLower (LlvmType -> LlvmType) -> LlvmType -> LlvmType
forall a b. (a -> b) -> a -> b
$ LlvmVar -> LlvmType
getVarType LlvmVar
var)

        -- Position of linkage is different for aliases.
        const :: String
const = case LMConst
c of
          LMConst
Global   -> String
"global"
          LMConst
Constant -> String
"constant"
          LMConst
Alias    -> String
"alias"

    in LlvmCgConfig -> LlvmVar -> SDoc -> SDoc
ppAssignment LlvmCgConfig
opts LlvmVar
var (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ LlvmLinkageType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmLinkageType
link SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
const SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
rhs SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
sect SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
align
       SDoc -> SDoc -> SDoc
$+$ SDoc
newLine

ppLlvmGlobal LlvmCgConfig
opts (LMGlobal LlvmVar
var Maybe LlvmStatic
val) = String -> SDoc -> SDoc
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"ppLlvmGlobal" (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
  String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Non Global var ppr as global! " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
var SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"=" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Maybe SDoc -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((LlvmStatic -> SDoc) -> Maybe LlvmStatic -> Maybe SDoc
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts) Maybe LlvmStatic
val)


-- | Print out a list of LLVM type aliases.
ppLlvmAliases :: [LlvmAlias] -> SDoc
ppLlvmAliases :: [LlvmAlias] -> SDoc
ppLlvmAliases [LlvmAlias]
tys = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (LlvmAlias -> SDoc) -> [LlvmAlias] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map LlvmAlias -> SDoc
ppLlvmAlias [LlvmAlias]
tys

-- | Print out an LLVM type alias.
ppLlvmAlias :: LlvmAlias -> SDoc
ppLlvmAlias :: LlvmAlias -> SDoc
ppLlvmAlias (LMString
name, LlvmType
ty)
  = Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'%' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
name SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
forall doc. IsLine doc => doc
equals SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"type" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
ty


-- | Print out a list of LLVM metadata.
ppLlvmMetas :: LlvmCgConfig -> [MetaDecl] -> SDoc
ppLlvmMetas :: LlvmCgConfig -> [MetaDecl] -> SDoc
ppLlvmMetas LlvmCgConfig
opts [MetaDecl]
metas = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (MetaDecl -> SDoc) -> [MetaDecl] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> MetaDecl -> SDoc
ppLlvmMeta LlvmCgConfig
opts) [MetaDecl]
metas

-- | Print out an LLVM metadata definition.
ppLlvmMeta :: LlvmCgConfig -> MetaDecl -> SDoc
ppLlvmMeta :: LlvmCgConfig -> MetaDecl -> SDoc
ppLlvmMeta LlvmCgConfig
opts (MetaUnnamed MetaId
n MetaExpr
m)
  = MetaId -> SDoc
forall a. Outputable a => a -> SDoc
ppr MetaId
n SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
forall doc. IsLine doc => doc
equals SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> MetaExpr -> SDoc
ppMetaExpr LlvmCgConfig
opts MetaExpr
m

ppLlvmMeta LlvmCgConfig
_opts (MetaNamed LMString
n [MetaId]
m)
  = SDoc
exclamation SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
n SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
forall doc. IsLine doc => doc
equals SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
exclamation SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
braces SDoc
nodes
  where
    nodes :: SDoc
nodes = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ SDoc -> [SDoc] -> [SDoc]
forall a. a -> [a] -> [a]
intersperse SDoc
forall doc. IsLine doc => doc
comma ([SDoc] -> [SDoc]) -> [SDoc] -> [SDoc]
forall a b. (a -> b) -> a -> b
$ (MetaId -> SDoc) -> [MetaId] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map MetaId -> SDoc
forall a. Outputable a => a -> SDoc
ppr [MetaId]
m


-- | Print out a list of function definitions.
ppLlvmFunctions :: LlvmCgConfig -> LlvmFunctions -> SDoc
ppLlvmFunctions :: LlvmCgConfig -> LlvmFunctions -> SDoc
ppLlvmFunctions LlvmCgConfig
opts LlvmFunctions
funcs = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (LlvmFunction -> SDoc) -> LlvmFunctions -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> LlvmFunction -> SDoc
ppLlvmFunction LlvmCgConfig
opts) LlvmFunctions
funcs

-- | Print out a function definition.
ppLlvmFunction :: LlvmCgConfig -> LlvmFunction -> SDoc
ppLlvmFunction :: LlvmCgConfig -> LlvmFunction -> SDoc
ppLlvmFunction LlvmCgConfig
opts LlvmFunction
fun =
    let attrDoc :: SDoc
attrDoc = [LlvmFuncAttr] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppSpaceJoin (LlvmFunction -> [LlvmFuncAttr]
funcAttrs LlvmFunction
fun)
        secDoc :: SDoc
secDoc = case LlvmFunction -> LMSection
funcSect LlvmFunction
fun of
                      Just LMString
s' -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"section" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> (SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
doubleQuotes (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
s')
                      LMSection
Nothing -> SDoc
forall doc. IsOutput doc => doc
empty
        prefixDoc :: SDoc
prefixDoc = case LlvmFunction -> Maybe LlvmStatic
funcPrefix LlvmFunction
fun of
                        Just LlvmStatic
v  -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"prefix" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts LlvmStatic
v
                        Maybe LlvmStatic
Nothing -> SDoc
forall doc. IsOutput doc => doc
empty
    in String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"define" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmFunctionDecl -> [LMString] -> SDoc
ppLlvmFunctionHeader (LlvmFunction -> LlvmFunctionDecl
funcDecl LlvmFunction
fun) (LlvmFunction -> [LMString]
funcArgs LlvmFunction
fun)
        SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
attrDoc SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
secDoc SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
prefixDoc
        SDoc -> SDoc -> SDoc
$+$ SDoc
forall doc. IsLine doc => doc
lbrace
        SDoc -> SDoc -> SDoc
$+$ LlvmCgConfig -> LlvmBlocks -> SDoc
ppLlvmBlocks LlvmCgConfig
opts (LlvmFunction -> LlvmBlocks
funcBody LlvmFunction
fun)
        SDoc -> SDoc -> SDoc
$+$ SDoc
forall doc. IsLine doc => doc
rbrace
        SDoc -> SDoc -> SDoc
$+$ SDoc
newLine
        SDoc -> SDoc -> SDoc
$+$ SDoc
newLine

-- | Print out a function definition header.
ppLlvmFunctionHeader :: LlvmFunctionDecl -> [LMString] -> SDoc
ppLlvmFunctionHeader :: LlvmFunctionDecl -> [LMString] -> SDoc
ppLlvmFunctionHeader (LlvmFunctionDecl LMString
n LlvmLinkageType
l LlvmCallConvention
c LlvmType
r LlvmParameterListType
varg [LlvmParameter]
p LMAlign
a) [LMString]
args
  = let varg' :: SDoc
varg' = case LlvmParameterListType
varg of
                      LlvmParameterListType
VarArgs | [LlvmParameter] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [LlvmParameter]
p    -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"..."
                              | Bool
otherwise -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
", ..."
                      LlvmParameterListType
_otherwise          -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
""
        align :: SDoc
align = case LMAlign
a of
                     Just Int
a' -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" align " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
a'
                     LMAlign
Nothing -> SDoc
forall doc. IsOutput doc => doc
empty
        args' :: [SDoc]
args' = ((LlvmParameter, LMString) -> SDoc)
-> [(LlvmParameter, LMString)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (\((LlvmType
ty,[LlvmParamAttr]
p),LMString
n) -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
ty SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [LlvmParamAttr] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppSpaceJoin [LlvmParamAttr]
p SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'%'
                                    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
n)
                    ([LlvmParameter] -> [LMString] -> [(LlvmParameter, LMString)]
forall a b. [a] -> [b] -> [(a, b)]
zip [LlvmParameter]
p [LMString]
args)
    in LlvmLinkageType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmLinkageType
l SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCallConvention -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmCallConvention
c SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
r SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'@' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
n SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
lparen SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<>
        ([SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ SDoc -> [SDoc] -> [SDoc]
forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate SDoc
forall doc. IsLine doc => doc
comma [SDoc]
args') SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
varg' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
rparen SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
align

-- | Print out a list of function declaration.
ppLlvmFunctionDecls :: LlvmFunctionDecls -> SDoc
ppLlvmFunctionDecls :: LlvmFunctionDecls -> SDoc
ppLlvmFunctionDecls LlvmFunctionDecls
decs = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (LlvmFunctionDecl -> SDoc) -> LlvmFunctionDecls -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map LlvmFunctionDecl -> SDoc
ppLlvmFunctionDecl LlvmFunctionDecls
decs

-- | Print out a function declaration.
-- Declarations define the function type but don't define the actual body of
-- the function.
ppLlvmFunctionDecl :: LlvmFunctionDecl -> SDoc
ppLlvmFunctionDecl :: LlvmFunctionDecl -> SDoc
ppLlvmFunctionDecl (LlvmFunctionDecl LMString
n LlvmLinkageType
l LlvmCallConvention
c LlvmType
r LlvmParameterListType
varg [LlvmParameter]
p LMAlign
a)
  = let varg' :: SDoc
varg' = case LlvmParameterListType
varg of
                      LlvmParameterListType
VarArgs | [LlvmParameter] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [LlvmParameter]
p    -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"..."
                              | Bool
otherwise -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
", ..."
                      LlvmParameterListType
_otherwise          -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
""
        align :: SDoc
align = case LMAlign
a of
                     Just Int
a' -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" align" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
a'
                     LMAlign
Nothing -> SDoc
forall doc. IsOutput doc => doc
empty
        args :: SDoc
args = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ SDoc -> [SDoc] -> [SDoc]
forall a. a -> [a] -> [a]
intersperse (SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
space) ([SDoc] -> [SDoc]) -> [SDoc] -> [SDoc]
forall a b. (a -> b) -> a -> b
$
                  (LlvmParameter -> SDoc) -> [LlvmParameter] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (\(LlvmType
t,[LlvmParamAttr]
a) -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [LlvmParamAttr] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppSpaceJoin [LlvmParamAttr]
a) [LlvmParameter]
p
    in String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"declare" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmLinkageType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmLinkageType
l SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCallConvention -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmCallConvention
c SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
r SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'@' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<>
        LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
n SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
lparen SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
args SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
varg' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
rparen SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
align SDoc -> SDoc -> SDoc
$+$ SDoc
newLine


-- | Print out a list of LLVM blocks.
ppLlvmBlocks :: LlvmCgConfig -> LlvmBlocks -> SDoc
ppLlvmBlocks :: LlvmCgConfig -> LlvmBlocks -> SDoc
ppLlvmBlocks LlvmCgConfig
opts LlvmBlocks
blocks = [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (LlvmBlock -> SDoc) -> LlvmBlocks -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> LlvmBlock -> SDoc
ppLlvmBlock LlvmCgConfig
opts) LlvmBlocks
blocks

-- | Print out an LLVM block.
-- It must be part of a function definition.
ppLlvmBlock :: LlvmCgConfig -> LlvmBlock -> SDoc
ppLlvmBlock :: LlvmCgConfig -> LlvmBlock -> SDoc
ppLlvmBlock LlvmCgConfig
opts (LlvmBlock LlvmBlockId
blockId [LlvmStatement]
stmts) =
  let isLabel :: LlvmStatement -> Bool
isLabel (MkLabel LlvmBlockId
_) = Bool
True
      isLabel LlvmStatement
_           = Bool
False
      ([LlvmStatement]
block, [LlvmStatement]
rest)       = (LlvmStatement -> Bool)
-> [LlvmStatement] -> ([LlvmStatement], [LlvmStatement])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break LlvmStatement -> Bool
isLabel [LlvmStatement]
stmts
      ppRest :: SDoc
ppRest = case [LlvmStatement]
rest of
        MkLabel LlvmBlockId
id:[LlvmStatement]
xs -> LlvmCgConfig -> LlvmBlock -> SDoc
ppLlvmBlock LlvmCgConfig
opts (LlvmBlockId -> [LlvmStatement] -> LlvmBlock
LlvmBlock LlvmBlockId
id [LlvmStatement]
xs)
        [LlvmStatement]
_             -> SDoc
forall doc. IsOutput doc => doc
empty
  in LlvmBlockId -> SDoc
ppLlvmBlockLabel LlvmBlockId
blockId
           SDoc -> SDoc -> SDoc
$+$ ([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (LlvmStatement -> SDoc) -> [LlvmStatement] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> LlvmStatement -> SDoc
ppLlvmStatement LlvmCgConfig
opts) [LlvmStatement]
block)
           SDoc -> SDoc -> SDoc
$+$ SDoc
newLine
           SDoc -> SDoc -> SDoc
$+$ SDoc
ppRest

-- | Print out an LLVM block label.
ppLlvmBlockLabel :: LlvmBlockId -> SDoc
ppLlvmBlockLabel :: LlvmBlockId -> SDoc
ppLlvmBlockLabel LlvmBlockId
id = LlvmBlockId -> SDoc
forall doc. IsLine doc => LlvmBlockId -> doc
pprUniqueAlways LlvmBlockId
id SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
colon


-- | Print out an LLVM statement.
ppLlvmStatement :: LlvmCgConfig -> LlvmStatement -> SDoc
ppLlvmStatement :: LlvmCgConfig -> LlvmStatement -> SDoc
ppLlvmStatement LlvmCgConfig
opts LlvmStatement
stmt =
  let ind :: SDoc -> SDoc
ind = (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"  " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<>)
  in case LlvmStatement
stmt of
        Assignment  LlvmVar
dst LlvmExpression
expr      -> SDoc -> SDoc
ind (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ LlvmCgConfig -> LlvmVar -> SDoc -> SDoc
ppAssignment LlvmCgConfig
opts LlvmVar
dst (LlvmCgConfig -> LlvmExpression -> SDoc
ppLlvmExpression LlvmCgConfig
opts LlvmExpression
expr)
        Fence       Bool
st LlvmSyncOrdering
ord        -> SDoc -> SDoc
ind (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ Bool -> LlvmSyncOrdering -> SDoc
ppFence Bool
st LlvmSyncOrdering
ord
        Branch      LlvmVar
target        -> SDoc -> SDoc
ind (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ LlvmCgConfig -> LlvmVar -> SDoc
ppBranch LlvmCgConfig
opts LlvmVar
target
        BranchIf    LlvmVar
cond LlvmVar
ifT LlvmVar
ifF  -> SDoc -> SDoc
ind (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ LlvmCgConfig -> LlvmVar -> LlvmVar -> LlvmVar -> SDoc
ppBranchIf LlvmCgConfig
opts LlvmVar
cond LlvmVar
ifT LlvmVar
ifF
        Comment     [LMString]
comments      -> SDoc -> SDoc
ind (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ [LMString] -> SDoc
ppLlvmComments [LMString]
comments
        MkLabel     LlvmBlockId
label         -> LlvmBlockId -> SDoc
ppLlvmBlockLabel LlvmBlockId
label
        Store       LlvmVar
value LlvmVar
ptr LMAlign
align
                                  -> SDoc -> SDoc
ind (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ LlvmCgConfig -> LlvmVar -> LlvmVar -> LMAlign -> SDoc
ppStore LlvmCgConfig
opts LlvmVar
value LlvmVar
ptr LMAlign
align
        Switch      LlvmVar
scrut LlvmVar
def [(LlvmVar, LlvmVar)]
tgs -> SDoc -> SDoc
ind (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ LlvmCgConfig -> LlvmVar -> LlvmVar -> [(LlvmVar, LlvmVar)] -> SDoc
ppSwitch LlvmCgConfig
opts LlvmVar
scrut LlvmVar
def [(LlvmVar, LlvmVar)]
tgs
        Return      Maybe LlvmVar
result        -> SDoc -> SDoc
ind (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ LlvmCgConfig -> Maybe LlvmVar -> SDoc
ppReturn LlvmCgConfig
opts Maybe LlvmVar
result
        Expr        LlvmExpression
expr          -> SDoc -> SDoc
ind (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ LlvmCgConfig -> LlvmExpression -> SDoc
ppLlvmExpression LlvmCgConfig
opts LlvmExpression
expr
        LlvmStatement
Unreachable               -> SDoc -> SDoc
ind (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"unreachable"
        LlvmStatement
Nop                       -> SDoc
forall doc. IsOutput doc => doc
empty
        MetaStmt    [MetaAnnot]
meta LlvmStatement
s        -> LlvmCgConfig -> [MetaAnnot] -> LlvmStatement -> SDoc
ppMetaStatement LlvmCgConfig
opts [MetaAnnot]
meta LlvmStatement
s


-- | Print out an LLVM expression.
ppLlvmExpression :: LlvmCgConfig -> LlvmExpression -> SDoc
ppLlvmExpression :: LlvmCgConfig -> LlvmExpression -> SDoc
ppLlvmExpression LlvmCgConfig
opts LlvmExpression
expr
  = case LlvmExpression
expr of
        Alloca     LlvmType
tp Int
amount        -> LlvmCgConfig -> LlvmType -> Int -> SDoc
ppAlloca LlvmCgConfig
opts LlvmType
tp Int
amount
        LlvmOp     LlvmMachOp
op LlvmVar
left LlvmVar
right    -> LlvmCgConfig -> LlvmMachOp -> LlvmVar -> LlvmVar -> SDoc
ppMachOp LlvmCgConfig
opts LlvmMachOp
op LlvmVar
left LlvmVar
right
        Call       LlvmCallType
tp LlvmVar
fp [LlvmVar]
args [LlvmFuncAttr]
attrs -> LlvmCgConfig
-> LlvmCallType -> LlvmVar -> [MetaExpr] -> [LlvmFuncAttr] -> SDoc
ppCall LlvmCgConfig
opts LlvmCallType
tp LlvmVar
fp ((LlvmVar -> MetaExpr) -> [LlvmVar] -> [MetaExpr]
forall a b. (a -> b) -> [a] -> [b]
map LlvmVar -> MetaExpr
MetaVar [LlvmVar]
args) [LlvmFuncAttr]
attrs
        CallM      LlvmCallType
tp LlvmVar
fp [MetaExpr]
args [LlvmFuncAttr]
attrs -> LlvmCgConfig
-> LlvmCallType -> LlvmVar -> [MetaExpr] -> [LlvmFuncAttr] -> SDoc
ppCall LlvmCgConfig
opts LlvmCallType
tp LlvmVar
fp [MetaExpr]
args [LlvmFuncAttr]
attrs
        Cast       LlvmCastOp
op LlvmVar
from LlvmType
to       -> LlvmCgConfig -> LlvmCastOp -> LlvmVar -> LlvmType -> SDoc
ppCast LlvmCgConfig
opts LlvmCastOp
op LlvmVar
from LlvmType
to
        Compare    LlvmCmpOp
op LlvmVar
left LlvmVar
right    -> LlvmCgConfig -> LlvmCmpOp -> LlvmVar -> LlvmVar -> SDoc
ppCmpOp LlvmCgConfig
opts LlvmCmpOp
op LlvmVar
left LlvmVar
right
        Extract    LlvmVar
vec LlvmVar
idx          -> LlvmCgConfig -> LlvmVar -> LlvmVar -> SDoc
ppExtract LlvmCgConfig
opts LlvmVar
vec LlvmVar
idx
        ExtractV   LlvmVar
struct Int
idx       -> LlvmCgConfig -> LlvmVar -> Int -> SDoc
ppExtractV LlvmCgConfig
opts LlvmVar
struct Int
idx
        Insert     LlvmVar
vec LlvmVar
elt LlvmVar
idx      -> LlvmCgConfig -> LlvmVar -> LlvmVar -> LlvmVar -> SDoc
ppInsert LlvmCgConfig
opts LlvmVar
vec LlvmVar
elt LlvmVar
idx
        GetElemPtr Bool
inb LlvmVar
ptr [LlvmVar]
indexes  -> LlvmCgConfig -> Bool -> LlvmVar -> [LlvmVar] -> SDoc
ppGetElementPtr LlvmCgConfig
opts Bool
inb LlvmVar
ptr [LlvmVar]
indexes
        Load       LlvmVar
ptr LMAlign
align        -> LlvmCgConfig -> LlvmVar -> LMAlign -> SDoc
ppLoad LlvmCgConfig
opts LlvmVar
ptr LMAlign
align
        ALoad      LlvmSyncOrdering
ord Bool
st LlvmVar
ptr       -> LlvmCgConfig -> LlvmSyncOrdering -> Bool -> LlvmVar -> SDoc
ppALoad LlvmCgConfig
opts LlvmSyncOrdering
ord Bool
st LlvmVar
ptr
        Malloc     LlvmType
tp Int
amount        -> LlvmCgConfig -> LlvmType -> Int -> SDoc
ppMalloc LlvmCgConfig
opts LlvmType
tp Int
amount
        AtomicRMW  LlvmAtomicOp
aop LlvmVar
tgt LlvmVar
src LlvmSyncOrdering
ordering -> LlvmCgConfig
-> LlvmAtomicOp -> LlvmVar -> LlvmVar -> LlvmSyncOrdering -> SDoc
ppAtomicRMW LlvmCgConfig
opts LlvmAtomicOp
aop LlvmVar
tgt LlvmVar
src LlvmSyncOrdering
ordering
        CmpXChg    LlvmVar
addr LlvmVar
old LlvmVar
new LlvmSyncOrdering
s_ord LlvmSyncOrdering
f_ord -> LlvmCgConfig
-> LlvmVar
-> LlvmVar
-> LlvmVar
-> LlvmSyncOrdering
-> LlvmSyncOrdering
-> SDoc
ppCmpXChg LlvmCgConfig
opts LlvmVar
addr LlvmVar
old LlvmVar
new LlvmSyncOrdering
s_ord LlvmSyncOrdering
f_ord
        Phi        LlvmType
tp [(LlvmVar, LlvmVar)]
predecessors  -> LlvmCgConfig -> LlvmType -> [(LlvmVar, LlvmVar)] -> SDoc
ppPhi LlvmCgConfig
opts LlvmType
tp [(LlvmVar, LlvmVar)]
predecessors
        Asm        LMString
asm LMString
c LlvmType
ty [LlvmVar]
v Bool
se Bool
sk -> LlvmCgConfig
-> LMString
-> LMString
-> LlvmType
-> [LlvmVar]
-> Bool
-> Bool
-> SDoc
ppAsm LlvmCgConfig
opts LMString
asm LMString
c LlvmType
ty [LlvmVar]
v Bool
se Bool
sk
        MExpr      [MetaAnnot]
meta LlvmExpression
expr        -> LlvmCgConfig -> [MetaAnnot] -> LlvmExpression -> SDoc
ppMetaAnnotExpr LlvmCgConfig
opts [MetaAnnot]
meta LlvmExpression
expr

ppMetaExpr :: LlvmCgConfig -> MetaExpr -> SDoc
ppMetaExpr :: LlvmCgConfig -> MetaExpr -> SDoc
ppMetaExpr LlvmCgConfig
opts = \case
  MetaVar (LMLitVar (LMNullLit LlvmType
_)) -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"null"
  MetaStr    LMString
s                     -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'!' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
doubleQuotes (LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
s)
  MetaNode   MetaId
n                     -> MetaId -> SDoc
forall a. Outputable a => a -> SDoc
ppr MetaId
n
  MetaVar    LlvmVar
v                     -> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
v
  MetaStruct [MetaExpr]
es                    -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'!' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
braces ([SDoc] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppCommaJoin ((MetaExpr -> SDoc) -> [MetaExpr] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> MetaExpr -> SDoc
ppMetaExpr LlvmCgConfig
opts) [MetaExpr]
es))


--------------------------------------------------------------------------------
-- * Individual print functions
--------------------------------------------------------------------------------

-- | Should always be a function pointer. So a global var of function type
-- (since globals are always pointers) or a local var of pointer function type.
ppCall :: LlvmCgConfig -> LlvmCallType -> LlvmVar -> [MetaExpr] -> [LlvmFuncAttr] -> SDoc
ppCall :: LlvmCgConfig
-> LlvmCallType -> LlvmVar -> [MetaExpr] -> [LlvmFuncAttr] -> SDoc
ppCall LlvmCgConfig
opts LlvmCallType
ct LlvmVar
fptr [MetaExpr]
args [LlvmFuncAttr]
attrs = case LlvmVar
fptr of
                           --
    -- if local var function pointer, unwrap
    LMLocalVar LlvmBlockId
_ (LMPointer (LMFunction LlvmFunctionDecl
d)) -> LlvmFunctionDecl -> SDoc
ppCall' LlvmFunctionDecl
d

    -- should be function type otherwise
    LMGlobalVar LMString
_ (LMFunction LlvmFunctionDecl
d) LlvmLinkageType
_ LMSection
_ LMAlign
_ LMConst
_    -> LlvmFunctionDecl -> SDoc
ppCall' LlvmFunctionDecl
d

    -- not pointer or function, so error
    LlvmVar
_other -> String -> SDoc
forall a. HasCallStack => String -> a
error (String -> SDoc) -> String -> SDoc
forall a b. (a -> b) -> a -> b
$ String
"ppCall called with non LMFunction type!\nMust be "
                String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" called with either global var of function type or "
                String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"local var of pointer function type."

    where
        ppCall' :: LlvmFunctionDecl -> SDoc
ppCall' (LlvmFunctionDecl LMString
_ LlvmLinkageType
_ LlvmCallConvention
cc LlvmType
ret LlvmParameterListType
argTy [LlvmParameter]
params LMAlign
_) =
            let tc :: SDoc
tc = if LlvmCallType
ct LlvmCallType -> LlvmCallType -> Bool
forall a. Eq a => a -> a -> Bool
== LlvmCallType
TailCall then String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"tail " else SDoc
forall doc. IsOutput doc => doc
empty
                ppValues :: SDoc
ppValues = LlvmCgConfig -> [[LlvmParamAttr]] -> [MetaExpr] -> SDoc
ppCallParams LlvmCgConfig
opts ((LlvmParameter -> [LlvmParamAttr])
-> [LlvmParameter] -> [[LlvmParamAttr]]
forall a b. (a -> b) -> [a] -> [b]
map LlvmParameter -> [LlvmParamAttr]
forall a b. (a, b) -> b
snd [LlvmParameter]
params) [MetaExpr]
args
                ppArgTy :: SDoc
ppArgTy  = ([SDoc] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppCommaJoin ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (LlvmParameter -> SDoc) -> [LlvmParameter] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmType -> SDoc)
-> (LlvmParameter -> LlvmType) -> LlvmParameter -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LlvmParameter -> LlvmType
forall a b. (a, b) -> a
fst) [LlvmParameter]
params) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<>
                           (case LlvmParameterListType
argTy of
                               LlvmParameterListType
VarArgs   -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
", ..."
                               LlvmParameterListType
FixedArgs -> SDoc
forall doc. IsOutput doc => doc
empty)
                fnty :: SDoc
fnty = SDoc
forall doc. IsLine doc => doc
space SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
lparen SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
ppArgTy SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
rparen
                attrDoc :: SDoc
attrDoc = [LlvmFuncAttr] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppSpaceJoin [LlvmFuncAttr]
attrs
            in  SDoc
tc SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"call" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCallConvention -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmCallConvention
cc SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
ret
                    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
fnty SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
fptr SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
lparen SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
ppValues
                    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
forall doc. IsLine doc => doc
rparen SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
attrDoc

        ppCallParams :: LlvmCgConfig -> [[LlvmParamAttr]] -> [MetaExpr] -> SDoc
        ppCallParams :: LlvmCgConfig -> [[LlvmParamAttr]] -> [MetaExpr] -> SDoc
ppCallParams LlvmCgConfig
opts [[LlvmParamAttr]]
attrs [MetaExpr]
args = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ SDoc -> [SDoc] -> [SDoc]
forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate SDoc
forall doc. IsLine doc => doc
comma ([SDoc] -> [SDoc]) -> [SDoc] -> [SDoc]
forall a b. (a -> b) -> a -> b
$ ([LlvmParamAttr] -> MetaExpr -> SDoc)
-> [[LlvmParamAttr]] -> [MetaExpr] -> [SDoc]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith [LlvmParamAttr] -> MetaExpr -> SDoc
ppCallMetaExpr [[LlvmParamAttr]]
attrs [MetaExpr]
args
         where
          -- Metadata needs to be marked as having the `metadata` type when used
          -- in a call argument
          ppCallMetaExpr :: [LlvmParamAttr] -> MetaExpr -> SDoc
ppCallMetaExpr [LlvmParamAttr]
attrs (MetaVar LlvmVar
v) = [LlvmParamAttr] -> LlvmCgConfig -> LlvmVar -> SDoc
ppVar' [LlvmParamAttr]
attrs LlvmCgConfig
opts LlvmVar
v
          ppCallMetaExpr [LlvmParamAttr]
_ MetaExpr
v             = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"metadata" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> MetaExpr -> SDoc
ppMetaExpr LlvmCgConfig
opts MetaExpr
v


ppMachOp :: LlvmCgConfig -> LlvmMachOp -> LlvmVar -> LlvmVar -> SDoc
ppMachOp :: LlvmCgConfig -> LlvmMachOp -> LlvmVar -> LlvmVar -> SDoc
ppMachOp LlvmCgConfig
opts LlvmMachOp
op LlvmVar
left LlvmVar
right =
  (LlvmMachOp -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmMachOp
op) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> (LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmVar -> LlvmType
getVarType LlvmVar
left)) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
left
        SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
right


ppCmpOp :: LlvmCgConfig -> LlvmCmpOp -> LlvmVar -> LlvmVar -> SDoc
ppCmpOp :: LlvmCgConfig -> LlvmCmpOp -> LlvmVar -> LlvmVar -> SDoc
ppCmpOp LlvmCgConfig
opts LlvmCmpOp
op LlvmVar
left LlvmVar
right =
  let cmpOp :: SDoc
cmpOp
        | LlvmType -> Bool
isInt (LlvmVar -> LlvmType
getVarType LlvmVar
left) Bool -> Bool -> Bool
&& LlvmType -> Bool
isInt (LlvmVar -> LlvmType
getVarType LlvmVar
right) = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"icmp"
        | LlvmType -> Bool
isFloat (LlvmVar -> LlvmType
getVarType LlvmVar
left) Bool -> Bool -> Bool
&& LlvmType -> Bool
isFloat (LlvmVar -> LlvmType
getVarType LlvmVar
right) = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"fcmp"
        | Bool
otherwise = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"icmp" -- Just continue as its much easier to debug
        {-
        | otherwise = error ("can't compare different types, left = "
                ++ (show $ getVarType left) ++ ", right = "
                ++ (show $ getVarType right))
        -}
  in SDoc
cmpOp SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCmpOp -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmCmpOp
op SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmVar -> LlvmType
getVarType LlvmVar
left)
        SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
left SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
right


ppAssignment :: LlvmCgConfig -> LlvmVar -> SDoc -> SDoc
ppAssignment :: LlvmCgConfig -> LlvmVar -> SDoc -> SDoc
ppAssignment LlvmCgConfig
opts LlvmVar
var SDoc
expr = LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
var SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
forall doc. IsLine doc => doc
equals SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
expr

ppFence :: Bool -> LlvmSyncOrdering -> SDoc
ppFence :: Bool -> LlvmSyncOrdering -> SDoc
ppFence Bool
st LlvmSyncOrdering
ord =
  let singleThread :: SDoc
singleThread = case Bool
st of Bool
True  -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"singlethread"
                                Bool
False -> SDoc
forall doc. IsOutput doc => doc
empty
  in String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"fence" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
singleThread SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmSyncOrdering -> SDoc
ppSyncOrdering LlvmSyncOrdering
ord

ppSyncOrdering :: LlvmSyncOrdering -> SDoc
ppSyncOrdering :: LlvmSyncOrdering -> SDoc
ppSyncOrdering LlvmSyncOrdering
SyncUnord     = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"unordered"
ppSyncOrdering LlvmSyncOrdering
SyncMonotonic = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"monotonic"
ppSyncOrdering LlvmSyncOrdering
SyncAcquire   = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"acquire"
ppSyncOrdering LlvmSyncOrdering
SyncRelease   = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"release"
ppSyncOrdering LlvmSyncOrdering
SyncAcqRel    = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"acq_rel"
ppSyncOrdering LlvmSyncOrdering
SyncSeqCst    = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"seq_cst"

ppAtomicOp :: LlvmAtomicOp -> SDoc
ppAtomicOp :: LlvmAtomicOp -> SDoc
ppAtomicOp LlvmAtomicOp
LAO_Xchg = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"xchg"
ppAtomicOp LlvmAtomicOp
LAO_Add  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"add"
ppAtomicOp LlvmAtomicOp
LAO_Sub  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"sub"
ppAtomicOp LlvmAtomicOp
LAO_And  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"and"
ppAtomicOp LlvmAtomicOp
LAO_Nand = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"nand"
ppAtomicOp LlvmAtomicOp
LAO_Or   = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"or"
ppAtomicOp LlvmAtomicOp
LAO_Xor  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"xor"
ppAtomicOp LlvmAtomicOp
LAO_Max  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"max"
ppAtomicOp LlvmAtomicOp
LAO_Min  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"min"
ppAtomicOp LlvmAtomicOp
LAO_Umax = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"umax"
ppAtomicOp LlvmAtomicOp
LAO_Umin = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"umin"

ppAtomicRMW :: LlvmCgConfig -> LlvmAtomicOp -> LlvmVar -> LlvmVar -> LlvmSyncOrdering -> SDoc
ppAtomicRMW :: LlvmCgConfig
-> LlvmAtomicOp -> LlvmVar -> LlvmVar -> LlvmSyncOrdering -> SDoc
ppAtomicRMW LlvmCgConfig
opts LlvmAtomicOp
aop LlvmVar
tgt LlvmVar
src LlvmSyncOrdering
ordering =
  String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"atomicrmw" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmAtomicOp -> SDoc
ppAtomicOp LlvmAtomicOp
aop SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
tgt SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma
  SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
src SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmSyncOrdering -> SDoc
ppSyncOrdering LlvmSyncOrdering
ordering

ppCmpXChg :: LlvmCgConfig -> LlvmVar -> LlvmVar -> LlvmVar
          -> LlvmSyncOrdering -> LlvmSyncOrdering -> SDoc
ppCmpXChg :: LlvmCgConfig
-> LlvmVar
-> LlvmVar
-> LlvmVar
-> LlvmSyncOrdering
-> LlvmSyncOrdering
-> SDoc
ppCmpXChg LlvmCgConfig
opts LlvmVar
addr LlvmVar
old LlvmVar
new LlvmSyncOrdering
s_ord LlvmSyncOrdering
f_ord =
  String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"cmpxchg" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
addr SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
old SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
new
  SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmSyncOrdering -> SDoc
ppSyncOrdering LlvmSyncOrdering
s_ord SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmSyncOrdering -> SDoc
ppSyncOrdering LlvmSyncOrdering
f_ord


ppLoad :: LlvmCgConfig -> LlvmVar -> LMAlign -> SDoc
ppLoad :: LlvmCgConfig -> LlvmVar -> LMAlign -> SDoc
ppLoad LlvmCgConfig
opts LlvmVar
var LMAlign
alignment =
  String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"load" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
derefType SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
var SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
align
  where
    derefType :: LlvmType
derefType = LlvmType -> LlvmType
pLower (LlvmType -> LlvmType) -> LlvmType -> LlvmType
forall a b. (a -> b) -> a -> b
$ LlvmVar -> LlvmType
getVarType LlvmVar
var
    align :: SDoc
align =
      case LMAlign
alignment of
        Just Int
n  -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
", align" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
n
        LMAlign
Nothing -> SDoc
forall doc. IsOutput doc => doc
empty

ppALoad :: LlvmCgConfig -> LlvmSyncOrdering -> SingleThreaded -> LlvmVar -> SDoc
ppALoad :: LlvmCgConfig -> LlvmSyncOrdering -> Bool -> LlvmVar -> SDoc
ppALoad LlvmCgConfig
opts LlvmSyncOrdering
ord Bool
st LlvmVar
var =
  let alignment :: Int
alignment = Platform -> LlvmType -> Int
llvmWidthInBits (LlvmCgConfig -> Platform
llvmCgPlatform LlvmCgConfig
opts) (LlvmVar -> LlvmType
getVarType LlvmVar
var) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`quot` Int
8
      align :: SDoc
align     = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
", align" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
alignment
      sThreaded :: SDoc
sThreaded | Bool
st        = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" singlethread"
                | Bool
otherwise = SDoc
forall doc. IsOutput doc => doc
empty
      derefType :: LlvmType
derefType = LlvmType -> LlvmType
pLower (LlvmType -> LlvmType) -> LlvmType -> LlvmType
forall a b. (a -> b) -> a -> b
$ LlvmVar -> LlvmType
getVarType LlvmVar
var
  in String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"load atomic" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
derefType SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
var SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
sThreaded
            SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmSyncOrdering -> SDoc
ppSyncOrdering LlvmSyncOrdering
ord SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
align

ppStore :: LlvmCgConfig -> LlvmVar -> LlvmVar -> LMAlign -> SDoc
ppStore :: LlvmCgConfig -> LlvmVar -> LlvmVar -> LMAlign -> SDoc
ppStore LlvmCgConfig
opts LlvmVar
val LlvmVar
dst LMAlign
alignment =
    String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"store" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
val SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
dst SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
align
  where
    align :: SDoc
align =
      case LMAlign
alignment of
        Just Int
n  -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
", align" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
n
        LMAlign
Nothing -> SDoc
forall doc. IsOutput doc => doc
empty


ppCast :: LlvmCgConfig -> LlvmCastOp -> LlvmVar -> LlvmType -> SDoc
ppCast :: LlvmCgConfig -> LlvmCastOp -> LlvmVar -> LlvmType -> SDoc
ppCast LlvmCgConfig
opts LlvmCastOp
op LlvmVar
from LlvmType
to
    =   LlvmCastOp -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmCastOp
op
    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmVar -> LlvmType
getVarType LlvmVar
from) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
from
    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"to"
    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
to


ppMalloc :: LlvmCgConfig -> LlvmType -> Int -> SDoc
ppMalloc :: LlvmCgConfig -> LlvmType -> Int -> SDoc
ppMalloc LlvmCgConfig
opts LlvmType
tp Int
amount =
  let amount' :: LlvmVar
amount' = LlvmLit -> LlvmVar
LMLitVar (LlvmLit -> LlvmVar) -> LlvmLit -> LlvmVar
forall a b. (a -> b) -> a -> b
$ Integer -> LlvmType -> LlvmLit
LMIntLit (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
amount) LlvmType
i32
  in String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"malloc" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
tp SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
amount'


ppAlloca :: LlvmCgConfig -> LlvmType -> Int -> SDoc
ppAlloca :: LlvmCgConfig -> LlvmType -> Int -> SDoc
ppAlloca LlvmCgConfig
opts LlvmType
tp Int
amount =
  let amount' :: LlvmVar
amount' = LlvmLit -> LlvmVar
LMLitVar (LlvmLit -> LlvmVar) -> LlvmLit -> LlvmVar
forall a b. (a -> b) -> a -> b
$ Integer -> LlvmType -> LlvmLit
LMIntLit (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
amount) LlvmType
i32
  in String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"alloca" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
tp SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
amount'


ppGetElementPtr :: LlvmCgConfig -> Bool -> LlvmVar -> [LlvmVar] -> SDoc
ppGetElementPtr :: LlvmCgConfig -> Bool -> LlvmVar -> [LlvmVar] -> SDoc
ppGetElementPtr LlvmCgConfig
opts Bool
inb LlvmVar
ptr [LlvmVar]
idx =
  let indexes :: SDoc
indexes = SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppCommaJoin ((LlvmVar -> SDoc) -> [LlvmVar] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts) [LlvmVar]
idx)
      inbound :: SDoc
inbound = if Bool
inb then String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"inbounds" else SDoc
forall doc. IsOutput doc => doc
empty
      derefType :: LlvmType
derefType = LlvmType -> LlvmType
pLower (LlvmType -> LlvmType) -> LlvmType -> LlvmType
forall a b. (a -> b) -> a -> b
$ LlvmVar -> LlvmType
getVarType LlvmVar
ptr
  in String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"getelementptr" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
inbound SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
derefType SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
ptr
                            SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
indexes


ppReturn :: LlvmCgConfig -> Maybe LlvmVar -> SDoc
ppReturn :: LlvmCgConfig -> Maybe LlvmVar -> SDoc
ppReturn LlvmCgConfig
opts (Just LlvmVar
var) = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"ret" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
var
ppReturn LlvmCgConfig
_    Maybe LlvmVar
Nothing    = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"ret" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
LMVoid


ppBranch :: LlvmCgConfig -> LlvmVar -> SDoc
ppBranch :: LlvmCgConfig -> LlvmVar -> SDoc
ppBranch LlvmCgConfig
opts LlvmVar
var = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"br" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
var


ppBranchIf :: LlvmCgConfig -> LlvmVar -> LlvmVar -> LlvmVar -> SDoc
ppBranchIf :: LlvmCgConfig -> LlvmVar -> LlvmVar -> LlvmVar -> SDoc
ppBranchIf LlvmCgConfig
opts LlvmVar
cond LlvmVar
trueT LlvmVar
falseT
  = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"br" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
cond SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
trueT SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
falseT


ppPhi :: LlvmCgConfig -> LlvmType -> [(LlvmVar,LlvmVar)] -> SDoc
ppPhi :: LlvmCgConfig -> LlvmType -> [(LlvmVar, LlvmVar)] -> SDoc
ppPhi LlvmCgConfig
opts LlvmType
tp [(LlvmVar, LlvmVar)]
preds =
  let ppPreds :: (LlvmVar, LlvmVar) -> SDoc
ppPreds (LlvmVar
val, LlvmVar
label) = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
brackets (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
val SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
label
  in String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"phi" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
tp SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hsep (SDoc -> [SDoc] -> [SDoc]
forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate SDoc
forall doc. IsLine doc => doc
comma ([SDoc] -> [SDoc]) -> [SDoc] -> [SDoc]
forall a b. (a -> b) -> a -> b
$ ((LlvmVar, LlvmVar) -> SDoc) -> [(LlvmVar, LlvmVar)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmVar, LlvmVar) -> SDoc
ppPreds [(LlvmVar, LlvmVar)]
preds)


ppSwitch :: LlvmCgConfig -> LlvmVar -> LlvmVar -> [(LlvmVar,LlvmVar)] -> SDoc
ppSwitch :: LlvmCgConfig -> LlvmVar -> LlvmVar -> [(LlvmVar, LlvmVar)] -> SDoc
ppSwitch LlvmCgConfig
opts LlvmVar
scrut LlvmVar
dflt [(LlvmVar, LlvmVar)]
targets =
  let ppTarget :: (LlvmVar, LlvmVar) -> SDoc
ppTarget  (LlvmVar
val, LlvmVar
lab) = LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
val SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
lab
      ppTargets :: [(LlvmVar, LlvmVar)] -> SDoc
ppTargets  [(LlvmVar, LlvmVar)]
xs        = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
brackets (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat (((LlvmVar, LlvmVar) -> SDoc) -> [(LlvmVar, LlvmVar)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmVar, LlvmVar) -> SDoc
ppTarget [(LlvmVar, LlvmVar)]
xs)
  in String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"switch" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
scrut SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
dflt
        SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [(LlvmVar, LlvmVar)] -> SDoc
ppTargets [(LlvmVar, LlvmVar)]
targets


ppAsm :: LlvmCgConfig -> LMString -> LMString -> LlvmType -> [LlvmVar] -> Bool -> Bool -> SDoc
ppAsm :: LlvmCgConfig
-> LMString
-> LMString
-> LlvmType
-> [LlvmVar]
-> Bool
-> Bool
-> SDoc
ppAsm LlvmCgConfig
opts LMString
asm LMString
constraints LlvmType
rty [LlvmVar]
vars Bool
sideeffect Bool
alignstack =
  let asm' :: SDoc
asm'  = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
doubleQuotes (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
asm
      cons :: SDoc
cons  = SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
doubleQuotes (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
constraints
      rty' :: SDoc
rty'  = LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
rty
      vars' :: SDoc
vars' = SDoc
forall doc. IsLine doc => doc
lparen SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppCommaJoin ((LlvmVar -> SDoc) -> [LlvmVar] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts) [LlvmVar]
vars) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
forall doc. IsLine doc => doc
rparen
      side :: SDoc
side  = if Bool
sideeffect then String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"sideeffect" else SDoc
forall doc. IsOutput doc => doc
empty
      align :: SDoc
align = if Bool
alignstack then String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"alignstack" else SDoc
forall doc. IsOutput doc => doc
empty
  in String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"call" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
rty' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"asm" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
side SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
align SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
asm' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma
        SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
cons SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
vars'

ppExtract :: LlvmCgConfig -> LlvmVar -> LlvmVar -> SDoc
ppExtract :: LlvmCgConfig -> LlvmVar -> LlvmVar -> SDoc
ppExtract LlvmCgConfig
opts LlvmVar
vec LlvmVar
idx =
    String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"extractelement"
    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmVar -> LlvmType
getVarType LlvmVar
vec) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
vec SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma
    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
idx

ppExtractV :: LlvmCgConfig -> LlvmVar -> Int -> SDoc
ppExtractV :: LlvmCgConfig -> LlvmVar -> Int -> SDoc
ppExtractV LlvmCgConfig
opts LlvmVar
struct Int
idx =
    String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"extractvalue"
    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmVar -> LlvmType
getVarType LlvmVar
struct) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
struct SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma
    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
idx

ppInsert :: LlvmCgConfig -> LlvmVar -> LlvmVar -> LlvmVar -> SDoc
ppInsert :: LlvmCgConfig -> LlvmVar -> LlvmVar -> LlvmVar -> SDoc
ppInsert LlvmCgConfig
opts LlvmVar
vec LlvmVar
elt LlvmVar
idx =
    String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"insertelement"
    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmVar -> LlvmType
getVarType LlvmVar
vec) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
vec SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma
    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmVar -> LlvmType
getVarType LlvmVar
elt) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
elt SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma
    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
idx


ppMetaStatement :: LlvmCgConfig -> [MetaAnnot] -> LlvmStatement -> SDoc
ppMetaStatement :: LlvmCgConfig -> [MetaAnnot] -> LlvmStatement -> SDoc
ppMetaStatement LlvmCgConfig
opts [MetaAnnot]
meta LlvmStatement
stmt =
   LlvmCgConfig -> LlvmStatement -> SDoc
ppLlvmStatement LlvmCgConfig
opts LlvmStatement
stmt SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> [MetaAnnot] -> SDoc
ppMetaAnnots LlvmCgConfig
opts [MetaAnnot]
meta

ppMetaAnnotExpr :: LlvmCgConfig -> [MetaAnnot] -> LlvmExpression -> SDoc
ppMetaAnnotExpr :: LlvmCgConfig -> [MetaAnnot] -> LlvmExpression -> SDoc
ppMetaAnnotExpr LlvmCgConfig
opts [MetaAnnot]
meta LlvmExpression
expr =
   LlvmCgConfig -> LlvmExpression -> SDoc
ppLlvmExpression LlvmCgConfig
opts LlvmExpression
expr SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> [MetaAnnot] -> SDoc
ppMetaAnnots LlvmCgConfig
opts [MetaAnnot]
meta

ppMetaAnnots :: LlvmCgConfig -> [MetaAnnot] -> SDoc
ppMetaAnnots :: LlvmCgConfig -> [MetaAnnot] -> SDoc
ppMetaAnnots LlvmCgConfig
opts [MetaAnnot]
meta = [SDoc] -> SDoc
forall doc. IsLine doc => [doc] -> doc
hcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (MetaAnnot -> SDoc) -> [MetaAnnot] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map MetaAnnot -> SDoc
ppMeta [MetaAnnot]
meta
  where
    ppMeta :: MetaAnnot -> SDoc
ppMeta (MetaAnnot LMString
name MetaExpr
e)
        = SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
exclamation SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
name SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+>
          case MetaExpr
e of
            MetaNode MetaId
n    -> MetaId -> SDoc
forall a. Outputable a => a -> SDoc
ppr MetaId
n
            MetaStruct [MetaExpr]
ms -> SDoc
exclamation SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
braces ([SDoc] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppCommaJoin ((MetaExpr -> SDoc) -> [MetaExpr] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> MetaExpr -> SDoc
ppMetaExpr LlvmCgConfig
opts) [MetaExpr]
ms))
            MetaExpr
other         -> SDoc
exclamation SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
braces (LlvmCgConfig -> MetaExpr -> SDoc
ppMetaExpr LlvmCgConfig
opts MetaExpr
other) -- possible?

-- | Return the variable name or value of the 'LlvmVar'
-- in Llvm IR textual representation (e.g. @\@x@, @%y@ or @42@).
ppName :: LlvmCgConfig -> LlvmVar -> SDoc
ppName :: LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
v = case LlvmVar
v of
   LMGlobalVar {} -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'@' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmVar -> SDoc
ppPlainName LlvmCgConfig
opts LlvmVar
v
   LMLocalVar  {} -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'%' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmVar -> SDoc
ppPlainName LlvmCgConfig
opts LlvmVar
v
   LMNLocalVar {} -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'%' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmVar -> SDoc
ppPlainName LlvmCgConfig
opts LlvmVar
v
   LMLitVar    {} ->             LlvmCgConfig -> LlvmVar -> SDoc
ppPlainName LlvmCgConfig
opts LlvmVar
v

-- | Return the variable name or value of the 'LlvmVar'
-- in a plain textual representation (e.g. @x@, @y@ or @42@).
ppPlainName :: LlvmCgConfig -> LlvmVar -> SDoc
ppPlainName :: LlvmCgConfig -> LlvmVar -> SDoc
ppPlainName LlvmCgConfig
opts LlvmVar
v = case LlvmVar
v of
   (LMGlobalVar LMString
x LlvmType
_ LlvmLinkageType
_ LMSection
_ LMAlign
_ LMConst
_) -> LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
x
   (LMLocalVar  LlvmBlockId
x LlvmType
LMLabel  ) -> LlvmBlockId -> SDoc
forall doc. IsLine doc => LlvmBlockId -> doc
pprUniqueAlways LlvmBlockId
x
   (LMLocalVar  LlvmBlockId
x LlvmType
_        ) -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'l' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmBlockId -> SDoc
forall doc. IsLine doc => LlvmBlockId -> doc
pprUniqueAlways LlvmBlockId
x
   (LMNLocalVar LMString
x LlvmType
_        ) -> LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
x
   (LMLitVar    LlvmLit
x          ) -> LlvmCgConfig -> LlvmLit -> SDoc
ppLit LlvmCgConfig
opts LlvmLit
x

-- | Print a literal value. No type.
ppLit :: LlvmCgConfig -> LlvmLit -> SDoc
ppLit :: LlvmCgConfig -> LlvmLit -> SDoc
ppLit LlvmCgConfig
opts LlvmLit
l = case LlvmLit
l of
   (LMIntLit Integer
i (LMInt Int
32))  -> Int32 -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Integer -> Int32
forall a. Num a => Integer -> a
fromInteger Integer
i :: Int32)
   (LMIntLit Integer
i (LMInt Int
64))  -> Int64 -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Integer -> Int64
forall a. Num a => Integer -> a
fromInteger Integer
i :: Int64)
   (LMIntLit   Integer
i LlvmType
_       )  -> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
i)::Int)
   (LMFloatLit Double
r LlvmType
LMFloat )  -> Platform -> Float -> SDoc
ppFloat (LlvmCgConfig -> Platform
llvmCgPlatform LlvmCgConfig
opts) (Float -> SDoc) -> Float -> SDoc
forall a b. (a -> b) -> a -> b
$ Double -> Float
narrowFp Double
r
   (LMFloatLit Double
r LlvmType
LMDouble)  -> Platform -> Double -> SDoc
ppDouble (LlvmCgConfig -> Platform
llvmCgPlatform LlvmCgConfig
opts) Double
r
   f :: LlvmLit
f@(LMFloatLit Double
_ LlvmType
_)       -> String -> SDoc -> SDoc
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"ppLit" (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Can't print this float literal: " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmLit -> SDoc
ppTypeLit LlvmCgConfig
opts LlvmLit
f)
   (LMVectorLit [LlvmLit]
ls  )       -> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'<' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [SDoc] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppCommaJoin ((LlvmLit -> SDoc) -> [LlvmLit] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> LlvmLit -> SDoc
ppTypeLit LlvmCgConfig
opts) [LlvmLit]
ls) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'>'
   (LMNullLit LlvmType
_     )       -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"null"
   -- #11487 was an issue where we passed undef for some arguments
   -- that were actually live. By chance the registers holding those
   -- arguments usually happened to have the right values anyways, but
   -- that was not guaranteed. To find such bugs reliably, we set the
   -- flag below when validating, which replaces undef literals (at
   -- common types) with values that are likely to cause a crash or test
   -- failure.
   (LMUndefLit LlvmType
t    )
      | LlvmCgConfig -> Bool
llvmCgFillUndefWithGarbage LlvmCgConfig
opts
      , Just LlvmLit
lit <- LlvmType -> Maybe LlvmLit
garbageLit LlvmType
t   -> LlvmCgConfig -> LlvmLit -> SDoc
ppLit LlvmCgConfig
opts LlvmLit
lit
      | Bool
otherwise                  -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"undef"

ppVar :: LlvmCgConfig -> LlvmVar -> SDoc
ppVar :: LlvmCgConfig -> LlvmVar -> SDoc
ppVar = [LlvmParamAttr] -> LlvmCgConfig -> LlvmVar -> SDoc
ppVar' []

ppVar' :: [LlvmParamAttr] -> LlvmCgConfig -> LlvmVar -> SDoc
ppVar' :: [LlvmParamAttr] -> LlvmCgConfig -> LlvmVar -> SDoc
ppVar' [LlvmParamAttr]
attrs LlvmCgConfig
opts LlvmVar
v = case LlvmVar
v of
  LMLitVar LlvmLit
x -> [LlvmParamAttr] -> LlvmCgConfig -> LlvmLit -> SDoc
ppTypeLit' [LlvmParamAttr]
attrs LlvmCgConfig
opts LlvmLit
x
  LlvmVar
x          -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmVar -> LlvmType
getVarType LlvmVar
x) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [LlvmParamAttr] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppSpaceJoin [LlvmParamAttr]
attrs SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmVar -> SDoc
ppName LlvmCgConfig
opts LlvmVar
x

ppTypeLit :: LlvmCgConfig -> LlvmLit -> SDoc
ppTypeLit :: LlvmCgConfig -> LlvmLit -> SDoc
ppTypeLit = [LlvmParamAttr] -> LlvmCgConfig -> LlvmLit -> SDoc
ppTypeLit' []

ppTypeLit' :: [LlvmParamAttr] -> LlvmCgConfig -> LlvmLit -> SDoc
ppTypeLit' :: [LlvmParamAttr] -> LlvmCgConfig -> LlvmLit -> SDoc
ppTypeLit' [LlvmParamAttr]
attrs LlvmCgConfig
opts LlvmLit
l = case LlvmLit
l of
  LMVectorLit {} -> LlvmCgConfig -> LlvmLit -> SDoc
ppLit LlvmCgConfig
opts LlvmLit
l
  LlvmLit
_              -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmLit -> LlvmType
getLitType LlvmLit
l) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [LlvmParamAttr] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppSpaceJoin [LlvmParamAttr]
attrs SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmLit -> SDoc
ppLit LlvmCgConfig
opts LlvmLit
l

ppStatic :: LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic :: LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts LlvmStatic
st = case LlvmStatic
st of
  LMComment       LMString
s -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"; " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
s
  LMStaticLit   LlvmLit
l   -> LlvmCgConfig -> LlvmLit -> SDoc
ppTypeLit LlvmCgConfig
opts LlvmLit
l
  LMUninitType    LlvmType
t -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" undef"
  LMStaticStr   LMString
s LlvmType
t -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" c\"" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LMString -> SDoc
forall doc. IsLine doc => LMString -> doc
ftext LMString
s SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"\\00\""
  LMStaticArray [LlvmStatic]
d LlvmType
t -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" [" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> [SDoc] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppCommaJoin ((LlvmStatic -> SDoc) -> [LlvmStatic] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts) [LlvmStatic]
d) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
']'
  LMStaticStruc [LlvmStatic]
d LlvmType
t -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"<{" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> [SDoc] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppCommaJoin ((LlvmStatic -> SDoc) -> [LlvmStatic] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts) [LlvmStatic]
d) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"}>"
  LMStaticStrucU [LlvmStatic]
d LlvmType
t -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"{" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> [SDoc] -> SDoc
forall a. Outputable a => [a] -> SDoc
ppCommaJoin ((LlvmStatic -> SDoc) -> [LlvmStatic] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts) [LlvmStatic]
d) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"}"
  LMStaticPointer LlvmVar
v -> LlvmCgConfig -> LlvmVar -> SDoc
ppVar LlvmCgConfig
opts LlvmVar
v
  LMTrunc LlvmStatic
v LlvmType
t       -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" trunc (" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts LlvmStatic
v SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" to " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
')'
  LMBitc LlvmStatic
v LlvmType
t        -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" bitcast (" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts LlvmStatic
v SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" to " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
')'
  LMPtoI LlvmStatic
v LlvmType
t        -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" ptrtoint (" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts LlvmStatic
v SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" to " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
')'
  LMAdd LlvmStatic
s1 LlvmStatic
s2       -> LlvmCgConfig
-> LlvmStatic -> LlvmStatic -> SDoc -> SDoc -> SDoc -> SDoc
pprStaticArith LlvmCgConfig
opts LlvmStatic
s1 LlvmStatic
s2 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"add") (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"fadd") (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"LMAdd")
  LMSub LlvmStatic
s1 LlvmStatic
s2       -> LlvmCgConfig
-> LlvmStatic -> LlvmStatic -> SDoc -> SDoc -> SDoc -> SDoc
pprStaticArith LlvmCgConfig
opts LlvmStatic
s1 LlvmStatic
s2 (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"sub") (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"fsub") (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"LMSub")


pprSpecialStatic :: LlvmCgConfig -> LlvmStatic -> SDoc
pprSpecialStatic :: LlvmCgConfig -> LlvmStatic -> SDoc
pprSpecialStatic LlvmCgConfig
opts LlvmStatic
stat = case LlvmStatic
stat of
   LMBitc LlvmStatic
v LlvmType
t        -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmType -> LlvmType
pLower LlvmType
t)
                        SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
", bitcast ("
                        SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts LlvmStatic
v SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" to " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
t
                        SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
')'
   LMStaticPointer LlvmVar
x -> LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr (LlvmType -> LlvmType
pLower (LlvmType -> LlvmType) -> LlvmType -> LlvmType
forall a b. (a -> b) -> a -> b
$ LlvmVar -> LlvmType
getVarType LlvmVar
x)
                        SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts LlvmStatic
stat
   LlvmStatic
_                 -> LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts LlvmStatic
stat


pprStaticArith :: LlvmCgConfig -> LlvmStatic -> LlvmStatic -> SDoc -> SDoc
                  -> SDoc -> SDoc
pprStaticArith :: LlvmCgConfig
-> LlvmStatic -> LlvmStatic -> SDoc -> SDoc -> SDoc -> SDoc
pprStaticArith LlvmCgConfig
opts LlvmStatic
s1 LlvmStatic
s2 SDoc
int_op SDoc
float_op SDoc
op_name =
  let ty1 :: LlvmType
ty1 = LlvmStatic -> LlvmType
getStatType LlvmStatic
s1
      op :: SDoc
op  = if LlvmType -> Bool
isFloat LlvmType
ty1 then SDoc
float_op else SDoc
int_op
  in if LlvmType
ty1 LlvmType -> LlvmType -> Bool
forall a. Eq a => a -> a -> Bool
== LlvmStatic -> LlvmType
getStatType LlvmStatic
s2
     then LlvmType -> SDoc
forall a. Outputable a => a -> SDoc
ppr LlvmType
ty1 SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
op SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc
forall doc. IsLine doc => doc
lparen SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts LlvmStatic
s1 SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
comma SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts LlvmStatic
s2 SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
rparen
     else String -> SDoc -> SDoc
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"pprStaticArith" (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
                 SDoc
op_name SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" with different types! s1: " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts LlvmStatic
s1
                         SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
textString
", s2: " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LlvmCgConfig -> LlvmStatic -> SDoc
ppStatic LlvmCgConfig
opts LlvmStatic
s2


--------------------------------------------------------------------------------
-- * Misc functions
--------------------------------------------------------------------------------

-- | Blank line.
newLine :: SDoc
newLine :: SDoc
newLine = SDoc
forall doc. IsOutput doc => doc
empty

-- | Exclamation point.
exclamation :: SDoc
exclamation :: SDoc
exclamation = Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'!'