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