xref: /csrg-svn/old/pcc/mip/common.c (revision 32805)
1 /*	common.c	4.3	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 ) return(lastfree=p);
105 
106 	cerror( "out of tree space; simplify expression");
107 	/* NOTREACHED */
108 	}
109 
110 tcheck(){ /* ensure that all nodes have been freed */
111 
112 	register NODE *p;
113 
114 	if( !nerrors )
115 		for( p=node; p<= &node[TREESZ-1]; ++p )
116 			if( p->in.op != FREE ) cerror( "wasted space: %o", p );
117 	tinit();
118 #ifdef FLEXNAMES
119 	freetstr();
120 #endif
121 	}
122 tfree( p )  NODE *p; {
123 	/* free the tree p */
124 	extern tfree1();
125 
126 	if( p->in.op != FREE ) walkf( p, tfree1 );
127 
128 	}
129 
130 tfree1(p)  NODE *p; {
131 	if( p == 0 ) cerror( "freeing blank tree!");
132 	else p->in.op = FREE;
133 	}
134 
135 fwalk( t, f, down ) register NODE *t; int (*f)(); {
136 
137 	int down1, down2;
138 
139 	more:
140 	down1 = down2 = 0;
141 
142 	(*f)( t, down, &down1, &down2 );
143 
144 	switch( optype( t->in.op ) ){
145 
146 	case BITYPE:
147 		fwalk( t->in.left, f, down1 );
148 		t = t->in.right;
149 		down = down2;
150 		goto more;
151 
152 	case UTYPE:
153 		t = t->in.left;
154 		down = down1;
155 		goto more;
156 
157 		}
158 	}
159 
160 #ifndef vax
161 walkf( t, f ) register NODE *t;  int (*f)(); {
162 	register opty;
163 
164 	opty = optype(t->in.op);
165 
166 	if( opty != LTYPE ) walkf( t->in.left, f );
167 	if( opty == BITYPE ) walkf( t->in.right, f );
168 	(*f)( t );
169 	}
170 #else
171 #define	NR	100
172 
173 /*
174  * Deliberately avoids recursion -- use this version on machines with
175  * expensive procedure calls.
176  */
177 walkf(t, f)
178 	register NODE *t;
179 	register int (*f)();
180 {
181 	register int i = 1;
182 	register int opty = optype(t->in.op);
183 	static NODE *at[NR];
184 	static int ao[NR];
185 
186 #define	PUSH(dir, state) \
187 	(ao[i] = state, at[i++] = t, t = t->in.dir, opty = optype(t->in.op))
188 #define	POP() \
189 	(opty = ao[--i], t = at[i])
190 
191 	do {
192 		switch (opty) {
193 		case LTYPE:	(*f)(t); POP(); break;
194 		case UTYPE:	PUSH(left, LTYPE); break;
195 		case BITYPE:	PUSH(left, BITYPE+1); break;
196 		case BITYPE+1:	PUSH(right, LTYPE); break;
197 		default:
198 			cerror("bad op type in walkf");
199 		}
200 		if (i >= NR) {
201 			walkf(t, f);
202 			POP();
203 		}
204 	} while (i > 0);
205 }
206 #undef NR
207 #undef PUSH
208 #undef POP
209 #endif
210 
211 
212 
213 int dope[ DSIZE ];
214 char *opst[DSIZE];
215 
216 struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = {
217 
218 	NAME, "NAME", LTYPE,
219 	STRING, "STRING", LTYPE,
220 	REG, "REG", LTYPE,
221 	OREG, "OREG", LTYPE,
222 	ICON, "ICON", LTYPE,
223 	FCON, "FCON", LTYPE,
224 	DCON, "DCON", LTYPE,
225 	CCODES, "CCODES", LTYPE,
226 	UNARY MINUS, "U-", UTYPE,
227 	UNARY MUL, "U*", UTYPE,
228 	UNARY AND, "U&", UTYPE,
229 	UNARY CALL, "UCALL", UTYPE|CALLFLG,
230 	UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG,
231 	NOT, "!", UTYPE|LOGFLG,
232 	COMPL, "~", UTYPE,
233 	FORCE, "FORCE", UTYPE,
234 	INIT, "INIT", UTYPE,
235 	SCONV, "SCONV", UTYPE,
236 	PCONV, "PCONV", UTYPE,
237 	PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG,
238 	ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG,
239 	MINUS, "-", BITYPE|FLOFLG|SIMPFLG,
240 	ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG,
241 	MUL, "*", BITYPE|FLOFLG|MULFLG,
242 	ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG,
243 	AND, "&", BITYPE|SIMPFLG|COMMFLG,
244 	ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG,
245 	QUEST, "?", BITYPE,
246 	COLON, ":", BITYPE,
247 	ANDAND, "&&", BITYPE|LOGFLG,
248 	OROR, "||", BITYPE|LOGFLG,
249 	CM, ",", BITYPE,
250 	COMOP, ",OP", BITYPE,
251 	ASSIGN, "=", BITYPE|ASGFLG,
252 	DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG,
253 	ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG,
254 	MOD, "%", BITYPE|DIVFLG,
255 	ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG,
256 	LS, "<<", BITYPE|SHFFLG,
257 	ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
258 	RS, ">>", BITYPE|SHFFLG,
259 	ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
260 	OR, "|", BITYPE|COMMFLG|SIMPFLG,
261 	ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
262 	ER, "^", BITYPE|COMMFLG|SIMPFLG,
263 	ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
264 	INCR, "++", BITYPE|ASGFLG,
265 	DECR, "--", BITYPE|ASGFLG,
266 	STREF, "->", BITYPE,
267 	CALL, "CALL", BITYPE|CALLFLG,
268 	FORTCALL, "FCALL", BITYPE|CALLFLG,
269 	EQ, "==", BITYPE|LOGFLG,
270 	NE, "!=", BITYPE|LOGFLG,
271 	LE, "<=", BITYPE|LOGFLG,
272 	LT, "<", BITYPE|LOGFLG,
273 	GE, ">", BITYPE|LOGFLG,
274 	GT, ">", BITYPE|LOGFLG,
275 	UGT, "UGT", BITYPE|LOGFLG,
276 	UGE, "UGE", BITYPE|LOGFLG,
277 	ULT, "ULT", BITYPE|LOGFLG,
278 	ULE, "ULE", BITYPE|LOGFLG,
279 #ifdef ARS
280 	ARS, "A>>", BITYPE,
281 #endif
282 	TYPE, "TYPE", LTYPE,
283 	LB, "[", BITYPE,
284 	CBRANCH, "CBRANCH", BITYPE,
285 	FLD, "FLD", UTYPE,
286 	PMCONV, "PMCONV", BITYPE,
287 	PVCONV, "PVCONV", BITYPE,
288 	RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG,
289 	CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG,
290 	GOTO, "GOTO", UTYPE,
291 	STASG, "STASG", BITYPE|ASGFLG,
292 	STARG, "STARG", UTYPE,
293 	STCALL, "STCALL", BITYPE|CALLFLG,
294 	UNARY STCALL, "USTCALL", UTYPE|CALLFLG,
295 
296 	-1,	"",	0
297 };
298 
299 mkdope(){
300 	register struct dopest *q;
301 
302 	for( q = indope; q->dopeop >= 0; ++q ){
303 		dope[q->dopeop] = q->dopeval;
304 		opst[q->dopeop] = q->opst;
305 		}
306 	}
307 # ifndef BUG4
308 tprint( t )  TWORD t; { /* output a nice description of the type of t */
309 
310 	static char * tnames[] = {
311 		"undef",
312 		"farg",
313 		"char",
314 		"short",
315 		"int",
316 		"long",
317 		"float",
318 		"double",
319 		"strty",
320 		"unionty",
321 		"enumty",
322 		"moety",
323 		"uchar",
324 		"ushort",
325 		"unsigned",
326 		"ulong",
327 		"?", "?"
328 		};
329 
330 	for(;; t = DECREF(t) ){
331 
332 		if( ISPTR(t) ) printf( "PTR " );
333 		else if( ISFTN(t) ) printf( "FTN " );
334 		else if( ISARY(t) ) printf( "ARY " );
335 		else {
336 			printf( "%s", tnames[t] );
337 			return;
338 			}
339 		}
340 	}
341 # endif
342 
343 #ifdef FLEXNAMES
344 #define	NTSTRBUF	40
345 #define	TSTRSZ		2048
346 char	itstrbuf[TSTRSZ];
347 char	*tstrbuf[NTSTRBUF] = { itstrbuf };
348 char	**curtstr = tstrbuf;
349 int	tstrused;
350 char	*malloc();
351 char	*strcpy();
352 
353 char *
354 tstr(cp)
355 	register char *cp;
356 {
357 	register int i = strlen(cp);
358 	register char *dp;
359 
360 	if (tstrused + i >= TSTRSZ) {
361 		if (++curtstr >= &tstrbuf[NTSTRBUF])
362 			cerror("out of temporary string space");
363 		tstrused = 0;
364 		if (*curtstr == 0) {
365 			dp = malloc(TSTRSZ);
366 			if (dp == 0)
367 				cerror("out of memory (tstr)");
368 			*curtstr = dp;
369 		}
370 	}
371 	(void) strcpy(dp = *curtstr+tstrused, cp);
372 	tstrused += i + 1;
373 	return (dp);
374 }
375 #endif
376