├── test.c ├── tccboot ├── initrd.img ├── qemu-tccboot ├── example ├── boot │ └── tccargs └── hello.c ├── user.c ├── ctype.c ├── Makefile ├── README ├── tccboot.h ├── gunzip.c ├── head.S ├── main.c ├── lib.c ├── linux-2.4.26-config ├── linux-2.4.26-tcc.patch ├── vsprintf.c ├── inflate.c └── dtoa.c /test.c: -------------------------------------------------------------------------------- 1 | int _start(void) 2 | { 3 | while(1); 4 | } 5 | -------------------------------------------------------------------------------- /tccboot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/8l/tccboot/HEAD/tccboot -------------------------------------------------------------------------------- /initrd.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/8l/tccboot/HEAD/initrd.img -------------------------------------------------------------------------------- /qemu-tccboot: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ~/qemu-current/i386-softmmu/qemu -snapshot -user-net -serial stdio \ 3 | -kernel tccboot \ 4 | -initrd initrd.img \ 5 | -append "root=/dev/hda" \ 6 | -hda example.romfs 7 | -------------------------------------------------------------------------------- /example/boot/tccargs: -------------------------------------------------------------------------------- 1 | # This file contains the TinyCC command line arguments needed to 2 | # compile the hello.c program. 3 | 4 | # the output binary (DO NOT CHANGE IT) 5 | -o kernel 6 | # no default libraries 7 | -nostdlib 8 | # no default includes paths 9 | -nostdinc 10 | # statically linked output 11 | -static 12 | # address of the start of the .text section 13 | -Wl,-Ttext,000100000 14 | # force binary output format 15 | -Wl,--oformat,binary 16 | # sources files 17 | hello.c 18 | -------------------------------------------------------------------------------- /example/hello.c: -------------------------------------------------------------------------------- 1 | /* simple Hello World program on the QEMU serial port */ 2 | 3 | void puts(const char *s); 4 | 5 | void _start(void) 6 | { 7 | puts("Hello World\n"); 8 | while (1); 9 | } 10 | 11 | void outb(int port, int val) 12 | { 13 | asm("outb %b1, %w0" : : "d" (port), "a" (val)); 14 | } 15 | 16 | unsigned char inb(int port) 17 | { 18 | int val; 19 | asm("inb %w1, %b0" : "=a"(val) : "d" (port)); 20 | return val; 21 | } 22 | 23 | void puts(const char *s) 24 | { 25 | while (*s) { 26 | outb(0x3f8, *s++); 27 | while ((inb(0x3f8 + 5) & 0x60) != 0x60); 28 | } 29 | } 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /user.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #define __NR_linux_open __NR_open 10 | #define __NR_linux_lseek __NR_lseek 11 | #define __NR_linux_read __NR_read 12 | #define __NR_linux_write __NR_write 13 | #define __NR_linux_close __NR_close 14 | #define __NR_linux_exit __NR_exit 15 | 16 | _syscall3(int,linux_open,const char *,filename,int,access,int,mode) 17 | _syscall3(int,linux_lseek,int,fd,int,offset,int,whence) 18 | _syscall3(int,linux_read,int,fd,void *,buf,int,size) 19 | _syscall3(int,linux_write,int,fd,const void *,buf,int,size) 20 | _syscall1(int,linux_close,int,fd) 21 | _syscall1(int,linux_exit,int,val) 22 | 23 | void exit(int val) 24 | { 25 | linux_exit(val); 26 | } 27 | 28 | void putstr(const char *s) 29 | { 30 | linux_write(1, s, strlen(s)); 31 | } 32 | 33 | uint8_t *load_image(const char *filename) 34 | { 35 | int fd, size; 36 | uint8_t *p; 37 | 38 | fd = linux_open(filename, O_RDONLY, 0); 39 | if (fd < 0) { 40 | return NULL; 41 | } 42 | size = linux_lseek(fd, 0, SEEK_END); 43 | linux_lseek(fd, 0, SEEK_SET); 44 | p = malloc(size + 15); 45 | p = (void *)((unsigned long)p & ~15); 46 | linux_read(fd, p, size); 47 | linux_close(fd); 48 | return p; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /ctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/ctype.c 3 | * 4 | * Copyright (C) 1991, 1992 Linus Torvalds 5 | */ 6 | 7 | #include 8 | 9 | unsigned char _ctype[] = { 10 | _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ 11 | _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ 12 | _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ 13 | _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ 14 | _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ 15 | _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ 16 | _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ 17 | _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ 18 | _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ 19 | _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ 20 | _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ 21 | _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ 22 | _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ 23 | _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ 24 | _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ 25 | _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ 26 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ 27 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ 28 | _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ 29 | _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ 30 | _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ 31 | _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ 32 | _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ 33 | _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ 34 | 35 | 36 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # modify to your linux-2.4.26 kernel path (you must build the kernel first) 2 | KERNEL_PATH=../linux-2.4.26 3 | # modify to your TinyCC 0.9.21 path (you must build TinyCC first) 4 | TCC_PATH=../.. 5 | CC=gcc 6 | CFLAGS=-D__KERNEL__ -Wall -O2 -g -I$(KERNEL_PATH)/include -fno-builtin-printf -DCONFIG_TCCBOOT -mpreferred-stack-boundary=2 -march=i386 -falign-functions=0 -I. 7 | 8 | all: tccboot initrd.img 9 | 10 | #tccboot.user: tcc.o main.o ctype.o vsprintf.o lib.o malloc.o dtoa.o user.o 11 | # $(CC) -static -nostdlib -o $@ $^ 12 | 13 | tccboot.out: head.o tcc.o main.o ctype.o vsprintf.o lib.o malloc.o \ 14 | dtoa.o gunzip.o 15 | ld -e startup_32 -Ttext=0x100000 -N -o $@ $^ 16 | 17 | tccboot.bin: tccboot.out 18 | objcopy -O binary -R .note -R .comment -S $< $@ 19 | 20 | tccboot: tccboot.bin 21 | $(KERNEL_PATH)/arch/i386/boot/tools/build \ 22 | -b $(KERNEL_PATH)/arch/i386/boot/bbootsect \ 23 | $(KERNEL_PATH)/arch/i386/boot/bsetup \ 24 | $< CURRENT > $@ 25 | 26 | tcc.o: $(TCC_PATH)/tcc.c 27 | $(CC) $(CFLAGS) -c -o $@ $< 28 | 29 | %.o: %.c 30 | $(CC) $(CFLAGS) -c -o $@ $< 31 | 32 | %.o: %.S 33 | $(CC) -D__ASSEMBLY__ -D__KERNEL__ -I$(KERNEL_PATH)/include -c -o $@ $< 34 | 35 | clean: 36 | rm -f *~ *.o tccboot.out tccboot.bin example.romfs 37 | 38 | cleanall: clean 39 | rm -f tccboot example.romfs initrd.img 40 | 41 | example.romfs: example/boot/tccargs example/hello.c 42 | cd example ; genromfs -f ../example.romfs 43 | 44 | initrd.img: example.romfs 45 | gzip < $< > $@ -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | http://www.bellard.org/tcc/tccboot.html 2 | 3 | Introduction: 4 | ------------ 5 | 6 | WARNING: don't try to play with TCCBOOT unless you are a kernel 7 | hacker! 8 | 9 | TCCBOOT is a bootloader which uses TinyCC to compile C and assembly 10 | sources and boot the resulting executable. It is typically used to 11 | compile the Linux kernel sources at boot time. 12 | 13 | TCCBOOT boots the same way as a Linux kernel, so any boot loader which 14 | can run a 'bzImage' Linux kernel image can run TCCBOOT. I only tested 15 | it with ISOLINUX, but LILO or GRUB should work too. 16 | 17 | TCCBOOT reads C or assembly sources from a gzipped ROMFS filesystem 18 | stored in an Initial Ram Disk (initrd). It first reads the file 19 | 'boot/tccargs' which contains the TinyCC command line (same syntax as 20 | the tcc executable). The TinyCC invocation should output one binary 21 | image 'kernel'. This image is loaded at address 0x00100000. TCCBOOT 22 | then does a jump to the address 0x00100000 in 32 bit flat mode. This 23 | is compatible with the ABI of the 'vmlinux' kernel image. 24 | 25 | Compilation: 26 | ----------- 27 | 28 | TCCBOOT was only tested with Linux 2.4.26. In order to build TCCBOOT, 29 | you must first compile a 2.4.26 kernel because for simplicity TCCBOOT 30 | uses some binary files and headers from the Linux kernel. TCCBOOT also 31 | needs the source code of TinyCC (tested with TinyCC version 32 | 0.9.21). You can modify the Makefile to give the needed paths. 33 | 34 | Example: 35 | ------- 36 | 37 | An "Hello World" ROMFS partition is included (initrd.img). You can 38 | rebuild it from the example/ directory. You can test it with the QEMU 39 | PC emulator with the 'qemu-tccboot' script. 40 | 41 | Kernel compilation: 42 | ------------------ 43 | 44 | For your information, the patch 'linux-2.4.26-tcc.patch' gives the 45 | necessary modifications to build a Linux kernel with TinyCC. The 46 | corresponding kernel configuration is in file 47 | linux-2.4.26-config. Patches are necessary for the following reasons: 48 | 49 | - unsupported assembly directives: .rept, .endr, .subsection 50 | - '#define __ASSEMBLY__' needed in assembly sources 51 | - static variables cannot be seen from the inline assembly code 52 | - typing/lvalue problems with '? :' 53 | - no long long bit fields 54 | - 'aligned' attribute not supported for whole structs, only for fields 55 | - obscur preprocessor bug 56 | 57 | Some of these problems could easily be fixed, but I am too lazy 58 | now. It is sure that there are still many bugs in the kernel generated 59 | by TinyCC/TCCBOOT, but at least it can boot and launch a shell. 60 | 61 | License: 62 | ------- 63 | 64 | TCCBOOT is distributed under the GNU General Public License. 65 | 66 | Fabrice Bellard. 67 | -------------------------------------------------------------------------------- /tccboot.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define SEEK_SET 0 14 | #define SEEK_CUR 1 15 | #define SEEK_END 2 16 | 17 | typedef struct FILE { 18 | int fd; 19 | } FILE; 20 | 21 | struct tm { 22 | int tm_sec; /* Seconds. [0-60] (1 leap second) */ 23 | int tm_min; /* Minutes. [0-59] */ 24 | int tm_hour; /* Hours. [0-23] */ 25 | int tm_mday; /* Day. [1-31] */ 26 | int tm_mon; /* Month. [0-11] */ 27 | int tm_year; /* Year - 1900. */ 28 | int tm_wday; /* Day of week. [0-6] */ 29 | int tm_yday; /* Days in year.[0-365] */ 30 | int tm_isdst; /* DST. [-1/0/1]*/ 31 | }; 32 | 33 | void *sbrk(int increment); 34 | void *malloc(size_t size); 35 | void *memalign(size_t alignment, size_t n); 36 | void free(void *ptr); 37 | int printf(const char *fmt, ...); 38 | int fprintf(FILE *f, const char *fmt, ...); 39 | uint8_t *load_image(const char *filename); 40 | void *realloc(void *ptr, size_t size); 41 | 42 | int open(const char *filename, int access, ...); 43 | int read(int fd, void *buf, size_t size); 44 | int close(int fd); 45 | long lseek(int fd, long offset, int whence); 46 | int write(int fd, const void *buf, size_t size); 47 | 48 | FILE *fopen(const char *path, const char *mode); 49 | FILE *fdopen(int fildes, const char *mode); 50 | int fclose(FILE *stream); 51 | size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 52 | int fputc(int c, FILE *stream); 53 | 54 | long strtol(const char *nptr, char **endptr, int base); 55 | long long strtoll(const char *nptr, char **endptr, int base); 56 | unsigned long strtoul(const char *nptr, char **endptr, int base); 57 | unsigned long long strtoull(const char *nptr, char **endptr, int base); 58 | int atoi(const char *s); 59 | float strtof(const char *nptr, char **endptr); 60 | double strtod(const char *nptr, char **endptr); 61 | long double strtold(const char *nptr, char **endptr); 62 | double ldexp(double x, int exp); 63 | 64 | int gettimeofday(struct timeval *tv, struct timezone *tz); 65 | time_t time(time_t *t); 66 | struct tm *localtime(const time_t *timep); 67 | 68 | void exit(int val); 69 | void getcwd(char *buf, size_t buf_size); 70 | 71 | typedef int jmp_buf[6]; 72 | 73 | int setjmp(jmp_buf buf); 74 | void longjmp(jmp_buf buf, int val); 75 | 76 | int main(int argc, char **argv); 77 | void fatal(const char *fmt, ...) __attribute__((noreturn)) ; 78 | void romfs_init(void); 79 | void show_filename(const char *filename); 80 | void set_output_file(const char *filename, 81 | uint8_t *base, size_t size); 82 | long get_output_file_size(void); 83 | void putstr(const char *s); 84 | int do_gunzip(uint8_t *dest, const uint8_t *src, int src_len); 85 | 86 | extern uint8_t *romfs_base; 87 | 88 | extern int errno; 89 | extern FILE *stderr; 90 | 91 | -------------------------------------------------------------------------------- /gunzip.c: -------------------------------------------------------------------------------- 1 | #include "tccboot.h" 2 | 3 | /* 4 | * gzip declarations 5 | */ 6 | 7 | #define OF(args) args 8 | #define STATIC static 9 | 10 | #define memzero(s, n) memset ((s), 0, (n)) 11 | 12 | typedef unsigned char uch; 13 | typedef unsigned short ush; 14 | typedef unsigned long ulg; 15 | 16 | #define WSIZE 0x8000 /* Window size must be at least 32k, */ 17 | /* and a power of two */ 18 | 19 | static uch *inbuf; /* input buffer */ 20 | static uch window[WSIZE]; /* Sliding window buffer */ 21 | 22 | static unsigned insize = 0; /* valid bytes in inbuf */ 23 | static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ 24 | static unsigned outcnt = 0; /* bytes in output buffer */ 25 | 26 | /* gzip flag byte */ 27 | #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ 28 | #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ 29 | #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ 30 | #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ 31 | #define COMMENT 0x10 /* bit 4 set: file comment present */ 32 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ 33 | #define RESERVED 0xC0 /* bit 6,7: reserved */ 34 | 35 | #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) 36 | 37 | /* Diagnostic functions */ 38 | #ifdef DEBUG 39 | # define Assert(cond,msg) {if(!(cond)) error(msg);} 40 | # define Trace(x) fprintf x 41 | # define Tracev(x) {if (verbose) fprintf x ;} 42 | # define Tracevv(x) {if (verbose>1) fprintf x ;} 43 | # define Tracec(c,x) {if (verbose && (c)) fprintf x ;} 44 | # define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} 45 | #else 46 | # define Assert(cond,msg) 47 | # define Trace(x) 48 | # define Tracev(x) 49 | # define Tracevv(x) 50 | # define Tracec(c,x) 51 | # define Tracecv(c,x) 52 | #endif 53 | 54 | static int fill_inbuf(void); 55 | static void flush_window(void); 56 | static void error(char *m); 57 | 58 | static void gzip_mark(void **ptr) 59 | { 60 | } 61 | static void gzip_release(void **ptr) 62 | { 63 | } 64 | 65 | static long bytes_out; 66 | static uch *output_data; 67 | static const uint8_t *input_data; 68 | static int input_len; 69 | 70 | #include "inflate.c" 71 | 72 | /* =========================================================================== 73 | * Fill the input buffer. This is called only when the buffer is empty 74 | * and at least one byte is really needed. 75 | */ 76 | static int fill_inbuf(void) 77 | { 78 | if (insize != 0) { 79 | error("ran out of input data\n"); 80 | } 81 | 82 | inbuf = (uint8_t *)input_data; 83 | insize = input_len; 84 | inptr = 1; 85 | return inbuf[0]; 86 | } 87 | 88 | static void flush_window(void) 89 | { 90 | memcpy(output_data, window, outcnt); 91 | output_data += outcnt; 92 | bytes_out += outcnt; 93 | outcnt = 0; 94 | } 95 | 96 | static void error(char *x) 97 | { 98 | fatal("%s", x); 99 | } 100 | 101 | int do_gunzip(uint8_t *dest, const uint8_t *src, int src_len) 102 | { 103 | input_data = src; 104 | input_len = src_len; 105 | output_data = dest; 106 | bytes_out = 0; 107 | gunzip(); 108 | return bytes_out; 109 | } 110 | -------------------------------------------------------------------------------- /head.S: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/boot/head.S 3 | * 4 | * Copyright (C) 1991, 1992, 1993 Linus Torvalds 5 | */ 6 | 7 | /* 8 | * head.S contains the 32-bit startup code. 9 | * 10 | * NOTE!!! Startup happens at absolute address 0x00001000, which is also where 11 | * the page directory will exist. The startup code will be overwritten by 12 | * the page directory. [According to comments etc elsewhere on a compressed 13 | * kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC] 14 | * 15 | * Page 0 is deliberately kept safe, since System Management Mode code in 16 | * laptops may need to access the BIOS data stored there. This is also 17 | * useful for future device drivers that either access the BIOS via VM86 18 | * mode. 19 | */ 20 | 21 | /* 22 | * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 23 | */ 24 | .text 25 | 26 | #include 27 | #include 28 | 29 | .globl startup_32 30 | 31 | startup_32: 32 | cld 33 | cli 34 | movl $(__KERNEL_DS),%eax 35 | movl %eax,%ds 36 | movl %eax,%es 37 | movl %eax,%fs 38 | movl %eax,%gs 39 | 40 | lss SYMBOL_NAME(stack_start),%esp 41 | xorl %eax,%eax 42 | 1: incl %eax # check that A20 really IS enabled 43 | movl %eax,0x000000 # loop forever if it isn't 44 | cmpl %eax,0x100000 45 | je 1b 46 | 47 | /* 48 | * Initialize eflags. Some BIOS's leave bits like NT set. This would 49 | * confuse the debugger if this code is traced. 50 | * XXX - best to initialize before switching to protected mode. 51 | */ 52 | pushl $0 53 | popfl 54 | /* 55 | * Clear BSS 56 | */ 57 | xorl %eax,%eax 58 | movl $ SYMBOL_NAME(_edata),%edi 59 | movl $ SYMBOL_NAME(_end),%ecx 60 | subl %edi,%ecx 61 | cld 62 | rep 63 | stosb 64 | /* 65 | * Do the decompression, and jump to the new kernel.. 66 | */ 67 | subl $16,%esp # place for structure on the stack 68 | movl %esp,%eax 69 | pushl %esi # real mode pointer as second arg 70 | pushl %eax # address of structure as first arg 71 | call SYMBOL_NAME(compile_kernel) 72 | orl %eax,%eax 73 | jnz 3f 74 | popl %esi # discard address 75 | popl %esi # real mode pointer 76 | xorl %ebx,%ebx 77 | ljmp $(__KERNEL_CS), $0x100000 78 | 79 | /* 80 | * We come here, if we were loaded high. 81 | * We need to move the move-in-place routine down to 0x1000 82 | * and then start it with the buffer addresses in registers, 83 | * which we got from the stack. 84 | */ 85 | 3: 86 | movl $move_routine_start,%esi 87 | movl $0x1000,%edi 88 | movl $move_routine_end,%ecx 89 | subl %esi,%ecx 90 | addl $3,%ecx 91 | shrl $2,%ecx 92 | cld 93 | rep 94 | movsl 95 | 96 | popl %esi # discard the address 97 | popl %ebx # real mode pointer 98 | popl %esi # low_buffer_start 99 | popl %ecx # lcount 100 | popl %edx # high_buffer_start 101 | popl %eax # hcount 102 | movl $0x100000,%edi 103 | cli # make sure we don't get interrupted 104 | ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine 105 | 106 | /* 107 | * Routine (template) for moving the decompressed kernel in place, 108 | * if we were high loaded. This _must_ PIC-code ! 109 | */ 110 | move_routine_start: 111 | movl %ecx,%ebp 112 | shrl $2,%ecx 113 | rep 114 | movsl 115 | movl %ebp,%ecx 116 | andl $3,%ecx 117 | rep 118 | movsb 119 | movl %edx,%esi 120 | movl %eax,%ecx # NOTE: rep movsb won't move if %ecx == 0 121 | addl $3,%ecx 122 | shrl $2,%ecx 123 | rep 124 | movsl 125 | movl %ebx,%esi # Restore setup pointer 126 | xorl %ebx,%ebx 127 | ljmp $(__KERNEL_CS), $0x100000 128 | move_routine_end: 129 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include "tccboot.h" 2 | #include 3 | #include 4 | 5 | #define TCCARGS_FILE "/boot/tccargs" 6 | #define KERNEL_MAX_SIZE (8 * 1024 * 1024) 7 | #define INITRD_MAX_SIZE (20 * 1024 * 1024) 8 | #define INITRD_MIN_ADDR 0x800000 9 | #define KERNEL_FILENAME "kernel" 10 | 11 | //#define DEBUG_INITRD_ADDR 12 | 13 | #define MAX_ARGS 1024 14 | 15 | struct moveparams { 16 | uint8_t *low_buffer_start; int lcount; 17 | uint8_t *high_buffer_start; int hcount; 18 | }; 19 | 20 | static unsigned char *real_mode; /* Pointer to real-mode data */ 21 | #define EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) 22 | #ifndef STANDARD_MEMORY_BIOS_CALL 23 | #define ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) 24 | #endif 25 | #define SCREEN_INFO (*(struct screen_info *)(real_mode+0)) 26 | #define INITRD_START (*(unsigned long *) (real_mode+0x218)) 27 | #define INITRD_SIZE (*(unsigned long *) (real_mode+0x21c)) 28 | 29 | #define STACK_SIZE (256 * 1024) 30 | 31 | long user_stack [STACK_SIZE]; 32 | 33 | struct { 34 | long * a; 35 | short b; 36 | } stack_start = { & user_stack [STACK_SIZE] , __KERNEL_DS }; 37 | 38 | 39 | static char *vidmem = (char *)0xb8000; 40 | static int vidport; 41 | static int lines, cols; 42 | 43 | void video_init(void) 44 | { 45 | if (SCREEN_INFO.orig_video_mode == 7) { 46 | vidmem = (char *) 0xb0000; 47 | vidport = 0x3b4; 48 | } else { 49 | vidmem = (char *) 0xb8000; 50 | vidport = 0x3d4; 51 | } 52 | 53 | lines = SCREEN_INFO.orig_video_lines; 54 | cols = SCREEN_INFO.orig_video_cols; 55 | } 56 | 57 | static void scroll(void) 58 | { 59 | int i; 60 | 61 | memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 ); 62 | for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 ) 63 | vidmem[i] = ' '; 64 | } 65 | 66 | void putstr(const char *s) 67 | { 68 | int x,y,pos; 69 | char c; 70 | 71 | x = SCREEN_INFO.orig_x; 72 | y = SCREEN_INFO.orig_y; 73 | 74 | while ( ( c = *s++ ) != '\0' ) { 75 | if ( c == '\n' ) { 76 | x = 0; 77 | if ( ++y >= lines ) { 78 | scroll(); 79 | y--; 80 | } 81 | } else if (c == '\r') { 82 | x = 0; 83 | } else { 84 | vidmem [ ( x + cols * y ) * 2 ] = c; 85 | if ( ++x >= cols ) { 86 | x = 0; 87 | if ( ++y >= lines ) { 88 | scroll(); 89 | y--; 90 | } 91 | } 92 | } 93 | } 94 | 95 | SCREEN_INFO.orig_x = x; 96 | SCREEN_INFO.orig_y = y; 97 | 98 | pos = (x + cols * y) * 2; /* Update cursor position */ 99 | outb_p(14, vidport); 100 | outb_p(0xff & (pos >> 9), vidport+1); 101 | outb_p(15, vidport); 102 | outb_p(0xff & (pos >> 1), vidport+1); 103 | } 104 | 105 | void exit(int val) 106 | { 107 | printf("\n\n -- System halted"); 108 | while (1); 109 | } 110 | 111 | char *tcc_args[MAX_ARGS]; 112 | 113 | static int expand_args(char ***pargv, const char *str) 114 | { 115 | const char *s1; 116 | char **argv, *arg; 117 | int argc, len; 118 | 119 | argc = 0; 120 | argv = tcc_args; 121 | argv[argc++] = "tcc"; 122 | for(;;) { 123 | while (isspace(*str)) 124 | str++; 125 | if (*str == '\0') 126 | break; 127 | if (*str == '#') { 128 | while (*str != '\n') 129 | str++; 130 | continue; 131 | } 132 | s1 = str; 133 | while (*str != '\0' && !isspace(*str)) 134 | str++; 135 | len = str - s1; 136 | arg = malloc(len + 1); 137 | memcpy(arg, s1, len); 138 | arg[len] = '\0'; 139 | argv[argc++] = arg; 140 | } 141 | *pargv = argv; 142 | return argc; 143 | } 144 | 145 | void show_filename(const char *filename) 146 | { 147 | int len; 148 | static int counter; 149 | char counter_ch[4] = "-\\|/"; 150 | 151 | len = strlen(filename); 152 | if (len >= 2 && filename[len - 2] == '.' && filename[len - 1] == 'c') { 153 | printf("%c %-50s\r", counter_ch[counter], filename); 154 | counter = (counter + 1) & 3; 155 | } 156 | } 157 | 158 | int compile_kernel(struct moveparams *mv, void *rmode) 159 | { 160 | int fd, len; 161 | char *args_buf; 162 | char **argv; 163 | int argc, ret, romfs_len; 164 | uint8_t *kernel_ptr, *initrd_ptr; 165 | unsigned long romfs_base1; 166 | 167 | real_mode = rmode; 168 | 169 | video_init(); 170 | 171 | /* this is risky, but normally the initrd is not mapped inside the 172 | malloc structures. However, it can overlap with its new 173 | location */ 174 | if (!INITRD_SIZE || !INITRD_START) 175 | fatal("the kernel source must be in a ROMFS filesystem stored as Initial Ram Disk (INITRD)"); 176 | len = INITRD_SIZE; 177 | /* NOTE: it is very important to move initrd first to avoid 178 | destroying it later */ 179 | initrd_ptr = memalign(16, len); 180 | memmove(initrd_ptr, (void *)INITRD_START, len); 181 | if (initrd_ptr[0] == 037 && ((initrd_ptr[1] == 0213) || 182 | (initrd_ptr[1] == 0236))) { 183 | printf("Decompressing initrd...\n"); 184 | romfs_base = memalign(16, INITRD_MAX_SIZE); 185 | romfs_len = do_gunzip(romfs_base, initrd_ptr, len); 186 | /* realloc it to minimize memory usage */ 187 | romfs_base = realloc(romfs_base, romfs_len); 188 | free(initrd_ptr); 189 | } else { 190 | romfs_base = initrd_ptr; 191 | romfs_len = len; 192 | } 193 | 194 | kernel_ptr = malloc(KERNEL_MAX_SIZE); 195 | set_output_file("kernel", kernel_ptr, KERNEL_MAX_SIZE); 196 | 197 | #ifdef DEBUG_INITRD_ADDR 198 | printf("romfs_base=%p romfs_len=%d kernel_ptr=%p\n", 199 | romfs_base, romfs_len, kernel_ptr); 200 | #endif 201 | printf("Compiling kernel...\n"); 202 | 203 | fd = open("/boot/tccargs", O_RDONLY); 204 | if (fd < 0) 205 | fatal("Could not find '%s'", TCCARGS_FILE); 206 | len = lseek(fd, 0, SEEK_END); 207 | lseek(fd, 0, SEEK_SET); 208 | args_buf = malloc(len + 1); 209 | len = read(fd, args_buf, len); 210 | close(fd); 211 | 212 | args_buf[len] = '\0'; 213 | argc = expand_args(&argv, args_buf); 214 | argv[argc] = NULL; 215 | free(args_buf); 216 | #if 0 217 | { 218 | int i; 219 | for(i=0;ilcount = 0; 231 | mv->hcount = get_output_file_size(); 232 | mv->high_buffer_start = kernel_ptr; 233 | 234 | /* relocate the uncompressed initrd so that the kernel cannot 235 | overwrite it */ 236 | romfs_base1 = ((unsigned long)(mv->high_buffer_start) + 237 | mv->hcount + PAGE_SIZE - 1) & 238 | ~(PAGE_SIZE - 1); 239 | if (romfs_base1 < INITRD_MIN_ADDR) 240 | romfs_base1 = INITRD_MIN_ADDR; 241 | if (!(kernel_ptr >= romfs_base + romfs_len && 242 | (unsigned long)romfs_base >= INITRD_MIN_ADDR) && 243 | (unsigned long)romfs_base < romfs_base1) { 244 | memmove((void *)romfs_base1, romfs_base, romfs_len); 245 | romfs_base = (void *)romfs_base1; 246 | } 247 | #ifdef DEBUG_INITRD_ADDR 248 | printf("initrd_start=%p initrd_size=%d\n", romfs_base, romfs_len); 249 | #endif 250 | INITRD_START = (unsigned long)romfs_base; 251 | INITRD_SIZE = romfs_len; 252 | return 1; 253 | } 254 | -------------------------------------------------------------------------------- /lib.c: -------------------------------------------------------------------------------- 1 | #include "tccboot.h" 2 | 3 | //#define ROMFS_DEBUG 4 | 5 | char msg_buf[1024]; 6 | 7 | void puts(const char *s) 8 | { 9 | putstr(s); 10 | putstr("\n"); 11 | } 12 | 13 | int printf(const char *fmt, ...) 14 | { 15 | va_list ap; 16 | va_start(ap, fmt); 17 | 18 | vsnprintf(msg_buf, sizeof(msg_buf), fmt, ap); 19 | putstr(msg_buf); 20 | va_end(ap); 21 | return 0; 22 | } 23 | 24 | FILE *stderr; 25 | 26 | int fprintf(FILE *f, const char *fmt, ...) 27 | { 28 | va_list ap; 29 | va_start(ap, fmt); 30 | 31 | vsnprintf(msg_buf, sizeof(msg_buf), fmt, ap); 32 | putstr(msg_buf); 33 | va_end(ap); 34 | return 0; 35 | } 36 | 37 | void getcwd(char *buf, size_t buf_size) 38 | { 39 | strcpy(buf, "/"); 40 | } 41 | 42 | void fatal(const char *fmt, ...) 43 | { 44 | va_list ap; 45 | va_start(ap, fmt); 46 | 47 | putstr("tccboot: panic: "); 48 | vsnprintf(msg_buf, sizeof(msg_buf), fmt, ap); 49 | putstr(msg_buf); 50 | putstr("\n"); 51 | va_end(ap); 52 | exit(1); 53 | } 54 | 55 | /**********************************************************/ 56 | 57 | int errno; 58 | 59 | long strtol(const char *nptr, char **endptr, int base) 60 | { 61 | return simple_strtol(nptr, endptr, base); 62 | } 63 | 64 | long long strtoll(const char *nptr, char **endptr, int base) 65 | { 66 | return simple_strtoll(nptr, endptr, base); 67 | } 68 | 69 | unsigned long strtoul(const char *nptr, char **endptr, int base) 70 | { 71 | return simple_strtoul(nptr, endptr, base); 72 | } 73 | 74 | unsigned long long strtoull(const char *nptr, char **endptr, int base) 75 | { 76 | return simple_strtoull(nptr, endptr, base); 77 | } 78 | 79 | int atoi(const char *s) 80 | { 81 | return strtol(s, NULL, 10); 82 | } 83 | 84 | /**********************************************************/ 85 | 86 | int gettimeofday(struct timeval *tv, struct timezone *tz) 87 | { 88 | tv->tv_sec = 0; 89 | tv->tv_usec = 0; 90 | return 0; 91 | } 92 | 93 | time_t time(time_t *t) 94 | { 95 | if (t) 96 | *t = 0; 97 | return 0; 98 | } 99 | 100 | struct tm *localtime(const time_t *timep) 101 | { 102 | static struct tm static_tm; 103 | return &static_tm; 104 | } 105 | 106 | int setjmp(jmp_buf buf) 107 | { 108 | return 0; 109 | } 110 | 111 | void longjmp(jmp_buf buf, int val) 112 | { 113 | exit(1); 114 | } 115 | 116 | /**********************************************************/ 117 | #define MALLOC_MAX_SIZE (128 * 1024 * 1024) 118 | extern uint8_t _end; 119 | uint8_t *malloc_ptr = &_end; 120 | 121 | void *sbrk(int increment) 122 | { 123 | uint8_t *ptr, *new_ptr; 124 | 125 | if (increment == 0) 126 | return malloc_ptr; 127 | ptr = malloc_ptr; 128 | new_ptr = malloc_ptr + increment; 129 | if (new_ptr > (&_end + MALLOC_MAX_SIZE)) { 130 | errno = ENOMEM; 131 | return (void *)-1; 132 | } 133 | malloc_ptr = new_ptr; 134 | return ptr; 135 | } 136 | 137 | #if 0 138 | #define MALLOC_ALIGN 4096 139 | 140 | void free(void *ptr) 141 | { 142 | } 143 | 144 | void *realloc(void *oldptr, size_t size) 145 | { 146 | void *ptr; 147 | if (size == 0) { 148 | free(oldptr); 149 | return NULL; 150 | } else { 151 | ptr = malloc(size); 152 | /* XXX: incorrect */ 153 | if (oldptr) { 154 | memcpy(ptr, oldptr, size); 155 | free(oldptr); 156 | } 157 | return ptr; 158 | } 159 | } 160 | #endif 161 | /**********************************************************/ 162 | 163 | uint8_t *romfs_base; 164 | 165 | /* The basic structures of the romfs filesystem */ 166 | 167 | #define ROMBSIZE BLOCK_SIZE 168 | #define ROMBSBITS BLOCK_SIZE_BITS 169 | #define ROMBMASK (ROMBSIZE-1) 170 | #define ROMFS_MAGIC 0x7275 171 | 172 | #define ROMFS_MAXFN 128 173 | 174 | #define __mkw(h,l) (((h)&0x00ff)<< 8|((l)&0x00ff)) 175 | #define __mkl(h,l) (((h)&0xffff)<<16|((l)&0xffff)) 176 | #define __mk4(a,b,c,d) htonl(__mkl(__mkw(a,b),__mkw(c,d))) 177 | #define ROMSB_WORD0 __mk4('-','r','o','m') 178 | #define ROMSB_WORD1 __mk4('1','f','s','-') 179 | 180 | /* On-disk "super block" */ 181 | 182 | struct romfs_super_block { 183 | uint32_t word0; 184 | uint32_t word1; 185 | uint32_t size; 186 | uint32_t checksum; 187 | char name[0]; /* volume name */ 188 | }; 189 | 190 | /* On disk inode */ 191 | 192 | struct romfs_inode { 193 | uint32_t next; /* low 4 bits see ROMFH_ */ 194 | uint32_t spec; 195 | uint32_t size; 196 | uint32_t checksum; 197 | char name[0]; 198 | }; 199 | 200 | #define ROMFH_TYPE 7 201 | #define ROMFH_HRD 0 202 | #define ROMFH_DIR 1 203 | #define ROMFH_REG 2 204 | #define ROMFH_SYM 3 205 | #define ROMFH_BLK 4 206 | #define ROMFH_CHR 5 207 | #define ROMFH_SCK 6 208 | #define ROMFH_FIF 7 209 | #define ROMFH_EXEC 8 210 | 211 | /* Alignment */ 212 | 213 | #define ROMFH_ALIGN 16 214 | 215 | #define MAX_FILE_HANDLES 256 216 | 217 | typedef struct FileHandle { 218 | uint8_t *base; 219 | unsigned long size, max_size; 220 | unsigned long pos; 221 | int is_rw; 222 | } FileHandle; 223 | 224 | static FileHandle file_handles[MAX_FILE_HANDLES]; 225 | 226 | static uint8_t *output_base; 227 | static size_t output_max_size, output_size; 228 | static uint8_t output_filename[128]; 229 | 230 | void set_output_file(const char *filename, 231 | uint8_t *base, size_t size) 232 | { 233 | strcpy(output_filename, filename); 234 | output_base = base; 235 | output_max_size = size; 236 | } 237 | 238 | long get_output_file_size(void) 239 | { 240 | return output_size; 241 | } 242 | 243 | static inline int get_file_handle(void) 244 | { 245 | int i; 246 | 247 | for(i = 0; i < MAX_FILE_HANDLES; i++) { 248 | if (!file_handles[i].base) 249 | return i; 250 | } 251 | errno = ENOMEM; 252 | return -1; 253 | } 254 | 255 | int open(const char *filename, int access, ...) 256 | { 257 | struct romfs_super_block *sb; 258 | unsigned long addr, next; 259 | struct romfs_inode *inode; 260 | int type, fd, len; 261 | char dir[1024]; 262 | const char *p, *r; 263 | 264 | if (access & O_CREAT) { 265 | /* specific case for file creation */ 266 | if (strcmp(filename, output_filename) != 0) 267 | return -EPERM; 268 | fd = get_file_handle(); 269 | if (fd < 0) 270 | return fd; 271 | file_handles[fd].base = output_base; 272 | file_handles[fd].max_size = output_max_size; 273 | file_handles[fd].is_rw = 1; 274 | file_handles[fd].pos = 0; 275 | file_handles[fd].size = 0; 276 | return fd; 277 | } 278 | 279 | show_filename(filename); 280 | 281 | sb = (void *)romfs_base; 282 | if (sb->word0 != ROMSB_WORD0 || 283 | sb->word1 != ROMSB_WORD1) 284 | goto fail; 285 | addr = ((unsigned long)sb->name + strlen(sb->name) + 1 + ROMFH_ALIGN - 1) & 286 | ~(ROMFH_ALIGN - 1); 287 | inode = (void *)addr; 288 | 289 | /* search the directory */ 290 | p = filename; 291 | while (*p == '/') 292 | p++; 293 | for(;;) { 294 | r = strchr(p, '/'); 295 | if (!r) 296 | break; 297 | len = r - p; 298 | if (len > sizeof(dir) - 1) 299 | goto fail; 300 | memcpy(dir, p, len); 301 | dir[len] = '\0'; 302 | p = r + 1; 303 | #ifdef ROMFS_DEBUG 304 | printf("dir=%s\n", dir); 305 | #endif 306 | 307 | for(;;) { 308 | next = ntohl(inode->next); 309 | type = next & 0xf; 310 | next &= ~0xf; 311 | if (!strcmp(dir, inode->name)) { 312 | #ifdef ROMFS_DEBUG 313 | printf("dirname=%s type=0x%x\n", inode->name, type); 314 | #endif 315 | if ((type & ROMFH_TYPE) == ROMFH_DIR) { 316 | chdir: 317 | addr = ((unsigned long)inode->name + strlen(inode->name) + 318 | 1 + ROMFH_ALIGN - 1) & 319 | ~(ROMFH_ALIGN - 1); 320 | inode = (void *)addr; 321 | break; 322 | } else if ((type & ROMFH_TYPE) == ROMFH_HRD) { 323 | addr = ntohl(inode->spec); 324 | inode = (void *)(romfs_base + addr); 325 | next = ntohl(inode->next); 326 | type = next & 0xf; 327 | if ((type & ROMFH_TYPE) != ROMFH_DIR) 328 | goto fail; 329 | goto chdir; 330 | } 331 | } 332 | if (next == 0) 333 | goto fail; 334 | inode = (void *)(romfs_base + next); 335 | } 336 | } 337 | for(;;) { 338 | next = ntohl(inode->next); 339 | type = next & 0xf; 340 | next &= ~0xf; 341 | #ifdef ROMFS_DEBUG 342 | printf("name=%s type=0x%x\n", inode->name, type); 343 | #endif 344 | if ((type & ROMFH_TYPE) == ROMFH_REG) { 345 | if (!strcmp(p, inode->name)) { 346 | fd = get_file_handle(); 347 | if (fd < 0) 348 | return fd; 349 | addr = ((unsigned long)inode->name + strlen(inode->name) + 350 | 1 + ROMFH_ALIGN - 1) & 351 | ~(ROMFH_ALIGN - 1); 352 | file_handles[fd].base = (void *)addr; 353 | file_handles[fd].is_rw = 0; 354 | file_handles[fd].pos = 0; 355 | file_handles[fd].size = ntohl(inode->size); 356 | return fd; 357 | } 358 | } 359 | if (next == 0) 360 | break; 361 | inode = (void *)(romfs_base + next); 362 | } 363 | fail: 364 | errno = ENOENT; 365 | return -1; 366 | } 367 | 368 | int read(int fd, void *buf, size_t size) 369 | { 370 | FileHandle *fh = &file_handles[fd]; 371 | int len; 372 | 373 | len = fh->size - fh->pos; 374 | if (len > (int)size) 375 | len = size; 376 | memcpy(buf, fh->base + fh->pos, len); 377 | fh->pos += len; 378 | return len; 379 | } 380 | 381 | int write(int fd, const void *buf, size_t size) 382 | { 383 | FileHandle *fh = &file_handles[fd]; 384 | int len; 385 | 386 | if (!fh->is_rw) 387 | return -EIO; 388 | len = fh->max_size - fh->pos; 389 | if ((int)size > len) { 390 | errno = ENOSPC; 391 | return -1; 392 | } 393 | memcpy(fh->base + fh->pos, buf, size); 394 | fh->pos += size; 395 | if (fh->pos > fh->size) { 396 | fh->size = fh->pos; 397 | output_size = fh->pos; 398 | } 399 | return size; 400 | } 401 | 402 | long lseek(int fd, long offset, int whence) 403 | { 404 | FileHandle *fh = &file_handles[fd]; 405 | 406 | switch(whence) { 407 | case SEEK_SET: 408 | break; 409 | case SEEK_END: 410 | offset += fh->size; 411 | break; 412 | case SEEK_CUR: 413 | offset += fh->pos; 414 | break; 415 | default: 416 | errno = EINVAL; 417 | return -1; 418 | } 419 | if (offset < 0) { 420 | errno = EINVAL; 421 | return -1; 422 | } 423 | fh->pos = offset; 424 | return offset; 425 | } 426 | 427 | int close(int fd) 428 | { 429 | FileHandle *fh = &file_handles[fd]; 430 | fh->base = NULL; 431 | return 0; 432 | } 433 | 434 | /**********************************************************/ 435 | 436 | float strtof(const char *nptr, char **endptr) 437 | { 438 | fatal("unimplemented: %s", __func__ ); 439 | } 440 | 441 | long double strtold(const char *nptr, char **endptr) 442 | { 443 | fatal("unimplemented: %s", __func__ ); 444 | } 445 | 446 | double ldexp(double x, int exp) 447 | { 448 | fatal("unimplemented: %s", __func__ ); 449 | } 450 | 451 | FILE *fopen(const char *path, const char *mode) 452 | { 453 | fatal("unimplemented: %s", __func__ ); 454 | } 455 | 456 | FILE *fdopen(int fildes, const char *mode) 457 | { 458 | FILE *f; 459 | f = malloc(sizeof(FILE)); 460 | f->fd = fildes; 461 | return f; 462 | } 463 | 464 | int fclose(FILE *stream) 465 | { 466 | close(stream->fd); 467 | free(stream); 468 | } 469 | 470 | size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) 471 | { 472 | int ret; 473 | if (nmemb == 1) { 474 | ret = write(stream->fd, ptr, size); 475 | if (ret < 0) 476 | return ret; 477 | } else { 478 | ret = write(stream->fd, ptr, size * nmemb); 479 | if (ret < 0) 480 | return ret; 481 | if (nmemb != 0) 482 | ret /= nmemb; 483 | } 484 | return ret; 485 | } 486 | 487 | int fputc(int c, FILE *stream) 488 | { 489 | uint8_t ch = c; 490 | write(stream->fd, &ch, 1); 491 | return 0; 492 | } 493 | -------------------------------------------------------------------------------- /linux-2.4.26-config: -------------------------------------------------------------------------------- 1 | # 2 | # Automatically generated by make menuconfig: don't edit 3 | # 4 | CONFIG_X86=y 5 | # CONFIG_SBUS is not set 6 | CONFIG_UID16=y 7 | 8 | # 9 | # Code maturity level options 10 | # 11 | # CONFIG_EXPERIMENTAL is not set 12 | 13 | # 14 | # Loadable module support 15 | # 16 | # CONFIG_MODULES is not set 17 | 18 | # 19 | # Processor type and features 20 | # 21 | # CONFIG_M386 is not set 22 | CONFIG_M486=y 23 | # CONFIG_M586 is not set 24 | # CONFIG_M586TSC is not set 25 | # CONFIG_M586MMX is not set 26 | # CONFIG_M686 is not set 27 | # CONFIG_MPENTIUMIII is not set 28 | # CONFIG_MPENTIUM4 is not set 29 | # CONFIG_MK6 is not set 30 | # CONFIG_MK7 is not set 31 | # CONFIG_MK8 is not set 32 | # CONFIG_MELAN is not set 33 | # CONFIG_MCRUSOE is not set 34 | # CONFIG_MWINCHIPC6 is not set 35 | # CONFIG_MWINCHIP2 is not set 36 | # CONFIG_MWINCHIP3D is not set 37 | # CONFIG_MCYRIXIII is not set 38 | # CONFIG_MVIAC3_2 is not set 39 | CONFIG_X86_WP_WORKS_OK=y 40 | CONFIG_X86_INVLPG=y 41 | CONFIG_X86_CMPXCHG=y 42 | CONFIG_X86_XADD=y 43 | CONFIG_X86_BSWAP=y 44 | CONFIG_X86_POPAD_OK=y 45 | # CONFIG_RWSEM_GENERIC_SPINLOCK is not set 46 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y 47 | CONFIG_X86_L1_CACHE_SHIFT=4 48 | CONFIG_X86_USE_STRING_486=y 49 | CONFIG_X86_ALIGNMENT_16=y 50 | CONFIG_X86_PPRO_FENCE=y 51 | # CONFIG_X86_F00F_WORKS_OK is not set 52 | # CONFIG_X86_MCE is not set 53 | # CONFIG_TOSHIBA is not set 54 | # CONFIG_I8K is not set 55 | # CONFIG_MICROCODE is not set 56 | # CONFIG_X86_MSR is not set 57 | # CONFIG_X86_CPUID is not set 58 | CONFIG_NOHIGHMEM=y 59 | # CONFIG_HIGHMEM4G is not set 60 | # CONFIG_HIGHMEM64G is not set 61 | # CONFIG_HIGHMEM is not set 62 | # CONFIG_MATH_EMULATION is not set 63 | # CONFIG_MTRR is not set 64 | # CONFIG_SMP is not set 65 | # CONFIG_X86_UP_APIC is not set 66 | # CONFIG_X86_UP_IOAPIC is not set 67 | # CONFIG_X86_TSC_DISABLE is not set 68 | 69 | # 70 | # General setup 71 | # 72 | CONFIG_NET=y 73 | # CONFIG_PCI is not set 74 | # CONFIG_ISA is not set 75 | # CONFIG_EISA is not set 76 | # CONFIG_MCA is not set 77 | # CONFIG_HOTPLUG is not set 78 | # CONFIG_PCMCIA is not set 79 | # CONFIG_HOTPLUG_PCI is not set 80 | CONFIG_SYSVIPC=y 81 | # CONFIG_BSD_PROCESS_ACCT is not set 82 | CONFIG_SYSCTL=y 83 | CONFIG_KCORE_ELF=y 84 | # CONFIG_KCORE_AOUT is not set 85 | # CONFIG_BINFMT_AOUT is not set 86 | CONFIG_BINFMT_ELF=y 87 | # CONFIG_BINFMT_MISC is not set 88 | # CONFIG_OOM_KILLER is not set 89 | # CONFIG_PM is not set 90 | # CONFIG_APM is not set 91 | 92 | # 93 | # ACPI Support 94 | # 95 | # CONFIG_ACPI is not set 96 | 97 | # 98 | # Memory Technology Devices (MTD) 99 | # 100 | # CONFIG_MTD is not set 101 | 102 | # 103 | # Parallel port support 104 | # 105 | # CONFIG_PARPORT is not set 106 | 107 | # 108 | # Plug and Play configuration 109 | # 110 | # CONFIG_PNP is not set 111 | # CONFIG_ISAPNP is not set 112 | 113 | # 114 | # Block devices 115 | # 116 | CONFIG_BLK_DEV_FD=y 117 | # CONFIG_BLK_DEV_XD is not set 118 | # CONFIG_PARIDE is not set 119 | # CONFIG_BLK_CPQ_DA is not set 120 | # CONFIG_BLK_CPQ_CISS_DA is not set 121 | # CONFIG_CISS_SCSI_TAPE is not set 122 | # CONFIG_CISS_MONITOR_THREAD is not set 123 | # CONFIG_BLK_DEV_DAC960 is not set 124 | # CONFIG_BLK_DEV_UMEM is not set 125 | CONFIG_BLK_DEV_LOOP=y 126 | # CONFIG_BLK_DEV_NBD is not set 127 | CONFIG_BLK_DEV_RAM=y 128 | CONFIG_BLK_DEV_RAM_SIZE=4096 129 | CONFIG_BLK_DEV_INITRD=y 130 | # CONFIG_BLK_STATS is not set 131 | 132 | # 133 | # Multi-device support (RAID and LVM) 134 | # 135 | # CONFIG_MD is not set 136 | # CONFIG_BLK_DEV_MD is not set 137 | # CONFIG_MD_LINEAR is not set 138 | # CONFIG_MD_RAID0 is not set 139 | # CONFIG_MD_RAID1 is not set 140 | # CONFIG_MD_RAID5 is not set 141 | # CONFIG_MD_MULTIPATH is not set 142 | # CONFIG_BLK_DEV_LVM is not set 143 | 144 | # 145 | # Networking options 146 | # 147 | CONFIG_PACKET=y 148 | # CONFIG_PACKET_MMAP is not set 149 | # CONFIG_NETLINK_DEV is not set 150 | # CONFIG_NETFILTER is not set 151 | # CONFIG_FILTER is not set 152 | CONFIG_UNIX=y 153 | CONFIG_INET=y 154 | CONFIG_IP_MULTICAST=y 155 | # CONFIG_IP_ADVANCED_ROUTER is not set 156 | # CONFIG_IP_PNP is not set 157 | # CONFIG_NET_IPIP is not set 158 | # CONFIG_NET_IPGRE is not set 159 | # CONFIG_IP_MROUTE is not set 160 | # CONFIG_INET_ECN is not set 161 | # CONFIG_SYN_COOKIES is not set 162 | # CONFIG_VLAN_8021Q is not set 163 | # CONFIG_IPX is not set 164 | # CONFIG_ATALK is not set 165 | 166 | # 167 | # Appletalk devices 168 | # 169 | # CONFIG_DEV_APPLETALK is not set 170 | # CONFIG_DECNET is not set 171 | # CONFIG_BRIDGE is not set 172 | 173 | # 174 | # QoS and/or fair queueing 175 | # 176 | # CONFIG_NET_SCHED is not set 177 | 178 | # 179 | # Network testing 180 | # 181 | # CONFIG_NET_PKTGEN is not set 182 | 183 | # 184 | # Telephony Support 185 | # 186 | # CONFIG_PHONE is not set 187 | # CONFIG_PHONE_IXJ is not set 188 | # CONFIG_PHONE_IXJ_PCMCIA is not set 189 | 190 | # 191 | # ATA/IDE/MFM/RLL support 192 | # 193 | CONFIG_IDE=y 194 | 195 | # 196 | # IDE, ATA and ATAPI Block devices 197 | # 198 | CONFIG_BLK_DEV_IDE=y 199 | # CONFIG_BLK_DEV_HD_IDE is not set 200 | # CONFIG_BLK_DEV_HD is not set 201 | CONFIG_BLK_DEV_IDEDISK=y 202 | CONFIG_IDEDISK_MULTI_MODE=y 203 | # CONFIG_IDEDISK_STROKE is not set 204 | # CONFIG_BLK_DEV_IDECS is not set 205 | CONFIG_BLK_DEV_IDECD=y 206 | # CONFIG_BLK_DEV_IDETAPE is not set 207 | # CONFIG_BLK_DEV_IDEFLOPPY is not set 208 | # CONFIG_BLK_DEV_IDESCSI is not set 209 | # CONFIG_IDE_TASK_IOCTL is not set 210 | # CONFIG_BLK_DEV_CMD640 is not set 211 | # CONFIG_BLK_DEV_CMD640_ENHANCED is not set 212 | # CONFIG_BLK_DEV_ISAPNP is not set 213 | # CONFIG_IDE_CHIPSETS is not set 214 | # CONFIG_IDEDMA_AUTO is not set 215 | # CONFIG_DMA_NONPCI is not set 216 | # CONFIG_BLK_DEV_ATARAID is not set 217 | # CONFIG_BLK_DEV_ATARAID_PDC is not set 218 | # CONFIG_BLK_DEV_ATARAID_HPT is not set 219 | # CONFIG_BLK_DEV_ATARAID_MEDLEY is not set 220 | # CONFIG_BLK_DEV_ATARAID_SII is not set 221 | 222 | # 223 | # SCSI support 224 | # 225 | # CONFIG_SCSI is not set 226 | 227 | # 228 | # Fusion MPT device support 229 | # 230 | # CONFIG_FUSION is not set 231 | # CONFIG_FUSION_BOOT is not set 232 | # CONFIG_FUSION_ISENSE is not set 233 | # CONFIG_FUSION_CTL is not set 234 | # CONFIG_FUSION_LAN is not set 235 | 236 | # 237 | # I2O device support 238 | # 239 | # CONFIG_I2O is not set 240 | # CONFIG_I2O_BLOCK is not set 241 | # CONFIG_I2O_LAN is not set 242 | # CONFIG_I2O_SCSI is not set 243 | # CONFIG_I2O_PROC is not set 244 | 245 | # 246 | # Network device support 247 | # 248 | CONFIG_NETDEVICES=y 249 | 250 | # 251 | # ARCnet devices 252 | # 253 | # CONFIG_ARCNET is not set 254 | CONFIG_DUMMY=y 255 | # CONFIG_BONDING is not set 256 | # CONFIG_EQUALIZER is not set 257 | # CONFIG_TUN is not set 258 | 259 | # 260 | # Ethernet (10 or 100Mbit) 261 | # 262 | CONFIG_NET_ETHERNET=y 263 | # CONFIG_SUNLANCE is not set 264 | # CONFIG_SUNBMAC is not set 265 | # CONFIG_SUNQE is not set 266 | # CONFIG_SUNGEM is not set 267 | # CONFIG_NET_VENDOR_3COM is not set 268 | # CONFIG_LANCE is not set 269 | # CONFIG_NET_VENDOR_SMC is not set 270 | # CONFIG_NET_VENDOR_RACAL is not set 271 | # CONFIG_NET_ISA is not set 272 | # CONFIG_NET_PCI is not set 273 | # CONFIG_NET_POCKET is not set 274 | 275 | # 276 | # Ethernet (1000 Mbit) 277 | # 278 | # CONFIG_ACENIC is not set 279 | # CONFIG_DL2K is not set 280 | # CONFIG_E1000 is not set 281 | # CONFIG_MYRI_SBUS is not set 282 | # CONFIG_NS83820 is not set 283 | # CONFIG_HAMACHI is not set 284 | # CONFIG_YELLOWFIN is not set 285 | # CONFIG_R8169 is not set 286 | # CONFIG_SK98LIN is not set 287 | # CONFIG_TIGON3 is not set 288 | # CONFIG_FDDI is not set 289 | # CONFIG_PLIP is not set 290 | # CONFIG_PPP is not set 291 | # CONFIG_SLIP is not set 292 | 293 | # 294 | # Wireless LAN (non-hamradio) 295 | # 296 | # CONFIG_NET_RADIO is not set 297 | 298 | # 299 | # Token Ring devices 300 | # 301 | # CONFIG_TR is not set 302 | # CONFIG_NET_FC is not set 303 | 304 | # 305 | # Wan interfaces 306 | # 307 | # CONFIG_WAN is not set 308 | 309 | # 310 | # Amateur Radio support 311 | # 312 | # CONFIG_HAMRADIO is not set 313 | 314 | # 315 | # IrDA (infrared) support 316 | # 317 | # CONFIG_IRDA is not set 318 | 319 | # 320 | # ISDN subsystem 321 | # 322 | # CONFIG_ISDN is not set 323 | 324 | # 325 | # Input core support 326 | # 327 | # CONFIG_INPUT is not set 328 | # CONFIG_INPUT_KEYBDEV is not set 329 | # CONFIG_INPUT_MOUSEDEV is not set 330 | # CONFIG_INPUT_JOYDEV is not set 331 | # CONFIG_INPUT_EVDEV is not set 332 | # CONFIG_INPUT_UINPUT is not set 333 | 334 | # 335 | # Character devices 336 | # 337 | CONFIG_VT=y 338 | CONFIG_VT_CONSOLE=y 339 | CONFIG_SERIAL=y 340 | CONFIG_SERIAL_CONSOLE=y 341 | # CONFIG_SERIAL_EXTENDED is not set 342 | # CONFIG_SERIAL_NONSTANDARD is not set 343 | CONFIG_UNIX98_PTYS=y 344 | CONFIG_UNIX98_PTY_COUNT=256 345 | 346 | # 347 | # I2C support 348 | # 349 | # CONFIG_I2C is not set 350 | 351 | # 352 | # Mice 353 | # 354 | # CONFIG_BUSMOUSE is not set 355 | CONFIG_MOUSE=y 356 | CONFIG_PSMOUSE=y 357 | # CONFIG_82C710_MOUSE is not set 358 | # CONFIG_PC110_PAD is not set 359 | # CONFIG_MK712_MOUSE is not set 360 | 361 | # 362 | # Joysticks 363 | # 364 | # CONFIG_INPUT_GAMEPORT is not set 365 | # CONFIG_QIC02_TAPE is not set 366 | # CONFIG_IPMI_HANDLER is not set 367 | # CONFIG_IPMI_PANIC_EVENT is not set 368 | # CONFIG_IPMI_DEVICE_INTERFACE is not set 369 | # CONFIG_IPMI_KCS is not set 370 | # CONFIG_IPMI_WATCHDOG is not set 371 | 372 | # 373 | # Watchdog Cards 374 | # 375 | # CONFIG_WATCHDOG is not set 376 | # CONFIG_SCx200 is not set 377 | # CONFIG_SCx200_GPIO is not set 378 | # CONFIG_AMD_RNG is not set 379 | # CONFIG_INTEL_RNG is not set 380 | # CONFIG_HW_RANDOM is not set 381 | # CONFIG_AMD_PM768 is not set 382 | # CONFIG_NVRAM is not set 383 | # CONFIG_RTC is not set 384 | # CONFIG_DTLK is not set 385 | # CONFIG_R3964 is not set 386 | # CONFIG_APPLICOM is not set 387 | 388 | # 389 | # Ftape, the floppy tape device driver 390 | # 391 | # CONFIG_FTAPE is not set 392 | # CONFIG_AGP is not set 393 | 394 | # 395 | # Direct Rendering Manager (XFree86 DRI support) 396 | # 397 | # CONFIG_DRM is not set 398 | # CONFIG_MWAVE is not set 399 | # CONFIG_OBMOUSE is not set 400 | 401 | # 402 | # Multimedia devices 403 | # 404 | # CONFIG_VIDEO_DEV is not set 405 | 406 | # 407 | # File systems 408 | # 409 | # CONFIG_QUOTA is not set 410 | # CONFIG_QFMT_V2 is not set 411 | # CONFIG_AUTOFS_FS is not set 412 | # CONFIG_AUTOFS4_FS is not set 413 | # CONFIG_REISERFS_FS is not set 414 | # CONFIG_REISERFS_CHECK is not set 415 | # CONFIG_REISERFS_PROC_INFO is not set 416 | # CONFIG_ADFS_FS is not set 417 | # CONFIG_ADFS_FS_RW is not set 418 | # CONFIG_AFFS_FS is not set 419 | # CONFIG_HFS_FS is not set 420 | # CONFIG_HFSPLUS_FS is not set 421 | # CONFIG_BEFS_FS is not set 422 | # CONFIG_BEFS_DEBUG is not set 423 | # CONFIG_BFS_FS is not set 424 | # CONFIG_EXT3_FS is not set 425 | # CONFIG_JBD is not set 426 | # CONFIG_JBD_DEBUG is not set 427 | # CONFIG_FAT_FS is not set 428 | # CONFIG_MSDOS_FS is not set 429 | # CONFIG_UMSDOS_FS is not set 430 | # CONFIG_VFAT_FS is not set 431 | # CONFIG_EFS_FS is not set 432 | # CONFIG_JFFS_FS is not set 433 | # CONFIG_JFFS2_FS is not set 434 | # CONFIG_CRAMFS is not set 435 | CONFIG_TMPFS=y 436 | CONFIG_RAMFS=y 437 | CONFIG_ISO9660_FS=y 438 | # CONFIG_JOLIET is not set 439 | # CONFIG_ZISOFS is not set 440 | # CONFIG_JFS_FS is not set 441 | # CONFIG_JFS_DEBUG is not set 442 | # CONFIG_JFS_STATISTICS is not set 443 | # CONFIG_MINIX_FS is not set 444 | # CONFIG_VXFS_FS is not set 445 | # CONFIG_NTFS_FS is not set 446 | # CONFIG_NTFS_RW is not set 447 | # CONFIG_HPFS_FS is not set 448 | CONFIG_PROC_FS=y 449 | # CONFIG_DEVFS_FS is not set 450 | # CONFIG_DEVFS_MOUNT is not set 451 | # CONFIG_DEVFS_DEBUG is not set 452 | CONFIG_DEVPTS_FS=y 453 | # CONFIG_QNX4FS_FS is not set 454 | # CONFIG_QNX4FS_RW is not set 455 | CONFIG_ROMFS_FS=y 456 | CONFIG_EXT2_FS=y 457 | # CONFIG_SYSV_FS is not set 458 | # CONFIG_UDF_FS is not set 459 | # CONFIG_UDF_RW is not set 460 | # CONFIG_UFS_FS is not set 461 | # CONFIG_UFS_FS_WRITE is not set 462 | # CONFIG_XFS_FS is not set 463 | # CONFIG_XFS_QUOTA is not set 464 | # CONFIG_XFS_RT is not set 465 | # CONFIG_XFS_TRACE is not set 466 | # CONFIG_XFS_DEBUG is not set 467 | 468 | # 469 | # Network File Systems 470 | # 471 | # CONFIG_CODA_FS is not set 472 | # CONFIG_INTERMEZZO_FS is not set 473 | # CONFIG_NFS_FS is not set 474 | # CONFIG_NFS_V3 is not set 475 | # CONFIG_NFS_DIRECTIO is not set 476 | # CONFIG_ROOT_NFS is not set 477 | # CONFIG_NFSD is not set 478 | # CONFIG_NFSD_V3 is not set 479 | # CONFIG_NFSD_TCP is not set 480 | # CONFIG_SUNRPC is not set 481 | # CONFIG_LOCKD is not set 482 | # CONFIG_SMB_FS is not set 483 | # CONFIG_NCP_FS is not set 484 | # CONFIG_NCPFS_PACKET_SIGNING is not set 485 | # CONFIG_NCPFS_IOCTL_LOCKING is not set 486 | # CONFIG_NCPFS_STRONG is not set 487 | # CONFIG_NCPFS_NFS_NS is not set 488 | # CONFIG_NCPFS_OS2_NS is not set 489 | # CONFIG_NCPFS_SMALLDOS is not set 490 | # CONFIG_NCPFS_NLS is not set 491 | # CONFIG_NCPFS_EXTRAS is not set 492 | # CONFIG_ZISOFS_FS is not set 493 | 494 | # 495 | # Partition Types 496 | # 497 | # CONFIG_PARTITION_ADVANCED is not set 498 | CONFIG_MSDOS_PARTITION=y 499 | # CONFIG_SMB_NLS is not set 500 | # CONFIG_NLS is not set 501 | 502 | # 503 | # Console drivers 504 | # 505 | CONFIG_VGA_CONSOLE=y 506 | # CONFIG_VIDEO_SELECT is not set 507 | 508 | # 509 | # Sound 510 | # 511 | # CONFIG_SOUND is not set 512 | 513 | # 514 | # USB support 515 | # 516 | # CONFIG_USB is not set 517 | 518 | # 519 | # Support for USB gadgets 520 | # 521 | # CONFIG_USB_GADGET is not set 522 | 523 | # 524 | # Bluetooth support 525 | # 526 | # CONFIG_BLUEZ is not set 527 | 528 | # 529 | # Kernel hacking 530 | # 531 | CONFIG_DEBUG_KERNEL=y 532 | # CONFIG_DEBUG_STACKOVERFLOW is not set 533 | # CONFIG_DEBUG_HIGHMEM is not set 534 | # CONFIG_DEBUG_SLAB is not set 535 | # CONFIG_DEBUG_IOVIRT is not set 536 | # CONFIG_MAGIC_SYSRQ is not set 537 | # CONFIG_DEBUG_SPINLOCK is not set 538 | # CONFIG_FRAME_POINTER is not set 539 | CONFIG_LOG_BUF_SHIFT=0 540 | 541 | # 542 | # Cryptographic options 543 | # 544 | # CONFIG_CRYPTO is not set 545 | 546 | # 547 | # Library routines 548 | # 549 | CONFIG_CRC32=y 550 | # CONFIG_ZLIB_INFLATE is not set 551 | # CONFIG_ZLIB_DEFLATE is not set 552 | -------------------------------------------------------------------------------- /linux-2.4.26-tcc.patch: -------------------------------------------------------------------------------- 1 | diff -ruNw /tmp/linux-2.4.26/arch/i386/kernel/entry.S linux-2.4.26/arch/i386/kernel/entry.S 2 | --- /tmp/linux-2.4.26/arch/i386/kernel/entry.S 2003-06-13 16:51:29.000000000 +0200 3 | +++ linux-2.4.26/arch/i386/kernel/entry.S 2004-10-23 22:19:02.000000000 +0200 4 | @@ -1,3 +1,4 @@ 5 | +#define __ASSEMBLY__ 6 | /* 7 | * linux/arch/i386/entry.S 8 | * 9 | @@ -664,6 +665,21 @@ 10 | .long SYMBOL_NAME(sys_ni_syscall) /* sys_remap_file_pages */ 11 | .long SYMBOL_NAME(sys_ni_syscall) /* sys_set_tid_address */ 12 | 13 | +#if 0 14 | .rept NR_syscalls-(.-sys_call_table)/4 15 | .long SYMBOL_NAME(sys_ni_syscall) 16 | .endr 17 | +#else 18 | + .long SYMBOL_NAME(sys_ni_syscall) 19 | + .long SYMBOL_NAME(sys_ni_syscall) 20 | + .long SYMBOL_NAME(sys_ni_syscall) 21 | + .long SYMBOL_NAME(sys_ni_syscall) 22 | + .long SYMBOL_NAME(sys_ni_syscall) 23 | + .long SYMBOL_NAME(sys_ni_syscall) 24 | + .long SYMBOL_NAME(sys_ni_syscall) 25 | + .long SYMBOL_NAME(sys_ni_syscall) 26 | + .long SYMBOL_NAME(sys_ni_syscall) 27 | + .long SYMBOL_NAME(sys_ni_syscall) 28 | + .long SYMBOL_NAME(sys_ni_syscall) 29 | + .long SYMBOL_NAME(sys_ni_syscall) 30 | +#endif 31 | diff -ruNw /tmp/linux-2.4.26/arch/i386/kernel/head.S linux-2.4.26/arch/i386/kernel/head.S 32 | --- /tmp/linux-2.4.26/arch/i386/kernel/head.S 2003-11-28 19:26:19.000000000 +0100 33 | +++ linux-2.4.26/arch/i386/kernel/head.S 2004-10-25 21:18:30.000000000 +0200 34 | @@ -1,3 +1,4 @@ 35 | +#define __ASSEMBLY__ 36 | /* 37 | * linux/arch/i386/kernel/head.S -- the 32-bit startup code. 38 | * 39 | @@ -41,6 +42,8 @@ 40 | * 41 | * On entry, %esi points to the real-mode code as a 32-bit pointer. 42 | */ 43 | +.globl _start 44 | +_start: 45 | startup_32: 46 | /* 47 | * Set segments to known values 48 | diff -ruNw /tmp/linux-2.4.26/arch/i386/kernel/i387.c linux-2.4.26/arch/i386/kernel/i387.c 49 | --- /tmp/linux-2.4.26/arch/i386/kernel/i387.c 2003-08-25 13:44:39.000000000 +0200 50 | +++ linux-2.4.26/arch/i386/kernel/i387.c 2004-10-14 04:17:43.000000000 +0200 51 | @@ -25,7 +25,7 @@ 52 | #define HAVE_HWFP 1 53 | #endif 54 | 55 | -static union i387_union empty_fpu_state; 56 | +union i387_union empty_fpu_state; 57 | 58 | void __init boot_init_fpu(void) 59 | { 60 | diff -ruNw /tmp/linux-2.4.26/arch/i386/kernel/process.c linux-2.4.26/arch/i386/kernel/process.c 61 | --- /tmp/linux-2.4.26/arch/i386/kernel/process.c 2004-02-18 14:36:30.000000000 +0100 62 | +++ linux-2.4.26/arch/i386/kernel/process.c 2004-10-25 21:30:36.000000000 +0200 63 | @@ -52,7 +52,7 @@ 64 | 65 | #include 66 | 67 | -asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 68 | +asmlinkage void ret_from_fork(void) /* __asm__("ret_from_fork") */ ; 69 | 70 | int hlt_counter; 71 | 72 | @@ -217,7 +217,7 @@ 73 | 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ 74 | }; 75 | 76 | -static struct 77 | +struct 78 | { 79 | unsigned short size __attribute__ ((packed)); 80 | unsigned long long * base __attribute__ ((packed)); 81 | diff -ruNw /tmp/linux-2.4.26/arch/i386/kernel/setup.c linux-2.4.26/arch/i386/kernel/setup.c 82 | --- /tmp/linux-2.4.26/arch/i386/kernel/setup.c 2004-04-14 15:05:25.000000000 +0200 83 | +++ linux-2.4.26/arch/i386/kernel/setup.c 2004-10-17 19:38:37.000000000 +0200 84 | @@ -1392,7 +1392,7 @@ 85 | */ 86 | 87 | extern void vide(void); 88 | -__asm__(".align 4\nvide: ret"); 89 | +__asm__(".align 4\n.globl vide\nvide: ret"); 90 | 91 | static int __init init_amd(struct cpuinfo_x86 *c) 92 | { 93 | diff -ruNw /tmp/linux-2.4.26/arch/i386/mm/init.c linux-2.4.26/arch/i386/mm/init.c 94 | --- /tmp/linux-2.4.26/arch/i386/mm/init.c 2004-04-14 15:05:25.000000000 +0200 95 | +++ linux-2.4.26/arch/i386/mm/init.c 2004-10-23 22:35:47.000000000 +0200 96 | @@ -36,6 +36,7 @@ 97 | #include 98 | #include 99 | #include 100 | +#include 101 | #include 102 | 103 | mmu_gather_t mmu_gathers[NR_CPUS]; 104 | diff -ruNw /tmp/linux-2.4.26/arch/i386/mm/pageattr.c linux-2.4.26/arch/i386/mm/pageattr.c 105 | --- /tmp/linux-2.4.26/arch/i386/mm/pageattr.c 2002-11-29 00:53:09.000000000 +0100 106 | +++ linux-2.4.26/arch/i386/mm/pageattr.c 2004-10-14 00:43:58.000000000 +0200 107 | @@ -44,8 +44,12 @@ 108 | addr = address & LARGE_PAGE_MASK; 109 | pbase = (pte_t *)page_address(base); 110 | for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) { 111 | - pbase[i] = mk_pte_phys(addr, 112 | - addr == address ? prot : PAGE_KERNEL); 113 | + pgprot_t prot1; 114 | + if (addr == address) 115 | + prot1 = prot; 116 | + else 117 | + prot1 = PAGE_KERNEL; 118 | + pbase[i] = mk_pte_phys(addr, prot1); 119 | } 120 | return base; 121 | } 122 | diff -ruNw /tmp/linux-2.4.26/drivers/ide/ide-lib.c linux-2.4.26/drivers/ide/ide-lib.c 123 | --- /tmp/linux-2.4.26/drivers/ide/ide-lib.c 2003-06-13 16:51:33.000000000 +0200 124 | +++ linux-2.4.26/drivers/ide/ide-lib.c 2004-10-23 23:00:51.000000000 +0200 125 | @@ -171,7 +171,7 @@ 126 | BUG(); 127 | return min(speed, speed_max[mode]); 128 | #else /* !CONFIG_BLK_DEV_IDEDMA */ 129 | - return min(speed, XFER_PIO_4); 130 | + return min((int)speed, XFER_PIO_4); 131 | #endif /* CONFIG_BLK_DEV_IDEDMA */ 132 | } 133 | 134 | diff -ruNw /tmp/linux-2.4.26/fs/partitions/efi.h linux-2.4.26/fs/partitions/efi.h 135 | --- /tmp/linux-2.4.26/fs/partitions/efi.h 2003-08-25 13:44:43.000000000 +0200 136 | +++ linux-2.4.26/fs/partitions/efi.h 2004-10-25 21:32:29.000000000 +0200 137 | @@ -85,9 +85,13 @@ 138 | } __attribute__ ((packed)) gpt_header; 139 | 140 | typedef struct _gpt_entry_attributes { 141 | +#if 0 142 | u64 required_to_function:1; 143 | u64 reserved:47; 144 | u64 type_guid_specific:16; 145 | +#else 146 | + u64 required; 147 | +#endif 148 | } __attribute__ ((packed)) gpt_entry_attributes; 149 | 150 | typedef struct _gpt_entry { 151 | diff -ruNw /tmp/linux-2.4.26/include/asm-i386/bugs.h linux-2.4.26/include/asm-i386/bugs.h 152 | --- /tmp/linux-2.4.26/include/asm-i386/bugs.h 2002-08-03 02:39:45.000000000 +0200 153 | +++ linux-2.4.26/include/asm-i386/bugs.h 2004-10-25 21:31:34.000000000 +0200 154 | @@ -50,8 +50,8 @@ 155 | 156 | __setup("no387", no_387); 157 | 158 | -static double __initdata x = 4195835.0; 159 | -static double __initdata y = 3145727.0; 160 | +double __initdata x = 4195835.0; 161 | +double __initdata y = 3145727.0; 162 | 163 | /* 164 | * This used to check for exceptions.. 165 | diff -ruNw /tmp/linux-2.4.26/include/asm-i386/byteorder.h linux-2.4.26/include/asm-i386/byteorder.h 166 | --- /tmp/linux-2.4.26/include/asm-i386/byteorder.h 2003-06-13 16:51:38.000000000 +0200 167 | +++ linux-2.4.26/include/asm-i386/byteorder.h 2004-10-23 23:08:08.000000000 +0200 168 | @@ -42,8 +42,10 @@ 169 | __u64 u; 170 | } v; 171 | v.u = val; 172 | -#ifdef CONFIG_X86_BSWAP 173 | - asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1" 174 | +#if defined(CONFIG_X86_BSWAP) && 0 175 | + /* XXX: constraint bug 176 | + bswap %eax ; bswap (%ecx) ; xchgl %eax,(%ecx) */ 177 | + asm("bswap %0 ; bswap %1 ; xchgl %0,%1" 178 | : "=r" (v.s.a), "=r" (v.s.b) 179 | : "0" (v.s.a), "1" (v.s.b)); 180 | #else 181 | diff -ruNw /tmp/linux-2.4.26/include/asm-i386/hw_irq.h linux-2.4.26/include/asm-i386/hw_irq.h 182 | --- /tmp/linux-2.4.26/include/asm-i386/hw_irq.h 2003-08-25 13:44:43.000000000 +0200 183 | +++ linux-2.4.26/include/asm-i386/hw_irq.h 2004-10-23 23:08:08.000000000 +0200 184 | @@ -156,6 +156,7 @@ 185 | asmlinkage void call_do_IRQ(void); \ 186 | __asm__( \ 187 | "\n" __ALIGN_STR"\n" \ 188 | + ".globl common_interrupt\n\t" \ 189 | "common_interrupt:\n\t" \ 190 | SAVE_ALL \ 191 | SYMBOL_NAME_STR(call_do_IRQ)":\n\t" \ 192 | @@ -176,6 +177,7 @@ 193 | asmlinkage void IRQ_NAME(nr); \ 194 | __asm__( \ 195 | "\n"__ALIGN_STR"\n" \ 196 | +".globl " SYMBOL_NAME_STR(IRQ) #nr "_interrupt\n\t"\ 197 | SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ 198 | "pushl $"#nr"-256\n\t" \ 199 | "jmp common_interrupt"); 200 | diff -ruNw /tmp/linux-2.4.26/include/asm-i386/page.h linux-2.4.26/include/asm-i386/page.h 201 | --- /tmp/linux-2.4.26/include/asm-i386/page.h 2002-08-03 02:39:45.000000000 +0200 202 | +++ linux-2.4.26/include/asm-i386/page.h 2004-10-23 23:08:08.000000000 +0200 203 | @@ -95,7 +95,7 @@ 204 | * undefined" opcode for parsing in the trap handler. 205 | */ 206 | 207 | -#if 1 /* Set to zero for a slightly smaller kernel */ 208 | +#if 0 /* Set to zero for a slightly smaller kernel */ 209 | #define BUG() \ 210 | __asm__ __volatile__( "ud2\n" \ 211 | "\t.word %c0\n" \ 212 | diff -ruNw /tmp/linux-2.4.26/include/asm-i386/processor.h linux-2.4.26/include/asm-i386/processor.h 213 | --- /tmp/linux-2.4.26/include/asm-i386/processor.h 2004-02-18 14:36:32.000000000 +0100 214 | +++ linux-2.4.26/include/asm-i386/processor.h 2004-10-23 23:08:08.000000000 +0200 215 | @@ -300,6 +300,7 @@ 216 | long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ 217 | long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ 218 | long padding[56]; 219 | + int dummy[0] __attribute__ ((aligned (16))); 220 | } __attribute__ ((aligned (16))); 221 | 222 | struct i387_soft_struct { 223 | diff -ruNw /tmp/linux-2.4.26/include/asm-i386/semaphore.h linux-2.4.26/include/asm-i386/semaphore.h 224 | --- /tmp/linux-2.4.26/include/asm-i386/semaphore.h 2002-11-29 00:53:15.000000000 +0100 225 | +++ linux-2.4.26/include/asm-i386/semaphore.h 2004-10-25 21:31:34.000000000 +0200 226 | @@ -207,7 +207,7 @@ 227 | "2:\tcall __up_wakeup\n\t" 228 | "jmp 1b\n" 229 | LOCK_SECTION_END 230 | - ".subsection 0\n" 231 | + /* ".subsection 0\n" */ 232 | :"=m" (sem->count) 233 | :"c" (sem) 234 | :"memory"); 235 | diff -ruNw /tmp/linux-2.4.26/include/asm-i386/string.h linux-2.4.26/include/asm-i386/string.h 236 | --- /tmp/linux-2.4.26/include/asm-i386/string.h 2001-11-22 20:46:18.000000000 +0100 237 | +++ linux-2.4.26/include/asm-i386/string.h 2004-10-23 23:08:08.000000000 +0200 238 | @@ -178,7 +178,7 @@ 239 | "leal -1(%%esi),%0\n" 240 | "2:\ttestb %%al,%%al\n\t" 241 | "jne 1b" 242 | - :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c)); 243 | + :"=r" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c)); 244 | return __res; 245 | } 246 | 247 | diff -ruNw /tmp/linux-2.4.26/include/asm-i386/system.h linux-2.4.26/include/asm-i386/system.h 248 | --- /tmp/linux-2.4.26/include/asm-i386/system.h 2004-04-14 15:05:40.000000000 +0200 249 | +++ linux-2.4.26/include/asm-i386/system.h 2004-10-25 21:30:22.000000000 +0200 250 | @@ -28,7 +28,7 @@ 251 | "popl %%esi\n\t" \ 252 | :"=m" (prev->thread.esp),"=m" (prev->thread.eip), \ 253 | "=b" (last) \ 254 | - :"m" (next->thread.esp),"m" (next->thread.eip), \ 255 | + :"g" (next->thread.esp),"g" (next->thread.eip), \ 256 | "a" (prev), "d" (next), \ 257 | "b" (prev)); \ 258 | } while (0) 259 | @@ -313,7 +313,7 @@ 260 | #define set_wmb(var, value) do { var = value; wmb(); } while (0) 261 | 262 | /* interrupt control.. */ 263 | -#define __save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */) 264 | +#define __save_flags(x) __asm__ __volatile__("pushfl ; popl %0" : "=g" (x) /* no input */) 265 | #define __restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc") 266 | #define __cli() __asm__ __volatile__("cli": : :"memory") 267 | #define __sti() __asm__ __volatile__("sti": : :"memory") 268 | diff -ruNw /tmp/linux-2.4.26/include/linux/byteorder/generic.h linux-2.4.26/include/linux/byteorder/generic.h 269 | --- /tmp/linux-2.4.26/include/linux/byteorder/generic.h 2003-11-28 19:26:21.000000000 +0100 270 | +++ linux-2.4.26/include/linux/byteorder/generic.h 2004-10-17 22:09:20.000000000 +0200 271 | @@ -86,8 +86,8 @@ 272 | */ 273 | #define cpu_to_le64 __cpu_to_le64 274 | #define le64_to_cpu __le64_to_cpu 275 | -#define cpu_to_le32 __cpu_to_le32 276 | -#define le32_to_cpu __le32_to_cpu 277 | +#define cpu_to_le32(x) __cpu_to_le32(x) 278 | +#define le32_to_cpu(x) __le32_to_cpu(x) 279 | #define cpu_to_le16 __cpu_to_le16 280 | #define le16_to_cpu __le16_to_cpu 281 | #define cpu_to_be64 __cpu_to_be64 282 | diff -ruNw /tmp/linux-2.4.26/include/linux/linkage.h linux-2.4.26/include/linux/linkage.h 283 | --- /tmp/linux-2.4.26/include/linux/linkage.h 2000-12-11 21:49:54.000000000 +0100 284 | +++ linux-2.4.26/include/linux/linkage.h 2004-10-23 23:08:08.000000000 +0200 285 | @@ -19,11 +19,7 @@ 286 | 287 | #define SYMBOL_NAME_STR(X) #X 288 | #define SYMBOL_NAME(X) X 289 | -#ifdef __STDC__ 290 | -#define SYMBOL_NAME_LABEL(X) X##: 291 | -#else 292 | -#define SYMBOL_NAME_LABEL(X) X/**/: 293 | -#endif 294 | +#define SYMBOL_NAME_LABEL(X) X: 295 | 296 | #ifdef __arm__ 297 | #define __ALIGN .align 0 298 | diff -ruNw /tmp/linux-2.4.26/include/linux/spinlock.h linux-2.4.26/include/linux/spinlock.h 299 | --- /tmp/linux-2.4.26/include/linux/spinlock.h 2004-02-18 14:36:32.000000000 +0100 300 | +++ linux-2.4.26/include/linux/spinlock.h 2004-10-25 21:31:34.000000000 +0200 301 | @@ -41,6 +41,7 @@ 302 | 303 | #include 304 | 305 | +#if 0 306 | #define LOCK_SECTION_NAME \ 307 | ".text.lock." __stringify(KBUILD_BASENAME) 308 | 309 | @@ -51,6 +52,11 @@ 310 | LOCK_SECTION_NAME ":\n\t" \ 311 | ".endif\n\t" 312 | 313 | +#else 314 | +#define LOCK_SECTION_NAME ".text.lock" 315 | +#define LOCK_SECTION_START(extra) ".section " LOCK_SECTION_NAME "\n\t" 316 | +#endif 317 | + 318 | #define LOCK_SECTION_END \ 319 | ".previous\n\t" 320 | 321 | diff -ruNw /tmp/linux-2.4.26/include/linux/wait.h linux-2.4.26/include/linux/wait.h 322 | --- /tmp/linux-2.4.26/include/linux/wait.h 2003-08-25 13:44:44.000000000 +0200 323 | +++ linux-2.4.26/include/linux/wait.h 2004-10-25 21:31:34.000000000 +0200 324 | @@ -64,14 +64,14 @@ 325 | # define wq_lock_t spinlock_t 326 | # define WAITQUEUE_RW_LOCK_UNLOCKED SPIN_LOCK_UNLOCKED 327 | 328 | -# define wq_read_lock spin_lock 329 | -# define wq_read_lock_irqsave spin_lock_irqsave 330 | -# define wq_read_unlock spin_unlock 331 | -# define wq_read_unlock_irqrestore spin_unlock_irqrestore 332 | -# define wq_write_lock_irq spin_lock_irq 333 | -# define wq_write_lock_irqsave spin_lock_irqsave 334 | -# define wq_write_unlock_irqrestore spin_unlock_irqrestore 335 | -# define wq_write_unlock spin_unlock 336 | +# define wq_read_lock(lock) spin_lock(lock) 337 | +# define wq_read_lock_irqsave(lock, flags) spin_lock_irqsave(lock, flags) 338 | +# define wq_read_unlock(lock) spin_unlock(lock) 339 | +# define wq_read_unlock_irqrestore(lock, flags) spin_unlock_irqrestore(lock, flags) 340 | +# define wq_write_lock_irq(lock) spin_lock_irq(lock) 341 | +# define wq_write_lock_irqsave(lock, flags) spin_lock_irqsave(lock, flags) 342 | +# define wq_write_unlock_irqrestore(lock, flags) spin_unlock_irqrestore(lock, flags) 343 | +# define wq_write_unlock(lock) spin_unlock(lock) 344 | #endif 345 | 346 | struct __wait_queue_head { 347 | diff -ruNw /tmp/linux-2.4.26/net/core/dev.c linux-2.4.26/net/core/dev.c 348 | --- /tmp/linux-2.4.26/net/core/dev.c 2004-04-14 15:05:41.000000000 +0200 349 | +++ linux-2.4.26/net/core/dev.c 2004-10-14 03:27:45.000000000 +0200 350 | @@ -2013,8 +2013,17 @@ 351 | ret = 0; 352 | if ((old_flags^flags)&IFF_UP) /* Bit is different ? */ 353 | { 354 | - ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev); 355 | + int (*dev_func)(struct net_device *); 356 | 357 | +#if 0 358 | + ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev); 359 | +#else 360 | + if (old_flags & IFF_UP) 361 | + dev_func = dev_close; 362 | + else 363 | + dev_func = dev_open; 364 | + ret = dev_func(dev); 365 | +#endif 366 | if (ret == 0) 367 | dev_mc_upload(dev); 368 | } 369 | diff -ruNw /tmp/linux-2.4.26/net/ipv4/raw.c linux-2.4.26/net/ipv4/raw.c 370 | --- /tmp/linux-2.4.26/net/ipv4/raw.c 2003-08-25 13:44:44.000000000 +0200 371 | +++ linux-2.4.26/net/ipv4/raw.c 2004-10-23 22:53:26.000000000 +0200 372 | @@ -311,6 +311,10 @@ 373 | u32 daddr; 374 | u8 tos; 375 | int err; 376 | + int (*getfrag)(const void *, 377 | + char *, 378 | + unsigned int, 379 | + unsigned int); 380 | 381 | /* This check is ONLY to check for arithmetic overflow 382 | on integer(!) len. Not more! Real check will be made 383 | @@ -426,8 +430,11 @@ 384 | rfh.dst = &rt->u.dst; 385 | if (!ipc.addr) 386 | ipc.addr = rt->rt_dst; 387 | - err = ip_build_xmit(sk, sk->protinfo.af_inet.hdrincl ? raw_getrawfrag : 388 | - raw_getfrag, &rfh, len, &ipc, rt, msg->msg_flags); 389 | + if (sk->protinfo.af_inet.hdrincl) 390 | + getfrag =raw_getrawfrag; 391 | + else 392 | + getfrag = raw_getfrag; 393 | + err = ip_build_xmit(sk, getfrag, &rfh, len, &ipc, rt, msg->msg_flags); 394 | 395 | done: 396 | if (free) 397 | diff -ruNw /tmp/linux-2.4.26/net/ipv4/udp.c linux-2.4.26/net/ipv4/udp.c 398 | --- /tmp/linux-2.4.26/net/ipv4/udp.c 2004-04-14 15:05:41.000000000 +0200 399 | +++ linux-2.4.26/net/ipv4/udp.c 2004-10-23 22:54:30.000000000 +0200 400 | @@ -441,6 +441,10 @@ 401 | u32 daddr; 402 | u8 tos; 403 | int err; 404 | + int (*getfrag)(const void *, 405 | + char *, 406 | + unsigned int, 407 | + unsigned int); 408 | 409 | /* This check is ONLY to check for arithmetic overflow 410 | on integer(!) len. Not more! Real check will be made 411 | @@ -560,11 +564,12 @@ 412 | /* RFC1122: OK. Provides the checksumming facility (MUST) as per */ 413 | /* 4.1.3.4. It's configurable by the application via setsockopt() */ 414 | /* (MAY) and it defaults to on (MUST). */ 415 | - 416 | + if (sk->no_check == UDP_CSUM_NOXMIT) 417 | + getfrag = udp_getfrag_nosum; 418 | + else 419 | + getfrag = udp_getfrag; 420 | err = ip_build_xmit(sk, 421 | - (sk->no_check == UDP_CSUM_NOXMIT ? 422 | - udp_getfrag_nosum : 423 | - udp_getfrag), 424 | + getfrag, 425 | &ufh, ulen, &ipc, rt, msg->msg_flags); 426 | 427 | out: 428 | -------------------------------------------------------------------------------- /vsprintf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/lib/vsprintf.c 3 | * 4 | * Copyright (C) 1991, 1992 Linus Torvalds 5 | */ 6 | 7 | /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ 8 | /* 9 | * Wirzenius wrote this portably, Torvalds fucked it up :-) 10 | */ 11 | 12 | /* 13 | * Fri Jul 13 2001 Crutcher Dunnavant 14 | * - changed to provide snprintf and vsnprintf functions 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | /** 27 | * simple_strtoul - convert a string to an unsigned long 28 | * @cp: The start of the string 29 | * @endp: A pointer to the end of the parsed string will be placed here 30 | * @base: The number base to use 31 | */ 32 | unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) 33 | { 34 | unsigned long result = 0,value; 35 | 36 | if (!base) { 37 | base = 10; 38 | if (*cp == '0') { 39 | base = 8; 40 | cp++; 41 | if ((*cp == 'x') && isxdigit(cp[1])) { 42 | cp++; 43 | base = 16; 44 | } 45 | } 46 | } 47 | while (isxdigit(*cp) && 48 | (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { 49 | result = result*base + value; 50 | cp++; 51 | } 52 | if (endp) 53 | *endp = (char *)cp; 54 | return result; 55 | } 56 | 57 | /** 58 | * simple_strtol - convert a string to a signed long 59 | * @cp: The start of the string 60 | * @endp: A pointer to the end of the parsed string will be placed here 61 | * @base: The number base to use 62 | */ 63 | long simple_strtol(const char *cp,char **endp,unsigned int base) 64 | { 65 | if(*cp=='-') 66 | return -simple_strtoul(cp+1,endp,base); 67 | return simple_strtoul(cp,endp,base); 68 | } 69 | 70 | /** 71 | * simple_strtoull - convert a string to an unsigned long long 72 | * @cp: The start of the string 73 | * @endp: A pointer to the end of the parsed string will be placed here 74 | * @base: The number base to use 75 | */ 76 | unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base) 77 | { 78 | unsigned long long result = 0,value; 79 | 80 | if (!base) { 81 | base = 10; 82 | if (*cp == '0') { 83 | base = 8; 84 | cp++; 85 | if ((*cp == 'x') && isxdigit(cp[1])) { 86 | cp++; 87 | base = 16; 88 | } 89 | } 90 | } 91 | while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) 92 | ? toupper(*cp) : *cp)-'A'+10) < base) { 93 | result = result*base + value; 94 | cp++; 95 | } 96 | if (endp) 97 | *endp = (char *)cp; 98 | return result; 99 | } 100 | 101 | /** 102 | * simple_strtoll - convert a string to a signed long long 103 | * @cp: The start of the string 104 | * @endp: A pointer to the end of the parsed string will be placed here 105 | * @base: The number base to use 106 | */ 107 | long long simple_strtoll(const char *cp,char **endp,unsigned int base) 108 | { 109 | if(*cp=='-') 110 | return -simple_strtoull(cp+1,endp,base); 111 | return simple_strtoull(cp,endp,base); 112 | } 113 | 114 | static int skip_atoi(const char **s) 115 | { 116 | int i=0; 117 | 118 | while (isdigit(**s)) 119 | i = i*10 + *((*s)++) - '0'; 120 | return i; 121 | } 122 | 123 | #define ZEROPAD 1 /* pad with zero */ 124 | #define SIGN 2 /* unsigned/signed long */ 125 | #define PLUS 4 /* show plus */ 126 | #define SPACE 8 /* space if plus */ 127 | #define LEFT 16 /* left justified */ 128 | #define SPECIAL 32 /* 0x */ 129 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ 130 | 131 | static char * number(char * buf, char * end, long long num, int base, int size, int precision, int type) 132 | { 133 | char c,sign,tmp[66]; 134 | const char *digits; 135 | static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; 136 | static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 137 | int i; 138 | 139 | digits = (type & LARGE) ? large_digits : small_digits; 140 | if (type & LEFT) 141 | type &= ~ZEROPAD; 142 | if (base < 2 || base > 36) 143 | return 0; 144 | c = (type & ZEROPAD) ? '0' : ' '; 145 | sign = 0; 146 | if (type & SIGN) { 147 | if (num < 0) { 148 | sign = '-'; 149 | num = -num; 150 | size--; 151 | } else if (type & PLUS) { 152 | sign = '+'; 153 | size--; 154 | } else if (type & SPACE) { 155 | sign = ' '; 156 | size--; 157 | } 158 | } 159 | if (type & SPECIAL) { 160 | if (base == 16) 161 | size -= 2; 162 | else if (base == 8) 163 | size--; 164 | } 165 | i = 0; 166 | if (num == 0) 167 | tmp[i++]='0'; 168 | else while (num != 0) 169 | tmp[i++] = digits[do_div(num,base)]; 170 | if (i > precision) 171 | precision = i; 172 | size -= precision; 173 | if (!(type&(ZEROPAD+LEFT))) { 174 | while(size-->0) { 175 | if (buf <= end) 176 | *buf = ' '; 177 | ++buf; 178 | } 179 | } 180 | if (sign) { 181 | if (buf <= end) 182 | *buf = sign; 183 | ++buf; 184 | } 185 | if (type & SPECIAL) { 186 | if (base==8) { 187 | if (buf <= end) 188 | *buf = '0'; 189 | ++buf; 190 | } else if (base==16) { 191 | if (buf <= end) 192 | *buf = '0'; 193 | ++buf; 194 | if (buf <= end) 195 | *buf = digits[33]; 196 | ++buf; 197 | } 198 | } 199 | if (!(type & LEFT)) { 200 | while (size-- > 0) { 201 | if (buf <= end) 202 | *buf = c; 203 | ++buf; 204 | } 205 | } 206 | while (i < precision--) { 207 | if (buf <= end) 208 | *buf = '0'; 209 | ++buf; 210 | } 211 | while (i-- > 0) { 212 | if (buf <= end) 213 | *buf = tmp[i]; 214 | ++buf; 215 | } 216 | while (size-- > 0) { 217 | if (buf <= end) 218 | *buf = ' '; 219 | ++buf; 220 | } 221 | return buf; 222 | } 223 | 224 | /** 225 | * vsnprintf - Format a string and place it in a buffer 226 | * @buf: The buffer to place the result into 227 | * @size: The size of the buffer, including the trailing null space 228 | * @fmt: The format string to use 229 | * @args: Arguments for the format string 230 | * 231 | * Call this function if you are already dealing with a va_list. 232 | * You probably want snprintf instead. 233 | */ 234 | int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) 235 | { 236 | int len; 237 | unsigned long long num; 238 | int i, base; 239 | char *str, *end, c; 240 | const char *s; 241 | 242 | int flags; /* flags to number() */ 243 | 244 | int field_width; /* width of output field */ 245 | int precision; /* min. # of digits for integers; max 246 | number of chars for from string */ 247 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ 248 | /* 'z' support added 23/7/1999 S.H. */ 249 | /* 'z' changed to 'Z' --davidm 1/25/99 */ 250 | 251 | 252 | /* Reject out-of-range values early */ 253 | if (unlikely((int) size < 0)) { 254 | #if 0 255 | /* There can be only one.. */ 256 | static int warn = 1; 257 | if (warn) { 258 | printk(KERN_WARNING "improper call of vsnprintf!\n"); 259 | dump_stack(); 260 | warn = 0; 261 | } 262 | #endif 263 | return 0; 264 | } 265 | 266 | str = buf; 267 | end = buf + size - 1; 268 | 269 | if (end < buf - 1) { 270 | end = ((void *) -1); 271 | size = end - buf + 1; 272 | } 273 | 274 | for (; *fmt ; ++fmt) { 275 | if (*fmt != '%') { 276 | if (str <= end) 277 | *str = *fmt; 278 | ++str; 279 | continue; 280 | } 281 | 282 | /* process flags */ 283 | flags = 0; 284 | repeat: 285 | ++fmt; /* this also skips first '%' */ 286 | switch (*fmt) { 287 | case '-': flags |= LEFT; goto repeat; 288 | case '+': flags |= PLUS; goto repeat; 289 | case ' ': flags |= SPACE; goto repeat; 290 | case '#': flags |= SPECIAL; goto repeat; 291 | case '0': flags |= ZEROPAD; goto repeat; 292 | } 293 | 294 | /* get field width */ 295 | field_width = -1; 296 | if (isdigit(*fmt)) 297 | field_width = skip_atoi(&fmt); 298 | else if (*fmt == '*') { 299 | ++fmt; 300 | /* it's the next argument */ 301 | field_width = va_arg(args, int); 302 | if (field_width < 0) { 303 | field_width = -field_width; 304 | flags |= LEFT; 305 | } 306 | } 307 | 308 | /* get the precision */ 309 | precision = -1; 310 | if (*fmt == '.') { 311 | ++fmt; 312 | if (isdigit(*fmt)) 313 | precision = skip_atoi(&fmt); 314 | else if (*fmt == '*') { 315 | ++fmt; 316 | /* it's the next argument */ 317 | precision = va_arg(args, int); 318 | } 319 | if (precision < 0) 320 | precision = 0; 321 | } 322 | 323 | /* get the conversion qualifier */ 324 | qualifier = -1; 325 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || 326 | *fmt =='Z' || *fmt == 'z') { 327 | qualifier = *fmt; 328 | ++fmt; 329 | if (qualifier == 'l' && *fmt == 'l') { 330 | qualifier = 'L'; 331 | ++fmt; 332 | } 333 | } 334 | 335 | /* default base */ 336 | base = 10; 337 | 338 | switch (*fmt) { 339 | case 'c': 340 | if (!(flags & LEFT)) { 341 | while (--field_width > 0) { 342 | if (str <= end) 343 | *str = ' '; 344 | ++str; 345 | } 346 | } 347 | c = (unsigned char) va_arg(args, int); 348 | if (str <= end) 349 | *str = c; 350 | ++str; 351 | while (--field_width > 0) { 352 | if (str <= end) 353 | *str = ' '; 354 | ++str; 355 | } 356 | continue; 357 | 358 | case 's': 359 | s = va_arg(args, char *); 360 | if ((unsigned long)s < PAGE_SIZE) 361 | s = ""; 362 | 363 | len = strnlen(s, precision); 364 | 365 | if (!(flags & LEFT)) { 366 | while (len < field_width--) { 367 | if (str <= end) 368 | *str = ' '; 369 | ++str; 370 | } 371 | } 372 | for (i = 0; i < len; ++i) { 373 | if (str <= end) 374 | *str = *s; 375 | ++str; ++s; 376 | } 377 | while (len < field_width--) { 378 | if (str <= end) 379 | *str = ' '; 380 | ++str; 381 | } 382 | continue; 383 | 384 | case 'p': 385 | if (field_width == -1) { 386 | field_width = 2*sizeof(void *); 387 | flags |= ZEROPAD; 388 | } 389 | str = number(str, end, 390 | (unsigned long) va_arg(args, void *), 391 | 16, field_width, precision, flags); 392 | continue; 393 | 394 | 395 | case 'n': 396 | /* FIXME: 397 | * What does C99 say about the overflow case here? */ 398 | if (qualifier == 'l') { 399 | long * ip = va_arg(args, long *); 400 | *ip = (str - buf); 401 | } else if (qualifier == 'Z' || qualifier == 'z') { 402 | size_t * ip = va_arg(args, size_t *); 403 | *ip = (str - buf); 404 | } else { 405 | int * ip = va_arg(args, int *); 406 | *ip = (str - buf); 407 | } 408 | continue; 409 | 410 | case '%': 411 | if (str <= end) 412 | *str = '%'; 413 | ++str; 414 | continue; 415 | 416 | /* integer number formats - set up the flags and "break" */ 417 | case 'o': 418 | base = 8; 419 | break; 420 | 421 | case 'X': 422 | flags |= LARGE; 423 | case 'x': 424 | base = 16; 425 | break; 426 | 427 | case 'd': 428 | case 'i': 429 | flags |= SIGN; 430 | case 'u': 431 | break; 432 | 433 | default: 434 | if (str <= end) 435 | *str = '%'; 436 | ++str; 437 | if (*fmt) { 438 | if (str <= end) 439 | *str = *fmt; 440 | ++str; 441 | } else { 442 | --fmt; 443 | } 444 | continue; 445 | } 446 | if (qualifier == 'L') 447 | num = va_arg(args, long long); 448 | else if (qualifier == 'l') { 449 | num = va_arg(args, unsigned long); 450 | if (flags & SIGN) 451 | num = (signed long) num; 452 | } else if (qualifier == 'Z' || qualifier == 'z') { 453 | num = va_arg(args, size_t); 454 | } else if (qualifier == 'h') { 455 | num = (unsigned short) va_arg(args, int); 456 | if (flags & SIGN) 457 | num = (signed short) num; 458 | } else { 459 | num = va_arg(args, unsigned int); 460 | if (flags & SIGN) 461 | num = (signed int) num; 462 | } 463 | str = number(str, end, num, base, 464 | field_width, precision, flags); 465 | } 466 | if (str <= end) 467 | *str = '\0'; 468 | else if (size > 0) 469 | /* don't write out a null byte if the buf size is zero */ 470 | *end = '\0'; 471 | /* the trailing null byte doesn't count towards the total 472 | * ++str; 473 | */ 474 | return str-buf; 475 | } 476 | 477 | /** 478 | * snprintf - Format a string and place it in a buffer 479 | * @buf: The buffer to place the result into 480 | * @size: The size of the buffer, including the trailing null space 481 | * @fmt: The format string to use 482 | * @...: Arguments for the format string 483 | */ 484 | int snprintf(char * buf, size_t size, const char *fmt, ...) 485 | { 486 | va_list args; 487 | int i; 488 | 489 | va_start(args, fmt); 490 | i=vsnprintf(buf,size,fmt,args); 491 | va_end(args); 492 | return i; 493 | } 494 | 495 | /** 496 | * vsprintf - Format a string and place it in a buffer 497 | * @buf: The buffer to place the result into 498 | * @fmt: The format string to use 499 | * @args: Arguments for the format string 500 | * 501 | * Call this function if you are already dealing with a va_list. 502 | * You probably want sprintf instead. 503 | */ 504 | int vsprintf(char *buf, const char *fmt, va_list args) 505 | { 506 | return vsnprintf(buf, (~0U)>>1, fmt, args); 507 | } 508 | 509 | 510 | /** 511 | * sprintf - Format a string and place it in a buffer 512 | * @buf: The buffer to place the result into 513 | * @fmt: The format string to use 514 | * @...: Arguments for the format string 515 | */ 516 | int sprintf(char * buf, const char *fmt, ...) 517 | { 518 | va_list args; 519 | int i; 520 | 521 | va_start(args, fmt); 522 | i=vsprintf(buf,fmt,args); 523 | va_end(args); 524 | return i; 525 | } 526 | 527 | /** 528 | * vsscanf - Unformat a buffer into a list of arguments 529 | * @buf: input buffer 530 | * @fmt: format of buffer 531 | * @args: arguments 532 | */ 533 | int vsscanf(const char * buf, const char * fmt, va_list args) 534 | { 535 | const char *str = buf; 536 | char *next; 537 | char digit; 538 | int num = 0; 539 | int qualifier; 540 | int base; 541 | int field_width; 542 | int is_sign = 0; 543 | 544 | while(*fmt && *str) { 545 | /* skip any white space in format */ 546 | /* white space in format matchs any amount of 547 | * white space, including none, in the input. 548 | */ 549 | if (isspace(*fmt)) { 550 | while (isspace(*fmt)) 551 | ++fmt; 552 | while (isspace(*str)) 553 | ++str; 554 | } 555 | 556 | /* anything that is not a conversion must match exactly */ 557 | if (*fmt != '%' && *fmt) { 558 | if (*fmt++ != *str++) 559 | break; 560 | continue; 561 | } 562 | 563 | if (!*fmt) 564 | break; 565 | ++fmt; 566 | 567 | /* skip this conversion. 568 | * advance both strings to next white space 569 | */ 570 | if (*fmt == '*') { 571 | while (!isspace(*fmt) && *fmt) 572 | fmt++; 573 | while (!isspace(*str) && *str) 574 | str++; 575 | continue; 576 | } 577 | 578 | /* get field width */ 579 | field_width = -1; 580 | if (isdigit(*fmt)) 581 | field_width = skip_atoi(&fmt); 582 | 583 | /* get conversion qualifier */ 584 | qualifier = -1; 585 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || 586 | *fmt == 'Z' || *fmt == 'z') { 587 | qualifier = *fmt; 588 | fmt++; 589 | } 590 | base = 10; 591 | is_sign = 0; 592 | 593 | if (!*fmt || !*str) 594 | break; 595 | 596 | switch(*fmt++) { 597 | case 'c': 598 | { 599 | char *s = (char *) va_arg(args,char*); 600 | if (field_width == -1) 601 | field_width = 1; 602 | do { 603 | *s++ = *str++; 604 | } while (--field_width > 0 && *str); 605 | num++; 606 | } 607 | continue; 608 | case 's': 609 | { 610 | char *s = (char *) va_arg(args, char *); 611 | if(field_width == -1) 612 | field_width = INT_MAX; 613 | /* first, skip leading white space in buffer */ 614 | while (isspace(*str)) 615 | str++; 616 | 617 | /* now copy until next white space */ 618 | while (*str && !isspace(*str) && field_width--) { 619 | *s++ = *str++; 620 | } 621 | *s = '\0'; 622 | num++; 623 | } 624 | continue; 625 | case 'n': 626 | /* return number of characters read so far */ 627 | { 628 | int *i = (int *)va_arg(args,int*); 629 | *i = str - buf; 630 | } 631 | continue; 632 | case 'o': 633 | base = 8; 634 | break; 635 | case 'x': 636 | case 'X': 637 | base = 16; 638 | break; 639 | case 'i': 640 | base = 0; 641 | case 'd': 642 | is_sign = 1; 643 | case 'u': 644 | break; 645 | case '%': 646 | /* looking for '%' in str */ 647 | if (*str++ != '%') 648 | return num; 649 | continue; 650 | default: 651 | /* invalid format; stop here */ 652 | return num; 653 | } 654 | 655 | /* have some sort of integer conversion. 656 | * first, skip white space in buffer. 657 | */ 658 | while (isspace(*str)) 659 | str++; 660 | 661 | digit = *str; 662 | if (is_sign && digit == '-') 663 | digit = *(str + 1); 664 | 665 | if (!digit 666 | || (base == 16 && !isxdigit(digit)) 667 | || (base == 10 && !isdigit(digit)) 668 | || (base == 8 && (!isdigit(digit) || digit > '7')) 669 | || (base == 0 && !isdigit(digit))) 670 | break; 671 | 672 | switch(qualifier) { 673 | case 'h': 674 | if (is_sign) { 675 | short *s = (short *) va_arg(args,short *); 676 | *s = (short) simple_strtol(str,&next,base); 677 | } else { 678 | unsigned short *s = (unsigned short *) va_arg(args, unsigned short *); 679 | *s = (unsigned short) simple_strtoul(str, &next, base); 680 | } 681 | break; 682 | case 'l': 683 | if (is_sign) { 684 | long *l = (long *) va_arg(args,long *); 685 | *l = simple_strtol(str,&next,base); 686 | } else { 687 | unsigned long *l = (unsigned long*) va_arg(args,unsigned long*); 688 | *l = simple_strtoul(str,&next,base); 689 | } 690 | break; 691 | case 'L': 692 | if (is_sign) { 693 | long long *l = (long long*) va_arg(args,long long *); 694 | *l = simple_strtoll(str,&next,base); 695 | } else { 696 | unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*); 697 | *l = simple_strtoull(str,&next,base); 698 | } 699 | break; 700 | case 'Z': 701 | case 'z': 702 | { 703 | size_t *s = (size_t*) va_arg(args,size_t*); 704 | *s = (size_t) simple_strtoul(str,&next,base); 705 | } 706 | break; 707 | default: 708 | if (is_sign) { 709 | int *i = (int *) va_arg(args, int*); 710 | *i = (int) simple_strtol(str,&next,base); 711 | } else { 712 | unsigned int *i = (unsigned int*) va_arg(args, unsigned int*); 713 | *i = (unsigned int) simple_strtoul(str,&next,base); 714 | } 715 | break; 716 | } 717 | num++; 718 | 719 | if (!next) 720 | break; 721 | str = next; 722 | } 723 | return num; 724 | } 725 | 726 | /** 727 | * sscanf - Unformat a buffer into a list of arguments 728 | * @buf: input buffer 729 | * @fmt: formatting of buffer 730 | * @...: resulting arguments 731 | */ 732 | int sscanf(const char * buf, const char * fmt, ...) 733 | { 734 | va_list args; 735 | int i; 736 | 737 | va_start(args,fmt); 738 | i = vsscanf(buf,fmt,args); 739 | va_end(args); 740 | return i; 741 | } 742 | -------------------------------------------------------------------------------- /inflate.c: -------------------------------------------------------------------------------- 1 | #define DEBG(x) 2 | #define DEBG1(x) 3 | /* inflate.c -- Not copyrighted 1992 by Mark Adler 4 | version c10p1, 10 January 1993 */ 5 | 6 | /* 7 | * Adapted for booting Linux by Hannu Savolainen 1993 8 | * based on gzip-1.0.3 9 | * 10 | * Nicolas Pitre , 1999/04/14 : 11 | * Little mods for all variable to reside either into rodata or bss segments 12 | * by marking constant variables with 'const' and initializing all the others 13 | * at run-time only. This allows for the kernel uncompressor to run 14 | * directly from Flash or ROM memory on embedded systems. 15 | */ 16 | 17 | /* 18 | Inflate deflated (PKZIP's method 8 compressed) data. The compression 19 | method searches for as much of the current string of bytes (up to a 20 | length of 258) in the previous 32 K bytes. If it doesn't find any 21 | matches (of at least length 3), it codes the next byte. Otherwise, it 22 | codes the length of the matched string and its distance backwards from 23 | the current position. There is a single Huffman code that codes both 24 | single bytes (called "literals") and match lengths. A second Huffman 25 | code codes the distance information, which follows a length code. Each 26 | length or distance code actually represents a base value and a number 27 | of "extra" (sometimes zero) bits to get to add to the base value. At 28 | the end of each deflated block is a special end-of-block (EOB) literal/ 29 | length code. The decoding process is basically: get a literal/length 30 | code; if EOB then done; if a literal, emit the decoded byte; if a 31 | length then get the distance and emit the referred-to bytes from the 32 | sliding window of previously emitted data. 33 | 34 | There are (currently) three kinds of inflate blocks: stored, fixed, and 35 | dynamic. The compressor deals with some chunk of data at a time, and 36 | decides which method to use on a chunk-by-chunk basis. A chunk might 37 | typically be 32 K or 64 K. If the chunk is incompressible, then the 38 | "stored" method is used. In this case, the bytes are simply stored as 39 | is, eight bits per byte, with none of the above coding. The bytes are 40 | preceded by a count, since there is no longer an EOB code. 41 | 42 | If the data is compressible, then either the fixed or dynamic methods 43 | are used. In the dynamic method, the compressed data is preceded by 44 | an encoding of the literal/length and distance Huffman codes that are 45 | to be used to decode this block. The representation is itself Huffman 46 | coded, and so is preceded by a description of that code. These code 47 | descriptions take up a little space, and so for small blocks, there is 48 | a predefined set of codes, called the fixed codes. The fixed method is 49 | used if the block codes up smaller that way (usually for quite small 50 | chunks), otherwise the dynamic method is used. In the latter case, the 51 | codes are customized to the probabilities in the current block, and so 52 | can code it much better than the pre-determined fixed codes. 53 | 54 | The Huffman codes themselves are decoded using a multi-level table 55 | lookup, in order to maximize the speed of decoding plus the speed of 56 | building the decoding tables. See the comments below that precede the 57 | lbits and dbits tuning parameters. 58 | */ 59 | 60 | 61 | /* 62 | Notes beyond the 1.93a appnote.txt: 63 | 64 | 1. Distance pointers never point before the beginning of the output 65 | stream. 66 | 2. Distance pointers can point back across blocks, up to 32k away. 67 | 3. There is an implied maximum of 7 bits for the bit length table and 68 | 15 bits for the actual data. 69 | 4. If only one code exists, then it is encoded using one bit. (Zero 70 | would be more efficient, but perhaps a little confusing.) If two 71 | codes exist, they are coded using one bit each (0 and 1). 72 | 5. There is no way of sending zero distance codes--a dummy must be 73 | sent if there are none. (History: a pre 2.0 version of PKZIP would 74 | store blocks with no distance codes, but this was discovered to be 75 | too harsh a criterion.) Valid only for 1.93a. 2.04c does allow 76 | zero distance codes, which is sent as one code of zero bits in 77 | length. 78 | 6. There are up to 286 literal/length codes. Code 256 represents the 79 | end-of-block. Note however that the static length tree defines 80 | 288 codes just to fill out the Huffman codes. Codes 286 and 287 81 | cannot be used though, since there is no length base or extra bits 82 | defined for them. Similarly, there are up to 30 distance codes. 83 | However, static trees define 32 codes (all 5 bits) to fill out the 84 | Huffman codes, but the last two had better not show up in the data. 85 | 7. Unzip can check dynamic Huffman blocks for complete code sets. 86 | The exception is that a single code would not be complete (see #4). 87 | 8. The five bits following the block type is really the number of 88 | literal codes sent minus 257. 89 | 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits 90 | (1+6+6). Therefore, to output three times the length, you output 91 | three codes (1+1+1), whereas to output four times the same length, 92 | you only need two codes (1+3). Hmm. 93 | 10. In the tree reconstruction algorithm, Code = Code + Increment 94 | only if BitLength(i) is not zero. (Pretty obvious.) 95 | 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) 96 | 12. Note: length code 284 can represent 227-258, but length code 285 97 | really is 258. The last length deserves its own, short code 98 | since it gets used a lot in very redundant files. The length 99 | 258 is special since 258 - 3 (the min match length) is 255. 100 | 13. The literal/length and distance code bit lengths are read as a 101 | single stream of lengths. It is possible (and advantageous) for 102 | a repeat code (16, 17, or 18) to go across the boundary between 103 | the two sets of lengths. 104 | */ 105 | 106 | #ifdef RCSID 107 | static char rcsid[] = "#Id: inflate.c,v 0.14 1993/06/10 13:27:04 jloup Exp #"; 108 | #endif 109 | 110 | #ifndef STATIC 111 | 112 | #if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H) 113 | # include 114 | # include 115 | #endif 116 | 117 | #include "gzip.h" 118 | #define STATIC 119 | #endif /* !STATIC */ 120 | 121 | #define slide window 122 | 123 | /* Huffman code lookup table entry--this entry is four bytes for machines 124 | that have 16-bit pointers (e.g. PC's in the small or medium model). 125 | Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 126 | means that v is a literal, 16 < e < 32 means that v is a pointer to 127 | the next table, which codes e - 16 bits, and lastly e == 99 indicates 128 | an unused code. If a code with e == 99 is looked up, this implies an 129 | error in the data. */ 130 | struct huft { 131 | uch e; /* number of extra bits or operation */ 132 | uch b; /* number of bits in this code or subcode */ 133 | union { 134 | ush n; /* literal, length base, or distance base */ 135 | struct huft *t; /* pointer to next level of table */ 136 | } v; 137 | }; 138 | 139 | 140 | /* Function prototypes */ 141 | STATIC int huft_build OF((unsigned *, unsigned, unsigned, 142 | const ush *, const ush *, struct huft **, int *)); 143 | STATIC int huft_free OF((struct huft *)); 144 | STATIC int inflate_codes OF((struct huft *, struct huft *, int, int)); 145 | STATIC int inflate_stored OF((void)); 146 | STATIC int inflate_fixed OF((void)); 147 | STATIC int inflate_dynamic OF((void)); 148 | STATIC int inflate_block OF((int *)); 149 | STATIC int inflate OF((void)); 150 | 151 | 152 | /* The inflate algorithm uses a sliding 32 K byte window on the uncompressed 153 | stream to find repeated byte strings. This is implemented here as a 154 | circular buffer. The index is updated simply by incrementing and then 155 | ANDing with 0x7fff (32K-1). */ 156 | /* It is left to other modules to supply the 32 K area. It is assumed 157 | to be usable as if it were declared "uch slide[32768];" or as just 158 | "uch *slide;" and then malloc'ed in the latter case. The definition 159 | must be in unzip.h, included above. */ 160 | /* unsigned wp; current position in slide */ 161 | #define wp outcnt 162 | #define flush_output(w) (wp=(w),flush_window()) 163 | 164 | /* Tables for deflate from PKZIP's appnote.txt. */ 165 | static const unsigned border[] = { /* Order of the bit length code lengths */ 166 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 167 | static const ush cplens[] = { /* Copy lengths for literal codes 257..285 */ 168 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 169 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; 170 | /* note: see note #13 above about the 258 in this list. */ 171 | static const ush cplext[] = { /* Extra bits for literal codes 257..285 */ 172 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 173 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ 174 | static const ush cpdist[] = { /* Copy offsets for distance codes 0..29 */ 175 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 176 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 177 | 8193, 12289, 16385, 24577}; 178 | static const ush cpdext[] = { /* Extra bits for distance codes */ 179 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 180 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 181 | 12, 12, 13, 13}; 182 | 183 | 184 | 185 | /* Macros for inflate() bit peeking and grabbing. 186 | The usage is: 187 | 188 | NEEDBITS(j) 189 | x = b & mask_bits[j]; 190 | DUMPBITS(j) 191 | 192 | where NEEDBITS makes sure that b has at least j bits in it, and 193 | DUMPBITS removes the bits from b. The macros use the variable k 194 | for the number of bits in b. Normally, b and k are register 195 | variables for speed, and are initialized at the beginning of a 196 | routine that uses these macros from a global bit buffer and count. 197 | 198 | If we assume that EOB will be the longest code, then we will never 199 | ask for bits with NEEDBITS that are beyond the end of the stream. 200 | So, NEEDBITS should not read any more bytes than are needed to 201 | meet the request. Then no bytes need to be "returned" to the buffer 202 | at the end of the last block. 203 | 204 | However, this assumption is not true for fixed blocks--the EOB code 205 | is 7 bits, but the other literal/length codes can be 8 or 9 bits. 206 | (The EOB code is shorter than other codes because fixed blocks are 207 | generally short. So, while a block always has an EOB, many other 208 | literal/length codes have a significantly lower probability of 209 | showing up at all.) However, by making the first table have a 210 | lookup of seven bits, the EOB code will be found in that first 211 | lookup, and so will not require that too many bits be pulled from 212 | the stream. 213 | */ 214 | 215 | STATIC ulg bb; /* bit buffer */ 216 | STATIC unsigned bk; /* bits in bit buffer */ 217 | 218 | STATIC const ush mask_bits[] = { 219 | 0x0000, 220 | 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 221 | 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff 222 | }; 223 | 224 | #define NEXTBYTE() (uch)get_byte() 225 | #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<>=(n);k-=(n);} 227 | 228 | 229 | /* 230 | Huffman code decoding is performed using a multi-level table lookup. 231 | The fastest way to decode is to simply build a lookup table whose 232 | size is determined by the longest code. However, the time it takes 233 | to build this table can also be a factor if the data being decoded 234 | is not very long. The most common codes are necessarily the 235 | shortest codes, so those codes dominate the decoding time, and hence 236 | the speed. The idea is you can have a shorter table that decodes the 237 | shorter, more probable codes, and then point to subsidiary tables for 238 | the longer codes. The time it costs to decode the longer codes is 239 | then traded against the time it takes to make longer tables. 240 | 241 | This results of this trade are in the variables lbits and dbits 242 | below. lbits is the number of bits the first level table for literal/ 243 | length codes can decode in one step, and dbits is the same thing for 244 | the distance codes. Subsequent tables are also less than or equal to 245 | those sizes. These values may be adjusted either when all of the 246 | codes are shorter than that, in which case the longest code length in 247 | bits is used, or when the shortest code is *longer* than the requested 248 | table size, in which case the length of the shortest code in bits is 249 | used. 250 | 251 | There are two different values for the two tables, since they code a 252 | different number of possibilities each. The literal/length table 253 | codes 286 possible values, or in a flat code, a little over eight 254 | bits. The distance table codes 30 possible values, or a little less 255 | than five bits, flat. The optimum values for speed end up being 256 | about one bit more than those, so lbits is 8+1 and dbits is 5+1. 257 | The optimum values may differ though from machine to machine, and 258 | possibly even between compilers. Your mileage may vary. 259 | */ 260 | 261 | 262 | STATIC const int lbits = 9; /* bits in base literal/length lookup table */ 263 | STATIC const int dbits = 6; /* bits in base distance lookup table */ 264 | 265 | 266 | /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ 267 | #define BMAX 16 /* maximum bit length of any code (16 for explode) */ 268 | #define N_MAX 288 /* maximum number of codes in any set */ 269 | 270 | 271 | STATIC unsigned hufts; /* track memory usage */ 272 | 273 | 274 | STATIC int huft_build(b, n, s, d, e, t, m) 275 | unsigned *b; /* code lengths in bits (all assumed <= BMAX) */ 276 | unsigned n; /* number of codes (assumed <= N_MAX) */ 277 | unsigned s; /* number of simple-valued codes (0..s-1) */ 278 | const ush *d; /* list of base values for non-simple codes */ 279 | const ush *e; /* list of extra bits for non-simple codes */ 280 | struct huft **t; /* result: starting table */ 281 | int *m; /* maximum lookup bits, returns actual */ 282 | /* Given a list of code lengths and a maximum table size, make a set of 283 | tables to decode that set of codes. Return zero on success, one if 284 | the given code set is incomplete (the tables are still built in this 285 | case), two if the input is invalid (all zero length codes or an 286 | oversubscribed set of lengths), and three if not enough memory. */ 287 | { 288 | unsigned a; /* counter for codes of length k */ 289 | unsigned c[BMAX+1]; /* bit length count table */ 290 | unsigned f; /* i repeats in table every f entries */ 291 | int g; /* maximum code length */ 292 | int h; /* table level */ 293 | register unsigned i; /* counter, current code */ 294 | register unsigned j; /* counter */ 295 | register int k; /* number of bits in current code */ 296 | int l; /* bits per table (returned in m) */ 297 | register unsigned *p; /* pointer into c[], b[], or v[] */ 298 | register struct huft *q; /* points to current table */ 299 | struct huft r; /* table entry for structure assignment */ 300 | struct huft *u[BMAX]; /* table stack */ 301 | unsigned v[N_MAX]; /* values in order of bit length */ 302 | register int w; /* bits before this table == (l * h) */ 303 | unsigned x[BMAX+1]; /* bit offsets, then code stack */ 304 | unsigned *xp; /* pointer into x */ 305 | int y; /* number of dummy codes added */ 306 | unsigned z; /* number of entries in current table */ 307 | 308 | DEBG("huft1 "); 309 | 310 | /* Generate counts for each bit length */ 311 | memzero(c, sizeof(c)); 312 | p = b; i = n; 313 | do { 314 | Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), 315 | n-i, *p)); 316 | c[*p]++; /* assume all entries <= BMAX */ 317 | p++; /* Can't combine with above line (Solaris bug) */ 318 | } while (--i); 319 | if (c[0] == n) /* null input--all zero length codes */ 320 | { 321 | *t = (struct huft *)NULL; 322 | *m = 0; 323 | return 0; 324 | } 325 | 326 | DEBG("huft2 "); 327 | 328 | /* Find minimum and maximum length, bound *m by those */ 329 | l = *m; 330 | for (j = 1; j <= BMAX; j++) 331 | if (c[j]) 332 | break; 333 | k = j; /* minimum code length */ 334 | if ((unsigned)l < j) 335 | l = j; 336 | for (i = BMAX; i; i--) 337 | if (c[i]) 338 | break; 339 | g = i; /* maximum code length */ 340 | if ((unsigned)l > i) 341 | l = i; 342 | *m = l; 343 | 344 | DEBG("huft3 "); 345 | 346 | /* Adjust last length count to fill out codes, if needed */ 347 | for (y = 1 << j; j < i; j++, y <<= 1) 348 | if ((y -= c[j]) < 0) 349 | return 2; /* bad input: more codes than bits */ 350 | if ((y -= c[i]) < 0) 351 | return 2; 352 | c[i] += y; 353 | 354 | DEBG("huft4 "); 355 | 356 | /* Generate starting offsets into the value table for each length */ 357 | x[1] = j = 0; 358 | p = c + 1; xp = x + 2; 359 | while (--i) { /* note that i == g from above */ 360 | *xp++ = (j += *p++); 361 | } 362 | 363 | DEBG("huft5 "); 364 | 365 | /* Make a table of values in order of bit lengths */ 366 | p = b; i = 0; 367 | do { 368 | if ((j = *p++) != 0) 369 | v[x[j]++] = i; 370 | } while (++i < n); 371 | 372 | DEBG("h6 "); 373 | 374 | /* Generate the Huffman codes and for each, make the table entries */ 375 | x[0] = i = 0; /* first Huffman code is zero */ 376 | p = v; /* grab values in bit order */ 377 | h = -1; /* no tables yet--level -1 */ 378 | w = -l; /* bits decoded == (l * h) */ 379 | u[0] = (struct huft *)NULL; /* just to keep compilers happy */ 380 | q = (struct huft *)NULL; /* ditto */ 381 | z = 0; /* ditto */ 382 | DEBG("h6a "); 383 | 384 | /* go through the bit lengths (k already is bits in shortest code) */ 385 | for (; k <= g; k++) 386 | { 387 | DEBG("h6b "); 388 | a = c[k]; 389 | while (a--) 390 | { 391 | DEBG("h6b1 "); 392 | /* here i is the Huffman code of length k bits for value *p */ 393 | /* make tables up to required level */ 394 | while (k > w + l) 395 | { 396 | DEBG1("1 "); 397 | h++; 398 | w += l; /* previous table always l bits */ 399 | 400 | /* compute minimum size table less than or equal to l bits */ 401 | z = (z = g - w) > (unsigned)l ? l : z; /* upper limit on table size */ 402 | if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ 403 | { /* too few codes for k-w bit table */ 404 | DEBG1("2 "); 405 | f -= a + 1; /* deduct codes from patterns left */ 406 | xp = c + k; 407 | while (++j < z) /* try smaller tables up to z bits */ 408 | { 409 | if ((f <<= 1) <= *++xp) 410 | break; /* enough codes to use up j bits */ 411 | f -= *xp; /* else deduct codes from patterns */ 412 | } 413 | } 414 | DEBG1("3 "); 415 | z = 1 << j; /* table entries for j-bit table */ 416 | 417 | /* allocate and link in new table */ 418 | if ((q = (struct huft *)malloc((z + 1)*sizeof(struct huft))) == 419 | (struct huft *)NULL) 420 | { 421 | if (h) 422 | huft_free(u[0]); 423 | return 3; /* not enough memory */ 424 | } 425 | DEBG1("4 "); 426 | hufts += z + 1; /* track memory usage */ 427 | *t = q + 1; /* link to list for huft_free() */ 428 | *(t = &(q->v.t)) = (struct huft *)NULL; 429 | u[h] = ++q; /* table starts after link */ 430 | 431 | DEBG1("5 "); 432 | /* connect to last table, if there is one */ 433 | if (h) 434 | { 435 | x[h] = i; /* save pattern for backing up */ 436 | r.b = (uch)l; /* bits to dump before this table */ 437 | r.e = (uch)(16 + j); /* bits in this table */ 438 | r.v.t = q; /* pointer to this table */ 439 | j = i >> (w - l); /* (get around Turbo C bug) */ 440 | u[h-1][j] = r; /* connect to last table */ 441 | } 442 | DEBG1("6 "); 443 | } 444 | DEBG("h6c "); 445 | 446 | /* set up table entry in r */ 447 | r.b = (uch)(k - w); 448 | if (p >= v + n) 449 | r.e = 99; /* out of values--invalid code */ 450 | else if (*p < s) 451 | { 452 | r.e = (uch)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ 453 | r.v.n = (ush)(*p); /* simple code is just the value */ 454 | p++; /* one compiler does not like *p++ */ 455 | } 456 | else 457 | { 458 | r.e = (uch)e[*p - s]; /* non-simple--look up in lists */ 459 | r.v.n = d[*p++ - s]; 460 | } 461 | DEBG("h6d "); 462 | 463 | /* fill code-like entries with r */ 464 | f = 1 << (k - w); 465 | for (j = i >> w; j < z; j += f) 466 | q[j] = r; 467 | 468 | /* backwards increment the k-bit code i */ 469 | for (j = 1 << (k - 1); i & j; j >>= 1) 470 | i ^= j; 471 | i ^= j; 472 | 473 | /* backup over finished tables */ 474 | while ((i & ((1 << w) - 1)) != x[h]) 475 | { 476 | h--; /* don't need to update q */ 477 | w -= l; 478 | } 479 | DEBG("h6e "); 480 | } 481 | DEBG("h6f "); 482 | } 483 | 484 | DEBG("huft7 "); 485 | 486 | /* Return true (1) if we were given an incomplete table */ 487 | return y != 0 && g != 1; 488 | } 489 | 490 | 491 | 492 | STATIC int huft_free(t) 493 | struct huft *t; /* table to free */ 494 | /* Free the malloc'ed tables built by huft_build(), which makes a linked 495 | list of the tables it made, with the links in a dummy first entry of 496 | each table. */ 497 | { 498 | register struct huft *p, *q; 499 | 500 | 501 | /* Go through linked list, freeing from the malloced (t[-1]) address. */ 502 | p = t; 503 | while (p != (struct huft *)NULL) 504 | { 505 | q = (--p)->v.t; 506 | free((char*)p); 507 | p = q; 508 | } 509 | return 0; 510 | } 511 | 512 | 513 | STATIC int inflate_codes(tl, td, bl, bd) 514 | struct huft *tl, *td; /* literal/length and distance decoder tables */ 515 | int bl, bd; /* number of bits decoded by tl[] and td[] */ 516 | /* inflate (decompress) the codes in a deflated (compressed) block. 517 | Return an error code or zero if it all goes ok. */ 518 | { 519 | register unsigned e; /* table entry flag/number of extra bits */ 520 | unsigned n, d; /* length and index for copy */ 521 | unsigned w; /* current window position */ 522 | struct huft *t; /* pointer to table entry */ 523 | unsigned ml, md; /* masks for bl and bd bits */ 524 | register ulg b; /* bit buffer */ 525 | register unsigned k; /* number of bits in bit buffer */ 526 | 527 | 528 | /* make local copies of globals */ 529 | b = bb; /* initialize bit buffer */ 530 | k = bk; 531 | w = wp; /* initialize window position */ 532 | 533 | /* inflate the coded data */ 534 | ml = mask_bits[bl]; /* precompute masks for speed */ 535 | md = mask_bits[bd]; 536 | for (;;) /* do until end of block */ 537 | { 538 | NEEDBITS((unsigned)bl) 539 | if ((e = (t = tl + ((unsigned)b & ml))->e) > 16) 540 | do { 541 | if (e == 99) 542 | return 1; 543 | DUMPBITS(t->b) 544 | e -= 16; 545 | NEEDBITS(e) 546 | } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); 547 | DUMPBITS(t->b) 548 | if (e == 16) /* then it's a literal */ 549 | { 550 | slide[w++] = (uch)t->v.n; 551 | Tracevv((stderr, "%c", slide[w-1])); 552 | if (w == WSIZE) 553 | { 554 | flush_output(w); 555 | w = 0; 556 | } 557 | } 558 | else /* it's an EOB or a length */ 559 | { 560 | /* exit if end of block */ 561 | if (e == 15) 562 | break; 563 | 564 | /* get length of block to copy */ 565 | NEEDBITS(e) 566 | n = t->v.n + ((unsigned)b & mask_bits[e]); 567 | DUMPBITS(e); 568 | 569 | /* decode distance of block to copy */ 570 | NEEDBITS((unsigned)bd) 571 | if ((e = (t = td + ((unsigned)b & md))->e) > 16) 572 | do { 573 | if (e == 99) 574 | return 1; 575 | DUMPBITS(t->b) 576 | e -= 16; 577 | NEEDBITS(e) 578 | } while ((e = (t = t->v.t + ((unsigned)b & mask_bits[e]))->e) > 16); 579 | DUMPBITS(t->b) 580 | NEEDBITS(e) 581 | d = w - t->v.n - ((unsigned)b & mask_bits[e]); 582 | DUMPBITS(e) 583 | Tracevv((stderr,"\\[%d,%d]", w-d, n)); 584 | 585 | /* do the copy */ 586 | do { 587 | n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); 588 | #if !defined(NOMEMCPY) && !defined(DEBUG) 589 | if (w - d >= e) /* (this test assumes unsigned comparison) */ 590 | { 591 | memcpy(slide + w, slide + d, e); 592 | w += e; 593 | d += e; 594 | } 595 | else /* do it slow to avoid memcpy() overlap */ 596 | #endif /* !NOMEMCPY */ 597 | do { 598 | slide[w++] = slide[d++]; 599 | Tracevv((stderr, "%c", slide[w-1])); 600 | } while (--e); 601 | if (w == WSIZE) 602 | { 603 | flush_output(w); 604 | w = 0; 605 | } 606 | } while (n); 607 | } 608 | } 609 | 610 | 611 | /* restore the globals from the locals */ 612 | wp = w; /* restore global window pointer */ 613 | bb = b; /* restore global bit buffer */ 614 | bk = k; 615 | 616 | /* done */ 617 | return 0; 618 | } 619 | 620 | 621 | 622 | STATIC int inflate_stored() 623 | /* "decompress" an inflated type 0 (stored) block. */ 624 | { 625 | unsigned n; /* number of bytes in block */ 626 | unsigned w; /* current window position */ 627 | register ulg b; /* bit buffer */ 628 | register unsigned k; /* number of bits in bit buffer */ 629 | 630 | DEBG(""); 673 | return 0; 674 | } 675 | 676 | 677 | 678 | STATIC int inflate_fixed() 679 | /* decompress an inflated type 1 (fixed Huffman codes) block. We should 680 | either replace this with a custom decoder, or at least precompute the 681 | Huffman tables. */ 682 | { 683 | int i; /* temporary variable */ 684 | struct huft *tl; /* literal/length code table */ 685 | struct huft *td; /* distance code table */ 686 | int bl; /* lookup bits for tl */ 687 | int bd; /* lookup bits for td */ 688 | unsigned l[288]; /* length list for huft_build */ 689 | 690 | DEBG(" 1) 711 | { 712 | huft_free(tl); 713 | 714 | DEBG(">"); 715 | return i; 716 | } 717 | 718 | 719 | /* decompress until an end-of-block code */ 720 | if (inflate_codes(tl, td, bl, bd)) 721 | return 1; 722 | 723 | 724 | /* free the decoding tables, return */ 725 | huft_free(tl); 726 | huft_free(td); 727 | return 0; 728 | } 729 | 730 | 731 | 732 | STATIC int inflate_dynamic() 733 | /* decompress an inflated type 2 (dynamic Huffman codes) block. */ 734 | { 735 | int i; /* temporary variables */ 736 | unsigned j; 737 | unsigned l; /* last length */ 738 | unsigned m; /* mask for bit lengths table */ 739 | unsigned n; /* number of lengths to get */ 740 | struct huft *tl; /* literal/length code table */ 741 | struct huft *td; /* distance code table */ 742 | int bl; /* lookup bits for tl */ 743 | int bd; /* lookup bits for td */ 744 | unsigned nb; /* number of bit length codes */ 745 | unsigned nl; /* number of literal/length codes */ 746 | unsigned nd; /* number of distance codes */ 747 | #ifdef PKZIP_BUG_WORKAROUND 748 | unsigned ll[288+32]; /* literal/length and distance code lengths */ 749 | #else 750 | unsigned ll[286+30]; /* literal/length and distance code lengths */ 751 | #endif 752 | register ulg b; /* bit buffer */ 753 | register unsigned k; /* number of bits in bit buffer */ 754 | 755 | DEBG(" 288 || nd > 32) 774 | #else 775 | if (nl > 286 || nd > 30) 776 | #endif 777 | return 1; /* bad lengths */ 778 | 779 | DEBG("dyn1 "); 780 | 781 | /* read in bit-length-code lengths */ 782 | for (j = 0; j < nb; j++) 783 | { 784 | NEEDBITS(3) 785 | ll[border[j]] = (unsigned)b & 7; 786 | DUMPBITS(3) 787 | } 788 | for (; j < 19; j++) 789 | ll[border[j]] = 0; 790 | 791 | DEBG("dyn2 "); 792 | 793 | /* build decoding table for trees--single level, 7 bit lookup */ 794 | bl = 7; 795 | if ((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) 796 | { 797 | if (i == 1) 798 | huft_free(tl); 799 | return i; /* incomplete code set */ 800 | } 801 | 802 | DEBG("dyn3 "); 803 | 804 | /* read in literal and distance code lengths */ 805 | n = nl + nd; 806 | m = mask_bits[bl]; 807 | i = l = 0; 808 | while ((unsigned)i < n) 809 | { 810 | NEEDBITS((unsigned)bl) 811 | j = (td = tl + ((unsigned)b & m))->b; 812 | DUMPBITS(j) 813 | j = td->v.n; 814 | if (j < 16) /* length of code in bits (0..15) */ 815 | ll[i++] = l = j; /* save last length in l */ 816 | else if (j == 16) /* repeat last length 3 to 6 times */ 817 | { 818 | NEEDBITS(2) 819 | j = 3 + ((unsigned)b & 3); 820 | DUMPBITS(2) 821 | if ((unsigned)i + j > n) 822 | return 1; 823 | while (j--) 824 | ll[i++] = l; 825 | } 826 | else if (j == 17) /* 3 to 10 zero length codes */ 827 | { 828 | NEEDBITS(3) 829 | j = 3 + ((unsigned)b & 7); 830 | DUMPBITS(3) 831 | if ((unsigned)i + j > n) 832 | return 1; 833 | while (j--) 834 | ll[i++] = 0; 835 | l = 0; 836 | } 837 | else /* j == 18: 11 to 138 zero length codes */ 838 | { 839 | NEEDBITS(7) 840 | j = 11 + ((unsigned)b & 0x7f); 841 | DUMPBITS(7) 842 | if ((unsigned)i + j > n) 843 | return 1; 844 | while (j--) 845 | ll[i++] = 0; 846 | l = 0; 847 | } 848 | } 849 | 850 | DEBG("dyn4 "); 851 | 852 | /* free decoding table for trees */ 853 | huft_free(tl); 854 | 855 | DEBG("dyn5 "); 856 | 857 | /* restore the global bit buffer */ 858 | bb = b; 859 | bk = k; 860 | 861 | DEBG("dyn5a "); 862 | 863 | /* build the decoding tables for literal/length and distance codes */ 864 | bl = lbits; 865 | if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) 866 | { 867 | DEBG("dyn5b "); 868 | if (i == 1) { 869 | error(" incomplete literal tree\n"); 870 | huft_free(tl); 871 | } 872 | return i; /* incomplete code set */ 873 | } 874 | DEBG("dyn5c "); 875 | bd = dbits; 876 | if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) 877 | { 878 | DEBG("dyn5d "); 879 | if (i == 1) { 880 | error(" incomplete distance tree\n"); 881 | #ifdef PKZIP_BUG_WORKAROUND 882 | i = 0; 883 | } 884 | #else 885 | huft_free(td); 886 | } 887 | huft_free(tl); 888 | return i; /* incomplete code set */ 889 | #endif 890 | } 891 | 892 | DEBG("dyn6 "); 893 | 894 | /* decompress until an end-of-block code */ 895 | if (inflate_codes(tl, td, bl, bd)) 896 | return 1; 897 | 898 | DEBG("dyn7 "); 899 | 900 | /* free the decoding tables, return */ 901 | huft_free(tl); 902 | huft_free(td); 903 | 904 | DEBG(">"); 905 | return 0; 906 | } 907 | 908 | 909 | 910 | STATIC int inflate_block(e) 911 | int *e; /* last block flag */ 912 | /* decompress an inflated block */ 913 | { 914 | unsigned t; /* block type */ 915 | register ulg b; /* bit buffer */ 916 | register unsigned k; /* number of bits in bit buffer */ 917 | 918 | DEBG(""); 950 | 951 | /* bad block type */ 952 | return 2; 953 | } 954 | 955 | 956 | 957 | STATIC int inflate() 958 | /* decompress an inflated entry */ 959 | { 960 | int e; /* last block flag */ 961 | int r; /* result code */ 962 | unsigned h; /* maximum struct huft's malloc'ed */ 963 | void *ptr; 964 | 965 | /* initialize window, bit buffer */ 966 | wp = 0; 967 | bk = 0; 968 | bb = 0; 969 | 970 | 971 | /* decompress until the last block */ 972 | h = 0; 973 | do { 974 | hufts = 0; 975 | gzip_mark(&ptr); 976 | if ((r = inflate_block(&e)) != 0) { 977 | gzip_release(&ptr); 978 | return r; 979 | } 980 | gzip_release(&ptr); 981 | if (hufts > h) 982 | h = hufts; 983 | } while (!e); 984 | 985 | /* Undo too much lookahead. The next read will be byte aligned so we 986 | * can discard unused bits in the last meaningful byte. 987 | */ 988 | while (bk >= 8) { 989 | bk -= 8; 990 | inptr--; 991 | } 992 | 993 | /* flush out slide */ 994 | flush_output(wp); 995 | 996 | 997 | /* return success */ 998 | #ifdef DEBUG 999 | fprintf(stderr, "<%u> ", h); 1000 | #endif /* DEBUG */ 1001 | return 0; 1002 | } 1003 | 1004 | #if 0 1005 | /********************************************************************** 1006 | * 1007 | * The following are support routines for inflate.c 1008 | * 1009 | **********************************************************************/ 1010 | 1011 | static ulg crc_32_tab[256]; 1012 | static ulg crc; /* initialized in makecrc() so it'll reside in bss */ 1013 | #define CRC_VALUE (crc ^ 0xffffffffUL) 1014 | 1015 | /* 1016 | * Code to compute the CRC-32 table. Borrowed from 1017 | * gzip-1.0.3/makecrc.c. 1018 | */ 1019 | 1020 | static void 1021 | makecrc(void) 1022 | { 1023 | /* Not copyrighted 1990 Mark Adler */ 1024 | 1025 | unsigned long c; /* crc shift register */ 1026 | unsigned long e; /* polynomial exclusive-or pattern */ 1027 | int i; /* counter for all possible eight bit values */ 1028 | int k; /* byte being shifted into crc apparatus */ 1029 | 1030 | /* terms of polynomial defining this crc (except x^32): */ 1031 | static const int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; 1032 | 1033 | /* Make exclusive-or pattern from polynomial */ 1034 | e = 0; 1035 | for (i = 0; i < sizeof(p)/sizeof(int); i++) 1036 | e |= 1L << (31 - p[i]); 1037 | 1038 | crc_32_tab[0] = 0; 1039 | 1040 | for (i = 1; i < 256; i++) 1041 | { 1042 | c = 0; 1043 | for (k = i | 256; k != 1; k >>= 1) 1044 | { 1045 | c = c & 1 ? (c >> 1) ^ e : c >> 1; 1046 | if (k & 1) 1047 | c ^= e; 1048 | } 1049 | crc_32_tab[i] = c; 1050 | } 1051 | 1052 | /* this is initialized here so this code could reside in ROM */ 1053 | crc = (ulg)0xffffffffUL; /* shift register contents */ 1054 | } 1055 | #endif 1056 | 1057 | /* gzip flag byte */ 1058 | #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ 1059 | #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ 1060 | #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ 1061 | #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ 1062 | #define COMMENT 0x10 /* bit 4 set: file comment present */ 1063 | #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ 1064 | #define RESERVED 0xC0 /* bit 6,7: reserved */ 1065 | 1066 | /* 1067 | * Do the uncompression! 1068 | */ 1069 | static int gunzip(void) 1070 | { 1071 | uch flags; 1072 | unsigned char magic[2]; /* magic header */ 1073 | char method; 1074 | ulg orig_crc = 0; /* original crc */ 1075 | ulg orig_len = 0; /* original uncompressed length */ 1076 | int res; 1077 | 1078 | magic[0] = (unsigned char)get_byte(); 1079 | magic[1] = (unsigned char)get_byte(); 1080 | method = (unsigned char)get_byte(); 1081 | 1082 | if (magic[0] != 037 || 1083 | ((magic[1] != 0213) && (magic[1] != 0236))) { 1084 | error("bad gzip magic numbers"); 1085 | return -1; 1086 | } 1087 | 1088 | /* We only support method #8, DEFLATED */ 1089 | if (method != 8) { 1090 | error("internal error, invalid method"); 1091 | return -1; 1092 | } 1093 | 1094 | flags = (uch)get_byte(); 1095 | if ((flags & ENCRYPTED) != 0) { 1096 | error("Input is encrypted\n"); 1097 | return -1; 1098 | } 1099 | if ((flags & CONTINUATION) != 0) { 1100 | error("Multi part input\n"); 1101 | return -1; 1102 | } 1103 | if ((flags & RESERVED) != 0) { 1104 | error("Input has invalid flags\n"); 1105 | return -1; 1106 | } 1107 | (ulg)get_byte(); /* Get timestamp */ 1108 | ((ulg)get_byte()) << 8; 1109 | ((ulg)get_byte()) << 16; 1110 | ((ulg)get_byte()) << 24; 1111 | 1112 | (void)get_byte(); /* Ignore extra flags for the moment */ 1113 | (void)get_byte(); /* Ignore OS type for the moment */ 1114 | 1115 | if ((flags & EXTRA_FIELD) != 0) { 1116 | unsigned len = (unsigned)get_byte(); 1117 | len |= ((unsigned)get_byte())<<8; 1118 | while (len--) (void)get_byte(); 1119 | } 1120 | 1121 | /* Get original file name if it was truncated */ 1122 | if ((flags & ORIG_NAME) != 0) { 1123 | /* Discard the old name */ 1124 | while (get_byte() != 0) /* null */ ; 1125 | } 1126 | 1127 | /* Discard file comment if any */ 1128 | if ((flags & COMMENT) != 0) { 1129 | while (get_byte() != 0) /* null */ ; 1130 | } 1131 | 1132 | /* Decompress */ 1133 | if ((res = inflate())) { 1134 | switch (res) { 1135 | case 0: 1136 | break; 1137 | case 1: 1138 | error("invalid compressed format (err=1)"); 1139 | break; 1140 | case 2: 1141 | error("invalid compressed format (err=2)"); 1142 | break; 1143 | case 3: 1144 | error("out of memory"); 1145 | break; 1146 | default: 1147 | error("invalid compressed format (other)"); 1148 | } 1149 | return -1; 1150 | } 1151 | 1152 | /* Get the crc and original length */ 1153 | /* crc32 (see algorithm.doc) 1154 | * uncompressed input size modulo 2^32 1155 | */ 1156 | orig_crc = (ulg) get_byte(); 1157 | orig_crc |= (ulg) get_byte() << 8; 1158 | orig_crc |= (ulg) get_byte() << 16; 1159 | orig_crc |= (ulg) get_byte() << 24; 1160 | 1161 | orig_len = (ulg) get_byte(); 1162 | orig_len |= (ulg) get_byte() << 8; 1163 | orig_len |= (ulg) get_byte() << 16; 1164 | orig_len |= (ulg) get_byte() << 24; 1165 | 1166 | #if 0 1167 | /* Validate decompression */ 1168 | if (orig_crc != CRC_VALUE) { 1169 | error("crc error"); 1170 | return -1; 1171 | } 1172 | #endif 1173 | if (orig_len != bytes_out) { 1174 | error("length error"); 1175 | return -1; 1176 | } 1177 | return 0; 1178 | } 1179 | 1180 | 1181 | -------------------------------------------------------------------------------- /dtoa.c: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | * 3 | * The author of this software is David M. Gay. 4 | * 5 | * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. 6 | * 7 | * Permission to use, copy, modify, and distribute this software for any 8 | * purpose without fee is hereby granted, provided that this entire notice 9 | * is included in all copies of any software which is or includes a copy 10 | * or modification of this software and in all copies of the supporting 11 | * documentation for such software. 12 | * 13 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 14 | * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY 15 | * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY 16 | * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 17 | * 18 | ***************************************************************/ 19 | 20 | /* Please send bug reports to David M. Gay (dmg at acm dot org, 21 | * with " at " changed at "@" and " dot " changed to "."). */ 22 | 23 | /* On a machine with IEEE extended-precision registers, it is 24 | * necessary to specify double-precision (53-bit) rounding precision 25 | * before invoking strtod or dtoa. If the machine uses (the equivalent 26 | * of) Intel 80x87 arithmetic, the call 27 | * _control87(PC_53, MCW_PC); 28 | * does this with many compilers. Whether this or another call is 29 | * appropriate depends on the compiler; for this to work, it may be 30 | * necessary to #include "float.h" or another system-dependent header 31 | * file. 32 | */ 33 | 34 | /* strtod for IEEE-, VAX-, and IBM-arithmetic machines. 35 | * 36 | * This strtod returns a nearest machine number to the input decimal 37 | * string (or sets errno to ERANGE). With IEEE arithmetic, ties are 38 | * broken by the IEEE round-even rule. Otherwise ties are broken by 39 | * biased rounding (add half and chop). 40 | * 41 | * Inspired loosely by William D. Clinger's paper "How to Read Floating 42 | * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. 43 | * 44 | * Modifications: 45 | * 46 | * 1. We only require IEEE, IBM, or VAX double-precision 47 | * arithmetic (not IEEE double-extended). 48 | * 2. We get by with floating-point arithmetic in a case that 49 | * Clinger missed -- when we're computing d * 10^n 50 | * for a small integer d and the integer n is not too 51 | * much larger than 22 (the maximum integer k for which 52 | * we can represent 10^k exactly), we may be able to 53 | * compute (d*10^k) * 10^(e-k) with just one roundoff. 54 | * 3. Rather than a bit-at-a-time adjustment of the binary 55 | * result in the hard case, we use floating-point 56 | * arithmetic to determine the adjustment to within 57 | * one bit; only in really hard cases do we need to 58 | * compute a second residual. 59 | * 4. Because of 3., we don't need a large table of powers of 10 60 | * for ten-to-e (just some small tables, e.g. of 10^k 61 | * for 0 <= k <= 22). 62 | */ 63 | 64 | /* 65 | * #define IEEE_8087 for IEEE-arithmetic machines where the least 66 | * significant byte has the lowest address. 67 | * #define IEEE_MC68k for IEEE-arithmetic machines where the most 68 | * significant byte has the lowest address. 69 | * #define Long int on machines with 32-bit ints and 64-bit longs. 70 | * #define IBM for IBM mainframe-style floating-point arithmetic. 71 | * #define VAX for VAX-style floating-point arithmetic (D_floating). 72 | * #define No_leftright to omit left-right logic in fast floating-point 73 | * computation of dtoa. 74 | * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 75 | * and strtod and dtoa should round accordingly. 76 | * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 77 | * and Honor_FLT_ROUNDS is not #defined. 78 | * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines 79 | * that use extended-precision instructions to compute rounded 80 | * products and quotients) with IBM. 81 | * #define ROUND_BIASED for IEEE-format with biased rounding. 82 | * #define Inaccurate_Divide for IEEE-format with correctly rounded 83 | * products but inaccurate quotients, e.g., for Intel i860. 84 | * #define NO_LONG_LONG on machines that do not have a "long long" 85 | * integer type (of >= 64 bits). On such machines, you can 86 | * #define Just_16 to store 16 bits per 32-bit Long when doing 87 | * high-precision integer arithmetic. Whether this speeds things 88 | * up or slows things down depends on the machine and the number 89 | * being converted. If long long is available and the name is 90 | * something other than "long long", #define Llong to be the name, 91 | * and if "unsigned Llong" does not work as an unsigned version of 92 | * Llong, #define #ULLong to be the corresponding unsigned type. 93 | * #define KR_headers for old-style C function headers. 94 | * #define Bad_float_h if your system lacks a float.h or if it does not 95 | * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, 96 | * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. 97 | * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) 98 | * if memory is available and otherwise does something you deem 99 | * appropriate. If MALLOC is undefined, malloc will be invoked 100 | * directly -- and assumed always to succeed. 101 | * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making 102 | * memory allocations from a private pool of memory when possible. 103 | * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, 104 | * unless #defined to be a different length. This default length 105 | * suffices to get rid of MALLOC calls except for unusual cases, 106 | * such as decimal-to-binary conversion of a very long string of 107 | * digits. The longest string dtoa can return is about 751 bytes 108 | * long. For conversions by strtod of strings of 800 digits and 109 | * all dtoa conversions in single-threaded executions with 8-byte 110 | * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte 111 | * pointers, PRIVATE_MEM >= 7112 appears adequate. 112 | * #define INFNAN_CHECK on IEEE systems to cause strtod to check for 113 | * Infinity and NaN (case insensitively). On some systems (e.g., 114 | * some HP systems), it may be necessary to #define NAN_WORD0 115 | * appropriately -- to the most significant word of a quiet NaN. 116 | * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) 117 | * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, 118 | * strtod also accepts (case insensitively) strings of the form 119 | * NaN(x), where x is a string of hexadecimal digits and spaces; 120 | * if there is only one string of hexadecimal digits, it is taken 121 | * for the 52 fraction bits of the resulting NaN; if there are two 122 | * or more strings of hex digits, the first is for the high 20 bits, 123 | * the second and subsequent for the low 32 bits, with intervening 124 | * white space ignored; but if this results in none of the 52 125 | * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 126 | * and NAN_WORD1 are used instead. 127 | * #define MULTIPLE_THREADS if the system offers preemptively scheduled 128 | * multiple threads. In this case, you must provide (or suitably 129 | * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed 130 | * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed 131 | * in pow5mult, ensures lazy evaluation of only one copy of high 132 | * powers of 5; omitting this lock would introduce a small 133 | * probability of wasting memory, but would otherwise be harmless.) 134 | * You must also invoke freedtoa(s) to free the value s returned by 135 | * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. 136 | * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that 137 | * avoids underflows on inputs whose result does not underflow. 138 | * If you #define NO_IEEE_Scale on a machine that uses IEEE-format 139 | * floating-point numbers and flushes underflows to zero rather 140 | * than implementing gradual underflow, then you must also #define 141 | * Sudden_Underflow. 142 | * #define YES_ALIAS to permit aliasing certain double values with 143 | * arrays of ULongs. This leads to slightly better code with 144 | * some compilers and was always used prior to 19990916, but it 145 | * is not strictly legal and can cause trouble with aggressively 146 | * optimizing compilers (e.g., gcc 2.95.1 under -O2). 147 | * #define USE_LOCALE to use the current locale's decimal_point value. 148 | * #define SET_INEXACT if IEEE arithmetic is being used and extra 149 | * computation should be done to set the inexact flag when the 150 | * result is inexact and avoid setting inexact when the result 151 | * is exact. In this case, dtoa.c must be compiled in 152 | * an environment, perhaps provided by #include "dtoa.c" in a 153 | * suitable wrapper, that defines two functions, 154 | * int get_inexact(void); 155 | * void clear_inexact(void); 156 | * such that get_inexact() returns a nonzero value if the 157 | * inexact bit is already set, and clear_inexact() sets the 158 | * inexact bit to 0. When SET_INEXACT is #defined, strtod 159 | * also does extra computations to set the underflow and overflow 160 | * flags when appropriate (i.e., when the result is tiny and 161 | * inexact or when it is a numeric value rounded to +-infinity). 162 | * #define NO_ERRNO if strtod should not assign errno = ERANGE when 163 | * the result overflows to +-Infinity or underflows to 0. 164 | */ 165 | 166 | #define IEEE_8087 167 | #define INFNAN_CHECK 168 | #define FLT_ROUNDS_IS_CONSTANT 169 | #define MODE_0_ONLY 170 | 171 | #ifndef Long 172 | #define Long long 173 | #endif 174 | #ifndef ULong 175 | typedef unsigned Long ULong; 176 | #endif 177 | 178 | #ifdef DEBUG 179 | #include "stdio.h" 180 | #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} 181 | #endif 182 | 183 | #include "tccboot.h" 184 | 185 | #ifdef USE_LOCALE 186 | #include "locale.h" 187 | #endif 188 | 189 | #ifdef MALLOC 190 | #ifdef KR_headers 191 | extern char *MALLOC(); 192 | #else 193 | extern void *MALLOC(size_t); 194 | #endif 195 | #else 196 | #define MALLOC malloc 197 | #endif 198 | 199 | #ifndef Omit_Private_Memory 200 | #ifndef PRIVATE_MEM 201 | #define PRIVATE_MEM 2304 202 | #endif 203 | #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) 204 | static double private_mem[PRIVATE_mem], *pmem_next = private_mem; 205 | #endif 206 | 207 | #undef IEEE_Arith 208 | #undef Avoid_Underflow 209 | #ifdef IEEE_MC68k 210 | #define IEEE_Arith 211 | #endif 212 | #ifdef IEEE_8087 213 | #define IEEE_Arith 214 | #endif 215 | 216 | #ifdef Bad_float_h 217 | 218 | #ifdef IEEE_Arith 219 | #define DBL_DIG 15 220 | #define DBL_MAX_10_EXP 308 221 | #define DBL_MAX_EXP 1024 222 | #define FLT_RADIX 2 223 | #endif /*IEEE_Arith*/ 224 | 225 | #ifdef IBM 226 | #define DBL_DIG 16 227 | #define DBL_MAX_10_EXP 75 228 | #define DBL_MAX_EXP 63 229 | #define FLT_RADIX 16 230 | #define DBL_MAX 7.2370055773322621e+75 231 | #endif 232 | 233 | #ifdef VAX 234 | #define DBL_DIG 16 235 | #define DBL_MAX_10_EXP 38 236 | #define DBL_MAX_EXP 127 237 | #define FLT_RADIX 2 238 | #define DBL_MAX 1.7014118346046923e+38 239 | #endif 240 | 241 | #ifndef LONG_MAX 242 | #define LONG_MAX 2147483647 243 | #endif 244 | 245 | #else /* ifndef Bad_float_h */ 246 | #include "float.h" 247 | #endif /* Bad_float_h */ 248 | 249 | #ifdef __cplusplus 250 | extern "C" { 251 | #endif 252 | 253 | #ifndef CONST 254 | #ifdef KR_headers 255 | #define CONST /* blank */ 256 | #else 257 | #define CONST const 258 | #endif 259 | #endif 260 | 261 | #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 262 | Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. 263 | #endif 264 | 265 | typedef union { double d; ULong L[2]; } U; 266 | 267 | #ifdef YES_ALIAS 268 | #define dval(x) x 269 | #ifdef IEEE_8087 270 | #define word0(x) ((ULong *)&x)[1] 271 | #define word1(x) ((ULong *)&x)[0] 272 | #else 273 | #define word0(x) ((ULong *)&x)[0] 274 | #define word1(x) ((ULong *)&x)[1] 275 | #endif 276 | #else 277 | #ifdef IEEE_8087 278 | #define word0(x) ((U*)&x)->L[1] 279 | #define word1(x) ((U*)&x)->L[0] 280 | #else 281 | #define word0(x) ((U*)&x)->L[0] 282 | #define word1(x) ((U*)&x)->L[1] 283 | #endif 284 | #define dval(x) ((U*)&x)->d 285 | #endif 286 | 287 | /* The following definition of Storeinc is appropriate for MIPS processors. 288 | * An alternative that might be better on some machines is 289 | * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) 290 | */ 291 | #if defined(IEEE_8087) + defined(VAX) 292 | #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ 293 | ((unsigned short *)a)[0] = (unsigned short)c, a++) 294 | #else 295 | #define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ 296 | ((unsigned short *)a)[1] = (unsigned short)c, a++) 297 | #endif 298 | 299 | /* #define P DBL_MANT_DIG */ 300 | /* Ten_pmax = floor(P*log(2)/log(5)) */ 301 | /* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ 302 | /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ 303 | /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ 304 | 305 | #ifdef IEEE_Arith 306 | #define Exp_shift 20 307 | #define Exp_shift1 20 308 | #define Exp_msk1 0x100000 309 | #define Exp_msk11 0x100000 310 | #define Exp_mask 0x7ff00000 311 | #define P 53 312 | #define Bias 1023 313 | #define Emin (-1022) 314 | #define Exp_1 0x3ff00000 315 | #define Exp_11 0x3ff00000 316 | #define Ebits 11 317 | #define Frac_mask 0xfffff 318 | #define Frac_mask1 0xfffff 319 | #define Ten_pmax 22 320 | #define Bletch 0x10 321 | #define Bndry_mask 0xfffff 322 | #define Bndry_mask1 0xfffff 323 | #define LSB 1 324 | #define Sign_bit 0x80000000 325 | #define Log2P 1 326 | #define Tiny0 0 327 | #define Tiny1 1 328 | #define Quick_max 14 329 | #define Int_max 14 330 | #ifndef NO_IEEE_Scale 331 | #define Avoid_Underflow 332 | #ifdef Flush_Denorm /* debugging option */ 333 | #undef Sudden_Underflow 334 | #endif 335 | #endif 336 | 337 | #ifndef Flt_Rounds 338 | #ifdef FLT_ROUNDS 339 | #define Flt_Rounds FLT_ROUNDS 340 | #else 341 | #define Flt_Rounds 1 342 | #endif 343 | #endif /*Flt_Rounds*/ 344 | 345 | #ifdef Honor_FLT_ROUNDS 346 | #define Rounding rounding 347 | #undef Check_FLT_ROUNDS 348 | #define Check_FLT_ROUNDS 349 | #else 350 | #define Rounding Flt_Rounds 351 | #endif 352 | 353 | #else /* ifndef IEEE_Arith */ 354 | #undef Check_FLT_ROUNDS 355 | #undef Honor_FLT_ROUNDS 356 | #undef SET_INEXACT 357 | #undef Sudden_Underflow 358 | #define Sudden_Underflow 359 | #ifdef IBM 360 | #undef Flt_Rounds 361 | #define Flt_Rounds 0 362 | #define Exp_shift 24 363 | #define Exp_shift1 24 364 | #define Exp_msk1 0x1000000 365 | #define Exp_msk11 0x1000000 366 | #define Exp_mask 0x7f000000 367 | #define P 14 368 | #define Bias 65 369 | #define Exp_1 0x41000000 370 | #define Exp_11 0x41000000 371 | #define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ 372 | #define Frac_mask 0xffffff 373 | #define Frac_mask1 0xffffff 374 | #define Bletch 4 375 | #define Ten_pmax 22 376 | #define Bndry_mask 0xefffff 377 | #define Bndry_mask1 0xffffff 378 | #define LSB 1 379 | #define Sign_bit 0x80000000 380 | #define Log2P 4 381 | #define Tiny0 0x100000 382 | #define Tiny1 0 383 | #define Quick_max 14 384 | #define Int_max 15 385 | #else /* VAX */ 386 | #undef Flt_Rounds 387 | #define Flt_Rounds 1 388 | #define Exp_shift 23 389 | #define Exp_shift1 7 390 | #define Exp_msk1 0x80 391 | #define Exp_msk11 0x800000 392 | #define Exp_mask 0x7f80 393 | #define P 56 394 | #define Bias 129 395 | #define Exp_1 0x40800000 396 | #define Exp_11 0x4080 397 | #define Ebits 8 398 | #define Frac_mask 0x7fffff 399 | #define Frac_mask1 0xffff007f 400 | #define Ten_pmax 24 401 | #define Bletch 2 402 | #define Bndry_mask 0xffff007f 403 | #define Bndry_mask1 0xffff007f 404 | #define LSB 0x10000 405 | #define Sign_bit 0x8000 406 | #define Log2P 1 407 | #define Tiny0 0x80 408 | #define Tiny1 0 409 | #define Quick_max 15 410 | #define Int_max 15 411 | #endif /* IBM, VAX */ 412 | #endif /* IEEE_Arith */ 413 | 414 | #ifndef IEEE_Arith 415 | #define ROUND_BIASED 416 | #endif 417 | 418 | #ifdef RND_PRODQUOT 419 | #define rounded_product(a,b) a = rnd_prod(a, b) 420 | #define rounded_quotient(a,b) a = rnd_quot(a, b) 421 | #ifdef KR_headers 422 | extern double rnd_prod(), rnd_quot(); 423 | #else 424 | extern double rnd_prod(double, double), rnd_quot(double, double); 425 | #endif 426 | #else 427 | #define rounded_product(a,b) a *= b 428 | #define rounded_quotient(a,b) a /= b 429 | #endif 430 | 431 | #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) 432 | #define Big1 0xffffffff 433 | 434 | #ifndef Pack_32 435 | #define Pack_32 436 | #endif 437 | 438 | #ifdef KR_headers 439 | #define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff) 440 | #else 441 | #define FFFFFFFF 0xffffffffUL 442 | #endif 443 | 444 | #ifdef NO_LONG_LONG 445 | #undef ULLong 446 | #ifdef Just_16 447 | #undef Pack_32 448 | /* When Pack_32 is not defined, we store 16 bits per 32-bit Long. 449 | * This makes some inner loops simpler and sometimes saves work 450 | * during multiplications, but it often seems to make things slightly 451 | * slower. Hence the default is now to store 32 bits per Long. 452 | */ 453 | #endif 454 | #else /* long long available */ 455 | #ifndef Llong 456 | #define Llong long long 457 | #endif 458 | #ifndef ULLong 459 | #define ULLong unsigned Llong 460 | #endif 461 | #endif /* NO_LONG_LONG */ 462 | 463 | #ifndef MULTIPLE_THREADS 464 | #define ACQUIRE_DTOA_LOCK(n) /*nothing*/ 465 | #define FREE_DTOA_LOCK(n) /*nothing*/ 466 | #endif 467 | 468 | #define Kmax 15 469 | 470 | #ifdef __cplusplus 471 | extern "C" double strtod(const char *s00, char **se); 472 | extern "C" char *dtoa(double d, int mode, int ndigits, 473 | int *decpt, int *sign, char **rve); 474 | #endif 475 | 476 | struct 477 | Bigint { 478 | struct Bigint *next; 479 | int k, maxwds, sign, wds; 480 | ULong x[1]; 481 | }; 482 | 483 | typedef struct Bigint Bigint; 484 | 485 | static Bigint *freelist[Kmax+1]; 486 | 487 | static Bigint * 488 | Balloc 489 | #ifdef KR_headers 490 | (k) int k; 491 | #else 492 | (int k) 493 | #endif 494 | { 495 | int x; 496 | Bigint *rv; 497 | #ifndef Omit_Private_Memory 498 | unsigned int len; 499 | #endif 500 | 501 | ACQUIRE_DTOA_LOCK(0); 502 | if (rv = freelist[k]) { 503 | freelist[k] = rv->next; 504 | } 505 | else { 506 | x = 1 << k; 507 | #ifdef Omit_Private_Memory 508 | rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); 509 | #else 510 | len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) 511 | /sizeof(double); 512 | if (pmem_next - private_mem + len <= PRIVATE_mem) { 513 | rv = (Bigint*)pmem_next; 514 | pmem_next += len; 515 | } 516 | else 517 | rv = (Bigint*)MALLOC(len*sizeof(double)); 518 | #endif 519 | rv->k = k; 520 | rv->maxwds = x; 521 | } 522 | FREE_DTOA_LOCK(0); 523 | rv->sign = rv->wds = 0; 524 | return rv; 525 | } 526 | 527 | static void 528 | Bfree 529 | #ifdef KR_headers 530 | (v) Bigint *v; 531 | #else 532 | (Bigint *v) 533 | #endif 534 | { 535 | if (v) { 536 | ACQUIRE_DTOA_LOCK(0); 537 | v->next = freelist[v->k]; 538 | freelist[v->k] = v; 539 | FREE_DTOA_LOCK(0); 540 | } 541 | } 542 | 543 | #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ 544 | y->wds*sizeof(Long) + 2*sizeof(int)) 545 | 546 | static Bigint * 547 | multadd 548 | #ifdef KR_headers 549 | (b, m, a) Bigint *b; int m, a; 550 | #else 551 | (Bigint *b, int m, int a) /* multiply by m and add a */ 552 | #endif 553 | { 554 | int i, wds; 555 | #ifdef ULLong 556 | ULong *x; 557 | ULLong carry, y; 558 | #else 559 | ULong carry, *x, y; 560 | #ifdef Pack_32 561 | ULong xi, z; 562 | #endif 563 | #endif 564 | Bigint *b1; 565 | 566 | wds = b->wds; 567 | x = b->x; 568 | i = 0; 569 | carry = a; 570 | do { 571 | #ifdef ULLong 572 | y = *x * (ULLong)m + carry; 573 | carry = y >> 32; 574 | *x++ = y & FFFFFFFF; 575 | #else 576 | #ifdef Pack_32 577 | xi = *x; 578 | y = (xi & 0xffff) * m + carry; 579 | z = (xi >> 16) * m + (y >> 16); 580 | carry = z >> 16; 581 | *x++ = (z << 16) + (y & 0xffff); 582 | #else 583 | y = *x * m + carry; 584 | carry = y >> 16; 585 | *x++ = y & 0xffff; 586 | #endif 587 | #endif 588 | } 589 | while(++i < wds); 590 | if (carry) { 591 | if (wds >= b->maxwds) { 592 | b1 = Balloc(b->k+1); 593 | Bcopy(b1, b); 594 | Bfree(b); 595 | b = b1; 596 | } 597 | b->x[wds++] = carry; 598 | b->wds = wds; 599 | } 600 | return b; 601 | } 602 | 603 | static Bigint * 604 | s2b 605 | #ifdef KR_headers 606 | (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; 607 | #else 608 | (CONST char *s, int nd0, int nd, ULong y9) 609 | #endif 610 | { 611 | Bigint *b; 612 | int i, k; 613 | Long x, y; 614 | 615 | x = (nd + 8) / 9; 616 | for(k = 0, y = 1; x > y; y <<= 1, k++) ; 617 | #ifdef Pack_32 618 | b = Balloc(k); 619 | b->x[0] = y9; 620 | b->wds = 1; 621 | #else 622 | b = Balloc(k+1); 623 | b->x[0] = y9 & 0xffff; 624 | b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; 625 | #endif 626 | 627 | i = 9; 628 | if (9 < nd0) { 629 | s += 9; 630 | do b = multadd(b, 10, *s++ - '0'); 631 | while(++i < nd0); 632 | s++; 633 | } 634 | else 635 | s += 10; 636 | for(; i < nd; i++) 637 | b = multadd(b, 10, *s++ - '0'); 638 | return b; 639 | } 640 | 641 | static int 642 | hi0bits 643 | #ifdef KR_headers 644 | (x) register ULong x; 645 | #else 646 | (register ULong x) 647 | #endif 648 | { 649 | register int k = 0; 650 | 651 | if (!(x & 0xffff0000)) { 652 | k = 16; 653 | x <<= 16; 654 | } 655 | if (!(x & 0xff000000)) { 656 | k += 8; 657 | x <<= 8; 658 | } 659 | if (!(x & 0xf0000000)) { 660 | k += 4; 661 | x <<= 4; 662 | } 663 | if (!(x & 0xc0000000)) { 664 | k += 2; 665 | x <<= 2; 666 | } 667 | if (!(x & 0x80000000)) { 668 | k++; 669 | if (!(x & 0x40000000)) 670 | return 32; 671 | } 672 | return k; 673 | } 674 | 675 | static int 676 | lo0bits 677 | #ifdef KR_headers 678 | (y) ULong *y; 679 | #else 680 | (ULong *y) 681 | #endif 682 | { 683 | register int k; 684 | register ULong x = *y; 685 | 686 | if (x & 7) { 687 | if (x & 1) 688 | return 0; 689 | if (x & 2) { 690 | *y = x >> 1; 691 | return 1; 692 | } 693 | *y = x >> 2; 694 | return 2; 695 | } 696 | k = 0; 697 | if (!(x & 0xffff)) { 698 | k = 16; 699 | x >>= 16; 700 | } 701 | if (!(x & 0xff)) { 702 | k += 8; 703 | x >>= 8; 704 | } 705 | if (!(x & 0xf)) { 706 | k += 4; 707 | x >>= 4; 708 | } 709 | if (!(x & 0x3)) { 710 | k += 2; 711 | x >>= 2; 712 | } 713 | if (!(x & 1)) { 714 | k++; 715 | x >>= 1; 716 | if (!x) 717 | return 32; 718 | } 719 | *y = x; 720 | return k; 721 | } 722 | 723 | static Bigint * 724 | i2b 725 | #ifdef KR_headers 726 | (i) int i; 727 | #else 728 | (int i) 729 | #endif 730 | { 731 | Bigint *b; 732 | 733 | b = Balloc(1); 734 | b->x[0] = i; 735 | b->wds = 1; 736 | return b; 737 | } 738 | 739 | static Bigint * 740 | mult 741 | #ifdef KR_headers 742 | (a, b) Bigint *a, *b; 743 | #else 744 | (Bigint *a, Bigint *b) 745 | #endif 746 | { 747 | Bigint *c; 748 | int k, wa, wb, wc; 749 | ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; 750 | ULong y; 751 | #ifdef ULLong 752 | ULLong carry, z; 753 | #else 754 | ULong carry, z; 755 | #ifdef Pack_32 756 | ULong z2; 757 | #endif 758 | #endif 759 | 760 | if (a->wds < b->wds) { 761 | c = a; 762 | a = b; 763 | b = c; 764 | } 765 | k = a->k; 766 | wa = a->wds; 767 | wb = b->wds; 768 | wc = wa + wb; 769 | if (wc > a->maxwds) 770 | k++; 771 | c = Balloc(k); 772 | for(x = c->x, xa = x + wc; x < xa; x++) 773 | *x = 0; 774 | xa = a->x; 775 | xae = xa + wa; 776 | xb = b->x; 777 | xbe = xb + wb; 778 | xc0 = c->x; 779 | #ifdef ULLong 780 | for(; xb < xbe; xc0++) { 781 | if (y = *xb++) { 782 | x = xa; 783 | xc = xc0; 784 | carry = 0; 785 | do { 786 | z = *x++ * (ULLong)y + *xc + carry; 787 | carry = z >> 32; 788 | *xc++ = z & FFFFFFFF; 789 | } 790 | while(x < xae); 791 | *xc = carry; 792 | } 793 | } 794 | #else 795 | #ifdef Pack_32 796 | for(; xb < xbe; xb++, xc0++) { 797 | if (y = *xb & 0xffff) { 798 | x = xa; 799 | xc = xc0; 800 | carry = 0; 801 | do { 802 | z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; 803 | carry = z >> 16; 804 | z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; 805 | carry = z2 >> 16; 806 | Storeinc(xc, z2, z); 807 | } 808 | while(x < xae); 809 | *xc = carry; 810 | } 811 | if (y = *xb >> 16) { 812 | x = xa; 813 | xc = xc0; 814 | carry = 0; 815 | z2 = *xc; 816 | do { 817 | z = (*x & 0xffff) * y + (*xc >> 16) + carry; 818 | carry = z >> 16; 819 | Storeinc(xc, z, z2); 820 | z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; 821 | carry = z2 >> 16; 822 | } 823 | while(x < xae); 824 | *xc = z2; 825 | } 826 | } 827 | #else 828 | for(; xb < xbe; xc0++) { 829 | if (y = *xb++) { 830 | x = xa; 831 | xc = xc0; 832 | carry = 0; 833 | do { 834 | z = *x++ * y + *xc + carry; 835 | carry = z >> 16; 836 | *xc++ = z & 0xffff; 837 | } 838 | while(x < xae); 839 | *xc = carry; 840 | } 841 | } 842 | #endif 843 | #endif 844 | for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; 845 | c->wds = wc; 846 | return c; 847 | } 848 | 849 | static Bigint *p5s; 850 | 851 | static Bigint * 852 | pow5mult 853 | #ifdef KR_headers 854 | (b, k) Bigint *b; int k; 855 | #else 856 | (Bigint *b, int k) 857 | #endif 858 | { 859 | Bigint *b1, *p5, *p51; 860 | int i; 861 | static int p05[3] = { 5, 25, 125 }; 862 | 863 | if (i = k & 3) 864 | b = multadd(b, p05[i-1], 0); 865 | 866 | if (!(k >>= 2)) 867 | return b; 868 | if (!(p5 = p5s)) { 869 | /* first time */ 870 | #ifdef MULTIPLE_THREADS 871 | ACQUIRE_DTOA_LOCK(1); 872 | if (!(p5 = p5s)) { 873 | p5 = p5s = i2b(625); 874 | p5->next = 0; 875 | } 876 | FREE_DTOA_LOCK(1); 877 | #else 878 | p5 = p5s = i2b(625); 879 | p5->next = 0; 880 | #endif 881 | } 882 | for(;;) { 883 | if (k & 1) { 884 | b1 = mult(b, p5); 885 | Bfree(b); 886 | b = b1; 887 | } 888 | if (!(k >>= 1)) 889 | break; 890 | if (!(p51 = p5->next)) { 891 | #ifdef MULTIPLE_THREADS 892 | ACQUIRE_DTOA_LOCK(1); 893 | if (!(p51 = p5->next)) { 894 | p51 = p5->next = mult(p5,p5); 895 | p51->next = 0; 896 | } 897 | FREE_DTOA_LOCK(1); 898 | #else 899 | p51 = p5->next = mult(p5,p5); 900 | p51->next = 0; 901 | #endif 902 | } 903 | p5 = p51; 904 | } 905 | return b; 906 | } 907 | 908 | static Bigint * 909 | lshift 910 | #ifdef KR_headers 911 | (b, k) Bigint *b; int k; 912 | #else 913 | (Bigint *b, int k) 914 | #endif 915 | { 916 | int i, k1, n, n1; 917 | Bigint *b1; 918 | ULong *x, *x1, *xe, z; 919 | 920 | #ifdef Pack_32 921 | n = k >> 5; 922 | #else 923 | n = k >> 4; 924 | #endif 925 | k1 = b->k; 926 | n1 = n + b->wds + 1; 927 | for(i = b->maxwds; n1 > i; i <<= 1) 928 | k1++; 929 | b1 = Balloc(k1); 930 | x1 = b1->x; 931 | for(i = 0; i < n; i++) 932 | *x1++ = 0; 933 | x = b->x; 934 | xe = x + b->wds; 935 | #ifdef Pack_32 936 | if (k &= 0x1f) { 937 | k1 = 32 - k; 938 | z = 0; 939 | do { 940 | *x1++ = *x << k | z; 941 | z = *x++ >> k1; 942 | } 943 | while(x < xe); 944 | if (*x1 = z) 945 | ++n1; 946 | } 947 | #else 948 | if (k &= 0xf) { 949 | k1 = 16 - k; 950 | z = 0; 951 | do { 952 | *x1++ = *x << k & 0xffff | z; 953 | z = *x++ >> k1; 954 | } 955 | while(x < xe); 956 | if (*x1 = z) 957 | ++n1; 958 | } 959 | #endif 960 | else do 961 | *x1++ = *x++; 962 | while(x < xe); 963 | b1->wds = n1 - 1; 964 | Bfree(b); 965 | return b1; 966 | } 967 | 968 | static int 969 | cmp 970 | #ifdef KR_headers 971 | (a, b) Bigint *a, *b; 972 | #else 973 | (Bigint *a, Bigint *b) 974 | #endif 975 | { 976 | ULong *xa, *xa0, *xb, *xb0; 977 | int i, j; 978 | 979 | i = a->wds; 980 | j = b->wds; 981 | #ifdef DEBUG 982 | if (i > 1 && !a->x[i-1]) 983 | Bug("cmp called with a->x[a->wds-1] == 0"); 984 | if (j > 1 && !b->x[j-1]) 985 | Bug("cmp called with b->x[b->wds-1] == 0"); 986 | #endif 987 | if (i -= j) 988 | return i; 989 | xa0 = a->x; 990 | xa = xa0 + j; 991 | xb0 = b->x; 992 | xb = xb0 + j; 993 | for(;;) { 994 | if (*--xa != *--xb) 995 | return *xa < *xb ? -1 : 1; 996 | if (xa <= xa0) 997 | break; 998 | } 999 | return 0; 1000 | } 1001 | 1002 | static Bigint * 1003 | diff 1004 | #ifdef KR_headers 1005 | (a, b) Bigint *a, *b; 1006 | #else 1007 | (Bigint *a, Bigint *b) 1008 | #endif 1009 | { 1010 | Bigint *c; 1011 | int i, wa, wb; 1012 | ULong *xa, *xae, *xb, *xbe, *xc; 1013 | #ifdef ULLong 1014 | ULLong borrow, y; 1015 | #else 1016 | ULong borrow, y; 1017 | #ifdef Pack_32 1018 | ULong z; 1019 | #endif 1020 | #endif 1021 | 1022 | i = cmp(a,b); 1023 | if (!i) { 1024 | c = Balloc(0); 1025 | c->wds = 1; 1026 | c->x[0] = 0; 1027 | return c; 1028 | } 1029 | if (i < 0) { 1030 | c = a; 1031 | a = b; 1032 | b = c; 1033 | i = 1; 1034 | } 1035 | else 1036 | i = 0; 1037 | c = Balloc(a->k); 1038 | c->sign = i; 1039 | wa = a->wds; 1040 | xa = a->x; 1041 | xae = xa + wa; 1042 | wb = b->wds; 1043 | xb = b->x; 1044 | xbe = xb + wb; 1045 | xc = c->x; 1046 | borrow = 0; 1047 | #ifdef ULLong 1048 | do { 1049 | y = (ULLong)*xa++ - *xb++ - borrow; 1050 | borrow = y >> 32 & (ULong)1; 1051 | *xc++ = y & FFFFFFFF; 1052 | } 1053 | while(xb < xbe); 1054 | while(xa < xae) { 1055 | y = *xa++ - borrow; 1056 | borrow = y >> 32 & (ULong)1; 1057 | *xc++ = y & FFFFFFFF; 1058 | } 1059 | #else 1060 | #ifdef Pack_32 1061 | do { 1062 | y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; 1063 | borrow = (y & 0x10000) >> 16; 1064 | z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; 1065 | borrow = (z & 0x10000) >> 16; 1066 | Storeinc(xc, z, y); 1067 | } 1068 | while(xb < xbe); 1069 | while(xa < xae) { 1070 | y = (*xa & 0xffff) - borrow; 1071 | borrow = (y & 0x10000) >> 16; 1072 | z = (*xa++ >> 16) - borrow; 1073 | borrow = (z & 0x10000) >> 16; 1074 | Storeinc(xc, z, y); 1075 | } 1076 | #else 1077 | do { 1078 | y = *xa++ - *xb++ - borrow; 1079 | borrow = (y & 0x10000) >> 16; 1080 | *xc++ = y & 0xffff; 1081 | } 1082 | while(xb < xbe); 1083 | while(xa < xae) { 1084 | y = *xa++ - borrow; 1085 | borrow = (y & 0x10000) >> 16; 1086 | *xc++ = y & 0xffff; 1087 | } 1088 | #endif 1089 | #endif 1090 | while(!*--xc) 1091 | wa--; 1092 | c->wds = wa; 1093 | return c; 1094 | } 1095 | 1096 | static double 1097 | ulp 1098 | #ifdef KR_headers 1099 | (x) double x; 1100 | #else 1101 | (double x) 1102 | #endif 1103 | { 1104 | register Long L; 1105 | double a; 1106 | 1107 | L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; 1108 | #ifndef Avoid_Underflow 1109 | #ifndef Sudden_Underflow 1110 | if (L > 0) { 1111 | #endif 1112 | #endif 1113 | #ifdef IBM 1114 | L |= Exp_msk1 >> 4; 1115 | #endif 1116 | word0(a) = L; 1117 | word1(a) = 0; 1118 | #ifndef Avoid_Underflow 1119 | #ifndef Sudden_Underflow 1120 | } 1121 | else { 1122 | L = -L >> Exp_shift; 1123 | if (L < Exp_shift) { 1124 | word0(a) = 0x80000 >> L; 1125 | word1(a) = 0; 1126 | } 1127 | else { 1128 | word0(a) = 0; 1129 | L -= Exp_shift; 1130 | word1(a) = L >= 31 ? 1 : 1 << 31 - L; 1131 | } 1132 | } 1133 | #endif 1134 | #endif 1135 | return dval(a); 1136 | } 1137 | 1138 | static double 1139 | b2d 1140 | #ifdef KR_headers 1141 | (a, e) Bigint *a; int *e; 1142 | #else 1143 | (Bigint *a, int *e) 1144 | #endif 1145 | { 1146 | ULong *xa, *xa0, w, y, z; 1147 | int k; 1148 | double d; 1149 | #ifdef VAX 1150 | ULong d0, d1; 1151 | #else 1152 | #define d0 word0(d) 1153 | #define d1 word1(d) 1154 | #endif 1155 | 1156 | xa0 = a->x; 1157 | xa = xa0 + a->wds; 1158 | y = *--xa; 1159 | #ifdef DEBUG 1160 | if (!y) Bug("zero y in b2d"); 1161 | #endif 1162 | k = hi0bits(y); 1163 | *e = 32 - k; 1164 | #ifdef Pack_32 1165 | if (k < Ebits) { 1166 | d0 = Exp_1 | y >> Ebits - k; 1167 | w = xa > xa0 ? *--xa : 0; 1168 | d1 = y << (32-Ebits) + k | w >> Ebits - k; 1169 | goto ret_d; 1170 | } 1171 | z = xa > xa0 ? *--xa : 0; 1172 | if (k -= Ebits) { 1173 | d0 = Exp_1 | y << k | z >> 32 - k; 1174 | y = xa > xa0 ? *--xa : 0; 1175 | d1 = z << k | y >> 32 - k; 1176 | } 1177 | else { 1178 | d0 = Exp_1 | y; 1179 | d1 = z; 1180 | } 1181 | #else 1182 | if (k < Ebits + 16) { 1183 | z = xa > xa0 ? *--xa : 0; 1184 | d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; 1185 | w = xa > xa0 ? *--xa : 0; 1186 | y = xa > xa0 ? *--xa : 0; 1187 | d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; 1188 | goto ret_d; 1189 | } 1190 | z = xa > xa0 ? *--xa : 0; 1191 | w = xa > xa0 ? *--xa : 0; 1192 | k -= Ebits + 16; 1193 | d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; 1194 | y = xa > xa0 ? *--xa : 0; 1195 | d1 = w << k + 16 | y << k; 1196 | #endif 1197 | ret_d: 1198 | #ifdef VAX 1199 | word0(d) = d0 >> 16 | d0 << 16; 1200 | word1(d) = d1 >> 16 | d1 << 16; 1201 | #else 1202 | #undef d0 1203 | #undef d1 1204 | #endif 1205 | return dval(d); 1206 | } 1207 | 1208 | static Bigint * 1209 | d2b 1210 | #ifdef KR_headers 1211 | (d, e, bits) double d; int *e, *bits; 1212 | #else 1213 | (double d, int *e, int *bits) 1214 | #endif 1215 | { 1216 | Bigint *b; 1217 | int de, k; 1218 | ULong *x, y, z; 1219 | #ifndef Sudden_Underflow 1220 | int i; 1221 | #endif 1222 | #ifdef VAX 1223 | ULong d0, d1; 1224 | d0 = word0(d) >> 16 | word0(d) << 16; 1225 | d1 = word1(d) >> 16 | word1(d) << 16; 1226 | #else 1227 | #define d0 word0(d) 1228 | #define d1 word1(d) 1229 | #endif 1230 | 1231 | #ifdef Pack_32 1232 | b = Balloc(1); 1233 | #else 1234 | b = Balloc(2); 1235 | #endif 1236 | x = b->x; 1237 | 1238 | z = d0 & Frac_mask; 1239 | d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ 1240 | #ifdef Sudden_Underflow 1241 | de = (int)(d0 >> Exp_shift); 1242 | #ifndef IBM 1243 | z |= Exp_msk11; 1244 | #endif 1245 | #else 1246 | if (de = (int)(d0 >> Exp_shift)) 1247 | z |= Exp_msk1; 1248 | #endif 1249 | #ifdef Pack_32 1250 | if (y = d1) { 1251 | if (k = lo0bits(&y)) { 1252 | x[0] = y | z << 32 - k; 1253 | z >>= k; 1254 | } 1255 | else 1256 | x[0] = y; 1257 | #ifndef Sudden_Underflow 1258 | i = 1259 | #endif 1260 | b->wds = (x[1] = z) ? 2 : 1; 1261 | } 1262 | else { 1263 | #ifdef DEBUG 1264 | if (!z) 1265 | Bug("Zero passed to d2b"); 1266 | #endif 1267 | k = lo0bits(&z); 1268 | x[0] = z; 1269 | #ifndef Sudden_Underflow 1270 | i = 1271 | #endif 1272 | b->wds = 1; 1273 | k += 32; 1274 | } 1275 | #else 1276 | if (y = d1) { 1277 | if (k = lo0bits(&y)) 1278 | if (k >= 16) { 1279 | x[0] = y | z << 32 - k & 0xffff; 1280 | x[1] = z >> k - 16 & 0xffff; 1281 | x[2] = z >> k; 1282 | i = 2; 1283 | } 1284 | else { 1285 | x[0] = y & 0xffff; 1286 | x[1] = y >> 16 | z << 16 - k & 0xffff; 1287 | x[2] = z >> k & 0xffff; 1288 | x[3] = z >> k+16; 1289 | i = 3; 1290 | } 1291 | else { 1292 | x[0] = y & 0xffff; 1293 | x[1] = y >> 16; 1294 | x[2] = z & 0xffff; 1295 | x[3] = z >> 16; 1296 | i = 3; 1297 | } 1298 | } 1299 | else { 1300 | #ifdef DEBUG 1301 | if (!z) 1302 | Bug("Zero passed to d2b"); 1303 | #endif 1304 | k = lo0bits(&z); 1305 | if (k >= 16) { 1306 | x[0] = z; 1307 | i = 0; 1308 | } 1309 | else { 1310 | x[0] = z & 0xffff; 1311 | x[1] = z >> 16; 1312 | i = 1; 1313 | } 1314 | k += 32; 1315 | } 1316 | while(!x[i]) 1317 | --i; 1318 | b->wds = i + 1; 1319 | #endif 1320 | #ifndef Sudden_Underflow 1321 | if (de) { 1322 | #endif 1323 | #ifdef IBM 1324 | *e = (de - Bias - (P-1) << 2) + k; 1325 | *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); 1326 | #else 1327 | *e = de - Bias - (P-1) + k; 1328 | *bits = P - k; 1329 | #endif 1330 | #ifndef Sudden_Underflow 1331 | } 1332 | else { 1333 | *e = de - Bias - (P-1) + 1 + k; 1334 | #ifdef Pack_32 1335 | *bits = 32*i - hi0bits(x[i-1]); 1336 | #else 1337 | *bits = (i+2)*16 - hi0bits(x[i]); 1338 | #endif 1339 | } 1340 | #endif 1341 | return b; 1342 | } 1343 | #undef d0 1344 | #undef d1 1345 | 1346 | static double 1347 | ratio 1348 | #ifdef KR_headers 1349 | (a, b) Bigint *a, *b; 1350 | #else 1351 | (Bigint *a, Bigint *b) 1352 | #endif 1353 | { 1354 | double da, db; 1355 | int k, ka, kb; 1356 | 1357 | dval(da) = b2d(a, &ka); 1358 | dval(db) = b2d(b, &kb); 1359 | #ifdef Pack_32 1360 | k = ka - kb + 32*(a->wds - b->wds); 1361 | #else 1362 | k = ka - kb + 16*(a->wds - b->wds); 1363 | #endif 1364 | #ifdef IBM 1365 | if (k > 0) { 1366 | word0(da) += (k >> 2)*Exp_msk1; 1367 | if (k &= 3) 1368 | dval(da) *= 1 << k; 1369 | } 1370 | else { 1371 | k = -k; 1372 | word0(db) += (k >> 2)*Exp_msk1; 1373 | if (k &= 3) 1374 | dval(db) *= 1 << k; 1375 | } 1376 | #else 1377 | if (k > 0) 1378 | word0(da) += k*Exp_msk1; 1379 | else { 1380 | k = -k; 1381 | word0(db) += k*Exp_msk1; 1382 | } 1383 | #endif 1384 | return dval(da) / dval(db); 1385 | } 1386 | 1387 | static CONST double 1388 | tens[] = { 1389 | 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1390 | 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1391 | 1e20, 1e21, 1e22 1392 | #ifdef VAX 1393 | , 1e23, 1e24 1394 | #endif 1395 | }; 1396 | 1397 | static CONST double 1398 | #ifdef IEEE_Arith 1399 | bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; 1400 | static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1401 | #ifdef Avoid_Underflow 1402 | 9007199254740992.*9007199254740992.e-256 1403 | /* = 2^106 * 1e-53 */ 1404 | #else 1405 | 1e-256 1406 | #endif 1407 | }; 1408 | /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ 1409 | /* flag unnecessarily. It leads to a song and dance at the end of strtod. */ 1410 | #define Scale_Bit 0x10 1411 | #define n_bigtens 5 1412 | #else 1413 | #ifdef IBM 1414 | bigtens[] = { 1e16, 1e32, 1e64 }; 1415 | static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; 1416 | #define n_bigtens 3 1417 | #else 1418 | bigtens[] = { 1e16, 1e32 }; 1419 | static CONST double tinytens[] = { 1e-16, 1e-32 }; 1420 | #define n_bigtens 2 1421 | #endif 1422 | #endif 1423 | 1424 | #ifndef IEEE_Arith 1425 | #undef INFNAN_CHECK 1426 | #endif 1427 | 1428 | #ifdef INFNAN_CHECK 1429 | 1430 | #ifndef NAN_WORD0 1431 | #define NAN_WORD0 0x7ff80000 1432 | #endif 1433 | 1434 | #ifndef NAN_WORD1 1435 | #define NAN_WORD1 0 1436 | #endif 1437 | 1438 | static int 1439 | match 1440 | #ifdef KR_headers 1441 | (sp, t) char **sp, *t; 1442 | #else 1443 | (CONST char **sp, char *t) 1444 | #endif 1445 | { 1446 | int c, d; 1447 | CONST char *s = *sp; 1448 | 1449 | while(d = *t++) { 1450 | if ((c = *++s) >= 'A' && c <= 'Z') 1451 | c += 'a' - 'A'; 1452 | if (c != d) 1453 | return 0; 1454 | } 1455 | *sp = s + 1; 1456 | return 1; 1457 | } 1458 | 1459 | #ifndef No_Hex_NaN 1460 | static void 1461 | hexnan 1462 | #ifdef KR_headers 1463 | (rvp, sp) double *rvp; CONST char **sp; 1464 | #else 1465 | (double *rvp, CONST char **sp) 1466 | #endif 1467 | { 1468 | ULong c, x[2]; 1469 | CONST char *s; 1470 | int havedig, udx0, xshift; 1471 | 1472 | x[0] = x[1] = 0; 1473 | havedig = xshift = 0; 1474 | udx0 = 1; 1475 | s = *sp; 1476 | while(c = *(CONST unsigned char*)++s) { 1477 | if (c >= '0' && c <= '9') 1478 | c -= '0'; 1479 | else if (c >= 'a' && c <= 'f') 1480 | c += 10 - 'a'; 1481 | else if (c >= 'A' && c <= 'F') 1482 | c += 10 - 'A'; 1483 | else if (c <= ' ') { 1484 | if (udx0 && havedig) { 1485 | udx0 = 0; 1486 | xshift = 1; 1487 | } 1488 | continue; 1489 | } 1490 | else if (/*(*/ c == ')' && havedig) { 1491 | *sp = s + 1; 1492 | break; 1493 | } 1494 | else 1495 | return; /* invalid form: don't change *sp */ 1496 | havedig = 1; 1497 | if (xshift) { 1498 | xshift = 0; 1499 | x[0] = x[1]; 1500 | x[1] = 0; 1501 | } 1502 | if (udx0) 1503 | x[0] = (x[0] << 4) | (x[1] >> 28); 1504 | x[1] = (x[1] << 4) | c; 1505 | } 1506 | if ((x[0] &= 0xfffff) || x[1]) { 1507 | word0(*rvp) = Exp_mask | x[0]; 1508 | word1(*rvp) = x[1]; 1509 | } 1510 | } 1511 | #endif /*No_Hex_NaN*/ 1512 | #endif /* INFNAN_CHECK */ 1513 | 1514 | double 1515 | strtod 1516 | #ifdef KR_headers 1517 | (s00, se) CONST char *s00; char **se; 1518 | #else 1519 | (CONST char *s00, char **se) 1520 | #endif 1521 | { 1522 | #ifdef Avoid_Underflow 1523 | int scale; 1524 | #endif 1525 | int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, 1526 | e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; 1527 | CONST char *s, *s0, *s1; 1528 | double aadj, aadj1, adj, rv, rv0; 1529 | Long L; 1530 | ULong y, z; 1531 | Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; 1532 | #ifdef SET_INEXACT 1533 | int inexact, oldinexact; 1534 | #endif 1535 | #ifdef Honor_FLT_ROUNDS 1536 | int rounding; 1537 | #endif 1538 | #ifdef USE_LOCALE 1539 | CONST char *s2; 1540 | #endif 1541 | 1542 | sign = nz0 = nz = 0; 1543 | dval(rv) = 0.; 1544 | for(s = s00;;s++) switch(*s) { 1545 | case '-': 1546 | sign = 1; 1547 | /* no break */ 1548 | case '+': 1549 | if (*++s) 1550 | goto break2; 1551 | /* no break */ 1552 | case 0: 1553 | goto ret0; 1554 | case '\t': 1555 | case '\n': 1556 | case '\v': 1557 | case '\f': 1558 | case '\r': 1559 | case ' ': 1560 | continue; 1561 | default: 1562 | goto break2; 1563 | } 1564 | break2: 1565 | if (*s == '0') { 1566 | nz0 = 1; 1567 | while(*++s == '0') ; 1568 | if (!*s) 1569 | goto ret; 1570 | } 1571 | s0 = s; 1572 | y = z = 0; 1573 | for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) 1574 | if (nd < 9) 1575 | y = 10*y + c - '0'; 1576 | else if (nd < 16) 1577 | z = 10*z + c - '0'; 1578 | nd0 = nd; 1579 | #ifdef USE_LOCALE 1580 | s1 = localeconv()->decimal_point; 1581 | if (c == *s1) { 1582 | c = '.'; 1583 | if (*++s1) { 1584 | s2 = s; 1585 | for(;;) { 1586 | if (*++s2 != *s1) { 1587 | c = 0; 1588 | break; 1589 | } 1590 | if (!*++s1) { 1591 | s = s2; 1592 | break; 1593 | } 1594 | } 1595 | } 1596 | } 1597 | #endif 1598 | if (c == '.') { 1599 | c = *++s; 1600 | if (!nd) { 1601 | for(; c == '0'; c = *++s) 1602 | nz++; 1603 | if (c > '0' && c <= '9') { 1604 | s0 = s; 1605 | nf += nz; 1606 | nz = 0; 1607 | goto have_dig; 1608 | } 1609 | goto dig_done; 1610 | } 1611 | for(; c >= '0' && c <= '9'; c = *++s) { 1612 | have_dig: 1613 | nz++; 1614 | if (c -= '0') { 1615 | nf += nz; 1616 | for(i = 1; i < nz; i++) 1617 | if (nd++ < 9) 1618 | y *= 10; 1619 | else if (nd <= DBL_DIG + 1) 1620 | z *= 10; 1621 | if (nd++ < 9) 1622 | y = 10*y + c; 1623 | else if (nd <= DBL_DIG + 1) 1624 | z = 10*z + c; 1625 | nz = 0; 1626 | } 1627 | } 1628 | } 1629 | dig_done: 1630 | e = 0; 1631 | if (c == 'e' || c == 'E') { 1632 | if (!nd && !nz && !nz0) { 1633 | goto ret0; 1634 | } 1635 | s00 = s; 1636 | esign = 0; 1637 | switch(c = *++s) { 1638 | case '-': 1639 | esign = 1; 1640 | case '+': 1641 | c = *++s; 1642 | } 1643 | if (c >= '0' && c <= '9') { 1644 | while(c == '0') 1645 | c = *++s; 1646 | if (c > '0' && c <= '9') { 1647 | L = c - '0'; 1648 | s1 = s; 1649 | while((c = *++s) >= '0' && c <= '9') 1650 | L = 10*L + c - '0'; 1651 | if (s - s1 > 8 || L > 19999) 1652 | /* Avoid confusion from exponents 1653 | * so large that e might overflow. 1654 | */ 1655 | e = 19999; /* safe for 16 bit ints */ 1656 | else 1657 | e = (int)L; 1658 | if (esign) 1659 | e = -e; 1660 | } 1661 | else 1662 | e = 0; 1663 | } 1664 | else 1665 | s = s00; 1666 | } 1667 | if (!nd) { 1668 | if (!nz && !nz0) { 1669 | #ifdef INFNAN_CHECK 1670 | /* Check for Nan and Infinity */ 1671 | switch(c) { 1672 | case 'i': 1673 | case 'I': 1674 | if (match(&s,"nf")) { 1675 | --s; 1676 | if (!match(&s,"inity")) 1677 | ++s; 1678 | word0(rv) = 0x7ff00000; 1679 | word1(rv) = 0; 1680 | goto ret; 1681 | } 1682 | break; 1683 | case 'n': 1684 | case 'N': 1685 | if (match(&s, "an")) { 1686 | word0(rv) = NAN_WORD0; 1687 | word1(rv) = NAN_WORD1; 1688 | #ifndef No_Hex_NaN 1689 | if (*s == '(') /*)*/ 1690 | hexnan(&rv, &s); 1691 | #endif 1692 | goto ret; 1693 | } 1694 | } 1695 | #endif /* INFNAN_CHECK */ 1696 | ret0: 1697 | s = s00; 1698 | sign = 0; 1699 | } 1700 | goto ret; 1701 | } 1702 | e1 = e -= nf; 1703 | 1704 | /* Now we have nd0 digits, starting at s0, followed by a 1705 | * decimal point, followed by nd-nd0 digits. The number we're 1706 | * after is the integer represented by those digits times 1707 | * 10**e */ 1708 | 1709 | if (!nd0) 1710 | nd0 = nd; 1711 | k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; 1712 | dval(rv) = y; 1713 | if (k > 9) { 1714 | #ifdef SET_INEXACT 1715 | if (k > DBL_DIG) 1716 | oldinexact = get_inexact(); 1717 | #endif 1718 | dval(rv) = tens[k - 9] * dval(rv) + z; 1719 | } 1720 | bd0 = 0; 1721 | if (nd <= DBL_DIG 1722 | #ifndef RND_PRODQUOT 1723 | #ifndef Honor_FLT_ROUNDS 1724 | && Flt_Rounds == 1 1725 | #endif 1726 | #endif 1727 | ) { 1728 | if (!e) 1729 | goto ret; 1730 | if (e > 0) { 1731 | if (e <= Ten_pmax) { 1732 | #ifdef VAX 1733 | goto vax_ovfl_check; 1734 | #else 1735 | #ifdef Honor_FLT_ROUNDS 1736 | /* round correctly FLT_ROUNDS = 2 or 3 */ 1737 | if (sign) { 1738 | rv = -rv; 1739 | sign = 0; 1740 | } 1741 | #endif 1742 | /* rv = */ rounded_product(dval(rv), tens[e]); 1743 | goto ret; 1744 | #endif 1745 | } 1746 | i = DBL_DIG - nd; 1747 | if (e <= Ten_pmax + i) { 1748 | /* A fancier test would sometimes let us do 1749 | * this for larger i values. 1750 | */ 1751 | #ifdef Honor_FLT_ROUNDS 1752 | /* round correctly FLT_ROUNDS = 2 or 3 */ 1753 | if (sign) { 1754 | rv = -rv; 1755 | sign = 0; 1756 | } 1757 | #endif 1758 | e -= i; 1759 | dval(rv) *= tens[i]; 1760 | #ifdef VAX 1761 | /* VAX exponent range is so narrow we must 1762 | * worry about overflow here... 1763 | */ 1764 | vax_ovfl_check: 1765 | word0(rv) -= P*Exp_msk1; 1766 | /* rv = */ rounded_product(dval(rv), tens[e]); 1767 | if ((word0(rv) & Exp_mask) 1768 | > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) 1769 | goto ovfl; 1770 | word0(rv) += P*Exp_msk1; 1771 | #else 1772 | /* rv = */ rounded_product(dval(rv), tens[e]); 1773 | #endif 1774 | goto ret; 1775 | } 1776 | } 1777 | #ifndef Inaccurate_Divide 1778 | else if (e >= -Ten_pmax) { 1779 | #ifdef Honor_FLT_ROUNDS 1780 | /* round correctly FLT_ROUNDS = 2 or 3 */ 1781 | if (sign) { 1782 | rv = -rv; 1783 | sign = 0; 1784 | } 1785 | #endif 1786 | /* rv = */ rounded_quotient(dval(rv), tens[-e]); 1787 | goto ret; 1788 | } 1789 | #endif 1790 | } 1791 | e1 += nd - k; 1792 | 1793 | #ifdef IEEE_Arith 1794 | #ifdef SET_INEXACT 1795 | inexact = 1; 1796 | if (k <= DBL_DIG) 1797 | oldinexact = get_inexact(); 1798 | #endif 1799 | #ifdef Avoid_Underflow 1800 | scale = 0; 1801 | #endif 1802 | #ifdef Honor_FLT_ROUNDS 1803 | if ((rounding = Flt_Rounds) >= 2) { 1804 | if (sign) 1805 | rounding = rounding == 2 ? 0 : 2; 1806 | else 1807 | if (rounding != 2) 1808 | rounding = 0; 1809 | } 1810 | #endif 1811 | #endif /*IEEE_Arith*/ 1812 | 1813 | /* Get starting approximation = rv * 10**e1 */ 1814 | 1815 | if (e1 > 0) { 1816 | if (i = e1 & 15) 1817 | dval(rv) *= tens[i]; 1818 | if (e1 &= ~15) { 1819 | if (e1 > DBL_MAX_10_EXP) { 1820 | ovfl: 1821 | #ifndef NO_ERRNO 1822 | errno = ERANGE; 1823 | #endif 1824 | /* Can't trust HUGE_VAL */ 1825 | #ifdef IEEE_Arith 1826 | #ifdef Honor_FLT_ROUNDS 1827 | switch(rounding) { 1828 | case 0: /* toward 0 */ 1829 | case 3: /* toward -infinity */ 1830 | word0(rv) = Big0; 1831 | word1(rv) = Big1; 1832 | break; 1833 | default: 1834 | word0(rv) = Exp_mask; 1835 | word1(rv) = 0; 1836 | } 1837 | #else /*Honor_FLT_ROUNDS*/ 1838 | word0(rv) = Exp_mask; 1839 | word1(rv) = 0; 1840 | #endif /*Honor_FLT_ROUNDS*/ 1841 | #ifdef SET_INEXACT 1842 | /* set overflow bit */ 1843 | dval(rv0) = 1e300; 1844 | dval(rv0) *= dval(rv0); 1845 | #endif 1846 | #else /*IEEE_Arith*/ 1847 | word0(rv) = Big0; 1848 | word1(rv) = Big1; 1849 | #endif /*IEEE_Arith*/ 1850 | if (bd0) 1851 | goto retfree; 1852 | goto ret; 1853 | } 1854 | e1 >>= 4; 1855 | for(j = 0; e1 > 1; j++, e1 >>= 1) 1856 | if (e1 & 1) 1857 | dval(rv) *= bigtens[j]; 1858 | /* The last multiplication could overflow. */ 1859 | word0(rv) -= P*Exp_msk1; 1860 | dval(rv) *= bigtens[j]; 1861 | if ((z = word0(rv) & Exp_mask) 1862 | > Exp_msk1*(DBL_MAX_EXP+Bias-P)) 1863 | goto ovfl; 1864 | if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { 1865 | /* set to largest number */ 1866 | /* (Can't trust DBL_MAX) */ 1867 | word0(rv) = Big0; 1868 | word1(rv) = Big1; 1869 | } 1870 | else 1871 | word0(rv) += P*Exp_msk1; 1872 | } 1873 | } 1874 | else if (e1 < 0) { 1875 | e1 = -e1; 1876 | if (i = e1 & 15) 1877 | dval(rv) /= tens[i]; 1878 | if (e1 >>= 4) { 1879 | if (e1 >= 1 << n_bigtens) 1880 | goto undfl; 1881 | #ifdef Avoid_Underflow 1882 | if (e1 & Scale_Bit) 1883 | scale = 2*P; 1884 | for(j = 0; e1 > 0; j++, e1 >>= 1) 1885 | if (e1 & 1) 1886 | dval(rv) *= tinytens[j]; 1887 | if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) 1888 | >> Exp_shift)) > 0) { 1889 | /* scaled rv is denormal; zap j low bits */ 1890 | if (j >= 32) { 1891 | word1(rv) = 0; 1892 | if (j >= 53) 1893 | word0(rv) = (P+2)*Exp_msk1; 1894 | else 1895 | word0(rv) &= 0xffffffff << j-32; 1896 | } 1897 | else 1898 | word1(rv) &= 0xffffffff << j; 1899 | } 1900 | #else 1901 | for(j = 0; e1 > 1; j++, e1 >>= 1) 1902 | if (e1 & 1) 1903 | dval(rv) *= tinytens[j]; 1904 | /* The last multiplication could underflow. */ 1905 | dval(rv0) = dval(rv); 1906 | dval(rv) *= tinytens[j]; 1907 | if (!dval(rv)) { 1908 | dval(rv) = 2.*dval(rv0); 1909 | dval(rv) *= tinytens[j]; 1910 | #endif 1911 | if (!dval(rv)) { 1912 | undfl: 1913 | dval(rv) = 0.; 1914 | #ifndef NO_ERRNO 1915 | errno = ERANGE; 1916 | #endif 1917 | if (bd0) 1918 | goto retfree; 1919 | goto ret; 1920 | } 1921 | #ifndef Avoid_Underflow 1922 | word0(rv) = Tiny0; 1923 | word1(rv) = Tiny1; 1924 | /* The refinement below will clean 1925 | * this approximation up. 1926 | */ 1927 | } 1928 | #endif 1929 | } 1930 | } 1931 | 1932 | /* Now the hard part -- adjusting rv to the correct value.*/ 1933 | 1934 | /* Put digits into bd: true value = bd * 10^e */ 1935 | 1936 | bd0 = s2b(s0, nd0, nd, y); 1937 | 1938 | for(;;) { 1939 | bd = Balloc(bd0->k); 1940 | Bcopy(bd, bd0); 1941 | bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ 1942 | bs = i2b(1); 1943 | 1944 | if (e >= 0) { 1945 | bb2 = bb5 = 0; 1946 | bd2 = bd5 = e; 1947 | } 1948 | else { 1949 | bb2 = bb5 = -e; 1950 | bd2 = bd5 = 0; 1951 | } 1952 | if (bbe >= 0) 1953 | bb2 += bbe; 1954 | else 1955 | bd2 -= bbe; 1956 | bs2 = bb2; 1957 | #ifdef Honor_FLT_ROUNDS 1958 | if (rounding != 1) 1959 | bs2++; 1960 | #endif 1961 | #ifdef Avoid_Underflow 1962 | j = bbe - scale; 1963 | i = j + bbbits - 1; /* logb(rv) */ 1964 | if (i < Emin) /* denormal */ 1965 | j += P - Emin; 1966 | else 1967 | j = P + 1 - bbbits; 1968 | #else /*Avoid_Underflow*/ 1969 | #ifdef Sudden_Underflow 1970 | #ifdef IBM 1971 | j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); 1972 | #else 1973 | j = P + 1 - bbbits; 1974 | #endif 1975 | #else /*Sudden_Underflow*/ 1976 | j = bbe; 1977 | i = j + bbbits - 1; /* logb(rv) */ 1978 | if (i < Emin) /* denormal */ 1979 | j += P - Emin; 1980 | else 1981 | j = P + 1 - bbbits; 1982 | #endif /*Sudden_Underflow*/ 1983 | #endif /*Avoid_Underflow*/ 1984 | bb2 += j; 1985 | bd2 += j; 1986 | #ifdef Avoid_Underflow 1987 | bd2 += scale; 1988 | #endif 1989 | i = bb2 < bd2 ? bb2 : bd2; 1990 | if (i > bs2) 1991 | i = bs2; 1992 | if (i > 0) { 1993 | bb2 -= i; 1994 | bd2 -= i; 1995 | bs2 -= i; 1996 | } 1997 | if (bb5 > 0) { 1998 | bs = pow5mult(bs, bb5); 1999 | bb1 = mult(bs, bb); 2000 | Bfree(bb); 2001 | bb = bb1; 2002 | } 2003 | if (bb2 > 0) 2004 | bb = lshift(bb, bb2); 2005 | if (bd5 > 0) 2006 | bd = pow5mult(bd, bd5); 2007 | if (bd2 > 0) 2008 | bd = lshift(bd, bd2); 2009 | if (bs2 > 0) 2010 | bs = lshift(bs, bs2); 2011 | delta = diff(bb, bd); 2012 | dsign = delta->sign; 2013 | delta->sign = 0; 2014 | i = cmp(delta, bs); 2015 | #ifdef Honor_FLT_ROUNDS 2016 | if (rounding != 1) { 2017 | if (i < 0) { 2018 | /* Error is less than an ulp */ 2019 | if (!delta->x[0] && delta->wds <= 1) { 2020 | /* exact */ 2021 | #ifdef SET_INEXACT 2022 | inexact = 0; 2023 | #endif 2024 | break; 2025 | } 2026 | if (rounding) { 2027 | if (dsign) { 2028 | adj = 1.; 2029 | goto apply_adj; 2030 | } 2031 | } 2032 | else if (!dsign) { 2033 | adj = -1.; 2034 | if (!word1(rv) 2035 | && !(word0(rv) & Frac_mask)) { 2036 | y = word0(rv) & Exp_mask; 2037 | #ifdef Avoid_Underflow 2038 | if (!scale || y > 2*P*Exp_msk1) 2039 | #else 2040 | if (y) 2041 | #endif 2042 | { 2043 | delta = lshift(delta,Log2P); 2044 | if (cmp(delta, bs) <= 0) 2045 | adj = -0.5; 2046 | } 2047 | } 2048 | apply_adj: 2049 | #ifdef Avoid_Underflow 2050 | if (scale && (y = word0(rv) & Exp_mask) 2051 | <= 2*P*Exp_msk1) 2052 | word0(adj) += (2*P+1)*Exp_msk1 - y; 2053 | #else 2054 | #ifdef Sudden_Underflow 2055 | if ((word0(rv) & Exp_mask) <= 2056 | P*Exp_msk1) { 2057 | word0(rv) += P*Exp_msk1; 2058 | dval(rv) += adj*ulp(dval(rv)); 2059 | word0(rv) -= P*Exp_msk1; 2060 | } 2061 | else 2062 | #endif /*Sudden_Underflow*/ 2063 | #endif /*Avoid_Underflow*/ 2064 | dval(rv) += adj*ulp(dval(rv)); 2065 | } 2066 | break; 2067 | } 2068 | adj = ratio(delta, bs); 2069 | if (adj < 1.) 2070 | adj = 1.; 2071 | if (adj <= 0x7ffffffe) { 2072 | /* adj = rounding ? ceil(adj) : floor(adj); */ 2073 | y = adj; 2074 | if (y != adj) { 2075 | if (!((rounding>>1) ^ dsign)) 2076 | y++; 2077 | adj = y; 2078 | } 2079 | } 2080 | #ifdef Avoid_Underflow 2081 | if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) 2082 | word0(adj) += (2*P+1)*Exp_msk1 - y; 2083 | #else 2084 | #ifdef Sudden_Underflow 2085 | if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { 2086 | word0(rv) += P*Exp_msk1; 2087 | adj *= ulp(dval(rv)); 2088 | if (dsign) 2089 | dval(rv) += adj; 2090 | else 2091 | dval(rv) -= adj; 2092 | word0(rv) -= P*Exp_msk1; 2093 | goto cont; 2094 | } 2095 | #endif /*Sudden_Underflow*/ 2096 | #endif /*Avoid_Underflow*/ 2097 | adj *= ulp(dval(rv)); 2098 | if (dsign) 2099 | dval(rv) += adj; 2100 | else 2101 | dval(rv) -= adj; 2102 | goto cont; 2103 | } 2104 | #endif /*Honor_FLT_ROUNDS*/ 2105 | 2106 | if (i < 0) { 2107 | /* Error is less than half an ulp -- check for 2108 | * special case of mantissa a power of two. 2109 | */ 2110 | if (dsign || word1(rv) || word0(rv) & Bndry_mask 2111 | #ifdef IEEE_Arith 2112 | #ifdef Avoid_Underflow 2113 | || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 2114 | #else 2115 | || (word0(rv) & Exp_mask) <= Exp_msk1 2116 | #endif 2117 | #endif 2118 | ) { 2119 | #ifdef SET_INEXACT 2120 | if (!delta->x[0] && delta->wds <= 1) 2121 | inexact = 0; 2122 | #endif 2123 | break; 2124 | } 2125 | if (!delta->x[0] && delta->wds <= 1) { 2126 | /* exact result */ 2127 | #ifdef SET_INEXACT 2128 | inexact = 0; 2129 | #endif 2130 | break; 2131 | } 2132 | delta = lshift(delta,Log2P); 2133 | if (cmp(delta, bs) > 0) 2134 | goto drop_down; 2135 | break; 2136 | } 2137 | if (i == 0) { 2138 | /* exactly half-way between */ 2139 | if (dsign) { 2140 | if ((word0(rv) & Bndry_mask1) == Bndry_mask1 2141 | && word1(rv) == ( 2142 | #ifdef Avoid_Underflow 2143 | (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) 2144 | ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : 2145 | #endif 2146 | 0xffffffff)) { 2147 | /*boundary case -- increment exponent*/ 2148 | word0(rv) = (word0(rv) & Exp_mask) 2149 | + Exp_msk1 2150 | #ifdef IBM 2151 | | Exp_msk1 >> 4 2152 | #endif 2153 | ; 2154 | word1(rv) = 0; 2155 | #ifdef Avoid_Underflow 2156 | dsign = 0; 2157 | #endif 2158 | break; 2159 | } 2160 | } 2161 | else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { 2162 | drop_down: 2163 | /* boundary case -- decrement exponent */ 2164 | #ifdef Sudden_Underflow /*{{*/ 2165 | L = word0(rv) & Exp_mask; 2166 | #ifdef IBM 2167 | if (L < Exp_msk1) 2168 | #else 2169 | #ifdef Avoid_Underflow 2170 | if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) 2171 | #else 2172 | if (L <= Exp_msk1) 2173 | #endif /*Avoid_Underflow*/ 2174 | #endif /*IBM*/ 2175 | goto undfl; 2176 | L -= Exp_msk1; 2177 | #else /*Sudden_Underflow}{*/ 2178 | #ifdef Avoid_Underflow 2179 | if (scale) { 2180 | L = word0(rv) & Exp_mask; 2181 | if (L <= (2*P+1)*Exp_msk1) { 2182 | if (L > (P+2)*Exp_msk1) 2183 | /* round even ==> */ 2184 | /* accept rv */ 2185 | break; 2186 | /* rv = smallest denormal */ 2187 | goto undfl; 2188 | } 2189 | } 2190 | #endif /*Avoid_Underflow*/ 2191 | L = (word0(rv) & Exp_mask) - Exp_msk1; 2192 | #endif /*Sudden_Underflow}}*/ 2193 | word0(rv) = L | Bndry_mask1; 2194 | word1(rv) = 0xffffffff; 2195 | #ifdef IBM 2196 | goto cont; 2197 | #else 2198 | break; 2199 | #endif 2200 | } 2201 | #ifndef ROUND_BIASED 2202 | if (!(word1(rv) & LSB)) 2203 | break; 2204 | #endif 2205 | if (dsign) 2206 | dval(rv) += ulp(dval(rv)); 2207 | #ifndef ROUND_BIASED 2208 | else { 2209 | dval(rv) -= ulp(dval(rv)); 2210 | #ifndef Sudden_Underflow 2211 | if (!dval(rv)) 2212 | goto undfl; 2213 | #endif 2214 | } 2215 | #ifdef Avoid_Underflow 2216 | dsign = 1 - dsign; 2217 | #endif 2218 | #endif 2219 | break; 2220 | } 2221 | if ((aadj = ratio(delta, bs)) <= 2.) { 2222 | if (dsign) 2223 | aadj = aadj1 = 1.; 2224 | else if (word1(rv) || word0(rv) & Bndry_mask) { 2225 | #ifndef Sudden_Underflow 2226 | if (word1(rv) == Tiny1 && !word0(rv)) 2227 | goto undfl; 2228 | #endif 2229 | aadj = 1.; 2230 | aadj1 = -1.; 2231 | } 2232 | else { 2233 | /* special case -- power of FLT_RADIX to be */ 2234 | /* rounded down... */ 2235 | 2236 | if (aadj < 2./FLT_RADIX) 2237 | aadj = 1./FLT_RADIX; 2238 | else 2239 | aadj *= 0.5; 2240 | aadj1 = -aadj; 2241 | } 2242 | } 2243 | else { 2244 | aadj *= 0.5; 2245 | aadj1 = dsign ? aadj : -aadj; 2246 | #ifdef Check_FLT_ROUNDS 2247 | switch(Rounding) { 2248 | case 2: /* towards +infinity */ 2249 | aadj1 -= 0.5; 2250 | break; 2251 | case 0: /* towards 0 */ 2252 | case 3: /* towards -infinity */ 2253 | aadj1 += 0.5; 2254 | } 2255 | #else 2256 | if (Flt_Rounds == 0) 2257 | aadj1 += 0.5; 2258 | #endif /*Check_FLT_ROUNDS*/ 2259 | } 2260 | y = word0(rv) & Exp_mask; 2261 | 2262 | /* Check for overflow */ 2263 | 2264 | if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { 2265 | dval(rv0) = dval(rv); 2266 | word0(rv) -= P*Exp_msk1; 2267 | adj = aadj1 * ulp(dval(rv)); 2268 | dval(rv) += adj; 2269 | if ((word0(rv) & Exp_mask) >= 2270 | Exp_msk1*(DBL_MAX_EXP+Bias-P)) { 2271 | if (word0(rv0) == Big0 && word1(rv0) == Big1) 2272 | goto ovfl; 2273 | word0(rv) = Big0; 2274 | word1(rv) = Big1; 2275 | goto cont; 2276 | } 2277 | else 2278 | word0(rv) += P*Exp_msk1; 2279 | } 2280 | else { 2281 | #ifdef Avoid_Underflow 2282 | if (scale && y <= 2*P*Exp_msk1) { 2283 | if (aadj <= 0x7fffffff) { 2284 | if ((z = aadj) <= 0) 2285 | z = 1; 2286 | aadj = z; 2287 | aadj1 = dsign ? aadj : -aadj; 2288 | } 2289 | word0(aadj1) += (2*P+1)*Exp_msk1 - y; 2290 | } 2291 | adj = aadj1 * ulp(dval(rv)); 2292 | dval(rv) += adj; 2293 | #else 2294 | #ifdef Sudden_Underflow 2295 | if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { 2296 | dval(rv0) = dval(rv); 2297 | word0(rv) += P*Exp_msk1; 2298 | adj = aadj1 * ulp(dval(rv)); 2299 | dval(rv) += adj; 2300 | #ifdef IBM 2301 | if ((word0(rv) & Exp_mask) < P*Exp_msk1) 2302 | #else 2303 | if ((word0(rv) & Exp_mask) <= P*Exp_msk1) 2304 | #endif 2305 | { 2306 | if (word0(rv0) == Tiny0 2307 | && word1(rv0) == Tiny1) 2308 | goto undfl; 2309 | word0(rv) = Tiny0; 2310 | word1(rv) = Tiny1; 2311 | goto cont; 2312 | } 2313 | else 2314 | word0(rv) -= P*Exp_msk1; 2315 | } 2316 | else { 2317 | adj = aadj1 * ulp(dval(rv)); 2318 | dval(rv) += adj; 2319 | } 2320 | #else /*Sudden_Underflow*/ 2321 | /* Compute adj so that the IEEE rounding rules will 2322 | * correctly round rv + adj in some half-way cases. 2323 | * If rv * ulp(rv) is denormalized (i.e., 2324 | * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid 2325 | * trouble from bits lost to denormalization; 2326 | * example: 1.2e-307 . 2327 | */ 2328 | if (y <= (P-1)*Exp_msk1 && aadj > 1.) { 2329 | aadj1 = (double)(int)(aadj + 0.5); 2330 | if (!dsign) 2331 | aadj1 = -aadj1; 2332 | } 2333 | adj = aadj1 * ulp(dval(rv)); 2334 | dval(rv) += adj; 2335 | #endif /*Sudden_Underflow*/ 2336 | #endif /*Avoid_Underflow*/ 2337 | } 2338 | z = word0(rv) & Exp_mask; 2339 | #ifndef SET_INEXACT 2340 | #ifdef Avoid_Underflow 2341 | if (!scale) 2342 | #endif 2343 | if (y == z) { 2344 | /* Can we stop now? */ 2345 | L = (Long)aadj; 2346 | aadj -= L; 2347 | /* The tolerances below are conservative. */ 2348 | if (dsign || word1(rv) || word0(rv) & Bndry_mask) { 2349 | if (aadj < .4999999 || aadj > .5000001) 2350 | break; 2351 | } 2352 | else if (aadj < .4999999/FLT_RADIX) 2353 | break; 2354 | } 2355 | #endif 2356 | cont: 2357 | Bfree(bb); 2358 | Bfree(bd); 2359 | Bfree(bs); 2360 | Bfree(delta); 2361 | } 2362 | #ifdef SET_INEXACT 2363 | if (inexact) { 2364 | if (!oldinexact) { 2365 | word0(rv0) = Exp_1 + (70 << Exp_shift); 2366 | word1(rv0) = 0; 2367 | dval(rv0) += 1.; 2368 | } 2369 | } 2370 | else if (!oldinexact) 2371 | clear_inexact(); 2372 | #endif 2373 | #ifdef Avoid_Underflow 2374 | if (scale) { 2375 | word0(rv0) = Exp_1 - 2*P*Exp_msk1; 2376 | word1(rv0) = 0; 2377 | dval(rv) *= dval(rv0); 2378 | #ifndef NO_ERRNO 2379 | /* try to avoid the bug of testing an 8087 register value */ 2380 | if (word0(rv) == 0 && word1(rv) == 0) 2381 | errno = ERANGE; 2382 | #endif 2383 | } 2384 | #endif /* Avoid_Underflow */ 2385 | #ifdef SET_INEXACT 2386 | if (inexact && !(word0(rv) & Exp_mask)) { 2387 | /* set underflow bit */ 2388 | dval(rv0) = 1e-300; 2389 | dval(rv0) *= dval(rv0); 2390 | } 2391 | #endif 2392 | retfree: 2393 | Bfree(bb); 2394 | Bfree(bd); 2395 | Bfree(bs); 2396 | Bfree(bd0); 2397 | Bfree(delta); 2398 | ret: 2399 | if (se) 2400 | *se = (char *)s; 2401 | return sign ? -dval(rv) : dval(rv); 2402 | } 2403 | 2404 | static int 2405 | quorem 2406 | #ifdef KR_headers 2407 | (b, S) Bigint *b, *S; 2408 | #else 2409 | (Bigint *b, Bigint *S) 2410 | #endif 2411 | { 2412 | int n; 2413 | ULong *bx, *bxe, q, *sx, *sxe; 2414 | #ifdef ULLong 2415 | ULLong borrow, carry, y, ys; 2416 | #else 2417 | ULong borrow, carry, y, ys; 2418 | #ifdef Pack_32 2419 | ULong si, z, zs; 2420 | #endif 2421 | #endif 2422 | 2423 | n = S->wds; 2424 | #ifdef DEBUG 2425 | /*debug*/ if (b->wds > n) 2426 | /*debug*/ Bug("oversize b in quorem"); 2427 | #endif 2428 | if (b->wds < n) 2429 | return 0; 2430 | sx = S->x; 2431 | sxe = sx + --n; 2432 | bx = b->x; 2433 | bxe = bx + n; 2434 | q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ 2435 | #ifdef DEBUG 2436 | /*debug*/ if (q > 9) 2437 | /*debug*/ Bug("oversized quotient in quorem"); 2438 | #endif 2439 | if (q) { 2440 | borrow = 0; 2441 | carry = 0; 2442 | do { 2443 | #ifdef ULLong 2444 | ys = *sx++ * (ULLong)q + carry; 2445 | carry = ys >> 32; 2446 | y = *bx - (ys & FFFFFFFF) - borrow; 2447 | borrow = y >> 32 & (ULong)1; 2448 | *bx++ = y & FFFFFFFF; 2449 | #else 2450 | #ifdef Pack_32 2451 | si = *sx++; 2452 | ys = (si & 0xffff) * q + carry; 2453 | zs = (si >> 16) * q + (ys >> 16); 2454 | carry = zs >> 16; 2455 | y = (*bx & 0xffff) - (ys & 0xffff) - borrow; 2456 | borrow = (y & 0x10000) >> 16; 2457 | z = (*bx >> 16) - (zs & 0xffff) - borrow; 2458 | borrow = (z & 0x10000) >> 16; 2459 | Storeinc(bx, z, y); 2460 | #else 2461 | ys = *sx++ * q + carry; 2462 | carry = ys >> 16; 2463 | y = *bx - (ys & 0xffff) - borrow; 2464 | borrow = (y & 0x10000) >> 16; 2465 | *bx++ = y & 0xffff; 2466 | #endif 2467 | #endif 2468 | } 2469 | while(sx <= sxe); 2470 | if (!*bxe) { 2471 | bx = b->x; 2472 | while(--bxe > bx && !*bxe) 2473 | --n; 2474 | b->wds = n; 2475 | } 2476 | } 2477 | if (cmp(b, S) >= 0) { 2478 | q++; 2479 | borrow = 0; 2480 | carry = 0; 2481 | bx = b->x; 2482 | sx = S->x; 2483 | do { 2484 | #ifdef ULLong 2485 | ys = *sx++ + carry; 2486 | carry = ys >> 32; 2487 | y = *bx - (ys & FFFFFFFF) - borrow; 2488 | borrow = y >> 32 & (ULong)1; 2489 | *bx++ = y & FFFFFFFF; 2490 | #else 2491 | #ifdef Pack_32 2492 | si = *sx++; 2493 | ys = (si & 0xffff) + carry; 2494 | zs = (si >> 16) + (ys >> 16); 2495 | carry = zs >> 16; 2496 | y = (*bx & 0xffff) - (ys & 0xffff) - borrow; 2497 | borrow = (y & 0x10000) >> 16; 2498 | z = (*bx >> 16) - (zs & 0xffff) - borrow; 2499 | borrow = (z & 0x10000) >> 16; 2500 | Storeinc(bx, z, y); 2501 | #else 2502 | ys = *sx++ + carry; 2503 | carry = ys >> 16; 2504 | y = *bx - (ys & 0xffff) - borrow; 2505 | borrow = (y & 0x10000) >> 16; 2506 | *bx++ = y & 0xffff; 2507 | #endif 2508 | #endif 2509 | } 2510 | while(sx <= sxe); 2511 | bx = b->x; 2512 | bxe = bx + n; 2513 | if (!*bxe) { 2514 | while(--bxe > bx && !*bxe) 2515 | --n; 2516 | b->wds = n; 2517 | } 2518 | } 2519 | return q; 2520 | } 2521 | 2522 | #ifndef MULTIPLE_THREADS 2523 | static char *dtoa_result; 2524 | #endif 2525 | 2526 | static char * 2527 | #ifdef KR_headers 2528 | rv_alloc(i) int i; 2529 | #else 2530 | rv_alloc(int i) 2531 | #endif 2532 | { 2533 | int j, k, *r; 2534 | 2535 | j = sizeof(ULong); 2536 | for(k = 0; 2537 | sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; 2538 | j <<= 1) 2539 | k++; 2540 | r = (int*)Balloc(k); 2541 | *r = k; 2542 | return 2543 | #ifndef MULTIPLE_THREADS 2544 | dtoa_result = 2545 | #endif 2546 | (char *)(r+1); 2547 | } 2548 | 2549 | static char * 2550 | #ifdef KR_headers 2551 | nrv_alloc(s, rve, n) char *s, **rve; int n; 2552 | #else 2553 | nrv_alloc(char *s, char **rve, int n) 2554 | #endif 2555 | { 2556 | char *rv, *t; 2557 | 2558 | t = rv = rv_alloc(n); 2559 | while(*t = *s++) t++; 2560 | if (rve) 2561 | *rve = t; 2562 | return rv; 2563 | } 2564 | 2565 | /* freedtoa(s) must be used to free values s returned by dtoa 2566 | * when MULTIPLE_THREADS is #defined. It should be used in all cases, 2567 | * but for consistency with earlier versions of dtoa, it is optional 2568 | * when MULTIPLE_THREADS is not defined. 2569 | */ 2570 | 2571 | void 2572 | #ifdef KR_headers 2573 | freedtoa(s) char *s; 2574 | #else 2575 | freedtoa(char *s) 2576 | #endif 2577 | { 2578 | Bigint *b = (Bigint *)((int *)s - 1); 2579 | b->maxwds = 1 << (b->k = *(int*)b); 2580 | Bfree(b); 2581 | #ifndef MULTIPLE_THREADS 2582 | if (s == dtoa_result) 2583 | dtoa_result = 0; 2584 | #endif 2585 | } 2586 | 2587 | /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. 2588 | * 2589 | * Inspired by "How to Print Floating-Point Numbers Accurately" by 2590 | * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. 2591 | * 2592 | * Modifications: 2593 | * 1. Rather than iterating, we use a simple numeric overestimate 2594 | * to determine k = floor(log10(d)). We scale relevant 2595 | * quantities using O(log2(k)) rather than O(k) multiplications. 2596 | * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't 2597 | * try to generate digits strictly left to right. Instead, we 2598 | * compute with fewer bits and propagate the carry if necessary 2599 | * when rounding the final digit up. This is often faster. 2600 | * 3. Under the assumption that input will be rounded nearest, 2601 | * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. 2602 | * That is, we allow equality in stopping tests when the 2603 | * round-nearest rule will give the same floating-point value 2604 | * as would satisfaction of the stopping test with strict 2605 | * inequality. 2606 | * 4. We remove common factors of powers of 2 from relevant 2607 | * quantities. 2608 | * 5. When converting floating-point integers less than 1e16, 2609 | * we use floating-point arithmetic rather than resorting 2610 | * to multiple-precision integers. 2611 | * 6. When asked to produce fewer than 15 digits, we first try 2612 | * to get by with floating-point arithmetic; we resort to 2613 | * multiple-precision integer arithmetic only if we cannot 2614 | * guarantee that the floating-point calculation has given 2615 | * the correctly rounded result. For k requested digits and 2616 | * "uniformly" distributed input, the probability is 2617 | * something like 10^(k-15) that we must resort to the Long 2618 | * calculation. 2619 | */ 2620 | 2621 | char * 2622 | dtoa 2623 | #ifdef KR_headers 2624 | (d, mode, ndigits, decpt, sign, rve) 2625 | double d; int mode, ndigits, *decpt, *sign; char **rve; 2626 | #else 2627 | (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) 2628 | #endif 2629 | { 2630 | /* Arguments ndigits, decpt, sign are similar to those 2631 | of ecvt and fcvt; trailing zeros are suppressed from 2632 | the returned string. If not null, *rve is set to point 2633 | to the end of the return value. If d is +-Infinity or NaN, 2634 | then *decpt is set to 9999. 2635 | 2636 | mode: 2637 | 0 ==> shortest string that yields d when read in 2638 | and rounded to nearest. 2639 | 1 ==> like 0, but with Steele & White stopping rule; 2640 | e.g. with IEEE P754 arithmetic , mode 0 gives 2641 | 1e23 whereas mode 1 gives 9.999999999999999e22. 2642 | 2 ==> max(1,ndigits) significant digits. This gives a 2643 | return value similar to that of ecvt, except 2644 | that trailing zeros are suppressed. 2645 | 3 ==> through ndigits past the decimal point. This 2646 | gives a return value similar to that from fcvt, 2647 | except that trailing zeros are suppressed, and 2648 | ndigits can be negative. 2649 | 4,5 ==> similar to 2 and 3, respectively, but (in 2650 | round-nearest mode) with the tests of mode 0 to 2651 | possibly return a shorter string that rounds to d. 2652 | With IEEE arithmetic and compilation with 2653 | -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same 2654 | as modes 2 and 3 when FLT_ROUNDS != 1. 2655 | 6-9 ==> Debugging modes similar to mode - 4: don't try 2656 | fast floating-point estimate (if applicable). 2657 | 2658 | Values of mode other than 0-9 are treated as mode 0. 2659 | 2660 | Sufficient space is allocated to the return value 2661 | to hold the suppressed trailing zeros. 2662 | */ 2663 | 2664 | int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, 2665 | j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, 2666 | spec_case, try_quick; 2667 | Long L; 2668 | #ifndef Sudden_Underflow 2669 | int denorm; 2670 | ULong x; 2671 | #endif 2672 | Bigint *b, *b1, *delta, *mlo, *mhi, *S; 2673 | double d2, ds, eps; 2674 | char *s, *s0; 2675 | #ifdef Honor_FLT_ROUNDS 2676 | int rounding; 2677 | #endif 2678 | #ifdef SET_INEXACT 2679 | int inexact, oldinexact; 2680 | #endif 2681 | 2682 | #ifndef MULTIPLE_THREADS 2683 | if (dtoa_result) { 2684 | freedtoa(dtoa_result); 2685 | dtoa_result = 0; 2686 | } 2687 | #endif 2688 | 2689 | if (word0(d) & Sign_bit) { 2690 | /* set sign for everything, including 0's and NaNs */ 2691 | *sign = 1; 2692 | word0(d) &= ~Sign_bit; /* clear sign bit */ 2693 | } 2694 | else 2695 | *sign = 0; 2696 | 2697 | #if defined(IEEE_Arith) + defined(VAX) 2698 | #ifdef IEEE_Arith 2699 | if ((word0(d) & Exp_mask) == Exp_mask) 2700 | #else 2701 | if (word0(d) == 0x8000) 2702 | #endif 2703 | { 2704 | /* Infinity or NaN */ 2705 | *decpt = 9999; 2706 | #ifdef IEEE_Arith 2707 | if (!word1(d) && !(word0(d) & 0xfffff)) 2708 | return nrv_alloc("Infinity", rve, 8); 2709 | #endif 2710 | return nrv_alloc("NaN", rve, 3); 2711 | } 2712 | #endif 2713 | #ifdef IBM 2714 | dval(d) += 0; /* normalize */ 2715 | #endif 2716 | if (!dval(d)) { 2717 | *decpt = 1; 2718 | return nrv_alloc("0", rve, 1); 2719 | } 2720 | 2721 | #ifdef SET_INEXACT 2722 | try_quick = oldinexact = get_inexact(); 2723 | inexact = 1; 2724 | #endif 2725 | #ifdef Honor_FLT_ROUNDS 2726 | if ((rounding = Flt_Rounds) >= 2) { 2727 | if (*sign) 2728 | rounding = rounding == 2 ? 0 : 2; 2729 | else 2730 | if (rounding != 2) 2731 | rounding = 0; 2732 | } 2733 | #endif 2734 | 2735 | b = d2b(dval(d), &be, &bbits); 2736 | #ifdef Sudden_Underflow 2737 | i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); 2738 | #else 2739 | if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { 2740 | #endif 2741 | dval(d2) = dval(d); 2742 | word0(d2) &= Frac_mask1; 2743 | word0(d2) |= Exp_11; 2744 | #ifdef IBM 2745 | if (j = 11 - hi0bits(word0(d2) & Frac_mask)) 2746 | dval(d2) /= 1 << j; 2747 | #endif 2748 | 2749 | /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 2750 | * log10(x) = log(x) / log(10) 2751 | * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) 2752 | * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) 2753 | * 2754 | * This suggests computing an approximation k to log10(d) by 2755 | * 2756 | * k = (i - Bias)*0.301029995663981 2757 | * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); 2758 | * 2759 | * We want k to be too large rather than too small. 2760 | * The error in the first-order Taylor series approximation 2761 | * is in our favor, so we just round up the constant enough 2762 | * to compensate for any error in the multiplication of 2763 | * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, 2764 | * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, 2765 | * adding 1e-13 to the constant term more than suffices. 2766 | * Hence we adjust the constant term to 0.1760912590558. 2767 | * (We could get a more accurate k by invoking log10, 2768 | * but this is probably not worthwhile.) 2769 | */ 2770 | 2771 | i -= Bias; 2772 | #ifdef IBM 2773 | i <<= 2; 2774 | i += j; 2775 | #endif 2776 | #ifndef Sudden_Underflow 2777 | denorm = 0; 2778 | } 2779 | else { 2780 | /* d is denormalized */ 2781 | 2782 | i = bbits + be + (Bias + (P-1) - 1); 2783 | x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 2784 | : word1(d) << 32 - i; 2785 | dval(d2) = x; 2786 | word0(d2) -= 31*Exp_msk1; /* adjust exponent */ 2787 | i -= (Bias + (P-1) - 1) + 1; 2788 | denorm = 1; 2789 | } 2790 | #endif 2791 | ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; 2792 | k = (int)ds; 2793 | if (ds < 0. && ds != k) 2794 | k--; /* want k = floor(ds) */ 2795 | k_check = 1; 2796 | if (k >= 0 && k <= Ten_pmax) { 2797 | if (dval(d) < tens[k]) 2798 | k--; 2799 | k_check = 0; 2800 | } 2801 | j = bbits - i - 1; 2802 | if (j >= 0) { 2803 | b2 = 0; 2804 | s2 = j; 2805 | } 2806 | else { 2807 | b2 = -j; 2808 | s2 = 0; 2809 | } 2810 | if (k >= 0) { 2811 | b5 = 0; 2812 | s5 = k; 2813 | s2 += k; 2814 | } 2815 | else { 2816 | b2 -= k; 2817 | b5 = -k; 2818 | s5 = 0; 2819 | } 2820 | if (mode < 0 || mode > 9) 2821 | mode = 0; 2822 | 2823 | #ifndef SET_INEXACT 2824 | #ifdef Check_FLT_ROUNDS 2825 | try_quick = Rounding == 1; 2826 | #else 2827 | try_quick = 1; 2828 | #endif 2829 | #endif /*SET_INEXACT*/ 2830 | 2831 | if (mode > 5) { 2832 | mode -= 4; 2833 | try_quick = 0; 2834 | } 2835 | leftright = 1; 2836 | switch(mode) { 2837 | case 0: 2838 | case 1: 2839 | ilim = ilim1 = -1; 2840 | i = 18; 2841 | ndigits = 0; 2842 | break; 2843 | case 2: 2844 | leftright = 0; 2845 | /* no break */ 2846 | case 4: 2847 | if (ndigits <= 0) 2848 | ndigits = 1; 2849 | ilim = ilim1 = i = ndigits; 2850 | break; 2851 | case 3: 2852 | leftright = 0; 2853 | /* no break */ 2854 | case 5: 2855 | i = ndigits + k + 1; 2856 | ilim = i; 2857 | ilim1 = i - 1; 2858 | if (i <= 0) 2859 | i = 1; 2860 | } 2861 | s = s0 = rv_alloc(i); 2862 | 2863 | #ifdef Honor_FLT_ROUNDS 2864 | if (mode > 1 && rounding != 1) 2865 | leftright = 0; 2866 | #endif 2867 | 2868 | if (ilim >= 0 && ilim <= Quick_max && try_quick) { 2869 | 2870 | /* Try to get by with floating-point arithmetic. */ 2871 | 2872 | i = 0; 2873 | dval(d2) = dval(d); 2874 | k0 = k; 2875 | ilim0 = ilim; 2876 | ieps = 2; /* conservative */ 2877 | if (k > 0) { 2878 | ds = tens[k&0xf]; 2879 | j = k >> 4; 2880 | if (j & Bletch) { 2881 | /* prevent overflows */ 2882 | j &= Bletch - 1; 2883 | dval(d) /= bigtens[n_bigtens-1]; 2884 | ieps++; 2885 | } 2886 | for(; j; j >>= 1, i++) 2887 | if (j & 1) { 2888 | ieps++; 2889 | ds *= bigtens[i]; 2890 | } 2891 | dval(d) /= ds; 2892 | } 2893 | else if (j1 = -k) { 2894 | dval(d) *= tens[j1 & 0xf]; 2895 | for(j = j1 >> 4; j; j >>= 1, i++) 2896 | if (j & 1) { 2897 | ieps++; 2898 | dval(d) *= bigtens[i]; 2899 | } 2900 | } 2901 | if (k_check && dval(d) < 1. && ilim > 0) { 2902 | if (ilim1 <= 0) 2903 | goto fast_failed; 2904 | ilim = ilim1; 2905 | k--; 2906 | dval(d) *= 10.; 2907 | ieps++; 2908 | } 2909 | dval(eps) = ieps*dval(d) + 7.; 2910 | word0(eps) -= (P-1)*Exp_msk1; 2911 | if (ilim == 0) { 2912 | S = mhi = 0; 2913 | dval(d) -= 5.; 2914 | if (dval(d) > dval(eps)) 2915 | goto one_digit; 2916 | if (dval(d) < -dval(eps)) 2917 | goto no_digits; 2918 | goto fast_failed; 2919 | } 2920 | #ifndef No_leftright 2921 | if (leftright) { 2922 | /* Use Steele & White method of only 2923 | * generating digits needed. 2924 | */ 2925 | dval(eps) = 0.5/tens[ilim-1] - dval(eps); 2926 | for(i = 0;;) { 2927 | L = dval(d); 2928 | dval(d) -= L; 2929 | *s++ = '0' + (int)L; 2930 | if (dval(d) < dval(eps)) 2931 | goto ret1; 2932 | if (1. - dval(d) < dval(eps)) 2933 | goto bump_up; 2934 | if (++i >= ilim) 2935 | break; 2936 | dval(eps) *= 10.; 2937 | dval(d) *= 10.; 2938 | } 2939 | } 2940 | else { 2941 | #endif 2942 | /* Generate ilim digits, then fix them up. */ 2943 | dval(eps) *= tens[ilim-1]; 2944 | for(i = 1;; i++, dval(d) *= 10.) { 2945 | L = (Long)(dval(d)); 2946 | if (!(dval(d) -= L)) 2947 | ilim = i; 2948 | *s++ = '0' + (int)L; 2949 | if (i == ilim) { 2950 | if (dval(d) > 0.5 + dval(eps)) 2951 | goto bump_up; 2952 | else if (dval(d) < 0.5 - dval(eps)) { 2953 | while(*--s == '0'); 2954 | s++; 2955 | goto ret1; 2956 | } 2957 | break; 2958 | } 2959 | } 2960 | #ifndef No_leftright 2961 | } 2962 | #endif 2963 | fast_failed: 2964 | s = s0; 2965 | dval(d) = dval(d2); 2966 | k = k0; 2967 | ilim = ilim0; 2968 | } 2969 | 2970 | /* Do we have a "small" integer? */ 2971 | 2972 | if (be >= 0 && k <= Int_max) { 2973 | /* Yes. */ 2974 | ds = tens[k]; 2975 | if (ndigits < 0 && ilim <= 0) { 2976 | S = mhi = 0; 2977 | if (ilim < 0 || dval(d) <= 5*ds) 2978 | goto no_digits; 2979 | goto one_digit; 2980 | } 2981 | for(i = 1;; i++, dval(d) *= 10.) { 2982 | L = (Long)(dval(d) / ds); 2983 | dval(d) -= L*ds; 2984 | #ifdef Check_FLT_ROUNDS 2985 | /* If FLT_ROUNDS == 2, L will usually be high by 1 */ 2986 | if (dval(d) < 0) { 2987 | L--; 2988 | dval(d) += ds; 2989 | } 2990 | #endif 2991 | *s++ = '0' + (int)L; 2992 | if (!dval(d)) { 2993 | #ifdef SET_INEXACT 2994 | inexact = 0; 2995 | #endif 2996 | break; 2997 | } 2998 | if (i == ilim) { 2999 | #ifdef Honor_FLT_ROUNDS 3000 | if (mode > 1) 3001 | switch(rounding) { 3002 | case 0: goto ret1; 3003 | case 2: goto bump_up; 3004 | } 3005 | #endif 3006 | dval(d) += dval(d); 3007 | if (dval(d) > ds || dval(d) == ds && L & 1) { 3008 | bump_up: 3009 | while(*--s == '9') 3010 | if (s == s0) { 3011 | k++; 3012 | *s = '0'; 3013 | break; 3014 | } 3015 | ++*s++; 3016 | } 3017 | break; 3018 | } 3019 | } 3020 | goto ret1; 3021 | } 3022 | 3023 | m2 = b2; 3024 | m5 = b5; 3025 | mhi = mlo = 0; 3026 | if (leftright) { 3027 | i = 3028 | #ifndef Sudden_Underflow 3029 | denorm ? be + (Bias + (P-1) - 1 + 1) : 3030 | #endif 3031 | #ifdef IBM 3032 | 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); 3033 | #else 3034 | 1 + P - bbits; 3035 | #endif 3036 | b2 += i; 3037 | s2 += i; 3038 | mhi = i2b(1); 3039 | } 3040 | if (m2 > 0 && s2 > 0) { 3041 | i = m2 < s2 ? m2 : s2; 3042 | b2 -= i; 3043 | m2 -= i; 3044 | s2 -= i; 3045 | } 3046 | if (b5 > 0) { 3047 | if (leftright) { 3048 | if (m5 > 0) { 3049 | mhi = pow5mult(mhi, m5); 3050 | b1 = mult(mhi, b); 3051 | Bfree(b); 3052 | b = b1; 3053 | } 3054 | if (j = b5 - m5) 3055 | b = pow5mult(b, j); 3056 | } 3057 | else 3058 | b = pow5mult(b, b5); 3059 | } 3060 | S = i2b(1); 3061 | if (s5 > 0) 3062 | S = pow5mult(S, s5); 3063 | 3064 | /* Check for special case that d is a normalized power of 2. */ 3065 | 3066 | spec_case = 0; 3067 | if ((mode < 2 || leftright) 3068 | #ifdef Honor_FLT_ROUNDS 3069 | && rounding == 1 3070 | #endif 3071 | ) { 3072 | if (!word1(d) && !(word0(d) & Bndry_mask) 3073 | #ifndef Sudden_Underflow 3074 | && word0(d) & (Exp_mask & ~Exp_msk1) 3075 | #endif 3076 | ) { 3077 | /* The special case */ 3078 | b2 += Log2P; 3079 | s2 += Log2P; 3080 | spec_case = 1; 3081 | } 3082 | } 3083 | 3084 | /* Arrange for convenient computation of quotients: 3085 | * shift left if necessary so divisor has 4 leading 0 bits. 3086 | * 3087 | * Perhaps we should just compute leading 28 bits of S once 3088 | * and for all and pass them and a shift to quorem, so it 3089 | * can do shifts and ors to compute the numerator for q. 3090 | */ 3091 | #ifdef Pack_32 3092 | if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) 3093 | i = 32 - i; 3094 | #else 3095 | if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) 3096 | i = 16 - i; 3097 | #endif 3098 | if (i > 4) { 3099 | i -= 4; 3100 | b2 += i; 3101 | m2 += i; 3102 | s2 += i; 3103 | } 3104 | else if (i < 4) { 3105 | i += 28; 3106 | b2 += i; 3107 | m2 += i; 3108 | s2 += i; 3109 | } 3110 | if (b2 > 0) 3111 | b = lshift(b, b2); 3112 | if (s2 > 0) 3113 | S = lshift(S, s2); 3114 | if (k_check) { 3115 | if (cmp(b,S) < 0) { 3116 | k--; 3117 | b = multadd(b, 10, 0); /* we botched the k estimate */ 3118 | if (leftright) 3119 | mhi = multadd(mhi, 10, 0); 3120 | ilim = ilim1; 3121 | } 3122 | } 3123 | if (ilim <= 0 && (mode == 3 || mode == 5)) { 3124 | if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { 3125 | /* no digits, fcvt style */ 3126 | no_digits: 3127 | k = -1 - ndigits; 3128 | goto ret; 3129 | } 3130 | one_digit: 3131 | *s++ = '1'; 3132 | k++; 3133 | goto ret; 3134 | } 3135 | if (leftright) { 3136 | if (m2 > 0) 3137 | mhi = lshift(mhi, m2); 3138 | 3139 | /* Compute mlo -- check for special case 3140 | * that d is a normalized power of 2. 3141 | */ 3142 | 3143 | mlo = mhi; 3144 | if (spec_case) { 3145 | mhi = Balloc(mhi->k); 3146 | Bcopy(mhi, mlo); 3147 | mhi = lshift(mhi, Log2P); 3148 | } 3149 | 3150 | for(i = 1;;i++) { 3151 | dig = quorem(b,S) + '0'; 3152 | /* Do we yet have the shortest decimal string 3153 | * that will round to d? 3154 | */ 3155 | j = cmp(b, mlo); 3156 | delta = diff(S, mhi); 3157 | j1 = delta->sign ? 1 : cmp(b, delta); 3158 | Bfree(delta); 3159 | #ifndef ROUND_BIASED 3160 | if (j1 == 0 && mode != 1 && !(word1(d) & 1) 3161 | #ifdef Honor_FLT_ROUNDS 3162 | && rounding >= 1 3163 | #endif 3164 | ) { 3165 | if (dig == '9') 3166 | goto round_9_up; 3167 | if (j > 0) 3168 | dig++; 3169 | #ifdef SET_INEXACT 3170 | else if (!b->x[0] && b->wds <= 1) 3171 | inexact = 0; 3172 | #endif 3173 | *s++ = dig; 3174 | goto ret; 3175 | } 3176 | #endif 3177 | if (j < 0 || j == 0 && mode != 1 3178 | #ifndef ROUND_BIASED 3179 | && !(word1(d) & 1) 3180 | #endif 3181 | ) { 3182 | if (!b->x[0] && b->wds <= 1) { 3183 | #ifdef SET_INEXACT 3184 | inexact = 0; 3185 | #endif 3186 | goto accept_dig; 3187 | } 3188 | #ifdef Honor_FLT_ROUNDS 3189 | if (mode > 1) 3190 | switch(rounding) { 3191 | case 0: goto accept_dig; 3192 | case 2: goto keep_dig; 3193 | } 3194 | #endif /*Honor_FLT_ROUNDS*/ 3195 | if (j1 > 0) { 3196 | b = lshift(b, 1); 3197 | j1 = cmp(b, S); 3198 | if ((j1 > 0 || j1 == 0 && dig & 1) 3199 | && dig++ == '9') 3200 | goto round_9_up; 3201 | } 3202 | accept_dig: 3203 | *s++ = dig; 3204 | goto ret; 3205 | } 3206 | if (j1 > 0) { 3207 | #ifdef Honor_FLT_ROUNDS 3208 | if (!rounding) 3209 | goto accept_dig; 3210 | #endif 3211 | if (dig == '9') { /* possible if i == 1 */ 3212 | round_9_up: 3213 | *s++ = '9'; 3214 | goto roundoff; 3215 | } 3216 | *s++ = dig + 1; 3217 | goto ret; 3218 | } 3219 | #ifdef Honor_FLT_ROUNDS 3220 | keep_dig: 3221 | #endif 3222 | *s++ = dig; 3223 | if (i == ilim) 3224 | break; 3225 | b = multadd(b, 10, 0); 3226 | if (mlo == mhi) 3227 | mlo = mhi = multadd(mhi, 10, 0); 3228 | else { 3229 | mlo = multadd(mlo, 10, 0); 3230 | mhi = multadd(mhi, 10, 0); 3231 | } 3232 | } 3233 | } 3234 | else 3235 | for(i = 1;; i++) { 3236 | *s++ = dig = quorem(b,S) + '0'; 3237 | if (!b->x[0] && b->wds <= 1) { 3238 | #ifdef SET_INEXACT 3239 | inexact = 0; 3240 | #endif 3241 | goto ret; 3242 | } 3243 | if (i >= ilim) 3244 | break; 3245 | b = multadd(b, 10, 0); 3246 | } 3247 | 3248 | /* Round off last digit */ 3249 | 3250 | #ifdef Honor_FLT_ROUNDS 3251 | switch(rounding) { 3252 | case 0: goto trimzeros; 3253 | case 2: goto roundoff; 3254 | } 3255 | #endif 3256 | b = lshift(b, 1); 3257 | j = cmp(b, S); 3258 | if (j > 0 || j == 0 && dig & 1) { 3259 | roundoff: 3260 | while(*--s == '9') 3261 | if (s == s0) { 3262 | k++; 3263 | *s++ = '1'; 3264 | goto ret; 3265 | } 3266 | ++*s++; 3267 | } 3268 | else { 3269 | trimzeros: 3270 | while(*--s == '0'); 3271 | s++; 3272 | } 3273 | ret: 3274 | Bfree(S); 3275 | if (mhi) { 3276 | if (mlo && mlo != mhi) 3277 | Bfree(mlo); 3278 | Bfree(mhi); 3279 | } 3280 | ret1: 3281 | #ifdef SET_INEXACT 3282 | if (inexact) { 3283 | if (!oldinexact) { 3284 | word0(d) = Exp_1 + (70 << Exp_shift); 3285 | word1(d) = 0; 3286 | dval(d) += 1.; 3287 | } 3288 | } 3289 | else if (!oldinexact) 3290 | clear_inexact(); 3291 | #endif 3292 | Bfree(b); 3293 | *s = 0; 3294 | *decpt = k + 1; 3295 | if (rve) 3296 | *rve = s; 3297 | return s0; 3298 | } 3299 | #ifdef __cplusplus 3300 | } 3301 | #endif 3302 | --------------------------------------------------------------------------------