home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / source / c / c21.c < prev    next >
Encoding:
C/C++ Source or Header  |  1975-07-18  |  9.5 KB  |  660 lines

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