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