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

Defined functions

intdouble defined in line 497; used 3 times
ncat defined in line 865; used 3 times
p2flush defined in line 1417; used 5 times
p2icon defined in line 1313; used 6 times
p2name defined in line 1391; used 4 times
p2op defined in line 1307; used 23 times
p2oreg defined in line 1324; used 3 times
p2pass defined in line 1344; used 29 times
p2reg defined in line 1336; used 4 times
p2str defined in line 1354; used 2 times
p2triple defined in line 1379; used 12 times
p2word defined in line 1407; used 11 times
putaddr defined in line 904; used 12 times
putbracket defined in line 57; used 1 times
putbranch defined in line 144; never used
putcall defined in line 1076; used 4 times
putcat defined in line 842; used 2 times
putch1 defined in line 724; used 6 times
putchcmp defined in line 816; used 1 times
putcheq defined in line 788; used 1 times
putchop defined in line 775; used 1 times
putcmgo defined in line 174; never used
putcomma defined in line 1242; used 13 times
putct1 defined in line 876; used 3 times
putcx1 defined in line 549; used 10 times
putcxcmp defined in line 700; used 1 times
putcxeq defined in line 513; used 2 times
putcxop defined in line 536; used 4 times
puteof defined in line 92; never used
putexpr defined in line 164; never used
putforce defined in line 429; never used
putgoto defined in line 135; never used
puthead defined in line 20; never used
putif defined in line 109; never used
putlabel defined in line 155; used 1 times
putmem defined in line 1044; used 2 times
putmnmx defined in line 1196; used 1 times
putnreg defined in line 83; never used
putop defined in line 362; used 3 times
putpower defined in line 442; used 1 times
putrbrack defined in line 75; used 1 times
putstmt defined in line 100; used 5 times
putx defined in line 202; used 19 times
simoffset defined in line 1255; used 2 times

Defined variables

p2bufend defined in line 17; used 1 times
p2buff defined in line 15; used 6 times
p2bufp defined in line 16; used 5 times

Defined macros

FOUR defined in line 10; used 6 times
P2BUFFMAX defined in line 14; used 2 times
Last modified: 1979-05-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2940
Valid CSS Valid XHTML 1.0 Strict