fixed

Pure Haskell large fixed-width integers.
git clone git://git.ppad.tech/fixed.git
Log | Files | Refs | README | LICENSE

commit 4df9f511b7baf73524a8e8cca6a71015ce82e754
parent e1ff7496e985da26c4b3670290f97273422e2038
Author: Jared Tobin <jared@jtobin.io>
Date:   Sat, 22 Nov 2025 14:23:11 +0400

lib: shr1-with-carry for wider

Diffstat:
Mlib/Data/Word/Wider.hs | 24++++++++++++++++++++++++
1 file changed, 24 insertions(+), 0 deletions(-)

diff --git a/lib/Data/Word/Wider.hs b/lib/Data/Word/Wider.hs @@ -10,6 +10,7 @@ module Data.Word.Wider where import Control.DeepSeq import Data.Bits ((.|.), (.&.), (.<<.), (.>>.)) +import qualified Data.Choice as C import qualified Data.Bits as B import qualified Data.Word.Limb as L import GHC.Exts @@ -145,3 +146,26 @@ sub_mod_c# a c b (# p0, p1, p2, p3 #) = in add_w# (# o0, o1, o2, o3 #) band {-# INLINE sub_mod_c# #-} +-- | Constant-time 1-bit shift-right with carry, indicating whether the +-- lowest bit was set. +shr1_c# + :: (# Word#, Word#, Word#, Word# #) -- ^ argument + -> (# (# Word#, Word#, Word#, Word# #), C.Choice #) -- ^ result, carry +shr1_c# (# w0, w1, w2, w3 #) = + let !s = case B.finiteBitSize (0 :: Word) of I# m -> m -# 1# + !c = 0## + !(# s3, c3 #) = (# uncheckedShiftRL# w3 1#, uncheckedShiftL# w3 s #) + !r3 = or# s3 c + !(# s2, c2 #) = (# uncheckedShiftRL# w2 1#, uncheckedShiftL# w2 s #) + !r2 = or# s2 c3 + !(# s1, c1 #) = (# uncheckedShiftRL# w1 1#, uncheckedShiftL# w1 s #) + !r1 = or# s1 c2 + !(# s0, c0 #) = (# uncheckedShiftRL# w0 1#, uncheckedShiftL# w0 s #) + !r0 = or# s0 c1 + in (# (# r0, r1, r2, r3 #), C.from_word_lsb# (uncheckedShiftRL# c0 s) #) +{-# INLINE shr1_c# #-} + +shr1_c :: Wider -> (Wider, Bool) +shr1_c (Wider w) = + let !(# r, c #) = shr1_c# w + in (Wider r, C.decide c)