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