xref: /original-bsd/old/pcc/ccom.tahoe/order.c (revision 5cf7f382)
1 #ifndef lint
2 static char sccsid[] = "@(#)order.c	1.8 (Berkeley) 08/26/88";
3 #endif
4 
5 # include "pass2.h"
6 
7 int maxargs = { -1 };
8 
9 /*ARGSUSED*/
10 stoasg( p, o ) NODE *p; {
11 	/* should the assignment op p be stored,
12 	   given that it lies as the right operand of o
13 	   (or the left, if o==UNARY MUL) */
14 	}
15 
16 deltest( p ) register NODE *p; {
17 	/* should we delay the INCR or DECR operation p */
18 	p = p->in.left;
19 	return( p->in.op == REG || p->in.op == NAME || p->in.op == OREG );
20 	}
21 
22 /*ARGSUSED*/
23 autoincr( p ) NODE *p; {
24 
25 	return(0);
26 	}
27 
28 mkadrs(p) register NODE *p; {
29 	register int o;
30 
31 	o = p->in.op;
32 
33 	if( asgop(o) ){
34 		if( p->in.left->in.su >= p->in.right->in.su ){
35 			if( p->in.left->in.op == UNARY MUL ){
36 				SETSTO( p->in.left->in.left, INTEMP );
37 				}
38 			else if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){
39 				SETSTO( p->in.left->in.left->in.left, INTEMP );
40 				}
41 			else { /* should be only structure assignment */
42 				SETSTO( p->in.left, INTEMP );
43 				}
44 			}
45 		else SETSTO( p->in.right, INTEMP );
46 		}
47 	else {
48 		if( p->in.left->in.su > p->in.right->in.su ){
49 			SETSTO( p->in.left, INTEMP );
50 			}
51 		else {
52 			SETSTO( p->in.right, INTEMP );
53 			}
54 		}
55 	}
56 
57 /*ARGSUSED*/
58 notoff( t, r, off, cp) TWORD t; CONSZ off; char *cp; {
59 	/* is it legal to make an OREG or NAME entry which has an
60 	/* offset of off, (from a register of r), if the
61 	/* resulting thing had type t */
62 
63 	return(0);  /* YES */
64 	}
65 
66 # define max(x,y) ((x)<(y)?(y):(x))
67 
68 sucomp( p ) register NODE *p; {
69 
70 	/* set the su field in the node to the sethi-ullman
71 	   number, or local equivalent */
72 
73 	register int o, ty, sul, sur, r;
74 
75 	o = p->in.op;
76 	ty = optype( o );
77 	p->in.su = szty( p->in.type );   /* 2 for double, else 1 */;
78 
79 	if( ty == LTYPE ){
80 		if( o == OREG ){
81 			r = p->tn.rval;
82 			/* oreg cost is (worst case) 1 + number of temp registers used */
83 			if( R2TEST(r) ){
84 				if( R2UPK1(r)!=100 && istreg(R2UPK1(r)) ) ++p->in.su;
85 				if( istreg(R2UPK2(r)) ) ++p->in.su;
86 				}
87 			else {
88 				if( istreg( r ) ) ++p->in.su;
89 				}
90 			}
91 		if( p->in.su == szty(p->in.type) &&
92 		   (p->in.op!=REG || !istreg(p->tn.rval)) &&
93 		   (p->in.type==INT ||
94 		    p->in.type==UNSIGNED ||
95 		    p->in.type==FLOAT ||
96 		    p->in.type==DOUBLE ||
97 		    ISPTR(p->in.type) ||
98 		    ISARY(p->in.type)) )
99 			p->in.su = 0;
100 		return;
101 		}
102 
103 	else if( ty == UTYPE ){
104 		switch( o ) {
105 		case UNARY CALL:
106 		case UNARY STCALL:
107 			p->in.su = fregs;  /* all regs needed */
108 			return;
109 
110 		default:
111 			p->in.su = p->in.left->in.su +
112 			(szty(p->in.type) >1 ? 2 : 0);
113 			return;
114 			}
115 		}
116 
117 
118 	/* If rhs needs n, lhs needs m, regular su computation */
119 
120 	sul = p->in.left->in.su;
121 	sur = p->in.right->in.su;
122 
123 	if( o == ASSIGN ){
124 		/* computed by doing right, then left (if not in mem), then doing it */
125 		p->in.su = max(sur,sul+1);
126 		return;
127 		}
128 
129 	if( o == CALL || o == STCALL ){
130 		/* in effect, takes all free registers */
131 		p->in.su = fregs;
132 		return;
133 		}
134 
135 	if( o == STASG ){
136 		/* right, then left */
137 		p->in.su = max( max( 1+sul, sur), fregs );
138 		return;
139 		}
140 
141 	if( asgop(o) ){
142 		/* computed by doing right, doing left address, doing left, op, and store */
143 		if(optype(p->in.left->in.op) != LTYPE)
144 			sul++;
145 		/* ediv uses more regs */
146 		if(o==ASG DIV && p->in.left->in.type==UNSIGNED || o==ASG MOD){
147 			p->in.su = max(max(sul,(sul!=0)+2),sur+1);
148 			return;
149 			}
150 		p->in.su = max(sur,sul+1);
151 		return;
152 		}
153 
154 	switch( o ){
155 	case ANDAND:
156 	case OROR:
157 	case QUEST:
158 	case COLON:
159 	case COMOP:
160 		p->in.su = max( max(sul,sur), 1);
161 		return;
162 
163 	case PLUS:
164 	case MUL:
165 	case OR:
166 	case ER:
167 		/* commutative ops; put harder on left */
168 		if( p->in.right->in.su > p->in.left->in.su && !istnode(p->in.left) ){
169 			register NODE *temp;
170 			temp = p->in.left;
171 			p->in.left = p->in.right;
172 			p->in.right = temp;
173 			}
174 		break;
175 	case DIV:
176 		/* ediv uses more regs */
177 		if(p->in.left->in.type!=UNSIGNED)
178 			break;
179 	case MOD:
180 		p->in.su = max(max(sul,(sul!=0)+2),sur+1);
181 		return;
182 		}
183 	/* binary op, computed by left, then right, then do op */
184 	p->in.su = max(sul,szty(p->in.right->in.type)+sur);
185 
186 	}
187 
188 int radebug = 0;
189 
190 rallo( p, down ) NODE *p; {
191 	/* do register allocation */
192 	register int o, down1, down2, ty;
193 
194 	if( radebug ) printf( "rallo( %o, %d )\n", p, down );
195 
196 	down2 = NOPREF;
197 	p->in.rall = down;
198 	down1 = ( down &= ~MUSTDO );
199 
200 	ty = optype( o = p->in.op );
201 	switch( o ) {
202 	case ASSIGN:
203 		down1 = NOPREF;
204 		down2 = down;
205 		break;
206 
207 	case CALL:
208 	case STASG:
209 	case EQ:
210 	case NE:
211 	case GT:
212 	case GE:
213 	case LT:
214 	case LE:
215 	case NOT:
216 	case ANDAND:
217 	case OROR:
218 		down1 = NOPREF;
219 		break;
220 
221 	case FORCE:
222 		down1 = R0|MUSTDO;
223 		break;
224 
225 		}
226 
227 	if( ty != LTYPE ) rallo( p->in.left, down1 );
228 	if( ty == BITYPE ) rallo( p->in.right, down2 );
229 
230 	}
231 
232 offstar( p ) register NODE *p; {
233 	if( p->in.op == PLUS ) {
234 		if( p->in.left->in.su == fregs ) {
235 			order( p->in.left, INTAREG|INAREG );
236 			return;
237 		} else if( p->in.right->in.su == fregs ) {
238 			order( p->in.right, INTAREG|INAREG );
239 			return;
240 		}
241 		if( p->in.left->in.op==LS &&
242 		  (p->in.left->in.left->in.op!=REG || tlen(p->in.left->in.left)!=SZINT/SZCHAR ) ) {
243 			order( p->in.left->in.left, INTAREG|INAREG );
244 			return;
245 		}
246 		if( p->in.right->in.op==LS &&
247 		  (p->in.right->in.left->in.op!=REG || tlen(p->in.right->in.left)!=SZINT/SZCHAR ) ) {
248 			order( p->in.right->in.left, INTAREG|INAREG );
249 			return;
250 		}
251 		if( p->in.type == (PTR|CHAR) || p->in.type == (PTR|UCHAR) ) {
252 			if( p->in.left->in.op!=REG || tlen(p->in.left)!=SZINT/SZCHAR ) {
253 				order( p->in.left, INTAREG|INAREG );
254 				return;
255 			}
256 			else if( p->in.right->in.op!=REG || tlen(p->in.right)!=SZINT/SZCHAR ) {
257 				order(p->in.right, INTAREG|INAREG);
258 				return;
259 			}
260 		}
261 	}
262 	if( p->in.op == PLUS || p->in.op == MINUS ){
263 		if( p->in.right->in.op == ICON ){
264 			p = p->in.left;
265 			order( p , INTAREG|INAREG);
266 			return;
267 			}
268 		}
269 
270 	if( p->in.op == UNARY MUL && !canaddr(p) ) {
271 		offstar( p->in.left );
272 		return;
273 	}
274 
275 	order( p, INTAREG|INAREG );
276 	}
277 
278 setincr( p ) register NODE *p; {
279 	p = p->in.left;
280 	if( p->in.op == UNARY MUL ){
281 		offstar( p->in.left );
282 		return( 1 );
283 		}
284 	return( 0 );
285 	}
286 
287 setbin( p ) register NODE *p; {
288 	register int ro, rt;
289 
290 	rt = p->in.right->in.type;
291 	ro = p->in.right->in.op;
292 
293 	if( canaddr( p->in.left ) && !canaddr( p->in.right ) ) { /* address rhs */
294 		if( ro == UNARY MUL ) {
295 			offstar( p->in.right->in.left );
296 			return(1);
297 		} else {
298 			order( p->in.right, INAREG|INTAREG|SOREG );
299 			return(1);
300 		}
301 	}
302 	if( !istnode( p->in.left) ) { /* try putting LHS into a reg */
303 		order( p->in.left, INAREG|INTAREG|INBREG|INTBREG|SOREG );
304 		return(1);
305 		}
306 	else if( ro == UNARY MUL && rt != CHAR && rt != UCHAR ){
307 		offstar( p->in.right->in.left );
308 		return(1);
309 		}
310 	else if( rt == CHAR || rt == UCHAR || rt == SHORT || rt == USHORT || (ro != REG &&
311 			ro != NAME && ro != OREG && ro != ICON ) ){
312 		order( p->in.right, INAREG|INBREG );
313 		return(1);
314 		}
315 	return(0);
316 	}
317 
318 /* VARARGS1 */
319 setstr( p ) register NODE *p; { /* structure assignment */
320 	if( p->in.right->in.op != REG ){
321 		order( p->in.right, INTAREG );
322 		return(1);
323 		}
324 	p = p->in.left;
325 	if( p->in.op != NAME && p->in.op != OREG ){
326 		if( p->in.op != UNARY MUL ) cerror( "bad setstr" );
327 		order( p->in.left, INTAREG );
328 		return( 1 );
329 		}
330 	return( 0 );
331 	}
332 
333 setasg( p ) register NODE *p; {
334 	/* setup for assignment operator */
335 
336 	if( !canaddr(p->in.right) ) {
337 		if( p->in.right->in.op == UNARY MUL )
338 			offstar(p->in.right->in.left);
339 		else
340 			order( p->in.right, INAREG|INBREG|SOREG );
341 		return(1);
342 		}
343 	if( p->in.left->in.op == UNARY MUL ) {
344 		offstar( p->in.left->in.left );
345 		return(1);
346 		}
347 	if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){
348 		offstar( p->in.left->in.left->in.left );
349 		return(1);
350 		}
351 /* FLD patch */
352 	if( p->in.left->in.op == FLD && !(p->in.right->in.type==INT || p->in.right->in.type==UNSIGNED)) {
353 		order( p->in.right, INAREG);
354 		return(1);
355 		}
356 /* end of FLD patch */
357 	return(0);
358 	}
359 
360 setasop( p ) register NODE *p; {
361 	/* setup for =ops */
362 	register int rt, ro;
363 
364 	rt = p->in.right->in.type;
365 	ro = p->in.right->in.op;
366 
367 	if( ro == UNARY MUL && rt != CHAR ){
368 		offstar( p->in.right->in.left );
369 		return(1);
370 		}
371 	if( ( rt == CHAR || rt == SHORT || rt == UCHAR || rt == USHORT ||
372 			( ro != REG && ro != ICON && ro != NAME && ro != OREG ) ) ){
373 		order( p->in.right, INAREG|INBREG );
374 		return(1);
375 		}
376 
377 
378 	p = p->in.left;
379 	if( p->in.op == FLD ) p = p->in.left;
380 
381 	switch( p->in.op ){
382 
383 	case REG:
384 	case ICON:
385 	case NAME:
386 	case OREG:
387 		return(0);
388 
389 	case UNARY MUL:
390 		if( p->in.left->in.op==OREG )
391 			return(0);
392 		else
393 			offstar( p->in.left );
394 		return(1);
395 
396 		}
397 	cerror( "illegal setasop" );
398 	/*NOTREACHED*/
399 	}
400 
401 int crslab = 99999;  /* Tahoe */
402 
403 getlab(){
404 	return( crslab-- );
405 	}
406 
407 deflab( l ){
408 	if (nerrors) return;
409 	printf( "L%d:\n", l );
410 	}
411 
412 genargs( p, ptemp ) register NODE *p, *ptemp; {
413 	register NODE *pasg;
414 	register int align;
415 	register int size;
416 	int count;
417 
418 	/* generate code for the arguments */
419 
420 	/*  first, do the arguments on the right */
421 	while( p->in.op == CM ){
422 		genargs( p->in.right, ptemp );
423 		p->in.op = FREE;
424 		p = p->in.left;
425 		}
426 
427 	if( p->in.op == STARG ){ /* structure valued argument */
428 
429 		size = p->stn.stsize;
430 		align = p->stn.stalign;
431 		if( p->in.left->in.op == ICON ){
432 			p->in.op = FREE;
433 			p= p->in.left;
434 			}
435 		else {
436 			/* make it look beautiful... */
437 			p->in.op = UNARY MUL;
438 			canon( p );  /* turn it into an oreg */
439 			for( count = 0; p->in.op != OREG && count < 10; ++count ){
440 				offstar( p->in.left );
441 				canon( p );
442 				}
443 			if( p->in.op != OREG ) cerror( "stuck starg" );
444 			}
445 
446 
447  		ptemp->tn.lval = 0;	/* all moves to (sp) */
448 
449 		pasg = talloc();
450 		pasg->in.op = STASG;
451 		pasg->stn.stsize = size;
452 		pasg->stn.stalign = align;
453 		pasg->in.right = p;
454 		pasg->in.left = tcopy( ptemp );
455 
456 		/* the following line is done only with the knowledge
457 		that it will be undone by the STASG node, with the
458 		offset (lval) field retained */
459 
460 		if( p->in.op == OREG ) p->in.op = REG;  /* only for temporaries */
461 
462  		order( pasg, FORARG );
463 		ptemp->tn.lval += size;
464 		return;
465 		}
466 
467 	/* ordinary case */
468 
469 	order( p, FORARG );
470 	}
471 
472 argsize( p ) register NODE *p; {
473 	register int t;
474 	t = 0;
475 	if( p->in.op == CM ){
476 		t = argsize( p->in.left );
477 		p = p->in.right;
478 		}
479 	if( p->in.type == DOUBLE || p->in.type == FLOAT ){
480 		SETOFF( t, 4 );
481 		return( t+8 );
482 		}
483 	else if( p->in.op == STARG ){
484  		SETOFF( t, 4 );  /* alignment */
485  		return( t + ((p->stn.stsize+3)/4)*4 );  /* size */
486 		}
487 	else {
488 		SETOFF( t, 4 );
489 		return( t+4 );
490 		}
491 	}
492