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