diff options
Diffstat (limited to 'libc/stdlib')
| -rw-r--r-- | libc/stdlib/drand48-iter.c | 40 | ||||
| -rw-r--r-- | libc/stdlib/srand48_r.c | 6 | 
2 files changed, 46 insertions, 0 deletions
| 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; | 
