diff options
author | Eric Andersen <andersen@codepoet.org> | 2002-08-15 13:02:13 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2002-08-15 13:02:13 +0000 |
commit | bc46671a9bcacca1e2fab1dd6468e72d954230bf (patch) | |
tree | 9ac3998bb78063fd58ae3841acc519da88e9b048 | |
parent | d5bb6d12f1ffee55f3287cf92a59ed1d8100e737 (diff) | |
download | uClibc-alpine-bc46671a9bcacca1e2fab1dd6468e72d954230bf.tar.bz2 uClibc-alpine-bc46671a9bcacca1e2fab1dd6468e72d954230bf.tar.xz |
Patch from Jarkko to fix drand48 to not use long long when
long long support is disabled in the uClibc Config.
-rw-r--r-- | include/stdlib.h | 2 | ||||
-rw-r--r-- | libc/stdlib/drand48-iter.c | 40 | ||||
-rw-r--r-- | libc/stdlib/srand48_r.c | 6 |
3 files changed, 48 insertions, 0 deletions
diff --git a/include/stdlib.h b/include/stdlib.h index 59aded8f0..555d48a55 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -505,6 +505,8 @@ struct drand48_data unsigned short int __init; /* Flag for initializing. */ #ifdef __UCLIBC_HAS_LONG_LONG__ unsigned long long int __a; /* Factor in congruential formula. */ +#else + unsigned long __a0, __a1; #endif /* __UCLIBC_HAS_LONG_LONG__ */ }; diff --git a/libc/stdlib/drand48-iter.c b/libc/stdlib/drand48-iter.c index a69d03326..3247bafbd 100644 --- a/libc/stdlib/drand48-iter.c +++ b/libc/stdlib/drand48-iter.c @@ -27,6 +27,7 @@ struct drand48_data __libc_drand48_data; +#ifdef __UCLIBC_HAS_LONG_LONG__ int __drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer) { @@ -55,3 +56,42 @@ __drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer) return 0; } + +#else +int +__drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer) +{ + uint32_t X0, X1; + uint32_t result0, result1; + + /* Initialize buffer, if not yet done. */ + if (unlikely(!buffer->__init)) + { + buffer->__a1 = 0x5; + buffer->__a0 = 0xdeece66d; + buffer->__c = 0xb; + buffer->__init = 1; + } + + /* Do the real work. We choose a data type which contains at least + 48 bits. Because we compute the modulus it does not care how + many bits really are computed. */ + + /* X = X1*base32 + X0 */ + X1 = xsubi[2]; + X0 = xsubi[0] | (uint32_t) xsubi[1] << 16; + + result0 = buffer->__a0 * X0; + result1 = (result0 > -buffer->__c ); /* Carry */ + /* If this overflows, the carry is already in result1 */ + result0 += buffer->__c; + + result1 += buffer->__a1*X0 + buffer->__a0*X1; + + xsubi[0] = result0 & 0xffff; + xsubi[1] = result0 >> 16; + xsubi[2] = result1 & 0xffff; + + return 0; +} +#endif diff --git a/libc/stdlib/srand48_r.c b/libc/stdlib/srand48_r.c index c0fa38e90..c7c510864 100644 --- a/libc/stdlib/srand48_r.c +++ b/libc/stdlib/srand48_r.c @@ -32,7 +32,13 @@ int srand48_r (seedval, buffer) buffer->__x[1] = seedval & 0xffffl; buffer->__x[0] = 0x330e; +#ifdef __UCLIBC_HAS_LONG_LONG__ buffer->__a = 0x5deece66dull; +#else + buffer->__a1 = 0x5; + buffer->__a0 = 0xdeece66d; +#endif + buffer->__c = 0xb; buffer->__init = 1; |