1: # include "pass2.h"
   2: 
   3: int fltused = 0;
   4: 
   5: stoasg( p, o ) register NODE *p; {
   6:     /* should the assignment op p be stored,
   7: 	   given that it lies as the right operand of o
   8: 	   (or the left, if o==UNARY MUL) */
   9:     return( shltype(p->in.left->in.op, p->in.left ) );
  10: 
  11:     }
  12: 
  13: deltest( p ) register NODE *p; {
  14:     /* should we delay the INCR or DECR operation p */
  15:     if( p->in.op == INCR && p->in.left->in.op == REG && spsz( p->in.left->in.type, p->in.right->tn.lval ) ){
  16:         /* STARREG */
  17:         return( 0 );
  18:         }
  19: 
  20:     p = p->in.left;
  21:     if( p->in.op == UNARY MUL ) p = p->in.left;
  22:     return( p->in.op == NAME || p->in.op == OREG || p->in.op == REG );
  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:                 if( p->in.left->in.su > 0 )
  44:                     SETSTO( p->in.left->in.left, INTEMP );
  45:                 else {
  46:                     if( p->in.right->in.su > 0 ) SETSTO( p->in.right, INTEMP );
  47:                     else cerror( "store finds both sides trivial" );
  48:                     }
  49:                 }
  50:             else if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){
  51:                 SETSTO( p->in.left->in.left->in.left, INTEMP );
  52:                 }
  53:             else { /* should be only structure assignment */
  54:                 SETSTO( p->in.left, INTEMP );
  55:                 }
  56:             }
  57:         else SETSTO( p->in.right, INTEMP );
  58:         }
  59:     else {
  60:         if( p->in.left->in.su > p->in.right->in.su ){
  61:             SETSTO( p->in.left, INTEMP );
  62:             }
  63:         else {
  64:             SETSTO( p->in.right, INTEMP );
  65:             }
  66:         }
  67:     }
  68: 
  69: notoff( t, r, off, cp) TWORD t; CONSZ off; char *cp; {
  70:     /* is it legal to make an OREG or NAME entry which has an
  71: 	/* offset of off, (from a register of r), if the
  72: 	/* resulting thing had type t */
  73: 
  74:     /* if( r == R0 ) return( 1 );  /* NO */
  75:     return(0);  /* YES */
  76:     }
  77: 
  78: # define max(x,y) ((x)<(y)?(y):(x))
  79: # define min(x,y) ((x)<(y)?(x):(y))
  80: 
  81: 
  82: # define ZCHAR 01
  83: # define ZLONG 02
  84: # define ZFLOAT 04
  85: 
  86: zum( p, zap ) register NODE *p; {
  87:     /* zap Sethi-Ullman number for chars, longs, floats */
  88:     /* in the case of longs, only STARNM's are zapped */
  89:     /* ZCHAR, ZLONG, ZFLOAT are used to select the zapping */
  90: 
  91:     register su;
  92: 
  93:     su = p->in.su;
  94: 
  95:     switch( p->in.type ){
  96: 
  97:     case CHAR:
  98:     case UCHAR:
  99:         if( !(zap&ZCHAR) ) break;
 100:         if( su == 0 ) p->in.su = su = 1;
 101:         break;
 102: 
 103:     case LONG:
 104:     case ULONG:
 105:         if( !(zap&ZLONG) ) break;
 106:         if( p->in.op == UNARY MUL && su == 0 ) p->in.su = su = 2;
 107:         break;
 108: 
 109:     case FLOAT:
 110:         if( !(zap&ZFLOAT) ) break;
 111:         if( su == 0 ) p->in.su = su = 1;
 112: 
 113:         }
 114: 
 115:     return( su );
 116:     }
 117: 
 118: sucomp( p ) register NODE *p; {
 119: 
 120:     /* set the su field in the node to the sethi-ullman
 121: 	   number, or local equivalent */
 122: 
 123:     register o, ty, sul, sur;
 124:     register nr;
 125: 
 126:     ty = optype( o=p->in.op);
 127:     nr = szty( p->in.type );
 128:     p->in.su = 0;
 129: 
 130:     if( ty == LTYPE ) {
 131:         if( p->in.type==FLOAT ) p->in.su = 1;
 132:         return;
 133:         }
 134:     else if( ty == UTYPE ){
 135:         switch( o ) {
 136:         case UNARY CALL:
 137:         case UNARY STCALL:
 138:             p->in.su = fregs;  /* all regs needed */
 139:             return;
 140: 
 141:         case UNARY MUL:
 142:             if( shumul( p->in.left ) ) return;
 143: 
 144:         default:
 145:             p->in.su = max( p->in.left->in.su, nr);
 146:             return;
 147:             }
 148:         }
 149: 
 150: 
 151:     /* If rhs needs n, lhs needs m, regular su computation */
 152: 
 153:     sul = p->in.left->in.su;
 154:     sur = p->in.right->in.su;
 155: 
 156:     if( o == ASSIGN ){
 157:         asop:  /* also used for +=, etc., to memory */
 158:         if( sul==0 ){
 159:             /* don't need to worry about the left side */
 160:             p->in.su = max( sur, nr );
 161:             }
 162:         else {
 163:             /* right, left address, op */
 164:             if( sur == 0 ){
 165:                 /* just get the lhs address into a register, and mov */
 166:                 /* the `nr' covers the case where value is in reg afterwards */
 167:                 p->in.su = max( sul, nr );
 168:                 }
 169:             else {
 170:                 /* right, left address, op */
 171:                 p->in.su = max( sur, nr+sul );
 172:                 }
 173:             }
 174:         return;
 175:         }
 176: 
 177:     if( o == CALL || o == STCALL ){
 178:         /* in effect, takes all free registers */
 179:         p->in.su = fregs;
 180:         return;
 181:         }
 182: 
 183:     if( o == STASG ){
 184:         /* right, then left */
 185:         p->in.su = max( max( sul+nr, sur), fregs );
 186:         return;
 187:         }
 188: 
 189:     if( logop(o) ){
 190:         /* do the harder side, then the easier side, into registers */
 191:         /* left then right, max(sul,sur+nr) */
 192:         /* right then left, max(sur,sul+nr) */
 193:         /* to hold both sides in regs: nr+nr */
 194:         nr = szty( p->in.left->in.type );
 195:         sul = zum( p->in.left, ZLONG|ZCHAR|ZFLOAT );
 196:         sur = zum( p->in.right, ZLONG|ZCHAR|ZFLOAT );
 197:         p->in.su = min( max(sul,sur+nr), max(sur,sul+nr) );
 198:         return;
 199:         }
 200: 
 201:     if( asgop(o) ){
 202:         /* computed by doing right, doing left address, doing left, op, and store */
 203:         switch( o ) {
 204:         case INCR:
 205:         case DECR:
 206:             /* do as binary op */
 207:             break;
 208: 
 209:         case ASG DIV:
 210:         case ASG MOD:
 211:         case ASG MUL:
 212:             if( p->in.type!=FLOAT && p->in.type!=DOUBLE ) nr = fregs;
 213:             goto gencase;
 214: 
 215:         case ASG PLUS:
 216:         case ASG MINUS:
 217:         case ASG AND:  /* really bic */
 218:         case ASG OR:
 219:             if( p->in.type == INT || p->in.type == UNSIGNED || ISPTR(p->in.type) ) goto asop;
 220: 
 221:         gencase:
 222:         default:
 223:             sur = zum( p->in.right, ZCHAR|ZLONG|ZFLOAT );
 224:             if( sur == 0 ){ /* easy case: if addressable,
 225: 				do left value, op, store */
 226:                 if( sul == 0 ) p->in.su = nr;
 227:                 /* harder: left adr, val, op, store */
 228:                 else p->in.su = max( sul, nr+1 );
 229:                 }
 230:             else { /* do right, left adr, left value, op, store */
 231:                 if( sul == 0 ){  /* right, left value, op, store */
 232:                     p->in.su = max( sur, nr+nr );
 233:                     }
 234:                 else {
 235:                     p->in.su = max( sur, max( sul+nr, 1+nr+nr ) );
 236:                     }
 237:                 }
 238:             return;
 239:             }
 240:         }
 241: 
 242:     switch( o ){
 243:     case ANDAND:
 244:     case OROR:
 245:     case QUEST:
 246:     case COLON:
 247:     case COMOP:
 248:         p->in.su = max( max(sul,sur), nr);
 249:         return;
 250:         }
 251: 
 252:     if( ( o==DIV || o==MOD || o==MUL )
 253:         && p->in.type!=FLOAT && p->in.type!=DOUBLE ) nr = fregs;
 254:     if( o==PLUS || o==MUL || o==OR || o==ER ){
 255:         /* AND is ruined by the hardware */
 256:         /* permute: get the harder on the left */
 257: 
 258:         register rt, lt;
 259: 
 260:         if( istnode( p->in.left ) || sul > sur ) goto noswap;  /* don't do it! */
 261: 
 262:         /* look for a funny type on the left, one on the right */
 263: 
 264: 
 265:         lt = p->in.left->in.type;
 266:         rt = p->in.right->in.type;
 267: 
 268:         if( rt == FLOAT && lt == DOUBLE ) goto swap;
 269: 
 270:         if( (rt==CHAR||rt==UCHAR) && (lt==INT||lt==UNSIGNED||ISPTR(lt)) ) goto swap;
 271: 
 272:         if( lt==LONG || lt==ULONG ){
 273:             if( rt==LONG || rt==ULONG ){
 274:                 /* if one is a STARNM, swap */
 275:                 if( p->in.left->in.op == UNARY MUL && sul==0 ) goto noswap;
 276:                 if( p->in.right->in.op == UNARY MUL && p->in.left->in.op != UNARY MUL ) goto swap;
 277:                 goto noswap;
 278:                 }
 279:             else if( p->in.left->in.op == UNARY MUL && sul == 0 ) goto noswap;
 280:             else goto swap;  /* put long on right, unless STARNM */
 281:             }
 282: 
 283:         /* we are finished with the type stuff now; if one is addressable,
 284: 			put it on the right */
 285:         if( sul == 0 && sur != 0 ){
 286: 
 287:             NODE *s;
 288:             int ssu;
 289: 
 290:         swap:
 291:             ssu = sul;  sul = sur; sur = ssu;
 292:             s = p->in.left;  p->in.left = p->in.right; p->in.right = s;
 293:             }
 294:         }
 295:     noswap:
 296: 
 297:     sur = zum( p->in.right, ZCHAR|ZLONG|ZFLOAT );
 298:     if( sur == 0 ){
 299:         /* get left value into a register, do op */
 300:         p->in.su = max( nr, sul );
 301:         }
 302:     else {
 303:         /* do harder into a register, then easier */
 304:         p->in.su = max( nr+nr, min( max( sul, nr+sur ), max( sur, nr+sul ) ) );
 305:         }
 306:     }
 307: 
 308: int radebug = 0;
 309: 
 310: mkrall( p, r ) register NODE *p; {
 311:     /* insure that the use of p gets done with register r; in effect, */
 312:     /* simulate offstar */
 313: 
 314:     if( p->in.op == FLD ){
 315:         p->in.left->in.rall = p->in.rall;
 316:         p = p->in.left;
 317:         }
 318: 
 319:     if( p->in.op != UNARY MUL ) return;  /* no more to do */
 320:     p = p->in.left;
 321:     if( p->in.op == UNARY MUL ){
 322:         p->in.rall = r;
 323:         p = p->in.left;
 324:         }
 325:     if( p->in.op == PLUS && p->in.right->in.op == ICON ){
 326:         p->in.rall = r;
 327:         p = p->in.left;
 328:         }
 329:     rallo( p, r );
 330:     }
 331: 
 332: rallo( p, down ) register NODE *p; {
 333:     /* do register allocation */
 334:     register o, type, down1, down2, ty;
 335: 
 336:     if( radebug ) printf( "rallo( %o, %o )\n", p, down );
 337: 
 338:     down2 = NOPREF;
 339:     p->in.rall = down;
 340:     down1 = ( down &= ~MUSTDO );
 341: 
 342:     ty = optype( o = p->in.op );
 343:     type = p->in.type;
 344: 
 345: 
 346:     if( type == DOUBLE || type == FLOAT ){
 347:         if( o == FORCE ) down1 = FR0|MUSTDO;
 348:         ++fltused;
 349:         }
 350:     else switch( o ) {
 351:     case ASSIGN:
 352:         down1 = NOPREF;
 353:         down2 = down;
 354:         break;
 355: 
 356:     case ASG MUL:
 357:     case ASG DIV:
 358:     case ASG MOD:
 359:         /* keep the addresses out of the hair of (r0,r1) */
 360:         if(fregs == 2 ){
 361:             /* lhs in (r0,r1), nothing else matters */
 362:             down1 = R1|MUSTDO;
 363:             down2 = NOPREF;
 364:             break;
 365:             }
 366:         /* at least 3 regs free */
 367:         /* compute lhs in (r0,r1), address of left in r2 */
 368:         p->in.left->in.rall = R1|MUSTDO;
 369:         mkrall( p->in.left, R2|MUSTDO );
 370:         /* now, deal with right */
 371:         if( fregs == 3 ) rallo( p->in.right, NOPREF );
 372:         else {
 373:             /* put address of long or value here */
 374:             p->in.right->in.rall = R3|MUSTDO;
 375:             mkrall( p->in.right, R3|MUSTDO );
 376:             }
 377:         return;
 378: 
 379:     case MUL:
 380:     case DIV:
 381:     case MOD:
 382:         rallo( p->in.left, R1|MUSTDO );
 383: 
 384:         if( fregs == 2 ){
 385:             rallo( p->in.right, NOPREF );
 386:             return;
 387:             }
 388:         /* compute addresses, stay away from (r0,r1) */
 389: 
 390:         p->in.right->in.rall = (fregs==3) ? R2|MUSTDO : R3|MUSTDO ;
 391:         mkrall( p->in.right, R2|MUSTDO );
 392:         return;
 393: 
 394:     case CALL:
 395:     case STASG:
 396:     case EQ:
 397:     case NE:
 398:     case GT:
 399:     case GE:
 400:     case LT:
 401:     case LE:
 402:     case NOT:
 403:     case ANDAND:
 404:     case OROR:
 405:         down1 = NOPREF;
 406:         break;
 407: 
 408:     case FORCE:
 409:         down1 = R0|MUSTDO;
 410:         break;
 411: 
 412:         }
 413: 
 414:     if( ty != LTYPE ) rallo( p->in.left, down1 );
 415:     if( ty == BITYPE ) rallo( p->in.right, down2 );
 416: 
 417:     }
 418: 
 419: offstar( p ) register NODE *p; {
 420:     if( p->in.op == PLUS ) {
 421:         if( p->in.left->in.su == fregs ) {
 422:             order( p->in.left, INTAREG|INAREG );
 423:             return;
 424:         } else if( p->in.right->in.su == fregs ) {
 425:             order( p->in.right, INTAREG|INAREG );
 426:             return;
 427:         }
 428:         if( p->in.left->in.op==LS &&
 429:           (p->in.left->in.left->in.op!=REG || tlen(p->in.left->in.left)!=sizeof(int) ) ) {
 430:             order( p->in.left->in.left, INTAREG|INAREG );
 431:             return;
 432:         }
 433:         if( p->in.right->in.op==LS &&
 434:           (p->in.right->in.left->in.op!=REG || tlen(p->in.right->in.left)!=sizeof(int) ) ) {
 435:             order( p->in.right->in.left, INTAREG|INAREG );
 436:             return;
 437:         }
 438:         if( p->in.type == (PTR|CHAR) || p->in.type == (PTR|UCHAR) ) {
 439:             if( p->in.left->in.op!=REG || tlen(p->in.left)!=sizeof(int) ) {
 440:                 order( p->in.left, INTAREG|INAREG );
 441:                 return;
 442:             }
 443:             else if( p->in.right->in.op!=REG || tlen(p->in.right)!=sizeof(int) ) {
 444:                 order(p->in.right, INTAREG|INAREG);
 445:                 return;
 446:             }
 447:         }
 448:     }
 449:     if( p->in.op == PLUS || p->in.op == MINUS ){
 450:         if( p->in.right->in.op == ICON ){
 451:             p = p->in.left;
 452:             order( p , INTAREG|INAREG);
 453:             return;
 454:             }
 455:         }
 456: 
 457:     if( p->in.op == UNARY MUL && !canaddr(p) ) {
 458:         offstar( p->in.left );
 459:         return;
 460:     }
 461: 
 462:     order( p, INTAREG|INAREG );
 463:     }
 464: 
 465: setincr( p ) register NODE *p; {
 466:     p = p->in.left;
 467:     if( p->in.op == UNARY MUL ){
 468:         offstar( p );
 469:         return( 1 );
 470:         }
 471:     return( 0 );
 472:     }
 473: 
 474: niceuty( p ) register NODE *p; {
 475:     register TWORD t;
 476: 
 477:     return( p->in.op == UNARY MUL && (t=p->in.type)!=CHAR &&
 478:         t!= UCHAR && t!= FLOAT &&
 479:         shumul( p->in.left) != STARREG );
 480:     }
 481: setbin( p ) register NODE *p; {
 482:     register NODE *r, *l;
 483: 
 484:     r = p->in.right;
 485:     l = p->in.left;
 486: 
 487:     if( p->in.right->in.su == 0 ){ /* rhs is addressable */
 488:         if( logop( p->in.op ) ){
 489:             if( l->in.op == UNARY MUL && l->in.type != FLOAT && shumul( l->in.left ) != STARREG ) offstar( l->in.left );
 490:             else order( l, INAREG|INTAREG|INBREG|INTBREG|INTEMP );
 491:             return( 1 );
 492:             }
 493:         if( !istnode( l ) ){
 494:             order( l, INTAREG|INTBREG );
 495:             return( 1 );
 496:             }
 497:         /* rewrite */
 498:         return( 0 );
 499:         }
 500:     /* now, rhs is complicated: must do both sides into registers */
 501:     /* do the harder side first */
 502: 
 503:     if( logop( p->in.op ) ){
 504:         /* relational: do both sides into regs if need be */
 505: 
 506:         if( r->in.su > l->in.su ){
 507:             if( niceuty(r) ){
 508:                 offstar( r->in.left );
 509:                 return( 1 );
 510:                 }
 511:             else if( !istnode( r ) ){
 512:                 order( r, INTAREG|INAREG|INTBREG|INBREG|INTEMP );
 513:                 return( 1 );
 514:                 }
 515:             }
 516:         if( niceuty(l) ){
 517:             offstar( l->in.left );
 518:             return( 1 );
 519:             }
 520:         else if( niceuty(r) ){
 521:             offstar( r->in.left );
 522:             return( 1 );
 523:             }
 524:         else if( !istnode( l ) ){
 525:             order( l, INTAREG|INAREG|INTBREG|INBREG|INTEMP );
 526:             return( 1 );
 527:             }
 528:         if( !istnode( r ) ){
 529:             order( r, INTAREG|INAREG|INTBREG|INBREG|INTEMP );
 530:             return( 1 );
 531:             }
 532:         cerror( "setbin can't deal with %s", opst[p->in.op] );
 533:         }
 534: 
 535:     /* ordinary operator */
 536: 
 537:     if( !istnode(r) && r->in.su > l->in.su ){
 538:         /* if there is a chance of making it addressable, try it... */
 539:         if( niceuty(r) ){
 540:             offstar( r->in.left );
 541:             return( 1 );  /* hopefully, it is addressable by now */
 542:             }
 543:         order( r, INTAREG|INAREG|INTBREG|INBREG|INTEMP );  /* anything goes on rhs */
 544:         return( 1 );
 545:         }
 546:     else {
 547:         if( !istnode( l ) ){
 548:             order( l, INTAREG|INTBREG );
 549:             return( 1 );
 550:             }
 551:         /* rewrite */
 552:         return( 0 );
 553:         }
 554:     }
 555: 
 556: setstr( p ) register NODE *p; { /* structure assignment */
 557:     if( p->in.right->in.op != REG ){
 558:         order( p->in.right, INTAREG );
 559:         return(1);
 560:         }
 561:     p = p->in.left;
 562:     if( p->in.op != NAME && p->in.op != OREG ){
 563:         if( p->in.op != UNARY MUL ) cerror( "bad setstr" );
 564:         order( p->in.left, INTAREG );
 565:         return( 1 );
 566:         }
 567:     return( 0 );
 568:     }
 569: 
 570: setasg( p ) register NODE *p; {
 571:     /* setup for assignment operator */
 572: 
 573:     if( p->in.right->in.su != 0 && p->in.right->in.op != REG ) {
 574:         if( p->in.right->in.op == UNARY MUL )
 575:             offstar( p->in.right->in.left );
 576:         else
 577:             order( p->in.right, INAREG|INBREG|SOREG|SNAME|SCON );
 578:         return(1);
 579:         }
 580:     if( p->in.right->in.op != REG && ( p->in.type == FLOAT || p->in.type == DOUBLE ) ) {
 581:         order( p->in.right, INBREG );
 582:         return(1);
 583:         }
 584:     if( p->in.left->in.op == UNARY MUL && !tshape( p->in.left, STARREG|STARNM ) ){
 585:         offstar( p->in.left->in.left );
 586:         return(1);
 587:         }
 588:     if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){
 589:         offstar( p->in.left->in.left->in.left );
 590:         return(1);
 591:         }
 592:     /* if things are really strange, get rhs into a register */
 593:     if( p->in.right->in.op != REG ){
 594:         order( p->in.right, INAREG|INBREG );
 595:         return( 1 );
 596:         }
 597:     return(0);
 598:     }
 599: 
 600: setasop( p ) register NODE *p; {
 601:     /* setup for =ops */
 602:     register sul, sur;
 603:     register NODE *q, *p2;
 604: 
 605:     sul = p->in.left->in.su;
 606:     sur = p->in.right->in.su;
 607: 
 608:     switch( p->in.op ){
 609: 
 610:     case ASG PLUS:
 611:     case ASG OR:
 612:     case ASG MINUS:
 613:         if( p->in.type != INT && p->in.type != UNSIGNED && !ISPTR(p->in.type) ) break;
 614:         if( p->in.right->in.type == CHAR || p->in.right->in.type == UCHAR ){
 615:             order( p->in.right, INAREG );
 616:             return( 1 );
 617:             }
 618:         break;
 619: 
 620:     case ASG ER:
 621:         if( sul == 0 || p->in.left->in.op == REG ){
 622:             if( p->in.left->in.type == CHAR || p->in.left->in.type == UCHAR ) goto rew;  /* rewrite */
 623:             order( p->in.right, INAREG|INBREG );
 624:             return( 1 );
 625:             }
 626:         goto leftadr;
 627:         }
 628: 
 629:     if( sur == 0 ){
 630: 
 631:     leftadr:
 632:         /* easy case: if addressable, do left value, op, store */
 633:         if( sul == 0 ) goto rew;  /* rewrite */
 634: 
 635:         /* harder; make aleft address, val, op, and store */
 636: 
 637:         if( p->in.left->in.op == UNARY MUL ){
 638:             offstar( p->in.left->in.left );
 639:             return( 1 );
 640:             }
 641:         if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){
 642:             offstar( p->in.left->in.left->in.left );
 643:             return( 1 );
 644:             }
 645:     rew:    /* rewrite, accounting for autoincrement and autodecrement */
 646: 
 647:         q = p->in.left;
 648:         if( q->in.op == FLD ) q = q->in.left;
 649:         if( q->in.op != UNARY MUL || shumul(q->in.left) != STARREG ) return(0); /* let reader.c do it */
 650: 
 651:         /* mimic code from reader.c */
 652: 
 653:         p2 = tcopy( p );
 654:         p->in.op = ASSIGN;
 655:         reclaim( p->in.right, RNULL, 0 );
 656:         p->in.right = p2;
 657: 
 658:         /* now, zap INCR on right, ASG MINUS on left */
 659: 
 660:         if( q->in.left->in.op == INCR ){
 661:             q = p2->in.left;
 662:             if( q->in.op == FLD ) q = q->in.left;
 663:             if( q->in.left->in.op != INCR ) cerror( "bad incr rewrite" );
 664:             }
 665:         else if( q->in.left->in.op != ASG MINUS )  cerror( " bad -= rewrite" );
 666: 
 667:         q->in.left->in.right->in.op = FREE;
 668:         q->in.left->in.op = FREE;
 669:         q->in.left = q->in.left->in.left;
 670: 
 671:         /* now, resume reader.c rewriting code */
 672: 
 673:         canon(p);
 674:         rallo( p, p->in.rall );
 675:         order( p2->in.left, INTBREG|INTAREG );
 676:         order( p2, INTBREG|INTAREG );
 677:         return( 1 );
 678:         }
 679: 
 680:     /* harder case: do right, left address, left value, op, store */
 681: 
 682:     if( p->in.right->in.op == UNARY MUL ){
 683:         offstar( p->in.right->in.left );
 684:         return( 1 );
 685:         }
 686:     /* sur> 0, since otherwise, done above */
 687:     if( p->in.right->in.op == REG ) goto leftadr;  /* make lhs addressable */
 688:     order( p->in.right, INAREG|INBREG );
 689:     return( 1 );
 690:     }
 691: 
 692: int crslab = 32767;
 693: 
 694: getlab(){
 695:     return( crslab-- );
 696:     }
 697: 
 698: deflab( l ){
 699:     printf( "L%d:\n", l );
 700:     }
 701: 
 702: genargs( p ) register NODE *p; {
 703:     register NODE *pasg;
 704:     register align;
 705:     register size;
 706:     int count;
 707: 
 708:     /* generate code for the arguments */
 709: 
 710:     /*  first, do the arguments on the right */
 711:     while( p->in.op == CM ){
 712:         genargs( p->in.right );
 713:         p->in.op = FREE;
 714:         p = p->in.left;
 715:         }
 716: 
 717:     if( p->in.op == STARG ){ /* structure valued argument */
 718: 
 719:         size = p->stn.stsize;
 720:         align = p->stn.stalign;
 721:         if( p->in.left->in.op == ICON ){
 722:             p->in.op = FREE;
 723:             p = p->in.left;
 724:             }
 725:         else {
 726:             /* make it look beautiful... */
 727:             p->in.op = UNARY MUL;
 728:             canon( p );  /* turn it into an oreg */
 729:             for( count = 0; p->in.op != OREG && count < 10; ++count ){
 730:                 offstar( p->in.left );
 731:                 canon( p );
 732:                 }
 733:             if( p->in.op != OREG ) cerror( "stuck starg" );
 734:             }
 735: 
 736:         pasg = talloc();
 737:         pasg->in.op = STARG;
 738:         pasg->in.rall = NOPREF;
 739:         pasg->stn.stsize = size;
 740:         pasg->stn.stalign = align;
 741:         pasg->in.left = p;
 742: 
 743:         order( pasg, FORARG );
 744:         return;
 745:         }
 746: 
 747:     /* ordinary case */
 748: 
 749:     order( p, FORARG );
 750:     }
 751: 
 752: OFFSZ
 753: argsize( p ) register NODE *p; {
 754:     OFFSZ t;
 755:     t = 0;
 756:     if( p->in.op == CM ){
 757:         t = argsize( p->in.left );
 758:         p = p->in.right;
 759:         }
 760:     if( p->in.type == DOUBLE || p->in.type == FLOAT ){
 761:         SETOFF( t, 2 );
 762:         return( t+8 );
 763:         }
 764:     else if( p->in.type == LONG || p->in.type == ULONG ) {
 765:         SETOFF( t, 2);
 766:         return( t+4 );
 767:         }
 768:     else if( p->in.op == STARG ){
 769:         SETOFF( t, p->stn.stalign );  /* alignment */
 770:         return( t + p->stn.stsize );  /* size */
 771:         }
 772:     else {
 773:         SETOFF( t, 2 );
 774:         return( t+2 );
 775:         }
 776:     }

Defined functions

argsize defined in line 752; used 2 times
autoincr defined in line 25; never used
deflab defined in line 698; never used
deltest defined in line 13; never used
genargs defined in line 702; used 2 times
getlab defined in line 694; never used
mkadrs defined in line 35; never used
mkrall defined in line 310; used 3 times
niceuty defined in line 474; used 4 times
notoff defined in line 69; never used
offstar defined in line 419; used 14 times
rallo defined in line 332; used 7 times
setasg defined in line 570; never used
setasop defined in line 600; never used
setbin defined in line 481; never used
setincr defined in line 465; never used
setstr defined in line 556; never used
stoasg defined in line 5; never used
sucomp defined in line 118; never used
zum defined in line 86; used 4 times

Defined variables

crslab defined in line 692; used 1 times
fltused defined in line 3; used 3 times
radebug defined in line 308; used 1 times

Defined macros

ZCHAR defined in line 82; used 5 times
ZFLOAT defined in line 84; used 5 times
ZLONG defined in line 83; used 5 times
max defined in line 78; used 18 times
min defined in line 79; used 2 times
Last modified: 1991-08-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3016
Valid CSS Valid XHTML 1.0 Strict