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