{-# LANGUAGE FlexibleContexts #-}

module LLVM.IRBuilder.Instruction where

import Prelude hiding (and, or, pred)

import Data.Word
import Data.Char (ord)
import GHC.Int
import GHC.Stack

import LLVM.AST hiding (args, dests)
import LLVM.AST.Type as AST
import LLVM.AST.Typed
import LLVM.AST.ParameterAttribute
import qualified LLVM.AST as AST
import qualified LLVM.AST.CallingConvention as CC
import qualified LLVM.AST.Constant as C
import qualified LLVM.AST.IntegerPredicate as IP
import qualified LLVM.AST.FloatingPointPredicate as FP

import LLVM.AST.Global
import LLVM.AST.Linkage

import LLVM.IRBuilder.Monad
import LLVM.IRBuilder.Module

-- | See <https://llvm.org/docs/LangRef.html#fneg-instruction reference>.
fneg :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> m Operand
fneg :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> m Operand
fneg Operand
a = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ FastMathFlags -> Operand -> InstructionMetadata -> Instruction
FNeg FastMathFlags
noFastMathFlags Operand
a []

-- | See <https://llvm.org/docs/LangRef.html#fadd-instruction reference>.
fadd :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
fadd :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
fadd Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ FastMathFlags
-> Operand -> Operand -> InstructionMetadata -> Instruction
FAdd FastMathFlags
noFastMathFlags Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#fmul-instruction reference>.
fmul :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
fmul :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
fmul Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ FastMathFlags
-> Operand -> Operand -> InstructionMetadata -> Instruction
FMul FastMathFlags
noFastMathFlags Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#fsub-instruction reference>.
fsub :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
fsub :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
fsub Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ FastMathFlags
-> Operand -> Operand -> InstructionMetadata -> Instruction
FSub FastMathFlags
noFastMathFlags Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#fdiv-instruction reference>.
fdiv :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
fdiv :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
fdiv Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ FastMathFlags
-> Operand -> Operand -> InstructionMetadata -> Instruction
FDiv FastMathFlags
noFastMathFlags Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#frem-instruction reference>.
frem :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
frem :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
frem Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ FastMathFlags
-> Operand -> Operand -> InstructionMetadata -> Instruction
FRem FastMathFlags
noFastMathFlags Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#add-instruction reference>.
add :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
add :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
add Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Bool
-> Bool -> Operand -> Operand -> InstructionMetadata -> Instruction
Add Bool
False Bool
False Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#mul-instruction reference>.
mul :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
mul :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
mul Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Bool
-> Bool -> Operand -> Operand -> InstructionMetadata -> Instruction
Mul Bool
False Bool
False Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#sub-instruction reference>.
sub :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
sub :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
sub Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Bool
-> Bool -> Operand -> Operand -> InstructionMetadata -> Instruction
Sub Bool
False Bool
False Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#udiv-instruction reference>.
udiv :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
udiv :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
udiv Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Bool -> Operand -> Operand -> InstructionMetadata -> Instruction
UDiv Bool
False Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#sdiv-instruction reference>.
sdiv :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
sdiv :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
sdiv Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Bool -> Operand -> Operand -> InstructionMetadata -> Instruction
SDiv Bool
False Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#urem-instruction reference>.
urem :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
urem :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
urem Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> InstructionMetadata -> Instruction
URem Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#srem-instruction reference>.
srem :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
srem :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
srem Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> InstructionMetadata -> Instruction
SRem Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#shl-instruction reference>.
shl :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
shl :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
shl Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Bool
-> Bool -> Operand -> Operand -> InstructionMetadata -> Instruction
Shl Bool
False Bool
False Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#lshl-instruction reference>.
lshr :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
lshr :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
lshr Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Bool -> Operand -> Operand -> InstructionMetadata -> Instruction
LShr Bool
True Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#ashl-instruction reference>.
ashr :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
ashr :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
ashr Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Bool -> Operand -> Operand -> InstructionMetadata -> Instruction
AShr Bool
True Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#and-instruction reference>.
and :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
and :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
and Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> InstructionMetadata -> Instruction
And Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#or-instruction reference>.
or :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
or :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
or Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> InstructionMetadata -> Instruction
Or Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#xor-instruction reference>.
xor :: (MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
xor :: forall (m :: * -> *).
(MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
xor Operand
a Operand
b = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> InstructionMetadata -> Instruction
Xor Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#alloca-instruction reference>.
alloca :: MonadIRBuilder m => Type -> Maybe Operand -> Word32 -> m Operand
alloca :: forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Maybe Operand -> Word32 -> m Operand
alloca Type
ty Maybe Operand
count Word32
align = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr (Type -> Type
ptr Type
ty) (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Type
-> Maybe Operand -> Word32 -> InstructionMetadata -> Instruction
Alloca Type
ty Maybe Operand
count Word32
align []

-- | See <https://llvm.org/docs/LangRef.html#load-instruction reference>.
load :: (HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Word32 -> m Operand
load :: forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Word32 -> m Operand
load Operand
a Word32
align = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> do
      let retty :: Type
retty = case Type
ta' of
                    PointerType Type
ty AddrSpace
_ -> Type
ty
                    Type
_ -> String -> Type
forall a. HasCallStack => String -> a
error String
"Cannot load non-pointer (Malformed AST)."
      Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
retty (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Bool
-> Operand
-> Maybe Atomicity
-> Word32
-> InstructionMetadata
-> Instruction
Load Bool
False Operand
a Maybe Atomicity
forall a. Maybe a
Nothing Word32
align []

-- | See <https://llvm.org/docs/LangRef.html#store-instruction reference>.
store :: MonadIRBuilder m => Operand -> Word32 -> Operand -> m ()
store :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Word32 -> Operand -> m ()
store Operand
addr Word32
align Operand
val = Instruction -> m ()
forall (m :: * -> *). MonadIRBuilder m => Instruction -> m ()
emitInstrVoid (Instruction -> m ()) -> Instruction -> m ()
forall a b. (a -> b) -> a -> b
$ Bool
-> Operand
-> Operand
-> Maybe Atomicity
-> Word32
-> InstructionMetadata
-> Instruction
Store Bool
False Operand
addr Operand
val Maybe Atomicity
forall a. Maybe a
Nothing Word32
align []

-- | Emit the @getelementptr@ instruction.
-- See <https://llvm.org/docs/LangRef.html#getelementptr-instruction reference>.
gep :: (HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) => Operand -> [Operand] -> m Operand
gep :: forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> [Operand] -> m Operand
gep Operand
addr [Operand]
is = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
addr
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> do
      Either String Type
ty <- Type -> [Operand] -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Type -> [Operand] -> m (Either String Type)
indexTypeByOperands Type
ta' [Operand]
is
      case Either String Type
ty of
        (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
        (Right Type
ty') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ty' (Bool -> Operand -> [Operand] -> InstructionMetadata -> Instruction
GetElementPtr Bool
False Operand
addr [Operand]
is [])

-- | Emit the @trunc ... to@ instruction.
-- See <https://llvm.org/docs/LangRef.html#trunc-to-instruction reference>.
trunc :: MonadIRBuilder m => Operand -> Type -> m Operand
trunc :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
trunc Operand
a Type
to = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
to (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Type -> InstructionMetadata -> Instruction
Trunc Operand
a Type
to []

-- | Emit the @fptrunc ... to@ instruction.
-- See <https://llvm.org/docs/LangRef.html#fptrunc-to-instruction reference>.
fptrunc :: MonadIRBuilder m => Operand -> Type -> m Operand
fptrunc :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
fptrunc Operand
a Type
to = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
to (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Type -> InstructionMetadata -> Instruction
FPTrunc Operand
a Type
to []

-- | Emit the @zext ... to@ instruction.
-- See <https://llvm.org/docs/LangRef.html#zext-to-instruction reference>.
zext :: MonadIRBuilder m => Operand -> Type -> m Operand
zext :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
zext Operand
a Type
to = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
to (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Type -> InstructionMetadata -> Instruction
ZExt Operand
a Type
to []

-- | Emit the @sext ... to@ instruction.
-- See <https://llvm.org/docs/LangRef.html#sext-to-instruction reference>.
sext :: MonadIRBuilder m => Operand -> Type -> m Operand
sext :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
sext Operand
a Type
to = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
to (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Type -> InstructionMetadata -> Instruction
SExt Operand
a Type
to []

-- | Emit the @fptoui ... to@ instruction.
-- See <https://llvm.org/docs/LangRef.html#fptoui-to-instruction reference>.
fptoui :: MonadIRBuilder m => Operand -> Type -> m Operand
fptoui :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
fptoui Operand
a Type
to = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
to (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Type -> InstructionMetadata -> Instruction
FPToUI Operand
a Type
to []

-- | Emit the @fptosi ... to@ instruction.
-- See <https://llvm.org/docs/LangRef.html#fptosi-to-instruction reference>.
fptosi :: MonadIRBuilder m => Operand -> Type -> m Operand
fptosi :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
fptosi Operand
a Type
to = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
to (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Type -> InstructionMetadata -> Instruction
FPToSI Operand
a Type
to []

-- | Emit the @fpext ... to@ instruction.
-- See <https://llvm.org/docs/LangRef.html#fpext-to-instruction reference>.
fpext :: MonadIRBuilder m => Operand -> Type -> m Operand
fpext :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
fpext Operand
a Type
to = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
to (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Type -> InstructionMetadata -> Instruction
FPExt Operand
a Type
to []

-- | Emit the @uitofp ... to@ instruction.
-- See <https://llvm.org/docs/LangRef.html#uitofp-to-instruction reference>.
uitofp :: MonadIRBuilder m => Operand -> Type -> m Operand
uitofp :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
uitofp Operand
a Type
to = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
to (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Type -> InstructionMetadata -> Instruction
UIToFP Operand
a Type
to []

-- | Emit the @sitofp ... to@ instruction.
-- See <https://llvm.org/docs/LangRef.html#sitofp-to-instruction reference>.
sitofp :: MonadIRBuilder m => Operand -> Type -> m Operand
sitofp :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
sitofp Operand
a Type
to = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
to (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Type -> InstructionMetadata -> Instruction
SIToFP Operand
a Type
to []

-- | Emit the @ptrtoint ... to@ instruction.
-- See <https://llvm.org/docs/LangRef.html#ptrtoint-to-instruction reference>.
ptrtoint :: MonadIRBuilder m => Operand -> Type -> m Operand
ptrtoint :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
ptrtoint Operand
a Type
to = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
to (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Type -> InstructionMetadata -> Instruction
PtrToInt Operand
a Type
to []

-- | Emit the @inttoptr ... to@ instruction.
-- See <https://llvm.org/docs/LangRef.html#inttoptr-to-instruction reference>.
inttoptr :: MonadIRBuilder m => Operand -> Type -> m Operand
inttoptr :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
inttoptr Operand
a Type
to = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
to (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Type -> InstructionMetadata -> Instruction
IntToPtr Operand
a Type
to []

-- | Emit the @bitcast ... to@ instruction.
-- See <https://llvm.org/docs/LangRef.html#bitcast-to-instruction reference>.
bitcast :: MonadIRBuilder m => Operand -> Type -> m Operand
bitcast :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
bitcast Operand
a Type
to = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
to (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Type -> InstructionMetadata -> Instruction
BitCast Operand
a Type
to []

-- | See <https://llvm.org/docs/LangRef.html#extractelement-instruction reference>.
extractElement :: (HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> m Operand
extractElement :: forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> m Operand
extractElement Operand
v Operand
i = do
  Either String Type
tv <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
v
  let elemTyp :: Type
elemTyp = case Either String Type
tv of
                  (Left String
s) -> String -> Type
forall a. HasCallStack => String -> a
error String
s
                  (Right (VectorType Word32
_ Type
typ)) -> Type
typ
                  (Right Type
typ) -> String -> Type
forall a. HasCallStack => String -> a
error (String -> Type) -> String -> Type
forall a b. (a -> b) -> a -> b
$ String
"extractElement: Expected a vector type but got " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Type -> String
forall a. Show a => a -> String
show Type
typ String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" (Malformed AST)."
  Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
elemTyp (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> InstructionMetadata -> Instruction
ExtractElement Operand
v Operand
i []

-- | See <https://llvm.org/docs/LangRef.html#insertelement-instruction reference>.
insertElement :: (HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> Operand -> m Operand
insertElement :: forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> Operand -> m Operand
insertElement Operand
v Operand
e Operand
i = do
  Either String Type
tv <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
v
  case Either String Type
tv of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
tv') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
tv' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> Operand -> InstructionMetadata -> Instruction
InsertElement Operand
v Operand
e Operand
i []

-- | See <https://llvm.org/docs/LangRef.html#shufflevector-instruction reference>.
shuffleVector :: (HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> [Int32] -> m Operand
shuffleVector :: forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> [Int32] -> m Operand
shuffleVector Operand
a Operand
b [Int32]
m = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  Either String Type
tm <- [Int32] -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
[Int32] -> m (Either String Type)
typeOf [Int32]
m
  let retType :: Type
retType = case (Either String Type
ta, Either String Type
tm) of
                  (Right (VectorType Word32
_ Type
elemTyp), Right (VectorType Word32
maskLength Type
_)) -> Word32 -> Type -> Type
VectorType Word32
maskLength Type
elemTyp
                  (Either String Type, Either String Type)
_ -> String -> Type
forall a. HasCallStack => String -> a
error String
"shuffleVector: Expected two vectors and a vector mask"
  Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
retType (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> [Int32] -> InstructionMetadata -> Instruction
ShuffleVector Operand
a Operand
b [Int32]
m []

-- | See <https://llvm.org/docs/LangRef.html#extractvalue-instruction reference>.
extractValue :: (HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) => Operand -> [Word32] -> m Operand
extractValue :: forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> [Word32] -> m Operand
extractValue Operand
a [Word32]
i = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  let aggType :: Type
aggType = case Either String Type
ta of
                  (Left String
s) -> String -> Type
forall a. HasCallStack => String -> a
error String
s
                  (Right typ :: Type
typ@ArrayType{}) -> Type
typ
                  (Right typ :: Type
typ@NamedTypeReference{}) -> Type
typ
                  (Right typ :: Type
typ@StructureType{}) -> Type
typ
                  (Right Type
typ) -> String -> Type
forall a. HasCallStack => String -> a
error (String -> Type) -> String -> Type
forall a b. (a -> b) -> a -> b
$ String
"extractValue: Expecting structure or array type but got " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Type -> String
forall a. Show a => a -> String
show Type
typ String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" (Malformed AST)."
  Either String Type
retType <- Type -> [Operand] -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Type -> [Operand] -> m (Either String Type)
indexTypeByOperands Type
aggType ((Word32 -> Operand) -> [Word32] -> [Operand]
forall a b. (a -> b) -> [a] -> [b]
map (Constant -> Operand
ConstantOperand (Constant -> Operand) -> (Word32 -> Constant) -> Word32 -> Operand
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Integer -> Constant
C.Int Word32
32 (Integer -> Constant) -> (Word32 -> Integer) -> Word32 -> Constant
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral) [Word32]
i)
  case Either String Type
retType of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
retType') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr (Type -> Type
pointerReferent Type
retType') (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> [Word32] -> InstructionMetadata -> Instruction
ExtractValue Operand
a [Word32]
i []

-- | See <https://llvm.org/docs/LangRef.html#insertvalue-instruction reference>.
insertValue :: (HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> [Word32] -> m Operand
insertValue :: forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> [Word32] -> m Operand
insertValue Operand
a Operand
e [Word32]
i = do
  Either String Type
ta <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
a
  case Either String Type
ta of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ta') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ta' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand
-> Operand -> [Word32] -> InstructionMetadata -> Instruction
InsertValue Operand
a Operand
e [Word32]
i []

-- | See <https://llvm.org/docs/LangRef.html#icmp-instruction reference>.
icmp :: MonadIRBuilder m => IP.IntegerPredicate -> Operand -> Operand -> m Operand
icmp :: forall (m :: * -> *).
MonadIRBuilder m =>
IntegerPredicate -> Operand -> Operand -> m Operand
icmp IntegerPredicate
pred Operand
a Operand
b = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
i1 (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ IntegerPredicate
-> Operand -> Operand -> InstructionMetadata -> Instruction
ICmp IntegerPredicate
pred Operand
a Operand
b []

-- | See <https://llvm.org/docs/LangRef.html#fcmp-instruction reference>.
fcmp :: MonadIRBuilder m => FP.FloatingPointPredicate -> Operand -> Operand -> m Operand
fcmp :: forall (m :: * -> *).
MonadIRBuilder m =>
FloatingPointPredicate -> Operand -> Operand -> m Operand
fcmp FloatingPointPredicate
pred Operand
a Operand
b = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
i1 (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ FloatingPointPredicate
-> Operand -> Operand -> InstructionMetadata -> Instruction
FCmp FloatingPointPredicate
pred Operand
a Operand
b []

-- | Unconditional branch.
-- Emit a @br label <dest>@ instruction
-- See <https://llvm.org/docs/LangRef.html#br-instruction reference>.
br :: MonadIRBuilder m => Name -> m ()
br :: forall (m :: * -> *). MonadIRBuilder m => Name -> m ()
br Name
val = Terminator -> m ()
forall (m :: * -> *). MonadIRBuilder m => Terminator -> m ()
emitTerm (Name -> InstructionMetadata -> Terminator
Br Name
val [])

-- | See <https://llvm.org/docs/LangRef.html#phi-instruction reference>.
phi :: (HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) => [(Operand, Name)] -> m Operand
phi :: forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
[(Operand, Name)] -> m Operand
phi [] = Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
AST.void (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Type -> [(Operand, Name)] -> InstructionMetadata -> Instruction
Phi Type
AST.void [] []
phi incoming :: [(Operand, Name)]
incoming@((Operand, Name)
i:[(Operand, Name)]
_) = do
  Either String Type
ty <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf ((Operand, Name) -> Operand
forall a b. (a, b) -> a
fst (Operand, Name)
i)
  case Either String Type
ty of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ty') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
ty' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Type -> [(Operand, Name)] -> InstructionMetadata -> Instruction
Phi Type
ty' [(Operand, Name)]
incoming []

-- | Emit a @ret void@ instruction.
-- See <https://llvm.org/docs/LangRef.html#ret-instruction reference>.
retVoid :: MonadIRBuilder m => m ()
retVoid :: forall (m :: * -> *). MonadIRBuilder m => m ()
retVoid = Terminator -> m ()
forall (m :: * -> *). MonadIRBuilder m => Terminator -> m ()
emitTerm (Maybe Operand -> InstructionMetadata -> Terminator
Ret Maybe Operand
forall a. Maybe a
Nothing [])

-- | See <https://llvm.org/docs/LangRef.html#call-instruction reference>.
call :: (HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) => Operand -> [(Operand, [ParameterAttribute])] -> m Operand
call :: forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> [(Operand, [ParameterAttribute])] -> m Operand
call Operand
fun [(Operand, [ParameterAttribute])]
args = do
  let instr :: Instruction
instr = Call {
    tailCallKind :: Maybe TailCallKind
AST.tailCallKind = Maybe TailCallKind
forall a. Maybe a
Nothing
  , callingConvention :: CallingConvention
AST.callingConvention = CallingConvention
CC.C
  , returnAttributes :: [ParameterAttribute]
AST.returnAttributes = []
  , function :: CallableOperand
AST.function = Operand -> CallableOperand
forall a b. b -> Either a b
Right Operand
fun
  , arguments :: [(Operand, [ParameterAttribute])]
AST.arguments = [(Operand, [ParameterAttribute])]
args
  , functionAttributes :: [Either GroupID FunctionAttribute]
AST.functionAttributes = []
  , metadata :: InstructionMetadata
AST.metadata = []
  }
  Either String Type
tf <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
fun
  case Either String Type
tf of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right (FunctionType Type
r [Type]
_ Bool
_)) -> case Type
r of
      Type
VoidType -> Instruction -> m ()
forall (m :: * -> *). MonadIRBuilder m => Instruction -> m ()
emitInstrVoid Instruction
instr m () -> m Operand -> m Operand
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Operand -> m Operand
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Constant -> Operand
ConstantOperand (Type -> Constant
C.Undef Type
void)))
      Type
_        -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
r Instruction
instr
    (Right (PointerType (FunctionType Type
r [Type]
_ Bool
_) AddrSpace
_)) -> case Type
r of
      Type
VoidType -> Instruction -> m ()
forall (m :: * -> *). MonadIRBuilder m => Instruction -> m ()
emitInstrVoid Instruction
instr m () -> m Operand -> m Operand
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Operand -> m Operand
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Constant -> Operand
ConstantOperand (Type -> Constant
C.Undef Type
void)))
      Type
_        -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
r Instruction
instr
    (Right Type
_) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
"Cannot call non-function (Malformed AST)."

-- | See <https://llvm.org/docs/LangRef.html#ret-instruction reference>.
ret :: MonadIRBuilder m => Operand -> m ()
ret :: forall (m :: * -> *). MonadIRBuilder m => Operand -> m ()
ret Operand
val = Terminator -> m ()
forall (m :: * -> *). MonadIRBuilder m => Terminator -> m ()
emitTerm (Maybe Operand -> InstructionMetadata -> Terminator
Ret (Operand -> Maybe Operand
forall a. a -> Maybe a
Just Operand
val) [])

-- | See <https://llvm.org/docs/LangRef.html#switch-instruction reference>.
switch :: MonadIRBuilder m => Operand -> Name -> [(C.Constant, Name)] -> m ()
switch :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Name -> [(Constant, Name)] -> m ()
switch Operand
val Name
def [(Constant, Name)]
dests = Terminator -> m ()
forall (m :: * -> *). MonadIRBuilder m => Terminator -> m ()
emitTerm (Terminator -> m ()) -> Terminator -> m ()
forall a b. (a -> b) -> a -> b
$ Operand
-> Name -> [(Constant, Name)] -> InstructionMetadata -> Terminator
Switch Operand
val Name
def [(Constant, Name)]
dests []

-- | See <https://llvm.org/docs/LangRef.html#select-instruction reference>.
select :: (HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) => Operand -> Operand -> Operand -> m Operand
select :: forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> Operand -> Operand -> m Operand
select Operand
cond Operand
t Operand
f = do
  Either String Type
tt <- Operand -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Operand -> m (Either String Type)
typeOf Operand
t
  case Either String Type
tt of
    (Left String
s) -> String -> m Operand
forall a. HasCallStack => String -> a
error String
s
    (Right Type
tt') -> Type -> Instruction -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Type -> Instruction -> m Operand
emitInstr Type
tt' (Instruction -> m Operand) -> Instruction -> m Operand
forall a b. (a -> b) -> a -> b
$ Operand -> Operand -> Operand -> InstructionMetadata -> Instruction
Select Operand
cond Operand
t Operand
f []

-- | Conditional branch (see 'br' for unconditional instructions).
-- See <https://llvm.org/docs/LangRef.html#br-instruction reference>.
condBr :: MonadIRBuilder m => Operand -> Name -> Name -> m ()
condBr :: forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Name -> Name -> m ()
condBr Operand
cond Name
tdest Name
fdest = Terminator -> m ()
forall (m :: * -> *). MonadIRBuilder m => Terminator -> m ()
emitTerm (Terminator -> m ()) -> Terminator -> m ()
forall a b. (a -> b) -> a -> b
$ Operand -> Name -> Name -> InstructionMetadata -> Terminator
CondBr Operand
cond Name
tdest Name
fdest []

-- | See <https://llvm.org/docs/LangRef.html#unreachable-instruction reference>.
unreachable :: MonadIRBuilder m => m ()
unreachable :: forall (m :: * -> *). MonadIRBuilder m => m ()
unreachable = Terminator -> m ()
forall (m :: * -> *). MonadIRBuilder m => Terminator -> m ()
emitTerm (Terminator -> m ()) -> Terminator -> m ()
forall a b. (a -> b) -> a -> b
$ InstructionMetadata -> Terminator
Unreachable []

-- | Creates a series of instructions to generate a pointer to a string
-- constant. Useful for making format strings to pass to @printf@, for example
globalStringPtr
  :: (HasCallStack, MonadIRBuilder m, MonadModuleBuilder m)
  => String       -- ^ The string to generate
  -> Name         -- ^ Variable name of the pointer
  -> m C.Constant
globalStringPtr :: forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
String -> Name -> m Constant
globalStringPtr String
str Name
nm = do
  let asciiVals :: [Integer]
asciiVals = (Char -> Integer) -> String -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> (Char -> Int) -> Char -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
ord) String
str
      llvmVals :: [Constant]
llvmVals  = (Integer -> Constant) -> [Integer] -> [Constant]
forall a b. (a -> b) -> [a] -> [b]
map (Word32 -> Integer -> Constant
C.Int Word32
8) ([Integer]
asciiVals [Integer] -> [Integer] -> [Integer]
forall a. [a] -> [a] -> [a]
++ [Integer
0]) -- append null terminator
      char :: Type
char      = Word32 -> Type
IntegerType Word32
8
      charArray :: Constant
charArray = Type -> [Constant] -> Constant
C.Array Type
char [Constant]
llvmVals
  Either String Type
ty <- Constant -> m (Either String Type)
forall a (m :: * -> *).
(Typed a, HasCallStack, MonadModuleBuilder m) =>
a -> m (Either String Type)
forall (m :: * -> *).
(HasCallStack, MonadModuleBuilder m) =>
Constant -> m (Either String Type)
LLVM.AST.Typed.typeOf Constant
charArray
  case Either String Type
ty of
    (Left String
s) -> String -> m Constant
forall a. HasCallStack => String -> a
error String
s
    (Right Type
ty') -> do
      Definition -> m ()
forall (m :: * -> *). MonadModuleBuilder m => Definition -> m ()
emitDefn (Definition -> m ()) -> Definition -> m ()
forall a b. (a -> b) -> a -> b
$ Global -> Definition
GlobalDefinition Global
globalVariableDefaults
        { name :: Name
name                  = Name
nm
        , type' :: Type
LLVM.AST.Global.type' = Type
ty'
        , linkage :: Linkage
linkage               = Linkage
External
        , isConstant :: Bool
isConstant            = Bool
True
        , initializer :: Maybe Constant
initializer           = Constant -> Maybe Constant
forall a. a -> Maybe a
Just Constant
charArray
        , unnamedAddr :: Maybe UnnamedAddr
unnamedAddr           = UnnamedAddr -> Maybe UnnamedAddr
forall a. a -> Maybe a
Just UnnamedAddr
GlobalAddr
        }
      Constant -> m Constant
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Constant -> m Constant) -> Constant -> m Constant
forall a b. (a -> b) -> a -> b
$ Bool -> Constant -> [Constant] -> Constant
C.GetElementPtr Bool
True
                              (Type -> Name -> Constant
C.GlobalReference (Type -> Type
ptr Type
ty') Name
nm)
                              [(Word32 -> Integer -> Constant
C.Int Word32
32 Integer
0), (Word32 -> Integer -> Constant
C.Int Word32
32 Integer
0)]

sizeof :: (HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) => Word32 -> Type -> m Operand
sizeof :: forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
Word32 -> Type -> m Operand
sizeof Word32
szBits Type
ty = do
  Operand
tyNullPtr <- Operand -> Type -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
inttoptr (Constant -> Operand
ConstantOperand (Constant -> Operand) -> Constant -> Operand
forall a b. (a -> b) -> a -> b
$ Word32 -> Integer -> Constant
C.Int Word32
szBits Integer
0) (Type -> Type
ptr Type
ty)
  Operand
tySzPtr <- Operand -> [Operand] -> m Operand
forall (m :: * -> *).
(HasCallStack, MonadIRBuilder m, MonadModuleBuilder m) =>
Operand -> [Operand] -> m Operand
gep Operand
tyNullPtr [Constant -> Operand
ConstantOperand (Constant -> Operand) -> Constant -> Operand
forall a b. (a -> b) -> a -> b
$ Word32 -> Integer -> Constant
C.Int Word32
szBits Integer
1]
  Operand -> Type -> m Operand
forall (m :: * -> *).
MonadIRBuilder m =>
Operand -> Type -> m Operand
ptrtoint Operand
tySzPtr (Type -> m Operand) -> Type -> m Operand
forall a b. (a -> b) -> a -> b
$ Word32 -> Type
IntegerType Word32
szBits