|
|
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(), *prepass(); ! 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: int odebug = 0, rdebug = 0, sdebug = 0; ! 47: ! 48: p2init( argc, argv ) ! 49: char *argv[]; ! 50: { ! 51: /* set the values of the pass 2 arguments */ ! 52: ! 53: register int c; extern int syncstdio; ! 54: register char *cp; ! 55: register files; ! 56: ! 57: allo0(); /* free all regs */ ! 58: files = 0; ! 59: ! 60: for( c=1; c<argc; ++c ) ! 61: { ! 62: if( *(cp=argv[c]) == '-' ) ! 63: { ! 64: while( *++cp ) ! 65: { ! 66: switch(++syncstdio, *cp) ! 67: { ! 68: ! 69: case 'X': /* pass1 flags */ ! 70: while( *++cp ) ! 71: { ! 72: /* VOID */ ! 73: } ! 74: --syncstdio; ! 75: --cp; ! 76: break; ! 77: # ifdef GDEBUG ! 78: #define LL_TOP 0 /* from mfile1.h */ ! 79: case 'g': /* another stab in the back */ ! 80: { ! 81: extern int gdebug; ! 82: extern int wloop_level, floop_level; ! 83: gdebug = !gdebug; ! 84: wloop_level = LL_TOP; /* natural */ ! 85: floop_level = LL_TOP; /* loops */ ! 86: } /* fall through */ ! 87: # endif ! 88: case 'l': /* linenos */ ! 89: --syncstdio; ! 90: ++lflag; ! 91: break; ! 92: ! 93: case 'e': /* expressions */ ! 94: ++e2debug; ! 95: break; ! 96: ! 97: case 'o': /* orders */ ! 98: ++odebug; ! 99: break; ! 100: ! 101: case 'r': /* register allocation */ ! 102: ++rdebug; ! 103: break; ! 104: ! 105: case 's': /* shapes */ ! 106: ++sdebug; ! 107: break; ! 108: ! 109: case 'u': /* Sethi-Ullman testing ! 110: (machine dependent) */ ! 111: ++udebug; ! 112: break; ! 113: ! 114: case 'f': /* try for faster compile speed */ ! 115: ++fast; ! 116: break; ! 117: ! 118: default: ! 119: cerror( "bad option: %c", *cp ); ! 120: } ! 121: } ! 122: } ! 123: else files = 1; /* assumed to be a ftitle */ ! 124: } ! 125: ! 126: mkdope(); ! 127: return( files ); ! 128: } ! 129: ! 130: NODE * ! 131: dlabel( p, l ) ! 132: register NODE *p; ! 133: { ! 134: /* define a label after p is executed */ ! 135: register NODE *q; ! 136: ! 137: /* condit will throw away things, fix here ! 138: /* if( !p ) cerror( "dlabel" ); ! 139: */ ! 140: if (!p) /* create conventional dumb subtree */ ! 141: { ! 142: p = talloc(); ! 143: p->tn.op = ICON; ! 144: p->tn.name = NULL; ! 145: p->tn.lval = 0; ! 146: p->tn.type = TINT; ! 147: } ! 148: q = talloc(); ! 149: q->tn.type = p->tn.type; ! 150: q->in.left = p; ! 151: q->tn.op = GENLAB; ! 152: q->bn.label = l; ! 153: return( q ); ! 154: } ! 155: ! 156: ! 157: NODE * ! 158: genbr( o, l, p ) ! 159: register NODE *p; ! 160: register o,l; ! 161: { ! 162: /* after evaluating p, generate a branch to l */ ! 163: /* if o is 0, unconditional */ ! 164: register NODE *q; ! 165: if( !p ) cerror( "genbr" ); ! 166: if( l < 0 ) cerror( "genbr1" ); ! 167: q = talloc(); ! 168: q->tn.op = o?GENBR:GENUBR; ! 169: q->tn.type = p->tn.type; ! 170: q->in.left = p; ! 171: q->bn.label = l; ! 172: q->bn.lop = o; ! 173: if( o && logop(p->tn.op) && ! 174: (p->tn.op != ANDAND) ! 175: && (p->tn.op != OROR) ! 176: ) p->tn.op = CMP; ! 177: return( q ); ! 178: } ! 179: ! 180: ! 181: static NODE * ! 182: oreff(p) ! 183: register NODE *p; ! 184: { ! 185: register NODE *r, *l; ! 186: NODE *condit(), *seq(); ! 187: int lab, t, f; ! 188: /* oreff is called if an || op is evaluated with goal=CEFF ! 189: The rhs of || ops should be executed only if the ! 190: lhs is false. Since our goal is CEFF, we don't need ! 191: a result of the ||, but we need to ! 192: preserve that dependancy with this special case */ ! 193: ! 194: /* We must catch this case before its children are ! 195: condit() and change the goal on it left child to CCC */ ! 196: ! 197: if (tcond(p->in.left)) { ! 198: tfree(p->in.right); ! 199: p->in.op = FREE; ! 200: p = condit( p->in.left, CEFF, -1, -1); ! 201: } else if (fcond(p->in.left)) { ! 202: p->in.op = COMOP; ! 203: p = condit( p, CEFF, -1, -1); ! 204: } else { ! 205: lab = getlab(); ! 206: l = condit( p->in.left, CCC, lab, -1); ! 207: r = condit( p->in.right, CEFF, -1, -1); ! 208: p->in.op = FREE; ! 209: p = seq(l, r); /* put r after l */ ! 210: p = dlabel(p, lab); ! 211: } ! 212: return p; ! 213: } ! 214: static NODE * ! 215: andeff(p) ! 216: register NODE *p; ! 217: { ! 218: register NODE *r, *l; ! 219: NODE *condit(); ! 220: int lab, t, f; ! 221: /* andeff is called if an && op is evaluated with goal=CEFF ! 222: The rhs of && ops should be executed only if the ! 223: lhs is true. Since our goal is CEFF, we don't need ! 224: a result of the &&, but we need to ! 225: preserve that dependancy with this special case */ ! 226: ! 227: /* We must catch this case before its children are ! 228: condit() and change the goal on it left child to CCC */ ! 229: ! 230: if (fcond(p->in.left)) { ! 231: tfree(p->in.right); ! 232: p->in.op = FREE; ! 233: p = condit( p->in.left, CEFF, -1, -1); ! 234: } else if (tcond(p->in.left)) { ! 235: p->in.op = COMOP; ! 236: p = condit( p, CEFF, -1, -1); ! 237: } else { ! 238: lab = getlab(); ! 239: p->in.op = FREE; ! 240: l = condit( p->in.left, CCC, -1, lab); ! 241: r = condit( p->in.right, CEFF, -1, -1); ! 242: p = seq(l, r); /* put r after l */ ! 243: p = dlabel(p, lab); ! 244: } ! 245: return p; ! 246: } ! 247: int negrel[] = ! 248: { ! 249: NE, EQ, GT, GE, LT, LE, UGT, UGE, ULT, ULE ! 250: } ; /* negatives of relationals */ ! 251: ! 252: tcond( p ) ! 253: register NODE *p; ! 254: { ! 255: /* return 1 if p is always true, 0 otherwise */ ! 256: register o = p->tn.op; ! 257: register NODE *q; ! 258: ! 259: switch( o ) ! 260: { ! 261: ! 262: case ICON: ! 263: return( p->tn.lval || p->tn.name != (char *) 0 ); ! 264: ! 265: case COMOP: ! 266: return( tcond( p->in.right ) ); ! 267: ! 268: case ANDAND: ! 269: return( tcond( p->in.left ) && tcond( p->in.right ) ); ! 270: ! 271: case OROR: ! 272: return( tcond( p->in.left ) || tcond( p->in.right ) ); ! 273: ! 274: case NOT: ! 275: return( fcond( p->in.left ) ); ! 276: ! 277: case QUEST: ! 278: q = p->in.right; ! 279: if( tcond( p->in.left ) ) return( tcond( q->in.left ) ); ! 280: if( fcond( p->in.left ) ) return( tcond( q->in.right ) ); ! 281: return( tcond( q->in.left ) && tcond( q->in.right ) ); ! 282: ! 283: default: ! 284: return( 0 ); ! 285: } ! 286: } ! 287: ! 288: fcond( p ) ! 289: register NODE *p; ! 290: { ! 291: /* return 1 if p is always false, 0 otherwise */ ! 292: register o = p->tn.op; ! 293: register NODE *q; ! 294: ! 295: switch( o ) ! 296: { ! 297: ! 298: case ICON: ! 299: return( !p->tn.lval && p->tn.name == (char *) 0 ); ! 300: ! 301: case COMOP: ! 302: return( fcond( p->in.right ) ); ! 303: ! 304: case ANDAND: ! 305: return( fcond( p->in.left ) || fcond( p->in.right ) ); ! 306: ! 307: case OROR: ! 308: return( fcond( p->in.left ) && fcond( p->in.right ) ); ! 309: ! 310: case NOT: ! 311: return( tcond( p->in.left ) ); ! 312: ! 313: case QUEST: ! 314: q = p->in.right; ! 315: if( tcond( p->in.left ) ) return( fcond( q->in.left ) ); ! 316: if( fcond( p->in.left ) ) return( fcond( q->in.right ) ); ! 317: return( fcond( q->in.left ) && fcond( q->in.right ) ); ! 318: ! 319: default: ! 320: return( 0 ); ! 321: } ! 322: } ! 323: ! 324: NODE * ! 325: rcomma( p ) ! 326: register NODE *p; ! 327: { ! 328: /* p is a COMOP; return the shrunken version thereof */ ! 329: ! 330: if( p->tn.op != COMOP ) cerror( "rcomma" ); ! 331: ! 332: if( p->in.left && p->in.right ) return( p ); ! 333: p->tn.op = FREE; ! 334: if( !p->in.left ) return( p->in.right ); ! 335: return( p->in.left ); ! 336: } ! 337: ! 338: NODE * ! 339: seq( p1, p2 ) ! 340: register NODE *p1, *p2; ! 341: { ! 342: /* execute p then q */ ! 343: register NODE *q; ! 344: ! 345: q = talloc(); ! 346: if (!p1) return p2; ! 347: if (!p2) return p1; ! 348: q->in.op = COMOP; ! 349: /*q->in.type = p2->in.right->in.type; why? */ ! 350: q->in.type = p2->in.type; ! 351: q->in.left = p1; ! 352: q->in.right = p2; ! 353: return q; ! 354: } ! 355: ! 356: NODE * ! 357: gtb( p, l ) ! 358: register NODE *p; ! 359: register l; ! 360: { ! 361: register NODE *q; ! 362: /* replace p by a trivial branch to l */ ! 363: /* if l is -1, return NULL */ ! 364: q = condit( p, CEFF, -1, -1 ); ! 365: if( l<0 ) return( q ); ! 366: if( !q ) ! 367: { ! 368: q = talloc(); ! 369: q->tn.op = ICON; ! 370: q->tn.lval = 0; ! 371: q->tn.name = (char *) 0; ! 372: q->tn.type = TINT; ! 373: } ! 374: return( genbr( 0, l, q ) ); ! 375: } ! 376: ! 377: NODE * ! 378: condit( p, goal, t, f ) ! 379: register NODE *p; ! 380: register goal,t,f; ! 381: { ! 382: /* generate code for conditionals in terms of GENLAB and GENBR nodes */ ! 383: /* goal is either CEFF, NRGS, or CCC */ ! 384: /* also, delete stuff that never needs get done */ ! 385: /* if goal==CEFF, return of null means nothing to be done */ ! 386: ! 387: register o, lt, lf, l; ! 388: register NODE *q, *q1, *q2; ! 389: ! 390: o = p->tn.op; ! 391: ! 392: #ifndef NODBG ! 393: if( odebug >2 ) ! 394: { ! 395: printf( "condit( %d (%s), %s, %d, %d )\n", (int)(p-node), ! 396: opst[o], goal==CCC?"CCC":(goal==NRGS?"NRGS":"CEFF"), ! 397: t, f ); ! 398: } ! 399: #endif ! 400: if( o == CBRANCH ) ! 401: { ! 402: p->in.right->tn.op = p->tn.op = FREE; ! 403: l = p->in.right->tn.lval; ! 404: p = p->in.left; ! 405: if( fcond( p ) ) return( gtb(p,l) ); ! 406: if( tcond( p ) ) return( gtb(p,-1) ); ! 407: return( condit( p, CCC, -1, l ) ); ! 408: } ! 409: ! 410: /* a convenient place to diddle a few special ops */ ! 411: if( callop(o) ) ! 412: { ! 413: if( optype(o) == UTYPE ) p->stn.argsize = 0; ! 414: else p->stn.argsize = argsize(p->in.right); ! 415: if( goal==CEFF ) goal = NRGS; ! 416: /* flow on, so that we can handle if( f(...) )... */ ! 417: } ! 418: else if( goal==CEFF && (asgop(o) || o==STASG || o==INIT)) goal=NRGS; ! 419: ! 420: /* do a bit of optimization */ ! 421: ! 422: if( goal == NRGS ) ! 423: { ! 424: if( logop(o) ) ! 425: { ! 426: /* must make p into ( p ? 1 : 0 ), then recompile */ ! 427: q1 = talloc(); ! 428: q1->tn.op = ICON; ! 429: q1->tn.name = (char *) 0; ! 430: q1->tn.lval = 1; ! 431: q1->tn.type = p->tn.type; ! 432: q2 = talloc(); ! 433: *q2 = *q1; ! 434: q2->tn.lval = 0; ! 435: q = talloc(); ! 436: q->tn.op = COLON; ! 437: q->tn.type = p->tn.type; ! 438: q->in.left = q1; ! 439: q->in.right = q2; ! 440: q1 = talloc(); ! 441: q1->tn.op = o = QUEST; ! 442: q1->tn.type = p->tn.type; ! 443: q1->in.left = p; ! 444: q1->in.right = q; ! 445: p = q1; /* flow on, and compile */ ! 446: } ! 447: } ! 448: ! 449: if( goal != CCC ) ! 450: { ! 451: if( o == QUEST ) ! 452: { ! 453: /* rewrite ? : when goal not CCC */ ! 454: lf = getlab(); ! 455: l = getlab(); ! 456: p->tn.op = COMOP; ! 457: q = p->in.right; ! 458: q1 = condit( q->in.left, goal, -1, -1 ); ! 459: q->in.right = condit( q->in.right, goal, -1, -1 ); ! 460: if( tcond( p->in.left ) ) ! 461: { ! 462: q->tn.op = FREE; ! 463: tfree( q->in.right ); ! 464: p->in.right = q1; ! 465: p->in.left=condit( p->in.left, CEFF, -1, -1 ); ! 466: return( rcomma( p ) ); ! 467: } ! 468: if( fcond( p->in.left ) ) ! 469: { ! 470: q->tn.op = FREE; ! 471: tfree( q1 ); ! 472: p->in.right = q->in.right; ! 473: p->in.left=condit( p->in.left, CEFF, -1, -1 ); ! 474: return( rcomma( p ) ); ! 475: } ! 476: if( !q1 ) ! 477: { ! 478: if( !q->in.right ) ! 479: { ! 480: /* may still have work to do ! 481: ** if left side of ? has effect ! 482: */ ! 483: q1 = condit(p->in.left, goal, ! 484: -1, -1); ! 485: if (!q1) ! 486: { ! 487: tfree( p->in.left ); ! 488: } ! 489: p->tn.op = q->tn.op = FREE; ! 490: return( q1 ); ! 491: } ! 492: /* rhs done if condition is false */ ! 493: p->in.left = condit( p->in.left, CCC, l, -1 ); ! 494: p->in.right = dlabel( q->in.right, l ); ! 495: q->tn.op = FREE; ! 496: return( p ); ! 497: } ! 498: else if( !q->in.right ) ! 499: { ! 500: /* lhs done if condition is true */ ! 501: p->in.left=condit( p->in.left, CCC, -1, lf ); ! 502: p->in.right = dlabel( q1, lf ); ! 503: q->tn.op = FREE; ! 504: return( p ); ! 505: } ! 506: ! 507: /* both sides exist and the condition is nontrivial */ ! 508: p->in.left = condit( p->in.left, CCC, -1, lf ); ! 509: q1 = force(q1); ! 510: q->in.right = force(q->in.right); ! 511: q1 = genbr( 0, l, q1 ); ! 512: q->in.left = dlabel( q1, lf ); ! 513: q->tn.op = COMOP; ! 514: return( dlabel( p, l ) ); ! 515: } ! 516: ! 517: if( goal == CEFF ) ! 518: { ! 519: /* some things may disappear */ ! 520: switch( o ) ! 521: { ! 522: ! 523: case CBRANCH: ! 524: case GENBR: ! 525: case GENUBR: ! 526: case CALL: ! 527: case UNARY CALL: ! 528: case FORTCALL: ! 529: case UNARY FORTCALL: ! 530: case STCALL: ! 531: case UNARY STCALL: ! 532: case STASG: ! 533: case INIT: ! 534: case MOD: /* do these for the side effects */ ! 535: case DIV: ! 536: case UOP0: ! 537: case UOP1: ! 538: case UOP2: ! 539: case UOP3: ! 540: case UOP4: ! 541: case UOP5: ! 542: case UOP6: ! 543: case UOP7: ! 544: case UOP8: ! 545: case UOP9: ! 546: #if defined(COMBINED) ! 547: case GENLAB: ! 548: #endif ! 549: goal = NRGS; ! 550: } ! 551: } ! 552: ! 553: /* The rhs of && and || ops are executed only if the ! 554: result is not clear from the lhs. If our goal is ! 555: CEFF, we don't need a result, but we need to ! 556: preserve that dependancy. So special case it. */ ! 557: if (goal==CEFF) { ! 558: if (o == ANDAND) return andeff(p); ! 559: if (o == OROR) return oreff(p); ! 560: } ! 561: /* This next batch of code wanders over the tree getting ! 562: rid of code which is for effect only and has no ! 563: effect */ ! 564: switch( optype(o) ) ! 565: { ! 566: case LTYPE: ! 567: if( goal == CEFF ) ! 568: { ! 569: p->tn.op = FREE; ! 570: return( NIL ); ! 571: } ! 572: break; ! 573: ! 574: case BITYPE: ! 575: p->in.right = condit( p->in.right, goal, -1, -1 ); ! 576: case UTYPE: ! 577: p->in.left = condit( p->in.left, o==COMOP?CEFF:goal, ! 578: -1, -1 ); ! 579: } ! 580: /* If we are only interested in effects, we quit here */ ! 581: if( goal == CEFF || o==COMOP ) ! 582: { ! 583: /* lhs or rhs may have disappeared */ ! 584: /* op need not get done */ ! 585: ! 586: switch( optype(o) ) ! 587: { ! 588: ! 589: case BITYPE: ! 590: p->tn.op = COMOP; ! 591: p = rcomma(p); ! 592: return ( p ); ! 593: ! 594: case UTYPE: ! 595: /* don't throw out prepass's labels */ ! 596: if(p->in.op == GENLAB) ! 597: return(p); ! 598: p->tn.op = FREE; ! 599: return( p->in.left ); ! 600: ! 601: case LTYPE: ! 602: p->tn.op = FREE; ! 603: return( NIL ); ! 604: } ! 605: } ! 606: return( p ); ! 607: } ! 608: ! 609: /* goal must = CCC from here on */ ! 610: ! 611: switch( o ) ! 612: { ! 613: ! 614: case ULE: ! 615: case ULT: ! 616: case UGE: ! 617: case UGT: ! 618: case EQ: ! 619: case NE: ! 620: case LE: ! 621: case LT: ! 622: case GE: ! 623: case GT: ! 624: if(t<0 ) ! 625: { ! 626: o = p->tn.op = negrel[o-EQ]; ! 627: t = f; ! 628: f = -1; ! 629: } ! 630: ! 631: #ifndef NOOPT ! 632: if( p->in.right->in.op == ICON && ! 633: p->in.right->tn.lval == 0 && ! 634: p->in.right->in.name == (char *) 0 ) ! 635: { ! 636: /* if chars are unsigned, do these optimizations ! 637: as if this is an unsigned compare*/ ! 638: #ifndef CHSIGN ! 639: if ( ! 640: ( p->in.left->tn.type == TCHAR || ! 641: ( p->in.left->in.op == CONV && ! 642: p->in.left->in.left->tn.type == TCHAR ) ) ! 643: && o >= LE && o <= GT) ! 644: o += UGT - GT; ! 645: #endif ! 646: ! 647: /* the question here is whether we can assume that */ ! 648: /* unconditional branches preserve condition codes */ ! 649: /* if this turned out to be no, we would have to */ ! 650: /* explicitly handle this case here */ ! 651: ! 652: switch( o ) ! 653: { ! 654: ! 655: case UGT: ! 656: case ULE: ! 657: o = p->in.op = (o==UGT)?NE:EQ; ! 658: case EQ: ! 659: case NE: ! 660: case LE: ! 661: case LT: ! 662: case GE: ! 663: case GT: ! 664: if( logop( p->in.left->tn.op ) ) ! 665: { ! 666: /* situation like (a==0)==0 */ ! 667: /* ignore optimization */ ! 668: goto noopt; ! 669: } ! 670: break; ! 671: ! 672: case ULT: /* never succeeds */ ! 673: return( gtb( p, f ) ); ! 674: ! 675: case UGE: ! 676: /* always succeeds */ ! 677: return( gtb( p, t ) ); ! 678: } ! 679: p->tn.op = p->in.right->tn.op = FREE; ! 680: p = condit( p->in.left, NRGS, -1, -1 ); ! 681: p = genbr( o, t, p ); ! 682: if( f<0 ) return( p ); ! 683: else return( genbr( 0, f, p ) ); ! 684: } ! 685: noopt: ! 686: # endif ! 687: ! 688: p->in.left = condit( p->in.left, NRGS, -1, -1 ); ! 689: p->in.right = condit( p->in.right, NRGS, -1, -1 ); ! 690: p = genbr( o, t, p ); ! 691: if( f>=0 ) p = genbr( 0, f, p ); ! 692: return( p ); ! 693: ! 694: case COMOP: ! 695: p->in.left = condit( p->in.left, CEFF, -1, -1 ); ! 696: p->in.right = condit( p->in.right, CCC, t, f ); ! 697: return( rcomma( p ) ); ! 698: ! 699: case NOT: ! 700: p->tn.op = FREE; ! 701: return( condit( p->in.left, CCC, f, t ) ); ! 702: ! 703: case ANDAND: ! 704: lf = f<0 ? getlab() : f; ! 705: lt = t<0 ? getlab() : t; ! 706: p->tn.op = COMOP; ! 707: if( tcond( p->in.left ) ) ! 708: { ! 709: /* left is always true */ ! 710: p->in.left = condit( p->in.left, CEFF, -1, -1 ); ! 711: p->in.right = condit( p->in.right, CCC, t, f ); ! 712: } ! 713: else { ! 714: /* lhs not always true */ ! 715: if( tcond( p->in.right ) ) ! 716: { ! 717: /* rhs is always true */ ! 718: p->in.right = ! 719: condit( p->in.right, CEFF, -1, -1 ); ! 720: if (p->in.right) { ! 721: /* const with sideeffect */ ! 722: p->in.left = ! 723: condit( p->in.left, CCC, -1,lf); ! 724: p->in.right = condit( p->in.right, ! 725: CCC, t, t ); ! 726: } else ! 727: p->in.left = ! 728: condit( p->in.left, CCC, t, f ); ! 729: } else { ! 730: p->in.left = ! 731: condit( p->in.left, CCC, -1, lf ); ! 732: p->in.right = ! 733: condit( p->in.right, CCC, t, f ); ! 734: } ! 735: } ! 736: q = rcomma( p ); ! 737: if( f<0 ) q = dlabel( q, lf ); ! 738: if( t<0 ) q = dlabel( q, lt ); ! 739: return( q ); ! 740: ! 741: case OROR: ! 742: lf = f<0 ? getlab() : f; ! 743: lt = t<0 ? getlab() : t; ! 744: p->tn.op = COMOP; ! 745: if( fcond( p->in.left ) ) ! 746: { ! 747: /* left is always false */ ! 748: p->in.left = condit( p->in.left, CEFF, -1, -1 ); ! 749: p->in.right = condit( p->in.right, CCC, t, f ); ! 750: } ! 751: else { ! 752: /* left is not always false */ ! 753: if( fcond( p->in.right ) ) ! 754: { ! 755: /* right always false */ ! 756: p->in.right = ! 757: condit( p->in.right, CEFF, -1, -1 ); ! 758: if (p->in.right) { ! 759: /* const with sideeffect */ ! 760: p->in.left = ! 761: condit( p->in.left, CCC, lt,-1); ! 762: /* This may generate a superfluous ! 763: test. Tough. */ ! 764: p->in.right = condit( p->in.right, ! 765: CCC, f, f ); ! 766: } else ! 767: p->in.left = ! 768: condit( p->in.left, CCC, t, f ); ! 769: } else { ! 770: p->in.left = ! 771: condit( p->in.left, CCC, lt, -1 ); ! 772: p->in.right = ! 773: condit( p->in.right, CCC, t, f ); ! 774: } ! 775: } ! 776: p = rcomma( p ); ! 777: if( f<0 ) p = dlabel( p, lf ); ! 778: if( t<0 ) p = dlabel( p, lt ); ! 779: return( p ); ! 780: ! 781: case QUEST: ! 782: lf = f<0 ? getlab() : f; ! 783: lt = t<0 ? getlab() : t; ! 784: p->in.left = condit( p->in.left, CCC, -1, l=getlab() ); ! 785: q = p->in.right; ! 786: q1 = condit( q->in.left, goal, lt, lf ); ! 787: q->in.left = dlabel( q1, l ); ! 788: q->in.right = condit( q->in.right, goal, t, f ); ! 789: p->tn.op = COMOP; ! 790: q->tn.op = COMOP; ! 791: if( t<0 ) p = dlabel( p, lt ); ! 792: if( f<0 ) p = dlabel( p, lf ); ! 793: return( p ); ! 794: ! 795: default: ! 796: /* get the condition codes, generate the branch */ ! 797: switch( optype(o) ) ! 798: { ! 799: case BITYPE: ! 800: p->in.right = condit( p->in.right, NRGS, -1, -1 ); ! 801: case UTYPE: ! 802: p->in.left = condit( p->in.left, NRGS, -1, -1 ); ! 803: } ! 804: if( t>=0 ) p = genbr( NE, t, p ); ! 805: if( f>=0 ) p = genbr( (t>=0)?0:EQ, f, p ); ! 806: return( p ); ! 807: } ! 808: } ! 809: ! 810: # ifndef TWOPASS ! 811: ! 812: p2compile( p ) ! 813: register NODE *p; ! 814: { ! 815: if( lflag ) lineid(p->ln.lineno ? p->ln.lineno : lineno, ftitle ); ! 816: tmpoff = 0; /* expression at top level reuses temps */ ! 817: /* generate code for the tree p */ ! 818: ! 819: # ifdef MYREADER ! 820: MYREADER(p); /* do your own laundering of the input */ ! 821: # endif ! 822: /* eliminate the conditionals */ ! 823: # ifndef NODBG ! 824: if( p && odebug>2 ) e2print(p); ! 825: # endif ! 826: /*p = prepass(p);*/ ! 827: if(p) ! 828: p = condit( p, CEFF, -1, -1 ); ! 829: if( p ) ! 830: { ! 831: /* expression does something */ ! 832: /* generate the code */ ! 833: # ifndef NODBG ! 834: if( odebug>2 ) e2print(p); ! 835: # endif ! 836: pjwreader(p); ! 837: pjwend(p); ! 838: } ! 839: # ifndef NODBG ! 840: else if( odebug>1 ) printf( "null effect\n" ); ! 841: # endif ! 842: allchk(); ! 843: /* tcheck will be done by the first pass at the end of a ftn. */ ! 844: /* first pass will do it... */ ! 845: } ! 846: ! 847: p2bbeg( aoff, myreg ) ! 848: register aoff,myreg; ! 849: { ! 850: static int myftn = -1; ! 851: SETOFF( aoff, ALSTACK ); ! 852: if( myftn != ftnno ) ! 853: { ! 854: /* beginning of function */ ! 855: maxboff = aoff; ! 856: myftn = ftnno; ! 857: maxtemp = 0; ! 858: maxarg = 0; ! 859: } ! 860: else ! 861: { ! 862: if( aoff > maxboff ) maxboff = aoff; ! 863: } ! 864: # ifdef SETREGS ! 865: SETREGS(myreg); ! 866: # endif ! 867: } ! 868: ! 869: p2bend() ! 870: { ! 871: SETOFF( maxboff, ALSTACK ); ! 872: SETOFF( maxarg, ALSTACK ); ! 873: SETOFF( maxtemp, ALSTACK ); ! 874: eobl2(); ! 875: maxboff = maxarg = maxtemp = 0; ! 876: } ! 877: ! 878: # endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.