summaryrefslogtreecommitdiff
path: root/libraries/ghc-bignum/src/GHC/Num/BigNat/Check.hs
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ghc-bignum/src/GHC/Num/BigNat/Check.hs')
-rw-r--r--libraries/ghc-bignum/src/GHC/Num/BigNat/Check.hs456
1 files changed, 456 insertions, 0 deletions
diff --git a/libraries/ghc-bignum/src/GHC/Num/BigNat/Check.hs b/libraries/ghc-bignum/src/GHC/Num/BigNat/Check.hs
new file mode 100644
index 0000000000..aad7d903ff
--- /dev/null
+++ b/libraries/ghc-bignum/src/GHC/Num/BigNat/Check.hs
@@ -0,0 +1,456 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE GHCForeignImportPrim #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE UnliftedFFITypes #-}
+{-# LANGUAGE NegativeLiterals #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# OPTIONS_GHC -Wno-name-shadowing #-}
+{-# OPTIONS_GHC -ddump-simpl -ddump-to-file #-}
+
+-- | Check Native implementation against another backend
+module GHC.Num.BigNat.Check where
+
+import GHC.Prim
+import GHC.Types
+import GHC.Num.WordArray
+import GHC.Num.Primitives
+import qualified GHC.Num.BigNat.Native as Native
+
+#if defined(BIGNUM_NATIVE)
+#error You can't validate Native backed against itself. Choose another backend (e.g. gmp, ffi)
+
+#elif defined(BIGNUM_FFI)
+import qualified GHC.Num.BigNat.FFI as Other
+
+#elif defined(BIGNUM_GMP)
+import qualified GHC.Num.BigNat.GMP as Other
+
+#else
+#error Undefined BigNat backend. Use a flag to select it (e.g. gmp, native, ffi)`
+#endif
+
+default ()
+
+bignat_compare
+ :: WordArray#
+ -> WordArray#
+ -> Int#
+bignat_compare a b =
+ let
+ gr = Other.bignat_compare a b
+ nr = Native.bignat_compare a b
+ in case gr ==# nr of
+ 0# -> case unexpectedValue of I# x -> x
+ _ -> gr
+
+mwaCompare
+ :: MutableWordArray# s
+ -> MutableWordArray# s
+ -> State# s
+ -> (# State# s, Bool# #)
+mwaCompare mwa mwb s =
+ case mwaSize# mwa s of
+ (# s, szA #) -> case mwaSize# mwb s of
+ (# s, szB #) -> case szA ==# szB of
+ 0# -> (# s, 0# #)
+ _ -> let
+ go i s
+ | isTrue# (i <# 0#) = (# s, 1# #)
+ | True =
+ case readWordArray# mwa i s of
+ (# s, a #) -> case readWordArray# mwb i s of
+ (# s, b #) -> case a `eqWord#` b of
+ 0# -> (# s, 0# #)
+ _ -> go (i -# 1#) s
+ in go (szA -# 1#) s
+
+mwaCompareOp
+ :: MutableWordArray# s
+ -> (MutableWordArray# s -> State# s -> State# s)
+ -> (MutableWordArray# s -> State# s -> State# s)
+ -> State# s
+ -> State# s
+mwaCompareOp mwa f g s =
+ case mwaSize# mwa s of { (# s, sz #) ->
+ case newWordArray# sz s of { (# s, mwb #) ->
+ case f mwa s of { s ->
+ case g mwb s of { s ->
+ case mwaTrimZeroes# mwa s of { s ->
+ case mwaTrimZeroes# mwb s of { s ->
+ case mwaCompare mwa mwb s of
+ (# s, 0# #) -> case unexpectedValue of _ -> s
+ (# s, _ #) -> s
+ }}}}}}
+
+mwaCompareOp2
+ :: MutableWordArray# s
+ -> MutableWordArray# s
+ -> (MutableWordArray# s -> MutableWordArray# s -> State# s -> State# s)
+ -> (MutableWordArray# s -> MutableWordArray# s -> State# s -> State# s)
+ -> State# s
+ -> State# s
+mwaCompareOp2 mwa mwb f g s =
+ case mwaSize# mwa s of { (# s, szA #) ->
+ case mwaSize# mwb s of { (# s, szB #) ->
+ case newWordArray# szA s of { (# s, mwa' #) ->
+ case newWordArray# szB s of { (# s, mwb' #) ->
+ case f mwa mwb s of { s ->
+ case g mwa' mwb' s of { s ->
+ case mwaTrimZeroes# mwa s of { s ->
+ case mwaTrimZeroes# mwb s of { s ->
+ case mwaTrimZeroes# mwa' s of { s ->
+ case mwaTrimZeroes# mwb' s of { s ->
+ case mwaCompare mwa mwa' s of { (# s, ba #) ->
+ case mwaCompare mwb mwb' s of { (# s, bb #) ->
+ case ba &&# bb of
+ 0# -> case unexpectedValue of _ -> s
+ _ -> s
+ }}}}}}}}}}}}
+
+mwaCompareOpBool
+ :: MutableWordArray# s
+ -> (MutableWordArray# s -> State# s -> (#State# s, Bool# #))
+ -> (MutableWordArray# s -> State# s -> (#State# s, Bool# #))
+ -> State# s
+ -> (# State# s, Bool# #)
+mwaCompareOpBool mwa f g s =
+ case mwaSize# mwa s of { (# s, sz #) ->
+ case newWordArray# sz s of { (# s, mwb #) ->
+ case f mwa s of { (# s, ra #) ->
+ case g mwb s of { (# s, rb #) ->
+ case ra ==# rb of
+ 0# -> case unexpectedValue of _ -> (# s, ra #)
+ _ -> case (ra ==# 1#) of -- don't compare MWAs if overflow signaled!
+ 1# -> (# s, ra #)
+ _ -> case mwaTrimZeroes# mwa s of { s ->
+ case mwaTrimZeroes# mwb s of { s ->
+ case mwaCompare mwa mwb s of
+ (# s, 0# #) -> case unexpectedValue of _ -> (# s, ra #)
+ _ -> (# s, ra #)
+ }}}}}}
+
+mwaCompareOpWord
+ :: MutableWordArray# s
+ -> (MutableWordArray# s -> State# s -> (#State# s, Word# #))
+ -> (MutableWordArray# s -> State# s -> (#State# s, Word# #))
+ -> State# s
+ -> (# State# s, Word# #)
+mwaCompareOpWord mwa f g s =
+ case mwaSize# mwa s of { (# s, sz #) ->
+ case newWordArray# sz s of { (# s, mwb #) ->
+ case f mwa s of { (# s, ra #) ->
+ case g mwb s of { (# s, rb #) ->
+ case mwaTrimZeroes# mwa s of { s ->
+ case mwaTrimZeroes# mwb s of { s ->
+ case mwaCompare mwa mwb s of
+ (# s, b #) -> case b &&# (ra `eqWord#` rb) of
+ 0# -> case unexpectedValue of _ -> (# s, ra #)
+ _ -> (# s, ra #)
+ }}}}}}
+
+bignat_add
+ :: MutableWordArray# RealWorld -- ^ Result
+ -> WordArray#
+ -> WordArray#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_add mwa wa wb
+ = mwaCompareOp mwa
+ (\m -> Other.bignat_add m wa wb)
+ (\m -> Native.bignat_add m wa wb)
+
+bignat_add_word
+ :: MutableWordArray# RealWorld -- ^ Result
+ -> WordArray#
+ -> Word#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_add_word mwa wa b
+ = mwaCompareOp mwa
+ (\m -> Other.bignat_add_word m wa b)
+ (\m -> Native.bignat_add_word m wa b)
+
+bignat_mul_word
+ :: MutableWordArray# RealWorld -- ^ Result
+ -> WordArray#
+ -> Word#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_mul_word mwa wa b
+ = mwaCompareOp mwa
+ (\m -> Other.bignat_mul_word m wa b)
+ (\m -> Native.bignat_mul_word m wa b)
+
+bignat_sub
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> WordArray#
+ -> State# RealWorld
+ -> (# State# RealWorld, Bool# #)
+bignat_sub mwa wa wb
+ = mwaCompareOpBool mwa
+ (\m -> Other.bignat_sub m wa wb)
+ (\m -> Native.bignat_sub m wa wb)
+
+bignat_sub_word
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> Word#
+ -> State# RealWorld
+ -> (# State# RealWorld, Bool# #)
+bignat_sub_word mwa wa b
+ = mwaCompareOpBool mwa
+ (\m -> Other.bignat_sub_word m wa b)
+ (\m -> Native.bignat_sub_word m wa b)
+
+bignat_mul
+ :: MutableWordArray# RealWorld -- ^ Result
+ -> WordArray#
+ -> WordArray#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_mul mwa wa wb
+ = mwaCompareOp mwa
+ (\m -> Other.bignat_mul m wa wb)
+ (\m -> Native.bignat_mul m wa wb)
+
+bignat_popcount :: WordArray# -> Word#
+bignat_popcount wa =
+ let
+ gr = Other.bignat_popcount wa
+ nr = Native.bignat_popcount wa
+ in case gr `eqWord#` nr of
+ 0# -> 1## `quotWord#` 0##
+ _ -> gr
+
+bignat_shiftl
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> Word#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_shiftl mwa wa n
+ = mwaCompareOp mwa
+ (\m -> Other.bignat_shiftl m wa n)
+ (\m -> Native.bignat_shiftl m wa n)
+
+bignat_shiftr
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> Word#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_shiftr mwa wa n
+ = mwaCompareOp mwa
+ (\m -> Other.bignat_shiftr m wa n)
+ (\m -> Native.bignat_shiftr m wa n)
+
+bignat_shiftr_neg
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> Word#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_shiftr_neg mwa wa n
+ = mwaCompareOp mwa
+ (\m -> Other.bignat_shiftr_neg m wa n)
+ (\m -> Native.bignat_shiftr_neg m wa n)
+
+bignat_or
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> WordArray#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_or mwa wa wb
+ = mwaCompareOp mwa
+ (\m -> Other.bignat_or m wa wb)
+ (\m -> Native.bignat_or m wa wb)
+
+bignat_xor
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> WordArray#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_xor mwa wa wb
+ = mwaCompareOp mwa
+ (\m -> Other.bignat_xor m wa wb)
+ (\m -> Native.bignat_xor m wa wb)
+
+bignat_and
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> WordArray#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_and mwa wa wb
+ = mwaCompareOp mwa
+ (\m -> Other.bignat_and m wa wb)
+ (\m -> Native.bignat_and m wa wb)
+
+bignat_and_not
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> WordArray#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_and_not mwa wa wb
+ = mwaCompareOp mwa
+ (\m -> Other.bignat_and_not m wa wb)
+ (\m -> Native.bignat_and_not m wa wb)
+
+bignat_quotrem
+ :: MutableWordArray# RealWorld
+ -> MutableWordArray# RealWorld
+ -> WordArray#
+ -> WordArray#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_quotrem mwq mwr wa wb
+ = mwaCompareOp2 mwq mwr
+ (\m1 m2 -> Other.bignat_quotrem m1 m2 wa wb)
+ (\m1 m2 -> Native.bignat_quotrem m1 m2 wa wb)
+
+bignat_quot
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> WordArray#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_quot mwq wa wb
+ = mwaCompareOp mwq
+ (\m -> Other.bignat_quot m wa wb)
+ (\m -> Native.bignat_quot m wa wb)
+
+bignat_rem
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> WordArray#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_rem mwr wa wb
+ = mwaCompareOp mwr
+ (\m -> Other.bignat_rem m wa wb)
+ (\m -> Native.bignat_rem m wa wb)
+
+bignat_quotrem_word
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> Word#
+ -> State# RealWorld
+ -> (# State# RealWorld, Word# #)
+bignat_quotrem_word mwq wa b
+ = mwaCompareOpWord mwq
+ (\m -> Other.bignat_quotrem_word m wa b)
+ (\m -> Native.bignat_quotrem_word m wa b)
+
+bignat_quot_word
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> Word#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_quot_word mwq wa b
+ = mwaCompareOp mwq
+ (\m -> Other.bignat_quot_word m wa b)
+ (\m -> Native.bignat_quot_word m wa b)
+
+bignat_rem_word
+ :: WordArray#
+ -> Word#
+ -> Word#
+bignat_rem_word wa b =
+ let
+ gr = Other.bignat_rem_word wa b
+ nr = Native.bignat_rem_word wa b
+ in case gr `eqWord#` nr of
+ 1# -> gr
+ _ -> case unexpectedValue of
+ W# e -> e
+
+bignat_gcd
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> WordArray#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_gcd mwr wa wb
+ = mwaCompareOp mwr
+ (\m -> Other.bignat_gcd m wa wb)
+ (\m -> Native.bignat_gcd m wa wb)
+
+bignat_gcd_word
+ :: WordArray#
+ -> Word#
+ -> Word#
+bignat_gcd_word wa b =
+ let
+ gr = Other.bignat_gcd_word wa b
+ nr = Native.bignat_gcd_word wa b
+ in case gr `eqWord#` nr of
+ 1# -> gr
+ _ -> case unexpectedValue of
+ W# e -> e
+
+bignat_gcd_word_word
+ :: Word#
+ -> Word#
+ -> Word#
+bignat_gcd_word_word a b =
+ let
+ gr = Other.bignat_gcd_word_word a b
+ nr = Native.bignat_gcd_word_word a b
+ in case gr `eqWord#` nr of
+ 1# -> gr
+ _ -> case unexpectedValue of
+ W# e -> e
+
+bignat_encode_double :: WordArray# -> Int# -> Double#
+bignat_encode_double a e =
+ let
+ gr = Other.bignat_encode_double a e
+ nr = Native.bignat_encode_double a e
+ in case gr ==## nr of
+ 1# -> gr
+ _ -> case unexpectedValue of
+ _ -> gr
+
+bignat_powmod_word :: WordArray# -> WordArray# -> Word# -> Word#
+bignat_powmod_word b e m =
+ let
+ gr = Other.bignat_powmod_word b e m
+ nr = Native.bignat_powmod_word b e m
+ in case gr `eqWord#` nr of
+ 1# -> gr
+ _ -> case unexpectedValue of
+ W# e -> e
+
+bignat_powmod
+ :: MutableWordArray# RealWorld
+ -> WordArray#
+ -> WordArray#
+ -> WordArray#
+ -> State# RealWorld
+ -> State# RealWorld
+bignat_powmod r b e m
+ = mwaCompareOp r
+ (\r' -> Other.bignat_powmod r' b e m)
+ (\r' -> Native.bignat_powmod r' b e m)
+
+bignat_powmod_words
+ :: Word#
+ -> Word#
+ -> Word#
+ -> Word#
+bignat_powmod_words b e m =
+ let
+ gr = Other.bignat_powmod_words b e m
+ nr = Native.bignat_powmod_words b e m
+ in case gr `eqWord#` nr of
+ 1# -> gr
+ _ -> case unexpectedValue of
+ W# e -> e