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