diff options
author | Robert de Bath <rdebath@poboxes.com> | 2005-01-23 15:31:04 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:48:50 +0200 |
commit | 62c27c1c5cb6257b13dfc9be0394e0d2e86f2735 (patch) | |
tree | f702b7e5f80293367e1b6f9812bd45e80378be26 /bcc | |
parent | 6cb598cc5f1c8ae6d14381c2776338584368257e (diff) | |
download | dev86-62c27c1c5cb6257b13dfc9be0394e0d2e86f2735.tar.gz |
Import Dev86src-0.16.17.tar.gzv0.16.17
Diffstat (limited to 'bcc')
-rw-r--r-- | bcc/Makefile | 10 | ||||
-rw-r--r-- | bcc/bcc-cc1.c | 1 | ||||
-rw-r--r-- | bcc/bcc.c | 19 | ||||
-rw-r--r-- | bcc/const.h | 19 | ||||
-rw-r--r-- | bcc/dbnode.c | 200 | ||||
-rw-r--r-- | bcc/dbprintf.c | 257 | ||||
-rw-r--r-- | bcc/debug.c | 386 | ||||
-rw-r--r-- | bcc/debug.h | 38 | ||||
-rw-r--r-- | bcc/declare.c | 5 | ||||
-rw-r--r-- | bcc/function.c | 2 | ||||
-rw-r--r-- | bcc/gencode.c | 18 | ||||
-rw-r--r-- | bcc/gencode.h | 4 | ||||
-rw-r--r-- | bcc/genloads.c | 1 | ||||
-rw-r--r-- | bcc/hashcmd.c | 192 | ||||
-rw-r--r-- | bcc/input.c | 74 | ||||
-rw-r--r-- | bcc/output.c | 7 | ||||
-rw-r--r-- | bcc/proto.h | 6 | ||||
-rw-r--r-- | bcc/scan.c | 2 | ||||
-rw-r--r-- | bcc/softop.c | 2 | ||||
-rw-r--r-- | bcc/table.c | 2 |
20 files changed, 993 insertions, 252 deletions
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; |