⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c10.c

📁 unix v6 的c compiler 很老了
💻 C
📖 第 1 页 / 共 2 页
字号:
#/*	    	C compiler, part 2*/#include "c1h.c"char	maprel[] {	EQUAL, NEQUAL, GREATEQ, GREAT, LESSEQ,			LESS, GREATQP, GREATP, LESSEQP, LESSP};char	notrel[] {	NEQUAL, EQUAL, GREAT, GREATEQ, LESS,			LESSEQ, GREATP, GREATQP, LESSP, LESSEQP};struct tconst czero { CON, INT, 0, 0};struct tconst cone  { CON, INT, 0, 1};struct tconst fczero { SFCON, DOUBLE, 0, 0 };struct	table	*cregtab;int	nreg	3;int	isn	10000;int	namsiz	8;main(argc, argv)char *argv[];{	extern fout;	if (argc<4) {		error("Arg count");		exit(1);	}	if(fopen(argv[1], ascbuf)<0) {		error("Missing temp file");		exit(1);	}	if ((fout = creat(argv[3], 0666)) < 0) {		error("Can't create %s", argv[3]);		exit(1);	}	spacep = treespace;	getree();	/*	 * If any floating-point instructions	 * were used, generate a reference which	 * pulls in the floating-point part of printf.	 */	if (nfloat)		printf(".globl	fltused\n");	/*	 * tack on the string file.	 */	close(ascbuf[0]);	if (fopen(argv[2], ascbuf)<0) {		error("Missing temp file");		exit(1);	}	printf(".globl\n.data\n");	getree();	flush();	exit(nerror!=0);}/* * Given a tree, a code table, and a * count of available registers, find the code table * for the appropriate operator such that the operands * are of the right type and the number of registers * required is not too large. * Return a ptr to the table entry or 0 if none found. */char *match(atree, table, nrleft)struct tnode *atree;struct table *table;{	int op, d1, d2, t1, t2, dope;	struct tnode *p2;	register struct tnode *p1, *tree;	register struct optab *opt;	if ((tree=atree)==0)		return(0);	if (table==lsptab)		table = sptab;	if ((op = tree->op)==0)		return(0);	dope = opdope[op];	if ((dope&LEAF) == 0)		p1 = tree->tr1;	else		p1 = tree;	t1 = p1->type;	d1 = dcalc(p1, nrleft);	if ((dope&BINARY)!=0) {		p2 = tree->tr2;		/*		 * If a subtree starts off with a conversion operator,		 * try for a match with the conversion eliminated.		 * E.g. int = double can be done without generating		 * the converted int in a register by		 * movf double,fr0; movfi fr0,int .		 */		if(opdope[p1->op]&CNVRT && (opdope[p2->op]&CNVRT)==0) {			tree->tr1 = p1->tr1;			if (opt = match(tree, table, nrleft))				return(opt);			tree->tr1 = p1;		} else if (opdope[p2->op]&CNVRT && (opdope[p1->op]&CNVRT)==0) {			tree->tr2 = p2->tr1;			if (opt = match(tree, table, nrleft))				return(opt);			tree->tr2 = p2;		}		t2 = p2->type;		d2 = dcalc(p2, nrleft);	}	for (; table->op!=op; table++)		if (table->op==0)			return(0);	for (opt = table->tabp; opt->tabdeg1!=0; opt++) {		if (d1 > (opt->tabdeg1&077)		 || (opt->tabdeg1 >= 0100 && (p1->op != STAR)))			continue;		if (notcompat(p1, opt->tabtyp1, op)) {			continue;		}		if ((opdope[op]&BINARY)!=0 && p2!=0) {			if (d2 > (opt->tabdeg2&077)			 || (opt->tabdeg2 >= 0100) && (p2->op != STAR) )				continue;			if (notcompat(p2,opt->tabtyp2, 0))				continue;		}		return(opt);	}	return(0);}/* * Given a tree, a code table, and a register, * produce code to evaluate the tree with the appropriate table. * Registers reg and upcan be used. * If there is a value, it is desired that it appear in reg. * The routine returns the register in which the value actually appears. * This routine must work or there is an error. * If the table called for is cctab, sptab, or efftab, * and tree can't be done using the called-for table, * another try is made. * If the tree can't be compiled using cctab, regtab is * used and a "tst" instruction is produced. * If the tree can't be compiled using sptab, * regtab is used and the register is pushed on the stack. * If the tree can't be compiled using efftab, * just use regtab. * Regtab must succeed or an "op not found" error results. * * A number of special cases are recognized, and * there is an interaction with the optimizer routines. */rcexpr(atree, atable, reg)struct tnode *atree;struct table *atable;{	register r;	int modf, nargs, recurf;	register struct tnode *tree;	register struct table *table;	table = atable;	recurf = 0;	if (reg<0) {		recurf++;		reg = ~reg;		if (reg>=020) {			reg =- 020;			recurf++;		}	}	if((tree=atree)==0)		return(0);	switch (tree->op)  {	/*	 * A conditional branch	 */	case CBRANCH:		cbranch(optim(tree->btree), tree->lbl, tree->cond, 0);		return(0);	/*	 * An initializing expression	 */	case INIT:		if (tree->tr1->op == AMPER)			tree->tr1 = tree->tr1->tr1;		if (tree->tr1->op==NAME)			pname(tree->tr1);		else if (tree->tr1==CON)			psoct(tree->tr1->value);		else			error("Illegal initialization");		putchar('\n');		return(0);	/*	 * Put the value of an expression in r0,	 * for a switch or a return	 */	case RFORCE:		if((r=rcexpr(tree->tr1, regtab, reg)) != 0)			printf("mov%c	r%d,r0\n", isfloat(tree->tr1), r);		return(0);	/*	 * sequential execution	 */	case COMMA:		rcexpr(tree->tr1, efftab, reg);		atree = tree = tree->tr2;		break;	/*	 * In the generated &~ operator,	 * fiddle things so a PDP-11 "bit"	 * instruction will be produced when cctab is used.	 */	case NAND:		if (table==cctab) {			tree->op = TAND;			tree->tr2 = optim(block(1, COMPL, INT, 0, tree->tr2));		}		break;	/*	 * Handle a subroutine call. It has to be done	 * here because if cexpr got called twice, the	 * arguments might be compiled twice.	 * There is also some fiddling so the	 * first argument, in favorable circumstances,	 * goes to (sp) instead of -(sp), reducing	 * the amount of stack-popping.	 */	case CALL:		r = 0;		nargs = 0;		modf = 0;		if (tree->tr1->op!=NAME) {	/* get nargs right */			nargs++;			nstack++;		}		tree = tree->tr2;		if(tree->op) {			while (tree->op==COMMA) {				r =+ comarg(tree->tr2, &modf);				tree = tree->tr1;				nargs++;			}			r =+ comarg(tree, &modf);			nargs++;		}		tree = atree;		tree->op = CALL2;		if (modf && tree->tr1->op==NAME && tree->tr1->class==EXTERN)			tree->op = CALL1;		cexpr(tree, regtab, reg);		popstk(r);		nstack =- nargs;		if (table==efftab || table==regtab)			return(0);		r = 0;		goto fixup;	/*	 * Longs need special treatment.	 */	case ASLSH:	case LSHIFT:		if (tree->type==LONG) {			if (tree->tr2->op==ITOL)				tree->tr2 = tree->tr2->tr1;			if (tree->op==ASLSH)				tree->op = ASLSHL;			else				tree->op = LLSHIFT;		}		break;	/*	 * Try to change * and / to shifts.	 */	case TIMES:	case DIVIDE:	case ASTIMES:	case ASDIV:		tree = pow2(tree);	}	/*	 * Try to find postfix ++ and -- operators that can be	 * pulled out and done after the rest of the expression	 */	if (table!=cctab && table!=cregtab && recurf<2	 && (opdope[tree->op]&LEAF)==0) {		if (r=delay(&atree, table, reg)) {			tree = atree;			table = efftab;			reg = r-1;		}	}	/*	 * Basically, try to reorder the computation	 * so  reg = x+y  is done as  reg = x; reg =+ y	 */	if (recurf==0 && reorder(&atree, table, reg)) {		if (table==cctab && atree->op==NAME)			return(reg);	}	tree = atree;	if (table==efftab && tree->op==NAME)		return(reg);	if ((r=cexpr(tree, table, reg))>=0)		return(r);	if (table!=regtab)  {		if((r=cexpr(tree, regtab, reg))>=0) {	fixup:			modf = isfloat(tree);			if (table==sptab || table==lsptab) {				if (tree->type==LONG) {					printf("mov\tr%d,-(sp)\n",r+1);					nstack++;				}				printf("mov%c	r%d,%c(sp)\n", modf, r,					table==sptab? '-':0);				nstack++;			}			if (table==cctab)				printf("tst%c	r%d\n", modf, r);			return(r);		}	}	if (tree->op>0 && tree->op<RFORCE && opntab[tree->op])		error("No code table for op: %s", opntab[tree->op]);	else		error("No code table for op %d", tree->op);	return(reg);}/* * Try to compile the tree with the code table using * registers areg and up.  If successful, * return the register where the value actually ended up. * If unsuccessful, return -1. * * Most of the work is the macro-expansion of the * code table. */cexpr(atree, table, areg)struct tnode *atree;struct table *table;{	int c, r;	register struct tnode *p, *p1, *tree;	struct table *ctable;	struct tnode *p2;	char *string;	int reg, reg1, rreg, flag, opd;	char *opt;	tree = atree;	reg = areg;	p1 = tree->tr2;	c = tree->op;	opd = opdope[c];	/*	 * When the value of a relational or a logical expression is	 * desired, more work must be done.	 */	if ((opd&RELAT||c==LOGAND||c==LOGOR||c==EXCLA) && table!=cctab) {		cbranch(tree, c=isn++, 1, reg);		rcexpr(&czero, table, reg);		branch(isn, 0);		label(c);		rcexpr(&cone, table, reg);		label(isn++);		return(reg);	}	if(c==QUEST) {		if (table==cctab)			return(-1);		cbranch(tree->tr1, c=isn++, 0, reg);		flag = nstack;		rreg = rcexpr(p1->tr1, table, reg);		nstack = flag;		branch(r=isn++, 0);		label(c);		reg = rcexpr(p1->tr2, table, rreg);		if (rreg!=reg)			printf("mov%c	r%d,r%d\n",			    isfloat(tree),reg,rreg);		label(r);		return(rreg);	}	reg = oddreg(tree, reg);	reg1 = reg+1;	/*	 * long values take 2 registers.	 */	if (tree->type==LONG && tree->op!=ITOL)		reg1++;	/*	 * Leaves of the expression tree	 */	if ((r = chkleaf(tree, table, reg)) >= 0)		return(r);	/*	 * x + (-1) is better done as x-1.	 */	if ((tree->op==PLUS||tree->op==ASPLUS) &&	    (p1=tree->tr2)->op == CON && p1->value == -1) {		p1->value = 1;		tree->op =+ (MINUS-PLUS);	}	if (table==cregtab)		table = regtab;	/*	 * The following peculiar code depends on the fact that	 * if you just want the codition codes set, efftab	 * will generate the right code unless the operator is	 * postfix ++ or --. Unravelled, if the table is	 * cctab and the operator is not special, try first	 * for efftab;  if the table isn't, if the operator is,	 * or the first match fails, try to match	 * with the table actually asked for.	 */	if (table!=cctab || c==INCAFT || c==DECAFT	 || (opt = match(tree, efftab, nreg-reg)) == 0)		if ((opt=match(tree, table, nreg-reg))==0)			return(-1);	string = opt->tabstring;	p1 = tree->tr1;	p2 = 0;	if (opdope[tree->op]&BINARY)		p2 = tree->tr2;loop:	/*	 * The 0200 bit asks for a tab.	 */	if ((c = *string++) & 0200) {		c =& 0177;		putchar('\t');	}	switch (c) {	case '\0':		if (!isfloat(tree))			if (tree->op==DIVIDE || tree->op==ASDIV)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -