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