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