------------------------------------------------------------------------------- |-- Module : Data.SBV.BitVectors.Splittable-- Copyright : (c) Levent Erkok-- License : BSD3-- Maintainer : erkokl@gmail.com-- Stability : experimental-- Portability : portable---- Implementation of bit-vector concatanetation and splits-----------------------------------------------------------------------------{-# LANGUAGE MultiParamTypeClasses #-}{-# LANGUAGE FunctionalDependencies #-}{-# LANGUAGE TypeSynonymInstances #-}{-# LANGUAGE FlexibleInstances #-}{-# LANGUAGE BangPatterns #-}moduleData.SBV.BitVectors.Splittable(Splittable(..),FromBits(..))whereimportData.Bits(Bits(..))importData.Word(Word8,Word16,Word32,Word64)importData.SBV.BitVectors.DataimportData.SBV.BitVectors.Modelinfixr5#-- | Splitting an @a@ into two @b@'s and joining back.-- Intuitively, @a@ is a larger bit-size word than @b@, typically double.-- The 'extend' operation captures embedding of a @b@ value into an @a@-- without changing its semantic value.---- Minimal complete definition: All, no defaults.classSplittableab|b->awheresplit::a->(b,b)(#)::b->b->aextend::b->agenSplit::(Integrala,Numb)=>Int->a->(b,b)genSplitssx=(fromIntegral((ix`shiftR`ss).&.mask),fromIntegral(ix.&.mask))whereix=toIntegerxmask=2^ss-1genJoin::(Integralb,Numa)=>Int->b->b->agenJoinssxy=fromIntegral((ix`shiftL`ss).|.iy)whereix=toIntegerxiy=toIntegery-- concrete instancesinstanceSplittableWord64Word32wheresplit=genSplit32(#)=genJoin32extendb=0#binstanceSplittableWord32Word16wheresplit=genSplit16(#)=genJoin16extendb=0#binstanceSplittableWord16Word8wheresplit=genSplit8(#)=genJoin8extendb=0#bcwSplit::(SymWorda,Numa)=>CW->(SBVa,SBVa)cwSplitz=(literalx,literaly)where(x,y)=genSplit(intSizeOfz`div`2)(cwValz)cwJoin::(SymWorda,Numa)=>CW->CW->SBVacwJoinxy=literal(genJoin(intSizeOfx)(cwValx)(cwValy))-- symbolic instancesinstanceSplittableSWord64SWord32wheresplit(SBV_(Leftz))=cwSplitzsplitz=(SBV(False,Size(Just32))(Right(cachex)),SBV(False,Size(Just32))(Right(cachey)))wherexst=dozsw<-sbvToSWstznewExprst(False,Size(Just32))(SBVApp(Extract6332)[zsw])yst=dozsw<-sbvToSWstznewExprst(False,Size(Just32))(SBVApp(Extract310)[zsw])(SBV_(Lefta))#(SBV_(Leftb))=cwJoinaba#b=SBV(False,Size(Just64))(Right(cachec))wherecst=doasw<-sbvToSWstabsw<-sbvToSWstbnewExprst(False,Size(Just64))(SBVAppJoin[asw,bsw])extendb=0#binstanceSplittableSWord32SWord16wheresplit(SBV_(Leftz))=cwSplitzsplitz=(SBV(False,Size(Just16))(Right(cachex)),SBV(False,Size(Just16))(Right(cachey)))wherexst=dozsw<-sbvToSWstznewExprst(False,Size(Just16))(SBVApp(Extract3116)[zsw])yst=dozsw<-sbvToSWstznewExprst(False,Size(Just16))(SBVApp(Extract150)[zsw])(SBV_(Lefta))#(SBV_(Leftb))=cwJoinaba#b=SBV(False,Size(Just32))(Right(cachec))wherecst=doasw<-sbvToSWstabsw<-sbvToSWstbnewExprst(False,Size(Just32))(SBVAppJoin[asw,bsw])extendb=0#binstanceSplittableSWord16SWord8wheresplit(SBV_(Leftz))=cwSplitzsplitz=(SBV(False,Size(Just8))(Right(cachex)),SBV(False,Size(Just8))(Right(cachey)))wherexst=dozsw<-sbvToSWstznewExprst(False,Size(Just8))(SBVApp(Extract158)[zsw])yst=dozsw<-sbvToSWstznewExprst(False,Size(Just8))(SBVApp(Extract70)[zsw])(SBV_(Lefta))#(SBV_(Leftb))=cwJoinaba#b=SBV(False,Size(Just16))(Right(cachec))wherecst=doasw<-sbvToSWstabsw<-sbvToSWstbnewExprst(False,Size(Just16))(SBVAppJoin[asw,bsw])extendb=0#b-- | Unblasting a value from symbolic-bits. The bits can be given little-endian-- or big-endian. For a signed number in little-endian, we assume the very last bit-- is the sign digit. This is a bit awkward, but it is more consistent with the "reverse" view of-- little-big-endian representations---- Minimal complete definiton: 'fromBitsLE'classFromBitsawherefromBitsLE,fromBitsBE::[SBool]->afromBitsBE=fromBitsLE.reverse-- | Construct a symbolic word from its bits given in little-endianfromBinLE::(Bitsa,SymWorda)=>[SBool]->SBVafromBinLE=go00wherego!acc_[]=accgo!acc!i(x:xs)=go(itex(setBitacci)acc)(i+1)xs-- | Perform a sanity check that we should receive precisely the same-- number of bits as required by the resulting type. The input is little-endiancheckAndConvert::(Bitsa,SymWorda)=>Int->[SBool]->SBVacheckAndConvertszxs|sz/=l=error$"SBV.fromBits.SWord"++ssz++": Expected "++ssz++" elements, got: "++showl|True=fromBinLExswherel=lengthxsssz=showszinstanceFromBitsSBoolwherefromBitsLE[x]=xfromBitsLExs=error$"SBV.fromBits.SBool: Expected 1 element, got: "++show(lengthxs)instanceFromBitsSWord8wherefromBitsLE=checkAndConvert8instanceFromBitsSInt8wherefromBitsLE=checkAndConvert8instanceFromBitsSWord16wherefromBitsLE=checkAndConvert16instanceFromBitsSInt16wherefromBitsLE=checkAndConvert16instanceFromBitsSWord32wherefromBitsLE=checkAndConvert32instanceFromBitsSInt32wherefromBitsLE=checkAndConvert32instanceFromBitsSWord64wherefromBitsLE=checkAndConvert64instanceFromBitsSInt64wherefromBitsLE=checkAndConvert64