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

Defined functions

argsize defined in line 499; used 2 times
autoincr defined in line 25; never used
deflab defined in line 445; never used
deltest defined in line 19; never used
genargs defined in line 449; used 2 times
getlab defined in line 441; never used
mkadrs defined in line 35; never used
notoff defined in line 64; never used
offstar defined in line 254; used 10 times
rallo defined in line 206; used 2 times
setasg defined in line 362; never used
setasop defined in line 389; never used
setbin defined in line 309; never used
setincr defined in line 300; never used
setstr defined in line 348; never used
stoasg defined in line 9; never used
sucomp defined in line 75; never used

Defined variables

crslab defined in line 439; used 1 times
maxargs defined in line 7; never used
radebug defined in line 204; used 1 times
sccsid defined in line 2; never used

Defined macros

max defined in line 73; used 9 times
Last modified: 1986-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1741
Valid CSS Valid XHTML 1.0 Strict