home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 6 / FreshFish_September1994.bin / new / dev / c / hce / hcesource / top / source / peep3.c < prev    next >
C/C++ Source or Header  |  1992-09-02  |  13KB  |  553 lines

  1. /* Copyright (c) 1988,1991 by Sozobon, Limited.  Author: Tony Andrews
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  */
  11.  
  12. /*
  13.  * 3-instruction peephole optimizations
  14.  */
  15.  
  16. #include "top.h"
  17.  
  18.  
  19. /*
  20.  * ipeep3(bp, ip) - look for 3-instruction optimizations at the given inst.
  21.  */
  22. static bool
  23. ipeep3(bp, i1)
  24. register BLOCK    *bp;
  25. register INST    *i1;
  26. {
  27.     register INST    *i2 = i1->next;    /* the next instruction */
  28.     INST    *i3 = i1->next->next;    /* the third instruction */
  29.  
  30.     register int    op1 = i1->opcode;
  31.     register int    op2 = i2->opcode;
  32.     register int    op3 = i3->opcode;
  33.  
  34.     /*
  35.      *    move.l    Am, Dn        =>    lea    N(Am), Ao
  36.      *    add.l    #N, Dn
  37.      *    move.l    Dn, Ao
  38.      *
  39.      *    Also, Dn must be dead after the third instruction.
  40.      */
  41.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  42.         (i1->src.amode == REG) &&
  43.         ISA(i1->src.areg) &&
  44.         (i1->dst.amode == REG) &&
  45.         ISD(i1->dst.areg)) {
  46.  
  47.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  48.             (i2->flags & LENL) &&
  49.             (i2->src.amode == IMM) &&
  50.             DOK(i2->src.disp) &&
  51.             (i2->dst.amode == REG) &&
  52.             (i2->dst.areg == i1->dst.areg)) {
  53.  
  54.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  55.                 (i3->src.amode == REG) &&
  56.                 (i3->src.areg == i1->dst.areg) &&
  57.                 (i3->dst.amode == REG) &&
  58.                 ISA(i3->dst.areg) &&
  59.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  60.  
  61.                 /*
  62.                  * rewrite i1 and delete i2 and i3
  63.                  */
  64.                 i1->opcode = LEA;
  65.                 i1->flags = 0;
  66.                 i1->dst = i3->dst;
  67.  
  68.                 i1->src.amode = REGID;
  69.                 i1->src.disp = i2->src.disp;
  70.  
  71.                     delinst(bp, i2);
  72.                     delinst(bp, i3);
  73.                     DBG(printf("%d ", __LINE__))
  74.                     return TRUE;
  75.             }
  76.         }
  77.     }
  78.  
  79.     /*
  80.      *    move.l    Dm, Dn        =>    move.l    Dm, Ao
  81.      *    add.l    #N, Dn            lea    N(Ao), Ao
  82.      *    move.l    Dn, Ao
  83.      *
  84.      *    Also, Dn must be dead after the third instruction.
  85.      */
  86.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  87.         (i1->src.amode == REG) &&
  88.         ISD(i1->src.areg) &&
  89.         (i1->dst.amode == REG) &&
  90.         ISD(i1->dst.areg)) {
  91.  
  92.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  93.             (i2->flags & LENL) &&
  94.             (i2->src.amode == IMM) &&
  95.             DOK(i2->src.disp) &&
  96.             (i2->dst.amode == REG) &&
  97.             (i2->dst.areg == i1->dst.areg)) {
  98.  
  99.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  100.                 (i3->src.amode == REG) &&
  101.                 (i3->src.areg == i1->dst.areg) &&
  102.                 (i3->dst.amode == REG) &&
  103.                 ISA(i3->dst.areg) &&
  104.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  105.  
  106.                 /*
  107.                  * rewrite i1 and i2 and delete i3
  108.                  */
  109.                 i1->dst.areg = i3->dst.areg;
  110.                 
  111.                 i2->opcode = LEA;
  112.                 i2->flags = 0;
  113.                 i2->dst = i3->dst;
  114.  
  115.                 i2->src.amode = REGID;
  116.                 i2->src.areg = i2->dst.areg;
  117.                 i2->src.disp = i2->src.disp;
  118.  
  119.                     delinst(bp, i3);
  120.                     DBG(printf("%d ", __LINE__))
  121.                     return TRUE;
  122.             }
  123.         }
  124.     }
  125.  
  126.     /*
  127.      *    move.l    Am, Dn        =>    lea    -N(Am), Ao
  128.      *    sub.l    #N, Dn
  129.      *    move.l    Dn, Ao
  130.      *
  131.      *    Also, Dn must be dead after the third instruction.
  132.      */
  133.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  134.         (i1->src.amode == REG) &&
  135.         ISA(i1->src.areg) &&
  136.         (i1->dst.amode == REG) &&
  137.         ISD(i1->dst.areg)) {
  138.  
  139.         if (((op2 == SUB) || (op2 == ADDQ)) &&
  140.             (i2->flags & LENL) &&
  141.             (i2->src.amode == IMM) &&
  142.             DOK(i2->src.disp) &&
  143.             (i2->dst.amode == REG) &&
  144.             (i2->dst.areg == i1->dst.areg)) {
  145.  
  146.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  147.                 (i3->src.amode == REG) &&
  148.                 (i3->src.areg == i1->dst.areg) &&
  149.                 (i3->dst.amode == REG) &&
  150.                 ISA(i3->dst.areg) &&
  151.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  152.  
  153.                 /*
  154.                  * rewrite i1 and delete i2 and i3
  155.                  */
  156.                 i1->opcode = LEA;
  157.                 i1->flags = 0;
  158.                 i1->dst = i3->dst;
  159.  
  160.                 i1->src.amode = REGID;
  161.                 i1->src.disp = -i2->src.disp;
  162.  
  163.                     delinst(bp, i2);
  164.                     delinst(bp, i3);
  165.                     DBG(printf("%d ", __LINE__))
  166.                     return TRUE;
  167.             }
  168.         }
  169.     }
  170.  
  171.     /*
  172.      *    move.l    Am, Dn        =>    lea    0(Am, Do), Ap
  173.      *    add.x    Do, Dn
  174.      *    move.l    Dn, Ap
  175.      *
  176.      *    The second instruction can be either a word or long add.
  177.      *    Also, Dn must be dead after the third instruction.
  178.      */
  179.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  180.         (i1->src.amode == REG) &&
  181.         ISA(i1->src.areg) &&
  182.         (i1->dst.amode == REG) &&
  183.         ISD(i1->dst.areg)) {
  184.  
  185.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  186.             (i2->flags & (LENL|LENW)) &&
  187.             (i2->src.amode == REG) &&
  188.             ISD(i2->src.areg) && (i1->dst.areg != i2->src.areg) &&
  189.             (i2->dst.amode == REG) &&
  190.             (i2->dst.areg == i1->dst.areg)) {
  191.  
  192.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  193.                 (i3->src.amode == REG) &&
  194.                 (i3->src.areg == i1->dst.areg) &&
  195.                 (i3->dst.amode == REG) &&
  196.                 ISA(i3->dst.areg) &&
  197.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  198.  
  199.                 /*
  200.                  * rewrite i1 and delete i2 and i3
  201.                  */
  202.                 i1->opcode = LEA;
  203.                 i1->flags = 0;
  204.                 i1->dst = i3->dst;
  205.  
  206.                 i1->src.amode = REGIDX;
  207.                 if (i2->flags & LENL)
  208.                     i1->src.amode |= XLONG;
  209.                 i1->src.ireg = i2->src.areg;
  210.                 i1->src.disp = 0;
  211.  
  212.                     delinst(bp, i2);
  213.                     delinst(bp, i3);
  214.                     DBG(printf("%d ", __LINE__))
  215.                     return TRUE;
  216.             }
  217.         }
  218.     }
  219.  
  220.     /*
  221.      *    move.l    X(Am), Dn    =>    move.l    X(Am), Ao
  222.      *    add.l    #N, Dn
  223.      *    move.l    Dn, Ao            lea    N(Ao), Ao
  224.      *
  225.      *    Also, Dn must be dead after the third instruction.
  226.      */
  227.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  228.         (i1->src.amode == REGI || i1->src.amode == REGID) &&
  229.         (i1->dst.amode == REG) &&
  230.         ISD(i1->dst.areg)) {
  231.  
  232.         if (((op2 == ADD) || (op2 == ADDQ)) &&
  233.             (i2->flags & LENL) &&
  234.             (i2->src.amode == IMM) &&
  235.             DOK(i2->src.disp) &&
  236.             (i2->dst.amode == REG) &&
  237.             (i2->dst.areg == i1->dst.areg)) {
  238.  
  239.             if ((op3 == MOVE) && (i3->flags & LENL) &&
  240.                 (i3->src.amode == REG) &&
  241.                 (i3->src.areg == i1->dst.areg) &&
  242.                 (i3->dst.amode == REG) &&
  243.                 ISA(i3->dst.areg) &&
  244.                 ((i3->live & RM(i3->src.areg)) == 0)) {
  245.  
  246.                 /*
  247.                  * rewrite i1 and i3 and delete i2
  248.                  */
  249.                 i1->dst = i3->dst;
  250.  
  251.                 i3->opcode = LEA;
  252.                 i3->flags = 0;
  253.                 i3->src.amode = REGID;
  254.                 i3->src.areg = i3->dst.areg;
  255.                 i3->src.disp = i2->src.disp;
  256.  
  257.                     delinst(bp, i2);
  258.                     DBG(printf("%d ", __LINE__))
  259.                     return TRUE;
  260.             }
  261.         }
  262.     }
  263.  
  264.     /*
  265.      *    move.x    X, Dn        =>    move.x    X, Do
  266.      *    ext.y    Dn            ext.y    Do
  267.      *    move.y    Dn, Do
  268.      *
  269.      *    Where Dn is dead.
  270.      */
  271.     if ((op1 == MOVE)&&(op2 == EXT)&&(op3 == MOVE)&&
  272.         (i1->dst.amode == REG) && ISD(i1->dst.areg) &&
  273.         (i2->src.amode == REG) && (i3->src.amode == REG) &&
  274.         (i3->dst.amode == REG) && ISD(i3->dst.areg) &&
  275.         (i1->dst.areg == i2->src.areg) && (i1->dst.areg == i3->src.areg) &&
  276.         (i2->flags == i3->flags)) {
  277.  
  278.         if ((i3->live & RM(i3->src.areg)) == 0) {
  279.             i1->dst.areg = i3->dst.areg;
  280.             i2->src.areg = i3->dst.areg;
  281.  
  282.                 delinst(bp, i3);
  283.                 DBG(printf("%d ", __LINE__))
  284.                 return TRUE;
  285.         }
  286.     }
  287.  
  288.     /*
  289.      *    move.l    X, Dm        =>    move.l    X, An
  290.      *    INST                INST
  291.      *    move.l    Dm, An            ...deleted...
  292.      *
  293.      *    where INST doesn't modify Dm, and Dm is dead after i3
  294.      */
  295.     if ((op1 == MOVE) && (op3 == MOVE) &&
  296.         (i1->dst.amode == REG) && ISD(i1->dst.areg) &&
  297.         (i3->src.amode == REG) && (i1->dst.areg == i3->src.areg) &&
  298.         (i3->dst.amode == REG) && ISA(i3->dst.areg) &&
  299.  
  300. /* ADDED BY TETISOFT
  301.  * Avoid move.l (a0),d0 => move.l (a0),a0
  302.  *     addq.l #1,(a0)    addq.l #1,(a0)
  303.  *     move.l d0,a0
  304.  */        !((i1->src.amode == REGI) && (uses(i2, i1->src.areg)) &&
  305.                      (i1->src.areg == i3->dst.areg)) &&
  306.  
  307.         !uses(i2, i3->src.areg)) {
  308.  
  309.         if ((i3->live & i3->src.areg) == 0) {
  310.             i1->dst.areg = i3->dst.areg;
  311.             delinst(bp, i3);
  312.  
  313.                 DBG(printf("%d ", __LINE__))
  314.             return TRUE;
  315.         }
  316.     }
  317.  
  318.     /*
  319.      *    move.l    Am, An            ...deleted...
  320.      *    addq.l    #1, Am            ...deleted...
  321.      *    ... stuff ...            ... stuff ...
  322.      *    ???.b    ..(An)..    =>    ???.b    ..(Am)+..
  323.      *
  324.      *    An must be dead after the last instruction. Nothing in
  325.      *    "stuff" can modify Am.
  326.      */
  327.     if ((op1 == MOVE) && (i1->flags & LENL) &&
  328.         (i1->src.amode == REG) && ISA(i1->src.areg) &&
  329.         (i1->dst.amode == REG) && ISA(i1->dst.areg)) {
  330.  
  331.         int    rm = i1->src.areg;
  332.         int    rn = i