diff options
48 files changed, 1532 insertions, 348 deletions
@@ -1,6 +1,14 @@ For version 0.16.*. -> Starting to remove builtin cpp from bcc-cc1, beware. +> Sorry forgot to flip this back: perror and strerror are back to using + the /lib/liberror.txt file for all 8086 Elks modes. Only i386 has the + file linked. Elksemu now traps accesses to this file and substitutes + a fake. + +> Added vararg macros to new preprocessor. + +> Builtin CPP removed for __BCC__ compile, bcc-cc1 fit in 16bit but + crashes. Thirty two bit works fine, gcc or bcc. (almost any 32bit.) > Added __BCC_VERSION__ macro, defined by bcc.c contains hex version no. @@ -16,13 +24,13 @@ For version 0.16.*. Native paths. As86_encap moved to LIBDIR. > I've altered 'perror' and 'strerror' to be normal when compiled for - everything except libc_f.a. Only that library it look for the - liberror.txt file and it now looks in "/lib/liberror.txt". + everything except libc_f.a. Only with that library will it look for the + liberror.txt file and it now looks in "/lib/liberror.txt" only. This means there's no need to install it anywhere except ELKS itself. > Change -Mg option to use uclibc as glibc2 seems to have stopped working. -> ar.c switch to usnig strerror. +> ar.c switch to using strerror. > Move elksemu, it's used like a shared library but is best treated like an emulator so it's now installed in DISTBIN. Also on Linux-386 it's @@ -2,10 +2,10 @@ # This file is part of the Linux-8086 Development environment and is # distributed under the GNU General Public License. -VERSION=0.16.16 +VERSION=0.16.17 TARGETS=install clean other \ - bcc unproto copt as86 ld86 elksemu \ + bcc86 unproto copt as86 ld86 elksemu \ install-all install-bcc install-emu install-lib \ install-lib2 install-ln install-man install-other \ all-libs alt-libs library lib-386 lib-bsd lib-dos lib-fast lib-stand \ @@ -59,10 +59,10 @@ make.fil: ifdef makefile.in @rm -f tmp.mak tmp.sed ifdef: ifdef.o - $(CC) $(LDFLAGS) -o ifdef ifdef.o + $(CC) $(IFDEFARCH) $(LDFLAGS) -o ifdef ifdef.o ifdef.o: ifdef.c - $(CC) $(CFLAGS) $(IFDEFFLAGS) -c ifdef.c + $(CC) $(IFDEFARCH) $(CFLAGS) $(IFDEFFLAGS) -c ifdef.c uninstall: @echo 'Sorry, no go; it was just wrong.' diff --git a/as/readsrc.c b/as/readsrc.c index df69756..1267419 100644 --- a/as/readsrc.c +++ b/as/readsrc.c @@ -50,7 +50,7 @@ PRIVATE struct get_s hid_getstak[MAXGET]; /* GET stack */ PRIVATE struct get_s *getstak; /* ptr */ #if BIGBUFFER == 1 -PRIVATE char *mem_start, *mem_end; +PRIVATE char *mem_start = 0, *mem_end; #endif PRIVATE char hid_linebuf[LINLEN]; /* line buffer */ @@ -109,6 +109,9 @@ char *name; #if BIGBUFFER == 1 if( mem_start == 0 ) { + size_t memsize = 0; + int cc; + if(fd) { struct stat st; @@ -120,36 +123,34 @@ char *name; goto cant_do_this; } } - if( filelength > 0 ) - { - if( (mem_start = malloc(filelength+2)) == 0 ) + + if (filelength > 0) { + if( (mem_start = malloc(filelength+4)) == 0 ) { mem_end = mem_start = "\n\n"; goto cant_do_this; - } + } + memsize = filelength; + filelength = read(fd, mem_start, filelength); - } - else - { - size_t memsize = 0; - int cc; + } else filelength = 0; - for(;;) - { - if( filelength >= memsize ) - { - if (memsize > 16000) - mem_start = asrealloc(mem_start, (memsize+=16384)+4); - else - mem_start = asrealloc(mem_start, (memsize+=memsize+32)+4); - } - cc = read(fd, mem_start+filelength, - (size_t)(memsize-filelength)); - if( cc <= 0 ) break; - filelength+=cc; - } + for(;;) + { + if( filelength >= memsize ) + { + if (memsize > 16000) + mem_start = asrealloc(mem_start, (memsize+=16384)+4); + else + mem_start = asrealloc(mem_start, (memsize+=memsize+32)+4); + } + cc = read(fd, mem_start+filelength, + (size_t)(memsize-filelength)); + if( cc <= 0 ) break; + filelength+=cc; } + *(mem_end=mem_start+filelength) = '\n'; mem_end[1] = '\0'; @@ -22,7 +22,7 @@ EXTERN char regs[]; EXTERN char typesizes[]; #endif -#ifdef DEBUG +#ifdef DEBUG_HASH unsigned nhash; unsigned nlookup; unsigned nsym; @@ -100,7 +100,7 @@ PUBLIC struct sym_s *lookup() register struct sym_s *symptr; register unsigned hashval; register unsigned length; -#ifdef DEBUG +#ifdef DEBUG_HASH int tries; ++nlookup; @@ -139,14 +139,14 @@ PUBLIC struct sym_s *lookup() { do { -#ifdef DEBUG +#ifdef DEBUG_HASH if (tries != 0) --nx[tries]; ++tries; if (tries < sizeof nx / sizeof nx[0]) ++nx[tries]; if (tries >= 5) - printchain(hashptr - spt) + printchain(hashptr - spt); #endif if ((unsigned char) length != symptr->length) continue; @@ -168,7 +168,7 @@ PUBLIC struct sym_s *lookup() } if (!ifflag) return NUL_PTR; -#ifdef DEBUG +#ifdef DEBUG_HASH ++nsym; if (hashptr >= spt && hashptr < spt + SPTSIZ) ++nhash; @@ -183,7 +183,7 @@ PUBLIC struct sym_s *lookup() return symptr; } -#ifdef DEBUG +#ifdef DEBUG_HASH static void printchain(hashval) unsigned hashval; @@ -200,7 +200,7 @@ unsigned hashval; PUBLIC void statistics() { -#ifdef DEBUG +#ifdef DEBUG_HASH int i; int weight; @@ -214,6 +214,6 @@ PUBLIC void statistics() weight += nx[i] * i; } printf("\n"); - printf("weight = %d%d\n", w); + printf("weight = %d%d\n", weight); #endif } diff --git a/bcc/Makefile b/bcc/Makefile index 169eae8..ae59d25 100644 --- a/bcc/Makefile +++ b/bcc/Makefile @@ -13,10 +13,10 @@ BCCDEFS =-DLOCALPREFIX=$(PREFIX) -DBINDIR=$(BINDIR) -DDEFARCH=0 BCFLAGS=$(ANSI) $(CFLAGS) $(LDFLAGS) -OBJS = bcc-cc1.o codefrag.o debug.o declare.o express.o exptree.o floatop.o \ +OBJS = bcc-cc1.o codefrag.o dbnode.o declare.o express.o exptree.o floatop.o \ function.o gencode.o genloads.o glogcode.o hardop.o input.o label.o \ loadexp.o longop.o output.o preproc.o preserve.o scan.o softop.o \ - state.o table.o type.o assign.o hashcmd.o + state.o table.o type.o assign.o hashcmd.o debug.o dbprintf.o all: bcc-cc1 bcc @@ -41,6 +41,12 @@ ccc: bcc.c bcc-cc1: $(OBJS) $(CC) $(BCCARCH) $(LDFLAGS) $(OBJS) -o bcc-cc1 +debug.o: debug.c debug.h + $(CC) $(ANSI) $(BCCARCH) $(CFLAGS) -c debug.c + +dbprintf.o: dbprintf.c + $(CC) $(ANSI) $(BCCARCH) $(CFLAGS) -c dbprintf.c + clean realclean: rm -f bcc bcc-cc1 ncc bcc09 ccc bcc.o $(OBJS) diff --git a/bcc/bcc-cc1.c b/bcc/bcc-cc1.c index 7ba8be0..00557cd 100644 --- a/bcc/bcc-cc1.c +++ b/bcc/bcc-cc1.c @@ -8,6 +8,7 @@ PUBLIC int main(argc, argv) int argc; char **argv; { + debug(1, "Start"); growheap(0); /* init order is important */ syminit(); etreeinit(); @@ -102,7 +102,7 @@ struct opt_list { } * options; int opt_v, opt_V, opt_e, opt_x, opt_I, opt_L, opt_W, opt_i, - opt_O, opt_M; + opt_O, opt_M, opt_f; #ifdef DEFARCH int opt_arch = (DEFARCH != 0); @@ -951,6 +951,7 @@ char ** argv; case 'I': opt_I++; break; case 'L': opt_L++; break; case 'i': opt_i++; break; + case 'f': opt_f++; break; case 'W': opt_W++; break; @@ -959,7 +960,6 @@ char ** argv; case 'w': /*IGNORED*/ break; case 'g': /*IGNORED*/ break; - case 'f': /*IGNORED*/ break; case 'p': /*IGNORED*/ break; default: @@ -1080,6 +1080,14 @@ char ** argv; append_option("-O", 'a'); } + if (opt_arch == 0) { + if (opt_f) { + /* append_option("--enable-floats", 'c'); */ + libc = catstr(libc, "+f"); + } else + append_option("-D__HAS_NO_FLOATS__", 'p'); + } + if (opt_arch == 1) libdir_suffix = "/i386"; if (opt_arch == 4) libdir_suffix = "/m09"; @@ -1099,7 +1107,7 @@ char * path1, * path2, * path3; { char * newstr; int l; - newstr = xalloc(strlen(path1)+strlen(path1)+strlen(path3) + newstr = xalloc(strlen(path1)+strlen(path2)+strlen(path3) + strlen(prefix_path)+2); strcpy(newstr, prefix_path); @@ -1232,9 +1240,14 @@ int size; void Usage() { #ifdef VERSION +#ifdef __AS386_16__ + if (opt_v) + fprintf(stderr, "%s: version %s (16bit)\n", progname, VERSION); +#else if (opt_v) fprintf(stderr, "%s: version %s\n", progname, VERSION); #endif +#endif fprintf(stderr, "Usage: %s [-ansi] [-options] [-o output] file [files].\n", progname); exit(1); diff --git a/bcc/const.h b/bcc/const.h index 1c44e19..c06aca0 100644 --- a/bcc/const.h +++ b/bcc/const.h @@ -8,6 +8,8 @@ #include <malloc.h> #endif +#include "debug.h" + /* switches for code generation */ #if !defined(I8088) && !defined(MC6809) @@ -23,9 +25,12 @@ #ifndef VERY_SMALL_MEMORY #define SELFTYPECHECK /* check calculated type = runtime type */ -#define DEBUG /* generate compiler-debugging code */ +#define DBNODE /* generate compiler node debugging code */ #define OPTIMISE /* include optimisation code */ -#define BUILTIN_CPP +#endif + +#ifndef __BCC__ +#define BUILTIN_CPP /* Remove the built in C preprocessor */ #endif #ifdef I8088 @@ -34,20 +39,21 @@ * since assembler has only 1 data seg */ # define DYNAMIC_LONG_ORDER 1 /* long word order spec. at compile time */ -#ifdef VERY_SMALL_MEMORY - +#ifdef __HAS_NO_FLOATS__ /* Humm, now this is nasty :-) */ #define float no_hope #define double no_hope #define atof atol #define NOFLOAT typedef long no_hope; +#endif -#else +#ifndef VERY_SMALL_MEMORY #ifndef NO_I80386 # define I80386 /* Little BCC doesn't need 386 */ #endif #endif + #endif #ifdef MC6809 @@ -85,3 +91,6 @@ typedef long no_hope; #define FORWARD static #define PRIVATE static #define PUBLIC + +/* #define C_CODE * Don't use assembler outstr() function. */ + diff --git a/bcc/dbnode.c b/bcc/dbnode.c new file mode 100644 index 0000000..e4a944c --- /dev/null +++ b/bcc/dbnode.c @@ -0,0 +1,200 @@ +/* dbnode.c - print debug messages for operators for bcc */ + +/* Copyright (C) 1992 Bruce Evans */ + +#include "bcc.h" + +#ifdef DBNODE +#include "gencode.h" +#include "reg.h" +#include "sc.h" +#include "scan.h" +#include "type.h" + +PRIVATE char *opname[LASTOP - FIRSTOP + 1] = /* operator names */ +{ /* order must agree with op.h */ + "cond?", + "or", + "eor", + "and", + "gt", "lt", + "add", + "div", "mod", + "lognot", "not", + "strucelt", "strucptr", + "eq", + "addab", "andab", "divab", "eorab", "modab", "mulab", "orab", + "slab", "srab", "subab", + "comma", + "cond:", + "logor", + "logand", + "logeq", + "ne", + "ge", "le", + "sl", "sr", + "sub", + "mul", + "address", "cast", "indirect", "neg", + "predec", "preinc", "postdec", "postinc", + "func", "list", "rootlist", + "leaf", + "ptraddab", "ptradd", "ptrsub", +}; + +FORWARD void outindchars P((int byte, indn_pt count)); + +PUBLIC void dbitem(item) +struct symstruct *item; +{ + dbtype(item->type); + if (item->storage == NOSTORAGE) + { + outbyte(' '); + outstr(item->name.namep + 2); + outstr(" (offset "); + outshex(item->offset.offi); + outbyte(')'); + return; + } + if (item->storage == LOCAL) + { + outbyte(' '); + if (item->flags == TEMP) + outstr("(temp)"); + else + outstr(item->name.namep); + } + outstr(" = "); + outindchars('[', item->indcount); + switch (item->storage) + { + case CONSTANT: + outstr("const "); + if (item->type->scalar & RSCALAR) + outstr("(whatever)"); + else if (item->type->scalar & UNSIGNED) + outuvalue((uvalue_t) item->offset.offv); + else + outvalue(item->offset.offv); + break; + case BREG: + case DREG: + case INDREG0: + case INDREG1: + case INDREG2: +#ifdef DATREG1 + case DATREG1: +#endif +#ifdef DATREG2 + case DATREG2: +#endif + outregname(item->storage); + if (item->level == OFFKLUDGELEVEL) + { + outplus(); + if (item->flags & LABELLED) + outlabel(item->name.label); + else + outccname(item->name.namep); + } + break; + case LOCAL: + outbyte('S'); + if (sp <= 0) + outplus(); + outshex(-sp); + break; + case GLOBAL: + if (item->flags & LABELLED) + outlabel(item->name.label); + else + outstr(item->name.namep); + break; + default: + outstr("bad storage ("); + outhex((uoffset_T) item->storage); + outbyte(')'); + outstr(" offset "); + } + if (item->storage != CONSTANT) + { + if (item->offset.offi >= 0) + outplus(); + outshex(item->offset.offi); + } + outindchars(']', item->indcount); +} + +PUBLIC void dbtype(type) +struct typestruct *type; +{ + for ( ; type != NULL; type = type->nexttype) + { + outbyte(' '); + switch (type->constructor) + { + case ARRAY: + outbyte('['); + outhex(type->typesize / type->nexttype->typesize); + outbyte(']'); + break; + case FUNCTION: + outstr("()"); + break; + case POINTER: + outbyte('*'); + break; + case STRUCTU: + outstr("struct "); + default: + if (type->scalar & UNSIGNED) + outstr("unsigned "); + outstr(type->tname); + break; + } + } +} + +PUBLIC void dbnode(exp) /* sub-nodes must be leaves */ +struct nodestruct *exp; +{ + if (!dbnodeon) + return; + outstr("! Debug: "); + if (exp->tag < FIRSTOP && exp->tag > LASTOP) + outstr("unknown op"); + else + outstr(opname[exp->tag - FIRSTOP]); + if (exp->right != NULL && exp->tag != FUNCOP && + exp->tag != LISTOP && exp->tag != ROOTLISTOP) + { + dbitem(exp->right->left.symptr); + outstr(" to"); + } + dbitem(exp->left.nodeptr->left.symptr); + outstr(" (used reg = "); + if (reguse & INDREG0) + outregname(INDREG0); + if (reguse & INDREG1) + outregname(INDREG1); + if (reguse & INDREG2) + outregname(INDREG2); + outnstr(")"); +} + +PUBLIC void dbnodeswap() +{ + if (dbnodeon) + outnstr("! Debug: expression subtree swapping"); +} + +PRIVATE void outindchars(byte, count) +int byte; +indn_pt count; +{ + while (count--) + outbyte(byte); +} + +#endif /* DBNODE */ diff --git a/bcc/dbprintf.c b/bcc/dbprintf.c new file mode 100644 index 0000000..a77a012 --- /dev/null +++ b/bcc/dbprintf.c @@ -0,0 +1,257 @@ + +#include <sys/types.h> +#include <fcntl.h> + +#if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__) +#include <stdarg.h> +#define va_strt va_start +#else +#include <varargs.h> +#define va_strt(p,i) va_start(p) +#endif + +#if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__) +int dbprintf(const char * fmt, ...) +#else +int dbprintf(fmt, va_alist) +__const char *fmt; +va_dcl +#endif +{ + va_list ptr; + int rv; + va_strt(ptr, fmt); + rv = vdbprintf(fmt,ptr); + va_end(ptr); + return rv; +} + +static unsigned char * __numout (long i, int base); +static void putch(int ch) { static char buf[2]; *buf = ch; write(2,buf,1); } + +int +vdbprintf(fmt, ap) +register __const char *fmt; +register va_list ap; +{ + int c; + int count = 0; + int type, base; + long val; + char * cp; + char padch=' '; + int minsize, maxsize; + + while(c=*fmt++) + { + count++; + if(c!='%') + putch(c); + else + { + type=1; + padch = *fmt; + maxsize=minsize=0; + if(padch == '-') fmt++; + + for(;;) + { + c=*fmt++; + if( c<'0' || c>'9' ) break; + minsize*=10; minsize+=c-'0'; + } + + if( c == '.' ) + for(;;) + { + c=*fmt++; + if( c<'0' || c>'9' ) break; + maxsize*=10; maxsize+=c-'0'; + } + + if( padch == '-' ) minsize = -minsize; + else + if( padch != '0' ) padch=' '; + + if( c == 0 ) break; + if(c=='h') + { + c=*fmt++; + type = 0; + } + else if(c=='l') + { + c=*fmt++; + type = 2; + } + + switch(c) + { + case 'x': base=16; type |= 4; if(0) { + case 'o': base= 8; type |= 4; } if(0) { + case 'u': base=10; type |= 4; } if(0) { + case 'd': base=-10; } + switch(type) + { + case 0: /* Promoted: val=va_arg(ap, short); break; */ + case 1: val=va_arg(ap, int); break; + case 2: val=va_arg(ap, long); break; + case 4: /* Promoted: val=va_arg(ap, unsigned short); break; */ + case 5: val=va_arg(ap, unsigned int); break; + case 6: val=va_arg(ap, unsigned long); break; + default:val=0; break; + } + cp = __numout(val,base); + if(0) { + case 's': + cp=va_arg(ap, char *); + } + count--; + c = strlen(cp); + if( !maxsize ) maxsize = c; + if( minsize > 0 ) + { + minsize -= c; + while(minsize>0) { putch(padch); count++; minsize--; } + minsize=0; + } + if( minsize < 0 ) minsize= -minsize-c; + while(*cp && maxsize-->0 ) + { + putch(*cp++); + count++; + } + while(minsize>0) { putch(' '); count++; minsize--; } + break; + case 'c': + putch(va_arg(ap, int)); + break; + case 'C': + c = va_arg(ap, int); + if (c>0x7F) { + c &=0x7F; + putch('M'); putch('-'); + } + if (c<' ' || c == '\177') { + putch('^'); putch(c^'@'); + } else + putch(c); + break; + default: + putch(c); + break; + } + } + } + return count; +} + +static char nstring[]="0123456789ABCDEF"; + +#ifndef __AS386_16__ +#define NUMLTH 11 + +static unsigned char * +__numout(long i, int base) +{ + static unsigned char out[NUMLTH+1]; + int n; + int flg = 0; + unsigned long val; + + if (base<0) + { + base = -base; + if (i<0) + { + flg = 1; + i = -i; + } + } + val = i; + + out[NUMLTH] = '\0'; + n = NUMLTH-1; + do + { + out[n--] = nstring[val % base]; + val /= base; + } + while(val); + if(flg) out[n--] = '-'; + return &out[n+1]; +} + +#else + +#asm +! numout.s +! +.bss +___out lcomm $C + +.text +___numout: +push bp +mov bp,sp +push di +push si +add sp,*-4 +mov byte ptr -8[bp],*$0 ! flg = 0 +mov si,4[bp] ; i or val.lo +mov di,6[bp] ; i or val.hi +mov cx,8[bp] ; base +test cx,cx ! base < 0 ? +jge .3num +neg cx ! base = -base +or di,di ! i < 0 ? +jns .5num +mov byte ptr -8[bp],*1 ! flg = 1 +neg di ! i = -i +neg si +sbb di,0 +.5num: +.3num: +mov byte ptr [___out+$B],*$0 ! out[11] = nul +mov -6[bp],*$A ! n = 10 + +.9num: +!!! out[n--] = nstring[val % base]; +xor dx,dx +xchg ax,di +div cx +xchg ax,di +xchg ax,si +div cx +xchg ax,si ! val(new) = val / base + +mov bx,dx ! dx = val % base + +mov al,_nstring[bx] +mov bx,-6[bp] +dec word ptr -6[bp] +mov ___out[bx],al + +mov ax,si +or ax,di ! while (val) +jne .9num + +cmp byte ptr -8[bp],*$0 ! flg == 0 ? +je .Dnum + +mov bx,-6[bp] +dec word ptr -6[bp] +mov byte ptr ___out[bx],*$2D ! out[n--] = minus + +.Dnum: +mov ax,-6[bp] +add ax,#___out+1 + +add sp,*4 +pop si +pop di +pop bp +ret +#endasm + +#endif diff --git a/bcc/debug.c b/bcc/debug.c index 2b1e12e..2ccda5d 100644 --- a/bcc/debug.c +++ b/bcc/debug.c @@ -1,200 +1,216 @@ -/* debug.c - print debug messages for operators for bcc */ - -/* Copyright (C) 1992 Bruce Evans */ - -#include "bcc.h" - -#ifdef DEBUG -#include "gencode.h" -#include "reg.h" -#include "sc.h" -#include "scan.h" -#include "type.h" - -PRIVATE char *opname[LASTOP - FIRSTOP + 1] = /* operator names */ -{ /* order must agree with op.h */ - "cond?", - "or", - "eor", - "and", - "gt", "lt", - "add", - "div", "mod", - "lognot", "not", - "strucelt", "strucptr", - "eq", - "addab", "andab", "divab", "eorab", "modab", "mulab", "orab", - "slab", "srab", "subab", - "comma", - "cond:", - "logor", - "logand", - "logeq", - "ne", - "ge", "le", - "sl", "sr", - "sub", - "mul", - "address", "cast", "indirect", "neg", - "predec", "preinc", "postdec", "postinc", - "func", "list", "rootlist", - "leaf", - "ptraddab", "ptradd", "ptrsub", -}; - -FORWARD void outindchars P((int byte, indn_pt count)); - -PUBLIC void dbitem(item) -struct symstruct *item; +/* + * debug.c: a generic debugging facility for unix programs. + * + * The calling program is required to call debug_setlevel(lvl) to set + * which messages will be displayed. The level is a two part value + * where the least significant (decimal) digit is a level as described + * below. The most significant digits are a class code. For a message + * to be displayed the class code must either be zero or match the + * class code of the debug(...) message. + * + * The 'debug(lvl, fmt, ...)' function displays debugging messages + * complete with source and line number. The function can be used + * as a normal one in if() smt else smt constructs. It returns the + * actual number of bytes printed so it's return value can be used + * inside an if(debug(...)) to enable more debugging code. This code + * will be removed by the compiler (as dead code) if debugging is + * not enabled. + * + * The level on the debug() statment also consists of a level and class + * code where the class code must be zero or match the setlevel's class + * code for the message to be displayed. + * + * Level 0 + * Always displayed if the debugging is enabled. + * You probably shouldn't use this. + * + * Level 1 + * Important state changes and errors that cause a significant change + * in program flow. + * + * Level 2 + * Rare things that cause a minor program flow adjustment. + * + * Level 3 + * Errors and useful messages that are slightly too verbose or common + * for 0-2 or don't quite fit in the classifications. + * + * Level 4 + * All remote responses or major results. (Trace results) + * + * Level 5 + * All remote commands or major tasks. (Trace jobs) + * + * Level 6 + * General information that will not be too verbose but is normally a + * little less important. (Trace state) + * + * Level 7 + * Similar to level 3 but verbose or not as useful. + * + * Level 8 + * Very verbose information that'll probably be useful sometime. + * + * Level 9 + * Anything and everything else, debugs that probably won't be useful + * ever again. (unclassified) + * + * Notes: + * If the programmer doesn't set the debug level this is not an important + * debug message or is only important right now. + * => default debug level == 9 + * + * If something fits in one of the lower levels but is very verbose + * it should nevertheless be moved upto level 3 or levels 7-9. + * (Possibly leaving a single line 'oops' at the lower level) + * + * The general idea is that debug levels 0-3 should not scroll too fast + * to read and nothing below level 7 should be much more verbose than + * levels 4 or 5. + * + ***************************************************************************** + * + * 2004-06-20: Added __STDC__ to debug.h so it can be called from non-ansi + * compiler. This file still needs ansi or unproto. + * + * 2004-06-20: Added check of DEBUG environment variable if setlevel isn't + * called before a debug(). + * + * 2004-06-20: Added #define VARARG_MACROS so the preprocessor can remove + * all the debugging 'stuff'. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +#include "debug.h" + +#define USE_DBPRINTF + +#ifndef DEBUG +static char ident[] = + "$Id: debug.c: (c) 1995-2004 Robert de Bath. Debugging disabled. $"; +#else +static char ident[] = + "$Id: debug.c: (c) 1995-2004 Robert de Bath. Debugging enabled. $"; + +static char * db_file = 0; +static int db_lineno = 0; +static int disp_state = 0; +static int disp_pos(void); + +static void debug_envvar(void); + +int debug_level = -1; + +void debug_do_setlevel(char * fname, int lineno, int level) { - dbtype(item->type); - if (item->storage == NOSTORAGE) - { - outbyte(' '); - outstr(item->name.namep + 2); - outstr(" (offset "); - outshex(item->offset.offi); - outbyte(')'); - return; - } - if (item->storage == LOCAL) - { - outbyte(' '); - if (item->flags == TEMP) - outstr("(temp)"); - else - outstr(item->name.namep); - } - outstr(" = "); - outindchars('[', item->indcount); - switch (item->storage) - { - case CONSTANT: - outstr("const "); - if (item->type->scalar & RSCALAR) - outstr("(whatever)"); - else if (item->type->scalar & UNSIGNED) - outuvalue((uvalue_t) item->offset.offv); - else - outvalue(item->offset.offv); - break; - case BREG: - case DREG: - case INDREG0: - case INDREG1: - case INDREG2: -#ifdef DATREG1 - case DATREG1: -#endif -#ifdef DATREG2 - case DATREG2: -#endif - outregname(item->storage); - if (item->level == OFFKLUDGELEVEL) - { - outplus(); - if (item->flags & LABELLED) - outlabel(item->name.label); - else - outccname(item->name.namep); - } - break; - case LOCAL: - outbyte('S'); - if (sp <= 0) - outplus(); - outshex(-sp); - break; - case GLOBAL: - if (item->flags & LABELLED) - outlabel(item->name.label); - else - outstr(item->name.namep); - break; - default: - outstr("bad storage ("); - outhex((uoffset_T) item->storage); - outbyte(')'); - outstr(" offset "); - } - if (item->storage != CONSTANT) - { - if (item->offset.offi >= 0) - outplus(); - outshex(item->offset.offi); - } - outindchars(']', item->indcount); + if(level || !debug_level) + debug_level = level; + debug_pos(fname, lineno); + debug_msg(1, "Debug level now %d", level); + debug_level = level; } -PUBLIC void dbtype(type) -struct typestruct *type; +int debug_pos(char * file, int lineno) { - for ( ; type != NULL; type = type->nexttype) - { - outbyte(' '); - switch (type->constructor) - { - case ARRAY: - outbyte('['); - outhex(type->typesize / type->nexttype->typesize); - outbyte(']'); - break; - case FUNCTION: - outstr("()"); - break; - case POINTER: - outbyte('*'); - break; - case STRUCTU: - outstr("struct "); - default: - if (type->scalar & UNSIGNED) - outstr("unsigned "); - outstr(type->tname); - break; - } - } + db_file = file; + db_lineno = lineno; + disp_state |= 1; + return disp_pos(); +} + +int debug_msg(int level, char * fmt, ...) +{ + va_list ap; + int rv = 0; + int disp = 0; + + if (debug_level == -1) debug_envvar(); + + if (level == -1) { + level = 0; + disp_state |= 1; + db_lineno = -1; + } + + disp_state |= 2; + + if (level>9 || debug_level>9) { + disp = (level%10 <= debug_level%10); + if (disp && level>9 && debug_level>9 && level/10 != debug_level/10) + disp = 0; + } else disp = (level <= debug_level); + + if (disp) + { + disp_state |= 4; + + va_start(ap, fmt); +#ifdef USE_DBPRINTF + rv = vdbprintf(fmt, ap); +#else + rv = vfprintf(stderr, fmt, ap); +#endif + va_end(ap); + } + return rv + disp_pos(); } -PUBLIC void debug(exp) /* sub-nodes must be leaves */ -struct nodestruct *exp; +int +disp_pos() { - if (!debugon) - return; - outstr("! Debug: "); - if (exp->tag < FIRSTOP && exp->tag > LASTOP) - outstr("unknown op"); - else - outstr(opname[exp->tag - FIRSTOP]); - if (exp->right != NULL && exp->tag != FUNCOP && - exp->tag != LISTOP && exp->tag != ROOTLISTOP) - { - dbitem(exp->right->left.symptr); - outstr(" to"); - } - dbitem(exp->left.nodeptr->left.symptr); - outstr(" (used reg = "); - if (reguse & INDREG0) - outregname(INDREG0); - if (reguse & INDREG1) - outregname(INDREG1); - if (reguse & INDREG2) - outregname(INDREG2); - outnstr(")"); + int rv = 0; + if (disp_state == 7 && db_lineno != -1) +#ifdef USE_DBPRINTF + rv = dbprintf(" at %s:%d\n", db_file, db_lineno); +#else + rv = fprintf(stderr, " at %s:%d\n", db_file, db_lineno); +#endif + + if ((disp_state&3) == 3) { + db_file = 0; + db_lineno = disp_state = 0; + } + return rv; } -PUBLIC void debugswap() +/* If setlevel isn't called check the environment */ + +static void debug_envvar(void) { - if (debugon) - outnstr("! Debug: expression subtree swapping"); + char * p = getenv("DEBUG"); + if (!p || !*p) + debug_level = 0; + else + debug_level = atoi(p); + if (debug_level) +#ifdef USE_DBPRINTF + dbprintf("Debug level now %d from environment.\n", debug_level); +#else + fprintf(stderr, "Debug level now %d from environment.\n", debug_level); +#endif } -PRIVATE void outindchars(byte, count) -int byte; -indn_pt count; +#endif + +#ifndef VARARG_MACROS +/* + * This function should never be called. + * + * If ident sees the message in a binary then your compiler is wasting + * space by allocating it for unused strings. + * + * We know GNU-C is ok, but it complains. + */ +int debug_never(int level, char * name, ...) { - while (count--) - outbyte(byte); +#ifndef __GNUC__ + 1?0:debug_never(0, "$Warning: Debugging strings exist in non-debug binary $"); +#endif + return 0; } +#endif -#endif /* DEBUG */ diff --git a/bcc/debug.h b/bcc/debug.h new file mode 100644 index 0000000..2039d5a --- /dev/null +++ b/bcc/debug.h @@ -0,0 +1,38 @@ + +#ifndef _DEBUG_H_ +#define _DEBUG_H_ + +#if __STDC__ +void debug_do_setlevel(char * fname, int lineno, int level); +int debug_pos(char * file, int lineno); +int debug_msg(int level, char * name, ...); +int debug_never(int level, char * name, ...); +#else +void debug_do_setlevel(); +int debug_pos(); +int debug_msg(); +int debug_never(); +#endif /* __STDC__ */ + +/* The new CPP has these. */ +#if defined(__BCC__) && (__BCC_VERSION__ >= 0x001011L) +#define VARARG_MACROS +#endif + +#ifdef DEBUG + +extern int debug_level; +#define debug !debug_level?0:debug_pos(__FILE__,__LINE__)+debug_msg +#define debug_setlevel(lvl) debug_do_setlevel(__FILE__, __LINE__, lvl) + +#else /* !DEBUG */ + +#ifdef VARARG_MACROS +# define debug(junk ...) 0 +#else +# define debug 1?0:debug_never +#endif +# define debug_setlevel(lvl) + +#endif /* DEBUG */ +#endif /* _DEBUG_H_ */ diff --git a/bcc/declare.c b/bcc/declare.c index ad3b31e..0820c4b 100644 --- a/bcc/declare.c +++ b/bcc/declare.c @@ -699,11 +699,12 @@ PRIVATE void declfunc() lbrace(); compound(); #ifdef I8088 - if (regfuse & callee1mask) { + if (regfuse & (callee1mask | INDREG0)) { outstr("! Register"); - if (regfuse & INDREG0 & callee1mask) outstr(" BX"); + if (regfuse & INDREG0 ) outstr(" BX"); if (regfuse & INDREG1 & callee1mask) outstr(" SI"); if (regfuse & INDREG2 & callee1mask) outstr(" DI"); + if (regfuse & LOCAL & callee1mask) outstr(" BP"); outstr(" used in function "); outnstr(funcname); if (optimise && !callersaves) { diff --git a/bcc/function.c b/bcc/function.c index 1f8b6f3..8fe679f 100644 --- a/bcc/function.c +++ b/bcc/function.c @@ -237,7 +237,7 @@ offset_T lastargsp; if (sp != lastargsp - target->type->typesize) { bugerror("botched push of arg"); -#ifdef DEBUG +#ifdef DBNODE outstr("arg type is "); dbtype(target->type); outnl(); diff --git a/bcc/gencode.c b/bcc/gencode.c index 9498159..91c524f 100644 --- a/bcc/gencode.c +++ b/bcc/gencode.c @@ -223,8 +223,8 @@ struct nodestruct *exp; if ((right = exp->right) == NULL) { makeleaf(left); -#ifdef DEBUG - debug(exp); +#ifdef DBNODE + dbnode(exp); #endif return; } @@ -265,8 +265,8 @@ struct nodestruct *exp; exp->left.nodeptr = right; right = exp->right = left; left = exp->left.nodeptr; -#ifdef DEBUG - debugswap(); +#ifdef DBNODE + dbnodeswap(); #endif } makeleaf(right); @@ -346,8 +346,8 @@ struct nodestruct *exp; indirec(source); } reguse = regmark; -#ifdef DEBUG - debug(exp); +#ifdef DBNODE + dbnode(exp); #endif if (commutop && ((target->storage == CONSTANT @@ -358,8 +358,8 @@ struct nodestruct *exp; { exp->left.nodeptr = right; exp->right = left; -#ifdef DEBUG - debugswap(); +#ifdef DBNODE + dbnodeswap(); #endif } } @@ -720,7 +720,7 @@ register struct nodestruct *exp; { { bugerror("botched nodetype calculation"); -#ifdef DEBUG +#ifdef DBNODE comment(); outstr("runtime type is "); dbtype(target->type); diff --git a/bcc/gencode.h b/bcc/gencode.h index 63d0614..9f53b70 100644 --- a/bcc/gencode.h +++ b/bcc/gencode.h @@ -14,8 +14,8 @@ EXTERN uoffset_T arg1size; /* size of 1st arg to function */ /* zero after allocation of 1st arg */ EXTERN store_pt callee1mask; /* calleemask with doubleregs masked if nec */ EXTERN uoffset_T dataoffset; /* amount of initialized data so far */ -#ifdef DEBUG -EXTERN bool_t debugon; /* nonzero to print debugging messages */ +#ifdef DBNODE +EXTERN bool_t dbnodeon; /* nonzero to print debugging messages */ /* depends on zero init */ #endif #ifdef FRAMEPOINTER diff --git a/bcc/genloads.c b/bcc/genloads.c index 3d0f919..efa3725 100644 --- a/bcc/genloads.c +++ b/bcc/genloads.c @@ -1010,6 +1010,7 @@ store_pt reg; break; case LOCAL: outstr(localregstr); + regfuse |= LOCAL; break; #ifdef STACKREG case STACKREG: diff --git a/bcc/hashcmd.c b/bcc/hashcmd.c index fd22166..c9ad943 100644 --- a/bcc/hashcmd.c +++ b/bcc/hashcmd.c @@ -14,10 +14,198 @@ #include "type.h" #ifndef BUILTIN_CPP -/* docontrol() - process control statement, #line and #asm only. */ +FORWARD void control P((void)); +FORWARD void asmcontrol P((void)); +FORWARD void warningcntl P((void)); +FORWARD void errorcntl P((void)); +/* docontrol() - process control statement, #line and #asm only. */ PUBLIC void docontrol() { - bugerror("docontrol for tiny machines not implemented yet"); + control(); + skipline(); + return; +} + +/* control() - select and switch to control statement */ + +PRIVATE void control() +{ + char sname[NAMESIZE + 1]; + sym_t ctlcase; + struct symstruct *symptr; + if (ctext && asmmode) + { + comment(); + outudec(input.linenumber); + outbyte(' '); + outline(lineptr); + } + + sname[0] = '#'; /* prepare for bad control */ + sname[1] = 0; + if (blanksident()) + strcat(sname, gsname); + if (sname[1] == 0 && ch == EOL) + return; + if (SYMOFCHAR(ch) == INTCONST) + { linecontol(); return; } + if ((symptr = findlorg(sname)) == NULL) + { + error(" bad control"); + return; + } + ctlcase = symptr->offset.offsym; + + switch (ctlcase) + { + case ASMCNTL: + if (asmmode) + error(" bad control"); + else + asmcontrol(); + break; + case ENDASMCNTL: + if (!asmmode) + error(" bad control"); + asmmode = FALSE; + break; + case LINECNTL: + { linecontol(); break; } + case WARNINGCNTL: + warningcntl(); + break; + case ERRORCNTL: + errorcntl(); + break; + default: + error(" bad control"); + break; + } +} + +/* asmcontrol() - process #asm */ + +PRIVATE void asmcontrol() +{ +#ifdef ASM_BARE + char treasure; /* to save at least one leading blank */ +#endif + + asmmode = TRUE; + if (expect_statement) + return; + + outnstr("!BCC_ASM"); + dumplocs(); +#ifndef ASM_BARE + cppscan(1); +#else + while (TRUE) + { + skipline(); + skipeol(); + if (eofile) + { + eofin("#asm"); + break; + } + if (SYMOFCHAR(ch) == SPECIALCHAR) + specialchar(); + treasure = 0; + if (SYMOFCHAR(ch) == WHITESPACE) + treasure = ch; + blanks(); + if (ch == '#') + { + if (ctext) + { + register char *lptr; + + comment(); + if (treasure != 0) + outbyte(treasure); + lptr = lineptr; + while (*lptr++ != EOL) /* XXX - handle COEOL too */ + outbyte(ch); + outnl(); + } + gch1(); + docontrol(); + if (!asmmode) + break; + } + else + { + if (treasure != 0) + outbyte(treasure); + while (ch != EOL) /* XXX - handle COEOL too */ + { + outbyte(ch); + gch1(); + } + outnl(); + } + } +#endif + outnstr("!BCC_ENDASM"); +} + +/* warningcntl() - process #warning */ + +PRIVATE void warningcntl() +{ + char estr[256], *ep = estr; + + *ep++ = '%'; *ep++ = 'w'; + while( ch != EOL ) { + if (ep < estr+sizeof(estr)-2 ) + *ep++ = ch; + gch1(); + } + *ep = 0; + error(estr); +} + +/* errorcntl() - process #error */ + +PRIVATE void errorcntl() +{ + char estr[256], *ep = estr; + + while( ch != EOL ) { + if (ep < estr+sizeof(estr)-2 ) + *ep++ = ch; + gch1(); + } + *ep = 0; + + error(estr); +} + +/* skipline() - skip rest of line */ + +PUBLIC void skipline() +{ + while (TRUE) + { + blanks(); + if (ch == EOL) + return; + if (ch == '\\') + { + gch1(); + if (ch == EOL) /* XXX - I think blanks() eats \EOL */ + return; + gch1(); /* XXX - escape() better? */ + } + else if (ch == '"' || ch == '\'') + { + stringorcharconst(); + charptr = constant.value.s; + } + else + gch1(); + } } #endif diff --git a/bcc/input.c b/bcc/input.c index 317c053..a17af4a 100644 --- a/bcc/input.c +++ b/bcc/input.c @@ -18,10 +18,7 @@ #include "input.h" #define INBUFSIZE 2048 - -#ifndef BUILTIN_CPP #define NO_EOFHACK -#endif struct fbufstruct /* file buffer structure */ { @@ -34,6 +31,7 @@ struct fbufstruct /* file buffer structure */ char fbuf[INBUFSIZE + 1]; /* buffer to read into */ }; +#ifdef BUILTIN_CPP struct inclist /* list of include file directories */ { char *incdirname; @@ -55,7 +53,6 @@ PRIVATE struct inclist inclast = #endif NULL, }; -#ifdef BUILTIN_CPP PRIVATE fastin_t inclevel; /* nest level of include files */ /* depends on zero init */ #endif @@ -67,12 +64,12 @@ PRIVATE bool_t suppress_line_numbers; #ifdef ARBITRARY_BACKSLASH_NEWLINES FORWARD void backslash P((void)); #endif -FORWARD void definefile P((char *fname)); -FORWARD void inputinit P((char *fname, fd_t fd)); -FORWARD void usage P((void)); #ifdef BUILTIN_CPP +FORWARD void definefile P((char *fname)); FORWARD void leaveinclude P((void)); #endif +FORWARD void inputinit P((char *fname, fd_t fd)); +FORWARD void usage P((void)); #ifdef ARBITRARY_BACKSLASH_NEWLINES PRIVATE void backslash() @@ -234,15 +231,10 @@ PUBLIC void include() while (blanksident()) { -#ifdef BUILTIN_CPP if ((gsymptr = findlorg(gsname)) == NULL || gsymptr->flags != DEFINITION) break; entermac(); -#else - if ((gsymptr = findlorg(gsname)) == NULL ) - break; -#endif } if ((terminator = ch) == '<') terminator = '>'; @@ -404,15 +396,13 @@ ts_s_inputbuf_tot += sizeof *inputbuf; #endif *(input.limit = newinputbuf->fbuf) = EOL; -#ifdef BUILTIN_CPP - /* dummy line so #include processing can start with skipline() */ + /* dummy line so processing can start with skipline() */ ch = *(lineptr = newinputbuf->fbuf - 1) = EOL; -#endif } PUBLIC void linecontol() { -static char linename[32]; + char linename[256]; char * ptr; int i=0; @@ -435,8 +425,10 @@ ts_s_pathname_tot -= strlen(inputbuf->fname) + 1; #endif ourfree(inputbuf->fname); } - inputbuf->fname_malloced = FALSE; - inputbuf->fname = linename; + inputbuf->fname_malloced = TRUE; + ptr = ourmalloc(strlen(linename)+1); + strcpy(ptr, linename); + inputbuf->fname = ptr; ptr=lineptr; #ifdef BUILTIN_CPP @@ -472,10 +464,8 @@ ts_s_inputbuf_tot -= sizeof *inputbuf; #endif inputbuf = input.includer; input = inputbuf->fcb; -#ifdef BUILTIN_CPP undefinestring(filemacro); definefile(inputbuf->fname); -#endif ch = *(lineptr = input.lineptr); skipline(); if (orig_cppmode && !suppress_line_numbers) @@ -493,8 +483,10 @@ char *argv[]; int argn; fd_t fd; char *fname; +#ifdef BUILTIN_CPP struct inclist *incnew; struct inclist *incptr; +#endif bool_t flag[128]; #if 0 @@ -506,7 +498,9 @@ char *argv[]; flag['3'] = sizeof (int) >= 4; #endif fname = "stdin"; +#ifdef BUILTIN_CPP (incptr = &incfirst)->incnext = &inclast; +#endif initout(); for (argn = 1; argn < argc; ++argn) { @@ -529,7 +523,7 @@ char *argv[]; case '3': /* generate 32-bit code */ #endif case 'c': /* caller saves */ -#ifdef DEBUG +#ifdef DBNODE case 'd': /* print debugging information in asm output */ #endif #ifdef BUILTIN_CPP @@ -607,8 +601,8 @@ ts_s_includelist += sizeof *incnew; callersaves = TRUE; definestring("__CALLER_SAVES__"); } -#ifdef DEBUG - debugon = flag['d']; +#ifdef DBNODE + dbnodeon = flag['d']; #endif orig_cppmode = cppmode = flag['E']; if (flag['f']) @@ -652,8 +646,8 @@ ts_s_includelist += sizeof *incnew; if (flag['3']) i386_32 = TRUE; #endif if (flag['c']) callersaves = TRUE; -#ifdef DEBUG - debugon = flag['d']; +#ifdef DBNODE + dbnodeon = flag['d']; #endif if (flag['f']) arg1inreg = TRUE; arg1op = arg1inreg ? ROOTLISTOP : LISTOP; @@ -668,8 +662,8 @@ ts_s_includelist += sizeof *incnew; #endif ctext = flag['t']; -#ifdef DEBUG - if (ctext) debugon = 1; +#ifdef DBNODE + if (ctext) dbnodeon = 1; #endif watchlc = flag['w']; setoutbufs(); @@ -688,6 +682,7 @@ PUBLIC void skipeol() static bool_t skip_printing_nl; #endif int nread; + debug(7, "skipeol %s:%d", inputbuf->fname, input.linenumber); if (eofile) return; @@ -767,6 +762,7 @@ case0: #endif nread = read(input.fd, lineptr = inputbuf->fbuf, INBUFSIZE); #ifndef NO_EOFHACK +#ifdef BUILTIN_CPP if( nread == 0 && inclevel > 0 ) { close(input.fd); @@ -774,6 +770,7 @@ case0: memcpy(inputbuf->fbuf, "\n", 1); nread = 1; } +#endif } #endif #endif @@ -882,13 +879,22 @@ more: PRIVATE void usage() { fatalerror( -#ifdef MC6809 -"usage: cc1 [-cdfptw[-]] [-Ddefine] [-Iincdir] [-Uundef] [-o outfile] [infile]"); -#else -#ifdef I80386 -"usage: cc1 [-03cdfltw[-]] [-Ddefine] [-Iincdir] [-Uundef] [-o outfile] [infile]"); +#ifdef BUILTIN_CPP +# ifdef MC6809 +"usage: cc1 [-cdfptw[-]] [-Ddefine] [-Iincdir] [-Uundef] [-o outfile] [infile]" +# else +# ifdef I80386 +"usage: cc1 [-03cdfltw[-]] [-Ddefine] [-Iincdir] [-Uundef] [-o outfile] [infile]" +# else +"usage: cc1 [-cdfltw[-]] [-Ddefine] [-Iincdir] [-Uundef] [-o outfile] [infile]" +# endif +# endif #else -"usage: cc1 [-cdfltw[-]] [-Ddefine] [-Iincdir] [-Uundef] [-o outfile] [infile]"); -#endif +# ifdef I80386 +"usage: cc1 [-03cdfltw[-]] [-o outfile] [infile]" +# else +"usage: cc1 [-cdfltw[-]] [-o outfile] [infile]" +# endif #endif + ); } diff --git a/bcc/output.c b/bcc/output.c index dd00c71..bdf64f6 100644 --- a/bcc/output.c +++ b/bcc/output.c @@ -32,7 +32,7 @@ PRIVATE fastin_t outstage; /* depends on zero init */ FORWARD void errorsummary P((void)); FORWARD void errsum1 P((void)); #ifdef MC6809 -#ifdef DEBUG +#ifdef DBNODE FORWARD void outvaldigs P((uvalue_t num)); #endif #endif @@ -116,6 +116,7 @@ char *message2; output = old_output; outstage = old_outstage; } + outstr("fail"); comment(); errorloc(); outstr(warning); @@ -734,7 +735,7 @@ unsigned num; } #ifdef MC6809 -#ifdef DEBUG +#ifdef DBNODE /* print unsigned value, hex format (like outhex except value_t is larger) */ @@ -778,7 +779,7 @@ register value_t num; outuvalue((uoffset_T) num); } -#endif /* DEBUG */ +#endif /* DBNODE */ #endif /* MC6809 */ /* push decimal digits of an unsigned onto a stack of chars */ diff --git a/bcc/proto.h b/bcc/proto.h index f1055d7..3b44a56 100644 --- a/bcc/proto.h +++ b/bcc/proto.h @@ -102,11 +102,11 @@ void uitol P((store_pt reg)); void restoreopreg P((void)); void saveopreg P((void)); -/* debug.c */ +/* dbnode.c */ void dbitem P((struct symstruct *item)); void dbtype P((struct typestruct *type)); -void debug P((struct nodestruct *exp)); -void debugswap P((void)); +void dbnode P((struct nodestruct *exp)); +void dbnodeswap P((void)); /* declare.c */ void colon P((void)); @@ -315,6 +315,7 @@ more: while (symofchar[c] <= MAXIDSYM && --length != 0); ch = c; *idptr = 0; + debug(7, "Got ident %s", gsname); lineptr = reglineptr; if (symofchar[c] == SPECIALCHAR) { @@ -471,6 +472,7 @@ PUBLIC void nextsym() if (SYMOFCHAR(ch = *(lineptr = reglineptr + 1)) == SPECIALCHAR && sym != SPECIALCHAR) specialchar(); + debug(7, "In nextsym, got %d \"%C\"", sym, lastch); switch (sym) { case CHARCONST: diff --git a/bcc/softop.c b/bcc/softop.c index dcfa8ae..a3938b3 100644 --- a/bcc/softop.c +++ b/bcc/softop.c @@ -222,9 +222,11 @@ struct symstruct *target; if (uflag) call("idiv_"); else { +#ifdef I80386 if (i386_32) outnop1str("cdq"); else +#endif outnop1str("cwd"); outop2str("idiv\t"); outregname(INDREG0); diff --git a/bcc/table.c b/bcc/table.c index fc7d3a1..166c143 100644 --- a/bcc/table.c +++ b/bcc/table.c @@ -574,7 +574,7 @@ char *message; { error2error("compiler out of memory", message); -#if defined(DEBUG) && 0 +#ifdef __AS386_16__ { unsigned size; char *ptr; diff --git a/copt/rules.86 b/copt/rules.86 index 2288050..9ec1235 100644 --- a/copt/rules.86 +++ b/copt/rules.86 @@ -553,3 +553,10 @@ mov %1,si mov %2,di !BCC_EOS +### +mov ax,%1 +mov %[ax|bx|cx|dx]2,ax +mov ax,%3 += +mov %2,%1 +mov ax,%3 @@ -110,5 +110,6 @@ struct define_item char * name; int arg_count; /* -1 = none; >=0 = brackets with N args */ int in_use; /* Skip this one for looking up #defines */ + int varargs; /* No warning if unexpected arguments. */ char value[1]; /* [arg,]*value */ }; @@ -111,7 +111,7 @@ static void do_proc_tail P((void)); static int get_if_expression P((void)); static int_type get_expression P((int)); static int_type get_exp_value P((void)); -static void gen_substrings P((char *, char *, int)); +static void gen_substrings P((char *, char *, int, int)); static char * insert_substrings P((char *, struct arg_store *, int)); int @@ -329,7 +329,7 @@ break_break: } /* We have arguments to process so lets do so. */ - gen_substrings(ptr->name, ptr->value, ptr->arg_count); + gen_substrings(ptr->name, ptr->value, ptr->arg_count, ptr->varargs); /* Don't mark macros with arguments as in use, it's very * difficult to say what the correct result would be so @@ -822,6 +822,11 @@ do_proc_define() cc++; ptr->arg_count++; ch=gettok_nosub(); + if( ch == TK_ELLIPSIS ) { + ptr->varargs = 1; + ch=gettok_nosub(); + if (ch == ',') ch = '*'; /* Force error if not ')' */ + } if( ch == ')' ) break; if( ch == ',' ) continue; } @@ -1247,10 +1252,11 @@ get_exp_value() } void -gen_substrings(macname, data_str, arg_count) +gen_substrings(macname, data_str, arg_count, is_vararg) char * macname; char * data_str; int arg_count; +int is_vararg; { char * mac_text = 0; struct arg_store *arg_list; @@ -1289,7 +1295,9 @@ int arg_count; if ( ch == '(' ) paren_count++; if ( ch == '"' || ch == '\'' ) { in_quote = 1; quote_char = ch; } if (paren_count == 0 && ch == ',' ) { - commas_found++; continue; + commas_found++; + if (commas_found < arg_count) + continue; } if ( ch == ')' ) { if (paren_count == 0) break; @@ -1297,9 +1305,13 @@ int arg_count; } } args_found = 1; - /* Too many args; ignore rest */ - if (commas_found >= arg_count ) continue; - ac = commas_found; + /* Too many args, deal with, or ignore, the rest. */ + if (commas_found >= arg_count) { + if(arg_count == 0) continue; + ac = arg_count-1; + } else + ac = commas_found; + if (arg_list[ac].value == 0) { cc = len = 0; arg_list[ac].in_define = def_count; @@ -1322,8 +1334,10 @@ int arg_count; if (commas_found || args_found) args_found = commas_found+1; - if( arg_count != args_found ) - cerror("Incorrect number of macro arguments"); + if( arg_count == 0 && args_found != 0 ) + cerror("Arguments given to macro without them."); + else if( !is_vararg && arg_count != args_found ) + cwarn("Incorrect number of macro arguments"); mac_text = insert_substrings(data_str, arg_list, arg_count); @@ -2,6 +2,7 @@ #include <stdio.h> #ifdef __STDC__ #include <stdlib.h> +#include <string.h> #else #include <malloc.h> #endif @@ -441,7 +441,11 @@ manifest_constant() #ifdef __linux__ save_name("__linux__", 'D'); #ifdef __i386__ - save_name("__linux_i386__", 'D'); + save_name("__elksemu_works__", 'D'); +#endif +/* Is this true ? */ +#ifdef __x86_64__ + save_name("__elksemu_works__", 'D'); #endif #endif #ifdef __unix__ @@ -14,8 +14,13 @@ static struct ar_hdr arbuf; +#ifdef __STDC__ void ld86r(int argc, char ** argv) +#else +ld86r(argc, argv) + int argc; char ** argv; +#endif { char buf[128]; FILE * fd, * ifd; @@ -4,10 +4,6 @@ #define OBJ_H -#ifdef I80386 -# define LONG_OFFSETS /* others can use this, but wasteful */ -#endif - #ifndef OMAGIC # ifdef I80386 # define OMAGIC 0x86A3 diff --git a/ld/objdump86.c b/ld/objdump86.c index d477f3b..003f04c 100644 --- a/ld/objdump86.c +++ b/ld/objdump86.c @@ -22,6 +22,7 @@ #include <malloc.h> #endif #include <string.h> +#include "const.h" #include "ar.h" #include "obj.h" @@ -78,6 +79,8 @@ int display_mode = 0; int multiple_files = 0; int byte_order = 0; +int opt_o; + long size_text, size_data, size_bss; long tot_size_text=0, tot_size_data=0, tot_size_bss=0; @@ -104,6 +107,7 @@ char ** argv; { case 's': display_mode = 1; break; case 'n': display_mode = 2; break; + case 'o': opt_o++; break; } else multiple_files++; @@ -382,9 +386,6 @@ read_syms() symtab = calloc(num_syms, sizeof(*symtab)); if( symtab == 0 ) return error("Out of memory"); - if(display_mode == 2 && multiple_files) - printf("\n%s:\n", ifname); - for(i=0; i<num_syms; i++) { unsigned int symtype; @@ -411,7 +412,7 @@ disp_syms() { int i; - if(display_mode == 2 && multiple_files) + if(display_mode == 2 && multiple_files && !opt_o) printf("\n%s:\n", ifname); for(i=0; i<num_syms; i++) @@ -444,6 +445,8 @@ disp_syms() } if( display_mode == 2 ) { + if (opt_o) + printf("%s: ", ifname); if( symtype == 0x004f || symtype == 0x0040 ) printf(" "); else @@ -788,7 +791,7 @@ nm_aout() if( bytes_left == 0 ) printf("No symbols in '%s'\n", ifname); - else if(multiple_files) + else if(multiple_files && !opt_o) printf("\n%s:\n", ifname); while(bytes_left > 16) @@ -807,6 +810,8 @@ nm_aout() } if( pending_nl ) putchar('\n'); + if (opt_o) + printf("%s: ", ifname); if( n_sclass == 0x10 ) printf(" "); else diff --git a/libc/error/Makefile b/libc/error/Makefile index 01a488f..f604c3b 100644 --- a/libc/error/Makefile +++ b/libc/error/Makefile @@ -4,14 +4,16 @@ CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) -ifeq ($(PLATFORM),i86-FAST) -OBJ=error.o sys_errlist.o perror.o sys_siglist.o __assert.o -else ifeq ($(LIB_OS),ELKS) + +ifneq ($(LIB_CPU),i86) OBJ=error2.o perror.o sys_siglist.o __assert.o else -OBJ=__assert.o +OBJ=error.o sys_errlist.o perror.o sys_siglist.o __assert.o endif + +else +OBJ=__assert.o endif all: $(LIBC)($(OBJ)) diff --git a/libc/i386fp/Makefile b/libc/i386fp/Makefile index 298ca18..e26ce21 100644 --- a/libc/i386fp/Makefile +++ b/libc/i386fp/Makefile @@ -9,12 +9,12 @@ FPSRC =fadd.x fcomp.x fdiv.x fmul.x fbsr.x \ fperr.c fperror.x fptoi.x fpushd.x fpulld.x \ fpushi.x fpushf.x fpullf.x frexp.x ftst.x \ gcclib.x \ - fabs.x ldexp.x modf.c \ + fabs.x ldexp.x ecvt.c \ fperr.h fplib.h FPOBJ =fadd.o fcomp.o fdiv.o fmul.o fpbsr.o \ fperr.o fperror.o fptoi.o fpushd.o fpulld.o \ fpushi.o fpushf.o fpullf.o frexp.o ftst.o \ - fabs.o ldexp.o modf.o + fabs.o ldexp.o ecvt.o LIB =. CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) diff --git a/libc/i386fp/ecvt.c b/libc/i386fp/ecvt.c new file mode 100644 index 0000000..6e0cef1 --- /dev/null +++ b/libc/i386fp/ecvt.c @@ -0,0 +1,122 @@ + +#define DIGMAX 30 /* max # of digits in string */ +#define DIGPREC 17 /* max # of significant digits */ +#define ECVT 0 +#define FCVT 1 +static char digstr[DIGMAX + 1 + 1]; /* +1 for end of string */ + + /* +1 in case rounding adds */ + /* another digit */ +static double negtab[] = + { 1e-256, 1e-128, 1e-64, 1e-32, 1e-16, 1e-8, 1e-4, 1e-2, 1e-1, 1.0 }; +static double postab[] = + { 1e+256, 1e+128, 1e+64, 1e+32, 1e+16, 1e+8, 1e+4, 1e+2, 1e+1 }; + +static char *_cvt(); + +/************************* + * Convert double val to a string of + * decimal digits. + * ndig = # of digits in resulting string + * Returns: + * *pdecpt = position of decimal point from left of first digit + * *psign = nonzero if value was negative + */ +char * +ecvt(val, ndig, pdecpt, psign) +double val; +int ndig, *pdecpt, *psign; + +{ + return _cvt(ECVT, val, ndig, pdecpt, psign); +} + +char * +fcvt(val, nfrac, pdecpt, psign) +double val; +int nfrac, *pdecpt, *psign; + +{ + return _cvt(FCVT, val, nfrac, pdecpt, psign); +} + +static char * +_cvt(cnvflag, val, ndig, pdecpt, psign) +double val; +int ndig, *pdecpt, *psign; + +{ + int decpt, pow, i; + char *p; + *psign = (val < 0) ? ((val = -val), 1) : 0; + ndig = (ndig < 0) ? 0 : (ndig < DIGMAX) ? ndig : DIGMAX; + if (val == 0) { + for (p = &digstr[0]; p < &digstr[ndig]; p++) + *p = '0'; + decpt = 0; + } else { + /* Adjust things so that 1 <= val < 10 */ + /* in these loops if val == MAXDOUBLE) */ + decpt = 1; + pow = 256; + i = 0; + while (val < 1) { + while (val < negtab[i + 1]) { + val /= negtab[i]; + decpt -= pow; + } + pow >>= 1; + i++; + } + pow = 256; + i = 0; + while (val >= 10) { + while (val >= postab[i]) { + val /= postab[i]; + decpt += pow; + } + pow >>= 1; + i++; + } + if (cnvflag == FCVT) { + ndig += decpt; + ndig = (ndig < 0) ? 0 : (ndig < DIGMAX) ? ndig : DIGMAX; + } + + /* Pick off digits 1 by 1 and stuff into digstr[] */ + /* Do 1 extra digit for rounding purposes */ + for (p = &digstr[0]; p <= &digstr[ndig]; p++) { + int n; + + /* 'twould be silly to have zillions of digits */ + /* when only DIGPREC are significant */ + if (p >= &digstr[DIGPREC]) + *p = '0'; + + else { + n = val; + *p = n + '0'; + val = (val - n) * 10; /* get next digit */ + } + } + if (*--p >= '5') { /* if we need to round */ + while (1) { + if (p == &digstr[0]) { /* if at start */ + ndig += cnvflag; + decpt++; /* shift dec pnt */ + digstr[0] = '1'; /* "100000..." */ + break; + } + *p = '0'; + --p; + if (*p != '9') { + (*p)++; + break; + } + } /* while */ + } /* if */ + } /* else */ + *pdecpt = decpt; + digstr[ndig] = 0; /* terminate string */ + return &digstr[0]; +} diff --git a/libc/i386sys/Makefile b/libc/i386sys/Makefile index 756ce43..665f71a 100644 --- a/libc/i386sys/Makefile +++ b/libc/i386sys/Makefile @@ -12,7 +12,7 @@ DSRC=dirent.c DOBJ=opendir.o closedir.o readdir.o ifeq ($(LIB_CPU)-$(LIB_OS),i386-ELKS) -OBJ=$(LOBJ3) $(LOBJ) $(EOBJ) $(DOBJ) +OBJ=$(LOBJ3) $(LOBJ) $(EOBJ) $(DOBJ) setjmp3.o SYSCALLS=syscalls CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) diff --git a/libc/i386sys/setjmp3.c b/libc/i386sys/setjmp3.c new file mode 100644 index 0000000..160795d --- /dev/null +++ b/libc/i386sys/setjmp3.c @@ -0,0 +1,56 @@ + +#include <setjmp.h> + +#if __AS386_32__ + +int +setjmp(env) +jmp_buf env; +{ +#asm +export __setjmp +__setjmp: + + pop ecx ! PC +#if __FIRST_ARG_IN_AX__ + mov ebx,eax +#else + mov ebx,esp + mov ebx,[ebx] ! TOS is prt -> env +#endif + mov [ebx+0],ecx ! PC + mov [ebx+4],esp ! This registers are all that may be constant. + mov [ebx+8],ebp + mov [ebx+12],esi ! Is saving these the "right thing" ? + mov [ebx+16],edi + xor eax,eax + jmp ecx +#endasm +} + +void +longjmp(env, rv) +jmp_buf env; +int rv; +{ +#asm +export __longjmp +__longjmp: + + pop ecx ! pc +#if __FIRST_ARG_IN_AX__ + mov ebx,eax ! env-> +#else + pop ebx ! env-> +#endif + pop eax ! rv + mov ecx,[ebx+0] ! PC + mov esp,[ebx+4] + mov ebp,[ebx+8] + mov esi,[ebx+12] + mov edi,[ebx+16] + jmp ecx +#endasm +} + +#endif diff --git a/libc/i386sys/syscall.dat b/libc/i386sys/syscall.dat index da9ad6c..595e75a 100644 --- a/libc/i386sys/syscall.dat +++ b/libc/i386sys/syscall.dat @@ -1,4 +1,3 @@ - # # Name No Args Flag, comment # @@ -6,6 +5,8 @@ # * = Needs libc code (Prefix __) # - = Obsolete/not required # +# Last updated 2005-01-01 +# # Name N C setup 0 X exit 1 1 * @@ -60,7 +61,7 @@ signal 48 2 geteuid 49 0 getegid 50 0 acct 51 1 -phys 52 X - +umount2 52 X - lock 53 X - ioctl 54 3 fcntl 55 3 @@ -111,7 +112,7 @@ statfs 99 2 fstatfs 100 2 ioperm 101 3 socketcall 102 2 * This is a lib internal for socket stuff -klog 103 X +syslog 103 X setitimer 104 3 getitimer 105 2 dv32_stat 106 2 * Has correct args for 32 bit dev_t @@ -121,7 +122,7 @@ olduname 109 X - iopl 110 1 vhangup 111 0 idle 112 0 - System internal -vm86 113 1 +vm86 113 1 * WARNING now vm86old wait4 114 4 swapoff 115 1 sysinfo 116 1 @@ -152,4 +153,133 @@ _llseek 140 X getdents 141 3 * New style readdir ? _newselect 142 X flock 143 2 -syscall_flock 143 X +msync 144 X +readv 145 X +writev 146 X +getsid 147 X +fdatasync 148 X +_sysctl 149 X +mlock 150 X +munlock 151 X +mlockall 152 X +munlockall 153 X +sched_setparam 154 X +sched_getparam 155 X +sched_setscheduler 156 X +sched_getscheduler 157 X +sched_yield 158 X +sched_get_priority_max 159 X +sched_get_priority_min 160 X +sched_rr_get_interval 161 X +nanosleep 162 2 +mremap 163 X +setresuid 164 X +getresuid 165 X +vm86 166 X +query_module 167 X +poll 168 X +nfsservctl 169 X +setresgid 170 X +getresgid 171 X +prctl 172 X +rt_sigreturn 173 X +rt_sigaction 174 X +rt_sigprocmask 175 X +rt_sigpending 176 X +rt_sigtimedwait 177 X +rt_sigqueueinfo 178 X +rt_sigsuspend 179 X +pread64 180 X +pwrite64 181 X +chown 182 X +getcwd 183 X +capget 184 X +capset 185 X +sigaltstack 186 X +sendfile 187 X +getpmsg 188 X +putpmsg 189 X +vfork 190 X +ugetrlimit 191 X +mmap2 192 X +truncate64 193 X +ftruncate64 194 X +stat64 195 X +lstat64 196 X +fstat64 197 X +lchown32 198 X +getuid32 199 X +getgid32 200 X +geteuid32 201 X +getegid32 202 X +setreuid32 203 X +setregid32 204 X +getgroups32 205 X +setgroups32 206 X +fchown32 207 X +setresuid32 208 X +getresuid32 209 X +setresgid32 210 X +getresgid32 211 X +chown32 212 X +setuid32 213 X +setgid32 214 X +setfsuid32 215 X +setfsgid32 216 X +pivot_root 217 X +mincore 218 X +madvise 219 X +madvise1 219 X +getdents64 220 X +fcntl64 221 X +Unused 223 X - /* is unused */ +gettid 224 X +readahead 225 X +setxattr 226 X +lsetxattr 227 X +fsetxattr 228 X +getxattr 229 X +lgetxattr 230 X +fgetxattr 231 X +listxattr 232 X +llistxattr 233 X +flistxattr 234 X +removexattr 235 X +lremovexattr 236 X +fremovexattr 237 X +tkill 238 X +sendfile64 239 X +futex 240 X +sched_setaffinity 241 X +sched_getaffinity 242 X +set_thread_area 243 X +get_thread_area 244 X +io_setup 245 X +io_destroy 246 X +io_getevents 247 X +io_submit 248 X +io_cancel 249 X +fadvise64 250 X +Unused 251 X - /* is unused */ +exit_group 252 X +lookup_dcookie 253 X +epoll_create 254 X +epoll_ctl 255 X +epoll_wait 256 X +remap_file_pages 257 X +set_tid_address 258 X +timer_create 259 X +timer_settime (__NR_timer_create+1) X +timer_gettime (__NR_timer_create+2) X +timer_getoverrun (__NR_timer_create+3) X +timer_delete (__NR_timer_create+4) X +clock_settime (__NR_timer_create+5) X +clock_gettime (__NR_timer_create+6) X +clock_getres (__NR_timer_create+7) X +clock_nanosleep (__NR_timer_create+8) X +statfs64 268 X +fstatfs64 269 X +tgkill 270 X +utimes 271 X +fadvise64_64 272 X +vserver 273 X diff --git a/libc/include/stdarg.h b/libc/include/stdarg.h index f5f6fbf..c5fcfac 100644 --- a/libc/include/stdarg.h +++ b/libc/include/stdarg.h @@ -26,6 +26,7 @@ #ifndef __STDARG_H #define __STDARG_H +#include <features.h> #ifdef sparc # define _VA_ALIST_ "__builtin_va_alist" diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index aeb7a43..11699ca 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -24,10 +24,10 @@ extern unsigned long strtoul __P ((const char * nptr, char ** endptr, int base)); #ifndef __HAS_NO_FLOATS__ extern double strtod __P ((const char * nptr, char ** endptr)); +extern double atof __P ((__const char *__nptr)); #endif extern long int atol __P ((__const char *__nptr)); -extern double atof __P ((__const char *__nptr)); extern int atoi __P ((__const char *__nptr)); /* Returned by `div'. */ diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h index ce975f0..bf41935 100644 --- a/libc/include/sys/cdefs.h +++ b/libc/include/sys/cdefs.h @@ -10,7 +10,9 @@ /* This is not a typedef so `const __ptr_t' does the right thing. */ #define __ptr_t void * +#ifndef __HAS_NO_FLOATS__ typedef long double __long_double_t; +#endif #else diff --git a/libc/misc/Makefile b/libc/misc/Makefile index b779802..85614a7 100644 --- a/libc/misc/Makefile +++ b/libc/misc/Makefile @@ -27,7 +27,7 @@ endif # No ELKS strtod() until BCC does 16 bit FP... ifneq ($(LIB_CPU),i86) -OBJ+=strtod.o +OBJ+=strtod.o atof.o endif CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) diff --git a/libc/misc/atof.c b/libc/misc/atof.c new file mode 100644 index 0000000..aeadaa5 --- /dev/null +++ b/libc/misc/atof.c @@ -0,0 +1,16 @@ +/* Copyright (C) Robert de Bath <robert@debath.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +double +#ifdef __STDC__ +atof(const char *p) +#else +atof(p) +char *p; +#endif +{ + return strtod(p, (char**)0); +} + diff --git a/libc/misc/strtod.c b/libc/misc/strtod.c index cef9d9f..8acb423 100644 --- a/libc/misc/strtod.c +++ b/libc/misc/strtod.c @@ -20,9 +20,6 @@ #include <stdlib.h> #include <ctype.h> -#ifndef __AS386_16__ -/* BCC-16 has broken FP code */ - double strtod(const char *nptr, char ** endptr) { @@ -97,4 +94,3 @@ strtod(const char *nptr, char ** endptr) } return (negative ? -number:number); } -#endif diff --git a/libc/stdio/Makefile b/libc/stdio/Makefile index 3c85f40..221ad8f 100644 --- a/libc/stdio/Makefile +++ b/libc/stdio/Makefile @@ -12,7 +12,7 @@ AOBJ=_stdio_init.o fputc.o fgetc.o fflush.o fgets.o gets.o fputs.o \ fclose.o fseek.o rewind.o ftell.o setbuffer.o setvbuf.o ungetc.o PSRC=printf.c -POBJ=printf.o sprintf.o fprintf.o vprintf.o vsprintf.o vfprintf.o +POBJ=printf.o sprintf.o fprintf.o vprintf.o vsprintf.o vfprintf.o fp_print.o SSRC=scanf.c SOBJ=scanf.o sscanf.o fscanf.o vscanf.o vsscanf.o vfscanf.o diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c index 6e7b3e1..b7b0b81 100644 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -129,7 +129,7 @@ static FILE string[1] = #ifdef L_vfprintf -#ifdef FLOATS +#ifndef __HAS_NO_FLOATS__ int (*__fp_print)() = 0; #endif @@ -344,7 +344,7 @@ register va_list ap; sign, pad, width, preci, buffer_mode); break; -#if FLOATS +#ifndef __HAS_NO_FLOATS__ case 'e': /* float */ case 'f': case 'g': @@ -378,3 +378,72 @@ register va_list ap; return (cnt); } #endif + +#ifdef L_fp_print +#ifndef __HAS_NO_FLOATS__ + +#ifdef __AS386_16__ +#asm + loc 1 ! Make sure the pointer is in the correct segment +auto_func: ! Label for bcc -M to work. + .word ___xfpcvt ! Pointer to the autorun function + .text ! So the function after is also in the correct seg. +#endasm +#endif + +#ifdef __AS386_32__ +#asm + loc 1 ! Make sure the pointer is in the correct segment +auto_func: ! Label for bcc -M to work. + .long ___xfpcvt ! Pointer to the autorun function + .text ! So the function after is also in the correct seg. +#endasm +#endif + +void +__fp_print_func(pval, style, preci, ptmp) + double * pval; + int style; + int preci; + char * ptmp; +{ + int decpt, negative; + char * cvt; + double val = *pval; + + if (preci < 0) preci = 6; + + cvt = fcvt(val, preci, &decpt, &negative); + if(negative) + *ptmp++ = '-'; + + if (decpt<0) { + *ptmp++ = '0'; + *ptmp++ = '.'; + while(decpt<0) { + *ptmp++ = '0'; decpt++; + } + } + + while(*cvt) { + *ptmp++ = *cvt++; + if (decpt == 1) + *ptmp++ = '.'; + decpt--; + } + + while(decpt > 0) { + *ptmp++ = '0'; + decpt--; + } +} + +void +__xfpcvt() +{ + extern int (*__fp_print)(); + __fp_print = __fp_print_func; +} + +#endif +#endif diff --git a/makefile.in b/makefile.in index 5a10e73..2f3832c 100644 --- a/makefile.in +++ b/makefile.in @@ -26,8 +26,9 @@ MAKEX= # inside an archive to get the last modified times of the component .o # files. This should be fine for Linux, but it won't be for AIX etc. # Unfortunatly it's even _required_ for linux because some versions -# of Redhat have a broken standard ar command. -#ifdef __linux_i386__ +# have a broken standard ar command. Ie they barf if given something +# they think is not an a.out. +#ifdef __linux__ AR=ar86 #endif @@ -59,12 +60,12 @@ CFLAGS=-O -m -w -DPOSIX_HEADERS_MISSING -DVERY_SMALL_MEMORY #ifdef __BCC__ ANSI =-ansi #ifdef __AS386_32__ -CFLAGS =-3 -LDFLAGS =-3 -s -N +CFLAGS =-Ml +LDFLAGS =-Ml -s #else -CFLAGS =-0 -LDFLAGS =-0 -s -H10000 -BCCARCH =-Mf -O +CFLAGS =-O +LDFLAGS =-s -H10000 +BCCARCH = #endif #endif @@ -87,7 +88,7 @@ EXE= #endif #ifdef GNUMAKE -all: check_config bcc cpp unproto copt as86 ar86 ld86 objdump86 \ +all: check_config bcc86 cpp unproto copt as86 ar86 ld86 objdump86 \ library lib-bsd alt-libs elksemu install: check_config install-bcc install-man \ @@ -96,7 +97,7 @@ install: check_config install-bcc install-man \ install-all: install install-other #else -all: check_config bcc cpp unproto copt as86 ar86 ld86 objdump86 +all: check_config bcc86 cpp unproto copt as86 ar86 ld86 objdump86 @echo @echo 'NOTE: To build the libraries you need GNU-Make.' @echo ' They are available precompiled in the Dev86clb-X.X.X.zip file.' @@ -148,7 +149,7 @@ bindir: $(MAKEX) @ln -s ../kinclude/arch include/arch 2>/dev/null || true #endif -bcc: bindir +bcc86: bindir echo '#define VERSION "'"$(VERSION)"'"' > bcc/version.h VER=$(VERSION) ; \ echo "#define VER_MAJ $${VER%%.*}" >> bcc/version.h ; \ @@ -172,6 +173,9 @@ copt: bindir $(MAKEC) copt $(MAKEARG) copt cp -p copt/copt$(EXE) lib/copt$(EXE) cp -p copt/rules.* lib/. + cp -p copt/rules.start lib/i386/. + cp -p copt/rules.386 lib/i386/. + cp -p copt/rules.end lib/i386/. as86: bindir echo '#define VERSION "'"$(VERSION)"'"' > as/version.h @@ -197,7 +201,7 @@ objdump86: bindir cp -p ld/objdump86$(EXE) bin/objdump86$(EXE) #ifndef __AS386_16__ -#ifdef __linux_i386__ +#ifdef __elksemu_works__ elksemu: bindir $(MAKEC) elksemu elksemu cp -p elksemu/elksemu bin/elksemu @@ -208,7 +212,7 @@ elksemu: bindir #endif #endif -install-bcc: bcc cpp unproto copt as86 ar86 ld86 objdump86 +install-bcc: bcc86 cpp unproto copt as86 ar86 ld86 objdump86 install -d $(DISTBIN) $(DISTLIB) install $(INEXE) bin/Bcc$(EXE) $(DISTBIN)/bcc$(EXE) install $(INEXE) bin/as86$(EXE) $(DISTASLD)/as86$(EXE) @@ -223,10 +227,12 @@ install-bcc: bcc cpp unproto copt as86 ar86 ld86 objdump86 install $(INEXE) lib/unproto$(EXE) $(DISTLIB)/unproto$(EXE) install $(INEXE) lib/copt$(EXE) $(DISTLIB)/copt$(EXE) install $(INDAT) lib/rules.* $(DISTLIB) + install -d $(DISTLIB)/i386 + install $(INDAT) lib/i386/rules.* $(DISTLIB)/i386 # NB: This doesn't install as a suid root, that's ok though. install-emu: elksemu -#ifdef __linux_i386__ +#ifdef __elksemu_works__ install -d $(DISTBIN) install $(INEXE) bin/elksemu $(DISTBIN)/elksemu #endif @@ -162,16 +162,17 @@ as -Ofile) produce object file .TP .B -f -error (float emulation not supported) +turn on floating point support, no effect with i386, changes libc library +with 8086 code. .TP .B -g -produce debugging info (does nothing) +produce debugging info (ignored.) .TP .B -o output file name follows (assembler, object or executable) (as usual) .TP .B -p -error (profiling not supported) +produce profiling info (ignored.) .TP .B -t1 pass to the assembler to renumber the text segment for multi-segment programs. |