1: #
   2: /*
   3: 
   4: 	    	C compiler, part 2
   5: 
   6: 
   7: */
   8: 
   9: #include "c1h.c"
  10: 
  11: char    maprel[] {  EQUAL, NEQUAL, GREATEQ, GREAT, LESSEQ,
  12:             LESS, GREATQP, GREATP, LESSEQP, LESSP
  13: };
  14: 
  15: char    notrel[] {  NEQUAL, EQUAL, GREAT, GREATEQ, LESS,
  16:             LESSEQ, GREATP, GREATQP, LESSP, LESSEQP
  17: };
  18: 
  19: struct tconst czero { CON, INT, 0, 0};
  20: struct tconst cone  { CON, INT, 0, 1};
  21: struct tconst fczero { SFCON, DOUBLE, 0, 0 };
  22: 
  23: struct  table   *cregtab;
  24: 
  25: int nreg    3;
  26: int isn 10000;
  27: int namsiz  8;
  28: 
  29: main(argc, argv)
  30: char *argv[];
  31: {
  32:     extern fout;
  33: 
  34:     if (argc<4) {
  35:         error("Arg count");
  36:         exit(1);
  37:     }
  38:     if(fopen(argv[1], ascbuf)<0) {
  39:         error("Missing temp file");
  40:         exit(1);
  41:     }
  42:     if ((fout = creat(argv[3], 0666)) < 0) {
  43:         error("Can't create %s", argv[3]);
  44:         exit(1);
  45:     }
  46:     spacep = treespace;
  47:     getree();
  48:     /*
  49: 	 * If any floating-point instructions
  50: 	 * were used, generate a reference which
  51: 	 * pulls in the floating-point part of printf.
  52: 	 */
  53:     if (nfloat)
  54:         printf(".globl	fltused\n");
  55:     /*
  56: 	 * tack on the string file.
  57: 	 */
  58:     close(ascbuf[0]);
  59:     if (fopen(argv[2], ascbuf)<0) {
  60:         error("Missing temp file");
  61:         exit(1);
  62:     }
  63:     printf(".globl\n.data\n");
  64:     getree();
  65:     flush();
  66:     exit(nerror!=0);
  67: }
  68: 
  69: /*
  70:  * Given a tree, a code table, and a
  71:  * count of available registers, find the code table
  72:  * for the appropriate operator such that the operands
  73:  * are of the right type and the number of registers
  74:  * required is not too large.
  75:  * Return a ptr to the table entry or 0 if none found.
  76:  */
  77: char *match(atree, table, nrleft)
  78: struct tnode *atree;
  79: struct table *table;
  80: {
  81:     int op, d1, d2, t1, t2, dope;
  82:     struct tnode *p2;
  83:     register struct tnode *p1, *tree;
  84:     register struct optab *opt;
  85: 
  86:     if ((tree=atree)==0)
  87:         return(0);
  88:     if (table==lsptab)
  89:         table = sptab;
  90:     if ((op = tree->op)==0)
  91:         return(0);
  92:     dope = opdope[op];
  93:     if ((dope&LEAF) == 0)
  94:         p1 = tree->tr1;
  95:     else
  96:         p1 = tree;
  97:     t1 = p1->type;
  98:     d1 = dcalc(p1, nrleft);
  99:     if ((dope&BINARY)!=0) {
 100:         p2 = tree->tr2;
 101:         /*
 102: 		 * If a subtree starts off with a conversion operator,
 103: 		 * try for a match with the conversion eliminated.
 104: 		 * E.g. int = double can be done without generating
 105: 		 * the converted int in a register by
 106: 		 * movf double,fr0; movfi fr0,int .
 107: 		 */
 108:         if(opdope[p1->op]&CNVRT && (opdope[p2->op]&CNVRT)==0) {
 109:             tree->tr1 = p1->tr1;
 110:             if (opt = match(tree, table, nrleft))
 111:                 return(opt);
 112:             tree->tr1 = p1;
 113:         } else if (opdope[p2->op]&CNVRT && (opdope[p1->op]&CNVRT)==0) {
 114:             tree->tr2 = p2->tr1;
 115:             if (opt = match(tree, table, nrleft))
 116:                 return(opt);
 117:             tree->tr2 = p2;
 118:         }
 119:         t2 = p2->type;
 120:         d2 = dcalc(p2, nrleft);
 121:     }
 122:     for (; table->op!=op; table++)
 123:         if (table->op==0)
 124:             return(0);
 125:     for (opt = table->tabp; opt->tabdeg1!=0; opt++) {
 126:         if (d1 > (opt->tabdeg1&077)
 127:          || (opt->tabdeg1 >= 0100 && (p1->op != STAR)))
 128:             continue;
 129:         if (notcompat(p1, opt->tabtyp1, op)) {
 130:             continue;
 131:         }
 132:         if ((opdope[op]&BINARY)!=0 && p2!=0) {
 133:             if (d2 > (opt->tabdeg2&077)
 134:              || (opt->tabdeg2 >= 0100) && (p2->op != STAR) )
 135:                 continue;
 136:             if (notcompat(p2,opt->tabtyp2, 0))
 137:                 continue;
 138:         }
 139:         return(opt);
 140:     }
 141:     return(0);
 142: }
 143: 
 144: /*
 145:  * Given a tree, a code table, and a register,
 146:  * produce code to evaluate the tree with the appropriate table.
 147:  * Registers reg and upcan be used.
 148:  * If there is a value, it is desired that it appear in reg.
 149:  * The routine returns the register in which the value actually appears.
 150:  * This routine must work or there is an error.
 151:  * If the table called for is cctab, sptab, or efftab,
 152:  * and tree can't be done using the called-for table,
 153:  * another try is made.
 154:  * If the tree can't be compiled using cctab, regtab is
 155:  * used and a "tst" instruction is produced.
 156:  * If the tree can't be compiled using sptab,
 157:  * regtab is used and the register is pushed on the stack.
 158:  * If the tree can't be compiled using efftab,
 159:  * just use regtab.
 160:  * Regtab must succeed or an "op not found" error results.
 161:  *
 162:  * A number of special cases are recognized, and
 163:  * there is an interaction with the optimizer routines.
 164:  */
 165: rcexpr(atree, atable, reg)
 166: struct tnode *atree;
 167: struct table *atable;
 168: {
 169:     register r;
 170:     int modf, nargs, recurf;
 171:     register struct tnode *tree;
 172:     register struct table *table;
 173: 
 174:     table = atable;
 175:     recurf = 0;
 176:     if (reg<0) {
 177:         recurf++;
 178:         reg = ~reg;
 179:         if (reg>=020) {
 180:             reg =- 020;
 181:             recurf++;
 182:         }
 183:     }
 184:     if((tree=atree)==0)
 185:         return(0);
 186:     switch (tree->op)  {
 187: 
 188:     /*
 189: 	 * A conditional branch
 190: 	 */
 191:     case CBRANCH:
 192:         cbranch(optim(tree->btree), tree->lbl, tree->cond, 0);
 193:         return(0);
 194: 
 195:     /*
 196: 	 * An initializing expression
 197: 	 */
 198:     case INIT:
 199:         if (tree->tr1->op == AMPER)
 200:             tree->tr1 = tree->tr1->tr1;
 201:         if (tree->tr1->op==NAME)
 202:             pname(tree->tr1);
 203:         else if (tree->tr1==CON)
 204:             psoct(tree->tr1->value);
 205:         else
 206:             error("Illegal initialization");
 207:         putchar('\n');
 208:         return(0);
 209: 
 210:     /*
 211: 	 * Put the value of an expression in r0,
 212: 	 * for a switch or a return
 213: 	 */
 214:     case RFORCE:
 215:         if((r=rcexpr(tree->tr1, regtab, reg)) != 0)
 216:             printf("mov%c	r%d,r0\n", isfloat(tree->tr1), r);
 217:         return(0);
 218: 
 219:     /*
 220: 	 * sequential execution
 221: 	 */
 222:     case COMMA:
 223:         rcexpr(tree->tr1, efftab, reg);
 224:         atree = tree = tree->tr2;
 225:         break;
 226: 
 227:     /*
 228: 	 * In the generated &~ operator,
 229: 	 * fiddle things so a PDP-11 "bit"
 230: 	 * instruction will be produced when cctab is used.
 231: 	 */
 232:     case NAND:
 233:         if (table==cctab) {
 234:             tree->op = TAND;
 235:             tree->tr2 = optim(block(1, COMPL, INT, 0, tree->tr2));
 236:         }
 237:         break;
 238: 
 239: 
 240:     /*
 241: 	 * Handle a subroutine call. It has to be done
 242: 	 * here because if cexpr got called twice, the
 243: 	 * arguments might be compiled twice.
 244: 	 * There is also some fiddling so the
 245: 	 * first argument, in favorable circumstances,
 246: 	 * goes to (sp) instead of -(sp), reducing
 247: 	 * the amount of stack-popping.
 248: 	 */
 249:     case CALL:
 250:         r = 0;
 251:         nargs = 0;
 252:         modf = 0;
 253:         if (tree->tr1->op!=NAME) {  /* get nargs right */
 254:             nargs++;
 255:             nstack++;
 256:         }
 257:         tree = tree->tr2;
 258:         if(tree->op) {
 259:             while (tree->op==COMMA) {
 260:                 r =+ comarg(tree->tr2, &modf);
 261:                 tree = tree->tr1;
 262:                 nargs++;
 263:             }
 264:             r =+ comarg(tree, &modf);
 265:             nargs++;
 266:         }
 267:         tree = atree;
 268:         tree->op = CALL2;
 269:         if (modf && tree->tr1->op==NAME && tree->tr1->class==EXTERN)
 270:             tree->op = CALL1;
 271:         cexpr(tree, regtab, reg);
 272:         popstk(r);
 273:         nstack =- nargs;
 274:         if (table==efftab || table==regtab)
 275:             return(0);
 276:         r = 0;
 277:         goto fixup;
 278: 
 279:     /*
 280: 	 * Longs need special treatment.
 281: 	 */
 282:     case ASLSH:
 283:     case LSHIFT:
 284:         if (tree->type==LONG) {
 285:             if (tree->tr2->op==ITOL)
 286:                 tree->tr2 = tree->tr2->tr1;
 287:             if (tree->op==ASLSH)
 288:                 tree->op = ASLSHL;
 289:             else
 290:                 tree->op = LLSHIFT;
 291:         }
 292:         break;
 293: 
 294:     /*
 295: 	 * Try to change * and / to shifts.
 296: 	 */
 297:     case TIMES:
 298:     case DIVIDE:
 299:     case ASTIMES:
 300:     case ASDIV:
 301:         tree = pow2(tree);
 302:     }
 303:     /*
 304: 	 * Try to find postfix ++ and -- operators that can be
 305: 	 * pulled out and done after the rest of the expression
 306: 	 */
 307:     if (table!=cctab && table!=cregtab && recurf<2
 308:      && (opdope[tree->op]&LEAF)==0) {
 309:         if (r=delay(&atree, table, reg)) {
 310:             tree = atree;
 311:             table = efftab;
 312:             reg = r-1;
 313:         }
 314:     }
 315:     /*
 316: 	 * Basically, try to reorder the computation
 317: 	 * so  reg = x+y  is done as  reg = x; reg =+ y
 318: 	 */
 319:     if (recurf==0 && reorder(&atree, table, reg)) {
 320:         if (table==cctab && atree->op==NAME)
 321:             return(reg);
 322:     }
 323:     tree = atree;
 324:     if (table==efftab && tree->op==NAME)
 325:         return(reg);
 326:     if ((r=cexpr(tree, table, reg))>=0)
 327:         return(r);
 328:     if (table!=regtab)  {
 329:         if((r=cexpr(tree, regtab, reg))>=0) {
 330:     fixup:
 331:             modf = isfloat(tree);
 332:             if (table==sptab || table==lsptab) {
 333:                 if (tree->type==LONG) {
 334:                     printf("mov\tr%d,-(sp)\n",r+1);
 335:                     nstack++;
 336:                 }
 337:                 printf("mov%c	r%d,%c(sp)\n", modf, r,
 338:                     table==sptab? '-':0);
 339:                 nstack++;
 340:             }
 341:             if (table==cctab)
 342:                 printf("tst%c	r%d\n", modf, r);
 343:             return(r);
 344:         }
 345:     }
 346:     if (tree->op>0 && tree->op<RFORCE && opntab[tree->op])
 347:         error("No code table for op: %s", opntab[tree->op]);
 348:     else
 349:         error("No code table for op %d", tree->op);
 350:     return(reg);
 351: }
 352: 
 353: /*
 354:  * Try to compile the tree with the code table using
 355:  * registers areg and up.  If successful,
 356:  * return the register where the value actually ended up.
 357:  * If unsuccessful, return -1.
 358:  *
 359:  * Most of the work is the macro-expansion of the
 360:  * code table.
 361:  */
 362: cexpr(atree, table, areg)
 363: struct tnode *atree;
 364: struct table *table;
 365: {
 366:     int c, r;
 367:     register struct tnode *p, *p1, *tree;
 368:     struct table *ctable;
 369:     struct tnode *p2;
 370:     char *string;
 371:     int reg, reg1, rreg, flag, opd;
 372:     char *opt;
 373: 
 374:     tree = atree;
 375:     reg = areg;
 376:     p1 = tree->tr2;
 377:     c = tree->op;
 378:     opd = opdope[c];
 379:     /*
 380: 	 * When the value of a relational or a logical expression is
 381: 	 * desired, more work must be done.
 382: 	 */
 383:     if ((opd&RELAT||c==LOGAND||c==LOGOR||c==EXCLA) && table!=cctab) {
 384:         cbranch(tree, c=isn++, 1, reg);
 385:         rcexpr(&czero, table, reg);
 386:         branch(isn, 0);
 387:         label(c);
 388:         rcexpr(&cone, table, reg);
 389:         label(isn++);
 390:         return(reg);
 391:     }
 392:     if(c==QUEST) {
 393:         if (table==cctab)
 394:             return(-1);
 395:         cbranch(tree->tr1, c=isn++, 0, reg);
 396:         flag = nstack;
 397:         rreg = rcexpr(p1->tr1, table, reg);
 398:         nstack = flag;
 399:         branch(r=isn++, 0);
 400:         label(c);
 401:         reg = rcexpr(p1->tr2, table, rreg);
 402:         if (rreg!=reg)
 403:             printf("mov%c	r%d,r%d\n",
 404:                 isfloat(tree),reg,rreg);
 405:         label(r);
 406:         return(rreg);
 407:     }
 408:     reg = oddreg(tree, reg);
 409:     reg1 = reg+1;
 410:     /*
 411: 	 * long values take 2 registers.
 412: 	 */
 413:     if (tree->type==LONG && tree->op!=ITOL)
 414:         reg1++;
 415:     /*
 416: 	 * Leaves of the expression tree
 417: 	 */
 418:     if ((r = chkleaf(tree, table, reg)) >= 0)
 419:         return(r);
 420:     /*
 421: 	 * x + (-1) is better done as x-1.
 422: 	 */
 423: 
 424:     if ((tree->op==PLUS||tree->op==ASPLUS) &&
 425:         (p1=tree->tr2)->op == CON && p1->value == -1) {
 426:         p1->value = 1;
 427:         tree->op =+ (MINUS-PLUS);
 428:     }
 429:     if (table==cregtab)
 430:         table = regtab;
 431:     /*
 432: 	 * The following peculiar code depends on the fact that
 433: 	 * if you just want the codition codes set, efftab
 434: 	 * will generate the right code unless the operator is
 435: 	 * postfix ++ or --. Unravelled, if the table is
 436: 	 * cctab and the operator is not special, try first
 437: 	 * for efftab;  if the table isn't, if the operator is,
 438: 	 * or the first match fails, try to match
 439: 	 * with the table actually asked for.
 440: 	 */
 441:     if (table!=cctab || c==INCAFT || c==DECAFT
 442:      || (opt = match(tree, efftab, nreg-reg)) == 0)
 443:         if ((opt=match(tree, table, nreg-reg))==0)
 444:             return(-1);
 445:     string = opt->tabstring;
 446:     p1 = tree->tr1;
 447:     p2 = 0;
 448:     if (opdope[tree->op]&BINARY)
 449:         p2 = tree->tr2;
 450: loop:
 451:     /*
 452: 	 * The 0200 bit asks for a tab.
 453: 	 */
 454:     if ((c = *string++) & 0200) {
 455:         c =& 0177;
 456:         putchar('\t');
 457:     }
 458:     switch (c) {
 459: 
 460:     case '\0':
 461:         if (!isfloat(tree))
 462:             if (tree->op==DIVIDE || tree->op==ASDIV)
 463:                 reg--;
 464:         return(reg);
 465: 
 466:     /* A1 */
 467:     case 'A':
 468:         p = p1;
 469:         goto adr;
 470: 
 471:     /* A2 */
 472:     case 'B':
 473:         p = p2;
 474:         goto adr;
 475: 
 476:     adr:
 477:         c = 0;
 478:         if (*string=='\'') {
 479:             c = 1;
 480:             string++;
 481:         } else if (*string=='+') {
 482:             c = 2;
 483:             string++;
 484:         }
 485:         pname(p, c);
 486:         goto loop;
 487: 
 488:     /* I */
 489:     case 'M':
 490:         if ((c = *string)=='\'')
 491:             string++;
 492:         else
 493:             c = 0;
 494:         prins(tree->op, c, instab);
 495:         goto loop;
 496: 
 497:     /* B1 */
 498:     case 'C':
 499:         if ((opd&LEAF) != 0)
 500:             p = tree;
 501:         else
 502:             p = p1;
 503:         goto pbyte;
 504: 
 505:     /* BF */
 506:     case 'P':
 507:         p = tree;
 508:         goto pb1;
 509: 
 510:     /* B2 */
 511:     case 'D':
 512:         p = p2;
 513:     pbyte:
 514:         if (p->type==CHAR)
 515:             putchar('b');
 516:     pb1:
 517:         if (isfloat(p))
 518:             putchar('f');
 519:         goto loop;
 520: 
 521:     /* BE */
 522:     case 'L':
 523:         if (p1->type==CHAR || p2->type==CHAR)
 524:             putchar('b');
 525:         p = tree;
 526:         goto pb1;
 527: 
 528:     /* F */
 529:     case 'G':
 530:         p = p1;
 531:         flag = 01;
 532:         goto subtre;
 533: 
 534:     /* S */
 535:     case 'K':
 536:         p = p2;
 537:         flag = 02;
 538:         goto subtre;
 539: 
 540:     /* H */
 541:     case 'H':
 542:         p = tree;
 543:         flag = 04;
 544: 
 545:     subtre:
 546:         ctable = regtab;
 547:         c = *string++ - 'A';
 548:         if (*string=='!') {
 549:             string++;
 550:             c =| 020;   /* force right register */
 551:         }
 552:         if ((c&02)!=0)
 553:             ctable = sptab;
 554:         if ((c&04)!=0)
 555:             ctable = cctab;
 556:         if ((flag&01) && ctable==regtab && (c&01)==0
 557:           && (tree->op==DIVIDE||tree->op==MOD
 558:            || tree->op==ASDIV||tree->op==ASMOD))
 559:             ctable = cregtab;
 560:         if ((c&01)!=0) {
 561:             p = p->tr1;
 562:             if(collcon(p) && ctable!=sptab) {
 563:                 if (p->op==STAR)
 564:                     p = p->tr1;
 565:                 p = p->tr1;
 566:             }
 567:         }
 568:         if (table==lsptab && ctable==sptab)
 569:             ctable = lsptab;
 570:         if (c&010)
 571:             r = reg1;
 572:         else
 573:             if (opdope[p->op]&LEAF || p->degree < 2)
 574:                 r = reg;
 575:             else
 576:                 r = areg;
 577:         rreg = rcexpr(p, ctable, r);
 578:         if (ctable!=regtab && ctable!=cregtab)
 579:             goto loop;
 580:         if (c&010) {
 581:             if (c&020 && rreg!=reg1)
 582:                 printf("mov%c	r%d,r%d\n",
 583:                     isfloat(tree),rreg,reg1);
 584:             else
 585:                 reg1 = rreg;
 586:         } else if (rreg!=reg)
 587:             if ((c&020)==0 && oddreg(tree, 0)==0 && (flag&04 ||
 588:                   flag&01
 589:               && xdcalc(p2, nreg-rreg-1) <= (opt->tabdeg2&077)
 590:              ||   flag&02
 591:               && xdcalc(p1,nreg-rreg-1) <= (opt->tabdeg1&077))) {
 592:                 reg = rreg;
 593:                 reg1 = rreg+1;
 594:             } else
 595:                 printf("mov%c\tr%d,r%d\n",
 596:                     isfloat(tree), rreg, reg);
 597:         goto loop;
 598: 
 599:     /* R */
 600:     case 'I':
 601:         r = reg;
 602:         if (*string=='-') {
 603:             string++;
 604:             r--;
 605:         }
 606:         goto preg;
 607: 
 608:     /* R1 */
 609:     case 'J':
 610:         r = reg1;
 611:     preg:
 612:         if (*string=='+') {
 613:             string++;
 614:             r++;
 615:         }
 616:         if (r>nreg)
 617:             error("Register overflow: simplify expression");
 618:         printf("r%d", r);
 619:         goto loop;
 620: 
 621:     case '-':       /* check -(sp) */
 622:         if (*string=='(') {
 623:             nstack++;
 624:             if (table!=lsptab)
 625:                 putchar('-');
 626:             goto loop;
 627:         }
 628:         break;
 629: 
 630:     case ')':       /* check (sp)+ */
 631:         putchar(')');
 632:         if (*string=='+')
 633:             nstack--;
 634:         goto loop;
 635: 
 636:     /* #1 */
 637:     case '#':
 638:         p = p1->tr1;
 639:         goto nmbr;
 640: 
 641:     /* #2 */
 642:     case '"':
 643:         p = p2->tr1;
 644: 
 645:     nmbr:
 646:         if(collcon(p)) {
 647:             if (p->op==STAR) {
 648:                 printf("*");
 649:                 p = p->tr1;
 650:             }
 651:             if ((p = p->tr2)->op == CON) {
 652:                 if (p->value)
 653:                     psoct(p->value);
 654:             } else if (p->op==AMPER)
 655:                 pname(p->tr1, 0);
 656:         }
 657:         goto loop;
 658: 
 659:     case 'T':       /* "tst R" if 1st op not in cctab */
 660:         if (dcalc(p1, 5)>12 && !match(p1, cctab, 10))
 661:             printf("tst	r%d\n", reg);
 662:         goto loop;
 663:     case 'V':   /* adc or sbc as required for longs */
 664:         switch(tree->op) {
 665:         case PLUS:
 666:         case ASPLUS:
 667:         case INCBEF:
 668:         case INCAFT:
 669:             printf("adc");
 670:             break;
 671: 
 672:         case MINUS:
 673:         case ASMINUS:
 674:         case NEG:
 675:         case DECBEF:
 676:         case DECAFT:
 677:             printf("sbc");
 678:             break;
 679: 
 680:         default:
 681:             while ((c = *string++)!='\n' && c!='\0');
 682:             break;
 683:         }
 684:         goto loop;
 685:     }
 686:     putchar(c);
 687:     goto loop;
 688: }
 689: 
 690: /*
 691:  * This routine just calls sreorder (below)
 692:  * on the subtrees and then on the tree itself.
 693:  * It returns non-zero if anything changed.
 694:  */
 695: reorder(treep, table, reg)
 696: struct tnode **treep;
 697: struct table *table;
 698: {
 699:     register r, r1;
 700:     register struct tnode *p;
 701: 
 702:     p = *treep;
 703:     if (opdope[p->op]&LEAF)
 704:         return(0);
 705:     r1 = 0;
 706:     while(sreorder(&p->tr1, table, reg))
 707:         r1++;
 708:     if (opdope[p->op]&BINARY)
 709:         while(sreorder(&p->tr2, table, reg))
 710:             r1++;
 711:     r = 0;
 712:     while (sreorder(treep, table, reg))
 713:         r++;
 714:     *treep = optim(*treep);
 715:     return(r);
 716: }
 717: 
 718: /*
 719:  * Basically this routine carries out two kinds of optimization.
 720:  * First, it observes that "x + (reg = y)" where actually
 721:  * the = is any assignment op is better done as "reg=y; x+reg".
 722:  * In this case rcexpr is called to do the first part and the
 723:  * tree is modified so the name of the register
 724:  * replaces the assignment.
 725:  * Moreover, expressions like "reg = x+y" are best done as
 726:  * "reg = x; reg =+ y" (so long as "reg" and "y" are not the same!).
 727:  */
 728: sreorder(treep, table, reg)
 729: struct tnode **treep;
 730: struct table *table;
 731: {
 732:     register struct tnode *p, *p1;
 733: 
 734:     p = *treep;
 735:     if (opdope[p->op]&LEAF)
 736:         return(0);
 737:     if (p->op==PLUS)
 738:         if (reorder(&p->tr2, table, reg))
 739:             *treep = p = optim(p);
 740:     p1 = p->tr1;
 741:     if (p->op==STAR || p->op==PLUS) {
 742:         if (reorder(&p->tr1, table, reg))
 743:             *treep = p = optim(p);
 744:         p1 = p->tr1;
 745:     }
 746:     if (p1->op==NAME) switch(p->op) {
 747:         case ASLSH:
 748:         case ASRSH:
 749:         case ASSIGN:
 750:             if (p1->class != REG || isfloat(p->tr2))
 751:                 return(0);
 752:             if (p->op==ASSIGN) switch (p->tr2->op) {
 753:             case TIMES:
 754:             case DIVIDE:
 755:                 if (!ispow2(p->tr2))
 756:                     break;
 757:                 p->tr2 = pow2(p->tr2);
 758:             case PLUS:
 759:             case MINUS:
 760:             case AND:
 761:             case NAND:
 762:             case OR:
 763:             case EXOR:
 764:             case LSHIFT:
 765:             case RSHIFT:
 766:                 p1 = p->tr2->tr2;
 767:                 if (xdcalc(p1) > 12
 768:                  || p1->op==NAME
 769:                  &&(p1->nloc==p->tr1->nloc
 770:                   || p1->regno==p->tr1->nloc))
 771:                     return(0);
 772:                 p1 = p->tr2;
 773:                 p->tr2 = p1->tr1;
 774:                 if (p1->tr1->op!=NAME
 775:                  || p1->tr1->class!=REG
 776:                  || p1->tr1->nloc!=p->tr1->nloc)
 777:                     rcexpr(p, efftab, reg);
 778:                 p->tr2 = p1->tr2;
 779:                 p->op = p1->op + ASPLUS - PLUS;
 780:                 *treep = p;
 781:                 return(1);
 782:             }
 783:             goto OK;
 784: 
 785:         case ASTIMES:
 786:         case ASDIV:
 787:             if (!ispow2(p))
 788:                 return(0);
 789:         case ASPLUS:
 790:         case ASMINUS:
 791:         case ASSAND:
 792:         case ASSNAND:
 793:         case ASOR:
 794:         case ASXOR:
 795:         case DECBEF:
 796:         case INCBEF:
 797:         OK:
 798:             if (table==cctab||table==cregtab)
 799:                 reg =+ 020;
 800:             rcexpr(optim(p), efftab, ~reg);
 801:             *treep = p1;
 802:             return(1);
 803:     }
 804:     return(0);
 805: }
 806: 
 807: /*
 808:  * Delay handles postfix ++ and --
 809:  * It observes that "x + y++" is better
 810:  * treated as "x + y; y++".
 811:  * If the operator is ++ or -- itself,
 812:  * it calls rcexpr to load the operand, letting
 813:  * the calling instance of rcexpr to do the
 814:  * ++ using efftab.
 815:  * Otherwise it uses sdelay to search for inc/dec
 816:  * among the operands.
 817:  */
 818: delay(treep, table, reg)
 819: struct tnode **treep;
 820: {
 821:     register struct tnode *p, *p1;
 822:     register r;
 823: 
 824:     p = *treep;
 825:     if (table!=efftab && (p->op==INCAFT||p->op==DECAFT)
 826:      && p->tr1->op==NAME) {
 827:         return(1+rcexpr(p->tr1, table, reg));
 828:     }
 829:     p1 = 0;
 830:     if (opdope[p->op]&BINARY)
 831:         p1 = sdelay(&p->tr2);
 832:     if (p1==0)
 833:         p1 = sdelay(&p->tr1);
 834:     if (p1) {
 835:         r = rcexpr(optim(p), table, reg);
 836:         *treep = p1;
 837:         return(r+1);
 838:     }
 839:     return(0);
 840: }
 841: 
 842: sdelay(ap)
 843: struct tnode **ap;
 844: {
 845:     register struct tnode *p, *p1;
 846: 
 847:     p = *ap;
 848:     if ((p->op==INCAFT||p->op==DECAFT) && p->tr1->op==NAME) {
 849:         *ap = ncopy(p->tr1);
 850:         return(p);
 851:     }
 852:     if (p->op==STAR || p->op==PLUS)
 853:         if (p1=sdelay(&p->tr1))
 854:             return(p1);
 855:     if (p->op==PLUS)
 856:         return(sdelay(&p->tr2));
 857:     return(0);
 858: }
 859: 
 860: /*
 861:  * Copy a tree node for a register variable.
 862:  * Used by sdelay because if *reg-- is turned
 863:  * into *reg; reg-- the *reg will in turn
 864:  * be changed to some offset class, accidentally
 865:  * modifying the reg--.
 866:  */
 867: ncopy(ap)
 868: struct tname *ap;
 869: {
 870:     register struct tname *p;
 871: 
 872:     p = ap;
 873:     if (p->class!=REG)
 874:         return(p);
 875:     return(block(3, NAME, p->type, p->elsize, p->tr1,
 876:         p->offset, p->nloc));
 877: }
 878: 
 879: /*
 880:  * If the tree can be immediately loaded into a register,
 881:  * produce code to do so and return success.
 882:  */
 883: chkleaf(atree, table, reg)
 884: struct tnode *atree;
 885: {
 886:     struct tnode lbuf;
 887:     register struct tnode *tree;
 888: 
 889:     tree = atree;
 890:     if (tree->op!=STAR && dcalc(tree, nreg-reg) > 12)
 891:         return(-1);
 892:     lbuf.op = LOAD;
 893:     lbuf.type = tree->type;
 894:     lbuf.degree = tree->degree;
 895:     lbuf.tr1 = tree;
 896:     return(rcexpr(&lbuf, table, reg));
 897: }
 898: 
 899: /*
 900:  * Compile a function argument.
 901:  * If the stack is currently empty, put it in (sp)
 902:  * rather than -(sp); this will save a pop.
 903:  * Return the number of bytes pushed,
 904:  * for future popping.
 905:  */
 906: comarg(atree, flagp)
 907: int *flagp;
 908: {
 909:     register struct tnode *tree;
 910:     register retval;
 911: 
 912:     tree = atree;
 913:     if (nstack || isfloat(tree) || tree->type==LONG) {
 914:         rcexpr(tree, sptab, 0);
 915:         retval = arlength(tree->type);
 916:     } else {
 917:         (*flagp)++;
 918:         rcexpr(tree, lsptab, 0);
 919:         retval = 0;
 920:     }
 921:     return(retval);
 922: }

Defined functions

cexpr defined in line 362; used 3 times
chkleaf defined in line 883; used 1 times
comarg defined in line 906; used 2 times
delay defined in line 818; used 1 times
main defined in line 29; never used
match defined in line 77; used 5 times
ncopy defined in line 867; used 1 times
rcexpr defined in line 165; used 14 times
reorder defined in line 695; used 3 times
sdelay defined in line 842; used 4 times
sreorder defined in line 728; used 3 times

Defined variables

cone defined in line 20; used 1 times
cregtab defined in line 23; used 5 times
czero defined in line 19; used 1 times
fczero defined in line 21; never used
isn defined in line 26; used 5 times
maprel defined in line 11; never used
namsiz defined in line 27; never used
notrel defined in line 15; never used
nreg defined in line 25; used 6 times
Last modified: 1975-07-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1786
Valid CSS Valid XHTML 1.0 Strict