diff options
author | Herbert Valerio Riedel <hvr@gnu.org> | 2015-03-29 19:02:08 +0200 |
---|---|---|
committer | Herbert Valerio Riedel <hvr@gnu.org> | 2015-03-31 10:59:36 +0200 |
commit | 995e8c1c8692b60c907c7d2ccea179d52ca8e69e (patch) | |
tree | 1314ec36672d72b33a99b33e017316c0b8585625 /libraries/integer-gmp/src/GHC/Integer/Logarithms/Internals.hs | |
parent | 1f69f37f34c6f15fd900c2c1cce3ce896168dde9 (diff) | |
download | haskell-995e8c1c8692b60c907c7d2ccea179d52ca8e69e.tar.gz |
Drop old integer-gmp-0.5 from GHC source tree
This completes what c774b28f76ee4c220f7c1c9fd81585e0e3af0e8a (#9281)
started. `integer-gmp-1.0` was added as an additional
`libraries/integer-gmp2` folder while retaining the ability to configure
GHC w/ the old `integer-gmp-0.5` to have a way back, and or the ability
to easily switch between old/new `integer-gmp` for benchmark/debugging
purposes.
This commit removes the old `libraries/integer-gmp` folder and moves
`libraries/integer-gmp2` into its place, while removing any mentions of
"gmp2" as well as the to support two different `integer-gmp` packages in
GHC's source-tree.
Reviewed By: austin
Differential Revision: https://phabricator.haskell.org/D769
Diffstat (limited to 'libraries/integer-gmp/src/GHC/Integer/Logarithms/Internals.hs')
-rw-r--r-- | libraries/integer-gmp/src/GHC/Integer/Logarithms/Internals.hs | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/libraries/integer-gmp/src/GHC/Integer/Logarithms/Internals.hs b/libraries/integer-gmp/src/GHC/Integer/Logarithms/Internals.hs new file mode 100644 index 0000000000..7ac3645c74 --- /dev/null +++ b/libraries/integer-gmp/src/GHC/Integer/Logarithms/Internals.hs @@ -0,0 +1,118 @@ +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE CPP #-} + +{-# OPTIONS_HADDOCK hide #-} + +#include "MachDeps.h" + +#if WORD_SIZE_IN_BITS == 32 +# define WSHIFT 5 +# define MMASK 31 +#elif WORD_SIZE_IN_BITS == 64 +# define WSHIFT 6 +# define MMASK 63 +#else +# error unsupported WORD_SIZE_IN_BITS +#endif + +-- | Fast 'Integer' logarithms to base 2. 'integerLog2#' and +-- 'wordLog2#' are of general usefulness, the others are only needed +-- for a fast implementation of 'fromRational'. Since they are needed +-- in "GHC.Float", we must expose this module, but it should not show +-- up in the docs. +-- +-- See https://ghc.haskell.org/trac/ghc/ticket/5122 +-- for the origin of the code in this module +module GHC.Integer.Logarithms.Internals + ( wordLog2# + , integerLog2IsPowerOf2# + , integerLog2# + , roundingMode# + ) where + +import GHC.Integer.Type +import GHC.Integer.Logarithms + +import GHC.Types +import GHC.Prim + +default () + +-- | Extended version of 'integerLog2#' +-- +-- Assumption: Integer is strictly positive +-- +-- First component of result is @log2 n@, second is @0#@ iff /n/ is a +-- power of two. +integerLog2IsPowerOf2# :: Integer -> (# Int#, Int# #) +-- The power of 2 test is n&(n-1) == 0, thus powers of 2 +-- are indicated bythe second component being zero. +integerLog2IsPowerOf2# (S# i#) = case int2Word# i# of + w -> (# wordLog2# w, word2Int# (w `and#` (w `minusWord#` 1##)) #) +integerLog2IsPowerOf2# (Jn# _) = (# -1#, -1# #) +-- Find the log2 as above, test whether that word is a power +-- of 2, if so, check whether only zero bits follow. +integerLog2IsPowerOf2# (Jp# bn) = check (s -# 1#) + where + s = sizeofBigNat# bn + check :: Int# -> (# Int#, Int# #) + check i = case indexBigNat# bn i of + 0## -> check (i -# 1#) + w -> (# wordLog2# w +# (uncheckedIShiftL# i WSHIFT#) + , case w `and#` (w `minusWord#` 1##) of + 0## -> test (i -# 1#) + _ -> 1# #) + test :: Int# -> Int# + test i = if isTrue# (i <# 0#) + then 0# + else case indexBigNat# bn i of + 0## -> test (i -# 1#) + _ -> 1# + + +-- Assumption: Integer and Int# are strictly positive, Int# is less +-- than logBase 2 of Integer, otherwise havoc ensues. +-- Used only for the numerator in fromRational when the denominator +-- is a power of 2. +-- The Int# argument is log2 n minus the number of bits in the mantissa +-- of the target type, i.e. the index of the first non-integral bit in +-- the quotient. +-- +-- 0# means round down (towards zero) +-- 1# means we have a half-integer, round to even +-- 2# means round up (away from zero) +roundingMode# :: Integer -> Int# -> Int# +roundingMode# (S# i#) t = + case int2Word# i# `and#` ((uncheckedShiftL# 2## t) `minusWord#` 1##) of + k -> case uncheckedShiftL# 1## t of + c -> if isTrue# (c `gtWord#` k) + then 0# + else if isTrue# (c `ltWord#` k) + then 2# + else 1# + +roundingMode# (Jn# bn) t = roundingMode# (Jp# bn) t -- dummy +roundingMode# (Jp# bn) t = + case word2Int# (int2Word# t `and#` MMASK##) of + j -> -- index of relevant bit in word + case uncheckedIShiftRA# t WSHIFT# of + k -> -- index of relevant word + case indexBigNat# bn k `and#` + ((uncheckedShiftL# 2## j) `minusWord#` 1##) of + r -> + case uncheckedShiftL# 1## j of + c -> if isTrue# (c `gtWord#` r) + then 0# + else if isTrue# (c `ltWord#` r) + + + then 2# + else test (k -# 1#) + where + test i = if isTrue# (i <# 0#) + then 1# + else case indexBigNat# bn i of + 0## -> test (i -# 1#) + _ -> 2# |