xref: /original-bsd/old/pcc/mip/common.c (revision f052b07a)
1 /*	common.c	4.5	88/05/11	*/
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	32
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 	NODE *Aat[NR];
184 	int Aao[NR];
185 	register int i = 1;
186 	register int opty = optype(t->in.op);
187 	register NODE **at = Aat;
188 	register int *ao = Aao;
189 
190 #define	PUSH(dir, state) \
191 	(ao[i] = state, at[i++] = t, t = t->in.dir, opty = optype(t->in.op))
192 #define	POP() \
193 	(opty = ao[--i], t = at[i])
194 
195 	do {
196 		switch (opty) {
197 		case LTYPE:	(*f)(t); POP(); break;
198 		case UTYPE:	PUSH(left, LTYPE); break;
199 		case BITYPE:	PUSH(left, BITYPE+1); break;
200 		case BITYPE+1:	PUSH(right, LTYPE); break;
201 		default:
202 			cerror("bad op type in walkf");
203 		}
204 		if (i >= NR) {
205 			walkf(t, f);
206 			POP();
207 		}
208 	} while (i > 0);
209 }
210 #undef NR
211 #undef PUSH
212 #undef POP
213 #endif
214 
215 
216 
217 int dope[ DSIZE ];
218 char *opst[DSIZE];
219 
220 struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = {
221 
222 	NAME, "NAME", LTYPE,
223 	STRING, "STRING", LTYPE,
224 	REG, "REG", LTYPE,
225 	OREG, "OREG", LTYPE,
226 	ICON, "ICON", LTYPE,
227 	FCON, "FCON", LTYPE,
228 	DCON, "DCON", LTYPE,
229 	CCODES, "CCODES", LTYPE,
230 	UNARY MINUS, "U-", UTYPE,
231 	UNARY MUL, "U*", UTYPE,
232 	UNARY AND, "U&", UTYPE,
233 	UNARY CALL, "UCALL", UTYPE|CALLFLG,
234 	UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG,
235 	NOT, "!", UTYPE|LOGFLG,
236 	COMPL, "~", UTYPE,
237 	FORCE, "FORCE", UTYPE,
238 	INIT, "INIT", UTYPE,
239 	SCONV, "SCONV", UTYPE,
240 	PCONV, "PCONV", UTYPE,
241 	PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG,
242 	ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG,
243 	MINUS, "-", BITYPE|FLOFLG|SIMPFLG,
244 	ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG,
245 	MUL, "*", BITYPE|FLOFLG|MULFLG,
246 	ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG,
247 	AND, "&", BITYPE|SIMPFLG|COMMFLG,
248 	ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG,
249 	QUEST, "?", BITYPE,
250 	COLON, ":", BITYPE,
251 	ANDAND, "&&", BITYPE|LOGFLG,
252 	OROR, "||", BITYPE|LOGFLG,
253 	CM, ",", BITYPE,
254 	COMOP, ",OP", BITYPE,
255 	ASSIGN, "=", BITYPE|ASGFLG,
256 	DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG,
257 	ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG,
258 	MOD, "%", BITYPE|DIVFLG,
259 	ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG,
260 	LS, "<<", BITYPE|SHFFLG,
261 	ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
262 	RS, ">>", BITYPE|SHFFLG,
263 	ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
264 	OR, "|", BITYPE|COMMFLG|SIMPFLG,
265 	ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
266 	ER, "^", BITYPE|COMMFLG|SIMPFLG,
267 	ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
268 	INCR, "++", BITYPE|ASGFLG,
269 	DECR, "--", BITYPE|ASGFLG,
270 	STREF, "->", BITYPE,
271 	CALL, "CALL", BITYPE|CALLFLG,
272 	FORTCALL, "FCALL", BITYPE|CALLFLG,
273 	EQ, "==", BITYPE|LOGFLG,
274 	NE, "!=", BITYPE|LOGFLG,
275 	LE, "<=", BITYPE|LOGFLG,
276 	LT, "<", BITYPE|LOGFLG,
277 	GE, ">", BITYPE|LOGFLG,
278 	GT, ">", BITYPE|LOGFLG,
279 	UGT, "UGT", BITYPE|LOGFLG,
280 	UGE, "UGE", BITYPE|LOGFLG,
281 	ULT, "ULT", BITYPE|LOGFLG,
282 	ULE, "ULE", BITYPE|LOGFLG,
283 #ifdef ARS
284 	ARS, "A>>", BITYPE,
285 #endif
286 	TYPE, "TYPE", LTYPE,
287 	LB, "[", BITYPE,
288 	CBRANCH, "CBRANCH", BITYPE,
289 	FLD, "FLD", UTYPE,
290 	PMCONV, "PMCONV", BITYPE,
291 	PVCONV, "PVCONV", BITYPE,
292 	RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG,
293 	CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG,
294 	GOTO, "GOTO", UTYPE,
295 	STASG, "STASG", BITYPE|ASGFLG,
296 	STARG, "STARG", UTYPE,
297 	STCALL, "STCALL", BITYPE|CALLFLG,
298 	UNARY STCALL, "USTCALL", UTYPE|CALLFLG,
299 
300 	-1,	"",	0
301 };
302 
303 mkdope(){
304 	register struct dopest *q;
305 
306 	for( q = indope; q->dopeop >= 0; ++q ){
307 		dope[q->dopeop] = q->dopeval;
308 		opst[q->dopeop] = q->opst;
309 		}
310 	}
311 # ifndef BUG4
312 tprint( t )  TWORD t; { /* output a nice description of the type of t */
313 
314 	static char * tnames[] = {
315 		"undef",
316 		"farg",
317 		"char",
318 		"short",
319 		"int",
320 		"long",
321 		"float",
322 		"double",
323 		"strty",
324 		"unionty",
325 		"enumty",
326 		"moety",
327 		"uchar",
328 		"ushort",
329 		"unsigned",
330 		"ulong",
331 		"?", "?"
332 		};
333 
334 	for(;; t = DECREF(t) ){
335 
336 		if( ISPTR(t) ) printf( "PTR " );
337 		else if( ISFTN(t) ) printf( "FTN " );
338 		else if( ISARY(t) ) printf( "ARY " );
339 		else {
340 			printf( "%s", tnames[t] );
341 			return;
342 			}
343 		}
344 	}
345 # endif
346 
347 #ifdef FLEXNAMES
348 #define	NTSTRBUF	40
349 #define	TSTRSZ		2048
350 char	itstrbuf[TSTRSZ];
351 char	*tstrbuf[NTSTRBUF] = { itstrbuf };
352 char	**curtstr = tstrbuf;
353 int	tstrused;
354 char	*malloc();
355 char	*strcpy();
356 
357 char *
358 tstr(cp)
359 	register char *cp;
360 {
361 	register int i = strlen(cp);
362 	register char *dp;
363 
364 	if (tstrused + i >= TSTRSZ) {
365 		if (++curtstr >= &tstrbuf[NTSTRBUF])
366 			cerror("out of temporary string space");
367 		tstrused = 0;
368 		if (*curtstr == 0) {
369 			dp = malloc(TSTRSZ);
370 			if (dp == 0)
371 				cerror("out of memory (tstr)");
372 			*curtstr = dp;
373 		}
374 	}
375 	(void) strcpy(dp = *curtstr+tstrused, cp);
376 	tstrused += i + 1;
377 	return (dp);
378 }
379 #endif
380