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