diff --git a/llvm-extra.cabal b/llvm-extra.cabal
--- a/llvm-extra.cabal
+++ b/llvm-extra.cabal
@@ -1,5 +1,5 @@
 Name:           llvm-extra
-Version:        0.7.2
+Version:        0.7.3
 License:        BSD3
 License-File:   LICENSE
 Author:         Henning Thielemann <haskell@henning-thielemann.de>
@@ -29,6 +29,10 @@
   * various kinds of loops (while) and condition structures (if-then-else)
     in "LLVM.Extra.Control"
   .
+  * more functional loop construction using "LLVM.Extra.Iterator"
+  .
+  * complex Haskell values mapped to LLVM values in "LLVM.Extra.Multi.Value"
+  .
   * automatic adaption to target specific extensions,
     currently used for access of vector operations
     that are specific to an SSE level on x86 processors
@@ -71,7 +75,7 @@
   default:     True
 
 Source-Repository this
-  Tag:         0.7.2
+  Tag:         0.7.3
   Type:        darcs
   Location:    http://code.haskell.org/~thielema/llvm-extra/
 
@@ -87,6 +91,7 @@
     tfp >=1.0 && <1.1,
     non-empty >=0.2.1 && <0.4,
     containers >=0.1 && <0.6,
+    bifunctors >=5.4 && <6,
     transformers >=0.1.1 && <0.6,
     utility-ht >=0.0.1 && <0.1
 
@@ -124,6 +129,8 @@
     LLVM.Extra.Scalar
     LLVM.Extra.Vector
     LLVM.Extra.ScalarOrVector
+    LLVM.Extra.Iterator
+    LLVM.Extra.Multi.Iterator
     LLVM.Extra.Multi.Value
     LLVM.Extra.Multi.Value.Memory
     LLVM.Extra.Multi.Vector
diff --git a/src/Array.hs b/src/Array.hs
--- a/src/Array.hs
+++ b/src/Array.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
 module Main where
 
 import LLVM.Extra.Control (arrayLoop, )
@@ -12,20 +13,21 @@
 import qualified LLVM.Extra.Class as Class
 import qualified LLVM.Extra.Arithmetic as A
 
+import qualified LLVM.ExecutionEngine as EE
 import qualified LLVM.Core as LLVM
+import LLVM.ExecutionEngine (simpleFunction, )
 import LLVM.Core
          (Value, valueOf, value, constOf, undef, zero, add, sub, mul, frem,
           createFunction, Function, Linkage(ExternalLinkage), ret,
           CodeGenModule, CodeGenFunction, store,
           Vector, extractelement, insertelement, shufflevector, )
-import LLVM.ExecutionEngine (simpleFunction, )
 import qualified System.IO as IO
 
 import Type.Data.Num.Decimal(D4, )
 import Data.Word (Word32, )
 import qualified Foreign.Storable as St
 import Foreign.Marshal.Array (allocaArray, )
-import Foreign.Ptr (Ptr, )
+import Foreign.Ptr (FunPtr, Ptr, )
 
 import qualified Data.Empty as Empty
 import Data.NonEmpty ((!:), )
@@ -72,7 +74,8 @@
 
 would not work, because Vector is not of type Generic.
 -}
-mChorusVectorArg :: CodeGenModule (Function (Word32 -> Ptr Float -> Vector D4 Float -> IO Float))
+mChorusVectorArg ::
+  CodeGenModule (Function (Word32 -> Ptr Float -> Vector D4 Float -> IO Float))
 mChorusVectorArg =
   createFunction ExternalLinkage $ \ size ptr freq -> do
     const1 <- constVec 1
@@ -143,7 +146,10 @@
     z <- Ext.runUnsafe X86.dpps x y (valueOf 0xF1)
     extractelement z (valueOf 0)
 
-mChorusVector :: CodeGenModule (Function (Word32 -> Ptr Float -> Float -> Float -> Float -> Float -> IO Float))
+mChorusVector ::
+  CodeGenModule
+    (Function
+      (Word32 -> Ptr Float -> Float -> Float -> Float -> Float -> IO Float))
 mChorusVector =
   createFunction ExternalLinkage $ \ size ptr f0 f1 f2 f3 -> do
     freq <- Vector.assemble [f0,f1,f2,f3]
@@ -164,7 +170,10 @@
 osciSaw freq phase =
   liftM2 (,) (waveSaw phase) (SoV.incPhase freq phase)
 
-mChorus :: CodeGenModule (Function (Word32 -> Ptr Float -> Float -> Float -> Float -> Float -> IO Float))
+mChorus ::
+  CodeGenModule
+    (Function
+      (Word32 -> Ptr Float -> Float -> Float -> Float -> Float -> IO Float))
 mChorus =
   createFunction ExternalLinkage $ \ size ptr f0 f1 f2 f3 -> do
     s <- arrayLoop size ptr Class.zeroTuple $
@@ -207,7 +216,10 @@
      c <- add a b
      return (c, (s1,t1))
 
-mChorusMonadic :: CodeGenModule (Function (Word32 -> Ptr Float -> Float -> Float -> Float -> Float -> IO Float))
+mChorusMonadic ::
+  CodeGenModule
+    (Function
+      (Word32 -> Ptr Float -> Float -> Float -> Float -> Float -> IO Float))
 mChorusMonadic =
   createFunction ExternalLinkage $ \ size ptr f0 f1 f2 f3 -> do
     s <- arrayLoop size ptr Class.zeroTuple $
@@ -220,13 +232,28 @@
       return phases'
     ret (fst (fst s))
 
-renderChorus :: IO ()
-renderChorus = do
+
+type Importer func = FunPtr func -> func
+
+generateFunction ::
+  EE.ExecutionFunction f =>
+  Importer f -> CodeGenModule (Function f) -> IO f
+generateFunction imprt code = do
   m <- LLVM.newModule
-  _f <- LLVM.defineModule m mChorusVector
+  fill <- do
+    func <- LLVM.defineModule m $ LLVM.setTarget LLVM.hostTriple >> code
+    EE.runEngineAccessWithModule m $ EE.getExecutionFunction imprt func
   LLVM.writeBitcodeToFile "array.bc" m
+  return fill
 
-  fill <- simpleFunction mChorusVector
+
+foreign import ccall safe "dynamic" derefChorusPtr ::
+  Importer
+    (Word32 -> Ptr Float -> Float -> Float -> Float -> Float -> IO Float)
+
+renderChorus :: IO ()
+renderChorus = do
+  fill <- generateFunction derefChorusPtr mChorusVector
   IO.withFile "speedtest.f32" IO.WriteMode $ \h ->
     let len = 10000000
     in  allocaArray len $ \ ptr ->
@@ -243,9 +270,12 @@
       return phase'
     ret (s :: Value Float)
 
+foreign import ccall safe "dynamic" derefSawPtr ::
+  Importer (Word32 -> Ptr Float -> Float -> IO Float)
+
 renderSaw :: IO ()
 renderSaw = do
-  fill <- simpleFunction mSaw
+  fill <- generateFunction derefSawPtr mSaw
   IO.withFile "speedtest.f32" IO.WriteMode $ \h ->
     let len = 10000000
     in  allocaArray len $ \ ptr ->
diff --git a/src/LLVM/Extra/Control.hs b/src/LLVM/Extra/Control.hs
--- a/src/LLVM/Extra/Control.hs
+++ b/src/LLVM/Extra/Control.hs
@@ -211,6 +211,10 @@
    return state
 
 
+{- |
+This is a loop with a single point for exit from within the loop.
+The @Bool@ value indicates whether the loop shall be continued.
+-}
 loopWithExit ::
    Phi a =>
    a ->
diff --git a/src/LLVM/Extra/Iterator.hs b/src/LLVM/Extra/Iterator.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Extra/Iterator.hs
@@ -0,0 +1,251 @@
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE TypeFamilies #-}
+module LLVM.Extra.Iterator where
+
+import qualified LLVM.Extra.MaybeContinuation as MaybeCont
+import qualified LLVM.Extra.Maybe as Maybe
+
+import qualified LLVM.Extra.ArithmeticPrivate as A
+import qualified LLVM.Extra.Class as Class
+import qualified LLVM.Extra.Control as C
+import qualified LLVM.Core as LLVM
+import LLVM.Util.Loop (Phi, )
+import LLVM.Core
+   (CodeGenFunction, Value, value, valueOf,
+    CmpRet, CmpResult, IsInteger, IsType, IsConst, )
+
+import Foreign.Ptr (Ptr, )
+
+import qualified Control.Monad.Trans.State as MS
+import qualified Control.Applicative as App
+import qualified Control.Functor.HT as FuncHT
+import Control.Monad (void, (<=<), )
+import Control.Applicative (Applicative, liftA2, (<$>), (<$), )
+
+import Data.Tuple.HT (mapFst, mapSnd, )
+
+import Prelude hiding (iterate, takeWhile, take, mapM)
+
+
+{- |
+Simulates a non-strict list.
+-}
+data T r a =
+   forall s. (Phi s) =>
+   Cons s (forall z. (Phi z) => s -> MaybeCont.T r z (a,s))
+
+mapM_ :: (a -> CodeGenFunction r ()) -> T r a -> CodeGenFunction r ()
+mapM_ f (Cons s next) =
+   void $
+   C.loopWithExit s
+      (\s0 ->
+         MaybeCont.resolve (next s0)
+            (return (valueOf False, s0))
+            (\(a,s1) -> (valueOf True, s1) <$ f a))
+      return
+
+mapState_ ::
+   (Phi t) =>
+   (a -> t -> CodeGenFunction r t) ->
+   T r a -> t -> CodeGenFunction r t
+mapState_ f (Cons s next) t =
+   snd <$>
+   C.loopWithExit (s,t)
+      (\(s0,t0) ->
+         MaybeCont.resolve (next s0)
+            (return (valueOf False, (s0,t0)))
+            (\(a,s1) -> (\t1 -> (valueOf True, (s1,t1))) <$> f a t0))
+      return
+
+mapStateM_ ::
+   (Phi t) =>
+   (a -> MS.StateT t (CodeGenFunction r) ()) ->
+   T r a -> MS.StateT t (CodeGenFunction r) ()
+mapStateM_ f xs =
+   MS.StateT $ \t ->
+      (,) () <$> mapState_ (\a t0 -> snd <$> MS.runStateT (f a) t0) xs t
+
+
+mapWhileState_ ::
+   (Phi t) =>
+   (a -> t -> CodeGenFunction r (Value Bool, t)) ->
+   T r a -> t -> CodeGenFunction r t
+mapWhileState_ f (Cons s next) t =
+   snd <$>
+   C.loopWithExit (s,t)
+      (\(s0,t0) ->
+         MaybeCont.resolve (next s0)
+            (return (valueOf False, (s0,t0)))
+            (\(a,s1) -> (\(b,t1) -> (b, (s1,t1))) <$> f a t0))
+      return
+
+
+empty :: T r a
+empty = Cons () (\() -> MaybeCont.nothing)
+
+singleton :: a -> T r a
+singleton a =
+   Cons
+      (valueOf True)
+      (\running -> MaybeCont.guard running >> return (a, valueOf False))
+
+
+instance Functor (T r) where
+   fmap f (Cons s next) = Cons s (\s0 -> mapFst f <$> next s0)
+
+{- |
+@ZipList@ semantics
+-}
+instance Applicative (T r) where
+   pure a = Cons () (\() -> return (a,()))
+   Cons fs fnext <*> Cons as anext =
+      Cons (fs,as)
+         (\(fs0,as0) -> do
+            (f,fs1) <- fnext fs0
+            (a,as1) <- anext as0
+            return (f a, (fs1,as1)))
+
+
+{-
+On the one hand,
+I did not want to name it @map@ because it differs from @fmap@.
+On the other hand, @mapM@ does not fit very well
+because the result is not in the CodeGenFunction monad.
+-}
+mapM :: (a -> CodeGenFunction r b) -> T r a -> T r b
+mapM f (Cons s next) = Cons s (MaybeCont.lift . FuncHT.mapFst f <=< next)
+
+mapMaybe ::
+   (Phi b, Class.Undefined b) =>
+   (a -> CodeGenFunction r (Maybe.T b)) -> T r a -> T r b
+mapMaybe f = catMaybes . mapM f
+
+catMaybes :: (Phi a, Class.Undefined a) => T r (Maybe.T a) -> T r a
+catMaybes (Cons s next) =
+   Cons s
+      (\s0 ->
+         MaybeCont.fromMaybe $
+         fmap (\(ma,s2) -> fmap (flip (,) s2) ma) $
+         C.loopWithExit s0
+            (\s1 ->
+               MaybeCont.resolve (next s1)
+                  (return (valueOf False, (Maybe.nothing, s1)))
+                  (\(ma,s2) ->
+                     Maybe.run ma
+                        (return (valueOf True, (Maybe.nothing, s2)))
+                        (\a -> return (valueOf False, (Maybe.just a, s2)))))
+            (return . snd))
+
+takeWhile :: (a -> CodeGenFunction r (Value Bool)) -> T r a -> T r a
+takeWhile p (Cons s next) =
+   Cons s
+      (\s0 -> do
+         (a,s1) <- next s0
+         MaybeCont.guard =<< MaybeCont.lift (p a)
+         return (a,s1))
+
+{- |
+Attention:
+This always performs one function call more than necessary.
+I.e. if 'f' reads from or writes to memory
+make sure that accessing one more pointer is legal.
+-}
+iterate :: (Phi a) => (a -> CodeGenFunction r a) -> a -> T r a
+iterate f a = Cons a (\a0 -> MaybeCont.lift $ fmap ((,) a0) $ f a0)
+
+{- |
+This is MaybeCont.toMaybe' where @('Undefined' a)@ constraint
+is replaced by a custom value.
+This way, we do not need 'Undefined' constraint in 'T'.
+On the other hand, an LLVM-undefined value would enable more LLVM optimizations.
+-}
+maybeFromCont ::
+   a -> MaybeCont.T r (Maybe.T a) a -> CodeGenFunction r (Maybe.T a)
+maybeFromCont undef (MaybeCont.Cons m) =
+   m (return $ Maybe.Cons (valueOf False) undef) (return . Maybe.just)
+
+cartesianAux ::
+   (Phi a, Phi b, Class.Undefined a, Class.Undefined b) =>
+   T r a -> T r b -> T r (Maybe.T (a,b))
+cartesianAux (Cons sa nextA) (Cons sb nextB) =
+   Cons (Maybe.nothing,sa,sb)
+      (\(ma0,sa0,sb0) -> do
+         (a1,sa1) <-
+            MaybeCont.fromMaybe $
+            Maybe.run ma0
+               (maybeFromCont (Class.undefTuple,sa0) $ nextA sa0)
+               (\a0 -> return (Maybe.just (a0,sa0)))
+         MaybeCont.lift $
+            MaybeCont.resolve (nextB sb0)
+               (return (Maybe.nothing,(Maybe.nothing,sa1,sb)))
+               (\(b1,sb1) ->
+                  return (Maybe.just (a1,b1), (Maybe.just a1, sa1, sb1))))
+
+
+-- * helper functions
+
+cartesian ::
+   (Phi a, Phi b, Class.Undefined a, Class.Undefined b) =>
+   T r a -> T r b -> T r (a,b)
+cartesian as bs = catMaybes $ cartesianAux as bs
+
+countDown ::
+   (Num i, IsConst i, IsInteger i, CmpRet i, CmpResult i ~ Bool) =>
+   Value i -> T r (Value i)
+countDown len =
+   takeWhile (A.cmp LLVM.CmpLT (value LLVM.zero)) $ iterate A.dec len
+
+take ::
+   (Num i, IsConst i, IsInteger i, CmpRet i, CmpResult i ~ Bool) =>
+   Value i -> T r a -> T r a
+take len xs = liftA2 const xs (countDown len)
+
+arrayPtrs :: (IsType a) => Value (Ptr a) -> T r (Value (Ptr a))
+arrayPtrs = iterate A.advanceArrayElementPtr
+
+
+-- * examples
+
+fixedLengthLoop ::
+   (Phi s,
+    Num i, IsConst i, IsInteger i, CmpRet i, CmpResult i ~ Bool) =>
+   Value i -> s ->
+   (s -> CodeGenFunction r s) ->
+   CodeGenFunction r s
+fixedLengthLoop len start loopBody =
+   mapState_ (const loopBody) (countDown len) start
+
+arrayLoop ::
+   (Phi a, IsType b,
+    Num i, IsConst i, IsInteger i, CmpRet i, CmpResult i ~ Bool) =>
+   Value i -> Value (Ptr b) -> a ->
+   (Value (Ptr b) -> a -> CodeGenFunction r a) ->
+   CodeGenFunction r a
+arrayLoop len ptr start loopBody =
+   mapState_ loopBody (take len $ arrayPtrs ptr) start
+
+arrayLoopWithExit ::
+   (Phi s, IsType a,
+    Num i, IsConst i, IsInteger i, CmpRet i, CmpResult i ~ Bool) =>
+   Value i -> Value (Ptr a) -> s ->
+   (Value (Ptr a) -> s -> CodeGenFunction r (Value Bool, s)) ->
+   CodeGenFunction r (Value i, s)
+arrayLoopWithExit len ptr0 start loopBody = do
+   (i, end) <-
+      mapWhileState_
+         (\(i,ptr) (_i,s) -> mapSnd ((,) i) <$> loopBody ptr s)
+         (liftA2 (,) (countDown len) (arrayPtrs ptr0))
+         (len,start)
+   pos <- A.sub len i
+   return (pos, end)
+
+arrayLoop2 ::
+   (Phi s, IsType a, IsType b,
+    Num i, IsConst i, IsInteger i, CmpRet i, CmpResult i ~ Bool) =>
+   Value i -> Value (Ptr a) -> Value (Ptr b) -> s ->
+   (Value (Ptr a) -> Value (Ptr b) -> s -> CodeGenFunction r s) ->
+   CodeGenFunction r s
+arrayLoop2 len ptrA ptrB start loopBody =
+   mapState_ (uncurry loopBody)
+      (take len $ liftA2 (,) (arrayPtrs ptrA) (arrayPtrs ptrB)) start
diff --git a/src/LLVM/Extra/MaybeContinuation.hs b/src/LLVM/Extra/MaybeContinuation.hs
--- a/src/LLVM/Extra/MaybeContinuation.hs
+++ b/src/LLVM/Extra/MaybeContinuation.hs
@@ -118,13 +118,11 @@
 guard b = Cons $ \n j ->
    ifThenElse b (j ()) n
 
-{-
-just :: CodeGenFunction r a -> T r z a
-just a = Cons $ \ _n j -> j =<< a
+just :: a -> T r z a
+just a = Cons $ \ _n j -> j a
 
 nothing :: T r z a
-nothing = Cons \n _j -> n
--}
+nothing = Cons $ \n _j -> n
 
 bind ::
    T r z a ->
diff --git a/src/LLVM/Extra/Memory.hs b/src/LLVM/Extra/Memory.hs
--- a/src/LLVM/Extra/Memory.hs
+++ b/src/LLVM/Extra/Memory.hs
@@ -46,9 +46,9 @@
 import Data.Word (Word8, Word16, Word32, Word64, )
 import Data.Int  (Int8,  Int16,  Int32,  Int64, )
 
+import qualified Control.Applicative as App
 import Control.Monad (ap, )
 import Control.Applicative (pure, liftA2, liftA3, )
-import qualified Control.Applicative as App
 
 import Data.Tuple.HT (fst3, snd3, thd3, )
 
diff --git a/src/LLVM/Extra/Multi/Iterator.hs b/src/LLVM/Extra/Multi/Iterator.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Extra/Multi/Iterator.hs
@@ -0,0 +1,39 @@
+module LLVM.Extra.Multi.Iterator (
+   takeWhile,
+   countDown,
+   take,
+   ) where
+
+import qualified LLVM.Extra.Multi.Value as MultiValue
+import qualified LLVM.Extra.Iterator as Iter
+
+import qualified LLVM.Core as LLVM
+import LLVM.Core (CodeGenFunction)
+
+import Control.Applicative (liftA2)
+
+import Prelude hiding (take, takeWhile)
+
+
+
+takeWhile ::
+   (a -> CodeGenFunction r (MultiValue.T Bool)) ->
+   Iter.T r a -> Iter.T r a
+takeWhile p = Iter.takeWhile (fmap unpackBool . p)
+
+unpackBool :: MultiValue.T Bool -> LLVM.Value Bool
+unpackBool (MultiValue.Cons b) = b
+
+countDown ::
+   (MultiValue.Additive i, MultiValue.Comparison i,
+    MultiValue.IntegerConstant i) =>
+   MultiValue.T i -> Iter.T r (MultiValue.T i)
+countDown len =
+   takeWhile (MultiValue.cmp LLVM.CmpLT MultiValue.zero) $
+   Iter.iterate MultiValue.dec len
+
+take ::
+   (MultiValue.Additive i, MultiValue.Comparison i,
+    MultiValue.IntegerConstant i) =>
+   MultiValue.T i -> Iter.T r a -> Iter.T r a
+take len xs = liftA2 const xs (countDown len)
diff --git a/src/LLVM/Extra/Multi/Value.hs b/src/LLVM/Extra/Multi/Value.hs
--- a/src/LLVM/Extra/Multi/Value.hs
+++ b/src/LLVM/Extra/Multi/Value.hs
@@ -26,7 +26,8 @@
 import Data.Complex (Complex((:+)))
 import Data.Function (id, (.), ($), )
 import Data.Tuple.HT (uncurry3, )
-import Data.Bool (Bool, )
+import Data.Maybe (Maybe(Nothing,Just), )
+import Data.Bool (Bool(False,True), )
 import Data.Word (Word8, Word16, Word32, Word64, )
 import Data.Int (Int8, Int16, Int32, Int64, )
 
@@ -208,6 +209,34 @@
 addPhisUnit _bb (Cons ()) (Cons ()) = return ()
 
 
+instance (C a) => C (Maybe a) where
+   type Repr f (Maybe a) = (f Bool, Repr f a)
+   cons Nothing = nothing
+   cons (Just a) = just $ cons a
+   undef = toMaybe undef undef
+   zero = toMaybe (cons False) zero
+   phis bb ma =
+      case splitMaybe ma of
+         (b,a) -> Monad.lift2 toMaybe (phis bb b) (phis bb a)
+   addPhis bb x y =
+      case (splitMaybe x, splitMaybe y) of
+         ((xb,xa), (yb,ya)) ->
+            addPhis bb xb yb >>
+            addPhis bb xa ya
+
+splitMaybe :: T (Maybe a) -> (T Bool, T a)
+splitMaybe (Cons (b,a)) = (Cons b, Cons a)
+
+toMaybe :: T Bool -> T a -> T (Maybe a)
+toMaybe (Cons b) (Cons a) = Cons (b,a)
+
+nothing :: (C a) => T (Maybe a)
+nothing = toMaybe (cons False) undef
+
+just :: T a -> T (Maybe a)
+just = toMaybe (cons True)
+
+
 instance (C a, C b) => C (a,b) where
    type Repr f (a, b) = (Repr f a, Repr f b)
    cons (a,b) = zip (cons a) (cons b)
@@ -626,7 +655,12 @@
    sub = sub
    neg = neg
 
+inc, dec ::
+   (Additive i, IntegerConstant i) => T i -> LLVM.CodeGenFunction r (T i)
+inc = add (fromInteger' 1)
+dec = sub (fromInteger' 1)
 
+
 class (Additive a) => PseudoRing a where
    mul :: T a -> T a -> LLVM.CodeGenFunction r (T a)
 
@@ -938,17 +972,61 @@
    inv :: T a -> LLVM.CodeGenFunction r (T a)
 
 instance Logic Bool where
-   and = liftM2 LLVM.and
-   or = liftM2 LLVM.or
-   xor = liftM2 LLVM.xor
-   inv = liftM LLVM.inv
+   and = liftM2 LLVM.and; or = liftM2 LLVM.or
+   xor = liftM2 LLVM.xor; inv = liftM LLVM.inv
 
+instance Logic Word8 where
+   and = liftM2 LLVM.and; or = liftM2 LLVM.or
+   xor = liftM2 LLVM.xor; inv = liftM LLVM.inv
 
+instance Logic Word16 where
+   and = liftM2 LLVM.and; or = liftM2 LLVM.or
+   xor = liftM2 LLVM.xor; inv = liftM LLVM.inv
+
+instance Logic Word32 where
+   and = liftM2 LLVM.and; or = liftM2 LLVM.or
+   xor = liftM2 LLVM.xor; inv = liftM LLVM.inv
+
+instance Logic Word64 where
+   and = liftM2 LLVM.and; or = liftM2 LLVM.or
+   xor = liftM2 LLVM.xor; inv = liftM LLVM.inv
+
+
 instance Logic a => A.Logic (T a) where
    and = and
    or = or
    xor = xor
    inv = inv
+
+
+
+class BitShift a where
+   shl :: T a -> T a -> LLVM.CodeGenFunction r (T a)
+   shr :: T a -> T a -> LLVM.CodeGenFunction r (T a)
+
+instance BitShift Word8 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr
+
+instance BitShift Word16 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr
+
+instance BitShift Word32 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr
+
+instance BitShift Word64 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr
+
+instance BitShift Int8 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.ashr
+
+instance BitShift Int16 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.ashr
+
+instance BitShift Int32 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.ashr
+
+instance BitShift Int64 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.ashr
 
 
 
diff --git a/src/LLVM/Extra/Multi/Vector.hs b/src/LLVM/Extra/Multi/Vector.hs
--- a/src/LLVM/Extra/Multi/Vector.hs
+++ b/src/LLVM/Extra/Multi/Vector.hs
@@ -44,6 +44,7 @@
    FloatingComparison(..),
    Comparison(..),
    Logic(..),
+   BitShift(..),
    ) where
 
 import qualified LLVM.Extra.Multi.Value as MultiValue
@@ -71,7 +72,8 @@
 import Data.Tuple (snd, )
 import Data.Maybe (maybe, )
 import Data.List (take, (++), )
-import Data.Word (Word32, )
+import Data.Word (Word8, Word16, Word32, Word64, )
+import Data.Int (Int8, Int16, Int32, Int64, )
 import Data.Bool (Bool, )
 
 import qualified Control.Applicative as App
@@ -767,3 +769,33 @@
    or = or
    xor = xor
    inv = inv
+
+
+
+class BitShift a where
+   shl :: (TypeNum.Positive n) => T n a -> T n a -> LLVM.CodeGenFunction r (T n a)
+   shr :: (TypeNum.Positive n) => T n a -> T n a -> LLVM.CodeGenFunction r (T n a)
+
+instance BitShift Word8 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr
+
+instance BitShift Word16 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr
+
+instance BitShift Word32 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr
+
+instance BitShift Word64 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.lshr
+
+instance BitShift Int8 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.ashr
+
+instance BitShift Int16 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.ashr
+
+instance BitShift Int32 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.ashr
+
+instance BitShift Int64 where
+   shl = liftM2 LLVM.shl; shr = liftM2 LLVM.ashr
