|
|
1.1 ! root 1: /* INTERMEDIATE CODE GENERATION FOR S. C. JOHNSON C COMPILERS */ ! 2: /* NEW VERSION USING BINARY POLISH POSTFIX INTERMEDIATE */ ! 3: #if FAMILY != PCC ! 4: WRONG put FILE !!!! ! 5: #endif ! 6: ! 7: #include "defs.h" ! 8: #include "pccdefs.h" ! 9: Addrp putcall(), putcxeq(), putcx1(), realpart(); ! 10: expptr imagpart(); ! 11: ftnint lencat(); ! 12: ! 13: #define FOUR 4 ! 14: extern int ops2[]; ! 15: extern int types2[]; ! 16: ! 17: #define P2BUFFMAX 128 ! 18: static long int p2buff[P2BUFFMAX]; ! 19: static long int *p2bufp = &p2buff[0]; ! 20: static long int *p2bufend = &p2buff[P2BUFFMAX]; ! 21: ! 22: ! 23: puthead(s, class) ! 24: char *s; ! 25: int class; ! 26: { ! 27: char buff[100]; ! 28: #if TARGET == VAX ! 29: if(s) ! 30: p2ps("\t.globl\t_%s", s); ! 31: #endif ! 32: /* put out fake copy of left bracket line, to be redone later */ ! 33: if( ! headerdone ) ! 34: { ! 35: #if FAMILY == PCC ! 36: p2flush(); ! 37: #endif ! 38: headoffset = ftell(textfile); ! 39: prhead(textfile); ! 40: headerdone = YES; ! 41: p2triple(P2STMT, (strlen(infname)+FOUR-1)/FOUR, 0); ! 42: p2str(infname); ! 43: #if TARGET == PDP11 ! 44: /* fake jump to start the optimizer */ ! 45: if(class != CLBLOCK) ! 46: putgoto( fudgelabel = newlabel() ); ! 47: #endif ! 48: ! 49: #if TARGET == VAX ! 50: /* jump from top to bottom */ ! 51: if(s!=CNULL && class!=CLBLOCK) ! 52: { ! 53: int proflab = newlabel(); ! 54: p2ps("_%s:", s); ! 55: p2pi("\t.word\tLWM%d", procno); ! 56: prsave(proflab); ! 57: p2pi("\tjmp\tL%d", fudgelabel = newlabel()); ! 58: } ! 59: #endif ! 60: } ! 61: } ! 62: ! 63: ! 64: ! 65: ! 66: ! 67: /* It is necessary to precede each procedure with a "left bracket" ! 68: * line that tells pass 2 how many register variables and how ! 69: * much automatic space is required for the function. This compiler ! 70: * does not know how much automatic space is needed until the ! 71: * entire procedure has been processed. Therefore, "puthead" ! 72: * is called at the begining to record the current location in textfile, ! 73: * then to put out a placeholder left bracket line. This procedure ! 74: * repositions the file and rewrites that line, then puts the ! 75: * file pointer back to the end of the file. ! 76: */ ! 77: ! 78: putbracket() ! 79: { ! 80: long int hereoffset; ! 81: ! 82: #if FAMILY == PCC ! 83: p2flush(); ! 84: #endif ! 85: hereoffset = ftell(textfile); ! 86: if(fseek(textfile, headoffset, 0)) ! 87: fatal("fseek failed"); ! 88: prhead(textfile); ! 89: if(fseek(textfile, hereoffset, 0)) ! 90: fatal("fseek failed 2"); ! 91: } ! 92: ! 93: ! 94: ! 95: ! 96: putrbrack(k) ! 97: int k; ! 98: { ! 99: p2op(P2RBRACKET, k); ! 100: } ! 101: ! 102: ! 103: ! 104: putnreg() ! 105: { ! 106: } ! 107: ! 108: ! 109: ! 110: ! 111: ! 112: ! 113: puteof() ! 114: { ! 115: p2op(P2EOF, 0); ! 116: p2flush(); ! 117: } ! 118: ! 119: ! 120: ! 121: putstmt() ! 122: { ! 123: p2triple(P2STMT, 0, lineno); ! 124: } ! 125: ! 126: ! 127: ! 128: ! 129: /* put out code for if( ! p) goto l */ ! 130: putif(p,l) ! 131: register expptr p; ! 132: int l; ! 133: { ! 134: register int k; ! 135: ! 136: if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL) ! 137: { ! 138: if(k != TYERROR) ! 139: err("non-logical expression in IF statement"); ! 140: frexpr(p); ! 141: } ! 142: else ! 143: { ! 144: putex1(p); ! 145: p2icon( (long int) l , P2INT); ! 146: p2op(P2CBRANCH, 0); ! 147: putstmt(); ! 148: } ! 149: } ! 150: ! 151: ! 152: ! 153: ! 154: ! 155: /* put out code for goto l */ ! 156: putgoto(label) ! 157: int label; ! 158: { ! 159: p2triple(P2GOTO, 1, label); ! 160: putstmt(); ! 161: } ! 162: ! 163: ! 164: /* branch to address constant or integer variable */ ! 165: putbranch(p) ! 166: register Addrp p; ! 167: { ! 168: #if TARGET == VAX ! 169: if (p->vstg == STGARG) ! 170: { ! 171: putx(p); ! 172: p2op(P2FORCE, P2LONG); ! 173: putstmt(); ! 174: p2pass("\tjmp\t*r0"); ! 175: return; ! 176: } ! 177: #endif ! 178: putex1(p); ! 179: p2op(P2GOTO, P2INT); ! 180: putstmt(); ! 181: } ! 182: ! 183: ! 184: ! 185: /* put out label l: */ ! 186: putlabel(label) ! 187: int label; ! 188: { ! 189: p2op(P2LABEL, label); ! 190: } ! 191: ! 192: ! 193: ! 194: ! 195: putexpr(p) ! 196: expptr p; ! 197: { ! 198: putex1(p); ! 199: putstmt(); ! 200: } ! 201: ! 202: ! 203: ! 204: ! 205: putcmgo(index, nlab, labs) ! 206: expptr index; ! 207: int nlab; ! 208: struct Labelblock *labs[]; ! 209: { ! 210: int i, labarray, skiplabel; ! 211: ! 212: if(! ISINT(index->headblock.vtype) ) ! 213: { ! 214: execerr("computed goto index must be integer", CNULL); ! 215: return; ! 216: } ! 217: ! 218: #if TARGET == VAX ! 219: /* use special case instruction */ ! 220: vaxgoto(index, nlab, labs); ! 221: #else ! 222: labarray = newlabel(); ! 223: preven(ALIADDR); ! 224: prlabel(asmfile, labarray); ! 225: prcona(asmfile, (ftnint) (skiplabel = newlabel()) ); ! 226: for(i = 0 ; i < nlab ; ++i) ! 227: if( labs[i] ) ! 228: prcona(asmfile, (ftnint)(labs[i]->labelno) ); ! 229: prcmgoto(index, nlab, skiplabel, labarray); ! 230: putlabel(skiplabel); ! 231: #endif ! 232: } ! 233: ! 234: putx(p) ! 235: expptr p; ! 236: { ! 237: char *memname(); ! 238: int opc; ! 239: int ncomma; ! 240: int type, k; ! 241: ! 242: if (!p) ! 243: return; ! 244: ! 245: switch(p->tag) ! 246: { ! 247: case TERROR: ! 248: free( (charptr) p ); ! 249: break; ! 250: ! 251: case TCONST: ! 252: switch(type = p->constblock.vtype) ! 253: { ! 254: case TYLOGICAL: ! 255: type = tyint; ! 256: case TYLONG: ! 257: case TYSHORT: ! 258: p2icon(p->constblock.const.ci, types2[type]); ! 259: free( (charptr) p ); ! 260: break; ! 261: ! 262: case TYADDR: ! 263: p2triple(P2ICON, 1, P2INT|P2PTR); ! 264: p2word(0L); ! 265: p2name(memname(STGCONST, ! 266: (int) p->constblock.const.ci) ); ! 267: free( (charptr) p ); ! 268: break; ! 269: ! 270: default: ! 271: putx( putconst(p) ); ! 272: break; ! 273: } ! 274: break; ! 275: ! 276: case TEXPR: ! 277: switch(opc = p->exprblock.opcode) ! 278: { ! 279: case OPCALL: ! 280: case OPCCALL: ! 281: if( ISCOMPLEX(p->exprblock.vtype) ) ! 282: putcxop(p); ! 283: else putcall(p); ! 284: break; ! 285: ! 286: case OPMIN: ! 287: case OPMAX: ! 288: putmnmx(p); ! 289: break; ! 290: ! 291: ! 292: case OPASSIGN: ! 293: if(ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ! 294: || ISCOMPLEX(p->exprblock.rightp->headblock.vtype) ) ! 295: frexpr( putcxeq(p) ); ! 296: else if( ISCHAR(p) ) ! 297: putcheq(p); ! 298: else ! 299: goto putopp; ! 300: break; ! 301: ! 302: case OPEQ: ! 303: case OPNE: ! 304: if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) || ! 305: ISCOMPLEX(p->exprblock.rightp->headblock.vtype) ) ! 306: { ! 307: putcxcmp(p); ! 308: break; ! 309: } ! 310: case OPLT: ! 311: case OPLE: ! 312: case OPGT: ! 313: case OPGE: ! 314: if(ISCHAR(p->exprblock.leftp)) ! 315: { ! 316: putchcmp(p); ! 317: break; ! 318: } ! 319: goto putopp; ! 320: ! 321: case OPPOWER: ! 322: putpower(p); ! 323: break; ! 324: ! 325: case OPSTAR: ! 326: #if FAMILY == PCC ! 327: /* m * (2**k) -> m<<k */ ! 328: if(INT(p->exprblock.leftp->headblock.vtype) && ! 329: ISICON(p->exprblock.rightp) && ! 330: ( (k = log2(p->exprblock.rightp->constblock.const.ci))>0) ) ! 331: { ! 332: p->exprblock.opcode = OPLSHIFT; ! 333: frexpr(p->exprblock.rightp); ! 334: p->exprblock.rightp = ICON(k); ! 335: goto putopp; ! 336: } ! 337: #endif ! 338: ! 339: case OPMOD: ! 340: goto putopp; ! 341: case OPPLUS: ! 342: case OPMINUS: ! 343: case OPSLASH: ! 344: case OPNEG: ! 345: if( ISCOMPLEX(p->exprblock.vtype) ) ! 346: putcxop(p); ! 347: else goto putopp; ! 348: break; ! 349: ! 350: case OPCONV: ! 351: if( ISCOMPLEX(p->exprblock.vtype) ) ! 352: putcxop(p); ! 353: else if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ) ! 354: { ! 355: ncomma = 0; ! 356: putx( mkconv(p->exprblock.vtype, ! 357: realpart(putcx1(p->exprblock.leftp, ! 358: &ncomma)))); ! 359: putcomma(ncomma, p->exprblock.vtype, NO); ! 360: free( (charptr) p ); ! 361: } ! 362: else goto putopp; ! 363: break; ! 364: ! 365: case OPNOT: ! 366: case OPOR: ! 367: case OPAND: ! 368: case OPEQV: ! 369: case OPNEQV: ! 370: case OPADDR: ! 371: case OPPLUSEQ: ! 372: case OPSTAREQ: ! 373: case OPCOMMA: ! 374: case OPQUEST: ! 375: case OPCOLON: ! 376: case OPBITOR: ! 377: case OPBITAND: ! 378: case OPBITXOR: ! 379: case OPBITNOT: ! 380: case OPLSHIFT: ! 381: case OPRSHIFT: ! 382: putopp: ! 383: putop(p); ! 384: break; ! 385: ! 386: case OPPAREN: ! 387: putx (p->exprblock.leftp); ! 388: break; ! 389: default: ! 390: badop("putx", opc); ! 391: } ! 392: break; ! 393: ! 394: case TADDR: ! 395: putaddr(p, YES); ! 396: break; ! 397: ! 398: default: ! 399: badtag("putx", p->tag); ! 400: } ! 401: } ! 402: ! 403: ! 404: ! 405: LOCAL putop(p) ! 406: expptr p; ! 407: { ! 408: int k; ! 409: expptr lp, tp; ! 410: int pt, lt; ! 411: int comma; ! 412: ! 413: switch(p->exprblock.opcode) /* check for special cases and rewrite */ ! 414: { ! 415: case OPCONV: ! 416: pt = p->exprblock.vtype; ! 417: lp = p->exprblock.leftp; ! 418: lt = lp->headblock.vtype; ! 419: if (pt == TYREAL && lt == TYDREAL) ! 420: { ! 421: putx(lp); ! 422: p2op(P2CONV, P2REAL); ! 423: return; ! 424: } ! 425: while(p->tag==TEXPR && p->exprblock.opcode==OPCONV && ! 426: ( (ISREAL(pt)&&ISREAL(lt)) || ! 427: (INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) )) ! 428: { ! 429: #if SZINT < SZLONG ! 430: if(lp->tag != TEXPR) ! 431: { ! 432: if(pt==TYINT && lt==TYLONG) ! 433: break; ! 434: if(lt==TYINT && pt==TYLONG) ! 435: break; ! 436: } ! 437: #endif ! 438: ! 439: #if TARGET == VAX ! 440: if(pt==TYDREAL && lt==TYREAL) ! 441: { ! 442: if(lp->tag==TEXPR && ! 443: lp->exprblock.opcode==OPCONV && ! 444: lp->exprblock.leftp->headblock.vtype==TYDREAL) ! 445: { ! 446: putx(lp->exprblock.leftp); ! 447: p2op(P2CONV, P2REAL); ! 448: p2op(P2CONV, P2DREAL); ! 449: free( (charptr) p ); ! 450: return; ! 451: } ! 452: else break; ! 453: } ! 454: #endif ! 455: if(lt==TYCHAR && lp->tag==TEXPR && ! 456: lp->exprblock.opcode==OPCALL) ! 457: { ! 458: p->exprblock.leftp = (expptr) putcall(lp); ! 459: putop(p); ! 460: putcomma(1, pt, NO); ! 461: free( (charptr) p ); ! 462: return; ! 463: } ! 464: free( (charptr) p ); ! 465: p = lp; ! 466: pt = lt; ! 467: lp = p->exprblock.leftp; ! 468: lt = lp->headblock.vtype; ! 469: } ! 470: if(p->tag==TEXPR && p->exprblock.opcode==OPCONV) ! 471: break; ! 472: putx(p); ! 473: if (types2[pt] != types2[lt]) ! 474: p2op(P2CONV,types2[pt]); ! 475: return; ! 476: ! 477: case OPADDR: ! 478: comma = NO; ! 479: lp = p->exprblock.leftp; ! 480: if(lp->tag != TADDR) ! 481: { ! 482: tp = (expptr) mkaltemp ! 483: (lp->headblock.vtype,lp->headblock.vleng); ! 484: putx( mkexpr(OPASSIGN, cpexpr(tp), lp) ); ! 485: lp = tp; ! 486: comma = YES; ! 487: } ! 488: putaddr(lp, NO); ! 489: if(comma) ! 490: putcomma(1, TYINT, NO); ! 491: free( (charptr) p ); ! 492: return; ! 493: #if TARGET == VAX ! 494: /* take advantage of a glitch in the code generator that does not check ! 495: the type clash in an assignment or comparison of an integer zero and ! 496: a floating left operand, and generates optimal code for the correct ! 497: type. (The PCC has no floating-constant node to encode this correctly.) ! 498: */ ! 499: case OPASSIGN: ! 500: case OPLT: ! 501: case OPLE: ! 502: case OPGT: ! 503: case OPGE: ! 504: case OPEQ: ! 505: case OPNE: ! 506: if(ISREAL(p->exprblock.leftp->headblock.vtype) && ! 507: ISREAL(p->exprblock.rightp->headblock.vtype) && ! 508: ISCONST(p->exprblock.rightp) && ! 509: p->exprblock.rightp->constblock.const.cd[0]==0) ! 510: { ! 511: p->exprblock.rightp->constblock.vtype = TYINT; ! 512: p->exprblock.rightp->constblock.const.ci = 0; ! 513: } ! 514: #endif ! 515: } ! 516: ! 517: if( (k = ops2[p->exprblock.opcode]) <= 0) ! 518: badop("putop", p->exprblock.opcode); ! 519: putx(p->exprblock.leftp); ! 520: if(p->exprblock.rightp) ! 521: putx(p->exprblock.rightp); ! 522: p2op(k, types2[p->exprblock.vtype]); ! 523: ! 524: if(p->exprblock.vleng) ! 525: frexpr(p->exprblock.vleng); ! 526: free( (charptr) p ); ! 527: } ! 528: ! 529: putforce(t, p) ! 530: int t; ! 531: expptr p; ! 532: { ! 533: p = mkconv(t, fixtype(p)); ! 534: putx(p); ! 535: p2op(P2FORCE, ! 536: (t==TYSHORT ? P2SHORT : (t==TYLONG ? P2LONG : P2DREAL)) ); ! 537: putstmt(); ! 538: } ! 539: ! 540: ! 541: ! 542: LOCAL putpower(p) ! 543: expptr p; ! 544: { ! 545: expptr base; ! 546: Addrp t1, t2; ! 547: ftnint k; ! 548: int type; ! 549: int ncomma; ! 550: ! 551: if(!ISICON(p->exprblock.rightp) || ! 552: (k = p->exprblock.rightp->constblock.const.ci)<2) ! 553: fatal("putpower: bad call"); ! 554: base = p->exprblock.leftp; ! 555: type = base->headblock.vtype; ! 556: ! 557: if ((k == 2) && base->tag == TADDR && ISCONST(base->addrblock.memoffset)) ! 558: { ! 559: putx( mkexpr(OPSTAR,cpexpr(base),cpexpr(base))); ! 560: ! 561: return; ! 562: } ! 563: t1 = mkaltemp(type, PNULL); ! 564: t2 = NULL; ! 565: ncomma = 1; ! 566: putassign(cpexpr(t1), cpexpr(base) ); ! 567: ! 568: for( ; (k&1)==0 && k>2 ; k>>=1 ) ! 569: { ! 570: ++ncomma; ! 571: putsteq(t1, t1); ! 572: } ! 573: ! 574: if(k == 2) ! 575: putx( mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) ); ! 576: else ! 577: { ! 578: t2 = mkaltemp(type, PNULL); ! 579: ++ncomma; ! 580: putassign(cpexpr(t2), cpexpr(t1)); ! 581: ! 582: for(k>>=1 ; k>1 ; k>>=1) ! 583: { ! 584: ++ncomma; ! 585: putsteq(t1, t1); ! 586: if(k & 1) ! 587: { ! 588: ++ncomma; ! 589: putsteq(t2, t1); ! 590: } ! 591: } ! 592: putx( mkexpr(OPSTAR, cpexpr(t2), ! 593: mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) )); ! 594: } ! 595: putcomma(ncomma, type, NO); ! 596: frexpr(t1); ! 597: if(t2) ! 598: frexpr(t2); ! 599: frexpr(p); ! 600: } ! 601: ! 602: ! 603: ! 604: ! 605: LOCAL Addrp intdouble(p, ncommap) ! 606: Addrp p; ! 607: int *ncommap; ! 608: { ! 609: register Addrp t; ! 610: ! 611: t = mkaltemp(TYDREAL, PNULL); ! 612: ++*ncommap; ! 613: putassign(cpexpr(t), p); ! 614: return(t); ! 615: } ! 616: ! 617: ! 618: ! 619: ! 620: ! 621: LOCAL Addrp putcxeq(p) ! 622: register expptr p; ! 623: { ! 624: register Addrp lp, rp; ! 625: int ncomma; ! 626: ! 627: if(p->tag != TEXPR) ! 628: badtag("putcxeq", p->tag); ! 629: ! 630: ncomma = 0; ! 631: lp = putcx1(p->exprblock.leftp, &ncomma); ! 632: rp = putcx1(p->exprblock.rightp, &ncomma); ! 633: putassign(realpart(lp), realpart(rp)); ! 634: if( ISCOMPLEX(p->exprblock.vtype) ) ! 635: { ! 636: ++ncomma; ! 637: putassign(imagpart(lp), imagpart(rp)); ! 638: } ! 639: putcomma(ncomma, TYREAL, NO); ! 640: frexpr(rp); ! 641: free( (charptr) p ); ! 642: return(lp); ! 643: } ! 644: ! 645: ! 646: ! 647: LOCAL putcxop(p) ! 648: expptr p; ! 649: { ! 650: Addrp putcx1(); ! 651: int ncomma; ! 652: ! 653: ncomma = 0; ! 654: putaddr( putcx1(p, &ncomma), NO); ! 655: putcomma(ncomma, TYINT, NO); ! 656: } ! 657: ! 658: ! 659: ! 660: LOCAL Addrp putcx1(p, ncommap) ! 661: register expptr p; ! 662: int *ncommap; ! 663: { ! 664: expptr q; ! 665: Addrp lp, rp; ! 666: register Addrp resp; ! 667: int opcode; ! 668: int ltype, rtype; ! 669: expptr mkrealcon(); ! 670: ! 671: if(p == NULL) ! 672: return(NULL); ! 673: ! 674: switch(p->tag) ! 675: { ! 676: case TCONST: ! 677: if( ISCOMPLEX(p->constblock.vtype) ) ! 678: p = (expptr) putconst(p); ! 679: return( (Addrp) p ); ! 680: ! 681: case TADDR: ! 682: if( ! addressable(p) ) ! 683: { ! 684: ++*ncommap; ! 685: resp = mkaltemp(tyint, PNULL); ! 686: putassign( cpexpr(resp), p->addrblock.memoffset ); ! 687: p->addrblock.memoffset = (expptr)resp; ! 688: } ! 689: return( (Addrp) p ); ! 690: ! 691: case TEXPR: ! 692: if( ISCOMPLEX(p->exprblock.vtype) ) ! 693: break; ! 694: ++*ncommap; ! 695: resp = mkaltemp(TYDREAL, NO); ! 696: putassign( cpexpr(resp), p); ! 697: return(resp); ! 698: ! 699: default: ! 700: badtag("putcx1", p->tag); ! 701: } ! 702: ! 703: opcode = p->exprblock.opcode; ! 704: if(opcode==OPCALL || opcode==OPCCALL) ! 705: { ! 706: ++*ncommap; ! 707: return( putcall(p) ); ! 708: } ! 709: else if(opcode == OPASSIGN) ! 710: { ! 711: ++*ncommap; ! 712: return( putcxeq(p) ); ! 713: } ! 714: resp = mkaltemp(p->exprblock.vtype, PNULL); ! 715: if(lp = putcx1(p->exprblock.leftp, ncommap) ) ! 716: ltype = lp->vtype; ! 717: if(rp = putcx1(p->exprblock.rightp, ncommap) ) ! 718: rtype = rp->vtype; ! 719: ! 720: switch(opcode) ! 721: { ! 722: case OPPAREN: ! 723: frexpr (resp); ! 724: resp = lp; ! 725: lp = NULL; ! 726: break; ! 727: ! 728: case OPCOMMA: ! 729: frexpr(resp); ! 730: resp = rp; ! 731: rp = NULL; ! 732: break; ! 733: ! 734: case OPNEG: ! 735: putassign( realpart(resp), mkexpr(OPNEG, realpart(lp), ENULL) ); ! 736: putassign( imagpart(resp), mkexpr(OPNEG, imagpart(lp), ENULL) ); ! 737: *ncommap += 2; ! 738: break; ! 739: ! 740: case OPPLUS: ! 741: case OPMINUS: ! 742: putassign( realpart(resp), ! 743: mkexpr(opcode, realpart(lp), realpart(rp) )); ! 744: if(rtype < TYCOMPLEX) ! 745: putassign( imagpart(resp), imagpart(lp) ); ! 746: else if(ltype < TYCOMPLEX) ! 747: { ! 748: if(opcode == OPPLUS) ! 749: putassign( imagpart(resp), imagpart(rp) ); ! 750: else putassign( imagpart(resp), ! 751: mkexpr(OPNEG, imagpart(rp), ENULL) ); ! 752: } ! 753: else ! 754: putassign( imagpart(resp), ! 755: mkexpr(opcode, imagpart(lp), imagpart(rp) )); ! 756: ! 757: *ncommap += 2; ! 758: break; ! 759: ! 760: case OPSTAR: ! 761: if(ltype < TYCOMPLEX) ! 762: { ! 763: if( ISINT(ltype) ) ! 764: lp = intdouble(lp, ncommap); ! 765: putassign( realpart(resp), ! 766: mkexpr(OPSTAR, cpexpr(lp), realpart(rp) )); ! 767: putassign( imagpart(resp), ! 768: mkexpr(OPSTAR, cpexpr(lp), imagpart(rp) )); ! 769: } ! 770: else if(rtype < TYCOMPLEX) ! 771: { ! 772: if( ISINT(rtype) ) ! 773: rp = intdouble(rp, ncommap); ! 774: putassign( realpart(resp), ! 775: mkexpr(OPSTAR, cpexpr(rp), realpart(lp) )); ! 776: putassign( imagpart(resp), ! 777: mkexpr(OPSTAR, cpexpr(rp), imagpart(lp) )); ! 778: } ! 779: else { ! 780: putassign( realpart(resp), mkexpr(OPMINUS, ! 781: mkexpr(OPSTAR, realpart(lp), realpart(rp)), ! 782: mkexpr(OPSTAR, imagpart(lp), imagpart(rp)) )); ! 783: putassign( imagpart(resp), mkexpr(OPPLUS, ! 784: mkexpr(OPSTAR, realpart(lp), imagpart(rp)), ! 785: mkexpr(OPSTAR, imagpart(lp), realpart(rp)) )); ! 786: } ! 787: *ncommap += 2; ! 788: break; ! 789: ! 790: case OPSLASH: ! 791: /* fixexpr has already replaced all divisions ! 792: * by a complex by a function call ! 793: */ ! 794: if( ISINT(rtype) ) ! 795: rp = intdouble(rp, ncommap); ! 796: putassign( realpart(resp), ! 797: mkexpr(OPSLASH, realpart(lp), cpexpr(rp)) ); ! 798: putassign( imagpart(resp), ! 799: mkexpr(OPSLASH, imagpart(lp), cpexpr(rp)) ); ! 800: *ncommap += 2; ! 801: break; ! 802: ! 803: case OPCONV: ! 804: putassign( realpart(resp), realpart(lp) ); ! 805: if( ISCOMPLEX(lp->vtype) ) ! 806: q = imagpart(lp); ! 807: else if(rp != NULL) ! 808: q = (expptr) realpart(rp); ! 809: else ! 810: q = mkrealcon(TYDREAL, 0.0); ! 811: putassign( imagpart(resp), q); ! 812: *ncommap += 2; ! 813: break; ! 814: ! 815: default: ! 816: badop("putcx1", opcode); ! 817: } ! 818: ! 819: frexpr(lp); ! 820: frexpr(rp); ! 821: free( (charptr) p ); ! 822: return(resp); ! 823: } ! 824: ! 825: ! 826: ! 827: ! 828: LOCAL putcxcmp(p) ! 829: register expptr p; ! 830: { ! 831: int opcode; ! 832: int ncomma; ! 833: register Addrp lp, rp; ! 834: expptr q; ! 835: ! 836: if(p->tag != TEXPR) ! 837: badtag("putcxcmp", p->tag); ! 838: ! 839: ncomma = 0; ! 840: opcode = p->exprblock.opcode; ! 841: lp = putcx1(p->exprblock.leftp, &ncomma); ! 842: rp = putcx1(p->exprblock.rightp, &ncomma); ! 843: ! 844: q = mkexpr( opcode==OPEQ ? OPAND : OPOR , ! 845: mkexpr(opcode, realpart(lp), realpart(rp)), ! 846: mkexpr(opcode, imagpart(lp), imagpart(rp)) ); ! 847: putx( fixexpr(q) ); ! 848: putcomma(ncomma, TYINT, NO); ! 849: ! 850: free( (charptr) lp); ! 851: free( (charptr) rp); ! 852: free( (charptr) p ); ! 853: } ! 854: ! 855: LOCAL Addrp putch1(p, ncommap) ! 856: register expptr p; ! 857: int * ncommap; ! 858: { ! 859: register Addrp t; ! 860: ! 861: switch(p->tag) ! 862: { ! 863: case TCONST: ! 864: return( putconst(p) ); ! 865: ! 866: case TADDR: ! 867: return( (Addrp) p ); ! 868: ! 869: case TEXPR: ! 870: ++*ncommap; ! 871: ! 872: switch(p->exprblock.opcode) ! 873: { ! 874: expptr q; ! 875: ! 876: case OPCALL: ! 877: case OPCCALL: ! 878: t = putcall(p); ! 879: break; ! 880: ! 881: case OPCONCAT: ! 882: t = mkaltemp(TYCHAR, ICON(lencat(p)) ); ! 883: q = (expptr) cpexpr(p->headblock.vleng); ! 884: putcat( cpexpr(t), p ); ! 885: /* put the correct length on the block */ ! 886: frexpr(t->vleng); ! 887: t->vleng = q; ! 888: ! 889: break; ! 890: ! 891: case OPCONV: ! 892: if(!ISICON(p->exprblock.vleng) ! 893: || p->exprblock.vleng->constblock.const.ci!=1 ! 894: || ! INT(p->exprblock.leftp->headblock.vtype) ) ! 895: fatal("putch1: bad character conversion"); ! 896: t = mkaltemp(TYCHAR, ICON(1) ); ! 897: putop( mkexpr(OPASSIGN, cpexpr(t), p) ); ! 898: break; ! 899: default: ! 900: badop("putch1", p->exprblock.opcode); ! 901: } ! 902: return(t); ! 903: ! 904: default: ! 905: badtag("putch1", p->tag); ! 906: } ! 907: /* NOTREACHED */ ! 908: } ! 909: ! 910: ! 911: ! 912: ! 913: LOCAL putchop(p) ! 914: expptr p; ! 915: { ! 916: int ncomma; ! 917: ! 918: ncomma = 0; ! 919: putaddr( putch1(p, &ncomma) , NO ); ! 920: putcomma(ncomma, TYCHAR, YES); ! 921: } ! 922: ! 923: ! 924: ! 925: ! 926: LOCAL putcheq(p) ! 927: register expptr p; ! 928: { ! 929: int ncomma; ! 930: expptr lp, rp; ! 931: ! 932: if(p->tag != TEXPR) ! 933: badtag("putcheq", p->tag); ! 934: ! 935: ncomma = 0; ! 936: lp = p->exprblock.leftp; ! 937: rp = p->exprblock.rightp; ! 938: if( rp->tag==TEXPR && rp->exprblock.opcode==OPCONCAT ) ! 939: putcat(lp, rp); ! 940: else if( ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) ) ! 941: { ! 942: putaddr( putch1(lp, &ncomma) , YES ); ! 943: putaddr( putch1(rp, &ncomma) , YES ); ! 944: putcomma(ncomma, TYINT, NO); ! 945: p2op(P2ASSIGN, P2CHAR); ! 946: } ! 947: else ! 948: { ! 949: putx( call2(TYINT, "s_copy", lp, rp) ); ! 950: putcomma(ncomma, TYINT, NO); ! 951: } ! 952: ! 953: frexpr(p->exprblock.vleng); ! 954: free( (charptr) p ); ! 955: } ! 956: ! 957: ! 958: ! 959: ! 960: LOCAL putchcmp(p) ! 961: register expptr p; ! 962: { ! 963: int ncomma; ! 964: expptr lp, rp; ! 965: ! 966: if(p->tag != TEXPR) ! 967: badtag("putchcmp", p->tag); ! 968: ! 969: ncomma = 0; ! 970: lp = p->exprblock.leftp; ! 971: rp = p->exprblock.rightp; ! 972: ! 973: if(ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) ) ! 974: { ! 975: putaddr( putch1(lp, &ncomma) , YES ); ! 976: putaddr( putch1(rp, &ncomma) , YES ); ! 977: p2op(ops2[p->exprblock.opcode], P2CHAR); ! 978: free( (charptr) p ); ! 979: putcomma(ncomma, TYINT, NO); ! 980: } ! 981: else ! 982: { ! 983: p->exprblock.leftp = call2(TYINT,"s_cmp", lp, rp); ! 984: p->exprblock.rightp = ICON(0); ! 985: putop(p); ! 986: } ! 987: } ! 988: ! 989: ! 990: ! 991: ! 992: ! 993: LOCAL putcat(lhs, rhs) ! 994: register Addrp lhs; ! 995: register expptr rhs; ! 996: { ! 997: int n, ncomma; ! 998: Addrp lp, cp; ! 999: ! 1000: ncomma = 0; ! 1001: n = ncat(rhs); ! 1002: lp = mkaltmpn(n, TYLENG, PNULL); ! 1003: cp = mkaltmpn(n, TYADDR, PNULL); ! 1004: ! 1005: n = 0; ! 1006: putct1(rhs, lp, cp, &n, &ncomma); ! 1007: ! 1008: putx( call4(TYSUBR, "s_cat", lhs, cp, lp, mkconv(TYLONG, ICON(n)) ) ); ! 1009: putcomma(ncomma, TYINT, NO); ! 1010: } ! 1011: ! 1012: ! 1013: ! 1014: ! 1015: ! 1016: LOCAL putct1(q, lp, cp, ip, ncommap) ! 1017: register expptr q; ! 1018: register Addrp lp, cp; ! 1019: int *ip, *ncommap; ! 1020: { ! 1021: int i; ! 1022: Addrp lp1, cp1; ! 1023: ! 1024: if(q->tag==TEXPR && q->exprblock.opcode==OPCONCAT) ! 1025: { ! 1026: putct1(q->exprblock.leftp, lp, cp, ip, ncommap); ! 1027: putct1(q->exprblock.rightp, lp, cp , ip, ncommap); ! 1028: frexpr(q->exprblock.vleng); ! 1029: free( (charptr) q ); ! 1030: } ! 1031: else ! 1032: { ! 1033: i = (*ip)++; ! 1034: lp1 = (Addrp) cpexpr(lp); ! 1035: lp1->memoffset = mkexpr(OPPLUS,lp1->memoffset, ICON(i*SZLENG)); ! 1036: cp1 = (Addrp) cpexpr(cp); ! 1037: cp1->memoffset = mkexpr(OPPLUS, cp1->memoffset, ICON(i*SZADDR)); ! 1038: putassign( lp1, cpexpr(q->headblock.vleng) ); ! 1039: putassign( cp1, addrof(putch1(q,ncommap)) ); ! 1040: *ncommap += 2; ! 1041: } ! 1042: } ! 1043: ! 1044: LOCAL putaddr(p, indir) ! 1045: register Addrp p; ! 1046: int indir; ! 1047: { ! 1048: int type, type2, funct; ! 1049: ftnint offset, simoffset(); ! 1050: expptr offp, shorten(); ! 1051: ! 1052: if( p->tag==TERROR || (p->memoffset!=NULL && ISERROR(p->memoffset)) ) ! 1053: { ! 1054: frexpr(p); ! 1055: return; ! 1056: } ! 1057: if (p->tag != TADDR) badtag ("putaddr",p->tag); ! 1058: ! 1059: type = p->vtype; ! 1060: type2 = types2[type]; ! 1061: funct = (p->vclass==CLPROC ? P2FUNCT<<2 : 0); ! 1062: ! 1063: offp = (p->memoffset ? (expptr) cpexpr(p->memoffset) : (expptr)NULL ); ! 1064: ! 1065: ! 1066: #if (FUDGEOFFSET != 1) ! 1067: if(offp) ! 1068: offp = mkexpr(OPSTAR, ICON(FUDGEOFFSET), offp); ! 1069: #endif ! 1070: ! 1071: offset = simoffset( &offp ); ! 1072: #if SZINT < SZLONG ! 1073: if(offp) ! 1074: if(shortsubs) ! 1075: offp = shorten(offp); ! 1076: else ! 1077: offp = mkconv(TYINT, offp); ! 1078: #else ! 1079: if(offp) ! 1080: offp = mkconv(TYINT, offp); ! 1081: #endif ! 1082: ! 1083: if (p->vclass == CLVAR ! 1084: && (p->vstg == STGBSS || p->vstg == STGEQUIV) ! 1085: && SMALLVAR(p->varsize) ! 1086: && offset >= -32768 && offset <= 32767) ! 1087: { ! 1088: anylocals = YES; ! 1089: if (indir && !offp) ! 1090: p2ldisp(offset, memname(p->vstg, p->memno), type2); ! 1091: else ! 1092: { ! 1093: p2reg(11, type2 | P2PTR); ! 1094: p2triple(P2ICON, 1, P2INT); ! 1095: p2word(offset); ! 1096: p2ndisp(memname(p->vstg, p->memno)); ! 1097: p2op(P2PLUS, type2 | P2PTR); ! 1098: if (offp) ! 1099: { ! 1100: putx(offp); ! 1101: p2op(P2PLUS, type2 | P2PTR); ! 1102: } ! 1103: if (indir) ! 1104: p2op(P2INDIRECT, type2); ! 1105: } ! 1106: frexpr((tagptr) p); ! 1107: return; ! 1108: } ! 1109: ! 1110: switch(p->vstg) ! 1111: { ! 1112: case STGAUTO: ! 1113: if(indir && !offp) ! 1114: { ! 1115: p2oreg(offset, AUTOREG, type2); ! 1116: break; ! 1117: } ! 1118: ! 1119: if(!indir && !offp && !offset) ! 1120: { ! 1121: p2reg(AUTOREG, type2 | P2PTR); ! 1122: break; ! 1123: } ! 1124: ! 1125: p2reg(AUTOREG, type2 | P2PTR); ! 1126: if(offp) ! 1127: { ! 1128: putx(offp); ! 1129: if(offset) ! 1130: p2icon(offset, P2INT); ! 1131: } ! 1132: else ! 1133: p2icon(offset, P2INT); ! 1134: if(offp && offset) ! 1135: p2op(P2PLUS, type2 | P2PTR); ! 1136: p2op(P2PLUS, type2 | P2PTR); ! 1137: if(indir) ! 1138: p2op(P2INDIRECT, type2); ! 1139: break; ! 1140: ! 1141: case STGARG: ! 1142: p2oreg( ! 1143: #ifdef ARGOFFSET ! 1144: ARGOFFSET + ! 1145: #endif ! 1146: (ftnint) (FUDGEOFFSET*p->memno), ! 1147: ARGREG, type2 | P2PTR | funct ); ! 1148: ! 1149: based: ! 1150: if(offset) ! 1151: { ! 1152: p2icon(offset, P2INT); ! 1153: p2op(P2PLUS, type2 | P2PTR); ! 1154: } ! 1155: if(offp) ! 1156: { ! 1157: putx(offp); ! 1158: p2op(P2PLUS, type2 | P2PTR); ! 1159: } ! 1160: if(indir) ! 1161: p2op(P2INDIRECT, type2); ! 1162: break; ! 1163: ! 1164: case STGLENG: ! 1165: if(indir) ! 1166: { ! 1167: p2oreg( ! 1168: #ifdef ARGOFFSET ! 1169: ARGOFFSET + ! 1170: #endif ! 1171: (ftnint) (FUDGEOFFSET*p->memno), ! 1172: ARGREG, type2 ); ! 1173: } ! 1174: else { ! 1175: p2reg(ARGREG, type2 | P2PTR ); ! 1176: p2icon( ! 1177: #ifdef ARGOFFSET ! 1178: ARGOFFSET + ! 1179: #endif ! 1180: (ftnint) (FUDGEOFFSET*p->memno), P2INT); ! 1181: p2op(P2PLUS, type2 | P2PTR ); ! 1182: } ! 1183: break; ! 1184: ! 1185: ! 1186: case STGBSS: ! 1187: case STGINIT: ! 1188: case STGEXT: ! 1189: case STGCOMMON: ! 1190: case STGEQUIV: ! 1191: case STGCONST: ! 1192: if(offp) ! 1193: { ! 1194: putx(offp); ! 1195: putmem(p, P2ICON, offset); ! 1196: p2op(P2PLUS, type2 | P2PTR); ! 1197: if(indir) ! 1198: p2op(P2INDIRECT, type2); ! 1199: } ! 1200: else ! 1201: putmem(p, (indir ? P2NAME : P2ICON), offset); ! 1202: ! 1203: break; ! 1204: ! 1205: case STGREG: ! 1206: if(indir) ! 1207: p2reg(p->memno, type2); ! 1208: else ! 1209: fatal("attempt to take address of a register"); ! 1210: break; ! 1211: ! 1212: case STGPREG: ! 1213: if(indir && !offp) ! 1214: p2oreg(offset, p->memno, type2); ! 1215: else ! 1216: { ! 1217: p2reg(p->memno, type2 | P2PTR); ! 1218: goto based; ! 1219: } ! 1220: break; ! 1221: ! 1222: default: ! 1223: badstg("putaddr", p->vstg); ! 1224: } ! 1225: frexpr(p); ! 1226: } ! 1227: ! 1228: ! 1229: ! 1230: ! 1231: LOCAL putmem(p, class, offset) ! 1232: expptr p; ! 1233: int class; ! 1234: ftnint offset; ! 1235: { ! 1236: int type2; ! 1237: int funct; ! 1238: char *name, *memname(); ! 1239: ! 1240: funct = (p->headblock.vclass==CLPROC ? P2FUNCT<<2 : 0); ! 1241: type2 = types2[p->headblock.vtype]; ! 1242: if(p->headblock.vclass == CLPROC) ! 1243: type2 |= (P2FUNCT<<2); ! 1244: name = memname(p->addrblock.vstg, p->addrblock.memno); ! 1245: if(class == P2ICON) ! 1246: { ! 1247: p2triple(P2ICON, name[0]!='\0', type2|P2PTR); ! 1248: p2word(offset); ! 1249: if(name[0]) ! 1250: p2name(name); ! 1251: } ! 1252: else ! 1253: { ! 1254: p2triple(P2NAME, offset!=0, type2); ! 1255: if(offset != 0) ! 1256: p2word(offset); ! 1257: p2name(name); ! 1258: } ! 1259: } ! 1260: ! 1261: ! 1262: ! 1263: LOCAL Addrp putcall(p) ! 1264: register Exprp p; ! 1265: { ! 1266: chainp arglist, charsp, cp; ! 1267: int n, first; ! 1268: Addrp t; ! 1269: register expptr q; ! 1270: Addrp fval; ! 1271: int type, type2, ctype, qtype, indir; ! 1272: ! 1273: type2 = types2[type = p->vtype]; ! 1274: charsp = NULL; ! 1275: indir = (p->opcode == OPCCALL); ! 1276: n = 0; ! 1277: first = YES; ! 1278: ! 1279: if(p->rightp) ! 1280: { ! 1281: arglist = p->rightp->listblock.listp; ! 1282: free( (charptr) (p->rightp) ); ! 1283: } ! 1284: else ! 1285: arglist = NULL; ! 1286: ! 1287: for(cp = arglist ; cp ; cp = cp->nextp) ! 1288: { ! 1289: q = (expptr) cp->datap; ! 1290: if(indir) ! 1291: ++n; ! 1292: else { ! 1293: q = (expptr) (cp->datap); ! 1294: if( ISCONST(q) ) ! 1295: { ! 1296: q = (expptr) putconst(q); ! 1297: cp->datap = (tagptr) q; ! 1298: } ! 1299: if( ISCHAR(q) && q->headblock.vclass!=CLPROC ) ! 1300: { ! 1301: charsp = hookup(charsp, ! 1302: mkchain(cpexpr(q->headblock.vleng), ! 1303: CHNULL)); ! 1304: n += 2; ! 1305: } ! 1306: else ! 1307: n += 1; ! 1308: } ! 1309: } ! 1310: ! 1311: if(type == TYCHAR) ! 1312: { ! 1313: if( ISICON(p->vleng) ) ! 1314: { ! 1315: fval = mkaltemp(TYCHAR, p->vleng); ! 1316: n += 2; ! 1317: } ! 1318: else { ! 1319: err("adjustable character function"); ! 1320: return; ! 1321: } ! 1322: } ! 1323: else if( ISCOMPLEX(type) ) ! 1324: { ! 1325: fval = mkaltemp(type, PNULL); ! 1326: n += 1; ! 1327: } ! 1328: else ! 1329: fval = NULL; ! 1330: ! 1331: ctype = (fval ? P2INT : type2); ! 1332: putaddr(p->leftp, NO); ! 1333: ! 1334: if(fval) ! 1335: { ! 1336: first = NO; ! 1337: putaddr( cpexpr(fval), NO); ! 1338: if(type==TYCHAR) ! 1339: { ! 1340: putx( mkconv(TYLENG,p->vleng) ); ! 1341: p2op(P2LISTOP, type2); ! 1342: } ! 1343: } ! 1344: ! 1345: for(cp = arglist ; cp ; cp = cp->nextp) ! 1346: { ! 1347: q = (expptr) (cp->datap); ! 1348: if(q->tag==TADDR && (indir || q->addrblock.vstg!=STGREG) ) ! 1349: putaddr(q, indir && q->addrblock.vtype!=TYCHAR); ! 1350: else if( ISCOMPLEX(q->headblock.vtype) ) ! 1351: putcxop(q); ! 1352: else if (ISCHAR(q) ) ! 1353: putchop(q); ! 1354: else if( ! ISERROR(q) ) ! 1355: { ! 1356: if(indir) ! 1357: putx(q); ! 1358: else { ! 1359: t = mkaltemp(qtype = q->headblock.vtype, ! 1360: q->headblock.vleng); ! 1361: putassign( cpexpr(t), q ); ! 1362: putaddr(t, NO); ! 1363: putcomma(1, qtype, YES); ! 1364: } ! 1365: } ! 1366: if(first) ! 1367: first = NO; ! 1368: else ! 1369: p2op(P2LISTOP, type2); ! 1370: } ! 1371: ! 1372: if(arglist) ! 1373: frchain(&arglist); ! 1374: for(cp = charsp ; cp ; cp = cp->nextp) ! 1375: { ! 1376: putx( mkconv(TYLENG,cp->datap) ); ! 1377: p2op(P2LISTOP, type2); ! 1378: } ! 1379: frchain(&charsp); ! 1380: p2op(n>0 ? P2CALL : P2CALL0 , ctype); ! 1381: free( (charptr) p ); ! 1382: return(fval); ! 1383: } ! 1384: ! 1385: ! 1386: ! 1387: LOCAL putmnmx(p) ! 1388: register expptr p; ! 1389: { ! 1390: int op, type; ! 1391: int ncomma; ! 1392: expptr qp; ! 1393: chainp p0, p1; ! 1394: Addrp sp, tp; ! 1395: ! 1396: if(p->tag != TEXPR) ! 1397: badtag("putmnmx", p->tag); ! 1398: ! 1399: type = p->exprblock.vtype; ! 1400: op = (p->exprblock.opcode==OPMIN ? OPLT : OPGT ); ! 1401: p0 = p->exprblock.leftp->listblock.listp; ! 1402: free( (charptr) (p->exprblock.leftp) ); ! 1403: free( (charptr) p ); ! 1404: ! 1405: sp = mkaltemp(type, PNULL); ! 1406: tp = mkaltemp(type, PNULL); ! 1407: qp = mkexpr(OPCOLON, cpexpr(tp), cpexpr(sp)); ! 1408: qp = mkexpr(OPQUEST, mkexpr(op, cpexpr(tp),cpexpr(sp)), qp); ! 1409: qp = fixexpr(qp); ! 1410: ! 1411: ncomma = 1; ! 1412: putassign( cpexpr(sp), p0->datap ); ! 1413: ! 1414: for(p1 = p0->nextp ; p1 ; p1 = p1->nextp) ! 1415: { ! 1416: ++ncomma; ! 1417: putassign( cpexpr(tp), p1->datap ); ! 1418: if(p1->nextp) ! 1419: { ! 1420: ++ncomma; ! 1421: putassign( cpexpr(sp), cpexpr(qp) ); ! 1422: } ! 1423: else ! 1424: putx(qp); ! 1425: } ! 1426: ! 1427: putcomma(ncomma, type, NO); ! 1428: frtemp(sp); ! 1429: frtemp(tp); ! 1430: frchain( &p0 ); ! 1431: } ! 1432: ! 1433: ! 1434: ! 1435: ! 1436: LOCAL putcomma(n, type, indir) ! 1437: int n, type, indir; ! 1438: { ! 1439: type = types2[type]; ! 1440: if(indir) ! 1441: type |= P2PTR; ! 1442: while(--n >= 0) ! 1443: p2op(P2COMOP, type); ! 1444: } ! 1445: ! 1446: ! 1447: ! 1448: ! 1449: ftnint simoffset(p0) ! 1450: expptr *p0; ! 1451: { ! 1452: ftnint offset, prod; ! 1453: register expptr p, lp, rp; ! 1454: ! 1455: offset = 0; ! 1456: p = *p0; ! 1457: if(p == NULL) ! 1458: return(0); ! 1459: ! 1460: if( ! ISINT(p->headblock.vtype) ) ! 1461: return(0); ! 1462: ! 1463: if(p->tag==TEXPR && p->exprblock.opcode==OPSTAR) ! 1464: { ! 1465: lp = p->exprblock.leftp; ! 1466: rp = p->exprblock.rightp; ! 1467: if(ISICON(rp) && lp->tag==TEXPR && ! 1468: lp->exprblock.opcode==OPPLUS && ISICON(lp->exprblock.rightp)) ! 1469: { ! 1470: p->exprblock.opcode = OPPLUS; ! 1471: lp->exprblock.opcode = OPSTAR; ! 1472: prod = rp->constblock.const.ci * ! 1473: lp->exprblock.rightp->constblock.const.ci; ! 1474: lp->exprblock.rightp->constblock.const.ci = rp->constblock.const.ci; ! 1475: rp->constblock.const.ci = prod; ! 1476: } ! 1477: } ! 1478: ! 1479: if(p->tag==TEXPR && p->exprblock.opcode==OPPLUS && ! 1480: ISICON(p->exprblock.rightp)) ! 1481: { ! 1482: rp = p->exprblock.rightp; ! 1483: lp = p->exprblock.leftp; ! 1484: offset += rp->constblock.const.ci; ! 1485: frexpr(rp); ! 1486: free( (charptr) p ); ! 1487: *p0 = lp; ! 1488: } ! 1489: ! 1490: if( ISCONST(p) ) ! 1491: { ! 1492: offset += p->constblock.const.ci; ! 1493: frexpr(p); ! 1494: *p0 = NULL; ! 1495: } ! 1496: ! 1497: return(offset); ! 1498: } ! 1499: ! 1500: ! 1501: ! 1502: ! 1503: ! 1504: p2op(op, type) ! 1505: int op, type; ! 1506: { ! 1507: p2triple(op, 0, type); ! 1508: } ! 1509: ! 1510: p2icon(offset, type) ! 1511: ftnint offset; ! 1512: int type; ! 1513: { ! 1514: p2triple(P2ICON, 0, type); ! 1515: p2word(offset); ! 1516: } ! 1517: ! 1518: ! 1519: ! 1520: ! 1521: p2oreg(offset, reg, type) ! 1522: ftnint offset; ! 1523: int reg, type; ! 1524: { ! 1525: p2triple(P2OREG, reg, type); ! 1526: p2word(offset); ! 1527: p2name(""); ! 1528: } ! 1529: ! 1530: ! 1531: ! 1532: ! 1533: p2reg(reg, type) ! 1534: int reg, type; ! 1535: { ! 1536: p2triple(P2REG, reg, type); ! 1537: } ! 1538: ! 1539: ! 1540: ! 1541: p2pi(s, i) ! 1542: char *s; ! 1543: int i; ! 1544: { ! 1545: char buff[100]; ! 1546: sprintf(buff, s, i); ! 1547: p2pass(buff); ! 1548: } ! 1549: ! 1550: ! 1551: ! 1552: p2pij(s, i, j) ! 1553: char *s; ! 1554: int i, j; ! 1555: { ! 1556: char buff[100]; ! 1557: sprintf(buff, s, i, j); ! 1558: p2pass(buff); ! 1559: } ! 1560: ! 1561: ! 1562: ! 1563: ! 1564: p2ps(s, t) ! 1565: char *s, *t; ! 1566: { ! 1567: char buff[100]; ! 1568: sprintf(buff, s, t); ! 1569: p2pass(buff); ! 1570: } ! 1571: ! 1572: ! 1573: ! 1574: ! 1575: p2pass(s) ! 1576: char *s; ! 1577: { ! 1578: p2triple(P2PASS, (strlen(s) + FOUR-1)/FOUR, 0); ! 1579: p2str(s); ! 1580: } ! 1581: ! 1582: ! 1583: ! 1584: ! 1585: p2str(s) ! 1586: register char *s; ! 1587: { ! 1588: union { long int word; char str[FOUR]; } u; ! 1589: register int i; ! 1590: ! 1591: i = 0; ! 1592: u.word = 0; ! 1593: while(*s) ! 1594: { ! 1595: u.str[i++] = *s++; ! 1596: if(i == FOUR) ! 1597: { ! 1598: p2word(u.word); ! 1599: u.word = 0; ! 1600: i = 0; ! 1601: } ! 1602: } ! 1603: if(i > 0) ! 1604: p2word(u.word); ! 1605: } ! 1606: ! 1607: ! 1608: ! 1609: ! 1610: p2triple(op, var, type) ! 1611: int op, var, type; ! 1612: { ! 1613: register long word; ! 1614: word = op | (var<<8); ! 1615: word |= ( (long int) type) <<16; ! 1616: p2word(word); ! 1617: } ! 1618: ! 1619: ! 1620: ! 1621: ! 1622: ! 1623: p2name(s) ! 1624: register char *s; ! 1625: { ! 1626: register int i; ! 1627: ! 1628: #ifdef UCBPASS2 ! 1629: /* arbitrary length names, terminated by a null, ! 1630: padded to a full word */ ! 1631: ! 1632: # define WL sizeof(long int) ! 1633: union { long int word; char str[WL]; } w; ! 1634: ! 1635: w.word = 0; ! 1636: i = 0; ! 1637: while(w.str[i++] = *s++) ! 1638: if(i == WL) ! 1639: { ! 1640: p2word(w.word); ! 1641: w.word = 0; ! 1642: i = 0; ! 1643: } ! 1644: if(i > 0) ! 1645: p2word(w.word); ! 1646: #else ! 1647: /* standard intermediate, names are 8 characters long */ ! 1648: ! 1649: union { long int word[2]; char str[8]; } u; ! 1650: ! 1651: u.word[0] = u.word[1] = 0; ! 1652: for(i = 0 ; i<8 && *s ; ++i) ! 1653: u.str[i] = *s++; ! 1654: p2word(u.word[0]); ! 1655: p2word(u.word[1]); ! 1656: ! 1657: #endif ! 1658: ! 1659: } ! 1660: ! 1661: ! 1662: ! 1663: ! 1664: p2word(w) ! 1665: long int w; ! 1666: { ! 1667: *p2bufp++ = w; ! 1668: if(p2bufp >= p2bufend) ! 1669: p2flush(); ! 1670: } ! 1671: ! 1672: ! 1673: ! 1674: p2flush() ! 1675: { ! 1676: if(p2bufp > p2buff) ! 1677: write(fileno(textfile), p2buff, (p2bufp-p2buff)*sizeof(long int)); ! 1678: p2bufp = p2buff; ! 1679: } ! 1680: ! 1681: ! 1682: ! 1683: LOCAL ! 1684: p2ldisp(offset, vname, type) ! 1685: ftnint offset; ! 1686: char *vname; ! 1687: int type; ! 1688: { ! 1689: char buff[100]; ! 1690: ! 1691: sprintf(buff, "%s-v.%d", vname, bsslabel); ! 1692: p2triple(P2OREG, 11, type); ! 1693: p2word(offset); ! 1694: p2name(buff); ! 1695: } ! 1696: ! 1697: ! 1698: ! 1699: p2ndisp(vname) ! 1700: char *vname; ! 1701: { ! 1702: char buff[100]; ! 1703: ! 1704: sprintf(buff, "%s-v.%d", vname, bsslabel); ! 1705: p2name(buff); ! 1706: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.