* src/SDCCcse.c (algebraicOpts): fixed bug 1579949
[fw/sdcc] / src / z80 / peeph-z80.def
index 63c89a44e18ccf4087ba132d937af645417b868b..bb740d2a5a4e0db04d5bb2db8d18f6204097b352 100644 (file)
+// peeph-z80.def - Z80 peephole rules
+//
+//
+// (c) Philipp Klaus Krause (pkk@spth.de, philipp@colecovision.eu) 2006 - 2007
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// This can't go into peeph.def since %1 could be (hl+) on gbz80.
 replace restart {
-       ld      a,%1(%2)
-       bit     %3,a
-       jp      %4,%5
+       ld      %1,%3
+       ld      %1,%2
 } by {
-       bit     %3,%1(%2)
-       jp      %4,%5
+       ; peephole z0 removed dead load into %1
+       ld      %1,%2
+} if notVolatile(%1 %3), operandsNotSame
+
+replace restart {
+       ld      %1,#%2
+       ld      a,0(%1)
+       ld      %3,a
+       ld      %1,#%5
+} by {
+       ld      a,(#%2)
+       ; peephole z1 used #%2 directly instead of going through %1 using indirect addressing.
+       ld      %3,a
+       ld      %1,#%5
 }
-replace {
-       ld      %1,%2)
-       ld      a,%2)
+
+replace restart {
+       ld      %1,#%2
+       ld      0(%1),a
+%4:
+       ld      %1,%5
 } by {
-        ld      %1,%2)
-        ld      a,%1
+       ld      (#%2),a
+       ; peephole z2 directly used #%2 instead of going through %1 using indirect addressing.
+%4:
+       ld      %1,%5
 }
-replace {
-       ld      %1),a
-       xor     a,a
-       or      a,%1)
-       jp      z,%2
+
+replace restart {
+       pop     af
+       ld      %1,#%2
+       ld      0(%1),%3
+       ld      %1,#%4
 } by {
-        ld      %1),a
-        or      a,a
-       jp      z,%2
+       ld      a,%3
+       ld      (#%2),a
+       ; peephole z3 used #%2 directly instead of going through %1 using indirect addressing.
+       pop     af
+       ld      %1,#%4
+} if operandsNotRelated(%3 'a')
+
+replace restart {
+       ld      bc,#%1 + %2
+       ld      a,%3
+       ld      (bc),a
+       ld      bc,#%4 + %5
+} by {
+       ld      a,%3
+       ld      (#%1 + %2),a
+       ; peephole z4 directly used address #%1 + %2 instead of placing it in bc first.
+       ld      bc,#%4 + %5
 }
-replace {
-       rlca
-       ld      a,#0x00
-       rla
+
+replace restart {
+       ld      bc,#%1 + %2 + %6
+       ld      a,%3
+       ld      (bc),a
+       ld      bc,#%4 + %5
 } by {
-       rlca
-        and     a,#0x01
+       ld      a,%3
+       ld      (#%1 + %2 + %6),a
+       ; peephole z5 directly used address #%1 + %2 + %6 instead of placing it in bc first.
+       ld      bc,#%4 + %5
 }
-replace {
-       ld      %3,a
-       ld      l,%1)
-       ld      h,%2)
-       ld      l,(hl)
+
+replace restart {
+       ld      bc,#%1 + %2
        ld      a,%3
+       ld      (bc),a
+%7:
+       ld      bc,#%4 + %5
 } by {
-       ld      %3,a
-       ld      l,%1)
-       ld      h,%2)
-       ld      l,(hl)
+       ld      a,%3
+       ld      (#%1 + %2),a
+       ; peephole z6 directly used address #%1 + %2 instead of placing it in bc first.
+%7:
+       ld      bc,#%4 + %5
 }
+
+replace restart {
+       ld      bc,#%1 + %2 + %6
+       ld      a,%3
+       ld      (bc),a
+%7:
+       ld      bc,#%4 + %5
+} by {
+       ld      a,%3
+       ld      (#%1 + %2 + %6),a
+       ; peephole z7 directly used address #%1 + %2 + %6 instead of placing it in bc first.
+%7:
+       ld      bc,#%4 + %5
+}
+
+replace restart {
+       ld      c,%1
+       ld      l,c
+       ret
+} by {
+       ld      l,%1
+       ; peephole z8 moved %1 directly into l instead of going through c.
+       ret
+}
+
+replace restart {
+       ld      b,h
+       ld      c,l
+       pop     af
+       push    bc
+       call    %1
+} by {
+       ex      (sp),hl
+       ; peephole z9 moved hl directly to the stack instead of going through bc.
+       call    %1
+}
+
+replace restart {
+       ld      d,h
+       ld      e,l
+       pop     af
+       push    de
+       call    %1
+} by {
+       ex      (sp),hl
+       ; peephole z10 moved hl directly to the stack instead of going through de.
+       call    %1
+}
+
+replace restart {
+       jp      %5
+} by {
+       ret
+       ; peephole z11 replaced jump by return.
+} if labelIsReturnOnly(), labelRefCountChange(%5 -1)
+
+replace restart {
+       jp      %1,%5
+} by {
+       ret     %1
+       ; peephole z11a replaced jump by return.
+} if labelIsReturnOnly(), labelRefCountChange(%5 -1)
+
+// Should be one of the last ones. Opens the code to further peephole optimization.
+replace restart {
+%1:
+} by {
+       ; peephole z12 removed unused label %1.
+} if labelRefCount(%1 0)
+
+// Applying z11 or z11a followed by z12 will often leave a dead ret at the end of the function. Remove it.
+replace {
+       jp      %5
+       ret
+} by {
+       jp      %5
+       ; peephole z13 removed unused ret.
+}
+
+// These should be the last rules, so that the peepholes above need to look at jp only.
+replace {
+       jp      %5
+} by {
+       jr      %5
+       ; peephole z14 changed absolute to relative unconditional jump.
+} if labelInRange()
+
+replace {
+       jp      Z,%5
+} by {
+       jr      Z,%5
+       ; peephole z15 changed absolute to relative conditional jump.
+} if labelInRange()
+
+replace {
+       jp      NZ,%5
+} by {
+       jr      NZ,%5
+       ; peephole z16 changed absolute to relative conditional jump.
+} if labelInRange()
+
+replace {
+       jp      C,%5
+} by {
+       jr      C,%5
+       ; peephole z17 changed absolute to relative conditional jump.
+} if labelInRange()
+
+replace {
+       jp      NC,%5
+} by {
+       jr      NC,%5
+       ; peephole z18 changed absolute to relative conditional jump.
+} if labelInRange()