|
|
1.1 ! root 1: /* @(#) reader.c : 1.7 3/5/84 */ ! 2: ! 3: # include "mfile2.h" ! 4: ! 5: /* some storage declarations */ ! 6: ! 7: # ifdef TWOPASS ! 8: NODE node[TREESZ]; ! 9: char ftitle[100] = "\"\""; /* the name of the file */ ! 10: int ftnno; /* number of current function */ ! 11: int lineno; ! 12: #endif ! 13: ! 14: int lflag; ! 15: int e2debug; ! 16: int udebug; ! 17: int fast; ! 18: ! 19: /* maxtemp is the maximum size (in bits) needed for temps so far */ ! 20: /* maxarg is ditto for outgoing arguments */ ! 21: /* maxboff is ditto for automatic variables */ ! 22: /* earlier attempts to keep these on a per-block basis were silly */ ! 23: int maxtemp; ! 24: extern int maxarg; ! 25: int maxboff; ! 26: NODE * condit(); ! 27: ! 28: NODE * ! 29: force(p) ! 30: register NODE *p; ! 31: { ! 32: register NODE *q, *r; ! 33: if( !p ) cerror( "force" ); ! 34: q = talloc(); ! 35: *q = *p; ! 36: r = talloc(); ! 37: *r = *p; ! 38: q->tn.op = ASSIGN; ! 39: q->in.right = p; ! 40: q->in.left = r; ! 41: r->tn.op = QNODE; ! 42: r->tn.rval = callreg(p); /* the reg where the value will be forced */ ! 43: return( q ); ! 44: } ! 45: ! 46: p2init( argc, argv ) ! 47: char *argv[]; ! 48: { ! 49: /* set the values of the pass 2 arguments */ ! 50: ! 51: register int c; ! 52: register char *cp; ! 53: register files; ! 54: ! 55: allo0(); /* free all regs */ ! 56: files = 0; ! 57: ! 58: for( c=1; c<argc; ++c ) ! 59: { ! 60: if( *(cp=argv[c]) == '-' ) ! 61: { ! 62: while( *++cp ) ! 63: { ! 64: switch( *cp ) ! 65: { ! 66: ! 67: case 'X': /* pass1 flags */ ! 68: while( *++cp ) ! 69: { ! 70: /* VOID */ ! 71: } ! 72: --cp; ! 73: break; ! 74: ! 75: case 'l': /* linenos */ ! 76: ++lflag; ! 77: break; ! 78: ! 79: case 'e': /* expressions */ ! 80: ++e2debug; ! 81: break; ! 82: ! 83: case 'o': /* orders */ ! 84: ++odebug; ! 85: break; ! 86: ! 87: case 'r': /* register allocation */ ! 88: ++rdebug; ! 89: break; ! 90: ! 91: case 's': /* shapes */ ! 92: ++sdebug; ! 93: break; ! 94: ! 95: case 'u': /* Sethi-Ullman testing ! 96: (machine dependent) */ ! 97: ++udebug; ! 98: break; ! 99: ! 100: case 'f': /* try for faster compile speed */ ! 101: ++fast; ! 102: break; ! 103: ! 104: default: ! 105: cerror( "bad option: %c", *cp ); ! 106: } ! 107: } ! 108: } ! 109: else files = 1; /* assumed to be a ftitle */ ! 110: } ! 111: ! 112: mkdope(); ! 113: return( files ); ! 114: } ! 115: ! 116: NODE * ! 117: dlabel( p, l ) ! 118: register NODE *p; ! 119: { ! 120: /* define a label after p is executed */ ! 121: register NODE *q; ! 122: if( !p ) cerror( "dlabel" ); ! 123: q = talloc(); ! 124: q->tn.type = p->tn.type; ! 125: q->in.left = p; ! 126: q->tn.op = GENLAB; ! 127: q->bn.label = l; ! 128: return( q ); ! 129: } ! 130: ! 131: ! 132: NODE * ! 133: genbr( o, l, p ) ! 134: register NODE *p; ! 135: register o,l; ! 136: { ! 137: /* after evaluating p, generate a branch to l */ ! 138: /* if o is 0, unconditional */ ! 139: register NODE *q; ! 140: if( !p ) cerror( "genbr" ); ! 141: if( l < 0 ) cerror( "genbr1" ); ! 142: q = talloc(); ! 143: q->tn.op = o?GENBR:GENUBR; ! 144: q->tn.type = p->tn.type; ! 145: q->in.left = p; ! 146: q->bn.label = l; ! 147: q->bn.lop = o; ! 148: if( o && logop(p->tn.op) && ! 149: (p->tn.op != ANDAND) ! 150: && (p->tn.op != OROR) ! 151: ) p->tn.op = CMP; ! 152: return( q ); ! 153: } ! 154: ! 155: ! 156: static NODE * ! 157: oreff(p) ! 158: register NODE *p; ! 159: { ! 160: register NODE *r, *l; ! 161: NODE *condit(), *seq(); ! 162: int lab, t, f; ! 163: /* oreff is called if an || op is evaluated with goal=CEFF ! 164: The rhs of || ops should be executed only if the ! 165: lhs is false. Since our goal is CEFF, we don't need ! 166: a result of the ||, but we need to ! 167: preserve that dependancy with this special case */ ! 168: ! 169: /* We must catch this case before its children are ! 170: condit() and change the goal on it left child to CCC */ ! 171: ! 172: if (tcond(p->in.left)) { ! 173: tfree(p->in.right); ! 174: p->in.op = FREE; ! 175: p = condit( p->in.left, CEFF, -1, -1); ! 176: } else if (fcond(p->in.left)) { ! 177: p->in.op = COMOP; ! 178: p = condit( p, CEFF, -1, -1); ! 179: } else { ! 180: lab = getlab(); ! 181: l = condit( p->in.left, CCC, lab, -1); ! 182: r = condit( p->in.right, CEFF, -1, -1); ! 183: p->in.op = FREE; ! 184: p = seq(l, r); /* put r after l */ ! 185: p = dlabel(p, lab); ! 186: } ! 187: return p; ! 188: } ! 189: static NODE * ! 190: andeff(p) ! 191: register NODE *p; ! 192: { ! 193: register NODE *r, *l; ! 194: NODE *condit(); ! 195: int lab, t, f; ! 196: /* andeff is called if an && op is evaluated with goal=CEFF ! 197: The rhs of && ops should be executed only if the ! 198: lhs is true. Since our goal is CEFF, we don't need ! 199: a result of the &&, but we need to ! 200: preserve that dependancy with this special case */ ! 201: ! 202: /* We must catch this case before its children are ! 203: condit() and change the goal on it left child to CCC */ ! 204: ! 205: if (fcond(p->in.left)) { ! 206: tfree(p->in.right); ! 207: p->in.op = FREE; ! 208: p = condit( p->in.left, CEFF, -1, -1); ! 209: } else if (tcond(p->in.left)) { ! 210: p->in.op = COMOP; ! 211: p = condit( p, CEFF, -1, -1); ! 212: } else { ! 213: lab = getlab(); ! 214: p->in.op = FREE; ! 215: l = condit( p->in.left, CCC, -1, lab); ! 216: r = condit( p->in.right, CEFF, -1, -1); ! 217: p = seq(l, r); /* put r after l */ ! 218: p = dlabel(p, lab); ! 219: } ! 220: return p; ! 221: } ! 222: int negrel[] = ! 223: { ! 224: NE, EQ, GT, GE, LT, LE, UGT, UGE, ULT, ULE ! 225: } ; /* negatives of relationals */ ! 226: ! 227: tcond( p ) ! 228: register NODE *p; ! 229: { ! 230: /* return 1 if p is always true, 0 otherwise */ ! 231: register o = p->tn.op; ! 232: register NODE *q; ! 233: ! 234: switch( o ) ! 235: { ! 236: ! 237: case ICON: ! 238: return( p->tn.lval || p->tn.name != (char *) 0 ); ! 239: ! 240: case COMOP: ! 241: return( tcond( p->in.right ) ); ! 242: ! 243: case ANDAND: ! 244: return( tcond( p->in.left ) && tcond( p->in.right ) ); ! 245: ! 246: case OROR: ! 247: return( tcond( p->in.left ) || tcond( p->in.right ) ); ! 248: ! 249: case NOT: ! 250: return( fcond( p->in.left ) ); ! 251: ! 252: case QUEST: ! 253: q = p->in.right; ! 254: if( tcond( p->in.left ) ) return( tcond( q->in.left ) ); ! 255: if( fcond( p->in.left ) ) return( tcond( q->in.right ) ); ! 256: return( tcond( q->in.left ) && tcond( q->in.right ) ); ! 257: ! 258: default: ! 259: return( 0 ); ! 260: } ! 261: } ! 262: ! 263: fcond( p ) ! 264: register NODE *p; ! 265: { ! 266: /* return 1 if p is always false, 0 otherwise */ ! 267: register o = p->tn.op; ! 268: register NODE *q; ! 269: ! 270: switch( o ) ! 271: { ! 272: ! 273: case ICON: ! 274: return( !p->tn.lval && p->tn.name == (char *) 0 ); ! 275: ! 276: case COMOP: ! 277: return( fcond( p->in.right ) ); ! 278: ! 279: case ANDAND: ! 280: return( fcond( p->in.left ) || fcond( p->in.right ) ); ! 281: ! 282: case OROR: ! 283: return( fcond( p->in.left ) && fcond( p->in.right ) ); ! 284: ! 285: case NOT: ! 286: return( tcond( p->in.left ) ); ! 287: ! 288: case QUEST: ! 289: q = p->in.right; ! 290: if( tcond( p->in.left ) ) return( fcond( q->in.left ) ); ! 291: if( fcond( p->in.left ) ) return( fcond( q->in.right ) ); ! 292: return( fcond( q->in.left ) && fcond( q->in.right ) ); ! 293: ! 294: default: ! 295: return( 0 ); ! 296: } ! 297: } ! 298: ! 299: NODE * ! 300: rcomma( p ) ! 301: register NODE *p; ! 302: { ! 303: /* p is a COMOP; return the shrunken version thereof */ ! 304: ! 305: if( p->tn.op != COMOP ) cerror( "rcomma" ); ! 306: ! 307: if( p->in.left && p->in.right ) return( p ); ! 308: p->tn.op = FREE; ! 309: if( !p->in.left ) return( p->in.right ); ! 310: return( p->in.left ); ! 311: } ! 312: ! 313: NODE * ! 314: seq( p1, p2 ) ! 315: register NODE *p1, *p2; ! 316: { ! 317: /* execute p then q */ ! 318: register NODE *q; ! 319: ! 320: q = talloc(); ! 321: if (!p1) return p2; ! 322: if (!p2) return p1; ! 323: q->in.op = COMOP; ! 324: q->in.type = p2->in.right->in.type; ! 325: q->in.left = p1; ! 326: q->in.right = p2; ! 327: return q; ! 328: } ! 329: ! 330: NODE * ! 331: gtb( p, l ) ! 332: register NODE *p; ! 333: register l; ! 334: { ! 335: register NODE *q; ! 336: /* replace p by a trivial branch to l */ ! 337: /* if l is -1, return NULL */ ! 338: q = condit( p, CEFF, -1, -1 ); ! 339: if( l<0 ) return( q ); ! 340: if( !q ) ! 341: { ! 342: q = talloc(); ! 343: q->tn.op = ICON; ! 344: q->tn.lval = 0; ! 345: q->tn.name = (char *) 0; ! 346: q->tn.type = TINT; ! 347: } ! 348: return( genbr( 0, l, q ) ); ! 349: } ! 350: ! 351: NODE * ! 352: condit( p, goal, t, f ) ! 353: register NODE *p; ! 354: register goal,t,f; ! 355: { ! 356: /* generate code for conditionals in terms of GENLAB and GENBR nodes */ ! 357: /* goal is either CEFF, NRGS, or CCC */ ! 358: /* also, delete stuff that never needs get done */ ! 359: /* if goal==CEFF, return of null means nothing to be done */ ! 360: ! 361: register o, lt, lf, l; ! 362: register NODE *q, *q1, *q2; ! 363: ! 364: o = p->tn.op; ! 365: ! 366: #ifndef NODBG ! 367: if( odebug >2 ) ! 368: { ! 369: printf( "condit( %d (%s), %s, %d, %d )\n", (int)(p-node), ! 370: opst[o], goal==CCC?"CCC":(goal==NRGS?"NRGS":"CEFF"), ! 371: t, f ); ! 372: } ! 373: #endif ! 374: if( o == CBRANCH ) ! 375: { ! 376: p->in.right->tn.op = p->tn.op = FREE; ! 377: l = p->in.right->tn.lval; ! 378: p = p->in.left; ! 379: if( fcond( p ) ) return( gtb(p,l) ); ! 380: if( tcond( p ) ) return( gtb(p,-1) ); ! 381: return( condit( p, CCC, -1, l ) ); ! 382: } ! 383: ! 384: /* a convenient place to diddle a few special ops */ ! 385: if( callop(o) ) ! 386: { ! 387: if( optype(o) == UTYPE ) p->stn.argsize = 0; ! 388: else p->stn.argsize = argsize(p->in.right); ! 389: if( goal==CEFF ) goal = NRGS; ! 390: /* flow on, so that we can handle if( f(...) )... */ ! 391: } ! 392: else if( goal==CEFF && (asgop(o) || o==STASG || o==INIT)) goal=NRGS; ! 393: ! 394: /* do a bit of optimization */ ! 395: ! 396: if( goal == NRGS ) ! 397: { ! 398: if( logop(o) ) ! 399: { ! 400: /* must make p into ( p ? 1 : 0 ), then recompile */ ! 401: q1 = talloc(); ! 402: q1->tn.op = ICON; ! 403: q1->tn.name = (char *) 0; ! 404: q1->tn.lval = 1; ! 405: q1->tn.type = p->tn.type; ! 406: q2 = talloc(); ! 407: *q2 = *q1; ! 408: q2->tn.lval = 0; ! 409: q = talloc(); ! 410: q->tn.op = COLON; ! 411: q->tn.type = p->tn.type; ! 412: q->in.left = q1; ! 413: q->in.right = q2; ! 414: q1 = talloc(); ! 415: q1->tn.op = o = QUEST; ! 416: q1->tn.type = p->tn.type; ! 417: q1->in.left = p; ! 418: q1->in.right = q; ! 419: p = q1; /* flow on, and compile */ ! 420: } ! 421: } ! 422: ! 423: if( goal != CCC ) ! 424: { ! 425: if( o == QUEST ) ! 426: { ! 427: /* rewrite ? : when goal not CCC */ ! 428: lf = getlab(); ! 429: l = getlab(); ! 430: p->tn.op = COMOP; ! 431: q = p->in.right; ! 432: q1 = condit( q->in.left, goal, -1, -1 ); ! 433: q->in.right = condit( q->in.right, goal, -1, -1 ); ! 434: if( tcond( p->in.left ) ) ! 435: { ! 436: q->tn.op = FREE; ! 437: tfree( q->in.right ); ! 438: p->in.right = q1; ! 439: p->in.left=condit( p->in.left, CEFF, -1, -1 ); ! 440: return( rcomma( p ) ); ! 441: } ! 442: if( fcond( p->in.left ) ) ! 443: { ! 444: q->tn.op = FREE; ! 445: tfree( q1 ); ! 446: p->in.right = q->in.right; ! 447: p->in.left=condit( p->in.left, CEFF, -1, -1 ); ! 448: return( rcomma( p ) ); ! 449: } ! 450: if( !q1 ) ! 451: { ! 452: if( !q->in.right ) ! 453: { ! 454: /* may still have work to do ! 455: ** if left side of ? has effect ! 456: */ ! 457: q1 = condit(p->in.left, goal, ! 458: -1, -1); ! 459: if (!q1) ! 460: { ! 461: tfree( p->in.left ); ! 462: } ! 463: p->tn.op = q->tn.op = FREE; ! 464: return( q1 ); ! 465: } ! 466: /* rhs done if condition is false */ ! 467: p->in.left = condit( p->in.left, CCC, l, -1 ); ! 468: p->in.right = dlabel( q->in.right, l ); ! 469: q->tn.op = FREE; ! 470: return( p ); ! 471: } ! 472: else if( !q->in.right ) ! 473: { ! 474: /* lhs done if condition is true */ ! 475: p->in.left=condit( p->in.left, CCC, -1, lf ); ! 476: p->in.right = dlabel( q1, lf ); ! 477: q->tn.op = FREE; ! 478: return( p ); ! 479: } ! 480: ! 481: /* both sides exist and the condition is nontrivial */ ! 482: p->in.left = condit( p->in.left, CCC, -1, lf ); ! 483: q1 = force(q1); ! 484: q->in.right = force(q->in.right); ! 485: q1 = genbr( 0, l, q1 ); ! 486: q->in.left = dlabel( q1, lf ); ! 487: q->tn.op = COMOP; ! 488: return( dlabel( p, l ) ); ! 489: } ! 490: ! 491: if( goal == CEFF ) ! 492: { ! 493: /* some things may disappear */ ! 494: switch( o ) ! 495: { ! 496: ! 497: case CBRANCH: ! 498: case GENBR: ! 499: case GENUBR: ! 500: case CALL: ! 501: case UNARY CALL: ! 502: case FORTCALL: ! 503: case UNARY FORTCALL: ! 504: case STCALL: ! 505: case UNARY STCALL: ! 506: case STASG: ! 507: case INIT: ! 508: case MOD: /* do these for the side effects */ ! 509: case DIV: ! 510: case UOP0: ! 511: case UOP1: ! 512: case UOP2: ! 513: case UOP3: ! 514: case UOP4: ! 515: case UOP5: ! 516: case UOP6: ! 517: case UOP7: ! 518: case UOP8: ! 519: case UOP9: ! 520: goal = NRGS; ! 521: } ! 522: } ! 523: ! 524: /* The rhs of && and || ops are executed only if the ! 525: result is not clear from the lhs. If our goal is ! 526: CEFF, we don't need a result, but we need to ! 527: preserve that dependancy. So special case it. */ ! 528: if (goal==CEFF) { ! 529: if (o == ANDAND) return andeff(p); ! 530: if (o == OROR) return oreff(p); ! 531: } ! 532: /* This next batch of code wanders over the tree getting ! 533: rid of code which is for effect only and has no ! 534: effect */ ! 535: switch( optype(o) ) ! 536: { ! 537: case LTYPE: ! 538: if( goal == CEFF ) ! 539: { ! 540: p->tn.op = FREE; ! 541: return( NIL ); ! 542: } ! 543: break; ! 544: ! 545: case BITYPE: ! 546: p->in.right = condit( p->in.right, goal, -1, -1 ); ! 547: case UTYPE: ! 548: p->in.left = condit( p->in.left, o==COMOP?CEFF:goal, ! 549: -1, -1 ); ! 550: } ! 551: /* If we are only interested in effects, we quit here */ ! 552: if( goal == CEFF || o==COMOP ) ! 553: { ! 554: /* lhs or rhs may have disappeared */ ! 555: /* op need not get done */ ! 556: ! 557: switch( optype(o) ) ! 558: { ! 559: ! 560: case BITYPE: ! 561: p->tn.op = COMOP; ! 562: p = rcomma(p); ! 563: return ( p ); ! 564: ! 565: case UTYPE: ! 566: p->tn.op = FREE; ! 567: return( p->in.left ); ! 568: ! 569: case LTYPE: ! 570: p->tn.op = FREE; ! 571: return( NIL ); ! 572: } ! 573: } ! 574: return( p ); ! 575: } ! 576: ! 577: /* goal must = CCC from here on */ ! 578: ! 579: switch( o ) ! 580: { ! 581: ! 582: case ULE: ! 583: case ULT: ! 584: case UGE: ! 585: case UGT: ! 586: case EQ: ! 587: case NE: ! 588: case LE: ! 589: case LT: ! 590: case GE: ! 591: case GT: ! 592: if(t<0 ) ! 593: { ! 594: o = p->tn.op = negrel[o-EQ]; ! 595: t = f; ! 596: f = -1; ! 597: } ! 598: ! 599: #ifndef NOOPT ! 600: if( p->in.right->in.op == ICON && ! 601: p->in.right->tn.lval == 0 && ! 602: p->in.right->in.name == (char *) 0 ) ! 603: { ! 604: /* if chars are unsigned, do these optimizations ! 605: as if this is an unsigned compare*/ ! 606: #ifndef CHSIGN ! 607: if ( ! 608: ( p->in.left->tn.type == TCHAR || ! 609: ( p->in.left->in.op == CONV && ! 610: p->in.left->in.left->tn.type == TCHAR ) ) ! 611: && o >= LE && o <= GT) ! 612: o += UGT - GT; ! 613: #endif ! 614: ! 615: /* the question here is whether we can assume that */ ! 616: /* unconditional branches preserve condition codes */ ! 617: /* if this turned out to be no, we would have to */ ! 618: /* explicitly handle this case here */ ! 619: ! 620: switch( o ) ! 621: { ! 622: ! 623: case UGT: ! 624: case ULE: ! 625: o = p->in.op = (o==UGT)?NE:EQ; ! 626: case EQ: ! 627: case NE: ! 628: case LE: ! 629: case LT: ! 630: case GE: ! 631: case GT: ! 632: if( logop( p->in.left->tn.op ) ) ! 633: { ! 634: /* situation like (a==0)==0 */ ! 635: /* ignore optimization */ ! 636: goto noopt; ! 637: } ! 638: break; ! 639: ! 640: case ULT: /* never succeeds */ ! 641: return( gtb( p, f ) ); ! 642: ! 643: case UGE: ! 644: /* always succeeds */ ! 645: return( gtb( p, t ) ); ! 646: } ! 647: p->tn.op = p->in.right->tn.op = FREE; ! 648: p = condit( p->in.left, NRGS, -1, -1 ); ! 649: p = genbr( o, t, p ); ! 650: if( f<0 ) return( p ); ! 651: else return( genbr( 0, f, p ) ); ! 652: } ! 653: noopt: ! 654: # endif ! 655: ! 656: p->in.left = condit( p->in.left, NRGS, -1, -1 ); ! 657: p->in.right = condit( p->in.right, NRGS, -1, -1 ); ! 658: p = genbr( o, t, p ); ! 659: if( f>=0 ) p = genbr( 0, f, p ); ! 660: return( p ); ! 661: ! 662: case COMOP: ! 663: p->in.left = condit( p->in.left, CEFF, -1, -1 ); ! 664: p->in.right = condit( p->in.right, CCC, t, f ); ! 665: return( rcomma( p ) ); ! 666: ! 667: case NOT: ! 668: p->tn.op = FREE; ! 669: return( condit( p->in.left, CCC, f, t ) ); ! 670: ! 671: case ANDAND: ! 672: lf = f<0 ? getlab() : f; ! 673: lt = t<0 ? getlab() : t; ! 674: p->tn.op = COMOP; ! 675: if( tcond( p->in.left ) ) ! 676: { ! 677: /* left is always true */ ! 678: p->in.left = condit( p->in.left, CEFF, -1, -1 ); ! 679: p->in.right = condit( p->in.right, CCC, t, f ); ! 680: } ! 681: else { ! 682: /* lhs not always true */ ! 683: if( tcond( p->in.right ) ) ! 684: { ! 685: /* rhs is always true */ ! 686: p->in.right = ! 687: condit( p->in.right, CEFF, -1, -1 ); ! 688: if (p->in.right) { ! 689: /* const with sideeffect */ ! 690: p->in.left = ! 691: condit( p->in.left, CCC, -1,lf); ! 692: p->in.right = condit( p->in.right, ! 693: CCC, t, t ); ! 694: } else ! 695: p->in.left = ! 696: condit( p->in.left, CCC, t, f ); ! 697: } else { ! 698: p->in.left = ! 699: condit( p->in.left, CCC, -1, lf ); ! 700: p->in.right = ! 701: condit( p->in.right, CCC, t, f ); ! 702: } ! 703: } ! 704: q = rcomma( p ); ! 705: if( f<0 ) q = dlabel( q, lf ); ! 706: if( t<0 ) q = dlabel( q, lt ); ! 707: return( q ); ! 708: ! 709: case OROR: ! 710: lf = f<0 ? getlab() : f; ! 711: lt = t<0 ? getlab() : t; ! 712: p->tn.op = COMOP; ! 713: if( fcond( p->in.left ) ) ! 714: { ! 715: /* left is always false */ ! 716: p->in.left = condit( p->in.left, CEFF, -1, -1 ); ! 717: p->in.right = condit( p->in.right, CCC, t, f ); ! 718: } ! 719: else { ! 720: /* left is not always false */ ! 721: if( fcond( p->in.right ) ) ! 722: { ! 723: /* right always false */ ! 724: p->in.right = ! 725: condit( p->in.right, CEFF, -1, -1 ); ! 726: if (p->in.right) { ! 727: /* const with sideeffect */ ! 728: p->in.left = ! 729: condit( p->in.left, CCC, lt,-1); ! 730: /* This may generate a superfluous ! 731: test. Tough. */ ! 732: p->in.right = condit( p->in.right, ! 733: CCC, f, f ); ! 734: } else ! 735: p->in.left = ! 736: condit( p->in.left, CCC, t, f ); ! 737: } else { ! 738: p->in.left = ! 739: condit( p->in.left, CCC, lt, -1 ); ! 740: p->in.right = ! 741: condit( p->in.right, CCC, t, f ); ! 742: } ! 743: } ! 744: p = rcomma( p ); ! 745: if( f<0 ) p = dlabel( p, lf ); ! 746: if( t<0 ) p = dlabel( p, lt ); ! 747: return( p ); ! 748: ! 749: case QUEST: ! 750: lf = f<0 ? getlab() : f; ! 751: lt = t<0 ? getlab() : t; ! 752: p->in.left = condit( p->in.left, CCC, -1, l=getlab() ); ! 753: q = p->in.right; ! 754: q1 = condit( q->in.left, goal, lt, lf ); ! 755: q->in.left = dlabel( q1, l ); ! 756: q->in.right = condit( q->in.right, goal, t, f ); ! 757: p->tn.op = COMOP; ! 758: q->tn.op = COMOP; ! 759: if( t<0 ) p = dlabel( p, lt ); ! 760: if( f<0 ) p = dlabel( p, lf ); ! 761: return( p ); ! 762: ! 763: default: ! 764: /* get the condition codes, generate the branch */ ! 765: switch( optype(o) ) ! 766: { ! 767: case BITYPE: ! 768: p->in.right = condit( p->in.right, NRGS, -1, -1 ); ! 769: case UTYPE: ! 770: p->in.left = condit( p->in.left, NRGS, -1, -1 ); ! 771: } ! 772: if( t>=0 ) p = genbr( NE, t, p ); ! 773: if( f>=0 ) p = genbr( (t>=0)?0:EQ, f, p ); ! 774: return( p ); ! 775: } ! 776: } ! 777: ! 778: # ifndef TWOPASS ! 779: ! 780: p2compile( p ) ! 781: register NODE *p; ! 782: { ! 783: if( lflag ) lineid( lineno, ftitle ); ! 784: tmpoff = 0; /* expression at top level reuses temps */ ! 785: /* generate code for the tree p */ ! 786: ! 787: # ifdef MYREADER ! 788: MYREADER(p); /* do your own laundering of the input */ ! 789: # endif ! 790: /* eliminate the conditionals */ ! 791: # ifndef NODBG ! 792: if( p && odebug>2 ) e2print(p); ! 793: # endif ! 794: p = condit( p, CEFF, -1, -1 ); ! 795: if( p ) ! 796: { ! 797: /* expression does something */ ! 798: /* generate the code */ ! 799: # ifndef NODBG ! 800: if( odebug>2 ) e2print(p); ! 801: # endif ! 802: codgen( p ); ! 803: } ! 804: # ifndef NODBG ! 805: else if( odebug>1 ) printf( "null effect\n" ); ! 806: # endif ! 807: allchk(); ! 808: /* tcheck will be done by the first pass at the end of a ftn. */ ! 809: /* first pass will do it... */ ! 810: } ! 811: ! 812: p2bbeg( aoff, myreg ) ! 813: register aoff,myreg; ! 814: { ! 815: static int myftn = -1; ! 816: SETOFF( aoff, ALSTACK ); ! 817: if( myftn != ftnno ) ! 818: { ! 819: /* beginning of function */ ! 820: maxboff = aoff; ! 821: myftn = ftnno; ! 822: maxtemp = 0; ! 823: maxarg = 0; ! 824: } ! 825: else ! 826: { ! 827: if( aoff > maxboff ) maxboff = aoff; ! 828: } ! 829: # ifdef SETREGS ! 830: SETREGS(myreg); ! 831: # endif ! 832: } ! 833: ! 834: p2bend() ! 835: { ! 836: SETOFF( maxboff, ALSTACK ); ! 837: SETOFF( maxarg, ALSTACK ); ! 838: SETOFF( maxtemp, ALSTACK ); ! 839: eobl2(); ! 840: maxboff = maxarg = maxtemp = 0; ! 841: } ! 842: ! 843: # endif ! 844: ! 845: char *cnames[] = ! 846: { ! 847: "CEFF", ! 848: "NRGS", ! 849: "CCC", ! 850: 0, ! 851: }; ! 852: ! 853: prgoal( goal ) ! 854: register goal; ! 855: { ! 856: /* print a nice-looking description of goal */ ! 857: ! 858: register i, flag; ! 859: ! 860: flag = 0; ! 861: for( i=0; cnames[i]; ++i ) ! 862: { ! 863: if( goal & (1<<i) ) ! 864: { ! 865: if( flag ) printf( "|" ); ! 866: ++flag; ! 867: printf( cnames[i] ); ! 868: } ! 869: } ! 870: if( !flag ) printf( "?%o", goal ); ! 871: ! 872: } ! 873: ! 874: #ifndef NODBG ! 875: e2print( p ) ! 876: register NODE *p; ! 877: { ! 878: printf( "\n********* costs=(0,...,NRGS;EFF;TEMP;CC)\n" ); ! 879: e22print( p ,"T"); ! 880: printf("=========\n"); ! 881: } ! 882: ! 883: e22print( p ,s) ! 884: register NODE *p; ! 885: char *s; ! 886: { ! 887: static down=0; ! 888: register ty; ! 889: ! 890: ty = optype( p->tn.op ); ! 891: if( ty == BITYPE ) ! 892: { ! 893: ++down; ! 894: e22print( p->in.right ,"R"); ! 895: --down; ! 896: } ! 897: e222print( down, p, s ); ! 898: ! 899: if( ty != LTYPE ) ! 900: { ! 901: ++down; ! 902: e22print( p->in.left, "L" ); ! 903: --down; ! 904: } ! 905: } ! 906: ! 907: e222print( down, p, s ) ! 908: NODE *p; ! 909: char *s; ! 910: { ! 911: /* print one node */ ! 912: int i, d; ! 913: ! 914: for( d=down; d>1; d -= 2 ) printf( "\t" ); ! 915: if( d ) printf( " " ); ! 916: ! 917: printf( "%s.%d) op= '%s'",s, (int)(p-node), opst[p->in.op] ); ! 918: switch( p->in.op ) ! 919: { ! 920: /* special cases */ ! 921: case REG: ! 922: printf( " %s", rnames[p->tn.rval] ); ! 923: break; ! 924: ! 925: case ICON: ! 926: case NAME: ! 927: case VAUTO: ! 928: case VPARAM: ! 929: case TEMP: ! 930: printf( " " ); ! 931: adrput( p ); ! 932: break; ! 933: ! 934: case STCALL: ! 935: case UNARY STCALL: ! 936: printf( " args=%d", p->stn.argsize ); ! 937: case STARG: ! 938: case STASG: ! 939: printf( " size=%d", p->stn.stsize ); ! 940: printf( " align=%d", p->stn.stalign ); ! 941: break; ! 942: ! 943: case GENBR: ! 944: printf( " %d (%s)", p->bn.label, opst[p->bn.lop] ); ! 945: break; ! 946: ! 947: case CALL: ! 948: case UNARY CALL: ! 949: printf( " args=%d", p->stn.argsize ); ! 950: break; ! 951: ! 952: case GENUBR: ! 953: case GENLAB: ! 954: printf( " %d", p->bn.label ); ! 955: break; ! 956: ! 957: case FUNARG: ! 958: printf( " offset=%d", p->tn.rval ); ! 959: ! 960: } ! 961: ! 962: printf( ", " ); ! 963: t2print( p->in.type ); ! 964: printf( ", c=[" ); ! 965: for( i=0; i<NRGS; ++i ) cprt( p->in.cst[i], "," ); ! 966: cprt( p->in.cst[NRGS], "; " ); ! 967: cprt( p->in.cst[CEFF], "; " ); ! 968: cprt( p->in.cst[CTEMP], "; " ); ! 969: cprt( p->in.cst[CCC], "]" ); ! 970: if( p->tn.goal == CEFF ) printf( " (EFF)\n" ); ! 971: else if( p->tn.goal == CCC ) printf( " (CC)\n" ); ! 972: else if( p->tn.goal != NRGS ) printf( "(BAD GOAL: %d)\n", p->tn.goal ); ! 973: else printf( "\n" ); ! 974: } ! 975: ! 976: t2print( t ) ! 977: TWORD t; ! 978: { ! 979: int i; ! 980: static struct { ! 981: TWORD mask; ! 982: char * string; ! 983: } t2tab[] = { ! 984: TANY, "ANY", ! 985: TINT, "INT", ! 986: TUNSIGNED, "UNSIGNED", ! 987: TCHAR, "CHAR", ! 988: TUCHAR, "UCHAR", ! 989: TSHORT, "SHORT", ! 990: TUSHORT, "USHORT", ! 991: TLONG, "LONG", ! 992: TULONG, "ULONG", ! 993: TFLOAT, "FLOAT", ! 994: TDOUBLE, "DOUBLE", ! 995: TPOINT, "POINTER", ! 996: TPOINT2, "POINTER2", ! 997: TSTRUCT, "STRUCT", ! 998: TVOID, "VOID", ! 999: 0, 0 ! 1000: }; ! 1001: ! 1002: for( i=0; t && t2tab[i].mask; ++i ) { ! 1003: if( (t&t2tab[i].mask) == t2tab[i].mask ) { ! 1004: printf( " %s", t2tab[i].string ); ! 1005: t ^= t2tab[i].mask; ! 1006: } ! 1007: } ! 1008: } ! 1009: ! 1010: # else ! 1011: e2print( p ) ! 1012: NODE *p; ! 1013: { ! 1014: werror( "e2print not compiled" ); ! 1015: } ! 1016: e222print( p, s ) ! 1017: NODE *p; ! 1018: char *s; ! 1019: { ! 1020: werror( "e222print not compiled" ); ! 1021: } ! 1022: # endif ! 1023: cprt( c, s ) ! 1024: register char *s; ! 1025: register c; ! 1026: { ! 1027: if( c >= INFINITY ) printf( "*%s", s ); ! 1028: else printf( "%d%s", c, s ); ! 1029: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.