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