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