1: /*	@(#)c11.c	2.2	SCCS id keyword */
   2: #
   3: /*
   4:  *  C compiler
   5:  */
   6: 
   7: #include "c1.h"
   8: 
   9: max(a, b)
  10: {
  11:     if (a>b)
  12:         return(a);
  13:     return(b);
  14: }
  15: 
  16: degree(at)
  17: struct tnode *at;
  18: {
  19:     register struct tnode *t, *t1;
  20: 
  21:     if ((t=at)==0 || t->op==0)
  22:         return(0);
  23:     if (t->op == CON)
  24:         return(-3);
  25:     if (t->op == AMPER)
  26:         return(-2);
  27:     if (t->op==ITOL) {
  28:         if ((t1 = isconstant(t)) && (t1->value>=0 || t1->type==UNSIGN))
  29:             return(-2);
  30:         if ((t1=t->tr1)->type==UNSIGN && opdope[t1->op]&LEAF)
  31:             return(-1);
  32:     }
  33:     if ((opdope[t->op] & LEAF) != 0) {
  34:         if (t->type==CHAR || t->type==FLOAT)
  35:             return(1);
  36:         return(0);
  37:     }
  38:     return(t->degree);
  39: }
  40: 
  41: pname(ap, flag)
  42: struct tnode *ap;
  43: {
  44:     register i;
  45:     register struct tnode *p;
  46:     struct { int intx[2]; };
  47: 
  48:     p = ap;
  49: loop:
  50:     switch(p->op) {
  51: 
  52:     case LCON:
  53:         printf("$%o", flag>10? p->lvalue.intx[1]:p->lvalue.intx[0]);
  54:         return;
  55: 
  56:     case SFCON:
  57:     case CON:
  58:         printf("$");
  59:         psoct(p->value);
  60:         return;
  61: 
  62:     case FCON:
  63:         printf("L%d", (p->value>0? p->value: -p->value));
  64:         return;
  65: 
  66:     case NAME:
  67:         i = p->offset;
  68:         if (flag>10)
  69:             i =+ 2;
  70:         if (i) {
  71:             psoct(i);
  72:             if (p->class!=OFFS)
  73:                 putchar('+');
  74:             if (p->class==REG)
  75:                 regerr();
  76:         }
  77:         switch(p->class) {
  78: 
  79:         case SOFFS:
  80:         case XOFFS:
  81:             pbase(p);
  82: 
  83:         case OFFS:
  84:             printf("(r%d)", p->regno);
  85:             return;
  86: 
  87:         case EXTERN:
  88:         case STATIC:
  89:             pbase(p);
  90:             return;
  91: 
  92:         case REG:
  93:             printf("r%d", p->nloc);
  94:             return;
  95: 
  96:         }
  97:         error("Compiler error: pname");
  98:         return;
  99: 
 100:     case AMPER:
 101:         putchar('$');
 102:         p = p->tr1;
 103:         if (p->op==NAME && p->class==REG)
 104:             regerr();
 105:         goto loop;
 106: 
 107:     case AUTOI:
 108:         printf("(r%d)%c", p->nloc, flag==1?0:'+');
 109:         return;
 110: 
 111:     case AUTOD:
 112:         printf("%c(r%d)", flag==2?0:'-', p->nloc);
 113:         return;
 114: 
 115:     case STAR:
 116:         p = p->tr1;
 117:         putchar('*');
 118:         goto loop;
 119: 
 120:     }
 121:     error("pname called illegally");
 122: }
 123: 
 124: regerr()
 125: {
 126:     error("Illegal use of register");
 127: }
 128: 
 129: pbase(ap)
 130: struct tnode *ap;
 131: {
 132:     register struct tnode *p;
 133: 
 134:     p = ap;
 135:     if (p->class==SOFFS || p->class==STATIC)
 136:         printf("L%d", p->nloc);
 137:     else
 138:         printf("%.8s", &(p->nloc));
 139: }
 140: 
 141: xdcalc(ap, nrleft)
 142: struct tnode *ap;
 143: {
 144:     register struct tnode *p;
 145:     register d;
 146: 
 147:     p = ap;
 148:     d = dcalc(p, nrleft);
 149:     if (d<20 && p->type==CHAR) {
 150:         if (nrleft>=1)
 151:             d = 20;
 152:         else
 153:             d = 24;
 154:     }
 155:     return(d);
 156: }
 157: 
 158: dcalc(ap, nrleft)
 159: struct tnode *ap;
 160: {
 161:     register struct tnode *p, *p1;
 162: 
 163:     if ((p=ap)==0)
 164:         return(0);
 165:     switch (p->op) {
 166: 
 167:     case NAME:
 168:         if (p->class==REG)
 169:             return(9);
 170: 
 171:     case AMPER:
 172:     case FCON:
 173:     case LCON:
 174:     case AUTOI:
 175:     case AUTOD:
 176:         return(12);
 177: 
 178:     case CON:
 179:     case SFCON:
 180:         if (p->value==0)
 181:             return(4);
 182:         if (p->value==1)
 183:             return(5);
 184:         if (p->value > 0)
 185:             return(8);
 186:         return(12);
 187: 
 188:     case STAR:
 189:         p1 = p->tr1;
 190:         if (p1->op==NAME||p1->op==CON||p1->op==AUTOI||p1->op==AUTOD)
 191:             if (p->type!=LONG)
 192:                 return(12);
 193:     }
 194:     if (p->type==LONG)
 195:         nrleft--;
 196:     return(p->degree <= nrleft? 20: 24);
 197: }
 198: 
 199: notcompat(ap, ast, op)
 200: struct tnode *ap;
 201: {
 202:     register at, st;
 203:     register struct tnode *p;
 204: 
 205:     p = ap;
 206:     at = p->type;
 207:     st = ast;
 208:     if (st==0)      /* word, byte */
 209:         return(at!=CHAR && at!=INT && at!=UNSIGN && at<PTR);
 210:     if (st==1)      /* word */
 211:         return(at!=INT && at!=UNSIGN && at<PTR);
 212:     if (st==9 && (at&XTYPE))
 213:         return(0);
 214:     st =- 2;
 215:     if ((at&(~(TYPE+XTYPE))) != 0)
 216:         at = 020;
 217:     if ((at&(~TYPE)) != 0)
 218:         at = at&TYPE | 020;
 219:     if (st==FLOAT && at==DOUBLE)
 220:         at = FLOAT;
 221:     if (p->op==NAME && p->class==REG && op==ASSIGN && st==CHAR)
 222:         return(0);
 223:     return(st != at);
 224: }
 225: 
 226: prins(op, c, itable)
 227: struct instab *itable;
 228: {
 229:     register struct instab *insp;
 230:     register char *ip;
 231: 
 232:     for (insp=itable; insp->op != 0; insp++) {
 233:         if (insp->op == op) {
 234:             ip = c? insp->str2: insp->str1;
 235:             if (ip==0)
 236:                 break;
 237:             printf("%s", ip);
 238:             return;
 239:         }
 240:     }
 241:     error("No match' for op %d", op);
 242: }
 243: 
 244: collcon(ap)
 245: struct tnode *ap;
 246: {
 247:     register op;
 248:     register struct tnode *p;
 249: 
 250:     p = ap;
 251:     if (p->op==STAR) {
 252:         if (p->type==LONG+PTR) /* avoid *x(r); *x+2(r) */
 253:             return(0);
 254:         p = p->tr1;
 255:     }
 256:     if (p->op==PLUS) {
 257:         op = p->tr2->op;
 258:         if (op==CON || op==AMPER)
 259:             return(1);
 260:     }
 261:     return(0);
 262: }
 263: 
 264: isfloat(at)
 265: struct tnode *at;
 266: {
 267:     register struct tnode *t;
 268: 
 269:     t = at;
 270:     if ((opdope[t->op]&RELAT)!=0)
 271:         t = t->tr1;
 272:     if (t->type==FLOAT || t->type==DOUBLE) {
 273:         nfloat = 1;
 274:         return('f');
 275:     }
 276:     return(0);
 277: }
 278: 
 279: oddreg(t, areg)
 280: struct tnode *t;
 281: {
 282:     register reg;
 283: 
 284:     reg = areg;
 285:     if (!isfloat(t)) {
 286:         if (opdope[t->op]&RELAT) {
 287:             if (t->tr1->type==LONG)
 288:                 return((reg+1) & ~01);
 289:             return(reg);
 290:         }
 291:         switch(t->op) {
 292:         case LLSHIFT:
 293:         case ASLSHL:
 294:             return((reg+1)&~01);
 295: 
 296:         case DIVIDE:
 297:         case MOD:
 298:         case ASDIV:
 299:         case ASMOD:
 300:         case PTOI:
 301:         case ULSH:
 302:         case ASULSH:
 303:             reg++;
 304: 
 305:         case TIMES:
 306:         case ASTIMES:
 307:             return(reg|1);
 308:         }
 309:     }
 310:     return(reg);
 311: }
 312: 
 313: arlength(t)
 314: {
 315:     if (t>=PTR)
 316:         return(2);
 317:     switch(t) {
 318: 
 319:     case INT:
 320:     case CHAR:
 321:     case UNSIGN:
 322:         return(2);
 323: 
 324:     case LONG:
 325:         return(4);
 326: 
 327:     case FLOAT:
 328:     case DOUBLE:
 329:         return(8);
 330:     }
 331:     return(1024);
 332: }
 333: 
 334: /*
 335:  * Strings for switch code.
 336:  */
 337: 
 338: /*
 339:  * Modified Memorial day May 80 to uniquely identify switch tables
 340:  * (as on Vax) so a shell script can optionally include them in RO code.
 341:  * This is useful in overlays to reduce the size of data space load.
 342:  * wfj 5/80
 343:  */
 344: #ifdef MENLO_OVLY
 345: char    dirsw[] {"\
 346: cmp	r0,$%o\n\
 347: jhi	L%d\n\
 348: asl	r0\n\
 349: jmp	*L%d(r0)\n\
 350: \t.data\n\
 351: L%d:\
 352: " };
 353: 
 354: char    hashsw[] {"\
 355: mov	r0,r1\n\
 356: clr	r0\n\
 357: div	$%o,r0\n\
 358: asl	r1\n\
 359: jmp	*L%d(r1)\n\
 360: \t.data\n\
 361: L%d:\
 362: "};
 363: #else
 364: char    dirsw[] {"\
 365: cmp	r0,$%o\n\
 366: jhi	L%d\n\
 367: asl	r0\n\
 368: jmp	*L%d(r0)\n\
 369: .data\n\
 370: L%d:\
 371: " };
 372: 
 373: char    hashsw[] {"\
 374: mov	r0,r1\n\
 375: clr	r0\n\
 376: div	$%o,r0\n\
 377: asl	r1\n\
 378: jmp	*L%d(r1)\n\
 379: .data\n\
 380: L%d:\
 381: "};
 382: 
 383: #endif
 384: /*
 385:  * If the unsigned casts below won't compile,
 386:  * try using the calls to lrem and ldiv.
 387:  */
 388: 
 389: pswitch(afp, alp, deflab)
 390: struct swtab *afp, *alp;
 391: {
 392:     int ncase, i, j, tabs, worst, best, range;
 393:     register struct swtab *swp, *fp, *lp;
 394:     int *poctab;
 395: 
 396:     fp = afp;
 397:     lp = alp;
 398:     if (fp==lp) {
 399:         printf("jbr	L%d\n", deflab);
 400:         return;
 401:     }
 402:     isn++;
 403:     if (sort(fp, lp))
 404:         return;
 405:     ncase = lp-fp;
 406:     lp--;
 407:     range = lp->swval - fp->swval;
 408:     /* direct switch */
 409:     if (range>0 && range <= 3*ncase) {
 410:         if (fp->swval)
 411:             printf("sub	$%o,r0\n", fp->swval);
 412:         printf(dirsw, range, deflab, isn, isn);
 413:         isn++;
 414:         for (i=fp->swval; ; i++) {
 415:             if (i==fp->swval) {
 416:                 printf("L%d\n", fp->swlab);
 417:                 if (fp==lp)
 418:                     break;
 419:                 fp++;
 420:             } else
 421:                 printf("L%d\n", deflab);
 422:         }
 423:         printf(".text\n");
 424:         return;
 425:     }
 426:     /* simple switch */
 427:     if (ncase<10) {
 428:         for (fp = afp; fp<=lp; fp++)
 429:             breq(fp->swval, fp->swlab);
 430:         printf("jbr	L%d\n", deflab);
 431:         return;
 432:     }
 433:     /* hash switch */
 434:     best = 077777;
 435:     poctab = getblk(((ncase+2)/2) * sizeof(*poctab));
 436:     for (i=ncase/4; i<=ncase/2; i++) {
 437:         for (j=0; j<i; j++)
 438:             poctab[j] = 0;
 439:         for (swp=fp; swp<=lp; swp++)
 440:             /* lrem(0, swp->swval, i) */
 441:             poctab[(unsigned)swp->swval%i]++;
 442:         worst = 0;
 443:         for (j=0; j<i; j++)
 444:             if (poctab[j]>worst)
 445:                 worst = poctab[j];
 446:         if (i*worst < best) {
 447:             tabs = i;
 448:             best = i*worst;
 449:         }
 450:     }
 451:     i = isn++;
 452:     printf(hashsw, tabs, i, i);
 453:     isn++;
 454:     for (i=0; i<tabs; i++)
 455:         printf("L%d\n", isn+i);
 456:     printf(".text\n");
 457:     for (i=0; i<tabs; i++) {
 458:         printf("L%d:", isn++);
 459:         for (swp=fp; swp<=lp; swp++) {
 460:             /* lrem(0, swp->swval, tabs) */
 461:             if ((unsigned)swp->swval%tabs == i) {
 462:                 /* ldiv(0, swp->swval, tabs) */
 463:                 breq((unsigned)swp->swval/tabs, swp->swlab);
 464:             }
 465:         }
 466:         printf("jbr	L%d\n", deflab);
 467:     }
 468: }
 469: 
 470: breq(v, l)
 471: {
 472:     if (v==0)
 473:         printf("tst	r0\n");
 474:     else
 475:         printf("cmp	r0,$%o\n", v);
 476:     printf("jeq	L%d\n", l);
 477: }
 478: 
 479: sort(afp, alp)
 480: struct swtab *afp, *alp;
 481: {
 482:     register struct swtab *cp, *fp, *lp;
 483:     int intch, t;
 484: 
 485:     fp = afp;
 486:     lp = alp;
 487:     while (fp < --lp) {
 488:         intch = 0;
 489:         for (cp=fp; cp<lp; cp++) {
 490:             if (cp->swval == cp[1].swval) {
 491:                 error("Duplicate case (%d)", cp->swval);
 492:                 return(1);
 493:             }
 494:             if (cp->swval > cp[1].swval) {
 495:                 intch++;
 496:                 t = cp->swval;
 497:                 cp->swval = cp[1].swval;
 498:                 cp[1].swval = t;
 499:                 t = cp->swlab;
 500:                 cp->swlab = cp[1].swlab;
 501:                 cp[1].swlab = t;
 502:             }
 503:         }
 504:         if (intch==0)
 505:             break;
 506:     }
 507:     return(0);
 508: }
 509: 
 510: ispow2(atree)
 511: {
 512:     register int d;
 513:     register struct tnode *tree;
 514: 
 515:     tree = atree;
 516:     if (!isfloat(tree) && tree->tr2->op==CON) {
 517:         d = tree->tr2->value;
 518:         if (d>1 && (d&(d-1))==0)
 519:             return(d);
 520:     }
 521:     return(0);
 522: }
 523: 
 524: pow2(atree)
 525: struct tnode *atree;
 526: {
 527:     register int d, i;
 528:     register struct tnode *tree;
 529: 
 530:     tree = atree;
 531:     if (d = ispow2(tree)) {
 532:         for (i=0; (d=>>1)!=0; i++);
 533:         tree->tr2->value = i;
 534:         switch (tree->op) {
 535: 
 536:         case TIMES:
 537:             tree->op = LSHIFT;
 538:             break;
 539: 
 540:         case ASTIMES:
 541:             tree->op = ASLSH;
 542:             break;
 543: 
 544:         case DIVIDE:
 545:             tree->op = ULSH;
 546:             tree->tr2->value = -i;
 547:             break;
 548: 
 549:         case ASDIV:
 550:             tree->op = ASULSH;
 551:             tree->tr2->value = -i;
 552:             break;
 553: 
 554:         case MOD:
 555:             tree->op = AND;
 556:             tree->tr2->value = (1<<i)-1;
 557:             break;
 558: 
 559:         case ASMOD:
 560:             tree->op = ASAND;
 561:             tree->tr2->value = (1<<i)-1;
 562:             break;
 563: 
 564:         default:
 565:             error("pow2 botch");
 566:         }
 567:         tree = optim(tree);
 568:     }
 569:     return(tree);
 570: }
 571: 
 572: cbranch(atree, albl, cond, areg)
 573: struct tnode *atree;
 574: {
 575:     int l1, op;
 576:     register lbl, reg;
 577:     register struct tnode *tree;
 578: 
 579:     lbl = albl;
 580:     reg = areg;
 581: again:
 582:     if ((tree=atree)==0)
 583:         return;
 584:     switch(tree->op) {
 585: 
 586:     case LOGAND:
 587:         if (cond) {
 588:             cbranch(tree->tr1, l1=isn++, 0, reg);
 589:             cbranch(tree->tr2, lbl, 1, reg);
 590:             label(l1);
 591:         } else {
 592:             cbranch(tree->tr1, lbl, 0, reg);
 593:             cbranch(tree->tr2, lbl, 0, reg);
 594:         }
 595:         return;
 596: 
 597:     case LOGOR:
 598:         if (cond) {
 599:             cbranch(tree->tr1, lbl, 1, reg);
 600:             cbranch(tree->tr2, lbl, 1, reg);
 601:         } else {
 602:             cbranch(tree->tr1, l1=isn++, 1, reg);
 603:             cbranch(tree->tr2, lbl, 0, reg);
 604:             label(l1);
 605:         }
 606:         return;
 607: 
 608:     case EXCLA:
 609:         cbranch(tree->tr1, lbl, !cond, reg);
 610:         return;
 611: 
 612:     case SEQNC:
 613:         rcexpr(tree->tr1, efftab, reg);
 614:         atree = tree->tr2;
 615:         goto again;
 616: 
 617:     case ITOL:
 618:         tree = tree->tr1;
 619:         break;
 620:     }
 621:     op = tree->op;
 622:     if (opdope[op]&RELAT
 623:      && tree->tr1->op==ITOL && tree->tr2->op==ITOL) {
 624:         tree->tr1 = tree->tr1->tr1;
 625:         tree->tr2 = tree->tr2->tr1;
 626:         if (op>=LESSEQ && op<=GREAT
 627:          && (tree->tr1->type==UNSIGN || tree->tr2->type==UNSIGN))
 628:             tree->op = op = op+LESSEQP-LESSEQ;
 629:     }
 630:     if (tree->type==LONG
 631:       || opdope[op]&RELAT&&tree->tr1->type==LONG) {
 632:         longrel(tree, lbl, cond, reg);
 633:         return;
 634:     }
 635:     rcexpr(tree, cctab, reg);
 636:     op = tree->op;
 637:     if ((opdope[op]&RELAT)==0)
 638:         op = NEQUAL;
 639:     else {
 640:         l1 = tree->tr2->op;
 641:         if ((l1==CON || l1==SFCON) && tree->tr2->value==0)
 642:             op =+ 200;      /* special for ptr tests */
 643:         else
 644:             op = maprel[op-EQUAL];
 645:     }
 646:     if (isfloat(tree))
 647:         printf("cfcc\n");
 648:     branch(lbl, op, !cond);
 649: }
 650: 
 651: branch(lbl, aop, c)
 652: {
 653:     register op;
 654: 
 655:     if(op=aop)
 656:         prins(op, c, branchtab);
 657:     else
 658:         printf("jbr");
 659:     printf("\tL%d\n", lbl);
 660: }
 661: 
 662: longrel(atree, lbl, cond, reg)
 663: struct tnode *atree;
 664: {
 665:     int xl1, xl2, xo, xz;
 666:     register int op, isrel;
 667:     register struct tnode *tree;
 668: 
 669:     if (reg&01)
 670:         reg++;
 671:     reorder(&atree, cctab, reg);
 672:     tree = atree;
 673:     isrel = 0;
 674:     if (opdope[tree->op]&RELAT) {
 675:         isrel++;
 676:         op = tree->op;
 677:     } else
 678:         op = NEQUAL;
 679:     if (!cond)
 680:         op = notrel[op-EQUAL];
 681:     xl1 = xlab1;
 682:     xl2 = xlab2;
 683:     xo = xop;
 684:     xlab1 = lbl;
 685:     xlab2 = 0;
 686:     xop = op;
 687:     xz = xzero;
 688:     xzero = !isrel || tree->tr2->op==ITOL && tree->tr2->tr1->op==CON
 689:         && tree->tr2->tr1->value==0;
 690:     if (tree->op==ANDN) {
 691:         tree->op = TAND;
 692:         tree->tr2 = optim(tnode(COMPL, LONG, tree->tr2));
 693:     }
 694:     if (cexpr(tree, cctab, reg) < 0) {
 695:         reg = rcexpr(tree, regtab, reg);
 696:         printf("ashc	$0,r%d\n", reg);
 697:         branch(xlab1, op, 0);
 698:     }
 699:     xlab1 = xl1;
 700:     xlab2 = xl2;
 701:     xop = xo;
 702:     xzero = xz;
 703: }
 704: 
 705: /*
 706:  * Tables for finding out how best to do long comparisons.
 707:  * First dimen is whether or not the comparison is with 0.
 708:  * Second is which test: e.g. a>b->
 709:  *	cmp	a,b
 710:  *	bgt	YES		(first)
 711:  *	blt	NO		(second)
 712:  *	cmp	a+2,b+2
 713:  *	bhi	YES		(third)
 714:  *  NO:	...
 715:  * Note some tests may not be needed.
 716:  */
 717: char    lrtab[2][3][6] {
 718:     0,  NEQUAL, LESS,   LESS,   GREAT,  GREAT,
 719:     NEQUAL, 0,  GREAT,  GREAT,  LESS,   LESS,
 720:     EQUAL,  NEQUAL, LESSEQP,LESSP,  GREATQP,GREATP,
 721: 
 722:     0,  NEQUAL, LESS,   LESS,   GREATEQ,GREAT,
 723:     NEQUAL, 0,  GREAT,  0,  0,  LESS,
 724:     EQUAL,  NEQUAL, EQUAL,  0,  0,  NEQUAL,
 725: };
 726: 
 727: xlongrel(f)
 728: {
 729:     register int op, bno;
 730: 
 731:     op = xop;
 732:     if (f==0) {
 733:         if (bno = lrtab[xzero][0][op-EQUAL])
 734:             branch(xlab1, bno, 0);
 735:         if (bno = lrtab[xzero][1][op-EQUAL]) {
 736:             xlab2 = isn++;
 737:             branch(xlab2, bno, 0);
 738:         }
 739:         if (lrtab[xzero][2][op-EQUAL]==0)
 740:             return(1);
 741:     } else {
 742:         branch(xlab1, lrtab[xzero][2][op-EQUAL], 0);
 743:         if (xlab2)
 744:             label(xlab2);
 745:     }
 746:     return(0);
 747: }
 748: 
 749: label(l)
 750: {
 751:     printf("L%d:", l);
 752: }
 753: 
 754: popstk(a)
 755: {
 756:     switch(a) {
 757: 
 758:     case 0:
 759:         return;
 760: 
 761:     case 2:
 762:         printf("tst	(sp)+\n");
 763:         return;
 764: 
 765:     case 4:
 766:         printf("cmp	(sp)+,(sp)+\n");
 767:         return;
 768:     }
 769:     printf("add	$%o,sp\n", a);
 770: }
 771: 
 772: error(s, p1, p2, p3, p4, p5, p6)
 773: {
 774: 
 775:     nerror++;
 776:     fprintf(stderr, "%d: ", line);
 777:     fprintf(stderr, s, p1, p2, p3, p4, p5, p6);
 778:     putc('\n', stderr);
 779: }
 780: 
 781: psoct(an)
 782: {
 783:     register int n, sign;
 784: 
 785:     sign = 0;
 786:     if ((n = an) < 0) {
 787:         n = -n;
 788:         sign = '-';
 789:     }
 790:     printf("%c%o", sign, n);
 791: }
 792: 
 793: /*
 794:  * Read in an intermediate file.
 795:  */
 796: #define STKS    100
 797: getree()
 798: {
 799:     struct tnode *expstack[STKS];
 800:     register struct tnode **sp;
 801:     register t, op;
 802:     static char s[9];
 803:     struct swtab *swp;
 804:     double atof();
 805:     char numbuf[64];
 806:     struct tname *np;
 807:     struct xtname *xnp;
 808:     struct ftconst *fp;
 809:     struct lconst *lp;
 810:     struct fasgn *sap;
 811:     int lbl, cond, lbl2, lbl3;
 812: 
 813:     curbase = funcbase;
 814:     sp = expstack;
 815:     for (;;) {
 816:         if (sp >= &expstack[STKS])
 817:             error("Stack overflow botch");
 818:         op = geti();
 819:         if ((op&0177400) != 0177000) {
 820:             error("Intermediate file error");
 821:             exit(1);
 822:         }
 823:         lbl = 0;
 824:         switch(op =& 0377) {
 825: 
 826:     case SINIT:
 827:         printf("%o\n", geti());
 828:         break;
 829: 
 830:     case EOFC:
 831:         return;
 832: 
 833:     case BDATA:
 834:         if (geti() == 1) {
 835:             printf(".byte ");
 836:             for (;;)  {
 837:                 printf("%o", geti());
 838:                 if (geti() != 1)
 839:                     break;
 840:                 printf(",");
 841:             }
 842:             printf("\n");
 843:         }
 844:         break;
 845: 
 846:     case PROG:
 847:         printf(".text\n");
 848:         break;
 849: 
 850:     case DATA:
 851:         printf(".data\n");
 852:         break;
 853: 
 854:     case BSS:
 855:         printf(".bss\n");
 856:         break;
 857: 
 858:     case SYMDEF:
 859:         outname(s);
 860:         printf(".globl%s%.8s\n", s[0]?"	":"", s);
 861:         sfuncr.nloc = 0;
 862:         break;
 863: 
 864:     case RETRN:
 865:         printf("jmp	cret\n");
 866:         break;
 867: 
 868:     case CSPACE:
 869:         t = outname(s);
 870:         printf(".comm	%.8s,%o\n", t, geti());
 871:         break;
 872: 
 873:     case SSPACE:
 874:         printf(".=.+%o\n", (t=geti()));
 875:         totspace += (unsigned)t;
 876:         break;
 877: 
 878:     case EVEN:
 879:         printf(".even\n");
 880:         break;
 881: 
 882:     case SAVE:
 883:         printf("jsr	r5,csv\n");
 884:         break;
 885: 
 886:     case SETSTK:
 887: #ifdef MENLO_OVLY
 888:         /*
 889: 		 * More of Bill Shannon's fix. This actually was a bug,
 890: 		 * harmless as it was though. It sort of enforced a STAUTO
 891: 		 * of -6 , you see....
 892: 		 */
 893:         t = geti();
 894: #else
 895:         t = geti()-6;
 896: #endif
 897:         if (t==2)
 898:             printf("tst	-(sp)\n");
 899:         else if (t != 0)
 900:             printf("sub	$%o,sp\n", t);
 901:         break;
 902: 
 903:     case PROFIL:
 904:         t = geti();
 905:         printf("mov	$L%d,r0\njsr	pc,mcount\n", t);
 906:         printf(".bss\nL%d:.=.+2\n.text\n", t);
 907:         break;
 908: 
 909:     case SNAME:
 910:         t = outname(s);
 911:         printf("~%s=L%d\n", t+1, geti());
 912:         break;
 913: 
 914:     case ANAME:
 915:         t = outname(s);
 916:         printf("~%s=%o\n", t+1, geti());
 917:         break;
 918: 
 919:     case RNAME:
 920:         t = outname(s);
 921:         printf("~%s=r%d\n", t+1, geti());
 922:         break;
 923: 
 924:     case SWIT:
 925:         t = geti();
 926:         line = geti();
 927:         curbase = funcbase;
 928:         while(swp=getblk(sizeof(*swp)), swp->swlab = geti())
 929:             swp->swval = geti();
 930:         pswitch(funcbase, swp, t);
 931:         break;
 932: 
 933:     case C3BRANCH:      /* for fortran [sic] */
 934:         lbl = geti();
 935:         lbl2 = geti();
 936:         lbl3 = geti();
 937:         goto xpr;
 938: 
 939:     case CBRANCH:
 940:         lbl = geti();
 941:         cond = geti();
 942: 
 943:     case EXPR:
 944:     xpr:
 945:         line = geti();
 946:         if (sp != &expstack[1]) {
 947:             error("Expression input botch");
 948:             exit(1);
 949:         }
 950:         nstack = 0;
 951:         *sp = optim(*--sp);
 952:         if (op==CBRANCH)
 953:             cbranch(*sp, lbl, cond, 0);
 954:         else if (op==EXPR)
 955:             rcexpr(*sp, efftab, 0);
 956:         else {
 957:             if ((*sp)->type==LONG) {
 958:                 rcexpr(tnode(RFORCE, (*sp)->type, *sp), efftab, 0);
 959:                 printf("ashc	$0,r0\n");
 960:             } else {
 961:                 rcexpr(*sp, cctab, 0);
 962:                 if (isfloat(*sp))
 963:                     printf("cfcc\n");
 964:             }
 965:             printf("jgt	L%d\n", lbl3);
 966:             printf("jlt	L%d\njbr	L%d\n", lbl, lbl2);
 967:         }
 968:         curbase = funcbase;
 969:         break;
 970: 
 971:     case NAME:
 972:         t = geti();
 973:         if (t==EXTERN) {
 974:             np = getblk(sizeof(*xnp));
 975:             np->type = geti();
 976:             outname(np->name);
 977:         } else {
 978:             np = getblk(sizeof(*np));
 979:             np->type = geti();
 980:             np->nloc = geti();
 981:         }
 982:         np->op = NAME;
 983:         np->class = t;
 984:         np->regno = 0;
 985:         np->offset = 0;
 986:         *sp++ = np;
 987:         break;
 988: 
 989:     case CON:
 990:         t = geti();
 991:         *sp++ = tconst(geti(), t);
 992:         break;
 993: 
 994:     case LCON:
 995:         geti(); /* ignore type, assume long */
 996:         t = geti();
 997:         op = geti();
 998:         if (t==0 && op>=0 || t == -1 && op<0) {
 999:             *sp++ = tnode(ITOL, LONG, tconst(op, INT));
1000:             break;
1001:         }
1002:         lp = getblk(sizeof(*lp));
1003:         lp->op = LCON;
1004:         lp->type = LONG;
1005:         lp->lvalue = ((long)t<<16) + (unsigned)op;  /* nonportable */
1006:         *sp++ = lp;
1007:         break;
1008: 
1009:     case FCON:
1010:         t = geti();
1011:         outname(numbuf);
1012:         fp = getblk(sizeof(*fp));
1013:         fp->op = FCON;
1014:         fp->type = t;
1015:         fp->value = isn++;
1016:         fp->fvalue = atof(numbuf);
1017:         *sp++ = fp;
1018:         break;
1019: 
1020:     case FSEL:
1021:         *sp = tnode(FSEL, geti(), *--sp, NULL);
1022:         t = geti();
1023:         (*sp++)->tr2 = tnode(COMMA, INT, tconst(geti(), INT), tconst(t, INT));
1024:         break;
1025: 
1026:     case STRASG:
1027:         sap = getblk(sizeof(*sap));
1028:         sap->op = STRASG;
1029:         sap->type = geti();
1030:         sap->mask = geti();
1031:         sap->tr1 = *--sp;
1032:         sap->tr2 = NULL;
1033:         *sp++ = sap;
1034:         break;
1035: 
1036:     case NULLOP:
1037:         *sp++ = tnode(0, 0, NULL, NULL);
1038:         break;
1039: 
1040:     case LABEL:
1041:         label(geti());
1042:         break;
1043: 
1044:     case NLABEL:
1045:         t = outname(s);
1046:         printf("%.8s:\n", t, t);
1047:         break;
1048: 
1049:     case RLABEL:
1050:         t = outname(s);
1051:         printf("%.8s:\n~~%s:\n", t, t+1);
1052:         break;
1053: 
1054:     case BRANCH:
1055:         branch(geti(), 0);
1056:         break;
1057: 
1058:     case SETREG:
1059:         nreg = geti()-1;
1060:         break;
1061: 
1062:     default:
1063:         if (opdope[op]&BINARY) {
1064:             if (sp < &expstack[1]) {
1065:                 error("Binary expression botch");
1066:                 exit(1);
1067:             }
1068:             t = *--sp;
1069:             *sp++ = tnode(op, geti(), *--sp, t);
1070:         } else
1071:             sp[-1] = tnode(op, geti(), sp[-1]);
1072:         break;
1073:     }
1074:     }
1075: }
1076: 
1077: geti()
1078: {
1079:     register i;
1080: 
1081:     i = getchar();
1082:     i += getchar()<<8;
1083:     return(i);
1084: }
1085: 
1086: outname(s)
1087: {
1088:     register char *p, c;
1089:     register n;
1090: 
1091:     p = s;
1092:     n = 0;
1093:     while (c = getchar()) {
1094:         *p++ = c;
1095:         n++;
1096:     }
1097:     do {
1098:         *p++ = 0;
1099:     } while (n++ < 8);
1100:     return(s);
1101: }
1102: 
1103: strasg(atp)
1104: struct fasgn *atp;
1105: {
1106:     register struct tnode *tp;
1107:     register nwords, i;
1108: 
1109:     nwords = atp->mask/sizeof(int);
1110:     tp = atp->tr1;
1111:     if (tp->op != ASSIGN) {
1112:         if (tp->op==RFORCE) {   /* function return */
1113:             if (sfuncr.nloc==0) {
1114:                 sfuncr.nloc = isn++;
1115:                 printf(".bss\nL%d:.=.+%o\n.text\n", sfuncr.nloc, nwords*sizeof(int));
1116:             }
1117:             atp->tr1 = tnode(ASSIGN, STRUCT, &sfuncr, tp->tr1);
1118:             strasg(atp);
1119:             printf("mov	$L%d,r0\n", sfuncr.nloc);
1120:             return;
1121:         }
1122:         if (tp->op==CALL) {
1123:             rcexpr(tp, efftab, 0);
1124:             return;
1125:         }
1126:         error("Illegal structure operation");
1127:         return;
1128:     }
1129:     tp->tr2 = strfunc(tp->tr2);
1130:     if (nwords==1)
1131:         setype(tp, INT);
1132:     else if (nwords==sizeof(int))
1133:         setype(tp, LONG);
1134:     else {
1135:         if (tp->tr1->op!=NAME && tp->tr1->op!=STAR
1136:          || tp->tr2->op!=NAME && tp->tr2->op!=STAR) {
1137:             error("unimplemented structure assignment");
1138:             return;
1139:         }
1140:         tp->tr1 = tnode(AMPER, STRUCT+PTR, tp->tr1);
1141:         tp->tr2 = tnode(AMPER, STRUCT+PTR, tp->tr2);
1142:         tp->op = STRSET;
1143:         tp->type = STRUCT+PTR;
1144:         tp = optim(tp);
1145:         rcexpr(tp, efftab, 0);
1146:         if (nwords < 7) {
1147:             for (i=0; i<nwords; i++)
1148:                 printf("mov	(r1)+,(r0)+\n");
1149:             return;
1150:         }
1151:         if (nreg<=1)
1152:             printf("mov	r2,-(sp)\n");
1153:         printf("mov	$%o,r2\n", nwords);
1154:         printf("L%d:mov	(r1)+,(r0)+\ndec\tr2\njne\tL%d\n", isn, isn);
1155:         isn++;
1156:         if (nreg<=1)
1157:             printf("mov	(sp)+,r2\n");
1158:         return;
1159:     }
1160:     rcexpr(tp, efftab, 0);
1161: }
1162: 
1163: setype(p, t)
1164: register struct tnode *p;
1165: register t;
1166: {
1167: 
1168:     for (;; p = p->tr1) {
1169:         p->type = t;
1170:         if (p->op==AMPER)
1171:             t = decref(t);
1172:         else if (p->op==STAR)
1173:             t = incref(t);
1174:         else if (p->op==ASSIGN)
1175:             setype(p->tr2, t);
1176:         else if (p->op!=PLUS)
1177:             break;
1178:     }
1179: }
1180: 
1181: /*
1182:  * Reduce the degree-of-reference by one.
1183:  * e.g. turn "ptr-to-int" into "int".
1184:  */
1185: decref(at)
1186: {
1187:     register t;
1188: 
1189:     t = at;
1190:     if ((t & ~TYPE) == 0) {
1191:         error("Illegal indirection");
1192:         return(t);
1193:     }
1194:     return((t>>TYLEN) & ~TYPE | t&TYPE);
1195: }
1196: 
1197: /*
1198:  * Increase the degree of reference by
1199:  * one; e.g. turn "int" to "ptr-to-int".
1200:  */
1201: incref(t)
1202: {
1203:     return(((t&~TYPE)<<TYLEN) | (t&TYPE) | PTR);
1204: }

Defined functions

arlength defined in line 313; used 1 times
branch defined in line 651; used 6 times
breq defined in line 470; used 2 times
cbranch defined in line 572; used 10 times
collcon defined in line 244; used 2 times
dcalc defined in line 158; used 7 times
decref defined in line 1185; used 1 times
degree defined in line 16; used 22 times
error defined in line 772; used 13 times
geti defined in line 1077; used 43 times
getree defined in line 797; used 2 times
incref defined in line 1201; used 1 times
isfloat defined in line 264; used 12 times
ispow2 defined in line 510; used 5 times
label defined in line 749; used 4 times
longrel defined in line 662; used 1 times
max defined in line 9; used 8 times
notcompat defined in line 199; used 2 times
oddreg defined in line 279; used 2 times
outname defined in line 1086; used 9 times
pbase defined in line 129; used 2 times
pname defined in line 41; used 3 times
popstk defined in line 754; used 1 times
pow2 defined in line 524; used 3 times
prins defined in line 226; used 2 times
psoct defined in line 781; used 3 times
pswitch defined in line 389; used 1 times
regerr defined in line 124; used 2 times
setype defined in line 1163; used 3 times
sort defined in line 479; used 1 times
strasg defined in line 1103; used 2 times
xdcalc defined in line 141; used 3 times
xlongrel defined in line 727; used 1 times

Defined variables

dirsw defined in line 364; used 1 times
hashsw defined in line 373; used 1 times
lrtab defined in line 717; used 4 times

Defined macros

STKS defined in line 796; used 2 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2296
Valid CSS Valid XHTML 1.0 Strict