]> Savannah Git Hosting - gnulib.git/commitdiff
vasnprintf: Optimize bit search operation.
authorBruno Haible <bruno@clisp.org>
Sat, 15 Oct 2011 11:20:29 +0000 (13:20 +0200)
committerBruno Haible <bruno@clisp.org>
Sat, 15 Oct 2011 11:20:29 +0000 (13:20 +0200)
* lib/vasnprintf.c (divide): Use optimizations from integer_length.c.
* m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF): Require
gl_DOUBLE_EXPONENT_LOCATION.
* modules/vasnprintf (Files): Add m4/exponentd.m4.
* modules/unistdio/u8-vasnprintf (Files): Likewise.
* modules/unistdio/u8-u8-vasnprintf (Files): Likewise.
* modules/unistdio/u16-vasnprintf (Files): Likewise.
* modules/unistdio/u16-u16-vasnprintf (Files): Likewise.
* modules/unistdio/u32-vasnprintf (Files): Likewise.
* modules/unistdio/u32-u32-vasnprintf (Files): Likewise.
* modules/unistdio/ulc-vasnprintf (Files): Likewise.
* m4/isnand.m4 (gl_PREREQ_ISNAND): Use AC_REQUIRE.

12 files changed:
ChangeLog
lib/vasnprintf.c
m4/isnand.m4
m4/vasnprintf.m4
modules/unistdio/u16-u16-vasnprintf
modules/unistdio/u16-vasnprintf
modules/unistdio/u32-u32-vasnprintf
modules/unistdio/u32-vasnprintf
modules/unistdio/u8-u8-vasnprintf
modules/unistdio/u8-vasnprintf
modules/unistdio/ulc-vasnprintf
modules/vasnprintf

index 43024b3415eccf8912c2eab9f3b7f6c7861d27f4..ee724cd329db91e0718a479c0e25d33ed90e5173 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2011-10-15  Bruno Haible  <bruno@clisp.org>
+
+       vasnprintf: Optimize bit search operation.
+       * lib/vasnprintf.c (divide): Use optimizations from integer_length.c.
+       * m4/vasnprintf.m4 (gl_PREREQ_VASNPRINTF): Require
+       gl_DOUBLE_EXPONENT_LOCATION.
+       * modules/vasnprintf (Files): Add m4/exponentd.m4.
+       * modules/unistdio/u8-vasnprintf (Files): Likewise.
+       * modules/unistdio/u8-u8-vasnprintf (Files): Likewise.
+       * modules/unistdio/u16-vasnprintf (Files): Likewise.
+       * modules/unistdio/u16-u16-vasnprintf (Files): Likewise.
+       * modules/unistdio/u32-vasnprintf (Files): Likewise.
+       * modules/unistdio/u32-u32-vasnprintf (Files): Likewise.
+       * modules/unistdio/ulc-vasnprintf (Files): Likewise.
+       * m4/isnand.m4 (gl_PREREQ_ISNAND): Use AC_REQUIRE.
+
 2011-10-15  Bruno Haible  <bruno@clisp.org>
 
        vasnprintf: Fix comments.
index 9c22475222c59737561eab15ecb7a2abff7fef68..40789f9ebba99ba607b187752ad1d7e7f801e4d8 100644 (file)
@@ -553,32 +553,61 @@ divide (mpn_t a, mpn_t b, mpn_t *q)
       size_t s;
       {
         mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
-        s = 31;
-        if (msd >= 0x10000)
-          {
-            msd = msd >> 16;
-            s -= 16;
-          }
-        if (msd >= 0x100)
-          {
-            msd = msd >> 8;
-            s -= 8;
-          }
-        if (msd >= 0x10)
-          {
-            msd = msd >> 4;
-            s -= 4;
-          }
-        if (msd >= 0x4)
+        /* Determine s = GMP_LIMB_BITS - integer_length (msd).
+           Code copied from gnulib's integer_length.c.  */
+# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+        s = __builtin_clz (msd);
+# else
+#  if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
+        if (GMP_LIMB_BITS <= DBL_MANT_BIT)
           {
-            msd = msd >> 2;
-            s -= 2;
+            /* Use 'double' operations.
+               Assumes an IEEE 754 'double' implementation.  */
+#   define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
+#   define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1)
+#   define NWORDS \
+     ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+            union { double value; unsigned int word[NWORDS]; } m;
+
+            /* Use a single integer to floating-point conversion.  */
+            m.value = msd;
+
+            s = GMP_LIMB_BITS
+                - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
+                   - DBL_EXP_BIAS);
           }
-        if (msd >= 0x2)
+        else
+#   undef NWORDS
+#  endif
           {
-            msd = msd >> 1;
-            s -= 1;
+            s = 31;
+            if (msd >= 0x10000)
+              {
+                msd = msd >> 16;
+                s -= 16;
+              }
+            if (msd >= 0x100)
+              {
+                msd = msd >> 8;
+                s -= 8;
+              }
+            if (msd >= 0x10)
+              {
+                msd = msd >> 4;
+                s -= 4;
+              }
+            if (msd >= 0x4)
+              {
+                msd = msd >> 2;
+                s -= 2;
+              }
+            if (msd >= 0x2)
+              {
+                msd = msd >> 1;
+                s -= 1;
+              }
           }
+# endif
       }
       /* 0 <= s < GMP_LIMB_BITS.
          Copy b, shifting it left by s bits.  */
index 2b18b0ac6df52b736184b3e0b123a772a1e134de..48f1a480781f67f04e0ae9ea6a8fad64e372b2fc 100644 (file)
@@ -1,4 +1,4 @@
-# isnand.m4 serial 10
+# isnand.m4 serial 11
 dnl Copyright (C) 2007-2011 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -43,7 +43,7 @@ AC_DEFUN([gl_FUNC_ISNAND_NO_LIBM],
 dnl Prerequisites of replacement isnand definition. It does not need -lm.
 AC_DEFUN([gl_PREREQ_ISNAND],
 [
-  gl_DOUBLE_EXPONENT_LOCATION
+  AC_REQUIRE([gl_DOUBLE_EXPONENT_LOCATION])
 ])
 
 dnl Test whether isnand() can be used with libm.
index 749d708d9e91c40c0bd38905f45269d164f81810..da0a6d9efc1da4e445c5d4c90a1d0723063f0d6b 100644 (file)
@@ -1,4 +1,4 @@
-# vasnprintf.m4 serial 33
+# vasnprintf.m4 serial 34
 dnl Copyright (C) 2002-2004, 2006-2011 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -64,6 +64,9 @@ AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF],
   dnl Use the _snprintf function only if it is declared (because on NetBSD it
   dnl is defined as a weak alias of snprintf; we prefer to use the latter).
   AC_CHECK_DECLS([_snprintf], , , [[#include <stdio.h>]])
+  dnl Knowing DBL_EXPBIT0_WORD and DBL_EXPBIT0_BIT enables an optimization
+  dnl in the code for NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE.
+  AC_REQUIRE([gl_DOUBLE_EXPONENT_LOCATION])
   dnl We can avoid a lot of code by assuming that snprintf's return value
   dnl conforms to ISO C99. So check that.
   AC_REQUIRE([gl_SNPRINTF_RETVAL_C99])
index d9e37e23adb6181cb2e69e8fbf1a5862951029b8..7a7f46f1113f16c6f94854bd3f23766757624be5 100644 (file)
@@ -13,6 +13,7 @@ m4/longlong.m4
 m4/intmax_t.m4
 m4/stdint_h.m4
 m4/inttypes_h.m4
+m4/exponentd.m4
 
 Depends-on:
 unistdio/base
index 21d19bd0ff98bb91a9a4a843eac46a7bfbf286bb..09e1330b46bcbb758a766fd715ecbd7737c57287 100644 (file)
@@ -13,6 +13,7 @@ m4/longlong.m4
 m4/intmax_t.m4
 m4/stdint_h.m4
 m4/inttypes_h.m4
+m4/exponentd.m4
 
 Depends-on:
 unistdio/base
index c239248ad7669b65af567b543c3a685e02c7009f..ac248bacb6bf0b2e5db3c709874373301a94718c 100644 (file)
@@ -13,6 +13,7 @@ m4/longlong.m4
 m4/intmax_t.m4
 m4/stdint_h.m4
 m4/inttypes_h.m4
+m4/exponentd.m4
 
 Depends-on:
 unistdio/base
index d73ddc8c30313293e3dd81f07348215b472a5575..6539a3ecb6f2a16066a8e162d41d87de4bb203ca 100644 (file)
@@ -13,6 +13,7 @@ m4/longlong.m4
 m4/intmax_t.m4
 m4/stdint_h.m4
 m4/inttypes_h.m4
+m4/exponentd.m4
 
 Depends-on:
 unistdio/base
index 5cc91503e1542eaec7e1c94ce770cfe52d396cdc..52d3c44243e101e88762a32a0b6dd5f90f18dd08 100644 (file)
@@ -13,6 +13,7 @@ m4/longlong.m4
 m4/intmax_t.m4
 m4/stdint_h.m4
 m4/inttypes_h.m4
+m4/exponentd.m4
 
 Depends-on:
 unistdio/base
index 049e5c1f8ec6a345795d36b7ab2dd1b1c6cb4225..adb961688673eff98152648eb5606d64205549ac 100644 (file)
@@ -13,6 +13,7 @@ m4/longlong.m4
 m4/intmax_t.m4
 m4/stdint_h.m4
 m4/inttypes_h.m4
+m4/exponentd.m4
 
 Depends-on:
 unistdio/base
index c3563c5e32d60897926290c2180cc18836f436f9..8caa7ec7b8542348b6f5cb470c3cfc96ef4edc0e 100644 (file)
@@ -13,6 +13,7 @@ m4/longlong.m4
 m4/intmax_t.m4
 m4/stdint_h.m4
 m4/inttypes_h.m4
+m4/exponentd.m4
 
 Depends-on:
 unistdio/base
index da6b28056c9ac0daa59b27cdecf90c8644031a80..54db8926842cb94f84a6f94da401c2bd79437e5f 100644 (file)
@@ -19,6 +19,7 @@ m4/inttypes_h.m4
 m4/vasnprintf.m4
 m4/printf.m4
 m4/math_h.m4
+m4/exponentd.m4
 
 Depends-on:
 alloca-opt