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