redundant rts/StgPrimFloat decodeDouble?

Herbert Valerio Riedel hvriedel at gmail.com
Tue Jul 29 07:50:33 UTC 2014


Hello *,

While working on integer-gmp2 I noticed that there seems to be redundant
code between rts/StgPrimFloat.c and integer-gmp. Specifically, there's a

  void
  __decodeDouble_2Int (I_ *man_sign, W_ *man_high, W_ *man_low, I_ *exp,
                       StgDouble dbl);

C implementation which does some low-level bit-fiddling on the IEEE
representation instead of just using the more portable standard frexp()
function, like I'm doing in integer-gmp2, e.g.:

  HsInt ​integer_gmp_decode_double (const HsDouble x, HsInt64 *const mantisse)
  ​{
   ​ if (x) {
    ​  int exp = 0;
      *mantisse = (HsInt64)scalbn(frexp(x, &exp), DBL_MANT_DIG);
     ​ return exp-DBL_MANT_DIG;
   ​ } else {
    ​  *mantisse = 0;
     ​ return 0;
   ​ }
  ​}

A similiar operation exists in integer-gmp/cbits/float.c

So here's my questions:


 1) Is there any reason/value in doing low-level IEEE bit-fiddling instead of
    just delegating to the C99/POSIX compliant frexp(3) operations?

 2) Specifically, `decodeDouble_2Int` seems to be dead-code. I'd like to
    instead move the 

      HsInt ​integer_gmp_decode_double (const HsDouble x, HsInt64 *const
      mantisse);

    which I currently import as

      #if WORD_SIZE_IN_BITS == 32
       foreign import prim "integer_gmp_cmm_decode_double" 
         cmm_decode_double :: Double# -> (# Int64#, Int# #)
      #elif WORD_SIZE_IN_BITS == 64
       foreign import prim "integer_gmp_cmm_decode_double" 
         cmm_decode_double :: Double# -> (# Int#, Int# #)
      #endif

   based on the size of `Int#` into rts/PrimOps.cmm & rts/StgPrimFloat.c
   as that may allow me to avoid any C-- in integer-gmp2 altogether (as I
   only need to go via C-- to return an unboxed pair)


Cheers,
  hvr


More information about the ghc-devs mailing list