|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.