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