home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / c / c21.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-05-03  |  12.1 KB  |  792 lines

  1. #
  2. /*
  3.  * C object code improver-- second part
  4.  */
  5.  
  6. #include "c2.h"
  7.  
  8. rmove()
  9. {
  10.     register struct node *p;
  11.     register int r;
  12.     register  r1, flt;
  13.  
  14.     for (p=first.forw; p!=0; p = p->forw) {
  15.     flt = 0;
  16.     switch (p->op) {
  17.  
  18.     case MOVF:
  19.     case MOVFO:
  20.     case MOVOF:
  21.         flt = NREG;
  22.  
  23.     case MOV:
  24.         if (p->subop==BYTE)
  25.             goto dble;
  26.         dualop(p);
  27.         if ((r = findrand(regs[RT1], flt)) >= 0) {
  28.             if (r == flt+isreg(regs[RT2]) && p->forw->op!=CBR
  29.                && p->forw->op!=SXT
  30.                && p->forw->op!=CFCC) {
  31.                 p->forw->back = p->back;
  32.                 p->back->forw = p->forw;
  33.                 redunm++;
  34.                 continue;
  35.             }
  36.         }
  37.         if (equstr(regs[RT1], "$0")) {
  38.             p->op = CLR;
  39.             strcpy(regs[RT1], regs[RT2]);
  40.             regs[RT2][0] = 0;
  41.             p->code = copy(1, regs[RT1]);
  42.             goto sngl;
  43.         }
  44.         repladdr(p, 0, flt);
  45.         r = isreg(regs[RT1]);
  46.         r1 = isreg(regs[RT2]);
  47.         dest(regs[RT2], flt);
  48.         if (r >= 0)
  49.             if (r1 >= 0)
  50.                 savereg(r1+flt, regs[r+flt]);
  51.             else
  52.                 savereg(r+flt, regs[RT2]);
  53.         else
  54.             if (r1 >= 0)
  55.                 savereg(r1+flt, regs[RT1]);
  56.             else
  57.                 setcon(regs[RT1], regs[RT2]);
  58.         source(regs[RT1]);
  59.         setcc(regs[RT2]);
  60.         continue;
  61.  
  62.     case ADDF:
  63.     case SUBF:
  64.     case DIVF:
  65.     case MULF:
  66.         flt = NREG;
  67.         goto dble;
  68.  
  69.     case ADD:
  70.     case SUB:
  71.     case BIC:
  72.     case BIS:
  73.     case MUL:
  74.     case DIV:
  75.     case ASH:
  76.     dble:
  77.         dualop(p);
  78.         if (p->op==BIC && (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777"))) {
  79.             p->op = CLR;
  80.             strcpy(regs[RT1], regs[RT2]);
  81.             regs[RT2][0] = 0;
  82.             p->code = copy(1, regs[RT1]);
  83.             goto sngl;
  84.         }
  85.         if ((p->op==BIC || p->op==BIS) && equstr(regs[RT1], "$0")) {
  86.             if (p->forw->op!=CBR) {
  87.                 p->back->forw = p->forw;
  88.                 p->forw->back = p->back;
  89.                 continue;
  90.             }
  91.         }
  92.         repladdr(p, 0, flt);
  93.         source(regs[RT1]);
  94.         dest(regs[RT2], flt);
  95.         if (p->op==DIV && (r = isreg(regs[RT2])>=0))
  96.             regs[r+1][0] = 0;
  97.         ccloc[0] = 0;
  98.         continue;
  99.  
  100.     case CLRF:
  101.     case NEGF:
  102.         flt = NREG;
  103.  
  104.     case CLR:
  105.     case COM:
  106.     case INC:
  107.     case DEC:
  108.     case NEG:
  109.     case ASR:
  110.     case ASL:
  111.     case SXT:
  112.         singop(p);
  113.     sngl:
  114.         dest(regs[RT1], flt);
  115.         if (p->op==CLR && flt==0)
  116.             if ((r = isreg(regs[RT1])) >= 0)
  117.                 savereg(r, "$0");
  118.             else
  119.                 setcon("$0", regs[RT1]);
  120.         ccloc[0] = 0;
  121.         continue;
  122.  
  123.     case TSTF:
  124.         flt = NREG;
  125.  
  126.     case TST:
  127.         singop(p);
  128.         repladdr(p, 0, flt);
  129.         source(regs[RT1]);
  130.         if (equstr(regs[RT1], ccloc)) {
  131.             p->back->forw = p->forw;
  132.             p->forw->back = p->back;
  133.             p = p->back;
  134.             nrtst++;
  135.             nchange++;
  136.         }
  137.         continue;
  138.  
  139.     case CMPF:
  140.         flt = NREG;
  141.  
  142.     case CMP:
  143.     case BIT:
  144.         dualop(p);
  145.         source(regs[RT1]);
  146.         source(regs[RT2]);
  147.         if(p->op==BIT) {
  148.             if (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777")) {
  149.                 p->op = TST;
  150.                 strcpy(regs[RT1], regs[RT2]);
  151.                 regs[RT2][0] = 0;
  152.                 p->code = copy(1, regs[RT1]);
  153.                 nchange++;
  154.                 nsaddr++;
  155.             } else if (equstr(regs[RT2], "$-1") || equstr(regs[RT2], "$177777")) {
  156.                 p->op = TST;
  157.                 regs[RT2][0] = 0;
  158.                 p->code = copy(1, regs[RT1]);
  159.                 nchange++;
  160.                 nsaddr++;
  161.             }
  162.             if (equstr(regs[RT1], "$0")) {
  163.                 p->op = TST;
  164.                 regs[RT2][0] = 0;
  165.                 p->code = copy(1, regs[RT1]);
  166.                 nchange++;
  167.                 nsaddr++;
  168.             } else if (equstr(regs[RT2], "$0")) {
  169.                 p->op = TST;
  170.                 strcpy(regs[RT1], regs[RT2]);
  171.                 regs[RT2][0] = 0;
  172.                 p->code = copy(1, regs[RT1]);
  173.                 nchange++;
  174.                 nsaddr++;
  175.             }
  176.         }
  177.         repladdr(p, 1, flt);
  178.         ccloc[0] = 0;
  179.         continue;
  180.  
  181.     case CBR:
  182.         if (p->back->op==TST || p->back->op==CMP) {
  183.             if (p->back->op==TST) {
  184.                 singop(p->back);
  185.                 savereg(RT2, "$0");
  186.             } else
  187.                 dualop(p->back);
  188.             r = compare(p->subop, findcon(RT1), findcon(RT2));
  189.             if (r==0) {
  190.                 p->back->back->forw = p->forw;
  191.                 p->forw->back = p->back->back;
  192.                 decref(p->ref);
  193.                 p = p->back->back;
  194.                 nchange++;
  195.             } else if (r>0) {
  196.                 p->op = JBR;
  197.                 p->subop = 0;
  198.                 p->back->back->forw = p;
  199.                 p->back = p->back->back;
  200.                 p = p->back;
  201.                 nchange++;
  202.             }
  203.         }
  204.     case CFCC:
  205.         ccloc[0] = 0;
  206.         continue;
  207.  
  208.     case JBR:
  209.         redunbr(p);
  210.  
  211.     default:
  212.         clearreg();
  213.     }
  214.     }
  215. }
  216.  
  217. jumpsw()
  218. {
  219.     register struct node *p, *p1;
  220.     register t;
  221.     register struct node *tp;
  222.     int nj;
  223.  
  224.     t = 0;
  225.     nj = 0;
  226.     for (p=first.forw; p!=0; p = p->forw)
  227.         p->refc = ++t;
  228.     for (p=first.forw; p!=0; p = p1) {
  229.         p1 = p->forw;
  230.         if (p->op == CBR && p1->op==JBR && p->ref && p1->ref
  231.          && abs(p->refc - p->ref->refc) > abs(p1->refc - p1->ref->refc)) {
  232.             if (p->ref==p1->ref)
  233.                 continue;
  234.             p->subop = revbr[p->subop];
  235.             tp = p1->ref;
  236.             p1->ref = p->ref;
  237.             p->ref = tp;
  238.             t = p1->labno;
  239.             p1->labno = p->labno;
  240.             p->labno = t;
  241.             nrevbr++;
  242.             nj++;
  243.         }
  244.     }
  245.     return(nj);
  246. }
  247.  
  248. addsob()
  249. {
  250.     register struct node *p, *p1;
  251.  
  252.     for (p = &first; (p1 = p->forw)!=0; p = p1) {
  253.         if (p->op==DEC && isreg(p->code)>=0
  254.          && p1->op==CBR && p1->subop==JNE) {
  255.             if (p->refc < p1->ref->refc)
  256.                 continue;
  257.             if (toofar(p1))
  258.                 continue;
  259.             p->labno = p1->labno;
  260.             p->op = SOB;
  261.             p->subop = 0;
  262.             p1->forw->back = p;
  263.             p->forw = p1->forw;
  264.             nsob++;
  265.         }
  266.     }
  267. }
  268.  
  269. toofar(p)
  270. struct node *p;
  271. {
  272.     register struct node *p1;
  273.     int len;
  274.  
  275.     len = 0;
  276.     for (p1 = p->ref; p1 && p1!=p; p1 = p1->forw)
  277.         len += ilen(p1);
  278.     if (len < 128)
  279.         return(0);
  280.     return(1);
  281. }
  282.  
  283. ilen(p)
  284. register struct node *p;
  285. {
  286.     register l;
  287.  
  288.     switch (p->op) {
  289.     case LABEL:
  290.     case DLABEL:
  291.     case TEXT:
  292.     case EROU:
  293.     case EVEN:
  294.         return(0);
  295.  
  296.     case CBR:
  297.         return(6);
  298.  
  299.     default:
  300.         dualop(p);
  301.         return(2 + adrlen(regs[RT1]) + adrlen(regs[RT2]));
  302.     }
  303. }
  304.  
  305. adrlen(s)
  306. register char *s;
  307. {
  308.     if (*s == 0)
  309.         return(0);
  310.     if (*s=='r')
  311.         return(0);
  312.     if (*s=='(' && *(s+1)=='r')
  313.         return(0);
  314.     if (*s=='-' && *(s+1)=='(')
  315.         return(0);
  316.     return(2);
  317. }
  318.  
  319. abs(x)
  320. {
  321.     return(x<0? -x: x);
  322. }
  323.  
  324. equop(ap1, p2)
  325. struct node *ap1, *p2;
  326. {
  327.     register char *cp1, *cp2;
  328.     register struct node *p1;
  329.  
  330.     p1 = ap1;
  331.     if (p1->op!=p2->op || p1->subop!=p2->subop)
  332.         return(0);
  333.     if (p1->op>0 && p1->op<MOV)
  334.         return(0);
  335.     cp1 = p1->code;
  336.     cp2 = p2->code;
  337.     if (cp1==0 && cp2==0)
  338.         return(1);
  339.     if (cp1==0 || cp2==0)
  340.         return(0);
  341.     while (*cp1 == *cp2++)
  342.         if (*cp1++ == 0)
  343.             return(1);
  344.     return(0);
  345. }
  346.  
  347. decref(p)
  348. register struct node *p;
  349. {
  350.     if (--p->refc <= 0) {
  351.         nrlab++;
  352.         p->back->forw = p->forw;
  353.         p->forw->back = p->back;
  354.     }
  355. }
  356.  
  357. struct node *
  358. nonlab(p)
  359. struct node *p;
  360. {
  361.     while (p && p->op==LABEL)
  362.         p = p->forw;
  363.     return(p);
  364. }
  365.  
  366. char *
  367. alloc(n)
  368. register n;
  369. {
  370.     register char *p;
  371.  
  372.     n++;
  373.     n &= ~01;
  374.     if (lasta+n >= lastr) {
  375.         if (sbrk(2000) == (char *)-1) {
  376.             fprintf(stderr, "C Optimizer: out of space\n");
  377.             exit(1);
  378.         }
  379.         lastr += 2000;
  380.     }
  381.     p = lasta;
  382.     lasta += n;
  383.     return(p);
  384. }
  385.  
  386. clearreg()
  387. {
  388.     register int i;
  389.  
  390.     for (i=0; i<2*NREG; i++)
  391.         regs[i][0] = '\0';
  392.     conloc[0] = 0;
  393.     ccloc[0] = 0;
  394. }
  395.  
  396. savereg(ai, as)
  397. char *as;
  398. {
  399.     register char *p, *s, *sp;
  400.  
  401.     sp = p = regs[ai];
  402.     s = as;
  403.     if (source(s))
  404.         return;
  405.     while (*p++ = *s) {
  406.         if (s[0]=='(' && s[1]=='r' && s[2]<'5') {
  407.             *sp = 0;
  408.             return;
  409.         }
  410.         if (*s++ == ',')
  411.             break;
  412.     }
  413.     *--p = '\0';
  414. }
  415.  
  416. dest(as, flt)
  417. char *as;
  418. {
  419.     register char *s;
  420.     register int i;
  421.  
  422.     s = as;
  423.     source(s);
  424.     if ((i = isreg(s)) >= 0)
  425.         regs[i+flt][0] = 0;
  426.     for (i=0; i<NREG+NREG; i++)
  427.         if (*regs[i]=='*' && equstr(s, regs[i]+1))
  428.             regs[i][0] = 0;
  429.     while ((i = findrand(s, flt)) >= 0)
  430.         regs[i][0] = 0;
  431.     while (*s) {
  432.         if ((*s=='(' && (*(s+1)!='r' || *(s+2)!='5')) || *s++=='*') {
  433.             for (i=0; i<NREG+NREG; i++) {
  434.                 if (regs[i][0] != '$')
  435.                     regs[i][0] = 0;
  436.                 conloc[0] = 0;
  437.             }
  438.             return;
  439.         }
  440.     }
  441. }
  442.  
  443. singop(ap)
  444. struct node *ap;
  445. {
  446.     register char *p1, *p2;
  447.  
  448.     p1 = ap->code;
  449.     p2 = regs[RT1];
  450.     while (*p2++ = *p1++);
  451.     regs[RT2][0] = 0;
  452. }
  453.  
  454.  
  455. dualop(ap)
  456. struct node *ap;
  457. {
  458.     register char *p1, *p2;
  459.     register struct node *p;
  460.  
  461.     p = ap;
  462.     p1 = p->code;
  463.     p2 = regs[RT1];
  464.     while (*p1 && *p1!=',')
  465.         *p2++ = *p1++;
  466.     *p2++ = 0;
  467.     p2 = regs[RT2];
  468.     *p2 = 0;
  469.     if (*p1++ !=',')
  470.         return;
  471.     while (*p2++ = *p1++);
  472. }
  473.  
  474. findrand(as, flt)
  475. char *as;
  476. {
  477.     register int i;
  478.     for (i = flt; i<NREG+flt; i++) {
  479.         if (equstr(regs[i], as))
  480.             return(i);
  481.     }
  482.     return(-1);
  483. }
  484.  
  485. isreg(as)
  486. char *as;
  487. {
  488.     register char *s;
  489.  
  490.     s = as;
  491.     if (s[0]=='r' && s[1]>='0' && s[1]<='4' && s[2]==0)
  492.         return(s[1]-'0');
  493.     return(-1);
  494. }
  495.  
  496. check()
  497. {
  498.     register struct node *p, *lp;
  499.  
  500.     lp = &first;
  501.     for (p=first.forw; p!=0; p = p->forw) {
  502.         if (p->back != lp)
  503.             abort();
  504.         lp = p;
  505.     }
  506. }
  507.  
  508. source(ap)
  509. char *ap;
  510. {
  511.     register char *p1, *p2;
  512.  
  513.     p1 = ap;
  514.     p2 = p1;
  515.     if (*p1==0)
  516.         return(0);
  517.     while (*p2++);
  518.     if (*p1=='-' && *(p1+1)=='('
  519.      || *p1=='*' && *(p1+1)=='-' && *(p1+2)=='('
  520.      || *(p2-2)=='+') {
  521.         while (*p1 && *p1++!='r');
  522.         if (*p1>='0' && *p1<='4')
  523.             regs[*p1 - '0'][0] = 0;
  524.         return(1);
  525.     }
  526.     return(0);
  527. }
  528.  
  529. repladdr(p, f, flt)
  530. struct node *p;
  531. {
  532.     register r;
  533.     int r1;
  534.     register char *p1, *p2;
  535.     static char rt1[50], rt2[50];
  536.  
  537.     if (f)
  538.         r1 = findrand(regs[RT2], flt);
  539.     else
  540.         r1 = -1;
  541.     r = findrand(regs[RT1], flt);
  542.     if (r1 >= NREG)
  543.         r1 -= NREG;
  544.     if (r >= NREG)
  545.         r -= NREG;
  546.     if (r>=0 || r1>=0) {
  547.         p2 = regs[RT1];
  548.         for (p1 = rt1; *p1++ = *p2++;);
  549.         if (regs[RT2][0]) {
  550.             p1 = rt2;
  551.             *p1++ = ',';
  552.             for (p2 = regs[RT2]; *p1++ = *p2++;);
  553.         } else
  554.             rt2[0] = 0;
  555.         if (r>=0) {
  556.             rt1[0] = 'r';
  557.             rt1[1] = r + '0';
  558.             rt1[2] = 0;
  559.             nsaddr++;
  560.         }
  561.         if (r1>=0) {
  562.             rt2[1] = 'r';
  563.             rt2[2] = r1 + '0';
  564.             rt2[3] = 0;
  565.             nsaddr++;
  566.         }
  567.         p->code = copy(2, rt1, rt2);
  568.     }
  569. }
  570.  
  571. movedat()
  572. {
  573.     register struct node *p1, *p2;
  574.     struct node *p3;
  575.     register seg;
  576.     struct node data;
  577.     struct node *datp;
  578.  
  579.     if (first.forw == 0)
  580.         return;
  581.     if (lastseg != TEXT && lastseg != -1) {
  582.         p1 = (struct node *)alloc(sizeof(first));
  583.         p1->op = lastseg;
  584.         p1->subop = 0;
  585.         p1->code = NULL;
  586.         p1->forw = first.forw;
  587.         p1->back = &first;
  588.         first.forw->back = p1;
  589.         first.forw = p1;
  590.     }
  591.     datp = &data;
  592.     for (p1 = first.forw; p1!=0; p1 = p1->forw) {
  593.         if (p1->op == DATA) {
  594.             p2 = p1->forw;
  595.             while (p2 && p2->op!=TEXT)
  596.                 p2 = p2->forw;
  597.             if (p2==0)
  598.                 break;
  599.             p3 = p1->back;
  600.             p1->back->forw = p2->forw;
  601.             p2->forw->back = p3;
  602.             p2->forw = 0;
  603.             datp->forw = p1;
  604.             p1->back = datp;
  605.             p1 = p3;
  606.             datp = p2;
  607.         }
  608.     }
  609.     if (data.forw) {
  610.         datp->forw = first.forw;
  611.         first.forw->back = datp;
  612.         data.forw->back = &first;
  613.         first.forw = data.forw;
  614.     }
  615.     seg = lastseg;
  616.     for (p1 = first.forw; p1!=0; p1 = p1->forw) {
  617.         if (p1->op==TEXT||p1->op==DATA||p1->op==BSS) {
  618.             if (p2 = p1->forw) {
  619.                 if (p2->op==TEXT||p2->op==DATA||p2->op==BSS)
  620.                     p1->op  = p2->op;
  621.             }
  622.             if (p1->op == seg || p1->forw&&p1->forw->op==seg) {
  623.                 p1->back->forw = p1->forw;
  624.                 p1->forw->back = p1->back;
  625.                 p1 = p1->back;
  626.                 continue;
  627.             }
  628.             seg = p1->op;
  629.         }
  630.     }
  631. }
  632.  
  633. redunbr(p)
  634. register struct node *p;
  635. {
  636.     register struct node *p1;
  637.     register char *ap1;
  638.     char *ap2;
  639.  
  640.     if ((p1 = p->ref) == 0)
  641.         return;
  642.     p1 = nonlab(p1);
  643.     if (p1->op==TST) {
  644.         singop(p1);
  645.         savereg(RT2, "$0");
  646.     } else if (p1->op==CMP)
  647.         dualop(p1);
  648.     else
  649.         return;
  650.     if (p1->forw->op!=CBR)
  651.         return;
  652.     ap1 = findcon(RT1);
  653.     ap2 = findcon(RT2);
  654.     p1 = p1->forw;
  655.     if (compare(p1->subop, ap1, ap2)>0) {
  656.         nredunj++;
  657.         nchange++;
  658.         decref(p->ref);
  659.         p->ref = p1->ref;
  660.         p->labno = p1->labno;
  661.         p->ref->refc++;
  662.     }
  663. }
  664.  
  665. char *
  666. findcon(i)
  667. {
  668.     register char *p;
  669.     register r;
  670.  
  671.     p = regs[i];
  672.     if (*p=='$')
  673.         return(p);
  674.     if ((r = isreg(p)) >= 0)
  675.         return(regs[r]);
  676.     if (equstr(p, conloc))
  677.         return(conval);
  678.     return(p);
  679. }
  680.  
  681. compare(oper, cp1, cp2)
  682. register char *cp1, *cp2;
  683. {
  684.     register unsigned n1, n2;
  685.  
  686.     if (*cp1++ != '$' || *cp2++ != '$')
  687.         return(-1);
  688.     n1 = 0;
  689.     while (*cp2 >= '0' && *cp2 <= '7') {
  690.         n1 <<= 3;
  691.         n1 += *cp2++ - '0';
  692.     }
  693.     n2 = n1;
  694.     n1 = 0;
  695.     while (*cp1 >= '0' && *cp1 <= '7') {
  696.         n1 <<= 3;
  697.         n1 += *cp1++ - '0';
  698.     }
  699.     if (*cp1=='+')
  700.         cp1++;
  701.     if (*cp2=='+')
  702.         cp2++;
  703.     do {
  704.         if (*cp1++ != *cp2)
  705.             return(-1);
  706.     } while (*cp2++);
  707.     switch(oper) {
  708.  
  709.     case JEQ:
  710.         return(n1 == n2);
  711.     case JNE:
  712.         return(n1 != n2);
  713.     case JLE:
  714.         return((int)n1 <= (int)n2);
  715.     case JGE:
  716.         return((int)n1 >= (int)n2);
  717.     case JLT:
  718.         return((int)n1 < (int)n2);
  719.     case JGT:
  720.         return((int)n1 > (int)n2);
  721.     case JLO:
  722.         return(n1 < n2);
  723.     case JHI:
  724.         return(n1 > n2);
  725.     case JLOS:
  726.         return(n1 <= n2);
  727.     case JHIS:
  728.         return(n1 >= n2);
  729.     }
  730.     return(-1);
  731. }
  732.  
  733. setcon(ar1, ar2)
  734. char *ar1, *ar2;
  735. {
  736.     register char *cl, *cv, *p;
  737.  
  738.     cl = ar2;
  739.     cv = ar1;
  740.     if (*cv != '$')
  741.         return;
  742.     if (!natural(cl))
  743.         return;
  744.     p = conloc;
  745.     while (*p++ = *cl++);
  746.     p = conval;
  747.     while (*p++ = *cv++);
  748. }
  749.  
  750. equstr(ap1, ap2)
  751. char *ap1, *ap2;
  752. {
  753.     char *p1, *p2;
  754.  
  755.     p1 = ap1;
  756.     p2 = ap2;
  757.     do {
  758.         if (*p1++ != *p2)
  759.             return(0);
  760.     } while (*p2++);
  761.     return(1);
  762. }
  763.  
  764. setcc(ap)
  765. char *ap;
  766. {
  767.     register char *p, *p1;
  768.  
  769.     p = ap;
  770.     if (!natural(p)) {
  771.         ccloc[0] = 0;
  772.         return;
  773.     }
  774.     p1 = ccloc;
  775.     while (*p1++ = *p++);
  776. }
  777.  
  778. natural(ap)
  779. char *ap;
  780. {
  781.     register char *p;
  782.  
  783.     p = ap;
  784.     if (*p=='*' || *p=='(' || *p=='-'&&*(p+1)=='(')
  785.         return(0);
  786.     while (*p++);
  787.     p--;
  788.     if (*--p == '+' || *p ==')' && *--p != '5')
  789.         return(0);
  790.     return(1);
  791. }
  792.