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

Defined functions

intdouble defined in line 527; used 3 times
ncat defined in line 894; used 3 times
p2i defined in line 1194; used 24 times
p2li defined in line 1246; used 1 times
p2offset defined in line 1258; used 3 times
p2op defined in line 1207; used 12 times
p2op2 defined in line 1227; used 43 times
p2reg defined in line 1236; used 7 times
p2str defined in line 1217; used 2 times
prarif defined in line 132; used 1 times
putaddr defined in line 933; used 13 times
putbranch defined in line 93; used 2 times
putcall defined in line 1018; used 4 times
putcat defined in line 871; used 2 times
putch1 defined in line 754; used 6 times
putchcmp defined in line 845; used 1 times
putcheq defined in line 818; used 1 times
putchop defined in line 805; used 1 times
putcmgo defined in line 146; used 1 times
putcomma defined in line 1179; used 13 times
putct1 defined in line 905; used 3 times
putcx1 defined in line 579; used 10 times
putcxcmp defined in line 730; used 1 times
putcxeq defined in line 543; used 2 times
putcxop defined in line 566; used 4 times
puteof defined in line 44; used 1 times
putexpr defined in line 121; used 4 times
putforce defined in line 460; used 7 times
putgoto defined in line 85; used 10 times
puthead defined in line 14; used 3 times
putif defined in line 60; used 12 times
putlabel defined in line 112; used 19 times
putmnmx defined in line 1133; used 1 times
putnreg defined in line 34; used 2 times
putop defined in line 332; used 3 times
putpower defined in line 472; used 1 times
putstmt defined in line 51; used 5 times
putx defined in line 173; used 24 times
Last modified: 1979-05-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2530
Valid CSS Valid XHTML 1.0 Strict