---- Copyright (c) 2009-2010, ERICSSON AB All rights reserved.-- -- Redistribution and use in source and binary forms, with or without-- modification, are permitted provided that the following conditions are met:-- -- * Redistributions of source code must retain the above copyright notice,-- this list of conditions and the following disclaimer.-- * Redistributions in binary form must reproduce the above copyright-- notice, this list of conditions and the following disclaimer in the-- documentation and/or other materials provided with the distribution.-- * Neither the name of the ERICSSON AB nor the names of its contributors-- may be used to endorse or promote products derived from this software-- without specific prior written permission.-- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS-- BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF-- THE POSSIBILITY OF SUCH DAMAGE.--moduleFeldspar.FixedPointwhereimportqualifiedPreludeimportFeldspar.PreludeimportFeldspar.Core.TypesimportFeldspar.Core.ExprimportFeldspar.CoreimportData.RatioimportSystem.IO.UnsafeimportFeldspar.Core.FunctionstypeFix32=(Int,DataSigned32)typeUFix32=(Int,DataUnsigned32)typeFix16=(Int,DataSigned16)typeUFix16=(Int,DataUnsigned16)typeFix8=(Int,DataSigned8)typeUFix8=(Int,DataUnsigned8)typeFix=(Int,DataInt)intToFix::Int->DataInt->FixintToFixexpval=(exp,val)intToFix32::Int->DataSigned32->Fix32intToFix32expval=(exp,val)intToUFix32::Int->DataUnsigned32->UFix32intToUFix32expval=(exp,val)intToFix16::Int->DataSigned16->Fix16intToFix16expval=(exp,val)intToUFix16::Int->DataUnsigned16->UFix16intToUFix16expval=(exp,val)intToFix8::Int->DataSigned8->Fix8intToFix8expval=(exp,val)intToUFix8::Int->DataUnsigned8->UFix8intToUFix8expval=(exp,val)fixToInt::Int->Fix->DataIntfixToIntexp'(exp,val)=val`leftShift`(exp-exp')fix32ToInt::Int->Fix32->DataSigned32fix32ToIntexp'(exp,val)=val`leftShift`(exp-exp')uFix32ToInt::Int->UFix32->DataUnsigned32uFix32ToIntexp'(exp,val)=val`leftShift`(exp-exp')fix16ToInt::Int->Fix16->DataSigned16fix16ToIntexp'(exp,val)=val`leftShift`(exp-exp')uFix16ToInt::Int->UFix16->DataUnsigned16uFix16ToIntexp'(exp,val)=val`leftShift`(exp-exp')fix8ToInt::Int->Fix8->DataSigned8fix8ToIntexp'(exp,val)=val`leftShift`(exp-exp')uFix8ToInt::Int->UFix8->DataUnsigned8uFix8ToIntexp'(exp,val)=val`leftShift`(exp-exp')floatToFix::Float->FixfloatToFixf=(0,value$Prelude.roundf)floatToFix32::Float->Fix32floatToFix32f=(0,value$Prelude.roundf)floatToUFix32::Float->UFix32floatToUFix32f=(0,value$Prelude.roundf)floatToFix16::Float->Fix16floatToFix16f=(0,value$Prelude.roundf)floatToUFix16::Float->UFix16floatToUFix16f=(0,value$Prelude.roundf)floatToFix8::Float->Fix8floatToFix8f=(0,value$Prelude.roundf)floatToUFix8::Float->UFix8floatToUFix8f=(0,value$Prelude.roundf)floatToFix32'::Int->Float->Fix32floatToFix32'expfl=(exp,value$Prelude.round$(flPrelude./(2.0Prelude.**(fromInteger(toIntegerexp)))::Float))floatToUFix32'::Int->Float->UFix32floatToUFix32'expfl=(exp,value$Prelude.round$(flPrelude./(2.0Prelude.**(fromInteger(toIntegerexp)))::Float))floatToFix16'::Int->Float->Fix16floatToFix16'expfl=(exp,value$Prelude.round$(flPrelude./(2.0Prelude.**(fromInteger(toIntegerexp)))::Float))floatToUFix16'::Int->Float->UFix16floatToUFix16'expfl=(exp,value$Prelude.round$(flPrelude./(2.0Prelude.**(fromInteger(toIntegerexp)))::Float))floatToFix8'::Int->Float->Fix8floatToFix8'expfl=(exp,value$Prelude.round$(flPrelude./(2.0Prelude.**(fromInteger(toIntegerexp)))::Float))floatToUFix8'::Int->Float->UFix8floatToUFix8'expfl=(exp,value$Prelude.round$(flPrelude./(2.0Prelude.**(fromInteger(toIntegerexp)))::Float))toExp32::Int->Fix32->Fix32toExp32exp(e,i)=(exp,i`leftShift`(e-exp))toExpU32::Int->UFix32->UFix32toExpU32exp(e,i)=(exp,i`leftShift`(e-exp))toExp16::Int->Fix16->Fix16toExp16exp(e,i)=(exp,i`leftShift`(e-exp))toExpU16::Int->UFix16->UFix16toExpU16exp(e,i)=(exp,i`leftShift`(e-exp))toExp8::Int->Fix8->Fix8toExp8exp(e,i)=(exp,i`leftShift`(e-exp))toExpU8::Int->UFix8->UFix8toExpU8exp(e,i)=(exp,i`leftShift`(e-exp))fixToFloat::(Integrala,Integralb)=>(a,Datab)->FloatfixToFloatfix=(2.0Prelude.**(fromInteger(toInteger(fstfix))))Prelude.*((fromInteger(toInteger(evalD(sndfix))))::Float)fix32ToFloat::Fix32->Floatfix32ToFloatfix=fixToFloatfixuFix32ToFloat::UFix32->FloatuFix32ToFloatfix=fixToFloatfixfix16ToFloat::Fix16->Floatfix16ToFloatfix=fixToFloatfixuFix16ToFloat::UFix16->FloatuFix16ToFloatfix=fixToFloatfixfix8ToFloat::Fix8->Floatfix8ToFloatfix=fixToFloatfixuFix8ToFloat::UFix8->FloatuFix8ToFloatfix=fixToFloatfixinBounds::Bool->Int->Int->BoolinBoundsswbitsi|sPrelude.&&(iPrelude.>sintmax)=False|sPrelude.&&(iPrelude.<sintmin)=False|(Prelude.nots)Prelude.&&(iPrelude.>uintmax)=False|(Prelude.nots)Prelude.&&(iPrelude.<uintmin)=False|otherwise=Truewhere(sintmax::Int)=2Prelude.^(wbitsPrelude.-1)-1(sintmin::Int)=-sintmax(uintmax::Int)=2Prelude.^wbitsPrelude.-1(uintmin::Int)=0fl01toFix::(Integrala,Integralb)=>Bool->Int->Float->(a,Datab)->Bool->(a,Datab)fl01toFixsbtsflfixgt|(Prelude.notgt)Prelude.&&(fl1Prelude.>fl)=fl01toFixsbtsfl((fstfix)Prelude.-1,sndfix)Prelude.False|(Prelude.notgt)Prelude.&&(fl1Prelude.<fl)=fl01toFixsbtsfl((fstfix)Prelude.-1,sndfix)Prelude.True|(Prelude.notgt)Prelude.&&(fl1Prelude.==fl)=((fstfix)Prelude.-1,sndfix)|gtPrelude.&&((inBoundssbtsval')Prelude.&&(fl2Prelude.>fl))=fl01toFixsbtsfl((fstfix)Prelude.-1,2*(sndfix))Prelude.True|gtPrelude.&&((inBoundssbtsval')Prelude.&&(fl2Prelude.<fl))=fl01toFixsbtsfl((fstfix)Prelude.-1,2*(sndfix)+1)Prelude.True|gtPrelude.&&((inBoundssbtsval')Prelude.&&(fl2Prelude.==fl))=fl01toFixsbtsfl((fstfix)Prelude.-1,2*(sndfix)+1)Prelude.True|otherwise=fixwherefl2=(2.0Prelude.*(fromIntegerval)Prelude.+1.0)Prelude.*(2.0Prelude.**((fromIntegerexp)Prelude.-1.0))fl1=(fromIntegerval)Prelude.*(2.0Prelude.**((fromIntegerexp)Prelude.-1.0))val'=2Prelude.*(fromIntegerval)Prelude.+1val=toInteger$evalD$sndfixexp=toInteger$fstfixfl01toFix'::Float->Fix->Bool->Fixfl01toFix'=fl01toFixTrue31fl01toUFix32::Float->UFix32->Bool->UFix32fl01toUFix32=fl01toFixFalse32fl01toFix32::Float->Fix32->Bool->Fix32fl01toFix32=fl01toFixTrue31fl01toUFix16::Float->UFix16->Bool->UFix16fl01toUFix16=fl01toFixFalse16fl01toFix16::Float->Fix16->Bool->Fix16fl01toFix16=fl01toFixTrue15fl01toUFix8::Float->UFix8->Bool->UFix8fl01toUFix8=fl01toFixFalse8fl01toFix8::Float->Fix8->Bool->Fix8fl01toFix8=fl01toFixTrue7zeroOneToFix::Float->FixzeroOneToFixfl=fl01toFix'fl(1,1)Prelude.FalsezeroOneToFix32::Float->Fix32zeroOneToFix32fl=fl01toFix32fl(1,1)Prelude.FalsezeroOneToUFix32::Float->UFix32zeroOneToUFix32fl=fl01toUFix32fl(1,1)Prelude.FalsezeroOneToFix16::Float->Fix16zeroOneToFix16fl=fl01toFix16fl(1,1)Prelude.FalsezeroOneToUFix16::Float->UFix16zeroOneToUFix16fl=fl01toUFix16fl(1,1)Prelude.FalsezeroOneToFix8::Float->Fix8zeroOneToFix8fl=fl01toFix8fl(1,1)Prelude.FalsezeroOneToUFix8::Float->UFix8zeroOneToUFix8fl=fl01toUFix8fl(1,1)Prelude.FalseaddFix::(Integralb,Bitsb)=>Int->(Int,Datab)->(Int,Datab)->(Int,Datab)addFixe(e1,i1)(e2,i2)=(e,i1`leftShift`(e1Prelude.-e)+i2`leftShift`(e2Prelude.-e))addFix''::Int->Fix->Fix->FixaddFix''=addFixaddFix32::Int->Fix32->Fix32->Fix32addFix32=addFixaddUFix32::Int->UFix32->UFix32->UFix32addUFix32=addFixaddFix16::Int->Fix16->Fix16->Fix16addFix16=addFixaddUFix16::Int->UFix16->UFix16->UFix16addUFix16=addFixaddFix8::Int->Fix8->Fix8->Fix8addFix8=addFixaddUFix8::Int->UFix8->UFix8->UFix8addUFix8=addFixrecipFix::(Integralb,Bitsb)=>Int->(Int,Datab)->(Int,Datab)recipFixexp(e,i)=(e2,i2)wheree2=expi2=divshish=1`rightShift`(expPrelude.+e)recipFix'::Int->Fix->FixrecipFix'=recipFixrecipFix32::Int->Fix32->Fix32recipFix32=recipFixrecipUFix32::Int->UFix32->UFix32recipUFix32=recipFixrecipFix16::Int->Fix16->Fix16recipFix16=recipFixrecipUFix16::Int->UFix16->UFix16recipUFix16=recipFixrecipFix8::Int->Fix8->Fix8recipFix8=recipFixrecipUFix8::Int->UFix8->UFix8recipUFix8=recipFixdivFix::(Integralb,Bitsb)=>Int->(Int,Datab)->(Int,Datab)->(Int,Datab)divFixexp(e1,i1)(e2,i2)=(e,i)wheree=expi=divshi2val=e1Prelude.-e2Prelude.-expsh=i1`leftShift`valdivFix'::Int->Fix->Fix->FixdivFix'=divFixdivFix32::Int->Fix32->Fix32->Fix32divFix32=divFixdivUFix32::Int->UFix32->UFix32->UFix32divUFix32=divFixdivFix16::Int->Fix16->Fix16->Fix16divFix16=divFixdivUFix16::Int->UFix16->UFix16->UFix16divUFix16=divFixdivFix8::Int->Fix8->Fix8->Fix8divFix8=divFixdivUFix8::Int->UFix8->UFix8->UFix8divUFix8=divFixaddFix'::(Integralb,Bitsb)=>(Int,Datab)->(Int,Datab)->(Int,Datab)addFix'(e1,i1)(e2,i2)=(m,(i1`leftShift`(e1Prelude.-m))+(i2`leftShift`(e2Prelude.-m)))wherem=Prelude.maxe1e2mulFix'::(Integralb,Bitsb)=>(Int,Datab)->(Int,Datab)->(Int,Datab)mulFix'(e1,i1)(e2,i2)=(added,(i1*i2))whereadded=e1Prelude.+e2negate'::(Integralb,Bitsb)=>(Int,Datab)->(Int,Datab)negate'(e,i)=(e,negatei)abs'::(Integralb,Bitsb)=>(Int,Datab)->(Int,Datab)abs'(e,i)=(e,abs(i))signum'::(Integralb,Bitsb)=>(Int,Datab)->(Int,Datab)signum'(e,i)=(0,signumi)fromInteger'::(Integralb,Bitsb)=>Integer->(Int,Datab)fromInteger'i=(0,fromIntegeri)instanceNumFixwherex+y=addFix'xyx*y=mulFix'xynegate=negate'abs=abs'signum=signum'fromInteger=fromInteger'instanceNumFix32wherex+y=addFix'xyx*y=mulFix'xynegate=negate'abs=abs'signum=signum'fromInteger=fromInteger'instanceNumUFix32wherex+y=addFix'xyx*y=mulFix'xynegate=negate'abs=abs'signum=signum'fromInteger=fromInteger'instanceNumFix16wherex+y=addFix'xyx*y=mulFix'xynegate=negate'abs=abs'signum=signum'fromInteger=fromInteger'instanceNumUFix16wherex+y=addFix'xyx*y=mulFix'xynegate=negate'abs=abs'signum=signum'fromInteger=fromInteger'instanceNumFix8wherex+y=addFix'xyx*y=mulFix'xynegate=negate'abs=abs'signum=signum'fromInteger=fromInteger'instanceNumUFix8wherex+y=addFix'xyx*y=mulFix'xynegate=negate'abs=abs'signum=signum'fromInteger=fromInteger'recip'::(Integralb,Bitsb)=>Int->(Int,Datab)->(Int,Datab)recip'bts(e,i)=(e2,i2)wherek=bts-2e2=Prelude.negate$ePrelude.+ksh=1`leftShift`ki2=divshifromRational'::(Integralb,Bitsb,Num(Int,Datab))=>Bool->Int->(Float->(Int,Datab))->(Integer->(Int,Datab))->Rational->(Int,Datab)fromRational'sbtszotffirat=addFixeintegfracwheree=(fstfrac)Prelude.+toShift'toShift'|s=Prelude.mintoShift((btsPrelude.-1)Prelude.-bitsInteg)|(Prelude.nots)=Prelude.mintoShift(btsPrelude.-bitsInteg)toShift|s=Prelude.max0(bitsFracPrelude.-(btsPrelude.-1)Prelude.+bitsInteg)|(Prelude.nots)=Prelude.max0(bitsFracPrelude.-btsPrelude.+bitsInteg)bitsFrac=Prelude.floor$Prelude.logBase2.0(fromInteger(toIntegervfrac))bitsInteg=Prelude.floor$Prelude.logBase2.0(fromInteger(toIntegervinteg))vinteg=evalD$sndintegvfrac=evalD$sndfracfrac=zotffl01integ=(fi(Prelude.quot(numeratorrat)(denominatorrat)))fl01=fl-((Prelude.fromInteger(Prelude.floorfl))::Float)fl=(Prelude.fromRationalrat)::FloatinstanceFractionalFixwhererecip=recip'32fromRational=fromRational'True32zeroOneToFixfromIntegerinstanceFractionalFix32whererecip=recip'32fromRational=fromRational'True32zeroOneToFix32fromIntegerinstanceFractionalUFix32whererecip=recip'31fromRational=fromRational'False31zeroOneToUFix32fromIntegerinstanceFractionalFix16whererecip=recip'16fromRational=fromRational'True16zeroOneToFix16fromIntegerinstanceFractionalUFix16whererecip=recip'15fromRational=fromRational'False15zeroOneToUFix16fromIntegerinstanceFractionalFix8whererecip=recip'8fromRational=fromRational'True8zeroOneToFix8fromIntegerinstanceFractionalUFix8whererecip=recip'7fromRational=fromRational'False7zeroOneToUFix8fromIntegerclassFixFloatLikeawhereaddFF::Int->a->a->arecipFF::Int->a->adivFF::Int->a->a->ainstanceFixFloatLike(DataFloat)whereaddFF_xy=x+yrecipFF_x=1/xdivFF_xy=x/yinstanceFixFloatLikeFixwhereaddFF=addFix''recipFF=recipFix'divFF=divFix'instanceFixFloatLikeFix32whereaddFF=addFix32recipFF=recipFix32divFF=divFix32instanceFixFloatLikeUFix32whereaddFF=addUFix32recipFF=recipUFix32divFF=divUFix32instanceFixFloatLikeFix16whereaddFF=addFix16recipFF=recipFix16divFF=divFix16instanceFixFloatLikeUFix16whereaddFF=addUFix16recipFF=recipUFix16divFF=divUFix16instanceFixFloatLikeFix8whereaddFF=addFix8recipFF=recipFix8divFF=divFix8instanceFixFloatLikeUFix8whereaddFF=addUFix8recipFF=recipUFix8divFF=divUFix8classFromFloattwherefloat::Float->tinstanceFromFloat(DataFloat)wherefloat=valueinstanceFromFloatFixwherefloat=floatToFixinstanceFromFloatFix32wherefloat=floatToFix32instanceFromFloatUFix32wherefloat=floatToUFix32instanceFromFloatFix16wherefloat=floatToFix16instanceFromFloatUFix16wherefloat=floatToUFix16instanceFromFloatFix8wherefloat=floatToFix8instanceFromFloatUFix8wherefloat=floatToUFix8-- Helper functions to generate shift with non-negative parameterleftShift::Bitsa=>Dataa->Int->DataaleftShiftab|bPrelude.>=0=a<<valueb|otherwise=a>>value(Prelude.negateb)rightShift::Bitsa=>Dataa->Int->DataarightShiftab|bPrelude.>=0=a>>valueb|otherwise=a<<value(Prelude.negateb)