llvm-0.0.2: LLVM/Core/Constant.hs
{-# LANGUAGE
DeriveDataTypeable
, FlexibleContexts
, FunctionalDependencies
, MultiParamTypeClasses
#-}
module LLVM.Core.Constant
(
-- * Constant expressions
ConstExpr(..)
-- ** Arithmetic
, neg
, not
, add
, sub
, mul
, udiv
, sdiv
, fdiv
, urem
, srem
, frem
, and
, or
, xor
, shl
, lshr
, ashr
-- ** Memory
, gep
-- ** Conversions
, trunc
, sExt
, zExt
, fpTrunc
, fpExt
, uiToFP
, siToFP
, fpToUI
, fpToSI
, ptrToInt
, intToPtr
, bitCast
-- ** Comparisons
, icmp
, fcmp
-- ** Miscellaneous operations
, select
, extractElement
, insertElement
, shuffleVector
-- * Constant values
, Const(..)
-- ** Scalar constants
, constInt
, constWord
, constReal
-- ** Composite constants
, constString
, constStringNul
) where
import Data.Int (Int8, Int16, Int32, Int64)
import Data.Typeable (Typeable)
import Data.Word (Word8, Word16, Word32, Word64)
import Foreign.C.String (withCStringLen)
import Foreign.Marshal.Utils (fromBool)
import Prelude hiding (and, const, not, or)
import qualified Prelude as Prelude
import System.IO.Unsafe (unsafePerformIO)
import qualified LLVM.Core.FFI as FFI
import qualified LLVM.Core.Instruction as I
import qualified LLVM.Core.Type as T
import qualified LLVM.Core.Value as V
newtype ConstExpr t = ConstExpr V.AnyValue
deriving (V.ConstValue, V.DynamicValue, Typeable, V.Value)
unary :: (V.ConstValue v) =>
(FFI.ValueRef -> FFI.ValueRef) -> v -> ConstExpr t
unary ffi = ConstExpr . V.mkAnyValue . ffi . V.valueRef
neg :: (V.ConstValue v, V.Arithmetic v, T.Arithmetic t) => v -> ConstExpr t
neg = unary FFI.constNeg
not :: (V.ConstValue v, T.Integer t, V.TypedValue v t) => v -> ConstExpr t
not = unary FFI.constNot
binary :: (V.ConstValue a, V.ConstValue b)
=> (FFI.ValueRef -> FFI.ValueRef -> FFI.ValueRef) -> a -> b
-> ConstExpr t
binary ffi a b = ConstExpr . V.mkAnyValue $ ffi (V.valueRef a) (V.valueRef b)
add :: (T.Arithmetic t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
add = binary FFI.constAdd
sub :: (T.Arithmetic t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
sub = binary FFI.constSub
mul :: (T.Arithmetic t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
mul = binary FFI.constMul
udiv :: (T.Integer t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
udiv = binary FFI.constUDiv
sdiv :: (T.Integer t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
sdiv = binary FFI.constSDiv
fdiv :: (T.Real t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
fdiv = binary FFI.constFDiv
urem :: (T.Integer t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
urem = binary FFI.constURem
srem :: (T.Integer t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
srem = binary FFI.constURem
frem :: (T.Real t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
frem = binary FFI.constFRem
and :: (T.Integer t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
and = binary FFI.constAnd
or :: (T.Integer t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
or = binary FFI.constOr
xor :: (T.Integer t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
xor = binary FFI.constXor
icmp :: (T.Integer t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> I.IntPredicate -> a -> b -> ConstExpr T.Int1
icmp p = binary (FFI.constICmp (I.fromIP p))
fcmp :: (T.Real t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> I.RealPredicate -> a -> b -> ConstExpr T.Int1
fcmp p = binary (FFI.constFCmp (I.fromRP p))
shl :: (T.Integer t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
shl = binary FFI.constShl
lshr :: (T.Integer t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
lshr = binary FFI.constLShr
ashr :: (T.Integer t, V.ConstValue a, V.TypedValue a t,
V.ConstValue b, V.TypedValue b t)
=> a -> b -> ConstExpr t
ashr = binary FFI.constAShr
gep :: (V.ConstValue v, T.Integer t, V.TypedValue v t)
=> a -> b -> ConstExpr t
gep = undefined
typed :: (V.ConstValue v, T.Type s, V.ConstValue w, V.DynamicValue w)
=> (FFI.ValueRef -> FFI.TypeRef -> FFI.ValueRef) -> v -> s -> w
typed ffi a b = V.fromAnyValue . V.mkAnyValue $ ffi (V.valueRef a) (T.typeRef b)
trunc :: (V.ConstValue v, T.Integer s, V.TypedValue v s,
V.ConstValue w, V.DynamicValue w, T.Integer t, V.TypedValue w t)
=> v -> t -> w
trunc = typed FFI.constTrunc
sExt :: (V.ConstValue v, T.Integer t, V.TypedValue v t)
=> v -> t -> ConstExpr t
sExt = typed FFI.constSExt
zExt :: (V.ConstValue v, T.Integer t, V.TypedValue v t)
=> v -> t -> ConstExpr t
zExt = typed FFI.constZExt
fpTrunc :: (V.ConstValue v, V.Real v, T.Real t)
=> v -> t -> ConstExpr t
fpTrunc = typed FFI.constFPTrunc
fpExt :: (V.ConstValue v, V.Real v, T.Real t)
=> v -> t -> ConstExpr t
fpExt = typed FFI.constFPExt
-- XXX How to express the inability to cast from scalar to vector?
uiToFP :: (V.ConstValue v, T.Integer s, V.TypedValue v s, T.Real t)
=> v -> s -> ConstExpr t
uiToFP = typed FFI.constUIToFP
siToFP :: (V.ConstValue v, V.Integer v, T.Integer s, T.Real t)
=> v -> s -> ConstExpr t
siToFP = typed FFI.constSIToFP
fpToUI :: (V.ConstValue v, V.Real v, T.Real s, T.Integer t)
=> v -> s -> ConstExpr t
fpToUI = typed FFI.constFPToUI
fpToSI :: (V.ConstValue v, V.Real v, T.Real s, T.Integer t)
=> v -> s -> ConstExpr t
fpToSI = typed FFI.constFPToSI
ptrToInt :: (V.ConstValue v, T.Integer t)
=> v -> T.Pointer a -> ConstExpr t
ptrToInt = typed FFI.constPtrToInt
intToPtr :: (V.ConstValue v, T.Integer t)
=> v -> t -> ConstExpr (T.Pointer a)
intToPtr = typed FFI.constIntToPtr
-- XXX How to express pointer/non-pointer and bit-width constraints?
bitCast :: (V.ConstValue v, T.Type t,
V.ConstValue w, V.DynamicValue w)
=> v -> t -> w
bitCast = typed FFI.constBitCast
select :: (V.TypedValue k T.Int1,
V.ConstValue a, V.TypedValue a t, V.ConstValue b, V.TypedValue b t)
=> k -> a -> b -> ConstExpr t
select k = binary (FFI.constSelect (V.valueRef k))
extractElement :: (V.ConstValue v, V.TypedValue v (T.Vector a),
V.ConstValue i, V.Integer i) => v -> i -> ConstExpr a
extractElement = binary FFI.constExtractElement
ternary :: (V.ConstValue a, V.ConstValue b, V.ConstValue c)
=> (FFI.ValueRef -> FFI.ValueRef -> FFI.ValueRef -> FFI.ValueRef)
-> a -> b -> c -> ConstExpr t
ternary ffi a b c = ConstExpr . V.mkAnyValue $
ffi (V.valueRef a) (V.valueRef b) (V.valueRef c)
insertElement :: (V.ConstValue v, V.TypedValue v (T.Vector a),
V.ConstValue e, V.TypedValue e a,
V.ConstValue i, V.Integer i)
=> v -> e -> i -> ConstExpr (T.Vector a)
insertElement = ternary FFI.constInsertElement
shuffleVector :: (V.ConstValue v1, V.TypedValue v1 (T.Vector a),
V.ConstValue v2, V.TypedValue v2 (T.Vector a),
V.ConstValue m, V.TypedValue m (T.Vector T.Int32))
=> v1 -> v2 -> m -> ConstExpr (T.Vector a)
shuffleVector = ternary FFI.constShuffleVector
constWord :: (T.Integer t, Integral a) => (b -> t) -> a -> V.ConstInt t
constWord typ val =
V.ConstInt . V.mkAnyValue $ FFI.constInt (T.typeRef (typ undefined))
(fromIntegral val) 0
constInt :: (T.Integer t, Integral a) => (b -> t) -> a -> V.ConstInt t
constInt typ val =
V.ConstInt . V.mkAnyValue $ FFI.constInt (T.typeRef (typ undefined))
(fromIntegral val) 1
constReal :: (T.Real t, RealFloat a) => (b -> t) -> a -> V.ConstReal t
constReal typ val = V.ConstReal . V.mkAnyValue $ FFI.constReal
(T.typeRef (typ undefined)) (realToFrac val)
constStringInternal :: Bool -> String -> V.ConstArray T.Int8
constStringInternal nulTerm s = unsafePerformIO $
withCStringLen s $ \(sPtr, sLen) ->
return . V.ConstArray . V.mkAnyValue $
FFI.constString sPtr (fromIntegral sLen) (fromBool (Prelude.not nulTerm))
constString :: String -> V.ConstArray T.Int8
constString = constStringInternal False
constStringNul :: String -> V.ConstArray T.Int8
constStringNul = constStringInternal True
class V.ConstValue t => Const a t | a -> t where
const :: a -> t
instance Const String (V.ConstArray T.Int8) where
const = constStringNul
instance Const Float (V.ConstReal T.Float) where
const = constReal T.float . fromRational . toRational
instance Const Double (V.ConstReal T.Double) where
const = constReal T.double
instance Const Int8 (V.ConstInt T.Int8) where
const = constInt T.int8 . fromIntegral
instance Const Int16 (V.ConstInt T.Int16) where
const = constInt T.int16 . fromIntegral
instance Const Int32 (V.ConstInt T.Int32) where
const = constInt T.int32 . fromIntegral
instance Const Int64 (V.ConstInt T.Int64) where
const = constInt T.int64
instance Const Word8 (V.ConstInt T.Int8) where
const = constWord T.int8 . fromIntegral
instance Const Word16 (V.ConstInt T.Int16) where
const = constWord T.int16 . fromIntegral
instance Const Word32 (V.ConstInt T.Int32) where
const = constWord T.int32 . fromIntegral
instance Const Word64 (V.ConstInt T.Int64) where
const = constWord T.int64 . fromIntegral