summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>2005-01-23 15:31:04 +0100
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:48:50 +0200
commit62c27c1c5cb6257b13dfc9be0394e0d2e86f2735 (patch)
treef702b7e5f80293367e1b6f9812bd45e80378be26
parent6cb598cc5f1c8ae6d14381c2776338584368257e (diff)
downloaddev86-62c27c1c5cb6257b13dfc9be0394e0d2e86f2735.tar.gz
Import Dev86src-0.16.17.tar.gzv0.16.17
-rw-r--r--Changes16
-rw-r--r--Makefile8
-rw-r--r--as/readsrc.c49
-rw-r--r--as/table.c16
-rw-r--r--bcc/Makefile10
-rw-r--r--bcc/bcc-cc1.c1
-rw-r--r--bcc/bcc.c19
-rw-r--r--bcc/const.h19
-rw-r--r--bcc/dbnode.c200
-rw-r--r--bcc/dbprintf.c257
-rw-r--r--bcc/debug.c386
-rw-r--r--bcc/debug.h38
-rw-r--r--bcc/declare.c5
-rw-r--r--bcc/function.c2
-rw-r--r--bcc/gencode.c18
-rw-r--r--bcc/gencode.h4
-rw-r--r--bcc/genloads.c1
-rw-r--r--bcc/hashcmd.c192
-rw-r--r--bcc/input.c74
-rw-r--r--bcc/output.c7
-rw-r--r--bcc/proto.h6
-rw-r--r--bcc/scan.c2
-rw-r--r--bcc/softop.c2
-rw-r--r--bcc/table.c2
-rw-r--r--copt/rules.867
-rw-r--r--cpp/cc.h1
-rw-r--r--cpp/cpp.c32
-rw-r--r--cpp/hash.c1
-rw-r--r--ifdef.c6
-rw-r--r--ld/mkar.c5
-rw-r--r--ld/obj.h4
-rw-r--r--ld/objdump86.c15
-rw-r--r--libc/error/Makefile10
-rw-r--r--libc/i386fp/Makefile4
-rw-r--r--libc/i386fp/ecvt.c122
-rw-r--r--libc/i386sys/Makefile2
-rw-r--r--libc/i386sys/setjmp3.c56
-rw-r--r--libc/i386sys/syscall.dat140
-rw-r--r--libc/include/stdarg.h1
-rw-r--r--libc/include/stdlib.h2
-rw-r--r--libc/include/sys/cdefs.h2
-rw-r--r--libc/misc/Makefile2
-rw-r--r--libc/misc/atof.c16
-rw-r--r--libc/misc/strtod.c4
-rw-r--r--libc/stdio/Makefile2
-rw-r--r--libc/stdio/printf.c73
-rw-r--r--makefile.in32
-rw-r--r--man/bcc.17
48 files changed, 1532 insertions, 348 deletions
diff --git a/Changes b/Changes
index 78a0c27..35fa465 100644
--- a/Changes
+++ b/Changes
@@ -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
diff --git a/Makefile b/Makefile
index 1b4de4a..b34dd33 100644
--- a/Makefile
+++ b/Makefile
@@ -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';
diff --git a/as/table.c b/as/table.c
index 9c70015..eb9a24d 100644
--- a/as/table.c
+++ b/as/table.c
@@ -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();
diff --git a/bcc/bcc.c b/bcc/bcc.c
index be7ee96..9e5269f 100644
--- a/bcc/bcc.c
+++ b/bcc/bcc.c
@@ -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));
diff --git a/bcc/scan.c b/bcc/scan.c
index 36271e4..7db7629 100644
--- a/bcc/scan.c
+++ b/bcc/scan.c
@@ -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
diff --git a/cpp/cc.h b/cpp/cc.h
index 9bb7ebd..9c298e7 100644
--- a/cpp/cc.h
+++ b/cpp/cc.h
@@ -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 */
};
diff --git a/cpp/cpp.c b/cpp/cpp.c
index 7d287f4..616cf87 100644
--- a/cpp/cpp.c
+++ b/cpp/cpp.c
@@ -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);
diff --git a/cpp/hash.c b/cpp/hash.c
index 7cab819..6013c54 100644
--- a/cpp/hash.c
+++ b/cpp/hash.c
@@ -2,6 +2,7 @@
#include <stdio.h>
#ifdef __STDC__
#include <stdlib.h>
+#include <string.h>
#else
#include <malloc.h>
#endif
diff --git a/ifdef.c b/ifdef.c
index 7289dc1..5f67acf 100644
--- a/ifdef.c
+++ b/ifdef.c
@@ -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__
diff --git a/ld/mkar.c b/ld/mkar.c
index 96163b7..8c4eb5b 100644
--- a/ld/mkar.c
+++ b/ld/mkar.c
@@ -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;
diff --git a/ld/obj.h b/ld/obj.h
index 7159a5d..ddfa7a1 100644
--- a/ld/obj.h
+++ b/ld/obj.h
@@ -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
diff --git a/man/bcc.1 b/man/bcc.1
index fd9b0c6..21a1d64 100644
--- a/man/bcc.1
+++ b/man/bcc.1
@@ -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.