home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / language / sozobon2 / peep3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-23  |  12.6 KB  |  546 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Tony Andrews
  2.  * Patched -- PvO -- see file patch *
  3.  *
  4.  * Permission is granted to anyone to use this software for any purpose
  5.  * on any computer system, and to redistribute it freely, with the
  6.  * following restrictions:
  7.  * 1) No charge may be made other than reasonable charges for reproduction.
  8.  * 2) Modified versions must be clearly marked as such.
  9.  * 3) The authors are not responsible for any harmful consequences
  10.  *    of using this software, even if they result from defects in it.
  11.  */
  12.  
  13. /*
  14.  * 3-instruction peephole optimizations
  15.  */
  16.  
  17. #include "top.h"
  18.  
  19.  
  20. /*
  21.  * ipeep3(bp, ip) - look for 3-instruction optimizations at the given inst.
  22.  */
  23. static bool
  24. ipeep3(bp, i1)
  25. register BLOCK    *bp;
  26. register INST    *i1;
  27. {
  28.     register INST    *i2 = i1->next;    /* the next instruction */
  29.     INST    *i3 = i1->next->next;    /* the third instruction */
  30.  
  31.     register int    op1 = i1->opcode;
  32.     register int    op2 = i2->opcode;
  33.     register int    op3 = i3->opcode;
  34.  
  35.     /*
  36.      *    move.l    Am, Dn        =>    lea    N(Am), Ao
  37.      *    add.l    #N, Dn
  38.      *    move.l    Dn, Ao
  39.      *
  40.      *    Also, Dn must be dead after the third instruction.
  41.      */
  42.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  43.         (i1->src.amode == REG) &&
  44.         ISA(i1->src.areg) &&
  45.         (i1->dst.amode == REG) &&
  46.         ISD(i1->dst.areg)) {
  47.  
  48.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  49.             (i2->flags & LENL) &&
  50.             (i2->src.amode == IMM) &&
  51.             DOK(i2->src.disp) &&
  52.             (i2->dst.amode == REG) &&
  53.             (i2->dst.areg == i1->dst.areg)) {
  54.  
  55.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  56.                 (i3->src.amode == REG) &&
  57.                 (i3->src.areg == i1->dst.areg) &&
  58.                 (i3->dst.amode == REG) &&
  59.                 ISA(i3->dst.areg) &&
  60.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  61.  
  62.                 /*
  63.                  * rewrite i1 and delete i2 and i3
  64.                  */
  65.                 i1->opcode = LEA;
  66.                 i1->flags = 0;
  67.                 i1->dst = i3->dst;
  68.  
  69.                 i1->src.amode = REGID;
  70.                 i1->src.disp = i2->src.disp;
  71.  
  72.                     delinst(bp, i2);
  73.                     delinst(bp, i3);
  74.                     DBG(printf("%d ", __LINE__))
  75.                     return TRUE;
  76.             }
  77.         }
  78.     }
  79.  
  80.     /*
  81.      *    move.l    Dm, Dn        =>    move.l    Dm, Ao
  82.      *    add.l    #N, Dn            lea    N(Ao), Ao
  83.      *    move.l    Dn, Ao
  84.      *
  85.      *    Also, Dn must be dead after the third instruction.
  86.      */
  87.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  88.         (i1->src.amode == REG) &&
  89.         ISD(i1->src.areg) &&
  90.         (i1->dst.amode == REG) &&
  91.         ISD(i1->dst.areg)) {
  92.  
  93.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  94.             (i2->flags & LENL) &&
  95.             (i2->src.amode == IMM) &&
  96.             DOK(i2->src.disp) &&
  97.             (i2->dst.amode == REG) &&
  98.             (i2->dst.areg == i1->dst.areg)) {
  99.  
  100.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  101.                 (i3->src.amode == REG) &&
  102.                 (i3->src.areg == i1->dst.areg) &&
  103.                 (i3->dst.amode == REG) &&
  104.                 ISA(i3->dst.areg) &&
  105.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  106.  
  107.                 /*
  108.                  * rewrite i1 and i2 and delete i3
  109.                  */
  110.                 i1->dst.areg = i3->dst.areg;
  111.                 
  112.                 i2->opcode = LEA;
  113.                 i2->flags = 0;
  114.                 i2->dst = i3->dst;
  115.  
  116.                 i2->src.amode = REGID;
  117.                 i2->src.areg = i2->dst.areg;
  118.                 i2->src.disp = i2->src.disp;
  119.  
  120.                     delinst(bp, i3);
  121.                     DBG(printf("%d ", __LINE__))
  122.                     return TRUE;
  123.             }
  124.         }
  125.     }
  126.  
  127.     /*
  128.      *    move.l    Am, Dn        =>    lea    -N(Am), Ao
  129.      *    sub.l    #N, Dn
  130.      *    move.l    Dn, Ao
  131.      *
  132.      *    Also, Dn must be dead after the third instruction.
  133.      */
  134.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  135.         (i1->src.amode == REG) &&
  136.         ISA(i1->src.areg) &&
  137.         (i1->dst.amode == REG) &&
  138.         ISD(i1->dst.areg)) {
  139.  
  140.         if (((op2 == SUB) || (op2 == ADDQ)) &&
  141.             (i2->flags & LENL) &&
  142.             (i2->src.amode == IMM) &&
  143.             DOK(i2->src.disp) &&
  144.             (i2->dst.amode == REG) &&
  145.             (i2->dst.areg == i1->dst.areg)) {
  146.  
  147.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  148.                 (i3->src.amode == REG) &&
  149.                 (i3->src.areg == i1->dst.areg) &&
  150.                 (i3->dst.amode == REG) &&
  151.                 ISA(i3->dst.areg) &&
  152.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  153.  
  154.                 /*
  155.                  * rewrite i1 and delete i2 and i3
  156.                  */
  157.                 i1->opcode = LEA;
  158.                 i1->flags = 0;
  159.                 i1->dst = i3->dst;
  160.  
  161.                 i1->src.amode = REGID;
  162.                 i1->src.disp = -i2->src.disp;
  163.  
  164.                     delinst(bp, i2);
  165.                     delinst(bp, i3);
  166.                     DBG(printf("%d ", __LINE__))
  167.                     return TRUE;
  168.             }
  169.         }
  170.     }
  171.  
  172.     /*
  173.      *    move.l    Am, Dn        =>    lea    0(Am, Do), Ap
  174.      *    add.x    Do, Dn
  175.      *    move.l    Dn, Ap
  176.      *
  177.      *    The second instruction can be either a word or long add.
  178.      *    Also, Dn must be dead after the third instruction.
  179.      */
  180.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  181.         (i1->src.amode == REG) &&
  182.         ISA(i1->src.areg) &&
  183.         (i1->dst.amode == REG) &&
  184.         ISD(i1->dst.areg)) {
  185.  
  186.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  187.             (i2->flags & (LENL|LENW)) &&
  188.             (i2->src.amode == REG) &&
  189.             ISD(i2->src.areg) && (i1->dst.areg != i2->src.areg) &&
  190.             (i2->dst.amode == REG) &&
  191.             (i2->dst.areg == i1->dst.areg)) {
  192.  
  193.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  194.                 (i3->src.amode == REG) &&
  195.                 (i3->src.areg == i1->dst.areg) &&
  196.                 (i3->dst.amode == REG) &&
  197.                 ISA(i3->dst.areg) &&
  198.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  199.  
  200.                 /*
  201.                  * rewrite i1 and delete i2 and i3
  202.                  */
  203.                 i1->opcode = LEA;
  204.                 i1->flags = 0;
  205.                 i1->dst = i3->dst;
  206.  
  207.                 i1->src.amode = REGIDX;
  208.                 if (i2->flags & LENL)
  209.                     i1->src.amode |= XLONG;
  210.                 i1->src.ireg = i2->src.areg;
  211.                 i1->src.disp = 0;
  212.  
  213.                     delinst(bp, i2);
  214.                     delinst(bp, i3);
  215.                     DBG(printf("%d ", __LINE__))
  216.                     return TRUE;
  217.             }
  218.         }
  219.     }
  220.  
  221.     /*
  222.      *    move.l    X(Am), Dn    =>    move.l    X(Am), Ao
  223.      *    add.l    #N, Dn
  224.      *    move.l    Dn, Ao            lea    N(Ao), Ao
  225.      *
  226.      *    Also, Dn must be dead after the third instruction.
  227.      */
  228.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  229.         (i1->src.amode == REGI || i1->src.amode == REGID) &&
  230.         (i1->dst.amode == REG) &&
  231.         ISD(i1->dst.areg)) {
  232.  
  233.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  234.             (i2->flags & LENL) &&
  235.             (i2->src.amode == IMM) &&
  236.             DOK(i2->src.disp) &&
  237.             (i2->dst.amode == REG) &&
  238.             (i2->dst.areg == i1->dst.areg)) {
  239.  
  240.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  241.                 (i3->src.amode == REG) &&
  242.                 (i3->src.areg == i1->dst.areg) &&
  243.                 (i3->dst.amode == REG) &&
  244.                 ISA(i3->dst.areg) &&
  245.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  246.  
  247.                 /*
  248.                  * rewrite i1 and i3 and delete i2
  249.                  */
  250.                 i1->dst = i3->dst;
  251.  
  252.                 i3->opcode = LEA;
  253.                 i3->flags = 0;
  254.                 i3->src.amode = REGID;
  255.                 i3->src.areg = i3->dst.areg;
  256.                 i3->src.disp = i2->src.disp;
  257.  
  258.                     delinst(bp, i2);
  259.                     DBG(printf("%d ", __LINE__))
  260.                     return TRUE;
  261.             }
  262.         }
  263.     }
  264.  
  265.     /*
  266.      *    move.x    X, Dn        =>    move.x    X, Do
  267.      *    ext.y    Dn            ext.y    Do
  268.      *    move.y    Dn, Do
  269.      *
  270.      *    Where Dn is dead.
  271.      */
  272.     if ((op1 == MOVE)&&(op2 == EXT)&&(op3 == MOVE)&&
  273.         (i1->dst.amode == REG) && ISD(i1->dst.areg) &&
  274.         (i2->src.amode == REG) && (i3->src.amode == REG) &&
  275.         (i3->dst.amode == REG) && ISD(i3->dst.areg) &&
  276.         (i1->dst.areg == i2->src.areg) && (i1->dst.areg == i3->src.areg) &&
  277.         (i2->flags == i3->flags)) {
  278.  
  279.         if ((i3->live & RM(i3->src.areg)) == 0) {
  280.             i1->dst.areg = i3->dst.areg;
  281.             i2->src.areg = i3->dst.areg;
  282.  
  283.                 delinst(bp, i3);
  284.                 DBG(printf("%d ", __LINE__))
  285.                 return TRUE;
  286.         }
  287.     }
  288.  
  289.     /*
  290.      *    move.l    X, Dm        =>    move.l    X, An
  291.      *    INST                INST
  292.      *    move.l    Dm, An            ...deleted...
  293.      *
  294.      *    where INST doesn't modify Dm, and Dm is dead after i3
  295.      */
  296.     if ((op1 == MOVE) && (op3 == MOVE) &&
  297.         (i1->dst.amode == REG) && ISD(i1->dst.areg) &&
  298.         (i3->src.amode == REG) && (i1->dst.areg == i3->src.areg) &&
  299.         (i3->dst.amode == REG) && ISA(i3->dst.areg) &&
  300.         !uses(i2, i3->src.areg) && !uses(i2, i3->dst.areg)) {
  301.  
  302.         if ((i3->live & RM(i3->src.areg)) == 0) {
  303.             i1->dst.areg = i3->dst.areg;
  304.             delinst(bp, i3);
  305.  
  306.                 DBG(printf("%d ", __LINE__))
  307.             return TRUE;
  308.         }
  309.     }
  310.  
  311.     /*
  312.      *    move.l    Am, An            ...deleted...
  313.      *    addq.l    #1, Am            ...deleted...
  314.      *    ... stuff ...            ... stuff ...
  315.      *    ???.b    ..(An)..    =>    ???.b    ..(Am)+..
  316.      *
  317.      *    An must be dead after the last instruction. Nothing in
  318.      *    "stuff" can modify Am.
  319.      */
  320.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  321.         (i1->src.amode == REG) && ISA(i1->src.areg) &&
  322.         (i1->dst.amode == REG) && ISA(i1->dst.areg)) {
  323.  
  324.         int    rm = i1->src.areg;
  325.         int    rn = i1->dst.areg;
  326.  
  327.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  328.             (i2->flags & LENL) &&
  329.             (i2->src.amode == IMM) && (i2->src.disp == 1) &&
  330.             (i2->dst.amode == REG) &&
  331.             (i2->dst.areg == rm)) {
  332.  
  333.             while (i3 != NULL) {
  334.                 if (sets(i3, rm))
  335.                     goto end7;
  336.  
  337.                 if (i3->src.amode==REGI && i3->src.areg==rn) {
  338.                     if (i3->live & RM(rn))
  339.                         goto end7;
  340.  
  341.                     if ((i3->flags & LENB) == 0)
  342.                         goto end7;
  343.  
  344.                     i3->src.amode |= INC;
  345.                     i3->src.areg = rm;
  346.  
  347.                         delinst(bp, i1);
  348.                         delinst(bp, i2);
  349.                         DBG(printf("%d ", __LINE__))
  350.                         return TRUE;
  351.                 }
  352.                 if (i3->dst.amode==REGI && i3->dst.areg==rn) {
  353.                     if (i3->live & RM(rn))
  354.                         goto end7;
  355.  
  356.                     if ((i3->flags & LENB) == 0)
  357.                         goto end7;
  358.  
  359.                     i3->dst.amode |= INC;
  360.                     i3->dst.areg = rm;
  361.  
  362.                         delinst(bp, i1);
  363.                         delinst(bp, i2);
  364.                         DBG(printf("%d ", __LINE__))
  365.                         return TRUE;
  366.                 }
  367.  
  368.                 if (i3->next == NULL)
  369.                     goto end7;
  370.                 else
  371.                     i3 = i3->next;
  372.  
  373.             }
  374.         }
  375.     }
  376. end7:
  377.  
  378.     /*
  379.      *    move.l    Am, An
  380.      *    addq.l    #2, Am
  381.      *    ... stuff ...
  382.      *    ???.w    ..(An)..    =>    ???.w    ..(Am)+..
  383.      *
  384.      *    An must be dead after the last instruction. Nothing in
  385.      *    "stuff" can modify Am.
  386.      */
  387.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  388.         (i1->src.amode == REG) && ISA(i1->src.areg) &&
  389.         (i1->dst.amode == REG) && ISA(i1->dst.areg)) {
  390.  
  391.         int    rm = i1->src.areg;
  392.         int    rn = i1->dst.areg;
  393.  
  394.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  395.             (i2->flags & LENL) &&
  396.             (i2->src.amode == IMM) && (i2->src.disp == 2) &&
  397.             (i2->dst.amode == REG) &&
  398.             (i2->dst.areg == rm)) {
  399.  
  400.             while (i3 != NULL) {
  401.                 if (sets(i3, rm))
  402.                     goto end9;
  403.  
  404.                 if (i3->src.amode==REGI && i3->src.areg==rn) {
  405.                     if (i3->live & RM(rn))
  406.                         goto end9;
  407.  
  408.                     if ((i3->flags & LENW) == 0)
  409.                         goto end9;
  410.  
  411.                     i3->src.amode |= INC;
  412.                     i3->src.areg = rm;
  413.  
  414.                         delinst(bp, i1);
  415.                         delinst(bp, i2);
  416.                         DBG(printf("%d ", __LINE__))
  417.                         return TRUE;
  418.                 }
  419.                 if (i3->dst.amode==REGI && i3->dst.areg==rn) {
  420.                     if (i3->live & RM(rn))
  421.                         goto end9;
  422.  
  423.                     if ((i3->flags & LENW) == 0)
  424.                         goto end9;
  425.  
  426.                     i3->dst.amode |= INC;
  427.                     i3->dst.areg = rm;
  428.  
  429.                         delinst(bp, i1);
  430.                         delinst(bp, i2);
  431.                         DBG(printf("%d ", __LINE__))
  432.                         return TRUE;
  433.                 }
  434.  
  435.                 if (i3->next == NULL)
  436.                     goto end9;
  437.                 else
  438.                     i3 = i3->next;
  439.  
  440.             }
  441.         }
  442.     }
  443. end9:
  444.  
  445.     /*
  446.      *    move.l    Am, An
  447.      *    addq.l    #4, Am
  448.      *    ... stuff ...
  449.      *    ???.l    ..(An)..    =>    ???.l    ..(Am)+..
  450.      *
  451.      *    An must be dead after the last instruction. Nothing in
  452.      *    "stuff" can modify Am.
  453.      */
  454.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  455.         (i1->src.amode == REG) && ISA(i1->src.areg) &&
  456.         (i1->dst.amode == REG) && ISA(i1->dst.areg)) {
  457.  
  458.         int    rm = i1->src.areg;
  459.         int    rn = i1->dst.areg;
  460.  
  461.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  462.             (i2->flags & LENL) &&
  463.             (i2->src.amode == IMM) && (i2->src.disp == 4) &&
  464.             (i2->dst.amode == REG) &&
  465.             (i2->dst.areg == rm)) {
  466.  
  467.             while (i3 != NULL) {
  468.                 if (sets(i3, rm))
  469.                     goto end11;
  470.  
  471.                 if (i3->src.amode==REGI && i3->src.areg==rn) {
  472.                     if (i3->live & RM(rn))
  473.                         goto end11;
  474.  
  475.                     if ((i3->flags & LENL) == 0)
  476.                         goto end11;
  477.  
  478.                     i3->src.amode |= INC;
  479.                     i3->src.areg = rm;
  480.  
  481.                         delinst(bp, i1);
  482.                         delinst(bp, i2);
  483.                         DBG(printf("%d ", __LINE__))
  484.                         return TRUE;
  485.                 }
  486.                 if (i3->dst.amode==REGI && i3->dst.areg==rn) {
  487.                     if (i3->live & RM(rn))
  488.                         goto end11;
  489.  
  490.                     if ((i3->flags & LENL) == 0)
  491.                         goto end11;
  492.  
  493.                     i3->dst.amode |= INC;
  494.                     i3->dst.areg = rm;
  495.  
  496.                         delinst(bp, i1);
  497.                         delinst(bp, i2);
  498.                         DBG(printf("%d ", __LINE__))
  499.                         return TRUE;
  500.                 }
  501.  
  502.                 if (i3->next == NULL)
  503.                     goto end11;
  504.                 else
  505.                     i3 = i3->next;
  506.  
  507.             }
  508.         }
  509.     }
  510. end11:
  511.  
  512.     return FALSE;
  513. }
  514.  
  515. /*
  516.  * peep3(bp) - scan blocks starting at 'bp'
  517.  */
  518. bool
  519. peep3(bp)
  520. register BLOCK    *bp;
  521. {
  522.     register INST    *ip;
  523.     register bool    changed = FALSE;
  524.  
  525.     DBG(printf("p3: "))
  526.     for (; bp != NULL ;bp = bp->next) {
  527.         ip = bp->first;
  528.         while (ip!=NULL && ip->next != NULL && ip->next->next != NULL) {
  529.             if (ipeep3(bp, ip)) {
  530.                 s_peep3++;
  531.                 bprep(bp);
  532.                 changed = TRUE;
  533.                 /*
  534.                  * If we had a match, then any instruction
  535.                  * could have been deleted, so the safe thing
  536.                  * to do is to go to the next block.
  537.                  */
  538.                 break;
  539.             } else
  540.                 ip = ip->next;
  541.         }
  542.     }
  543.     DBG(printf("\n"); fflush(stdout))
  544.     return changed;
  545. }
  546.