module LLVM.ExecutionEngine.Target(TargetData(..), ourTargetData, targetDataFromString) where --import Data.Word import Foreign.C.String import System.IO.Unsafe(unsafePerformIO) --import LLVM.Core import LLVM.ExecutionEngine.Engine(runEngineAccess, getExecutionEngineTargetData) import qualified LLVM.FFI.Core as FFI import qualified LLVM.FFI.Target as FFI type Type = FFI.TypeRef data TargetData = TargetData { aBIAlignmentOfType :: Type -> Int, aBISizeOfType :: Type -> Int, littleEndian :: Bool, callFrameAlignmentOfType :: Type -> Int, -- elementAtOffset :: Type -> Word64 -> Int, intPtrType :: Type, -- offsetOfElements :: Int -> Word64, pointerSize :: Int, -- preferredAlignmentOfGlobal :: Value a -> Int, preferredAlignmentOfType :: Type -> Int, sizeOfTypeInBits :: Type -> Int, storeSizeOfType :: Type -> Int } un :: IO a -> a un = unsafePerformIO -- Gets the target data for the JIT target. -- This is really constant, so unsafePerformIO is safe. ourEngineTargetDataRef :: FFI.TargetDataRef ourEngineTargetDataRef = un $ runEngineAccess getExecutionEngineTargetData -- Normally the TargetDataRef never changes, so the operation -- are really pure functions. makeTargetData :: FFI.TargetDataRef -> TargetData makeTargetData r = TargetData { aBIAlignmentOfType = fromIntegral . un . FFI.aBIAlignmentOfType r, aBISizeOfType = fromIntegral . un . FFI.aBISizeOfType r, littleEndian = un (FFI.byteOrder r) /= 0, callFrameAlignmentOfType = fromIntegral . un . FFI.callFrameAlignmentOfType r, intPtrType = un $ FFI.intPtrType r, pointerSize = fromIntegral $ un $ FFI.pointerSize r, preferredAlignmentOfType = fromIntegral . un . FFI.preferredAlignmentOfType r, sizeOfTypeInBits = fromIntegral . un . FFI.sizeOfTypeInBits r, storeSizeOfType = fromIntegral . un . FFI.storeSizeOfType r } ourTargetData :: TargetData ourTargetData = makeTargetData ourEngineTargetDataRef targetDataFromString :: String -> TargetData targetDataFromString s = makeTargetData $ un $ withCString s FFI.createTargetData