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