xref: /csrg-svn/old/pcc/mip/common.c (revision 34254)
1*34254Sdonn /*	common.c	4.5	88/05/11	*/
218385Sralph 
318385Sralph #ifdef PASS1COMMON
418385Sralph #include "pass1.h"
518385Sralph #else
618385Sralph #ifdef PASS2COMMON
718385Sralph #include "pass2.h"
818385Sralph #endif
918385Sralph #endif
1018385Sralph 
1118385Sralph #ifdef FORT
1218385Sralph #undef BUFSTDERR
1318385Sralph #endif
1418385Sralph #ifndef ONEPASS
1518385Sralph #undef BUFSTDERR
1618385Sralph #endif
1718385Sralph # ifndef EXIT
1818385Sralph # define EXIT exit
1918385Sralph # endif
2018385Sralph 
2118385Sralph int nerrors = 0;  /* number of errors */
2218385Sralph 
2318385Sralph extern unsigned int offsz;
2418385Sralph 
caloff()2518385Sralph unsigned caloff(){
2618385Sralph 	register i;
2718385Sralph 	unsigned int temp;
2818385Sralph 	unsigned int off;
2918385Sralph 	temp = 1;
3018385Sralph 	i = 0;
3118385Sralph 	do {
3218385Sralph 		temp <<= 1;
3318385Sralph 		++i;
3418385Sralph 		} while( temp != 0 );
3518385Sralph 	off = 1 << (i-1);
3618385Sralph 	return (off);
3718385Sralph 	}
3818385Sralph 
3918385Sralph NODE *lastfree;  /* pointer to last free node; (for allocator) */
4018385Sralph 
4118385Sralph 	/* VARARGS1 */
uerror(s,a)4218385Sralph uerror( s, a ) char *s; { /* nonfatal error message */
4318385Sralph 	/* the routine where is different for pass 1 and pass 2;
4418385Sralph 	/*  it tells where the error took place */
4518385Sralph 
4618385Sralph 	++nerrors;
4718385Sralph 	where('u');
4818385Sralph 	fprintf( stderr, s, a );
4918385Sralph 	fprintf( stderr, "\n" );
5018385Sralph #ifdef BUFSTDERR
5118385Sralph 	fflush(stderr);
5218385Sralph #endif
5318385Sralph 	if( nerrors > 30 ) cerror( "too many errors");
5418385Sralph 	}
5518385Sralph 
5618385Sralph 	/* VARARGS1 */
cerror(s,a,b,c)5718385Sralph cerror( s, a, b, c ) char *s; { /* compiler error: die */
5818385Sralph 	where('c');
5918385Sralph 	if( nerrors && nerrors <= 30 ){ /* give the compiler the benefit of the doubt */
6018385Sralph 		fprintf( stderr, "cannot recover from earlier errors: goodbye!\n" );
6118385Sralph 		}
6218385Sralph 	else {
6318385Sralph 		fprintf( stderr, "compiler error: " );
6418385Sralph 		fprintf( stderr, s, a, b, c );
6518385Sralph 		fprintf( stderr, "\n" );
6618385Sralph 		}
6718385Sralph #ifdef BUFSTDERR
6818385Sralph 	fflush(stderr);
6918385Sralph #endif
7018385Sralph 	EXIT(1);
7118385Sralph 	}
7218385Sralph 
7318385Sralph int Wflag = 0; /* Non-zero means do not print warnings */
7418385Sralph 
7518385Sralph 	/* VARARGS1 */
werror(s,a,b)7618385Sralph werror( s, a, b ) char *s; {  /* warning */
7718385Sralph 	if(Wflag) return;
7818385Sralph 	where('w');
7918385Sralph 	fprintf( stderr, "warning: " );
8018385Sralph 	fprintf( stderr, s, a, b );
8118385Sralph 	fprintf( stderr, "\n" );
8218385Sralph #ifdef BUFSTDERR
8318385Sralph 	fflush(stderr);
8418385Sralph #endif
8518385Sralph 	}
8618385Sralph 
tinit()8718385Sralph tinit(){ /* initialize expression tree search */
8818385Sralph 
8924401Smckusick 	register NODE *p;
9018385Sralph 
9118385Sralph 	for( p=node; p<= &node[TREESZ-1]; ++p ) p->in.op = FREE;
9218385Sralph 	lastfree = node;
9318385Sralph 
9418385Sralph 	}
9518385Sralph 
9618385Sralph # define TNEXT(p) (p== &node[TREESZ-1]?node:p+1)
9718385Sralph 
9818385Sralph NODE *
talloc()9918385Sralph talloc(){
10024401Smckusick 	register NODE *p, *q;
10118385Sralph 
10218385Sralph 	q = lastfree;
10318385Sralph 	for( p = TNEXT(q); p!=q; p= TNEXT(p))
10432806Sdonn 		if( p->in.op ==FREE )
10532806Sdonn 			return(lastfree=p);
10618385Sralph 
10718385Sralph 	cerror( "out of tree space; simplify expression");
10818385Sralph 	/* NOTREACHED */
10918385Sralph 	}
11018385Sralph 
tcheck()11118385Sralph tcheck(){ /* ensure that all nodes have been freed */
11218385Sralph 
11324401Smckusick 	register NODE *p;
11418385Sralph 
11518385Sralph 	if( !nerrors )
11618385Sralph 		for( p=node; p<= &node[TREESZ-1]; ++p )
11732806Sdonn 			if( p->in.op != FREE )
11832806Sdonn 				cerror( "wasted space: %o", p );
11918385Sralph 	tinit();
12018385Sralph #ifdef FLEXNAMES
12118385Sralph 	freetstr();
12218385Sralph #endif
12318385Sralph 	}
tfree(p)12418385Sralph tfree( p )  NODE *p; {
12518385Sralph 	/* free the tree p */
12618385Sralph 	extern tfree1();
12718385Sralph 
12818385Sralph 	if( p->in.op != FREE ) walkf( p, tfree1 );
12918385Sralph 
13018385Sralph 	}
13118385Sralph 
tfree1(p)13218385Sralph tfree1(p)  NODE *p; {
13318385Sralph 	if( p == 0 ) cerror( "freeing blank tree!");
13418385Sralph 	else p->in.op = FREE;
13518385Sralph 	}
13618385Sralph 
fwalk(t,f,down)13718385Sralph fwalk( t, f, down ) register NODE *t; int (*f)(); {
13818385Sralph 
13918385Sralph 	int down1, down2;
14018385Sralph 
14118385Sralph 	more:
14218385Sralph 	down1 = down2 = 0;
14318385Sralph 
14418385Sralph 	(*f)( t, down, &down1, &down2 );
14518385Sralph 
14618385Sralph 	switch( optype( t->in.op ) ){
14718385Sralph 
14818385Sralph 	case BITYPE:
14918385Sralph 		fwalk( t->in.left, f, down1 );
15018385Sralph 		t = t->in.right;
15118385Sralph 		down = down2;
15218385Sralph 		goto more;
15318385Sralph 
15418385Sralph 	case UTYPE:
15518385Sralph 		t = t->in.left;
15618385Sralph 		down = down1;
15718385Sralph 		goto more;
15818385Sralph 
15918385Sralph 		}
16018385Sralph 	}
16118385Sralph 
16224401Smckusick #ifndef vax
walkf(t,f)16318385Sralph walkf( t, f ) register NODE *t;  int (*f)(); {
16418385Sralph 	register opty;
16518385Sralph 
16618385Sralph 	opty = optype(t->in.op);
16718385Sralph 
16818385Sralph 	if( opty != LTYPE ) walkf( t->in.left, f );
16918385Sralph 	if( opty == BITYPE ) walkf( t->in.right, f );
17018385Sralph 	(*f)( t );
17118385Sralph 	}
17224401Smckusick #else
173*34254Sdonn #define	NR	32
17418385Sralph 
17524401Smckusick /*
17624401Smckusick  * Deliberately avoids recursion -- use this version on machines with
17724401Smckusick  * expensive procedure calls.
17824401Smckusick  */
walkf(t,f)17924401Smckusick walkf(t, f)
18024401Smckusick 	register NODE *t;
18124401Smckusick 	register int (*f)();
18224401Smckusick {
183*34254Sdonn 	NODE *Aat[NR];
184*34254Sdonn 	int Aao[NR];
18524401Smckusick 	register int i = 1;
18624401Smckusick 	register int opty = optype(t->in.op);
187*34254Sdonn 	register NODE **at = Aat;
188*34254Sdonn 	register int *ao = Aao;
18918385Sralph 
19024401Smckusick #define	PUSH(dir, state) \
19124401Smckusick 	(ao[i] = state, at[i++] = t, t = t->in.dir, opty = optype(t->in.op))
19224401Smckusick #define	POP() \
19324401Smckusick 	(opty = ao[--i], t = at[i])
19418385Sralph 
19524401Smckusick 	do {
19624401Smckusick 		switch (opty) {
19724401Smckusick 		case LTYPE:	(*f)(t); POP(); break;
19824401Smckusick 		case UTYPE:	PUSH(left, LTYPE); break;
19924401Smckusick 		case BITYPE:	PUSH(left, BITYPE+1); break;
20024401Smckusick 		case BITYPE+1:	PUSH(right, LTYPE); break;
20124401Smckusick 		default:
20224401Smckusick 			cerror("bad op type in walkf");
20324401Smckusick 		}
20424401Smckusick 		if (i >= NR) {
20524401Smckusick 			walkf(t, f);
20624401Smckusick 			POP();
20724401Smckusick 		}
20824401Smckusick 	} while (i > 0);
20924401Smckusick }
21024401Smckusick #undef NR
21124401Smckusick #undef PUSH
21224401Smckusick #undef POP
21324401Smckusick #endif
21424401Smckusick 
21524401Smckusick 
21624401Smckusick 
21718385Sralph int dope[ DSIZE ];
21818385Sralph char *opst[DSIZE];
21918385Sralph 
22018385Sralph struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = {
22118385Sralph 
22218385Sralph 	NAME, "NAME", LTYPE,
22318385Sralph 	STRING, "STRING", LTYPE,
22418385Sralph 	REG, "REG", LTYPE,
22518385Sralph 	OREG, "OREG", LTYPE,
22618385Sralph 	ICON, "ICON", LTYPE,
22718385Sralph 	FCON, "FCON", LTYPE,
22818385Sralph 	DCON, "DCON", LTYPE,
22918385Sralph 	CCODES, "CCODES", LTYPE,
23018385Sralph 	UNARY MINUS, "U-", UTYPE,
23118385Sralph 	UNARY MUL, "U*", UTYPE,
23218385Sralph 	UNARY AND, "U&", UTYPE,
23318385Sralph 	UNARY CALL, "UCALL", UTYPE|CALLFLG,
23418385Sralph 	UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG,
23518385Sralph 	NOT, "!", UTYPE|LOGFLG,
23618385Sralph 	COMPL, "~", UTYPE,
23718385Sralph 	FORCE, "FORCE", UTYPE,
23818385Sralph 	INIT, "INIT", UTYPE,
23918385Sralph 	SCONV, "SCONV", UTYPE,
24018385Sralph 	PCONV, "PCONV", UTYPE,
24118385Sralph 	PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG,
24218385Sralph 	ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG,
24318385Sralph 	MINUS, "-", BITYPE|FLOFLG|SIMPFLG,
24418385Sralph 	ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG,
24518385Sralph 	MUL, "*", BITYPE|FLOFLG|MULFLG,
24618385Sralph 	ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG,
24718385Sralph 	AND, "&", BITYPE|SIMPFLG|COMMFLG,
24818385Sralph 	ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG,
24918385Sralph 	QUEST, "?", BITYPE,
25018385Sralph 	COLON, ":", BITYPE,
25118385Sralph 	ANDAND, "&&", BITYPE|LOGFLG,
25218385Sralph 	OROR, "||", BITYPE|LOGFLG,
25318385Sralph 	CM, ",", BITYPE,
25418385Sralph 	COMOP, ",OP", BITYPE,
25518385Sralph 	ASSIGN, "=", BITYPE|ASGFLG,
25618385Sralph 	DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG,
25718385Sralph 	ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG,
25818385Sralph 	MOD, "%", BITYPE|DIVFLG,
25918385Sralph 	ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG,
26018385Sralph 	LS, "<<", BITYPE|SHFFLG,
26118385Sralph 	ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
26218385Sralph 	RS, ">>", BITYPE|SHFFLG,
26318385Sralph 	ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
26418385Sralph 	OR, "|", BITYPE|COMMFLG|SIMPFLG,
26518385Sralph 	ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
26618385Sralph 	ER, "^", BITYPE|COMMFLG|SIMPFLG,
26718385Sralph 	ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
26818385Sralph 	INCR, "++", BITYPE|ASGFLG,
26918385Sralph 	DECR, "--", BITYPE|ASGFLG,
27018385Sralph 	STREF, "->", BITYPE,
27118385Sralph 	CALL, "CALL", BITYPE|CALLFLG,
27218385Sralph 	FORTCALL, "FCALL", BITYPE|CALLFLG,
27318385Sralph 	EQ, "==", BITYPE|LOGFLG,
27418385Sralph 	NE, "!=", BITYPE|LOGFLG,
27518385Sralph 	LE, "<=", BITYPE|LOGFLG,
27618385Sralph 	LT, "<", BITYPE|LOGFLG,
27718385Sralph 	GE, ">", BITYPE|LOGFLG,
27818385Sralph 	GT, ">", BITYPE|LOGFLG,
27918385Sralph 	UGT, "UGT", BITYPE|LOGFLG,
28018385Sralph 	UGE, "UGE", BITYPE|LOGFLG,
28118385Sralph 	ULT, "ULT", BITYPE|LOGFLG,
28218385Sralph 	ULE, "ULE", BITYPE|LOGFLG,
28318385Sralph #ifdef ARS
28418385Sralph 	ARS, "A>>", BITYPE,
28518385Sralph #endif
28618385Sralph 	TYPE, "TYPE", LTYPE,
28718385Sralph 	LB, "[", BITYPE,
28818385Sralph 	CBRANCH, "CBRANCH", BITYPE,
28918385Sralph 	FLD, "FLD", UTYPE,
29018385Sralph 	PMCONV, "PMCONV", BITYPE,
29118385Sralph 	PVCONV, "PVCONV", BITYPE,
29218385Sralph 	RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG,
29318385Sralph 	CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG,
29418385Sralph 	GOTO, "GOTO", UTYPE,
29518385Sralph 	STASG, "STASG", BITYPE|ASGFLG,
29618385Sralph 	STARG, "STARG", UTYPE,
29718385Sralph 	STCALL, "STCALL", BITYPE|CALLFLG,
29818385Sralph 	UNARY STCALL, "USTCALL", UTYPE|CALLFLG,
29918385Sralph 
30018385Sralph 	-1,	"",	0
30118385Sralph };
30218385Sralph 
mkdope()30318385Sralph mkdope(){
30418385Sralph 	register struct dopest *q;
30518385Sralph 
30618385Sralph 	for( q = indope; q->dopeop >= 0; ++q ){
30718385Sralph 		dope[q->dopeop] = q->dopeval;
30818385Sralph 		opst[q->dopeop] = q->opst;
30918385Sralph 		}
31018385Sralph 	}
31118385Sralph # ifndef BUG4
tprint(t)31218385Sralph tprint( t )  TWORD t; { /* output a nice description of the type of t */
31318385Sralph 
31418385Sralph 	static char * tnames[] = {
31518385Sralph 		"undef",
31618385Sralph 		"farg",
31718385Sralph 		"char",
31818385Sralph 		"short",
31918385Sralph 		"int",
32018385Sralph 		"long",
32118385Sralph 		"float",
32218385Sralph 		"double",
32318385Sralph 		"strty",
32418385Sralph 		"unionty",
32518385Sralph 		"enumty",
32618385Sralph 		"moety",
32718385Sralph 		"uchar",
32818385Sralph 		"ushort",
32918385Sralph 		"unsigned",
33018385Sralph 		"ulong",
33118385Sralph 		"?", "?"
33218385Sralph 		};
33318385Sralph 
33418385Sralph 	for(;; t = DECREF(t) ){
33518385Sralph 
33618385Sralph 		if( ISPTR(t) ) printf( "PTR " );
33718385Sralph 		else if( ISFTN(t) ) printf( "FTN " );
33818385Sralph 		else if( ISARY(t) ) printf( "ARY " );
33918385Sralph 		else {
34018385Sralph 			printf( "%s", tnames[t] );
34118385Sralph 			return;
34218385Sralph 			}
34318385Sralph 		}
34418385Sralph 	}
34518385Sralph # endif
34618385Sralph 
34718385Sralph #ifdef FLEXNAMES
34818385Sralph #define	NTSTRBUF	40
34918385Sralph #define	TSTRSZ		2048
35018385Sralph char	itstrbuf[TSTRSZ];
35118385Sralph char	*tstrbuf[NTSTRBUF] = { itstrbuf };
35218385Sralph char	**curtstr = tstrbuf;
35318385Sralph int	tstrused;
35432805Sdonn char	*malloc();
35532805Sdonn char	*strcpy();
35618385Sralph 
35718385Sralph char *
tstr(cp)35818385Sralph tstr(cp)
35918385Sralph 	register char *cp;
36018385Sralph {
36118385Sralph 	register int i = strlen(cp);
36218385Sralph 	register char *dp;
36318385Sralph 
36418385Sralph 	if (tstrused + i >= TSTRSZ) {
36518385Sralph 		if (++curtstr >= &tstrbuf[NTSTRBUF])
36618385Sralph 			cerror("out of temporary string space");
36718385Sralph 		tstrused = 0;
36818385Sralph 		if (*curtstr == 0) {
36932805Sdonn 			dp = malloc(TSTRSZ);
37018385Sralph 			if (dp == 0)
37118385Sralph 				cerror("out of memory (tstr)");
37218385Sralph 			*curtstr = dp;
37318385Sralph 		}
37418385Sralph 	}
37532805Sdonn 	(void) strcpy(dp = *curtstr+tstrused, cp);
37618385Sralph 	tstrused += i + 1;
37718385Sralph 	return (dp);
37818385Sralph }
37918385Sralph #endif
380