{-# LANGUAGE CPP #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
#include "MachDeps.h"
module Data.Memory.Internal.Scrubber
( getScrubber
) where
import GHC.Prim
import Data.Memory.Internal.CompatPrim (booleanPrim)
getScrubber :: Int# -> (Addr# -> State# RealWorld -> State# RealWorld)
getScrubber :: Int# -> Addr# -> State# RealWorld -> State# RealWorld
getScrubber Int#
sz
| Int# -> Bool
booleanPrim (Int#
sz Int# -> Int# -> Int#
==# Int#
4#) = Addr# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> State# d -> State# d
scrub4
| Int# -> Bool
booleanPrim (Int#
sz Int# -> Int# -> Int#
==# Int#
8#) = Addr# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> State# d -> State# d
scrub8
| Int# -> Bool
booleanPrim (Int#
sz Int# -> Int# -> Int#
==# Int#
16#) = Addr# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> State# d -> State# d
scrub16
| Int# -> Bool
booleanPrim (Int#
sz Int# -> Int# -> Int#
==# Int#
32#) = Addr# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> State# d -> State# d
scrub32
| Bool
otherwise = Int# -> Addr# -> State# RealWorld -> State# RealWorld
scrubBytes Int#
sz
where
scrub4 :: Addr# -> State# d -> State# d
scrub4 Addr#
a = \State# d
s -> Addr# -> Int# -> Word# -> State# d -> State# d
forall d. Addr# -> Int# -> Word# -> State# d -> State# d
writeWord32OffAddr# Addr#
a Int#
0# Word#
0## State# d
s
{-# INLINE scrub4 #-}
#if WORD_SIZE_IN_BITS == 64
scrub8 :: Addr# -> State# d -> State# d
scrub8 Addr#
a = \State# d
s -> Addr# -> Int# -> Word# -> State# d -> State# d
forall d. Addr# -> Int# -> Word# -> State# d -> State# d
writeWord64OffAddr# Addr#
a Int#
0# Word#
0## State# d
s
{-# INLINE scrub8 #-}
scrub16 :: Addr# -> State# d -> State# d
scrub16 Addr#
a = \State# d
s1 ->
let !s2 :: State# d
s2 = Addr# -> Int# -> Word# -> State# d -> State# d
forall d. Addr# -> Int# -> Word# -> State# d -> State# d
writeWord64OffAddr# Addr#
a Int#
0# Word#
0## State# d
s1
!s3 :: State# d
s3 = Addr# -> Int# -> Word# -> State# d -> State# d
forall d. Addr# -> Int# -> Word# -> State# d -> State# d
writeWord64OffAddr# Addr#
a Int#
1# Word#
0## State# d
s2
in State# d
s3
{-# INLINE scrub16 #-}
scrub32 :: Addr# -> State# d -> State# d
scrub32 Addr#
a = \State# d
s1 ->
let !s2 :: State# d
s2 = Addr# -> Int# -> Word# -> State# d -> State# d
forall d. Addr# -> Int# -> Word# -> State# d -> State# d
writeWord64OffAddr# Addr#
a Int#
0# Word#
0## State# d
s1
!s3 :: State# d
s3 = Addr# -> Int# -> Word# -> State# d -> State# d
forall d. Addr# -> Int# -> Word# -> State# d -> State# d
writeWord64OffAddr# Addr#
a Int#
1# Word#
0## State# d
s2
!s4 :: State# d
s4 = Addr# -> Int# -> Word# -> State# d -> State# d
forall d. Addr# -> Int# -> Word# -> State# d -> State# d
writeWord64OffAddr# Addr#
a Int#
2# Word#
0## State# d
s3
!s5 :: State# d
s5 = Addr# -> Int# -> Word# -> State# d -> State# d
forall d. Addr# -> Int# -> Word# -> State# d -> State# d
writeWord64OffAddr# Addr#
a Int#
3# Word#
0## State# d
s4
in State# d
s5
{-# INLINE scrub32 #-}
#else
scrub8 a = \s1 ->
let !s2 = writeWord32OffAddr# a 0# 0## s1
!s3 = writeWord32OffAddr# a 1# 0## s2
in s3
{-# INLINE scrub8 #-}
scrub16 a = \s1 ->
let !s2 = writeWord32OffAddr# a 0# 0## s1
!s3 = writeWord32OffAddr# a 1# 0## s2
!s4 = writeWord32OffAddr# a 2# 0## s3
!s5 = writeWord32OffAddr# a 3# 0## s4
in s5
{-# INLINE scrub16 #-}
scrub32 a = \s1 ->
let !s2 = writeWord32OffAddr# a 0# 0## s1
!s3 = writeWord32OffAddr# a 1# 0## s2
!s4 = writeWord32OffAddr# a 2# 0## s3
!s5 = writeWord32OffAddr# a 3# 0## s4
!s6 = writeWord32OffAddr# a 4# 0## s5
!s7 = writeWord32OffAddr# a 5# 0## s6
!s8 = writeWord32OffAddr# a 6# 0## s7
!s9 = writeWord32OffAddr# a 7# 0## s8
in s9
{-# INLINE scrub32 #-}
#endif
scrubBytes :: Int# -> Addr# -> State# RealWorld -> State# RealWorld
scrubBytes :: Int# -> Addr# -> State# RealWorld -> State# RealWorld
scrubBytes Int#
sz8 Addr#
addr = \State# RealWorld
s -> Int# -> Addr# -> State# RealWorld -> State# RealWorld
loop Int#
sz8 Addr#
addr State# RealWorld
s
where loop :: Int# -> Addr# -> State# RealWorld -> State# RealWorld
loop :: Int# -> Addr# -> State# RealWorld -> State# RealWorld
loop Int#
n Addr#
a State# RealWorld
s
| Int# -> Bool
booleanPrim (Int#
n Int# -> Int# -> Int#
==# Int#
0#) = State# RealWorld
s
| Bool
otherwise =
case Addr# -> Int# -> Word# -> State# RealWorld -> State# RealWorld
forall d. Addr# -> Int# -> Word# -> State# d -> State# d
writeWord8OffAddr# Addr#
a Int#
0# Word#
0## State# RealWorld
s of
State# RealWorld
s' -> Int# -> Addr# -> State# RealWorld -> State# RealWorld
loop (Int#
n Int# -> Int# -> Int#
-# Int#
1#) (Addr# -> Int# -> Addr#
plusAddr# Addr#
a Int#
1#) State# RealWorld
s'
{-# INLINE loop #-}
{-# INLINE scrubBytes #-}