[commit: ghc] wip/T9281: Implement `decodeDouble_Int64#` primop (50bf0be)

git at git.haskell.org git at git.haskell.org
Sun Aug 17 11:45:33 UTC 2014


Repository : ssh://git@git.haskell.org/ghc

On branch  : wip/T9281
Link       : http://ghc.haskell.org/trac/ghc/changeset/50bf0bef2b22f6d26a31eebf807a919bf64a3319/ghc

>---------------------------------------------------------------

commit 50bf0bef2b22f6d26a31eebf807a919bf64a3319
Author: Herbert Valerio Riedel <hvr at gnu.org>
Date:   Sat Aug 16 00:46:18 2014 +0200

    Implement `decodeDouble_Int64#` primop
    
    Summary:
    The existing `decodeDouble_2Int#` primop is rather inconvenient to use
    (and in fact is not even used by `integer-gmp`) as the mantissa is split
    into 3 components which would actually fit in an `Int64#` value.
    
    However, `decodeDouble_Int64#` is to be used by the new `integer-gmp2`
    re-implementation (see #9281).
    
    Moreover, `decodeDouble_2Int#` performs direct bit-wise operations on the
    IEEE representation which can be replaced by a combination of the
    portable standard C99 `scalbn(3)` and `frexp(3)` functions.
    
    Test Plan: tested via `integer-gmp2`
    
    Reviewers: simonmar, austin
    
    Subscribers: simonmar, relrod, ezyang, carter
    
    Differential Revision: https://phabricator.haskell.org/D160
    
    GHC Trac Issues: #9281


>---------------------------------------------------------------

50bf0bef2b22f6d26a31eebf807a919bf64a3319
 compiler/prelude/primops.txt.pp |  5 +++++
 includes/stg/MiscClosures.h     |  1 +
 rts/Linker.c                    |  1 +
 rts/PrimOps.cmm                 | 17 +++++++++++++++++
 rts/StgPrimFloat.c              | 18 ++++++++++++++++++
 rts/StgPrimFloat.h              |  1 +
 6 files changed, 43 insertions(+)

diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp
index d5566fe..8972115 100644
--- a/compiler/prelude/primops.txt.pp
+++ b/compiler/prelude/primops.txt.pp
@@ -606,6 +606,11 @@ primop   DoubleDecode_2IntOp   "decodeDouble_2Int#" GenPrimOp
     respectively, and the last is the exponent.}
    with out_of_line = True
 
+primop   DoubleDecode_Int64Op   "decodeDouble_Int64#" GenPrimOp
+   Double# -> (# INT64, Int# #)
+   {Decode {\tt Double\#} into mantissa and base-2 exponent.}
+   with out_of_line = True
+
 ------------------------------------------------------------------------
 section "Float#"
 	{Operations on single-precision (32-bit) floating-point numbers.}
diff --git a/includes/stg/MiscClosures.h b/includes/stg/MiscClosures.h
index d2b933d..0d323e2 100644
--- a/includes/stg/MiscClosures.h
+++ b/includes/stg/MiscClosures.h
@@ -341,6 +341,7 @@ RTS_FUN_DECL(StgReturn);
 
 RTS_FUN_DECL(stg_decodeFloatzuIntzh);
 RTS_FUN_DECL(stg_decodeDoublezu2Intzh);
+RTS_FUN_DECL(stg_decodeDoublezuInt64zh);
 
 RTS_FUN_DECL(stg_unsafeThawArrayzh);
 RTS_FUN_DECL(stg_casArrayzh);
diff --git a/rts/Linker.c b/rts/Linker.c
index a0ad90c..07a330e 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1106,6 +1106,7 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(cmp_thread)                                         \
       SymI_HasProto(createAdjustor)                                     \
       SymI_HasProto(stg_decodeDoublezu2Intzh)                           \
+      SymI_HasProto(stg_decodeDoublezuInt64zh)                          \
       SymI_HasProto(stg_decodeFloatzuIntzh)                             \
       SymI_HasProto(defaultsHook)                                       \
       SymI_HasProto(stg_delayzh)                                        \
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index ee50f7f..cb4cd5e 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -22,6 +22,7 @@
  * ---------------------------------------------------------------------------*/
 
 #include "Cmm.h"
+#include "MachDeps.h"
 
 #ifdef __PIC__
 import pthread_mutex_lock;
@@ -807,6 +808,22 @@ stg_decodeDoublezu2Intzh ( D_ arg )
     return (r1, r2, r3, r4);
 }
 
+/* Double# -> (# Int64#, Int# #) */
+stg_decodeDoublezuInt64zh ( D_ arg )
+{
+    CInt exp;
+    I64  mant;
+    W_   mant_ptr;
+
+    STK_CHK_GEN_N (SIZEOF_INT64);
+    reserve BYTES_TO_WDS(SIZEOF_INT64) = mant_ptr {
+        (exp) = ccall __decodeDouble_Int64(mant_ptr "ptr", arg);
+        mant = I64[mant_ptr];
+    }
+
+    return (mant, TO_W_(exp));
+}
+
 /* -----------------------------------------------------------------------------
  * Concurrency primitives
  * -------------------------------------------------------------------------- */
diff --git a/rts/StgPrimFloat.c b/rts/StgPrimFloat.c
index 63fe52e..5f60db7 100644
--- a/rts/StgPrimFloat.c
+++ b/rts/StgPrimFloat.c
@@ -17,6 +17,10 @@
 
 #define IEEE_FLOATING_POINT 1
 
+#if FLT_RADIX != 2
+# error FLT_RADIX != 2 not supported
+#endif
+
 /*
  * Encoding and decoding Doubles.  Code based on the HBC code
  * (lib/fltcode.c).
@@ -158,6 +162,20 @@ __decodeDouble_2Int (I_ *man_sign, W_ *man_high, W_ *man_low, I_ *exp, StgDouble
     }
 }
 
+/* This is expected to replace uses of __decodeDouble_2Int() in the long run */
+StgInt
+__decodeDouble_Int64 (StgInt64 *const mantissa, const StgDouble dbl)
+{
+    if (dbl) {
+        int exp = 0;
+        *mantissa = (StgInt64)scalbn(frexp(dbl, &exp), DBL_MANT_DIG);
+        return exp-DBL_MANT_DIG;
+    } else {
+        *mantissa = 0;
+        return 0;
+    }
+}
+
 /* Convenient union types for checking the layout of IEEE 754 types -
    based on defs in GNU libc <ieee754.h>
 */
diff --git a/rts/StgPrimFloat.h b/rts/StgPrimFloat.h
index fefe8c9..617888c 100644
--- a/rts/StgPrimFloat.h
+++ b/rts/StgPrimFloat.h
@@ -12,6 +12,7 @@
 #include "BeginPrivate.h"
 
 /* grimy low-level support functions defined in StgPrimFloat.c */
+StgInt    __decodeDouble_Int64 (StgInt64 *mantissa, StgDouble dbl);
 void      __decodeDouble_2Int (I_ *man_sign, W_ *man_high, W_ *man_low, I_ *exp, StgDouble dbl);
 void      __decodeFloat_Int (I_ *man, I_ *exp, StgFloat flt);
 



More information about the ghc-commits mailing list