File:  [MW Coherent from dump] / coherent / b / bin / c / n1 / cc1.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:37 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * n1/cc1.c
 * This is the mainline of the new, direct to bits code generator.
 * It is mainly just a driving routine.
 * The tree reader and the diagnostic routines are also in this file.
 * Everything in here is machine independent.
 */

#ifdef	vax
#include "INC$LIB:cc1.h"
#else
#include "cc1.h"
#endif

#if	!OVERLAID
FILE	*ifp;			/* Input file */
FILE	*ofp;			/* Output file */
char	file[NFNAME];		/* File name */
char	module[NMNAME];		/* Module name */
int	line;			/* Line number */
char	id[NCSYMB];		/* Temp. id buffer */
VARIANT	variant;		/* Variant template */
#if !TINY
int	mflag;			/* Debug modify routines */
int	sflag;			/* Debug select routines */
int	oflag;			/* Debug output routines */
#endif
#endif

int	qccmp();		/* Quicksort compare */
SYM	*hash1[NSHASH];		/* Hash table */
int	nnsw;			/* Switch nesting level */
int	nsw[NNSW];		/* Switch label */
CASES	*cases;			/* Case buffer */

#if !OVERLAID
/*
 * Mainline.
 * Interpret options and
 * open files.
 */
main(argc, argv)
char *argv[];
{
	passname = "cc1";
	if (argc < 4)
		usage();
	getvariant(argv[1]);
#if GEMDOS
	{
		extern long gemdos();
		extern char *lmalloc();
		free(lmalloc((gemdos(0x48,-1L)-4096) & ~1023L));
	}
#endif
	if ((ifp=fopen(argv[2], SRMODE)) == NULL) {
		fprintf(stderr, "%s: cannot open.\n", argv[2]);
		exit(BAD);
	}
	if ((ofp=fopen(argv[3], SWMODE)) == NULL) {
		fprintf(stderr, "%s: cannot create.\n", argv[3]);
		exit(BAD);
	}
#if !TINY
	if (argc > 4)
		mflag = atoi(argv[4]);
	if (argc > 5)
		sflag = atoi(argv[5]);
	if (argc > 6)
		oflag = atoi(argv[6]);
#endif
	labgen = 10000;
	oldseg = -1;
	work1();
	if (nerr != 0)
		exit(BAD);
	exit(OK);
}

/*
 * Print usage message.
 */
usage()
{
#if !TINY
	fprintf(stderr,
		"Usage: cc1 variant in out [mlevel [slevel [olevel]]]\n");
#else
	fprintf(stderr, "Usage: cc1 variant in out\n");
#endif
	exit(BAD);
}
#else
/*
 * Mainline for the overlaid version
 * of the coder. The files are already open.
 * Set up for fatal errors. Process the file
 * and return status.
 */
cc1()
{
	passname = "cc1";
	if (setjmp(death) != 0) {
		freetree();
		freepool();
		freegsym();
		return (ABORT);
	}
	labgen = 10000;
	oldseg = -1;
#if MONOLITHIC
	nnsw = 0;
#endif
	work1();
	freetree();
	freepool();
	freegsym();
	if (nerr != 0)
		return (BAD);
	return (OK);
}
#endif

/*
 * Read temp. file.
 * Do simple things right here.
 * Read in trees and pass them over
 * to the tree compilation code.
 */
work1()
{
	register int	i;
	register int	op;
	register TREE	*tp;
	register int	d;
	register int	n;
	register int	tt;
	register int	ln;

	coderinit();
	for (;;) {
		op = bget();
		switch (op) {

		case LINE:
			line = iget();
			/* bput(op); */
			/* iput(line); */
			break;

		case DLABEL:
			bput(DLABEL);
			tcpy(bget());
			break;

		case MNAME:
			sget(module, NMNAME);
			bput(op);
			sput(module);
			break;

		case FNAME:
			sget(file, NFNAME);
			/* bput(op); */
			/* sput(file); */
			break;

		case GLABEL:
		case SLABEL:
			sget(id, NCSYMB);
			bput(op);
			sput(id);
			break;

		case COMM:
			bput(op);
			sget(id, NCSYMB);
			sput(id);
			zput(zget());
			break;

		case LLABEL:
			bput(op);
			iput(iget());
			break;

		case BLOCK:
			bput(op);
			zput(zget());
			break;

		case JUMP:
			genubr(iget());
			break;

		case ENTER:
			newseg(bget());
			break;

		case AUTOS:
			doautos();
			break;

		case PROLOG:
			bput(PROLOG);
			doprolog();
			break;

		case ALIGN:
			bput(ALIGN);
			bput(bget());
			break;

		case EPILOG:
			doepilog();
			bput(EPILOG);
			break;

		case EEXPR:
			tp = modify(treeget(), MEFFECT);
			code(tp, MEFFECT, 0, 0);
			break;

		case IBLOCK:
			iblock(bget());
			break;

		case IEXPR:
			tp = treeget();
			tt = tp->t_type;
			tp = modify(tp->t_lp, MINIT);
			iexpr(tp, tt);
			break;

		case FEXPR:
		case TEXPR:
			ln = iget();
			tp = modify(treeget(), MFLOW);
			code(tp, MFLOW, op==TEXPR, ln);
			break;

		case REXPR:
			tp = modify(treeget(), MRETURN);
			code(tp, MRETURN, 0, 0);
			break;

		case SEXPR:
			if (nnsw >= NNSW)
				cfatal("switch overflow");
			nsw[nnsw++] = n = newlab();
			tp = modify(treeget(), MSWITCH);
			code(tp, MSWITCH, 0, 0);
			genubr(n);
			break;

		case SBODY:
			if (nnsw <= 0)
				cbotch("switch underflow");
			genlab(nsw[--nnsw]);
			d = iget();
			n = iget();
			if (n != 0) {
				cases = (CASES *)malloc(n*sizeof(CASES));
				if (cases == NULL)
					cfatal("too many cases");
				for (i=0; i<n; ++i) {
					cases[i].c_val = iget();
					cases[i].c_lab = iget();
				}
				shellsort((char *)cases, n, sizeof(cases[0]), &qccmp);
			}
			genswitch(d, n);
			if (n != 0)
				free((char *)cases);
			break;

		case FINISH:
			bput(op);
			return;

		case EOF:
			cfatal("unexpected EOF");

		default:
			cbotch("bad temporary file opcode %d", op);
		}
	}
}

/*
 * This routine is used by the library
 * quicksort routine to compare two elements
 * in the case constant buffer.
 */
qccmp(a, b)
struct cases *a, *b;
{
	return (a->c_val - b->c_val);
}

/*
 * Generate a local label.
 */
genlab(n)
{
	bput(LLABEL);
	iput((ival_t)n);
}

/* end of n1/cc1.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.