# 2.11BSD#431 - /usr/src/lib/pcc/order.c

##### Functions

    argsize           X
    autoincr          X
    deflab            X
    deltest           X
    genargs           X
    getlab            X
    mkadrs            X
    mkrall            X
    niceuty           X
    notoff            X
    offstar           X
    rallo             X
    setasg            X
    setasop           X
    setbin            X
    setincr           X
    setstr            X
    stoasg            X
    sucomp            X
    zum               X

##### Variables

    crslab            X
    fltused           X
    radebug           X

##### Macros

    ZCHAR             X
    ZFLOAT            X
    ZLONG             X
    max               X
    min               X

       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

- in line 757
- in /usr/src/lib/pcc/local2.c line 654

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

- in line 712
- in /usr/src/lib/pcc/local2.c line 658

getlab defined in line 694; never used
mkadrs defined in line 35; never used
mkrall defined in line 310; used 3 times

- in line 369, 375, 391

niceuty defined in line 474; used 4 times

- in line 507, 516-520(2), 539

notoff defined in line 69; never used
offstar defined in line 419; used 14 times

- in line 458, 468, 489, 508, 517-521(2), 540, 575, 585-589(2), 638-642(2), 683, 730

rallo defined in line 332; used 7 times

- in line 329, 371, 382-385(2), 414-415(2), 674

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

- in line 195-196(2), 223, 297

#### Defined variables

crslab defined in line 692; used 1 times

- in line 695

fltused defined in line 3; used 3 times

- in line 348
- in /usr/src/lib/pcc/local2.c line 25-26(2)

radebug defined in line 308; used 1 times

- in line 336

#### Defined macros

ZCHAR defined in line 82; used 5 times

- in line 99, 195-196(2), 223, 297

ZFLOAT defined in line 84; used 5 times

- in line 110, 195-196(2), 223, 297

ZLONG defined in line 83; used 5 times

- in line 105, 195-196(2), 223, 297

max defined in line 78; used 18 times

- in line 145, 160, 167-171(2), 185(2), 197(2), 228-235(4), 248(2), 300-304(4)

min defined in line 79; used 2 times

- in line 197, 304

Last modified: 1991-08-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1627 |