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