{-# LANGUAGE CPP #-}

module HaskellWorks.Data.RankSelect.Base.Internal
    ( select1Word64Broadword
    , select1Word64Bmi2
    , select1Word64Bmi2Base0
    , select1Word64
    , select1Word32Broadword
    , select1Word32Bmi2
    , select1Word32
    ) where

import Data.Bits                      (countTrailingZeros, shiftR)
import Data.Bits.Pdep
import Data.Int
import Data.Word
import HaskellWorks.Data.Bits.BitWise
import HaskellWorks.Data.Int.Narrow

select1Word64Bmi2Base0 :: Word64 -> Word64 -> Word64
select1Word64Bmi2Base0 :: Word64 -> Word64 -> Word64
select1Word64Bmi2Base0 Word64
w Word64
r = Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int
forall b. FiniteBits b => b -> Int
countTrailingZeros (Word64 -> Word64 -> Word64
forall a. Pdep a => a -> a -> a
pdep (Word64
1 Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.<. Word64
r) Word64
w))
{-# INLINE select1Word64Bmi2Base0 #-}

select1Word64Bmi2 :: Word64 -> Word64 -> Word64
select1Word64Bmi2 :: Word64 -> Word64 -> Word64
select1Word64Bmi2 Word64
w Word64
r =
  let zeros :: Int
zeros = Word64 -> Int
forall b. FiniteBits b => b -> Int
countTrailingZeros (Word64 -> Word64 -> Word64
forall a. Pdep a => a -> a -> a
pdep (Word64
1 Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.<. (Word64
r Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
1)) Word64
w) :: Int
      mask :: Word64
mask  = Int64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
zeros Int -> Word64 -> Int
forall a. Shift a => a -> Word64 -> a
.<. Word64
57) :: Int64) Int64 -> Int -> Int64
forall a. Bits a => a -> Int -> a
`shiftR` Int
63) :: Word64
  in (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
zeros Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.|. Word64
mask) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
1
{-# INLINE select1Word64Bmi2 #-}

select1Word32Bmi2 :: Word32 -> Word64 -> Word64
select1Word32Bmi2 :: Word32 -> Word64 -> Word64
select1Word32Bmi2 Word32
w Word64
r =
  let zeros :: Int
zeros = Word32 -> Int
forall b. FiniteBits b => b -> Int
countTrailingZeros (Word32 -> Word32 -> Word32
forall a. Pdep a => a -> a -> a
pdep (Word32
1 Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.<. (Word64
r Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
1)) Word32
w) :: Int
      mask :: Word64
mask  = Int64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
zeros Int -> Word64 -> Int
forall a. Shift a => a -> Word64 -> a
.<. Word64
58) :: Int64) Int64 -> Int -> Int64
forall a. Bits a => a -> Int -> a
`shiftR` Int
63) :: Word64
  in (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
zeros Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.|. Word64
mask) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
1
{-# INLINE select1Word32Bmi2 #-}

select1Word64Broadword :: Word64 -> Word64 -> Word64
select1Word64Broadword :: Word64 -> Word64 -> Word64
select1Word64Broadword Word64
_ Word64
0 = Word64
0
select1Word64Broadword Word64
v Word64
rn =
  -- Do a normal parallel bit count for a 64-bit integer,
  -- but store all intermediate steps.
  let a :: Word64
a = (Word64
v Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x5555555555555555) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ ((Word64
v Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>.  Word64
1) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x5555555555555555)    in
  let b :: Word64
b = (Word64
a Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x3333333333333333) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ ((Word64
a Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>.  Word64
2) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x3333333333333333)    in
  let c :: Word64
c = (Word64
b Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x0f0f0f0f0f0f0f0f) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ ((Word64
b Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>.  Word64
4) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x0f0f0f0f0f0f0f0f)    in
  let d :: Word64
d = (Word64
c Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x00ff00ff00ff00ff) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ ((Word64
c Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>.  Word64
8) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x00ff00ff00ff00ff)    in
  let e :: Word64
e = (Word64
d Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x0000ffff0000ffff) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ ((Word64
d Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
16) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x0000ffff0000ffff)    in
  let f :: Word64
f = (Word64
e Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x00000000ffffffff) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ ((Word64
e Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
32) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x00000000ffffffff)    in
  -- Now do branchless select!
  let r0 :: Word64
r0 = Word64
f Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64 -> Narrowed64 Word64
forall a. Narrow64 a => a -> Narrowed64 a
narrow64 Word64
rn                                                in
  let s0 :: Word64
s0 = Word64
64 :: Word64                                                       in
  let t0 :: Word64
t0 = (Word64
d Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
32) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ (Word64
d Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
48)                                            in
  let s1 :: Word64
s1 = Word64
s0 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- ((Word64
t0 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
r0) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
256) Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
3                                     in
  let r1 :: Word64
r1 = Word64
r0 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- (Word64
t0 Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. ((Word64
t0 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
r0) Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
8))                                    in
  let t1 :: Word64
t1 =      (Word64
d Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
s1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
16)) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0xff                       in
  let s2 :: Word64
s2 = Word64
s1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- ((Word64
t1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
r1) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
256) Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
4                                     in
  let r2 :: Word64
r2 = Word64
r1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- (Word64
t1 Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. ((Word64
t1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
r1) Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
8))                                    in
  let t2 :: Word64
t2 =      (Word64
c Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
s2 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
8))  Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0xf                        in
  let s3 :: Word64
s3 = Word64
s2 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- ((Word64
t2 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
r2) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
256) Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
5                                     in
  let r3 :: Word64
r3 = Word64
r2 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- (Word64
t2 Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. ((Word64
t2 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
r2) Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
8))                                    in
  let t3 :: Word64
t3 =      (Word64
b Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
s3 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
4))  Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x7                        in
  let s4 :: Word64
s4 = Word64
s3 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- ((Word64
t3 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
r3) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
256) Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
6                                     in
  let r4 :: Word64
r4 = Word64
r3 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- (Word64
t3 Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. ((Word64
t3 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
r3) Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
8))                                    in
  let t4 :: Word64
t4 =      (Word64
a Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
s4 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
2))  Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x3                        in
  let s5 :: Word64
s5 = Word64
s4 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- ((Word64
t4 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
r4) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
256) Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
7                                     in
  let r5 :: Word64
r5 = Word64
r4 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- (Word64
t4 Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. ((Word64
t4 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
r4) Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
8))                                    in
  let t5 :: Word64
t5 =      (Word64
v Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
s5 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
1))  Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
0x1                        in
  let s6 :: Word64
s6 = Word64
s5 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- ((Word64
t5 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
r5) Word64 -> Word64 -> Word64
forall a. BitWise a => a -> a -> a
.&. Word64
256) Word64 -> Word64 -> Word64
forall a. Shift a => a -> Word64 -> a
.>. Word64
8                                     in
  Word64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
s6
{-# INLINE select1Word64Broadword #-}

select1Word32Broadword :: Word32 -> Word64 -> Word64
select1Word32Broadword :: Word32 -> Word64 -> Word64
select1Word32Broadword Word32
_ Word64
0 = Word64
0
select1Word32Broadword Word32
v Word64
rn =
  -- Do a normal parallel bit count for a 64-bit integer,
  -- but store all intermediate steps.
  let a :: Word32
a = (Word32
v Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x55555555) Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ ((Word32
v Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>.  Word64
1) Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x55555555)    in
  let b :: Word32
b = (Word32
a Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x33333333) Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ ((Word32
a Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>.  Word64
2) Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x33333333)    in
  let c :: Word32
c = (Word32
b Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x0f0f0f0f) Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ ((Word32
b Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>.  Word64
4) Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x0f0f0f0f)    in
  let d :: Word32
d = (Word32
c Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x00ff00ff) Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ ((Word32
c Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>.  Word64
8) Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x00ff00ff)    in
  let e :: Word32
e = (Word32
d Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x000000ff) Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ ((Word32
d Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
16) Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x000000ff)    in
  -- Now do branchless select!
  let r0 :: Word32
r0 = Word32
e Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
1 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word64 -> Narrowed32 Word64
forall a. Narrow32 a => a -> Narrowed32 a
narrow32 Word64
rn                                                in
  let s0 :: Word32
s0 = Word32
64 :: Word32                                                       in
  let t0 :: Word32
t0 = (Word32
d Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
32) Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ (Word32
d Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
48)                                            in
  let s1 :: Word32
s1 = Word32
s0 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- ((Word32
t0 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
r0) Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
256) Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
3                                     in
  let r1 :: Word32
r1 = Word32
r0 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- (Word32
t0 Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. ((Word32
t0 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
r0) Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
8))                                    in
  let t1 :: Word32
t1 =      (Word32
d Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
s1 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
16)) Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0xff                       in
  let s2 :: Word32
s2 = Word32
s1 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- ((Word32
t1 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
r1) Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
256) Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
4                                     in
  let r2 :: Word32
r2 = Word32
r1 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- (Word32
t1 Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. ((Word32
t1 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
r1) Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
8))                                    in
  let t2 :: Word32
t2 =      (Word32
c Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
s2 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
8))  Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0xf                        in
  let s3 :: Word32
s3 = Word32
s2 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- ((Word32
t2 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
r2) Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
256) Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
5                                     in
  let r3 :: Word32
r3 = Word32
r2 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- (Word32
t2 Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. ((Word32
t2 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
r2) Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
8))                                    in
  let t3 :: Word32
t3 =      (Word32
b Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
s3 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
4))  Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x7                        in
  let s4 :: Word32
s4 = Word32
s3 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- ((Word32
t3 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
r3) Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
256) Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
6                                     in
  let r4 :: Word32
r4 = Word32
r3 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- (Word32
t3 Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. ((Word32
t3 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
r3) Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
8))                                    in
  let t4 :: Word32
t4 =      (Word32
a Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
s4 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
2))  Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x3                        in
  let s5 :: Word32
s5 = Word32
s4 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- ((Word32
t4 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
r4) Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
256) Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
7                                     in
  let r5 :: Word32
r5 = Word32
r4 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- (Word32
t4 Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. ((Word32
t4 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
r4) Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
8))                                    in
  let t5 :: Word32
t5 =      (Word32
v Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32
s5 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
1))  Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
0x1                        in
  let s6 :: Word32
s6 = Word32
s5 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- ((Word32
t5 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
r5) Word32 -> Word32 -> Word32
forall a. BitWise a => a -> a -> a
.&. Word32
256) Word32 -> Word64 -> Word32
forall a. Shift a => a -> Word64 -> a
.>. Word64
8                                     in
  Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
s6
{-# INLINE select1Word32Broadword #-}

select1Word64 :: Word64 -> Word64 -> Word64
#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)
select1Word64 = select1Word64Bmi2
#else
select1Word64 :: Word64 -> Word64 -> Word64
select1Word64 = Word64 -> Word64 -> Word64
select1Word64Broadword
#endif
{-# INLINE select1Word64 #-}

select1Word32 :: Word32 -> Word64 -> Word64
#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)
select1Word32 = select1Word32Bmi2
#else
select1Word32 :: Word32 -> Word64 -> Word64
select1Word32 = Word32 -> Word64 -> Word64
select1Word32Broadword
#endif
{-# INLINE select1Word32 #-}