This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
middle-end/3616: Internal compiler error in update_equiv_regs
- To: gcc-gnats at gcc dot gnu dot org
- Subject: middle-end/3616: Internal compiler error in update_equiv_regs
- From: Eamon Hughes <eh at sonyoxford dot co dot uk>
- Date: Mon, 9 Jul 2001 13:19:57 +0100
>Number: 3616
>Category: middle-end
>Synopsis: Internal compiler error in update_equiv_regs
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Jul 09 05:26:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Eamon Hughes
>Release: 3.0
>Organization:
>Environment:
System: OSF1 vodka V4.0 1091 alpha
Machine: alpha
host: alphaev56-dec-osf4.0e
build: alphaev56-dec-osf4.0e
target: m68k-unknown-coff
configured with: ../../source/gcc-3.0/configure --target=m68k-coff --enable-languages=c --prefix=/usr/cross -v
>Description:
When compiling newlib-1.8.2 I get the following output...
Making all in stdlib
make[3]: Entering directory `/gnu/m68k-coff/newlib-1.8.2/m68k-coff/newlib/libc/stdlib'
m68k-coff-gcc -DPACKAGE=\"newlib\" -DVERSION=\"1.8.2\" -I. -I../../../../../../source/newlib-1.8.2/newlib/libc/stdlib -O2 -DMISSING_SYSCALL_NAMES -I../../targ-include -I../../../../../../source/newlib-1.8.2/newlib/libc/../libc/include -fno-builtin -g -O2 -W -Wall -c ../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c: In function `_dtoa_r':
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:294: warning: suggest parentheses around assignment used as truth value
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:340: warning: suggest parentheses around + or - inside shift
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:341: warning: suggest parentheses around + or - inside shift
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:341: warning: suggest parentheses around + or - inside shift
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:418: warning: comparison between signed and unsigned
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:452: warning: suggest parentheses around assignment used as truth value
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:567: warning: suggest parentheses around && within ||
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:643: warning: suggest parentheses around assignment used as truth value
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:681: warning: suggest parentheses around assignment used as truth value
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:772: warning: suggest parentheses around && within ||
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:778: warning: suggest parentheses around && within ||
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:822: warning: suggest parentheses around && within ||
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:224: warning: `ilim' might be used uninitialized in this function
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:224: warning: `ilim1' might be used uninitialized in this function
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:225: warning: `spec_case' might be used uninitialized in this function
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:232: warning: `mlo' might be used uninitialized in this function
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:854: Internal compiler error in update_equiv_regs, at local-alloc.c:1097
Please submit a full bug report,
with preprocessed source if appropriate.
Again with -v and -save-temps...
m68k-coff-gcc -DPACKAGE=\"newlib\" -DVERSION=\"1.8.2\" -I. -I../../../../../../source/newlib-1.8.2/newlib/libc/stdlib -O2 -DMISSING_SYSCALL_NAMES -I../../targ-include -I../../../../../../source/newlib-1.8.2/newlib/libc/../libc/include -fno-builtin -g -O2 -W -Wall -c ../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c -save-temps -v
Reading specs from /usr/cross/lib/gcc-lib/m68k-coff/3.0/specs
Configured with: ../../source/gcc-3.0/configure --target=m68k-coff --enable-languages=c --prefix=/usr/cross -v
Thread model: single
gcc version 3.0
/usr/cross/lib/gcc-lib/m68k-coff/3.0/cpp0 -lang-c -v -I. -I../../../../../../source/newlib-1.8.2/newlib/libc/stdlib -I../../targ-include -I../../../../../../source/newlib-1.8.2/newlib/libc/../libc/include -D__GNUC__=3 -D__GNUC_MINOR__=0 -D__GNUC_PATCHLEVEL__=0 -Dmc68000 -D__embedded__ -D__mc68000__ -D__embedded__ -D__mc68000 -Asystem=embedded -Amachine=mc68000 -D__OPTIMIZE__ -D__STDC_HOSTED__=1 -W -Wall -D__HAVE_68881__ -Dmc68020 -D__mc68020 -D__mc68020__ -DPACKAGE="newlib" -DVERSION="1.8.2" -DMISSING_SYSCALL_NAMES ../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c dtoa.i
GNU CPP version 3.0 (cpplib) (68k, Motorola syntax)
ignoring nonexistent directory "/usr/cross/m68k-coff/sys-include"
ignoring nonexistent directory "/usr/cross/m68k-coff/include"
#include "..." search starts here:
#include <...> search starts here:
.
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib
../../targ-include
../../../../../../source/newlib-1.8.2/newlib/libc/include
/usr/cross/lib/gcc-lib/m68k-coff/3.0/include
End of search list.
/usr/cross/lib/gcc-lib/m68k-coff/3.0/cc1 -fpreprocessed dtoa.i -quiet -dumpbase dtoa.c -g -O2 -O2 -W -Wall -version -fno-builtin -o dtoa.s
GNU CPP version 3.0 (cpplib) (68k, Motorola syntax)
GNU C version 3.0 (m68k-coff)
compiled by GNU C version 3.0.
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c: In function `_dtoa_r':
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:294: warning: suggest parentheses around assignment used as truth value
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:340: warning: suggest parentheses around + or - inside shift
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:341: warning: suggest parentheses around + or - inside shift
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:341: warning: suggest parentheses around + or - inside shift
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:418: warning: comparison between signed and unsigned
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:452: warning: suggest parentheses around assignment used as truth value
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:567: warning: suggest parentheses around && within ||
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:643: warning: suggest parentheses around assignment used as truth value
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:681: warning: suggest parentheses around assignment used as truth value
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:772: warning: suggest parentheses around && within ||
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:778: warning: suggest parentheses around && within ||
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:822: warning: suggest parentheses around && within ||
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:224: warning: `ilim' might be used uninitialized in this function
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:224: warning: `ilim1' might be used uninitialized in this function
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:225: warning: `spec_case' might be used uninitialized in this function
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:232: warning: `mlo' might be used uninitialized in this function
../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c:854: Internal compiler error in update_equiv_regs, at local-alloc.c:1097
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://www.gnu.org/software/gcc/bugs.html> for instructions.
>How-To-Repeat:
Preprocessed file.
/gnu/m68k-coff/newlib-1.8.2/m68k-coff/newlib/libc/stdlib/dtoa.i
# 29 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c"
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/_ansi.h" 1
# 15 "../../../../../../source/newlib-1.8.2/newlib/libc/include/_ansi.h"
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/config.h" 1
# 106 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/config.h"
typedef int __int32_t;
typedef unsigned int __uint32_t;
# 16 "../../../../../../source/newlib-1.8.2/newlib/libc/include/_ansi.h" 2
# 30 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/stdlib.h" 1
# 13 "../../../../../../source/newlib-1.8.2/newlib/libc/include/stdlib.h"
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/_ansi.h" 1
# 14 "../../../../../../source/newlib-1.8.2/newlib/libc/include/stdlib.h" 2
# 1 "/usr/cross/lib/gcc-lib/m68k-coff/3.0/include/stddef.h" 1 3
# 199 "/usr/cross/lib/gcc-lib/m68k-coff/3.0/include/stddef.h" 3
typedef long unsigned int size_t;
# 287 "/usr/cross/lib/gcc-lib/m68k-coff/3.0/include/stddef.h" 3
typedef long int wchar_t;
# 18 "../../../../../../source/newlib-1.8.2/newlib/libc/include/stdlib.h" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/reent.h" 1
# 13 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/reent.h"
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/_ansi.h" 1
# 14 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/reent.h" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/time.h" 1
# 10 "../../../../../../source/newlib-1.8.2/newlib/libc/include/time.h"
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/_ansi.h" 1
# 11 "../../../../../../source/newlib-1.8.2/newlib/libc/include/time.h" 2
# 21 "../../../../../../source/newlib-1.8.2/newlib/libc/include/time.h"
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/machine/time.h" 1
# 22 "../../../../../../source/newlib-1.8.2/newlib/libc/include/time.h" 2
# 30 "../../../../../../source/newlib-1.8.2/newlib/libc/include/time.h"
# 1 "/usr/cross/lib/gcc-lib/m68k-coff/3.0/include/stddef.h" 1 3
# 31 "../../../../../../source/newlib-1.8.2/newlib/libc/include/time.h" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/machine/types.h" 1
# 34 "../../../../../../source/newlib-1.8.2/newlib/libc/include/time.h" 2
typedef unsigned long clock_t;
typedef long time_t;
struct tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
clock_t clock (void);
double difftime (time_t _time2, time_t _time1);
time_t mktime (struct tm *_timeptr);
time_t time (time_t *_timer);
char *asctime (const struct tm *_tblock);
char *ctime (const time_t *_time);
struct tm *gmtime (const time_t *_timer);
struct tm *localtime (const time_t *_timer);
size_t strftime (char *_s, size_t _maxsize, const char *_fmt, const struct tm *_t);
char *asctime_r (const struct tm *, char *);
char *ctime_r (const time_t *, char *);
struct tm *gmtime_r (const time_t *, struct tm *);
struct tm *localtime_r (const time_t *, struct tm *);
# 15 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/reent.h" 2
# 28 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/reent.h"
typedef __uint32_t __ULong;
struct _glue
{
struct _glue *_next;
int _niobs;
struct __sFILE *_iobs;
};
struct _Bigint
{
struct _Bigint *_next;
int _k, _maxwds, _sign, _wds;
__ULong _x[1];
};
struct _atexit {
struct _atexit *_next;
int _ind;
void (*_fns[32])(void);
};
# 64 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/reent.h"
struct __sbuf {
unsigned char *_base;
int _size;
};
typedef long _fpos_t;
# 102 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/reent.h"
struct __sFILE {
unsigned char *_p;
int _r;
int _w;
short _flags;
short _file;
struct __sbuf _bf;
int _lbfsize;
void * _cookie;
int (*_read) (void * _cookie, char *_buf, int _n);
int (*_write) (void * _cookie, const char *_buf, int _n);
_fpos_t (*_seek) (void * _cookie, _fpos_t _offset, int _whence);
int (*_close) (void * _cookie);
struct __sbuf _ub;
unsigned char *_up;
int _ur;
unsigned char _ubuf[3];
unsigned char _nbuf[1];
struct __sbuf _lb;
int _blksize;
int _offset;
struct _reent *_data;
};
# 146 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/reent.h"
struct _reent
{
int _errno;
struct __sFILE *_stdin, *_stdout, *_stderr;
int _inc;
char _emergency[25];
int _current_category;
const char *_current_locale;
int __sdidinit;
void (*__cleanup) (struct _reent *);
struct _Bigint *_result;
int _result_k;
struct _Bigint *_p5s;
struct _Bigint **_freelist;
int _cvtlen;
char *_cvtbuf;
union
{
struct
{
unsigned int _rand_next;
char * _strtok_last;
char _asctime_buf[26];
struct tm _localtime_buf;
int _gamma_signgam;
} _reent;
struct
{
unsigned char * _nextf[30];
unsigned int _nmalloc[30];
} _unused;
} _new;
struct _atexit *_atexit;
struct _atexit _atexit0;
void (**(_sig_func))(int);
struct _glue __sglue;
struct __sFILE __sf[3];
};
# 225 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/reent.h"
extern struct _reent *_impure_ptr ;
void _reclaim_reent (struct _reent *);
# 20 "../../../../../../source/newlib-1.8.2/newlib/libc/include/stdlib.h" 2
typedef struct
{
int quot;
int rem;
} div_t;
typedef struct
{
long quot;
long rem;
} ldiv_t;
# 45 "../../../../../../source/newlib-1.8.2/newlib/libc/include/stdlib.h"
extern int __mb_cur_max;
void abort (void) __attribute__ ((noreturn));
int abs (int);
int atexit (void (*__func)(void));
double atof (const char *__nptr);
float atoff (const char *__nptr);
int atoi (const char *__nptr);
long atol (const char *__nptr);
void * bsearch (const void * __key, const void * __base, size_t __nmemb, size_t __size, int (*_compar) (const void *, const void *));
void * calloc (size_t __nmemb, size_t __size);
div_t div (int __numer, int __denom);
void exit (int __status) __attribute__ ((noreturn));
void free (void *);
char * getenv (const char *__string);
char * _getenv_r (struct _reent *, const char *__string);
char * _findenv (const char *, int *);
char * _findenv_r (struct _reent *, const char *, int *);
long labs (long);
ldiv_t ldiv (long __numer, long __denom);
void * malloc (size_t __size);
int mblen (const char *, size_t);
int _mblen_r (struct _reent *, const char *, size_t, int *);
int mbtowc (wchar_t *, const char *, size_t);
int _mbtowc_r (struct _reent *, wchar_t *, const char *, size_t, int *);
int wctomb (char *, wchar_t);
int _wctomb_r (struct _reent *, char *, wchar_t, int *);
size_t mbstowcs (wchar_t *, const char *, size_t);
size_t _mbstowcs_r (struct _reent *, wchar_t *, const char *, size_t, int *);
size_t wcstombs (char *, const wchar_t *, size_t);
size_t _wcstombs_r (struct _reent *, char *, const wchar_t *, size_t, int *);
void qsort (void * __base, size_t __nmemb, size_t __size, int(*_compar)(const void *, const void *));
int rand (void);
void * realloc (void * __r, size_t __size);
void srand (unsigned __seed);
double strtod (const char *__n, char **_end_PTR);
float strtodf (const char *__n, char **_end_PTR);
long strtol (const char *__n, char **_end_PTR, int __base);
unsigned long strtoul (const char *_n_PTR, char **_end_PTR, int __base);
unsigned long _strtoul_r (struct _reent *,const char *_n_PTR, char **_end_PTR, int __base);
int system (const char *__string);
void cfree (void *);
int putenv (const char *__string);
int setenv (const char *__string, const char *__value, int __overwrite);
int _setenv_r (struct _reent *, const char *__string, const char *__value, int __overwrite);
char * gcvt (double,int,char *);
char * gcvtf (float,int,char *);
char * fcvt (double,int,int *,int *);
char * fcvtf (float,int,int *,int *);
char * ecvt (double,int,int *,int *);
char * ecvtbuf (double, int, int*, int*, char *);
char * fcvtbuf (double, int, int*, int*, char *);
char * ecvtf (float,int,int *,int *);
char * dtoa (double, int, int, int *, int*, char**);
int rand_r (unsigned *__seed);
# 127 "../../../../../../source/newlib-1.8.2/newlib/libc/include/stdlib.h"
char * _dtoa_r (struct _reent *, double, int, int, int *, int*, char**);
void * _malloc_r (struct _reent *, size_t);
void * _calloc_r (struct _reent *, size_t, size_t);
void _free_r (struct _reent *, void *);
void * _realloc_r (struct _reent *, void *, size_t);
void _mstats_r (struct _reent *, char *);
int _system_r (struct _reent *, const char *);
void __eprintf (const char *, const char *, unsigned int, const char *);
# 31 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/reent.h" 1
# 48 "../../../../../../source/newlib-1.8.2/newlib/libc/include/reent.h"
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/reent.h" 1
# 49 "../../../../../../source/newlib-1.8.2/newlib/libc/include/reent.h" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/_types.h" 1
# 12 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/_types.h"
typedef long _off_t;
typedef long _ssize_t;
# 50 "../../../../../../source/newlib-1.8.2/newlib/libc/include/reent.h" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/machine/types.h" 1
# 51 "../../../../../../source/newlib-1.8.2/newlib/libc/include/reent.h" 2
# 1 "/usr/cross/lib/gcc-lib/m68k-coff/3.0/include/stddef.h" 1 3
# 54 "../../../../../../source/newlib-1.8.2/newlib/libc/include/reent.h" 2
struct stat;
struct tms;
struct timeval;
struct timezone;
extern int _close_r (struct _reent *, int);
extern int _execve_r (struct _reent *, char *, char **, char **);
extern int _fcntl_r (struct _reent *, int, int, int);
extern int _fork_r (struct _reent *);
extern int _fstat_r (struct _reent *, int, struct stat *);
extern int _getpid_r (struct _reent *);
extern int _kill_r (struct _reent *, int, int);
extern int _link_r (struct _reent *, const char *, const char *);
extern _off_t _lseek_r (struct _reent *, int, _off_t, int);
extern int _open_r (struct _reent *, const char *, int, int);
extern _ssize_t _read_r (struct _reent *, int, void *, size_t);
extern void *_sbrk_r (struct _reent *, size_t);
extern int _stat_r (struct _reent *, const char *, struct stat *);
extern unsigned long _times_r (struct _reent *, struct tms *);
extern int _unlink_r (struct _reent *, const char *);
extern int _wait_r (struct _reent *, int *);
extern _ssize_t _write_r (struct _reent *, int, const void *, size_t);
extern int _gettimeofday_r (struct _reent *, struct timeval *tp, struct timezone *tzp);
# 32 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/string.h" 1
# 14 "../../../../../../source/newlib-1.8.2/newlib/libc/include/string.h"
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/_ansi.h" 1
# 15 "../../../../../../source/newlib-1.8.2/newlib/libc/include/string.h" 2
# 1 "/usr/cross/lib/gcc-lib/m68k-coff/3.0/include/stddef.h" 1 3
# 18 "../../../../../../source/newlib-1.8.2/newlib/libc/include/string.h" 2
void * memchr (const void *, int, size_t);
int memcmp (const void *, const void *, size_t);
void * memcpy (void *, const void *, size_t);
void * memmove (void *, const void *, size_t);
void * memset (void *, int, size_t);
char *strcat (char *, const char *);
char *strchr (const char *, int);
int strcmp (const char *, const char *);
int strcoll (const char *, const char *);
char *strcpy (char *, const char *);
size_t strcspn (const char *, const char *);
char *strerror (int);
size_t strlen (const char *);
char *strncat (char *, const char *, size_t);
int strncmp (const char *, const char *, size_t);
char *strncpy (char *, const char *, size_t);
char *strpbrk (const char *, const char *);
char *strrchr (const char *, int);
size_t strspn (const char *, const char *);
char *strstr (const char *, const char *);
char *strtok (char *, const char *);
size_t strxfrm (char *, const char *, size_t);
char *strtok_r (char *, const char *, char **);
int bcmp (const char *, const char *, size_t);
void bcopy (const char *, char *, size_t);
void bzero (char *, size_t);
int ffs (int);
char *index (const char *, int);
void * memccpy (void *, const void *, int, size_t);
char *rindex (const char *, int);
int strcasecmp (const char *, const char *);
char *strdup (const char *);
int strncasecmp (const char *, const char *, size_t);
char *strsep (char **, const char *);
char *strlwr (char *);
char *strupr (char *);
# 33 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/mprec.h" 1
# 29 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/mprec.h"
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/ieeefp.h" 1
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/_ansi.h" 1
# 5 "../../../../../../source/newlib-1.8.2/newlib/libc/include/ieeefp.h" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/machine/ieeefp.h" 1
# 7 "../../../../../../source/newlib-1.8.2/newlib/libc/include/ieeefp.h" 2
# 16 "../../../../../../source/newlib-1.8.2/newlib/libc/include/ieeefp.h"
typedef union
{
double value;
struct
{
unsigned int sign : 1;
unsigned int exponent: 11;
unsigned int fraction0:4;
unsigned int fraction1:16;
unsigned int fraction2:16;
unsigned int fraction3:16;
} number;
struct
{
unsigned int sign : 1;
unsigned int exponent: 11;
unsigned int quiet:1;
unsigned int function0:3;
unsigned int function1:16;
unsigned int function2:16;
unsigned int function3:16;
} nan;
struct
{
unsigned long msw;
unsigned long lsw;
} parts;
long aslong[2];
} __ieee_double_shape_type;
# 97 "../../../../../../source/newlib-1.8.2/newlib/libc/include/ieeefp.h"
typedef union
{
float value;
struct
{
unsigned int sign : 1;
unsigned int exponent: 8;
unsigned int fraction0: 7;
unsigned int fraction1: 16;
} number;
struct
{
unsigned int sign:1;
unsigned int exponent:8;
unsigned int quiet:1;
unsigned int function0:6;
unsigned int function1:16;
} nan;
long p1;
} __ieee_float_shape_type;
# 153 "../../../../../../source/newlib-1.8.2/newlib/libc/include/ieeefp.h"
typedef int fp_rnd;
fp_rnd fpgetround (void);
fp_rnd fpsetround (fp_rnd);
typedef int fp_except;
fp_except fpgetmask (void);
fp_except fpsetmask (fp_except);
fp_except fpgetsticky (void);
fp_except fpsetsticky (fp_except);
typedef int fp_rdi;
fp_rdi fpgetroundtoi (void);
fp_rdi fpsetroundtoi (fp_rdi);
int isnan (double);
int isinf (double);
int finite (double);
int isnanf (float);
int isinff (float);
int finitef (float);
# 30 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/mprec.h" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/math.h" 1
# 9 "../../../../../../source/newlib-1.8.2/newlib/libc/include/math.h"
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/reent.h" 1
# 10 "../../../../../../source/newlib-1.8.2/newlib/libc/include/math.h" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/machine/ieeefp.h" 1
# 11 "../../../../../../source/newlib-1.8.2/newlib/libc/include/math.h" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/_ansi.h" 1
# 12 "../../../../../../source/newlib-1.8.2/newlib/libc/include/math.h" 2
union __dmath
{
__uint32_t i[2];
double d;
};
extern const union __dmath __infinity;
# 33 "../../../../../../source/newlib-1.8.2/newlib/libc/include/math.h"
extern double atan (double);
extern double cos (double);
extern double sin (double);
extern double tan (double);
extern double tanh (double);
extern double frexp (double, int *);
extern double modf (double, double *);
extern double ceil (double);
extern double fabs (double);
extern double floor (double);
extern double acos (double);
extern double asin (double);
extern double atan2 (double, double);
extern double cosh (double);
extern double sinh (double);
extern double exp (double);
extern double ldexp (double, int);
extern double log (double);
extern double log10 (double);
extern double pow (double, double);
extern double sqrt (double);
extern double fmod (double, double);
extern double infinity (void);
extern double nan (void);
extern int isnan (double);
extern int isinf (double);
extern int finite (double);
extern double copysign (double, double);
extern int ilogb (double);
extern double asinh (double);
extern double cbrt (double);
extern double nextafter (double, double);
extern double rint (double);
extern double scalbn (double, int);
extern double log1p (double);
extern double expm1 (double);
extern double acosh (double);
extern double atanh (double);
extern double remainder (double, double);
extern double gamma (double);
extern double gamma_r (double, int *);
extern double lgamma (double);
extern double lgamma_r (double, int *);
extern double erf (double);
extern double erfc (double);
extern double y0 (double);
extern double y1 (double);
extern double yn (int, double);
extern double j0 (double);
extern double j1 (double);
extern double jn (int, double);
extern double hypot (double, double);
extern double cabs();
extern double drem (double, double);
extern float atanf (float);
extern float cosf (float);
extern float sinf (float);
extern float tanf (float);
extern float tanhf (float);
extern float frexpf (float, int *);
extern float modff (float, float *);
extern float ceilf (float);
extern float fabsf (float);
extern float floorf (float);
extern float acosf (float);
extern float asinf (float);
extern float atan2f (float, float);
extern float coshf (float);
extern float sinhf (float);
extern float expf (float);
extern float ldexpf (float, int);
extern float logf (float);
extern float log10f (float);
extern float powf (float, float);
extern float sqrtf (float);
extern float fmodf (float, float);
extern float infinityf (void);
extern float nanf (void);
extern int isnanf (float);
extern int isinff (float);
extern int finitef (float);
extern float copysignf (float, float);
extern int ilogbf (float);
extern float asinhf (float);
extern float cbrtf (float);
extern float nextafterf (float, float);
extern float rintf (float);
extern float scalbnf (float, int);
extern float log1pf (float);
extern float expm1f (float);
extern float acoshf (float);
extern float atanhf (float);
extern float remainderf (float, float);
extern float gammaf (float);
extern float gammaf_r (float, int *);
extern float lgammaf (float);
extern float lgammaf_r (float, int *);
extern float erff (float);
extern float erfcf (float);
extern float y0f (float);
extern float y1f (float);
extern float ynf (int, float);
extern float j0f (float);
extern float j1f (float);
extern float jnf (int, float);
extern float hypotf (float, float);
extern float cabsf();
extern float dremf (float, float);
extern int signgam;
struct exception
{
int type;
char *name;
double arg1;
double arg2;
double retval;
int err;
};
extern int matherr (struct exception *e);
# 246 "../../../../../../source/newlib-1.8.2/newlib/libc/include/math.h"
enum __fdlibm_version
{
__fdlibm_ieee = -1,
__fdlibm_svid,
__fdlibm_xopen,
__fdlibm_posix
};
extern const enum __fdlibm_version __fdlib_version;
# 31 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/mprec.h" 2
# 1 "/usr/cross/lib/gcc-lib/m68k-coff/3.0/include/float.h" 1 3
# 32 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/mprec.h" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/errno.h" 1
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/errno.h" 1
# 11 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/errno.h"
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/reent.h" 1
# 12 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/errno.h" 2
extern int *__errno (void);
extern const char * const _sys_errlist[];
extern int _sys_nerr;
# 2 "../../../../../../source/newlib-1.8.2/newlib/libc/include/errno.h" 2
# 33 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/mprec.h" 2
# 1 "../../../../../../source/newlib-1.8.2/newlib/libc/include/sys/config.h" 1
# 34 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/mprec.h" 2
# 66 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/mprec.h"
union double_union
{
double d;
__uint32_t i[2];
};
# 259 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/mprec.h"
typedef struct _Bigint _Bigint;
# 282 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/mprec.h"
struct _reent ;
double _ulp (double x);
double _b2d (_Bigint *a , int *e);
_Bigint * _Balloc (struct _reent *p, int k);
void _Bfree (struct _reent *p, _Bigint *v);
_Bigint * _multadd (struct _reent *p, _Bigint *, int, int);
_Bigint * _s2b (struct _reent *, const char*, int, int, __ULong);
_Bigint * _i2b (struct _reent *,int);
_Bigint * _multiply (struct _reent *, _Bigint *, _Bigint *);
_Bigint * _pow5mult (struct _reent *, _Bigint *, int k);
int _hi0bits (__ULong);
int _lo0bits (__ULong *);
_Bigint * _d2b (struct _reent *p, double d, int *e, int *bits);
_Bigint * _lshift (struct _reent *p, _Bigint *b, int k);
_Bigint * __mdiff (struct _reent *p, _Bigint *a, _Bigint *b);
int __mcmp (_Bigint *a, _Bigint *b);
double _ratio (_Bigint *a, _Bigint *b);
# 308 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/mprec.h"
extern const double __mprec_tinytens[];
extern const double __mprec_bigtens[];
extern const double __mprec_tens[];
double _mprec_log10 (int);
# 34 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c" 2
static int
quorem(_Bigint * b , _Bigint * S)
{
int n;
__int32_t borrow, y;
__ULong carry, q, ys;
__ULong *bx, *bxe, *sx, *sxe;
__int32_t z;
__ULong si, zs;
n = S->_wds;
if (b->_wds < n)
return 0;
sx = S->_x;
sxe = sx + --n;
bx = b->_x;
bxe = bx + n;
q = *bxe / (*sxe + 1);
if (q)
{
borrow = 0;
carry = 0;
do
{
si = *sx++;
ys = (si & 0xffff) * q + carry;
zs = (si >> 16) * q + (ys >> 16);
carry = zs >> 16;
y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
borrow = y >> 16;
;
z = (*bx >> 16) - (zs & 0xffff) + borrow;
borrow = z >> 16;
;
(((unsigned short *)bx)[0] = (unsigned short)z, ((unsigned short *)bx)[1] = (unsigned short)y, bx++);
# 91 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c"
}
while (sx <= sxe);
if (!*bxe)
{
bx = b->_x;
while (--bxe > bx && !*bxe)
--n;
b->_wds = n;
}
}
if (__mcmp (b, S) >= 0)
{
q++;
borrow = 0;
carry = 0;
bx = b->_x;
sx = S->_x;
do
{
si = *sx++;
ys = (si & 0xffff) + carry;
zs = (si >> 16) + (ys >> 16);
carry = zs >> 16;
y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
borrow = y >> 16;
;
z = (*bx >> 16) - (zs & 0xffff) + borrow;
borrow = z >> 16;
;
(((unsigned short *)bx)[0] = (unsigned short)z, ((unsigned short *)bx)[1] = (unsigned short)y, bx++);
# 130 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c"
}
while (sx <= sxe);
bx = b->_x;
bxe = bx + n;
if (!*bxe)
{
while (--bxe > bx && !*bxe)
--n;
b->_wds = n;
}
}
return q;
}
# 179 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c"
char *
_dtoa_r(struct _reent *ptr , double _d , int mode , int ndigits , int *decpt , int *sign , char **rve)
# 189 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c"
{
# 224 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c"
int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0,
k_check, leftright, m2, m5, s2, s5, spec_case, try_quick;
union double_union d, d2, eps;
__int32_t L;
int denorm;
__ULong x;
_Bigint *b, *b1, *delta, *mlo, *mhi, *S;
double ds;
char *s, *s0;
d.d = _d;
if (ptr->_result)
{
ptr->_result->_k = ptr->_result_k;
ptr->_result->_maxwds = 1 << ptr->_result_k;
_Bfree (ptr, ptr->_result);
ptr->_result = 0;
}
if ((d.i[0]) & ((__uint32_t)0x80000000L))
{
*sign = 1;
(d.i[0]) &= ~((__uint32_t)0x80000000L);
}
else
*sign = 0;
if (((d.i[0]) & ((__uint32_t)0x7ff00000L)) == ((__uint32_t)0x7ff00000L))
{
*decpt = 9999;
s =
!(d.i[1]) && !((d.i[0]) & 0xfffff) ? "Infinity" :
"NaN";
if (rve)
*rve =
s[3] ? s + 8 :
s + 3;
return s;
}
if (!d.d)
{
*decpt = 1;
s = "0";
if (rve)
*rve = s + 1;
return s;
}
b = _d2b (ptr, d.d, &be, &bbits);
if (i = (int) ((d.i[0]) >> 20 & (((__uint32_t)0x7ff00000L) >> 20)))
{
d2.d = d.d;
(d2.i[0]) &= ((__uint32_t)0xfffffL);
(d2.i[0]) |= ((__uint32_t)0x3ff00000L);
# 327 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c"
i -= 1023;
denorm = 0;
}
else
{
i = bbits + be + (1023 + (53 - 1) - 1);
x = i > 32 ? (d.i[0]) << 64 - i | (d.i[1]) >> i - 32
: (d.i[1]) << 32 - i;
d2.d = x;
(d2.i[0]) -= 31 * ((__uint32_t)0x100000L);
i -= (1023 + (53 - 1) - 1) + 1;
denorm = 1;
}
ds = (d2.d - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981;
k = (int) ds;
if (ds < 0. && ds != k)
k--;
k_check = 1;
if (k >= 0 && k <= 22)
{
if (d.d < __mprec_tens[k])
k--;
k_check = 0;
}
j = bbits - i - 1;
if (j >= 0)
{
b2 = 0;
s2 = j;
}
else
{
b2 = -j;
s2 = 0;
}
if (k >= 0)
{
b5 = 0;
s5 = k;
s2 += k;
}
else
{
b2 -= k;
b5 = -k;
s5 = 0;
}
if (mode < 0 || mode > 9)
mode = 0;
try_quick = 1;
if (mode > 5)
{
mode -= 4;
try_quick = 0;
}
leftright = 1;
switch (mode)
{
case 0:
case 1:
ilim = ilim1 = -1;
i = 18;
ndigits = 0;
break;
case 2:
leftright = 0;
case 4:
if (ndigits <= 0)
ndigits = 1;
ilim = ilim1 = i = ndigits;
break;
case 3:
leftright = 0;
case 5:
i = ndigits + k + 1;
ilim = i;
ilim1 = i - 1;
if (i <= 0)
i = 1;
}
j = sizeof (__ULong);
for (ptr->_result_k = 0; sizeof (_Bigint) - sizeof (__ULong) + j <= i;
j <<= 1)
ptr->_result_k++;
ptr->_result = _Balloc (ptr, ptr->_result_k);
s = s0 = (char *) ptr->_result;
if (ilim >= 0 && ilim <= 14 && try_quick)
{
i = 0;
d2.d = d.d;
k0 = k;
ilim0 = ilim;
ieps = 2;
if (k > 0)
{
ds = __mprec_tens[k & 0xf];
j = k >> 4;
if (j & 0x10)
{
j &= 0x10 - 1;
d.d /= __mprec_bigtens[5 - 1];
ieps++;
}
for (; j; j >>= 1, i++)
if (j & 1)
{
ieps++;
ds *= __mprec_bigtens[i];
}
d.d /= ds;
}
else if (j1 = -k)
{
d.d *= __mprec_tens[j1 & 0xf];
for (j = j1 >> 4; j; j >>= 1, i++)
if (j & 1)
{
ieps++;
d.d *= __mprec_bigtens[i];
}
}
if (k_check && d.d < 1. && ilim > 0)
{
if (ilim1 <= 0)
goto fast_failed;
ilim = ilim1;
k--;
d.d *= 10.;
ieps++;
}
eps.d = ieps * d.d + 7.;
(eps.i[0]) -= (53 - 1) * ((__uint32_t)0x100000L);
if (ilim == 0)
{
S = mhi = 0;
d.d -= 5.;
if (d.d > eps.d)
goto one_digit;
if (d.d < -eps.d)
goto no_digits;
goto fast_failed;
}
if (leftright)
{
eps.d = 0.5 / __mprec_tens[ilim - 1] - eps.d;
for (i = 0;;)
{
L = d.d;
d.d -= L;
*s++ = '0' + (int) L;
if (d.d < eps.d)
goto ret1;
if (1. - d.d < eps.d)
goto bump_up;
if (++i >= ilim)
break;
eps.d *= 10.;
d.d *= 10.;
}
}
else
{
eps.d *= __mprec_tens[ilim - 1];
for (i = 1;; i++, d.d *= 10.)
{
L = d.d;
d.d -= L;
*s++ = '0' + (int) L;
if (i == ilim)
{
if (d.d > 0.5 + eps.d)
goto bump_up;
else if (d.d < 0.5 - eps.d)
{
while (*--s == '0');
s++;
goto ret1;
}
break;
}
}
}
fast_failed:
s = s0;
d.d = d2.d;
k = k0;
ilim = ilim0;
}
if (be >= 0 && k <= 14)
{
ds = __mprec_tens[k];
if (ndigits < 0 && ilim <= 0)
{
S = mhi = 0;
if (ilim < 0 || d.d <= 5 * ds)
goto no_digits;
goto one_digit;
}
for (i = 1;; i++)
{
L = d.d / ds;
d.d -= L * ds;
# 563 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c"
*s++ = '0' + (int) L;
if (i == ilim)
{
d.d += d.d;
if (d.d > ds || d.d == ds && L & 1)
{
bump_up:
while (*--s == '9')
if (s == s0)
{
k++;
*s = '0';
break;
}
++*s++;
}
break;
}
if (!(d.d *= 10.))
break;
}
goto ret1;
}
m2 = b2;
m5 = b5;
mhi = mlo = 0;
if (leftright)
{
if (mode < 2)
{
i =
denorm ? be + (1023 + (53 - 1) - 1 + 1) :
1 + 53 - bbits;
}
else
{
j = ilim - 1;
if (m5 >= j)
m5 -= j;
else
{
s5 += j -= m5;
b5 += j;
m5 = 0;
}
if ((i = ilim) < 0)
{
m2 -= i;
i = 0;
}
}
b2 += i;
s2 += i;
mhi = _i2b (ptr, 1);
}
if (m2 > 0 && s2 > 0)
{
i = m2 < s2 ? m2 : s2;
b2 -= i;
m2 -= i;
s2 -= i;
}
if (b5 > 0)
{
if (leftright)
{
if (m5 > 0)
{
mhi = _pow5mult (ptr, mhi, m5);
b1 = _multiply (ptr, mhi, b);
_Bfree (ptr, b);
b = b1;
}
if (j = b5 - m5)
b = _pow5mult (ptr, b, j);
}
else
b = _pow5mult (ptr, b, b5);
}
S = _i2b (ptr, 1);
if (s5 > 0)
S = _pow5mult (ptr, S, s5);
if (mode < 2)
{
if (!(d.i[1]) && !((d.i[0]) & ((__uint32_t)0xfffffL))
&& (d.i[0]) & ((__uint32_t)0x7ff00000L)
)
{
b2 += 1;
s2 += 1;
spec_case = 1;
}
else
spec_case = 0;
}
# 681 "../../../../../../source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c"
if (i = ((s5 ? 32 - _hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0x1f)
i = 32 - i;
if (i > 4)
{
i -= 4;
b2 += i;
m2 += i;
s2 += i;
}
else if (i < 4)
{
i += 28;
b2 += i;
m2 += i;
s2 += i;
}
if (b2 > 0)
b = _lshift (ptr, b, b2);
if (s2 > 0)
S = _lshift (ptr, S, s2);
if (k_check)
{
if (__mcmp (b, S) < 0)
{
k--;
b = _multadd (ptr, b, 10, 0);
if (leftright)
mhi = _multadd (ptr, mhi, 10, 0);
ilim = ilim1;
}
}
if (ilim <= 0 && mode > 2)
{
if (ilim < 0 || __mcmp (b, S = _multadd (ptr, S, 5, 0)) <= 0)
{
no_digits:
k = -1 - ndigits;
goto ret;
}
one_digit:
*s++ = '1';
k++;
goto ret;
}
if (leftright)
{
if (m2 > 0)
mhi = _lshift (ptr, mhi, m2);
mlo = mhi;
if (spec_case)
{
mhi = _Balloc (ptr, mhi->_k);
memcpy((char *)&mhi->_sign, (char *)&mlo->_sign, mlo->_wds*sizeof(__int32_t) + 2*sizeof(int));
mhi = _lshift (ptr, mhi, 1);
}
for (i = 1;; i++)
{
dig = quorem (b, S) + '0';
j = __mcmp (b, mlo);
delta = __mdiff (ptr, S, mhi);
j1 = delta->_sign ? 1 : __mcmp (b, delta);
_Bfree (ptr, delta);
if (j1 == 0 && !mode && !((d.i[1]) & 1))
{
if (dig == '9')
goto round_9_up;
if (j > 0)
dig++;
*s++ = dig;
goto ret;
}
if (j < 0 || j == 0 && !mode
&& !((d.i[1]) & 1)
)
{
if (j1 > 0)
{
b = _lshift (ptr, b, 1);
j1 = __mcmp (b, S);
if ((j1 > 0 || j1 == 0 && dig & 1)
&& dig++ == '9')
goto round_9_up;
}
*s++ = dig;
goto ret;
}
if (j1 > 0)
{
if (dig == '9')
{
round_9_up:
*s++ = '9';
goto roundoff;
}
*s++ = dig + 1;
goto ret;
}
*s++ = dig;
if (i == ilim)
break;
b = _multadd (ptr, b, 10, 0);
if (mlo == mhi)
mlo = mhi = _multadd (ptr, mhi, 10, 0);
else
{
mlo = _multadd (ptr, mlo, 10, 0);
mhi = _multadd (ptr, mhi, 10, 0);
}
}
}
else
for (i = 1;; i++)
{
*s++ = dig = quorem (b, S) + '0';
if (i >= ilim)
break;
b = _multadd (ptr, b, 10, 0);
}
b = _lshift (ptr, b, 1);
j = __mcmp (b, S);
if (j > 0 || j == 0 && dig & 1)
{
roundoff:
while (*--s == '9')
if (s == s0)
{
k++;
*s++ = '1';
goto ret;
}
++*s++;
}
else
{
while (*--s == '0');
s++;
}
ret:
_Bfree (ptr, S);
if (mhi)
{
if (mlo && mlo != mhi)
_Bfree (ptr, mlo);
_Bfree (ptr, mhi);
}
ret1:
_Bfree (ptr, b);
*s = 0;
*decpt = k + 1;
if (rve)
*rve = s;
return s0;
}
The source code is...
/gnu/source/newlib-1.8.2/newlib/libc/stdlib/dtoa.c
/****************************************************************
*
* The author of this software is David M. Gay.
*
* Copyright (c) 1991 by AT&T.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
***************************************************************/
/* Please send bug reports to
David M. Gay
AT&T Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-2070
U.S.A.
dmg@research.att.com or research!dmg
*/
#include <_ansi.h>
#include <stdlib.h>
#include <reent.h>
#include <string.h>
#include "mprec.h"
static int
_DEFUN (quorem,
(b, S),
_Bigint * b _AND _Bigint * S)
{
int n;
__Long borrow, y;
__ULong carry, q, ys;
__ULong *bx, *bxe, *sx, *sxe;
#ifdef Pack_32
__Long z;
__ULong si, zs;
#endif
n = S->_wds;
#ifdef DEBUG
/*debug*/ if (b->_wds > n)
/*debug*/ Bug ("oversize b in quorem");
#endif
if (b->_wds < n)
return 0;
sx = S->_x;
sxe = sx + --n;
bx = b->_x;
bxe = bx + n;
q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
#ifdef DEBUG
/*debug*/ if (q > 9)
/*debug*/ Bug ("oversized quotient in quorem");
#endif
if (q)
{
borrow = 0;
carry = 0;
do
{
#ifdef Pack_32
si = *sx++;
ys = (si & 0xffff) * q + carry;
zs = (si >> 16) * q + (ys >> 16);
carry = zs >> 16;
y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
z = (*bx >> 16) - (zs & 0xffff) + borrow;
borrow = z >> 16;
Sign_Extend (borrow, z);
Storeinc (bx, z, y);
#else
ys = *sx++ * q + carry;
carry = ys >> 16;
y = *bx - (ys & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
*bx++ = y & 0xffff;
#endif
}
while (sx <= sxe);
if (!*bxe)
{
bx = b->_x;
while (--bxe > bx && !*bxe)
--n;
b->_wds = n;
}
}
if (cmp (b, S) >= 0)
{
q++;
borrow = 0;
carry = 0;
bx = b->_x;
sx = S->_x;
do
{
#ifdef Pack_32
si = *sx++;
ys = (si & 0xffff) + carry;
zs = (si >> 16) + (ys >> 16);
carry = zs >> 16;
y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
z = (*bx >> 16) - (zs & 0xffff) + borrow;
borrow = z >> 16;
Sign_Extend (borrow, z);
Storeinc (bx, z, y);
#else
ys = *sx++ + carry;
carry = ys >> 16;
y = *bx - (ys & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
*bx++ = y & 0xffff;
#endif
}
while (sx <= sxe);
bx = b->_x;
bxe = bx + n;
if (!*bxe)
{
while (--bxe > bx && !*bxe)
--n;
b->_wds = n;
}
}
return q;
}
/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
*
* Inspired by "How to Print Floating-Point Numbers Accurately" by
* Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
*
* Modifications:
* 1. Rather than iterating, we use a simple numeric overestimate
* to determine k = floor(log10(d)). We scale relevant
* quantities using O(log2(k)) rather than O(k) multiplications.
* 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
* try to generate digits strictly left to right. Instead, we
* compute with fewer bits and propagate the carry if necessary
* when rounding the final digit up. This is often faster.
* 3. Under the assumption that input will be rounded nearest,
* mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
* That is, we allow equality in stopping tests when the
* round-nearest rule will give the same floating-point value
* as would satisfaction of the stopping test with strict
* inequality.
* 4. We remove common factors of powers of 2 from relevant
* quantities.
* 5. When converting floating-point integers less than 1e16,
* we use floating-point arithmetic rather than resorting
* to multiple-precision integers.
* 6. When asked to produce fewer than 15 digits, we first try
* to get by with floating-point arithmetic; we resort to
* multiple-precision integer arithmetic only if we cannot
* guarantee that the floating-point calculation has given
* the correctly rounded result. For k requested digits and
* "uniformly" distributed input, the probability is
* something like 10^(k-15) that we must resort to the long
* calculation.
*/
char *
_DEFUN (_dtoa_r,
(ptr, _d, mode, ndigits, decpt, sign, rve),
struct _reent *ptr _AND
double _d _AND
int mode _AND
int ndigits _AND
int *decpt _AND
int *sign _AND
char **rve)
{
/* Arguments ndigits, decpt, sign are similar to those
of ecvt and fcvt; trailing zeros are suppressed from
the returned string. If not null, *rve is set to point
to the end of the return value. If d is +-Infinity or NaN,
then *decpt is set to 9999.
mode:
0 ==> shortest string that yields d when read in
and rounded to nearest.
1 ==> like 0, but with Steele & White stopping rule;
e.g. with IEEE P754 arithmetic , mode 0 gives
1e23 whereas mode 1 gives 9.999999999999999e22.
2 ==> max(1,ndigits) significant digits. This gives a
return value similar to that of ecvt, except
that trailing zeros are suppressed.
3 ==> through ndigits past the decimal point. This
gives a return value similar to that from fcvt,
except that trailing zeros are suppressed, and
ndigits can be negative.
4-9 should give the same return values as 2-3, i.e.,
4 <= mode <= 9 ==> same return as mode
2 + (mode & 1). These modes are mainly for
debugging; often they run slower but sometimes
faster than modes 2-3.
4,5,8,9 ==> left-to-right digit generation.
6-9 ==> don't try fast floating-point estimate
(if applicable).
Values of mode other than 0-9 are treated as mode 0.
Sufficient space is allocated to the return value
to hold the suppressed trailing zeros.
*/
int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0,
k_check, leftright, m2, m5, s2, s5, spec_case, try_quick;
union double_union d, d2, eps;
__Long L;
#ifndef Sudden_Underflow
int denorm;
__ULong x;
#endif
_Bigint *b, *b1, *delta, *mlo, *mhi, *S;
double ds;
char *s, *s0;
d.d = _d;
if (ptr->_result)
{
ptr->_result->_k = ptr->_result_k;
ptr->_result->_maxwds = 1 << ptr->_result_k;
Bfree (ptr, ptr->_result);
ptr->_result = 0;
}
if (word0 (d) & Sign_bit)
{
/* set sign for everything, including 0's and NaNs */
*sign = 1;
word0 (d) &= ~Sign_bit; /* clear sign bit */
}
else
*sign = 0;
#if defined(IEEE_Arith) + defined(VAX)
#ifdef IEEE_Arith
if ((word0 (d) & Exp_mask) == Exp_mask)
#else
if (word0 (d) == 0x8000)
#endif
{
/* Infinity or NaN */
*decpt = 9999;
s =
#ifdef IEEE_Arith
!word1 (d) && !(word0 (d) & 0xfffff) ? "Infinity" :
#endif
"NaN";
if (rve)
*rve =
#ifdef IEEE_Arith
s[3] ? s + 8 :
#endif
s + 3;
return s;
}
#endif
#ifdef IBM
d.d += 0; /* normalize */
#endif
if (!d.d)
{
*decpt = 1;
s = "0";
if (rve)
*rve = s + 1;
return s;
}
b = d2b (ptr, d.d, &be, &bbits);
#ifdef Sudden_Underflow
i = (int) (word0 (d) >> Exp_shift1 & (Exp_mask >> Exp_shift1));
#else
if (i = (int) (word0 (d) >> Exp_shift1 & (Exp_mask >> Exp_shift1)))
{
#endif
d2.d = d.d;
word0 (d2) &= Frac_mask1;
word0 (d2) |= Exp_11;
#ifdef IBM
if (j = 11 - hi0bits (word0 (d2) & Frac_mask))
d2.d /= 1 << j;
#endif
/* log(x) ~=~ log(1.5) + (x-1.5)/1.5
* log10(x) = log(x) / log(10)
* ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
* log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
*
* This suggests computing an approximation k to log10(d) by
*
* k = (i - Bias)*0.301029995663981
* + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
*
* We want k to be too large rather than too small.
* The error in the first-order Taylor series approximation
* is in our favor, so we just round up the constant enough
* to compensate for any error in the multiplication of
* (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
* and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
* adding 1e-13 to the constant term more than suffices.
* Hence we adjust the constant term to 0.1760912590558.
* (We could get a more accurate k by invoking log10,
* but this is probably not worthwhile.)
*/
i -= Bias;
#ifdef IBM
i <<= 2;
i += j;
#endif
#ifndef Sudden_Underflow
denorm = 0;
}
else
{
/* d is denormalized */
i = bbits + be + (Bias + (P - 1) - 1);
x = i > 32 ? word0 (d) << 64 - i | word1 (d) >> i - 32
: word1 (d) << 32 - i;
d2.d = x;
word0 (d2) -= 31 * Exp_msk1; /* adjust exponent */
i -= (Bias + (P - 1) - 1) + 1;
denorm = 1;
}
#endif
ds = (d2.d - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981;
k = (int) ds;
if (ds < 0. && ds != k)
k--; /* want k = floor(ds) */
k_check = 1;
if (k >= 0 && k <= Ten_pmax)
{
if (d.d < tens[k])
k--;
k_check = 0;
}
j = bbits - i - 1;
if (j >= 0)
{
b2 = 0;
s2 = j;
}
else
{
b2 = -j;
s2 = 0;
}
if (k >= 0)
{
b5 = 0;
s5 = k;
s2 += k;
}
else
{
b2 -= k;
b5 = -k;
s5 = 0;
}
if (mode < 0 || mode > 9)
mode = 0;
try_quick = 1;
if (mode > 5)
{
mode -= 4;
try_quick = 0;
}
leftright = 1;
switch (mode)
{
case 0:
case 1:
ilim = ilim1 = -1;
i = 18;
ndigits = 0;
break;
case 2:
leftright = 0;
/* no break */
case 4:
if (ndigits <= 0)
ndigits = 1;
ilim = ilim1 = i = ndigits;
break;
case 3:
leftright = 0;
/* no break */
case 5:
i = ndigits + k + 1;
ilim = i;
ilim1 = i - 1;
if (i <= 0)
i = 1;
}
j = sizeof (__ULong);
for (ptr->_result_k = 0; sizeof (_Bigint) - sizeof (__ULong) + j <= i;
j <<= 1)
ptr->_result_k++;
ptr->_result = Balloc (ptr, ptr->_result_k);
s = s0 = (char *) ptr->_result;
if (ilim >= 0 && ilim <= Quick_max && try_quick)
{
/* Try to get by with floating-point arithmetic. */
i = 0;
d2.d = d.d;
k0 = k;
ilim0 = ilim;
ieps = 2; /* conservative */
if (k > 0)
{
ds = tens[k & 0xf];
j = k >> 4;
if (j & Bletch)
{
/* prevent overflows */
j &= Bletch - 1;
d.d /= bigtens[n_bigtens - 1];
ieps++;
}
for (; j; j >>= 1, i++)
if (j & 1)
{
ieps++;
ds *= bigtens[i];
}
d.d /= ds;
}
else if (j1 = -k)
{
d.d *= tens[j1 & 0xf];
for (j = j1 >> 4; j; j >>= 1, i++)
if (j & 1)
{
ieps++;
d.d *= bigtens[i];
}
}
if (k_check && d.d < 1. && ilim > 0)
{
if (ilim1 <= 0)
goto fast_failed;
ilim = ilim1;
k--;
d.d *= 10.;
ieps++;
}
eps.d = ieps * d.d + 7.;
word0 (eps) -= (P - 1) * Exp_msk1;
if (ilim == 0)
{
S = mhi = 0;
d.d -= 5.;
if (d.d > eps.d)
goto one_digit;
if (d.d < -eps.d)
goto no_digits;
goto fast_failed;
}
#ifndef No_leftright
if (leftright)
{
/* Use Steele & White method of only
* generating digits needed.
*/
eps.d = 0.5 / tens[ilim - 1] - eps.d;
for (i = 0;;)
{
L = d.d;
d.d -= L;
*s++ = '0' + (int) L;
if (d.d < eps.d)
goto ret1;
if (1. - d.d < eps.d)
goto bump_up;
if (++i >= ilim)
break;
eps.d *= 10.;
d.d *= 10.;
}
}
else
{
#endif
/* Generate ilim digits, then fix them up. */
eps.d *= tens[ilim - 1];
for (i = 1;; i++, d.d *= 10.)
{
L = d.d;
d.d -= L;
*s++ = '0' + (int) L;
if (i == ilim)
{
if (d.d > 0.5 + eps.d)
goto bump_up;
else if (d.d < 0.5 - eps.d)
{
while (*--s == '0');
s++;
goto ret1;
}
break;
}
}
#ifndef No_leftright
}
#endif
fast_failed:
s = s0;
d.d = d2.d;
k = k0;
ilim = ilim0;
}
/* Do we have a "small" integer? */
if (be >= 0 && k <= Int_max)
{
/* Yes. */
ds = tens[k];
if (ndigits < 0 && ilim <= 0)
{
S = mhi = 0;
if (ilim < 0 || d.d <= 5 * ds)
goto no_digits;
goto one_digit;
}
for (i = 1;; i++)
{
L = d.d / ds;
d.d -= L * ds;
#ifdef Check_FLT_ROUNDS
/* If FLT_ROUNDS == 2, L will usually be high by 1 */
if (d.d < 0)
{
L--;
d.d += ds;
}
#endif
*s++ = '0' + (int) L;
if (i == ilim)
{
d.d += d.d;
if (d.d > ds || d.d == ds && L & 1)
{
bump_up:
while (*--s == '9')
if (s == s0)
{
k++;
*s = '0';
break;
}
++*s++;
}
break;
}
if (!(d.d *= 10.))
break;
}
goto ret1;
}
m2 = b2;
m5 = b5;
mhi = mlo = 0;
if (leftright)
{
if (mode < 2)
{
i =
#ifndef Sudden_Underflow
denorm ? be + (Bias + (P - 1) - 1 + 1) :
#endif
#ifdef IBM
1 + 4 * P - 3 - bbits + ((bbits + be - 1) & 3);
#else
1 + P - bbits;
#endif
}
else
{
j = ilim - 1;
if (m5 >= j)
m5 -= j;
else
{
s5 += j -= m5;
b5 += j;
m5 = 0;
}
if ((i = ilim) < 0)
{
m2 -= i;
i = 0;
}
}
b2 += i;
s2 += i;
mhi = i2b (ptr, 1);
}
if (m2 > 0 && s2 > 0)
{
i = m2 < s2 ? m2 : s2;
b2 -= i;
m2 -= i;
s2 -= i;
}
if (b5 > 0)
{
if (leftright)
{
if (m5 > 0)
{
mhi = pow5mult (ptr, mhi, m5);
b1 = mult (ptr, mhi, b);
Bfree (ptr, b);
b = b1;
}
if (j = b5 - m5)
b = pow5mult (ptr, b, j);
}
else
b = pow5mult (ptr, b, b5);
}
S = i2b (ptr, 1);
if (s5 > 0)
S = pow5mult (ptr, S, s5);
/* Check for special case that d is a normalized power of 2. */
if (mode < 2)
{
if (!word1 (d) && !(word0 (d) & Bndry_mask)
#ifndef Sudden_Underflow
&& word0 (d) & Exp_mask
#endif
)
{
/* The special case */
b2 += Log2P;
s2 += Log2P;
spec_case = 1;
}
else
spec_case = 0;
}
/* Arrange for convenient computation of quotients:
* shift left if necessary so divisor has 4 leading 0 bits.
*
* Perhaps we should just compute leading 28 bits of S once
* and for all and pass them and a shift to quorem, so it
* can do shifts and ors to compute the numerator for q.
*/
#ifdef Pack_32
if (i = ((s5 ? 32 - hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0x1f)
i = 32 - i;
#else
if (i = ((s5 ? 32 - hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0xf)
i = 16 - i;
#endif
if (i > 4)
{
i -= 4;
b2 += i;
m2 += i;
s2 += i;
}
else if (i < 4)
{
i += 28;
b2 += i;
m2 += i;
s2 += i;
}
if (b2 > 0)
b = lshift (ptr, b, b2);
if (s2 > 0)
S = lshift (ptr, S, s2);
if (k_check)
{
if (cmp (b, S) < 0)
{
k--;
b = multadd (ptr, b, 10, 0); /* we botched the k estimate */
if (leftright)
mhi = multadd (ptr, mhi, 10, 0);
ilim = ilim1;
}
}
if (ilim <= 0 && mode > 2)
{
if (ilim < 0 || cmp (b, S = multadd (ptr, S, 5, 0)) <= 0)
{
/* no digits, fcvt style */
no_digits:
k = -1 - ndigits;
goto ret;
}
one_digit:
*s++ = '1';
k++;
goto ret;
}
if (leftright)
{
if (m2 > 0)
mhi = lshift (ptr, mhi, m2);
/* Compute mlo -- check for special case
* that d is a normalized power of 2.
*/
mlo = mhi;
if (spec_case)
{
mhi = Balloc (ptr, mhi->_k);
Bcopy (mhi, mlo);
mhi = lshift (ptr, mhi, Log2P);
}
for (i = 1;; i++)
{
dig = quorem (b, S) + '0';
/* Do we yet have the shortest decimal string
* that will round to d?
*/
j = cmp (b, mlo);
delta = diff (ptr, S, mhi);
j1 = delta->_sign ? 1 : cmp (b, delta);
Bfree (ptr, delta);
#ifndef ROUND_BIASED
if (j1 == 0 && !mode && !(word1 (d) & 1))
{
if (dig == '9')
goto round_9_up;
if (j > 0)
dig++;
*s++ = dig;
goto ret;
}
#endif
if (j < 0 || j == 0 && !mode
#ifndef ROUND_BIASED
&& !(word1 (d) & 1)
#endif
)
{
if (j1 > 0)
{
b = lshift (ptr, b, 1);
j1 = cmp (b, S);
if ((j1 > 0 || j1 == 0 && dig & 1)
&& dig++ == '9')
goto round_9_up;
}
*s++ = dig;
goto ret;
}
if (j1 > 0)
{
if (dig == '9')
{ /* possible if i == 1 */
round_9_up:
*s++ = '9';
goto roundoff;
}
*s++ = dig + 1;
goto ret;
}
*s++ = dig;
if (i == ilim)
break;
b = multadd (ptr, b, 10, 0);
if (mlo == mhi)
mlo = mhi = multadd (ptr, mhi, 10, 0);
else
{
mlo = multadd (ptr, mlo, 10, 0);
mhi = multadd (ptr, mhi, 10, 0);
}
}
}
else
for (i = 1;; i++)
{
*s++ = dig = quorem (b, S) + '0';
if (i >= ilim)
break;
b = multadd (ptr, b, 10, 0);
}
/* Round off last digit */
b = lshift (ptr, b, 1);
j = cmp (b, S);
if (j > 0 || j == 0 && dig & 1)
{
roundoff:
while (*--s == '9')
if (s == s0)
{
k++;
*s++ = '1';
goto ret;
}
++*s++;
}
else
{
while (*--s == '0');
s++;
}
ret:
Bfree (ptr, S);
if (mhi)
{
if (mlo && mlo != mhi)
Bfree (ptr, mlo);
Bfree (ptr, mhi);
}
ret1:
Bfree (ptr, b);
*s = 0;
*decpt = k + 1;
if (rve)
*rve = s;
return s0;
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: