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

Defined functions

intdouble defined in line 528; used 3 times
ncat defined in line 895; used 3 times
p2i defined in line 1195; used 24 times
p2li defined in line 1247; used 1 times
p2offset defined in line 1259; used 3 times
p2op defined in line 1208; used 12 times
p2op2 defined in line 1228; used 43 times
p2reg defined in line 1237; used 7 times
p2str defined in line 1218; used 2 times
prarif defined in line 133; used 1 times
putaddr defined in line 934; used 13 times
putbranch defined in line 94; used 2 times
putcall defined in line 1019; used 4 times
putcat defined in line 872; used 2 times
putch1 defined in line 755; used 6 times
putchcmp defined in line 846; used 1 times
putcheq defined in line 819; used 1 times
putchop defined in line 806; used 1 times
putcmgo defined in line 147; used 2 times
putcomma defined in line 1180; used 13 times
putct1 defined in line 906; used 3 times
putcx1 defined in line 580; used 10 times
putcxcmp defined in line 731; used 1 times
putcxeq defined in line 544; used 2 times
putcxop defined in line 567; used 4 times
puteof defined in line 45; used 1 times
putexpr defined in line 122; used 4 times
putforce defined in line 461; used 7 times
putgoto defined in line 86; used 10 times
puthead defined in line 15; used 4 times
putif defined in line 61; used 12 times
putlabel defined in line 113; used 21 times
putmnmx defined in line 1134; used 1 times
putnreg defined in line 35; used 2 times
putop defined in line 333; used 3 times
putpower defined in line 473; used 1 times
putstmt defined in line 52; used 5 times
putx defined in line 174; used 24 times
Last modified: 1983-12-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3133
Valid CSS Valid XHTML 1.0 Strict