diff --git a/cbits/bits.c b/cbits/bits.c
--- a/cbits/bits.c
+++ b/cbits/bits.c
@@ -19,6 +19,7 @@
   uint32_t result = 0;
 
   while (1) {
+    // Mask out all but the lowest bit
     const uint32_t lowest = (-mask & mask);
 
     if (lowest == 0) {
@@ -54,6 +55,7 @@
   uint64_t result = 0;
 
   while (1) {
+    // Mask out all but the lowest bit
     const uint64_t lowest = (-mask & mask);
 
     if (lowest == 0) {
@@ -65,6 +67,70 @@
     result |= lsb & lowest;
     mask &= ~lowest;
     src >>= 1;
+  }
+
+  return result;
+}
+
+uint32_t fast_pext32(
+    uint32_t src,
+    uint32_t mask) {
+  uint32_t result;
+
+  __asm__ __volatile__("pextl  %%ecx,%%ebx,%%eax"
+                       :"=a"(result)
+                       :"a"(result), "b"(src), "c"(mask)
+                       );
+
+  return result;
+}
+
+uint32_t slow_pext32(
+    uint32_t src,
+    uint32_t mask) {
+  uint32_t result = 0;
+  int offset = 0;
+
+  for (int bit = 0; bit != sizeof(uint32_t) * 8; ++bit) {
+    const uint32_t src_bit = (src >> bit) & 1;
+    const uint32_t mask_bit = (mask >> bit) & 1;
+
+    if (mask_bit) {
+      result |= (uint32_t)(src_bit) << offset;
+      ++offset;
+    }
+  }
+
+  return result;
+}
+
+uint64_t fast_pext64(
+    uint64_t src,
+    uint64_t mask) {
+  uint64_t result;
+
+  __asm__ __volatile__("pextq  %%rcx,%%rbx,%%rax"
+                       :"=a"(result)
+                       :"a"(result), "b"(src), "c"(mask)
+                       );
+
+  return result;
+}
+
+uint64_t slow_pext64(
+    uint64_t src,
+    uint64_t mask) {
+  uint64_t result = 0;
+  int offset = 0;
+
+  for (int bit = 0; bit != sizeof(uint64_t) * 8; ++bit) {
+    const uint64_t src_bit = (src >> bit) & 1;
+    const uint64_t mask_bit = (mask >> bit) & 1;
+
+    if (mask_bit) {
+      result |= (uint64_t)(src_bit) << offset;
+      ++offset;
+    }
   }
 
   return result;
diff --git a/hw-prim-bits.cabal b/hw-prim-bits.cabal
--- a/hw-prim-bits.cabal
+++ b/hw-prim-bits.cabal
@@ -1,5 +1,5 @@
 name:                   hw-prim-bits
-version:                0.1.0.2
+version:                0.1.0.3
 synopsis:               Primitive support for bit manipulation
 description:            Please see README.md
 homepage:               https://github.com/githubuser/hw-prim-bits#readme
diff --git a/src/HaskellWorks/Prim/Bits.hs b/src/HaskellWorks/Prim/Bits.hs
--- a/src/HaskellWorks/Prim/Bits.hs
+++ b/src/HaskellWorks/Prim/Bits.hs
@@ -15,3 +15,14 @@
 instance Pdep Word32 where
   pdep = pdep32
   {-# INLINE pdep #-}
+
+class Pext a where
+  pext :: a -> a -> a
+
+instance Pext Word64 where
+  pext = pext64
+  {-# INLINE pext #-}
+
+instance Pext Word32 where
+  pext = pext32
+  {-# INLINE pext #-}
diff --git a/src/HaskellWorks/Prim/Bits/Fast.hs b/src/HaskellWorks/Prim/Bits/Fast.hs
--- a/src/HaskellWorks/Prim/Bits/Fast.hs
+++ b/src/HaskellWorks/Prim/Bits/Fast.hs
@@ -1,6 +1,8 @@
 module HaskellWorks.Prim.Bits.Fast
   ( pdep64
   , pdep32
+  , pext64
+  , pext32
   ) where
 
 import Data.Word
@@ -16,3 +18,15 @@
 pdep32 :: Word32 -> Word32 -> Word32
 pdep32 = fast_pdep32
 {-# INLINE pdep32 #-}
+
+foreign import ccall unsafe "bits.h" fast_pext64 :: Word64 -> Word64 -> Word64
+
+pext64 :: Word64 -> Word64 -> Word64
+pext64 = fast_pext64
+{-# INLINE pext64 #-}
+
+foreign import ccall unsafe "bits.h" fast_pext32 :: Word32 -> Word32 -> Word32
+
+pext32 :: Word32 -> Word32 -> Word32
+pext32 = fast_pext32
+{-# INLINE pext32 #-}
diff --git a/src/HaskellWorks/Prim/Bits/Slow.hs b/src/HaskellWorks/Prim/Bits/Slow.hs
--- a/src/HaskellWorks/Prim/Bits/Slow.hs
+++ b/src/HaskellWorks/Prim/Bits/Slow.hs
@@ -1,6 +1,8 @@
 module HaskellWorks.Prim.Bits.Slow
   ( pdep64
   , pdep32
+  , pext64
+  , pext32
   ) where
 
 import Data.Word
@@ -16,3 +18,15 @@
 pdep32 :: Word32 -> Word32 -> Word32
 pdep32 = slow_pdep32
 {-# INLINE pdep32 #-}
+
+foreign import ccall unsafe "bits.h" slow_pext64 :: Word64 -> Word64 -> Word64
+
+pext64 :: Word64 -> Word64 -> Word64
+pext64 = slow_pext64
+{-# INLINE pext64 #-}
+
+foreign import ccall unsafe "bits.h" slow_pext32 :: Word32 -> Word32 -> Word32
+
+pext32 :: Word32 -> Word32 -> Word32
+pext32 = slow_pext32
+{-# INLINE pext32 #-}
diff --git a/test/HaskellWorks/Prim/BitsSpec.hs b/test/HaskellWorks/Prim/BitsSpec.hs
--- a/test/HaskellWorks/Prim/BitsSpec.hs
+++ b/test/HaskellWorks/Prim/BitsSpec.hs
@@ -22,3 +22,11 @@
     a <- forAll $ G.word32 R.constantBounded
     b <- forAll $ G.word32 R.constantBounded
     S.pdep32 a b === F.pdep32 a b
+  it "pext64 behaves the same" $ require $ property $ do
+    a <- forAll $ G.word64 R.constantBounded
+    b <- forAll $ G.word64 R.constantBounded
+    S.pext64 a b === F.pext64 a b
+  it "pext32 behaves the same" $ require $ property $ do
+    a <- forAll $ G.word32 R.constantBounded
+    b <- forAll $ G.word32 R.constantBounded
+    S.pext32 a b === F.pext32 a b
