summaryrefslogtreecommitdiffstats
path: root/gettext-runtime/libasprintf
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2011-10-15 13:24:29 +0200
committerBruno Haible <bruno@clisp.org>2011-10-15 13:24:55 +0200
commit61e3e44b2a49643c05f0f5c0221d5a2ae3d363fd (patch)
tree1b4f377b2b8b1e7472738f65586341a5fa0ba1a9 /gettext-runtime/libasprintf
parentf17ea2fd4bac7cdb3d934378cbcdce6b1118beb7 (diff)
downloadexternal_gettext-61e3e44b2a49643c05f0f5c0221d5a2ae3d363fd.zip
external_gettext-61e3e44b2a49643c05f0f5c0221d5a2ae3d363fd.tar.gz
external_gettext-61e3e44b2a49643c05f0f5c0221d5a2ae3d363fd.tar.bz2
Update from gnulib.
Diffstat (limited to 'gettext-runtime/libasprintf')
-rw-r--r--gettext-runtime/libasprintf/ChangeLog6
-rw-r--r--gettext-runtime/libasprintf/vasnprintf.c73
2 files changed, 57 insertions, 22 deletions
diff --git a/gettext-runtime/libasprintf/ChangeLog b/gettext-runtime/libasprintf/ChangeLog
index da626d5..7032d00 100644
--- a/gettext-runtime/libasprintf/ChangeLog
+++ b/gettext-runtime/libasprintf/ChangeLog
@@ -1,5 +1,11 @@
2011-10-15 Bruno Haible <bruno@clisp.org>
+ vasnprintf: Optimize bit search operation.
+ * vasnprintf.c (divide): Use optimizations from gnulib's
+ integer_length.c.
+
+2011-10-15 Bruno Haible <bruno@clisp.org>
+
vasnprintf: Fix comments.
* vasnprintf.c (decode_long_double, decode_double): Fix comments.
diff --git a/gettext-runtime/libasprintf/vasnprintf.c b/gettext-runtime/libasprintf/vasnprintf.c
index 665d599..c6676c0 100644
--- a/gettext-runtime/libasprintf/vasnprintf.c
+++ b/gettext-runtime/libasprintf/vasnprintf.c
@@ -552,32 +552,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. */