EarlyC/prestructc/c10.c

Find at most related files.
including files from this version of Unix.

/*

	    	C compiler, part 2

	Copyright 1972 Bell Telephone Laboratories, Inc.

*/

waste()		/* waste space */
{
	waste(waste(waste),waste(waste),waste(waste));
	waste(waste(waste),waste(waste),waste(waste));
	waste(waste(waste),waste(waste),waste(waste));
	waste(waste(waste),waste(waste),waste(waste));
	waste(waste(waste),waste(waste),waste(waste));
	waste(waste(waste),waste(waste),waste(waste));
	waste(waste(waste),waste(waste),waste(waste));
	waste(waste(waste),waste(waste),waste(waste));
}
main(argc, argv)
char argv[][];
{
	extern fout, fin, nerror, line;
	extern getwrd, rcexpr, tmpfil;
	extern cctab[], regtab[], efftab[], sptab[];
	int sp[], c, table[], tabtab[3][], tree;

	if (argc<4) {
		error("Arg count");
		exit(1);
	}
	if((fin=open(argv[1],0))<0) {
		error("Cant't find %s", argv[1]);
		exit(1);
	}
	if((fout=creat(argv[3],017))<0) {
		error("Can't create %s", argv[3]);
		exit(1);
	}
	tmpfil = argv[2];

	tabtab[0] = regtab;
	tabtab[1] = efftab;
	tabtab[2] = cctab;
	tabtab[3] = sptab;
	while(c=getchar()) {
		if(c=='#') {
			sp = 0;
			c = getwrd();
			tree = getwrd();
			table = tabtab[getwrd()];
			line = getwrd();
			while(c--)
				*sp++ = getwrd();
			rcexpr(tree, table, 0);
		} else
			putchar(c);
	}
	flush();
	exit(nerror!=0);
}

match(tree, table, nreg)
int tree[], table[]; {
	extern opdope[], cctab, maprel;
	int op, d1, d2, t1, t2, p1[], p2[], dope, cctab[];
	int maprel[];
	char mp[];

	if (tree==0)
		return(0);
	op = *tree;
	if (op>=29)			/* if not leaf */
		p1 = tree[3];
	else
		p1 = tree;
	t1 = p1[1];
	d1 = dcalc(p1, nreg);
	if (((dope=opdope[op])&01)!=0) {	/* binary? */
		p2 = tree[4];
		t2 = p2[1];
		d2 = dcalc(p2, nreg);
		if (d2>d1 & (dope&0100)!=0)	/* commute? */
		    if (table!=cctab | (op!=47&op!=48)) { /* commute? */
			if ((dope&04)!=0)	/* relation? */
				*tree = op = maprel[op-60];
			dope = t1;
			t1 = t2;
			t2 = dope;
			dope = p1;
			tree[3] = p1 = p2;
			tree[4] = p2 = dope;
			dope = d1;
			d1 = d2;
			d2 = dope;
			dope = t1;
			t1 = t2;
			t2 = dope;
		}
	}
	while(*table) {
		if (*table++ == op) goto foundop;
		table++;
	}
	return(0);
foundop:
	table = *table;
nxtry:
	mp = table;
	if (*mp == 0)
		return(0);
	if (d1 > (*mp&077) | (*mp>=0100)&(*p1!=36))
		goto notyet;
	if (notcompat(t1, mp[1]))
		goto notyet;
	if ((opdope[op]&01)!=0 & p2!=0) {
		if (d2 > (mp[2]&077) | (mp[2]>=0100)&(*p2!=36))
			goto notyet;
		if (notcompat(t2,mp[3]))
			goto notyet;
	}
now:
	return(table[2]);
notyet:
	table = table+3;
	goto nxtry;
}

rcexpr(tree, table, reg)
int tree[]; {
	extern cexpr, regtab, cctab, sptab, printf, error;
	extern jumpc, cbranch;
	int r, modf;

	if(tree==0)
		return(0);
	if(*tree == 103 | *tree==104) {
		(*tree==103?jumpc:cbranch)(tree[1],tree[2],tree[3],0);
		return(0);
	}
	modf = isfloat(tree)? 'f':0;
	if (*tree == 110) {			/* force r0 */
		if((r=rcexpr(tree[3], table, reg)) != 0)
			printf("mov%c	r%d,r0\n", modf, r);
		return(0);
	}
	if ((r=cexpr(tree, table, reg))>=0)
		return(r);
	if (table!=regtab) 
		if((r=cexpr(tree, regtab, reg))>=0) {
			if (table==sptab)
				printf("mov%c	r%d,-(sp)\n", modf, r);
			if (table==cctab) {
				if (modf=='f')
					printf("cfcc\n");
				printf("tst%c	r%d\n", modf, r);
			}
			return(0);
		}
	error("No match for op %d", *tree);
}

cexpr(tree, table, reg)
int tree[][], table[]; {
	extern match, nreg, printf, pname, putchar, regtab;
	extern sptab, cctab, rcexpr, prins, rlength, popstk;
	extern collcon, isn, label, branch, cbranch;
	extern maprel[];
	int p1[], p2[], c, r, p[], otable[], ctable[], regtab[], cctab[];
	int sptab[];
	char string[], match[];
	int reg1, rreg;

	if ((c = *tree)==100) {		/* call */
		p1 = tree[3];
		p2 = tree[4];
		r = 0;
		if(*p2) {
			while (*p2==9) { /* comma */
				rcexpr(p2[4], sptab, 0);
				r =+ arlength((p=p2[4])[1]);
				p2 = p2[3];
			}
			rcexpr(p2, sptab, 0);
			r =+ arlength(p2[1]);
		}
		*tree = 101;
		tree[2] = r;		/* save arg length */
	}
	if(c==90) {		/* ? */
		cbranch(tree[3], c=isn++, 0, reg);
		rcexpr(tree[4][3], table, reg);
		branch(r=isn++, 0);
		label(c);
		reg = rcexpr(tree[4][4], table, reg);
		label(r);
		goto retrn;
	}
	reg = oddreg(tree, reg);
	reg1 = reg+1;
	if ((string=match(tree, table, nreg-reg))==0) 
		return(-1);
	p1 = tree[3];
	p2 = tree[4];
loop:
	switch(c = *string++) {

	case '\0':
		p = tree;
		if (*p==101) {
			if (p[2]>0)
				popstk(p[2]);
			reg = 0;
		}
retrn:
		c = isfloat(tree);
		if (table==cctab & c)
			printf("cfcc\n");
		if (!c)
			if ((c = *tree)==43 | c==73)
				reg--;
		return(reg);

	/* A1 */
	case 'A':
		p = tree[3];
		goto adr;

	/* A2 */
	case 'B':
		p = tree[4];
		goto adr;

	/* A */
	case 'O':
		p = tree;
	adr:
		pname(p);
		goto loop;

	/* I */
	case 'M':
		if ((c = *string)=='\'')
			string++; else
			c = 0;
		prins(*tree, c);
		goto loop;

	/* B1 */
	case 'C':
		if ((c = *tree)<28)
			p = tree;
		else
			p = tree[3];
		goto pbyte;

	/* BF */
	case 'P':
		p = tree;
		goto pb1;

	/* B2 */
	case 'D':
		p = tree[4];
	pbyte:
		if (p[1]==1)	/* char type? */
			putchar('b');
	pb1:
		if (isfloat(p))
			putchar('f');
		goto loop;

	/* BE */
	case 'L':
		if (tree[3][1]==1 | tree[4][1]==1)
			putchar('b');
		p = tree;
		goto pb1;

	/* C1 */
	case 'E':
		p = p1[3];
		goto const;

	/* C2 */
	case 'F':
		p = p2[3];
	const:
		printf("%o", p);
		goto loop;

	/* F */
	case 'G':
		p = p1;
		goto subtre;

	/* S */
	case 'K':
		p = p2;
		goto subtre;

	/* H */
	case 'H':
		p = tree;

	subtre:
		ctable = regtab;
		r = reg;
		c = *string++ - 'A';
		if ((c&02)!=0)
			ctable = sptab;
		if ((c&04)!=0)
			ctable = cctab;
		if((c&010)!=0)
			r = reg1;
		if((c&01)!=0)
			if(*p==36) {
				p = p[3];
				if(collcon(p) & ctable!=sptab)
					p = p[3];
			}
		rreg = rcexpr(p, ctable, r);
		if (rreg==r | ctable!=regtab)
			goto loop;
		if (string[-2]=='G')	/* left operand */
			if (oddreg(tree, 0)==1) {
				printf("mov	r%d,r%d\n", rreg, r);
				goto loop;
			}
		if (r==reg) {
			reg = rreg;
			reg1 = rreg+1;
		} else
			reg1 = rreg;
		goto loop;

	/* R */
	case 'I':
		r = reg;
		if (*string=='-') {
			string++;
			r--;
		}
		goto preg;

	/* R1 */
	case 'J':
		r = reg1;
	preg:
		if (r>=5)
			error("Register overflow: simplify expression");
		printf("r%d", r);
		goto loop;

	case '#':
		p = p1[3];
		goto nmbr;

	case '"':
		p = p2[3];
		goto nmbr;

	case '~':
		p = tree[3];

	nmbr:
		if(collcon(p)) {
			if (*p==41)			/* - */
				putchar('-');
			switch (*(p = p[4])) {

			case 21:		/* number */
				if (p[3])
					printf("%d.", p[3]);
				break;

			case 35:		/* & name */
				pname(p[3]);
				break;

			}
	}
		goto loop;

	/* V */
	case 'V':
		tree[0] = maprel[(c=tree[0])-60];
		goto loop;

	/* Z */
	case 'Z':
		printf("$%o", p1[5]+p1[4]);
		goto loop;

	case '^':		/* for ++ -- */
		printf("%o", tree[4]);
		goto loop;
	}
	putchar(c);
	goto loop;
}

pname(p)
int p[][]; {
	char np[];
	int i;

loop:
	switch(*p) {

	case 21:		/* const */
		printf("$%o", p[3]);
		return;

	case 23:		/* float const */
		printf("L%d", p[3]);
		return;

	casename:
	case 20:		/* name */
		if (i=p[4])
			printf("%d.+", i);
		switch(p[3]) {

		case 5:		/* auto, param */
			printf("%d.(r5)", p[5]);
			return;

		/* extern */
		case 6:
			printf("%p", &p[5]);
			return;

		case 4:
			error("Illegal structure reference");
			printf("$0");
			return;

		}
		printf("L%d", p[5]);
		return;

	case 35:		/* & */
		putchar('$');
		p = p[3];
		goto loop;

	case 36:		/* * */
		putchar('*');
		p = p[3];
		goto loop;

	}
	error("pname called illegally");
}

dcalc(p, nreg)
int p[]; {
	int op, t, p1[], p2[];

	if (p==0)
		return(0);
	op = *p;
	switch (op) {

	case 20:		/* name */
	case 35:		/* & (non-automatic) */
		return(12);

	case 21:		/* short constant */
		return(p[3]==0? 4:8);

	case 23:		/* float const */
		return(p[3]==0? 4:12);

	case 36:		/* * */
		p1 = p[3];
		if (*p1==20)		/* name or offset name */
			return(12);
	}

def:
	return(p[2]<=nreg? 20: 24);
}

notcompat(at, st) {

	if (st==0)		/* word, byte */
		return(at>1 & at<=07);
	if (st==1)		/* word */
		return(at>0 & at<=07);
	st =- 2;
	if ((at&077740) != 0)
		at = 020;		/* *int for **stuff */
	if ((at&077770) != 0)
		at = at&07 | 020;
	if (st==2 & at==3)
		at = 2;
	return(st != at);
}

prins(op, c) {
	extern instab[], printf;
	int insp[];

	insp = instab;
	while(*insp) {
		if (*insp++ == op) {
			if ((c = insp[c!=0])==0)
				goto err;
			printf("%s", c);
			return;
		} else
			insp = insp + 2;
	}
err:
	error("No match' for op %d", op);
}

collcon(p)
int p[]; {
	int p1[], t[];

	if(*p==40 | *p==41) {
		if(*(p1=p[4])==21) {	/* number */
			return(1);
		}
		if (*p1==35)
			return(1);
		if (*(p1=p[3])==35) {
			p1 = p[3];
			p[3] = p[4];
			p[4] = p1;
			return(1);
		}
	}
	return(0);
}

isfloat(t)
int t[];
{
	extern opdope[];
	int rt;

	if ((opdope[t[0]]&04)!=0)	/* relational */
		t = t[3];
	if ((rt=t[1])>=2 & rt<=3)
		return(rt);
	return(0);
}

nreg 3;
isn 10000;
namsiz 8;
line;
tmpfil;
nerror;

oddreg(t, reg)
int t[];
{
	if (!isfloat(t))
		switch(*t) {
		case 43:	/* / */
		case 44:	/* % */
		case 73:	/* =/ */
		case 74:	/* =% */
			reg++;

		case 42:	/* * */
		case 72:	/* =* */
			return(reg|1);
		}
	return(reg);
}

arlength(t)
{
	int arl;

	if ((arl=rlength(t)) == 4)
		return(8);
	return(arl);
}

maprel[] 60, 61, 64, 65, 62, 63, 68, 69, 66, 67;