xref: /csrg-svn/old/pcc/mip/common.c (revision 32806)
1 /*	common.c	4.4	87/12/09	*/
2 
3 #ifdef PASS1COMMON
4 #include "pass1.h"
5 #else
6 #ifdef PASS2COMMON
7 #include "pass2.h"
8 #endif
9 #endif
10 
11 #ifdef FORT
12 #undef BUFSTDERR
13 #endif
14 #ifndef ONEPASS
15 #undef BUFSTDERR
16 #endif
17 # ifndef EXIT
18 # define EXIT exit
19 # endif
20 
21 int nerrors = 0;  /* number of errors */
22 
23 extern unsigned int offsz;
24 
25 unsigned caloff(){
26 	register i;
27 	unsigned int temp;
28 	unsigned int off;
29 	temp = 1;
30 	i = 0;
31 	do {
32 		temp <<= 1;
33 		++i;
34 		} while( temp != 0 );
35 	off = 1 << (i-1);
36 	return (off);
37 	}
38 
39 NODE *lastfree;  /* pointer to last free node; (for allocator) */
40 
41 	/* VARARGS1 */
42 uerror( s, a ) char *s; { /* nonfatal error message */
43 	/* the routine where is different for pass 1 and pass 2;
44 	/*  it tells where the error took place */
45 
46 	++nerrors;
47 	where('u');
48 	fprintf( stderr, s, a );
49 	fprintf( stderr, "\n" );
50 #ifdef BUFSTDERR
51 	fflush(stderr);
52 #endif
53 	if( nerrors > 30 ) cerror( "too many errors");
54 	}
55 
56 	/* VARARGS1 */
57 cerror( s, a, b, c ) char *s; { /* compiler error: die */
58 	where('c');
59 	if( nerrors && nerrors <= 30 ){ /* give the compiler the benefit of the doubt */
60 		fprintf( stderr, "cannot recover from earlier errors: goodbye!\n" );
61 		}
62 	else {
63 		fprintf( stderr, "compiler error: " );
64 		fprintf( stderr, s, a, b, c );
65 		fprintf( stderr, "\n" );
66 		}
67 #ifdef BUFSTDERR
68 	fflush(stderr);
69 #endif
70 	EXIT(1);
71 	}
72 
73 int Wflag = 0; /* Non-zero means do not print warnings */
74 
75 	/* VARARGS1 */
76 werror( s, a, b ) char *s; {  /* warning */
77 	if(Wflag) return;
78 	where('w');
79 	fprintf( stderr, "warning: " );
80 	fprintf( stderr, s, a, b );
81 	fprintf( stderr, "\n" );
82 #ifdef BUFSTDERR
83 	fflush(stderr);
84 #endif
85 	}
86 
87 tinit(){ /* initialize expression tree search */
88 
89 	register NODE *p;
90 
91 	for( p=node; p<= &node[TREESZ-1]; ++p ) p->in.op = FREE;
92 	lastfree = node;
93 
94 	}
95 
96 # define TNEXT(p) (p== &node[TREESZ-1]?node:p+1)
97 
98 NODE *
99 talloc(){
100 	register NODE *p, *q;
101 
102 	q = lastfree;
103 	for( p = TNEXT(q); p!=q; p= TNEXT(p))
104 		if( p->in.op ==FREE )
105 			return(lastfree=p);
106 
107 	cerror( "out of tree space; simplify expression");
108 	/* NOTREACHED */
109 	}
110 
111 tcheck(){ /* ensure that all nodes have been freed */
112 
113 	register NODE *p;
114 
115 	if( !nerrors )
116 		for( p=node; p<= &node[TREESZ-1]; ++p )
117 			if( p->in.op != FREE )
118 				cerror( "wasted space: %o", p );
119 	tinit();
120 #ifdef FLEXNAMES
121 	freetstr();
122 #endif
123 	}
124 tfree( p )  NODE *p; {
125 	/* free the tree p */
126 	extern tfree1();
127 
128 	if( p->in.op != FREE ) walkf( p, tfree1 );
129 
130 	}
131 
132 tfree1(p)  NODE *p; {
133 	if( p == 0 ) cerror( "freeing blank tree!");
134 	else p->in.op = FREE;
135 	}
136 
137 fwalk( t, f, down ) register NODE *t; int (*f)(); {
138 
139 	int down1, down2;
140 
141 	more:
142 	down1 = down2 = 0;
143 
144 	(*f)( t, down, &down1, &down2 );
145 
146 	switch( optype( t->in.op ) ){
147 
148 	case BITYPE:
149 		fwalk( t->in.left, f, down1 );
150 		t = t->in.right;
151 		down = down2;
152 		goto more;
153 
154 	case UTYPE:
155 		t = t->in.left;
156 		down = down1;
157 		goto more;
158 
159 		}
160 	}
161 
162 #ifndef vax
163 walkf( t, f ) register NODE *t;  int (*f)(); {
164 	register opty;
165 
166 	opty = optype(t->in.op);
167 
168 	if( opty != LTYPE ) walkf( t->in.left, f );
169 	if( opty == BITYPE ) walkf( t->in.right, f );
170 	(*f)( t );
171 	}
172 #else
173 #define	NR	100
174 
175 /*
176  * Deliberately avoids recursion -- use this version on machines with
177  * expensive procedure calls.
178  */
179 walkf(t, f)
180 	register NODE *t;
181 	register int (*f)();
182 {
183 	register int i = 1;
184 	register int opty = optype(t->in.op);
185 	static NODE *at[NR];
186 	static int ao[NR];
187 
188 #define	PUSH(dir, state) \
189 	(ao[i] = state, at[i++] = t, t = t->in.dir, opty = optype(t->in.op))
190 #define	POP() \
191 	(opty = ao[--i], t = at[i])
192 
193 	do {
194 		switch (opty) {
195 		case LTYPE:	(*f)(t); POP(); break;
196 		case UTYPE:	PUSH(left, LTYPE); break;
197 		case BITYPE:	PUSH(left, BITYPE+1); break;
198 		case BITYPE+1:	PUSH(right, LTYPE); break;
199 		default:
200 			cerror("bad op type in walkf");
201 		}
202 		if (i >= NR) {
203 			walkf(t, f);
204 			POP();
205 		}
206 	} while (i > 0);
207 }
208 #undef NR
209 #undef PUSH
210 #undef POP
211 #endif
212 
213 
214 
215 int dope[ DSIZE ];
216 char *opst[DSIZE];
217 
218 struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = {
219 
220 	NAME, "NAME", LTYPE,
221 	STRING, "STRING", LTYPE,
222 	REG, "REG", LTYPE,
223 	OREG, "OREG", LTYPE,
224 	ICON, "ICON", LTYPE,
225 	FCON, "FCON", LTYPE,
226 	DCON, "DCON", LTYPE,
227 	CCODES, "CCODES", LTYPE,
228 	UNARY MINUS, "U-", UTYPE,
229 	UNARY MUL, "U*", UTYPE,
230 	UNARY AND, "U&", UTYPE,
231 	UNARY CALL, "UCALL", UTYPE|CALLFLG,
232 	UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG,
233 	NOT, "!", UTYPE|LOGFLG,
234 	COMPL, "~", UTYPE,
235 	FORCE, "FORCE", UTYPE,
236 	INIT, "INIT", UTYPE,
237 	SCONV, "SCONV", UTYPE,
238 	PCONV, "PCONV", UTYPE,
239 	PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG,
240 	ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG,
241 	MINUS, "-", BITYPE|FLOFLG|SIMPFLG,
242 	ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG,
243 	MUL, "*", BITYPE|FLOFLG|MULFLG,
244 	ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG,
245 	AND, "&", BITYPE|SIMPFLG|COMMFLG,
246 	ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG,
247 	QUEST, "?", BITYPE,
248 	COLON, ":", BITYPE,
249 	ANDAND, "&&", BITYPE|LOGFLG,
250 	OROR, "||", BITYPE|LOGFLG,
251 	CM, ",", BITYPE,
252 	COMOP, ",OP", BITYPE,
253 	ASSIGN, "=", BITYPE|ASGFLG,
254 	DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG,
255 	ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG,
256 	MOD, "%", BITYPE|DIVFLG,
257 	ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG,
258 	LS, "<<", BITYPE|SHFFLG,
259 	ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
260 	RS, ">>", BITYPE|SHFFLG,
261 	ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
262 	OR, "|", BITYPE|COMMFLG|SIMPFLG,
263 	ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
264 	ER, "^", BITYPE|COMMFLG|SIMPFLG,
265 	ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
266 	INCR, "++", BITYPE|ASGFLG,
267 	DECR, "--", BITYPE|ASGFLG,
268 	STREF, "->", BITYPE,
269 	CALL, "CALL", BITYPE|CALLFLG,
270 	FORTCALL, "FCALL", BITYPE|CALLFLG,
271 	EQ, "==", BITYPE|LOGFLG,
272 	NE, "!=", BITYPE|LOGFLG,
273 	LE, "<=", BITYPE|LOGFLG,
274 	LT, "<", BITYPE|LOGFLG,
275 	GE, ">", BITYPE|LOGFLG,
276 	GT, ">", BITYPE|LOGFLG,
277 	UGT, "UGT", BITYPE|LOGFLG,
278 	UGE, "UGE", BITYPE|LOGFLG,
279 	ULT, "ULT", BITYPE|LOGFLG,
280 	ULE, "ULE", BITYPE|LOGFLG,
281 #ifdef ARS
282 	ARS, "A>>", BITYPE,
283 #endif
284 	TYPE, "TYPE", LTYPE,
285 	LB, "[", BITYPE,
286 	CBRANCH, "CBRANCH", BITYPE,
287 	FLD, "FLD", UTYPE,
288 	PMCONV, "PMCONV", BITYPE,
289 	PVCONV, "PVCONV", BITYPE,
290 	RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG,
291 	CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG,
292 	GOTO, "GOTO", UTYPE,
293 	STASG, "STASG", BITYPE|ASGFLG,
294 	STARG, "STARG", UTYPE,
295 	STCALL, "STCALL", BITYPE|CALLFLG,
296 	UNARY STCALL, "USTCALL", UTYPE|CALLFLG,
297 
298 	-1,	"",	0
299 };
300 
301 mkdope(){
302 	register struct dopest *q;
303 
304 	for( q = indope; q->dopeop >= 0; ++q ){
305 		dope[q->dopeop] = q->dopeval;
306 		opst[q->dopeop] = q->opst;
307 		}
308 	}
309 # ifndef BUG4
310 tprint( t )  TWORD t; { /* output a nice description of the type of t */
311 
312 	static char * tnames[] = {
313 		"undef",
314 		"farg",
315 		"char",
316 		"short",
317 		"int",
318 		"long",
319 		"float",
320 		"double",
321 		"strty",
322 		"unionty",
323 		"enumty",
324 		"moety",
325 		"uchar",
326 		"ushort",
327 		"unsigned",
328 		"ulong",
329 		"?", "?"
330 		};
331 
332 	for(;; t = DECREF(t) ){
333 
334 		if( ISPTR(t) ) printf( "PTR " );
335 		else if( ISFTN(t) ) printf( "FTN " );
336 		else if( ISARY(t) ) printf( "ARY " );
337 		else {
338 			printf( "%s", tnames[t] );
339 			return;
340 			}
341 		}
342 	}
343 # endif
344 
345 #ifdef FLEXNAMES
346 #define	NTSTRBUF	40
347 #define	TSTRSZ		2048
348 char	itstrbuf[TSTRSZ];
349 char	*tstrbuf[NTSTRBUF] = { itstrbuf };
350 char	**curtstr = tstrbuf;
351 int	tstrused;
352 char	*malloc();
353 char	*strcpy();
354 
355 char *
356 tstr(cp)
357 	register char *cp;
358 {
359 	register int i = strlen(cp);
360 	register char *dp;
361 
362 	if (tstrused + i >= TSTRSZ) {
363 		if (++curtstr >= &tstrbuf[NTSTRBUF])
364 			cerror("out of temporary string space");
365 		tstrused = 0;
366 		if (*curtstr == 0) {
367 			dp = malloc(TSTRSZ);
368 			if (dp == 0)
369 				cerror("out of memory (tstr)");
370 			*curtstr = dp;
371 		}
372 	}
373 	(void) strcpy(dp = *curtstr+tstrused, cp);
374 	tstrused += i + 1;
375 	return (dp);
376 }
377 #endif
378