-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Utility functions for the llvm interface -- -- The Low-Level Virtual-Machine is a compiler back-end with optimizer. -- You may also call it a high-level portable assembler. This package -- provides various utility functions for the Haskell interface to LLVM, -- for example: -- -- @package llvm-extra @version 0.1 module LLVM.Extra.Extension -- | This is an Applicative functor that registers, what extensions are -- needed in order to run the contained instructions. You can escape from -- the functor by calling run and providing a generic -- implementation. -- -- We use an applicative functor since with a monadic interface we had to -- create the specialised code in every case, in order to see which -- extensions where used in the course of creating the instructions. -- -- We use only one (unparameterized) type for all extensions, since this -- is the most simple solution. Alternatively we could use a type -- parameter where class constraints show what extensions are needed. -- This would be just like exceptions that are explicit in the type -- signature as in the control-monad-exception package. However we would -- still need to lift all basic LLVM instructions to the new monad. data T a -- | Analogous to FunctionArgs -- -- The type parameter r and its functional dependency are -- necessary since g must be a function of the form a -> -- ... -> c -> CodeGenFunction r d and we must ensure that the -- explicit r and the implicit r in the g do -- match. class CallArgs g r | g -> r data Subtarget Subtarget :: String -> String -> (forall r. CodeGenFunction r Bool) -> Subtarget -- | Declare that a certain plain LLVM instruction depends on a particular -- extension. This can be useful if you rely on the data layout of a -- certain architecture when doing a bitcast, or if you know that LLVM -- translates a certain generic operation to something especially optimal -- for the declared extension. wrap :: Subtarget -> a -> T a -- | Create an intrinsic and register the needed extension. We cannot -- immediately check whether the signature matches or whether the right -- extension is given. However, when resolving intrinsics LLVM will not -- find the intrinsic if the extension is wrong, and it also checks the -- signature. intrinsic :: (IsFunction f, CallArgs f g, CallArgs g r) => Subtarget -> String -> T g intrinsicAttr :: (IsFunction f, CallArgs f g, CallArgs g r) => [Attribute] -> Subtarget -> String -> T g -- | run generic specific generates the specific code if -- the required extensions are available on the host processor and -- generic otherwise. run :: CodeGenFunction r a -> T (CodeGenFunction r a) -> CodeGenFunction r a -- | Convenient variant of run: Only run the code with extended -- instructions if an additional condition is given. runWhen :: Bool -> CodeGenFunction r a -> T (CodeGenFunction r a) -> CodeGenFunction r a -- | Only for debugging purposes. runUnsafe :: T a -> a with :: (Functor f) => f a -> (a -> b) -> f b with2 :: (Applicative f) => f a -> f b -> (a -> b -> c) -> f c with3 :: (Applicative f) => f a -> f b -> f c -> (a -> b -> c -> d) -> f d instance Functor T instance Applicative T instance CallArgs (CodeGenFunction r (Value a)) r instance (CallArgs g r) => CallArgs (Value a -> g) r module LLVM.Extra.ExtensionCheck.X86 sse1 :: Subtarget sse2 :: Subtarget sse3 :: Subtarget ssse3 :: Subtarget sse41 :: Subtarget sse42 :: Subtarget module LLVM.Extra.Class class Zero a zeroTuple :: (Zero a) => a zeroTuplePointed :: (Zero a, Applicative f) => f a buildTupleTraversable :: (Monad m, Traversable f, Applicative f) => m a -> m (f a) undefTuplePointed :: (Undefined a, Applicative f) => f a valueTupleOfFunctor :: (MakeValueTuple h l, Functor f) => f h -> f l tupleDescFoldable :: (IsTuple a, Foldable f) => f a -> [TypeDesc] phisTraversable :: (Phi a, Traversable f) => BasicBlock -> f a -> CodeGenFunction r (f a) addPhisFoldable :: (Phi a, Foldable f, Applicative f) => BasicBlock -> f a -> f a -> CodeGenFunction r () instance (Zero a, Zero b, Zero c) => Zero (a, b, c) instance (Zero a, Zero b) => Zero (a, b) instance (IsFirstClass a) => Zero (Value a) instance Zero () module LLVM.Extra.Representation -- | An implementation of both MakeValueTuple and Memory must -- ensure that haskellValue is compatible with -- llvmStruct. That is, writing and reading llvmStruct -- by LLVM must be the same as accessing haskellValue by -- Storable methods. -- -- We use a functional dependency in order to let type inference work -- nicely. class (Phi llvmValue, IsType llvmStruct) => Memory llvmValue llvmStruct | llvmValue -> llvmStruct load :: (Memory llvmValue llvmStruct) => Value (Ptr llvmStruct) -> CodeGenFunction r llvmValue store :: (Memory llvmValue llvmStruct) => llvmValue -> Value (Ptr llvmStruct) -> CodeGenFunction r (Value ()) decompose :: (Memory llvmValue llvmStruct) => Value llvmStruct -> CodeGenFunction r llvmValue compose :: (Memory llvmValue llvmStruct) => llvmValue -> CodeGenFunction r (Value llvmStruct) modify :: (Memory llvmValue llvmStruct) => (llvmValue -> CodeGenFunction r llvmValue) -> Value (Ptr llvmStruct) -> CodeGenFunction r (Value ()) castStorablePtr :: (MakeValueTuple haskellValue llvmValue, Memory llvmValue llvmStruct) => Ptr haskellValue -> Ptr llvmStruct type MemoryRecord r o v = MemoryElement r o v v data MemoryElement r o v x memoryElement :: (Memory x llvmStruct, GetValue o n llvmStruct, GetElementPtr o (n, ()) llvmStruct) => (v -> x) -> n -> MemoryElement r o v x loadRecord :: MemoryRecord r o llvmValue -> Value (Ptr o) -> CodeGenFunction r llvmValue storeRecord :: MemoryRecord r o llvmValue -> llvmValue -> Value (Ptr o) -> CodeGenFunction r (Value ()) decomposeRecord :: MemoryRecord r o llvmValue -> Value o -> CodeGenFunction r llvmValue composeRecord :: (IsType o) => MemoryRecord r o llvmValue -> llvmValue -> CodeGenFunction r (Value o) loadNewtype :: (Memory a o) => (a -> llvmValue) -> Value (Ptr o) -> CodeGenFunction r llvmValue storeNewtype :: (Memory a o) => (llvmValue -> a) -> llvmValue -> Value (Ptr o) -> CodeGenFunction r (Value ()) decomposeNewtype :: (Memory a o) => (a -> llvmValue) -> Value o -> CodeGenFunction r llvmValue composeNewtype :: (Memory a o) => (llvmValue -> a) -> llvmValue -> CodeGenFunction r (Value o) newForeignPtrInit :: FunPtr (Ptr a -> IO ()) -> FunPtr (IO (Ptr a)) -> IO (ForeignPtr a) newForeignPtrParam :: (Storable b, MakeValueTuple b bl, Memory bl bp) => FunPtr (Ptr a -> IO ()) -> FunPtr (Ptr bp -> IO (Ptr a)) -> b -> IO (ForeignPtr a) -- | Adding the finalizer to a ForeignPtr seems to be the only way that -- warrants execution of the finalizer (not too early and not never). -- However, the normal ForeignPtr finalizers must be independent from -- Haskell runtime. In contrast to ForeignPtr finalizers, addFinalizer -- adds finalizers to boxes, that are optimized away. Thus finalizers are -- run too early or not at all. Concurrent.ForeignPtr and using threaded -- execution is the only way to get finalizers in Haskell IO. newForeignPtr :: (Storable a) => IO () -> a -> IO (ForeignPtr a) withForeignPtr :: (Storable a, MakeValueTuple a al, Memory al ap) => ForeignPtr a -> (Ptr ap -> IO b) -> IO b -- | Returns 16 Byte aligned piece of memory. Otherwise program crashes -- when vectors are part of the structure. I think that malloc in -- LLVM-2.5 and LLVM-2.6 is simply buggy. -- -- FIXME: Aligning to 16 Byte might not be appropriate for all vector -- types on all platforms. Maybe we should use alignment of Storable -- class in order to determine the right alignment. malloc :: (IsSized a s) => CodeGenFunction r (Value (Ptr a)) free :: (IsSized a s) => Value (Ptr a) -> CodeGenFunction r (Value ()) instance Memory () (Struct ()) instance (IsFirstClass a) => Memory (Value a) a instance (Memory al as, Memory bl bs, Memory cl cs, IsSized as sas, IsSized bs sbs, IsSized cs scs) => Memory (al, bl, cl) (Struct (as, (bs, (cs, ())))) instance (Memory al as, Memory bl bs, IsSized as sas, IsSized bs sbs) => Memory (al, bl) (Struct (as, (bs, ()))) instance Applicative (MemoryElement r o v) instance Functor (MemoryElement r o v) -- | These functions work in arbitrary monads but are especially helpful -- when working with the CodeGenFunction monad. module LLVM.Extra.Monad chain :: (Monad m) => [a -> m a] -> (a -> m a) liftR2 :: (Monad m) => (a -> b -> m c) -> m a -> m b -> m c liftR3 :: (Monad m) => (a -> b -> c -> m d) -> m a -> m b -> m c -> m d module LLVM.Extra.Arithmetic add :: (IsArithmetic a) => Value a -> Value a -> CodeGenFunction r (Value a) sub :: (IsArithmetic a) => Value a -> Value a -> CodeGenFunction r (Value a) inc :: (IsArithmetic a, IsConst a, Num a) => Value a -> CodeGenFunction r (Value a) dec :: (IsArithmetic a, IsConst a, Num a) => Value a -> CodeGenFunction r (Value a) mul :: (IsArithmetic a) => Value a -> Value a -> CodeGenFunction r (Value a) square :: (IsArithmetic a) => Value a -> CodeGenFunction r (Value a) fdiv :: (IsFloating a) => Value a -> Value a -> CodeGenFunction r (Value a) udiv :: (IsInteger a) => Value a -> Value a -> CodeGenFunction r (Value a) urem :: (IsInteger a) => Value a -> Value a -> CodeGenFunction r (Value a) fcmp :: (IsFloating a, CmpRet a b) => FPPredicate -> Value a -> Value a -> CodeGenFunction r (Value b) icmp :: (IsIntegerOrPointer a, CmpRet a b) => IntPredicate -> Value a -> Value a -> CodeGenFunction r (Value b) and :: (IsInteger a) => Value a -> Value a -> CodeGenFunction r (Value a) or :: (IsInteger a) => Value a -> Value a -> CodeGenFunction r (Value a) -- | This would also work for vectors, if LLVM would support -- select with bool vectors as condition. umin :: (IsInteger a, CmpRet a Bool) => Value a -> Value a -> CodeGenFunction r (Value a) umax :: (IsInteger a, CmpRet a Bool) => Value a -> Value a -> CodeGenFunction r (Value a) smin :: (IsInteger a, CmpRet a Bool) => Value a -> Value a -> CodeGenFunction r (Value a) smax :: (IsInteger a, CmpRet a Bool) => Value a -> Value a -> CodeGenFunction r (Value a) sabs :: (IsInteger a, CmpRet a Bool) => Value a -> CodeGenFunction r (Value a) fmin :: (IsFloating a, CmpRet a Bool) => Value a -> Value a -> CodeGenFunction r (Value a) fmax :: (IsFloating a, CmpRet a Bool) => Value a -> Value a -> CodeGenFunction r (Value a) fabs :: (IsFloating a, CmpRet a Bool) => Value a -> CodeGenFunction r (Value a) advanceArrayElementPtr :: Value (Ptr o) -> CodeGenFunction r (Value (Ptr o)) sqrt :: (IsFloating a) => Value a -> CodeGenFunction r (Value a) sin :: (IsFloating a) => Value a -> CodeGenFunction r (Value a) cos :: (IsFloating a) => Value a -> CodeGenFunction r (Value a) exp :: (IsFloating a) => Value a -> CodeGenFunction r (Value a) log :: (IsFloating a) => Value a -> CodeGenFunction r (Value a) pow :: (IsFloating a) => Value a -> Value a -> CodeGenFunction r (Value a) -- | Useful control structures additionally to those in -- LLVM.Util.Loop. module LLVM.Extra.Control arrayLoop :: (Phi a, IsType b, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i Bool) => Value i -> Value (Ptr b) -> a -> (Value (Ptr b) -> a -> CodeGenFunction r a) -> CodeGenFunction r a arrayLoopWithExit :: (Phi s, IsType a, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i Bool) => Value i -> Value (Ptr a) -> s -> (Value (Ptr a) -> s -> CodeGenFunction r (Value Bool, s)) -> CodeGenFunction r (Value i, s) arrayLoop2WithExit :: (Phi s, IsType a, IsType b, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i Bool) => Value i -> Value (Ptr a) -> Value (Ptr b) -> s -> (Value (Ptr a) -> Value (Ptr b) -> s -> CodeGenFunction r (Value Bool, s)) -> CodeGenFunction r (Value i, s) whileLoop :: (Phi a) => a -> (a -> CodeGenFunction r (Value Bool)) -> (a -> CodeGenFunction r a) -> CodeGenFunction r a -- | This construct starts new blocks, so be prepared when continueing -- after an ifThenElse. ifThenElse :: (Phi a) => Value Bool -> CodeGenFunction r a -> CodeGenFunction r a -> CodeGenFunction r a ifThen :: (Phi a) => Value Bool -> a -> CodeGenFunction r a -> CodeGenFunction r a class (Phi a) => Select a select :: (Select a) => Value Bool -> a -> a -> CodeGenFunction r a selectTraversable :: (Select a, Traversable f, Applicative f) => Value Bool -> f a -> f a -> CodeGenFunction r (f a) -- | Branch-free variant of ifThen that is faster if the enclosed -- block is very simply, say, if it contains at most two instructions. It -- can only be used as alternative to ifThen if the enclosed block -- is free of side effects. ifThenSelect :: (Select a) => Value Bool -> a -> CodeGenFunction r a -> CodeGenFunction r a instance (Select a, Select b, Select c) => Select (a, b, c) instance (Select a, Select b) => Select (a, b) instance Select () instance (IsFirstClass a, CmpRet a Bool) => Select (Value a) -- | Maybe datatype implemented in continuation passing style. module LLVM.Extra.MaybeContinuation -- | Isomorphic to ReaderT (CodeGenFunction r z) (ContT z -- (CodeGenFunction r)) a, where the reader provides the block for -- Nothing and the continuation part manages the Just. newtype T r z a Cons :: (CodeGenFunction r z -> (a -> CodeGenFunction r z) -> CodeGenFunction r z) -> T r z a resolve :: T r z a -> CodeGenFunction r z -> (a -> CodeGenFunction r z) -> CodeGenFunction r z map :: (a -> CodeGenFunction r b) -> T r z a -> T r z b -- | counterpart to Data.Maybe.HT.toMaybe withBool :: (Phi z) => Value Bool -> CodeGenFunction r a -> T r z a fromBool :: (Phi z) => CodeGenFunction r (Value Bool, a) -> T r z a toBool :: (Undefined a) => T r (Value Bool, a) a -> CodeGenFunction r (Value Bool, a) lift :: CodeGenFunction r a -> T r z a guard :: (Phi z) => Value Bool -> T r z () bind :: T r z a -> (a -> T r z b) -> T r z b -- | If the returned position is smaller than the array size, then returned -- final state is undefined. arrayLoop :: (Phi s, IsType a, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i Bool) => Value i -> Value (Ptr a) -> s -> (Value (Ptr a) -> s -> T r (Value Bool, s) s) -> CodeGenFunction r (Value i, s) arrayLoop2 :: (Phi s, IsType a, IsType b, Num i, IsConst i, IsInteger i, IsFirstClass i, CmpRet i Bool) => Value i -> Value (Ptr a) -> Value (Ptr b) -> s -> (Value (Ptr a) -> Value (Ptr b) -> s -> T r (Value Bool, (Value (Ptr b), s)) s) -> CodeGenFunction r (Value i, s) instance Monad (T r z) instance Applicative (T r z) instance Functor (T r z) -- | Some special operations on X86 processors. If you want to use them in -- algorithm you will always have to prepare an alternative -- implementation in terms of plain LLVM instructions. You will then run -- them with run and this driver function then selects the most -- advanced of both implementations. Functions that are written this way -- can be found in LLVM.Extra.Vector. Availability of extensions -- is checked with the CPUID instruction. However this does only -- work if you compile code for the host machine, that is cross -- compilation will fail! For cross compilation we would need access to -- the SubTarget detection of LLVM that is only available in the C++ -- interface in version 2.6. module LLVM.Extra.Extension.X86 maxss :: T (VFloat -> VFloat -> CodeGenFunction r VFloat) minss :: T (VFloat -> VFloat -> CodeGenFunction r VFloat) maxps :: T (VFloat -> VFloat -> CodeGenFunction r VFloat) minps :: T (VFloat -> VFloat -> CodeGenFunction r VFloat) maxsd :: T (VDouble -> VDouble -> CodeGenFunction r VDouble) minsd :: T (VDouble -> VDouble -> CodeGenFunction r VDouble) maxpd :: T (VDouble -> VDouble -> CodeGenFunction r VDouble) minpd :: T (VDouble -> VDouble -> CodeGenFunction r VDouble) cmpss :: T (FPPredicate -> VFloat -> VFloat -> CodeGenFunction r (Value (Vector D4 Int32))) cmpps :: T (FPPredicate -> VFloat -> VFloat -> CodeGenFunction r (Value (Vector D4 Int32))) cmpsd :: T (FPPredicate -> VDouble -> VDouble -> CodeGenFunction r (Value (Vector D2 Int64))) cmppd :: T (FPPredicate -> VDouble -> VDouble -> CodeGenFunction r (Value (Vector D2 Int64))) pcmpgtb :: T (Value (Vector D16 Int8) -> Value (Vector D16 Int8) -> CodeGenFunction r (Value (Vector D16 Int8))) pcmpgtw :: T (Value (Vector D8 Int16) -> Value (Vector D8 Int16) -> CodeGenFunction r (Value (Vector D8 Int16))) pcmpgtd :: T (Value (Vector D4 Int32) -> Value (Vector D4 Int32) -> CodeGenFunction r (Value (Vector D4 Int32))) pcmpgtq :: T (Value (Vector D2 Int64) -> Value (Vector D2 Int64) -> CodeGenFunction r (Value (Vector D2 Int64))) pcmpugtb :: T (Value (Vector D16 Word8) -> Value (Vector D16 Word8) -> CodeGenFunction r (Value (Vector D16 Word8))) pcmpugtw :: T (Value (Vector D8 Word16) -> Value (Vector D8 Word16) -> CodeGenFunction r (Value (Vector D8 Word16))) pcmpugtd :: T (Value (Vector D4 Word32) -> Value (Vector D4 Word32) -> CodeGenFunction r (Value (Vector D4 Word32))) pcmpugtq :: T (Value (Vector D2 Word64) -> Value (Vector D2 Word64) -> CodeGenFunction r (Value (Vector D2 Word64))) pminsb :: T (Value (Vector D16 Int8) -> Value (Vector D16 Int8) -> CodeGenFunction r (Value (Vector D16 Int8))) pminsw :: T (Value (Vector D8 Int16) -> Value (Vector D8 Int16) -> CodeGenFunction r (Value (Vector D8 Int16))) pminsd :: T (Value (Vector D4 Int32) -> Value (Vector D4 Int32) -> CodeGenFunction r (Value (Vector D4 Int32))) pmaxsb :: T (Value (Vector D16 Int8) -> Value (Vector D16 Int8) -> CodeGenFunction r (Value (Vector D16 Int8))) pmaxsw :: T (Value (Vector D8 Int16) -> Value (Vector D8 Int16) -> CodeGenFunction r (Value (Vector D8 Int16))) pmaxsd :: T (Value (Vector D4 Int32) -> Value (Vector D4 Int32) -> CodeGenFunction r (Value (Vector D4 Int32))) pminub :: T (Value (Vector D16 Word8) -> Value (Vector D16 Word8) -> CodeGenFunction r (Value (Vector D16 Word8))) pminuw :: T (Value (Vector D8 Word16) -> Value (Vector D8 Word16) -> CodeGenFunction r (Value (Vector D8 Word16))) pminud :: T (Value (Vector D4 Word32) -> Value (Vector D4 Word32) -> CodeGenFunction r (Value (Vector D4 Word32))) pmaxub :: T (Value (Vector D16 Word8) -> Value (Vector D16 Word8) -> CodeGenFunction r (Value (Vector D16 Word8))) pmaxuw :: T (Value (Vector D8 Word16) -> Value (Vector D8 Word16) -> CodeGenFunction r (Value (Vector D8 Word16))) pmaxud :: T (Value (Vector D4 Word32) -> Value (Vector D4 Word32) -> CodeGenFunction r (Value (Vector D4 Word32))) pabsb :: T (Value (Vector D16 Int8) -> CodeGenFunction r (Value (Vector D16 Int8))) pabsw :: T (Value (Vector D8 Int16) -> CodeGenFunction r (Value (Vector D8 Int16))) pabsd :: T (Value (Vector D4 Int32) -> CodeGenFunction r (Value (Vector D4 Int32))) pmuludq :: T (Value (Vector D4 Word32) -> Value (Vector D4 Word32) -> CodeGenFunction r (Value (Vector D2 Word64))) pmulld :: T (Value (Vector D4 Word32) -> Value (Vector D4 Word32) -> CodeGenFunction r (Value (Vector D4 Word32))) cvtps2dq :: T (VFloat -> CodeGenFunction r (Value (Vector D4 Int32))) -- | the upper two integers are set to zero, there is no instruction that -- converts to Int64 cvtpd2dq :: T (VDouble -> CodeGenFunction r (Value (Vector D4 Int32))) -- | MXCSR is not really supported by LLVM-2.6. LLVM does not know about -- the dependency of all floating point operations on this status -- register. ldmxcsr :: T (Value (Ptr Word32) -> CodeGenFunction r (Value ())) stmxcsr :: T (Value (Ptr Word32) -> CodeGenFunction r (Value ())) withMXCSR :: Word32 -> T (CodeGenFunction r a -> CodeGenFunction r a) haddps :: T (VFloat -> VFloat -> CodeGenFunction r VFloat) haddpd :: T (VDouble -> VDouble -> CodeGenFunction r VDouble) dpps :: T (VFloat -> VFloat -> Value Word32 -> CodeGenFunction r VFloat) dppd :: T (VDouble -> VDouble -> Value Word32 -> CodeGenFunction r VDouble) roundss :: T (VFloat -> Value Word32 -> CodeGenFunction r VFloat) roundps :: T (VFloat -> Value Word32 -> CodeGenFunction r VFloat) roundsd :: T (VDouble -> Value Word32 -> CodeGenFunction r VDouble) roundpd :: T (VDouble -> Value Word32 -> CodeGenFunction r VDouble) absss :: T (VFloat -> CodeGenFunction r VFloat) abssd :: T (VDouble -> CodeGenFunction r VDouble) absps :: T (VFloat -> CodeGenFunction r VFloat) abspd :: T (VDouble -> CodeGenFunction r VDouble) module LLVM.Extra.Vector size :: (Nat n) => Value (Vector n a) -> Int sizeInTuple :: (ShuffleMatch n v) => v -> Int -- | Manually assemble a vector of equal values. Better use -- ScalarOrVector.replicate. replicate :: (Access n a va) => a -> CodeGenFunction r va iterate :: (Access n a va) => (a -> CodeGenFunction r a) -> a -> CodeGenFunction r va -- | construct a vector out of single elements -- -- You must assert that the length of the list matches the vector size. assemble :: (Access n a va) => [a] -> CodeGenFunction r va -- | Manually implement vector shuffling using insertelement and -- extractelement. In contrast to LLVM's built-in instruction it supports -- distinct vector sizes, but it allows only one input vector (or a tuple -- of vectors, but we cannot shuffle between them). shuffle :: (Access m a ca, Access n a va) => va -> ConstValue (Vector m Word32) -> CodeGenFunction r ca -- | Rotate one element towards the higher elements. -- -- I don't want to call it rotateLeft or rotateRight, because there is no -- prefered layout for the vector elements. In Intel's instruction manual -- vector elements are indexed like the bits, that is from right to left. -- However, when working with Haskell list and enumeration syntax, the -- start index is left. rotateUp :: (ShuffleMatch n v) => v -> CodeGenFunction r v rotateDown :: (ShuffleMatch n v) => v -> CodeGenFunction r v reverse :: (ShuffleMatch n v) => v -> CodeGenFunction r v shiftUp :: (Access n a v) => a -> v -> CodeGenFunction r (a, v) shiftDown :: (Access n a v) => a -> v -> CodeGenFunction r (a, v) shiftUpMultiZero :: (IsPrimitive a, IsPowerOf2 n) => Int -> Value (Vector n a) -> CodeGenFunction r (Value (Vector n a)) shiftDownMultiZero :: (IsPrimitive a, IsPowerOf2 n) => Int -> Value (Vector n a) -> CodeGenFunction r (Value (Vector n a)) class (IsPowerOf2 n, Phi v) => ShuffleMatch n v | v -> n shuffleMatch :: (ShuffleMatch n v) => ConstValue (Vector n Word32) -> v -> CodeGenFunction r v shuffleMatchTraversable :: (ShuffleMatch n v, Traversable f) => ConstValue (Vector n Word32) -> f v -> CodeGenFunction r (f v) -- | Allow to work on records of vectors as if they are vectors of records. -- This is a reasonable approach for records of different element types -- since processor vectors can only be built from elements of the same -- type. But also say for chunked stereo signal this makes sense. In this -- case we would work on Stereo (Value a). class (ShuffleMatch n v) => Access n a v | v -> a n, a n -> v insert :: (Access n a v) => Value Word32 -> a -> v -> CodeGenFunction r v extract :: (Access n a v) => Value Word32 -> v -> CodeGenFunction r a insertTraversable :: (Access n a v, Traversable f, Applicative f) => Value Word32 -> f a -> f v -> CodeGenFunction r (f v) extractTraversable :: (Access n a v, Traversable f) => Value Word32 -> f v -> CodeGenFunction r (f a) insertChunk :: (Access m a ca, Access n a va) => Int -> ca -> va -> CodeGenFunction r va modify :: (Access n a va) => Value Word32 -> (a -> CodeGenFunction r a) -> (va -> CodeGenFunction r va) -- | Like LLVM.Util.Loop.mapVector but the loop is unrolled, which is -- faster since it can be packed by the code generator. map :: (Access n a va, Access n b vb) => (a -> CodeGenFunction r b) -> (va -> CodeGenFunction r vb) mapChunks :: (Access m a ca, Access m b cb, Access n a va, Access n b vb) => (ca -> CodeGenFunction r cb) -> (va -> CodeGenFunction r vb) zipChunksWith :: (Access m a ca, Access m b cb, Access m c cc, Access n a va, Access n b vb, Access n c vc) => (ca -> cb -> CodeGenFunction r cc) -> (va -> vb -> CodeGenFunction r vc) -- | If the target vector type is a native type then the chop operation -- produces no actual machine instruction. (nop) If the vector cannot be -- evenly divided into chunks the last chunk will be padded with -- undefined values. chop :: (Access m a ca, Access n a va) => va -> [CodeGenFunction r ca] -- | The target size is determined by the type. If the chunk list provides -- more data, the exceeding data is dropped. If the chunk list provides -- too few data, the target vector is filled with undefined elements. concat :: (Access m a ca, Access n a va) => [ca] -> CodeGenFunction r va -- | LLVM.select on boolean vectors cannot be translated to X86 code in -- LLVM-2.6, thus I code my own version that calls select on all -- elements. This is slow but works. When this issue is fixed, this -- function will be replaced by LLVM.select. select :: (IsFirstClass a, IsPrimitive a, IsPowerOf2 n, CmpRet a Bool) => Value (Vector n Bool) -> Value (Vector n a) -> Value (Vector n a) -> CodeGenFunction r (Value (Vector n a)) signedFraction :: (IsFloating a, IsConst a, Real a, IsPowerOf2 n) => Value (Vector n a) -> CodeGenFunction r (Value (Vector n a)) -- | Needs (log n) vector additions cumulate1 :: (IsArithmetic a, IsPrimitive a, IsPowerOf2 n) => Value (Vector n a) -> CodeGenFunction r (Value (Vector n a)) umul32to64 :: (IsPowerOf2 n) => Value (Vector n Word32) -> Value (Vector n Word32) -> CodeGenFunction r (Value (Vector n Word64)) -- | The order of addition is chosen for maximum efficiency. We do not try -- to prevent cancelations. class (IsArithmetic a, IsPrimitive a) => Arithmetic a sum :: (Arithmetic a, IsPowerOf2 n) => Value (Vector n a) -> CodeGenFunction r (Value a) sumToPair :: (Arithmetic a, IsPowerOf2 n) => Value (Vector n a) -> CodeGenFunction r (Value a, Value a) sumInterleavedToPair :: (Arithmetic a, IsPowerOf2 n) => Value (Vector n a) -> CodeGenFunction r (Value a, Value a) cumulate :: (Arithmetic a, IsPowerOf2 n) => Value a -> Value (Vector n a) -> CodeGenFunction r (Value a, Value (Vector n a)) dotProduct :: (Arithmetic a, IsPowerOf2 n) => Value (Vector n a) -> Value (Vector n a) -> CodeGenFunction r (Value a) mul :: (Arithmetic a, IsPowerOf2 n) => Value (Vector n a) -> Value (Vector n a) -> CodeGenFunction r (Value (Vector n a)) -- | Attention: The rounding and fraction functions only work for floating -- point values with maximum magnitude of maxBound :: Int32. -- This way we safe expensive handling of possibly seldom cases. class (Arithmetic a, CmpRet a Bool, IsConst a) => Real a min :: (Real a, IsPowerOf2 n) => Value (Vector n a) -> Value (Vector n a) -> CodeGenFunction r (Value (Vector n a)) max :: (Real a, IsPowerOf2 n) => Value (Vector n a) -> Value (Vector n a) -> CodeGenFunction r (Value (Vector n a)) abs :: (Real a, IsPowerOf2 n) => Value (Vector n a) -> CodeGenFunction r (Value (Vector n a)) truncate :: (Real a, IsPowerOf2 n) => Value (Vector n a) -> CodeGenFunction r (Value (Vector n a)) fraction :: (Real a, IsPowerOf2 n) => Value (Vector n a) -> CodeGenFunction r (Value (Vector n a)) floor :: (Real a, IsPowerOf2 n) => Value (Vector n a) -> CodeGenFunction r (Value (Vector n a)) instance Real Word64 instance Real Word32 instance Real Word16 instance Real Word8 instance Real Int64 instance Real Int32 instance Real Int16 instance Real Int8 instance Real Double instance Real Float instance Arithmetic Word32 instance Arithmetic Word64 instance Arithmetic Word16 instance Arithmetic Word8 instance Arithmetic Int64 instance Arithmetic Int32 instance Arithmetic Int16 instance Arithmetic Int8 instance Arithmetic Double instance Arithmetic Float instance (Access n a0 v0, Access n a1 v1, Access n a2 v2) => Access n (a0, a1, a2) (v0, v1, v2) instance (ShuffleMatch n v0, ShuffleMatch n v1, ShuffleMatch n v2) => ShuffleMatch n (v0, v1, v2) instance (Access n a0 v0, Access n a1 v1) => Access n (a0, a1) (v0, v1) instance (ShuffleMatch n v0, ShuffleMatch n v1) => ShuffleMatch n (v0, v1) instance (IsPowerOf2 n, IsPrimitive a) => Access n (Value a) (Value (Vector n a)) instance (IsPowerOf2 n, IsPrimitive a) => ShuffleMatch n (Value (Vector n a)) -- | Support for unified handling of scalars and vectors. -- -- Attention: The rounding and fraction functions only work for floating -- point values with maximum magnitude of maxBound :: Int32. -- This way we safe expensive handling of possibly seldom cases. module LLVM.Extra.ScalarOrVector class (Real a, IsFloating a) => Fraction a truncate :: (Fraction a) => Value a -> CodeGenFunction r (Value a) fraction :: (Fraction a) => Value a -> CodeGenFunction r (Value a) -- | The fraction has the same sign as the argument. This is not particular -- useful but fast on IEEE implementations. signedFraction :: (Fraction a) => Value a -> CodeGenFunction r (Value a) -- | increment (first operand) may be negative, phase must always be -- non-negative addToPhase :: (Fraction a) => Value a -> Value a -> CodeGenFunction r (Value a) -- | both increment and phase must be non-negative incPhase :: (Fraction a) => Value a -> Value a -> CodeGenFunction r (Value a) class Replicate scalar vector | vector -> scalar replicate :: (Replicate scalar vector) => Value scalar -> CodeGenFunction r (Value vector) replicateConst :: (Replicate scalar vector) => ConstValue scalar -> ConstValue vector replicateOf :: (IsConst a, Replicate a v) => a -> Value v class (IsArithmetic a) => Real a min :: (Real a) => Value a -> Value a -> CodeGenFunction r (Value a) max :: (Real a) => Value a -> Value a -> CodeGenFunction r (Value a) abs :: (Real a) => Value a -> CodeGenFunction r (Value a) instance (IsPowerOf2 n, Real a) => Real (Vector n a) instance Real Word64 instance Real Word32 instance Real Word16 instance Real Word8 instance Real Int64 instance Real Int32 instance Real Int16 instance Real Int8 instance Real FP128 instance Real Double instance Real Float instance (IsPowerOf2 n, IsPrimitive a) => Replicate a (Vector n a) instance Replicate Word64 Word64 instance Replicate Word32 Word32 instance Replicate Word16 Word16 instance Replicate Word8 Word8 instance Replicate Int64 Int64 instance Replicate Int32 Int32 instance Replicate Int16 Int16 instance Replicate Int8 Int8 instance Replicate Bool Bool instance Replicate FP128 FP128 instance Replicate Double Double instance Replicate Float Float instance (IsPowerOf2 n, Real a, IsFloating a, IsConst a) => Fraction (Vector n a) instance Fraction Double instance Fraction Float