Partially implemented RFE #2471534 and some other minor improvements
[fw/sdcc] / src / z80 / peeph-z80.def
index cd7f16749d58c1a92d60e294f65ce5f4731ec1b3..ef6e078f74b0babb811349510f063a1072f11787 100644 (file)
@@ -1,7 +1,9 @@
 // peeph.def - Common Z80 and gbz80 peephole rules
 //
+// These peepholes could be potentially moved to peeph.def, but a GBZ80 expert
+// Should have a look at them before.
 //
-// (c) Philipp Klaus Krause (pkk@spth.de, philipp@colecovision.eu) 2006 - 2007
+// (c) Philipp Klaus Krause (pkk@spth.de, philipp@colecovision.eu) 2006 - 2008
 //
 // 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
 replace restart {
        ld      %1,%1
 } by {
-       ; peephole 1 removed redundant load.
+       ; peephole -1 removed redundant load.
 } if notVolatile(%1)
 
+// This one doesn't work currently since the peephole optimizer can't match lines generated by multiline macros: Bug #1570701
+//replace restart {
+//     pop     af
+//     ld      sp,%1
+//} by {
+//     ; peephole -1a eleminated dead pop.
+//     ld      sp,%1
+//} if notUsed('a')
+
+replace restart {
+       ld      %1,%2
+} by {
+       ; peephole 0a removed dead load from %2 into %1.
+} if notVolatile(%1), notUsed(%1)
+// Should probably check for notVolatile(%2), too, but gives many false positives and no regression tests fail.
+
+replace restart {
+       ld      %1,%2
+       ld      a,%1
+} by {
+       ; peephole 0b loaded %2 into a directly instead of going through %1.
+       ld      a,%2
+} if notVolatile(%1), notUsed(%1)
+
+replace restart {
+       ld      %1,%2 (%3)
+       ld      a,%1
+} by {
+       ; peephole 0c loaded %2 (%3) into a directly instead of going through %1.
+       ld      a,%2 (%3)
+} if notVolatile(%1), notUsed(%1)
+
+replace restart {
+       ld      %1,#%2
+       ld      a,%3 (%1)
+} by {
+       ; peephole 0d loaded %2 into a directly instead of going through %1.
+       ld      a,(#%2+%3)
+} if notUsed(%1)
+
+replace restart {
+       srl     %1
+       ld      a,%1
+} by {
+       ld      a,%1
+       ; peephole 0e shifted in a instead of %1.
+       srl     a
+} if notVolatile(%1), notUsed(%1)
+
+replace restart {
+       ld      %1,(hl)
+       ld      a,%2 (%3)
+       sub     a,%1
+} by {
+       ld      a,%2 (%3)
+       ; peephole 0f used (hl) in sub directly instead of going through %1.
+       sub     a,(hl)
+} if notVolatile(%1), notUsed(%1)
+
+replace restart {
+       inc     bc
+       ld      l,c
+       ld      h,b
+} by {
+       ld      l,c
+       ld      h,b
+       ; peephole 0g incremented in hl instead of bc.
+       inc     hl
+} if notUsed('bc')
+
+// Catch double and triple incs before later peepholes introduce an ex de,hl in here.
+replace restart {
+       inc     de
+       inc     de
+       ld      l,e
+       ld      h,d
+} by {
+       ld      l,e
+       ld      h,d
+       ; peephole 0h' incremented in hl instead of de.
+       inc     hl
+       inc     hl
+} if notUsed('de')
+
+replace restart {
+       inc     de
+       ld      l,e
+       ld      h,d
+} by {
+       ld      l,e
+       ld      h,d
+       ; peephole 0h incremented in hl instead of de.
+       inc     hl
+} if notUsed('de')
+
+replace restart {
+       ld      e,%1
+       ld      d,%2
+       ld      l,e
+       ld      h,d
+} by {
+       ; peephole 0i loaded %2%1 into hl directly instead of going through de.
+       ld      l,%1
+       ld      h,%2
+} if notUsed('de')
+
+replace restart {
+       ld      bc,#%2 + %3
+       ld      a,(bc)
+       ld      c,a
+} by {
+       ; peephole 0j used hl for #%2 + %3 instead of bc, not going through a.
+       ld      hl,#%2 + %3
+       ld      c,(hl)
+} if notUsed('a'), notUsed('hl')
+
+replace restart {
+       ld      de,#%2 + %3
+       ld      a,(de)
+       ld      e,a
+} by {
+       ; peephole 0j' used hl for #%2 + %3 instead of de, not going through a.
+       ld      hl,#%2 + %3
+       ld      e,(hl)
+} if notUsed('a'), notUsed('hl')
+
+replace restart {
+       ex      de,hl
+       push    hl
+} by {
+       ; peephole 0k pushed de directly instead of going through hl.
+       push    de
+} if notUsed('de'), notUsed('hl')
+
+replace restart {
+       ex      de,hl
+       push    de
+} by {
+       ; peephole 0k' pushed hl directly instead of going through de.
+       push    hl
+} if notUsed('de'), notUsed('hl')
+
+replace restart {
+       ld      l,%1
+       ld      h,d
+       push    hl
+} by {
+       ; peephole 0k'' pushed de instead of hl removing a load.
+       ld      e,%1
+       push    de
+} if notUsed('hl'), notUsed('e')
+
+replace restart {
+       ex      de,hl
+       push    bc
+       push    de
+} by {
+       ; peephole 0l pushed hl directly instead of going through de.
+       push    bc
+       push    hl
+} if notUsed('de'), notUsed('hl')
+
+replace restart {
+       ld      l,c
+       ld      h,b
+       push    hl
+} by {
+       ; peephole 0m pushed bc directly instead of going through hl.
+       push    bc
+} if notUsed('hl')
+
+replace restart {
+       ld      l,%1
+       ld      h,b
+       push    hl
+} by {
+       ; peephole 0m' pushed bc instead of hl removing a load.
+       ld      c,%1
+       push    bc
+} if notUsed('hl'), notUsed('c')
+
+replace restart {
+       ld      c,a
+       push    de
+       ld      a,c
+} by {
+       ; peephole 0n removed redundant load of a through c.
+       push    de
+} if notUsed('c')
+
+replace restart {
+       ld      c,e
+       ld      b,d
+       ld      a,(bc)
+} by {
+       ; peephole 0o used de directly instead of going through bc.
+       ld      a,(de)
+} if notUsed('bc')
+
+replace restart {
+       pop     de
+       ld      l,e
+       ld      h,d
+} by {
+       ; peephole 0p popped hl directly instead of going through de.
+       pop     hl
+} if notUsed('de')
+
+replace restart {
+       ld      %1,a
+       ld      %2 (%3),%1
+} by {
+       ; peephole 0q loaded a into %2 (%3) directly instead of going through %1.
+       ld      %2 (%3),a
+} if notVolatile(%1), notUsed(%1)
+
+replace restart {
+       ld      %1 (ix),%2
+       ld      %3, %1 (ix)
+} by {
+       ; peephole 0r loaded %3 from %2 instead of going through %1 (ix).
+       ld      %1 (ix),%2
+       ld      %3, %2
+}
+// Don't need to check for volatile, since ix is used for the stack.
+
+replace restart {
+       ld      %1, %2 (%3)
+       ld      b, %1
+} by {
+       ; peephole 0s loaded b from %2 (%3) instead of going through %1.
+       ld      b, %2 (%3)
+} if notVolatile(%1), notUsed(%1)
+
+replace restart {
+       ld      %1,a
+       ld      %2,%3
+       ld      %4,%1
+} by {
+       ; peephole 0t loaded %4 from a instead of going through %1.
+       ld      %1,a
+       ld      %2,%3
+       ld      %4,a
+} if notVolatile(%1), operandsNotRelated(%1 %3), operandsNotRelated(%1 %2)
+
+replace restart {
+       ld      %1,a
+       ld      a,%2
+       adc     a,#%3
+       ld      %4,%1
+} by {
+       ld      %1,a
+       ; peephole 0t' loaded %4 from a instead of going through %1.
+       ld      %4,a
+       ld      a,%2
+       adc     a,#%3
+} if notVolatile(%1), operandsNotRelated(%1 %2), operandsNotRelated(%4 %2)
+
+replace restart {
+       ld      %1,a
+       ld      a,#%2
+       adc     a,#%3
+       ld      %4,%1
+} by {
+       ld      %1,a
+       ; peephole 0t'' loaded %4 from a instead of going through %1.
+       ld      %4,a
+       ld      a,#%2
+       adc     a,#%3
+} if notVolatile(%1)
+
+replace restart {
+       ld      %1,(hl)
+       ld      e,%1
+} by {
+       ; peephole 0u loaded e from (hl) instead of going through %1.
+       ld      e,(hl)
+} if notUsed(%1)
+
+replace restart {
+       ld      %1,l
+       ld      %2 (%3),%1
+} by { 
+       ; peephole 0v loaded %2 (%3) from l instead of going through %1.
+       ld      %2 (%3),l
+} if notUsed(%1)
+
+replace restart {
+       ld      l,%1 (ix)
+       ld      h,%2 (ix)
+       ld      %3,(hl)
+       srl     %3
+       ld      l,%1 (ix)
+       ld      h,%2 (ix)
+       ld      (hl),%3
+} by { 
+       ld      l,%1 (ix)
+       ld      h,%2 (ix)
+       ; peephole 0w shifted (hl) in place.
+       srl     (hl)
+       ld      %3,(hl)
+} if notVolatile(%3)
+// Don't check for volatile since ix points to the stack.
+
+replace restart {
+       push    af
+       inc     sp
+       ld      a,e
+       push    af
+       inc     sp
+} by {
+       ; peephole 0x pushed de instead of pushing a twice.
+       ld      d,a
+       push    de
+} if notUsed('d'), notUsed('a')
+
+replace restart {
+       push    af
+       inc     sp
+       ld      a,c
+       push    af
+       inc     sp
+} by {
+       ; peephole 0y pushed bc instead of pushing a twice.
+       ld      b,a
+       push    bc
+} if notUsed('b'), notUsed('a')
+
+replace restart {
+       ld      a,#%1
+       ld      d,a
+} by {
+       ; peephole 0z loaded #%1 into d directly instead of going through a.
+       ld      d,#%1
+} if notUsed('a')
+
+replace restart {
+       ld      a,%1 (ix)
+       push    af
+       inc     sp
+       ld      a,%2 (ix)
+       push    af
+       inc     sp
+} by {
+       ; peephole 0za pushed %1 (ix), %2(ix) through hl instead of af.
+       ld      h,%1 (ix)
+       ld      l,%2 (ix)
+       push    hl
+} if notUsed('a'), notUsed('hl')
+
+replace restart {
+       ld      c,l
+       ld      b,h
+       push    bc
+} by {
+       ; peephole 0zb pushed hl instead of bc.
+       push    hl
+} if notUsed('bc')
+
+// Doesn'T work due to bug #1947081
+//replace restart {
+//     pop     %1
+//     push    %1
+//} by {
+//     ; peephole 0zc eleminated dead pop/push pair.
+//} if notUsed(%1)
+
+replace restart {
+       ld      iy,#%1
+       or      a,%2 (iy)
+} by {
+       ; peephole 0zd used hl instead of iy.
+       ld      hl,#%1 + %2
+       or      a,(hl)
+} if notUsed('iy'), notUsed('hl')
+
+replace restart {
+       ld      iy,#%1
+       ld      %2,%3 (%4)
+} by {
+       ; peephole 0ze used hl instead of iy.
+       ld      hl,#%1 + %3
+       ld      %2,(hl)
+} if notUsed('iy'), notUsed('hl')
+
+replace restart {
+       ld      iy,#%1
+       ld      %2 (%3), %4
+} by {
+       ; peephole 0zf used hl instead of iy.
+       ld      hl,#%1 + %2
+       ld      (hl), %4
+} if notUsed('iy'), notUsed('hl'), operandsNotRelated(%4 'h'), operandsNotRelated(%4 'l')
+
+replace restart {
+       ld      e,l
+       ld      d,h
+       ld      %1,(de)
+} by {
+       ; peephole 0zg loaded %1 from (hl) directly instead of going through (de).
+       ld      %1,(hl)
+} if notUsed('de')
+
+replace restart {
+       ld      c,l
+       ld      b,h
+       ld      %1,(bc)
+} by {
+       ; peephole 0zh loaded %1 from (hl) directly instead of going through (bc).
+       ld      %1,(hl)
+} if notUsed('bc')
+
+replace restart {
+       ld      c,l
+       ld      b,h
+       inc     bc
+} by {
+       ; peephole 0zi incremented in hl instead of bc.
+       inc     hl
+       ld      c,l
+       ld      b,h
+} if notUsed('hl')
+
+replace restart {
+       ld      a,%1 (%2)
+       bit     %3,a
+} by {
+       ; peephole 0zj tested bit of %1 (%2) directly instead of going through a.
+       bit     %3,%1 (%2)
+} if notUsed('a')
+
+replace restart {
+       ld      bc, #%1 + %2
+       ld      l,c
+       ld      h,b
+} by {
+       ; peephole 0zk stored constant #%1 + %2 into hl directly instead of going through bc.
+       ld      hl, #%1 + %2
+} if notUsed('bc')
+
+replace restart {
+       ld      c, %1 (%2)
+       ld      b, %3 (%4)
+       ld      l,c
+       ld      h,b
+} by {
+       ; peephole 0zk' stored %1 (%2) %3 (%4) into hl directly instead of going through bc.
+       ld      l, %1 (%2)
+       ld      h, %3 (%4)
+} if notUsed('bc')
+
 replace restart {
        jp      NC,%1
        jp      %2
@@ -77,19 +530,6 @@ replace restart {
        ; peephole 8 redirected jump-to-jump at %5 by jump to %6
 } if labelIsUncondJump(), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
 
-replace restart {
-       ld      %2,%3
-       jp      %4
-%5:
-       ld      %2,%3
-%4:
-} by {
-       ; peephole 9 removed jump and redundant load.
-%5:
-       ld      %2,%3
-%4:
-} if labelRefCountChange(%4 -1)
-
 replace restart {
        xor     a,a
        ld      a,#0x00
@@ -143,25 +583,23 @@ replace restart {
 // Maybe we can try this after 2.7.0 release
 
 replace restart {
-       ld      %2,%3
+       ld      %1,a
        ld      a,%2
-       and     a,%1
-       ld      %2,%4
+       or      a,%1
 } by {
-       ld      a,%3
-       ; peephole 16 moved %3 directly into a instead of going through %2.
-       and     a,%1
-       ld      %2,%4
-} if notVolatile(%2), operandsNotSame
+       ld      %1,a
+       or      a,%2
+       ; peephole 17a removed load by reordering or arguments.
+} if notVolatile(%1)
 
 replace restart {
        ld      %1,a
-       ld      a,%2
+       ld      a,%2 (ix)
        or      a,%1
 } by {
        ld      %1,a
-       or      a,%2
-       ; peephole 17 removed load by reordering or arguments.
+       or      a,%2 (ix)
+       ; peephole 17b removed load by reordering or arguments.
 } if notVolatile(%1)
 
 replace restart {
@@ -182,6 +620,14 @@ replace restart {
        ; peephole 19 removed redundant or after or.
 }
 
+replace restart {
+       or      a,%1 (%2)
+       or      a,a
+} by {
+       or      a,%1 (%2)
+       ; peephole 19a removed redundant or after or.
+}
+
 replace restart {
        and     a,%1
        or      a,a
@@ -190,6 +636,14 @@ replace restart {
        ; peephole 20 removed redundant or after and.
 }
 
+replace restart {
+       and     a,%1 (%2)
+       or      a,a
+} by {
+       and     a,%1 (%2)
+       ; peephole 20a removed redundant or after and.
+}
+
 replace restart {
        xor     a,%1
        or      a,a
@@ -199,14 +653,12 @@ replace restart {
 }
 
 replace restart {
-       ld      %1,a
-       and     a,%2
-       ld      %1,a
+       xor     a,%1 (%2)
+       or      a,a
 } by {
-       ; peephole 22 removed redundant load into %1.
-       and     a,%2
-       ld      %1,a
-} if notVolatile(%1)
+       xor     a,%1 (%2)
+       ; peephole 21a removed redundant or after xor.
+}
 
 replace {
        ld      %1,%2
@@ -225,68 +677,8 @@ replace restart {
 } by {
        ld      %1,%2
        ld      %3,%4
-       ; peephole 24 removed redundant load from %3%1 into %4%2
-} if notVolatile(%1 %2 %3 %4)
-
-replace restart {
-       ld      b,%1
-       ld      a,b
-       pop     bc
-} by {
-       ld      a,%1
-       ; peephole 25 removed load into b
-       pop     bc
-}
-
-replace restart {
-       ld      c,%1
-       ld      a,c
-       pop     bc
-} by {
-       ld      a,%1
-       ; peephole 26 removed load into c
-       pop     bc
-}
-
-replace restart {
-       ld      d,%1
-       ld      a,d
-       pop     de
-} by {
-       ld      a,%1
-       ; peephole 27 removed load into d
-       pop     de
-}
-
-replace restart {
-       ld      e,%1
-       ld      a,e
-       pop     de
-} by {
-       ld      a,%1
-       ; peephole 28 removed load into e
-       pop     de
-}
-
-replace restart {
-       ld      h,%1
-       ld      a,h
-       pop     hl
-} by {
-       ld      a,%1
-       ; peephole 29 removed load into h
-       pop     hl
-}
-
-replace restart {
-       ld      l,%1
-       ld      a,l
-       pop     hl
-} by {
-       ld      a,%1
-       ; peephole 30 removed load into l
-       pop     hl
-}
+       ; peephole 24 removed redundant load from %3%1 into %4%2
+} if notVolatile(%1 %2 %3 %4)
 
 replace restart {
        ld      a,c
@@ -441,12 +833,37 @@ replace restart {
        ld      %1,a
        ld      a,%2
        add     a,%1
-       ld      %1,a
 } by {
        ; peephole 42 removed loads by exploiting commutativity of addition.
        add     a,%2
-       ld      %1,a
-} if notVolatile(%1)
+} if notVolatile(%1), notUsed(%1), operandsNotRelated(%2 '(bc)' '(de)')
+
+replace restart {
+       ld      %1 (ix),a
+       ld      a,#%2
+       add     a,%1 (ix)
+} by {
+       ld      %1 (ix),a
+       ; peephole 42a removed loads by exploiting commutativity of addition.
+       add     a,#%2
+}
+// Don't need to check for volatile, since ix is used to access the stack.
+
+// sdcc does not use the H flag. sla resets it, while add sets it.
+// To ensure that the state of the H flag is not changed by this
+// peephole uncomment the add %3, %4 at the end (since it overwrite the H flag).
+replace restart {
+       ld      %1, a
+       sla     %1
+       ld      a, %2
+       //add   %3, %4
+} by {
+       add     a, a
+       ; peephole 42b shifted in accumulator insted of %1
+       ld      %1, a
+       ld      a, %2
+       //add   %3, %4
+}
 
 // sdcc does not use the H flag. sla resets it, while add sets it.
 // To ensure that the state of the H flag is not changed by this
@@ -454,16 +871,48 @@ replace restart {
 replace restart {
        ld      %1, a
        sla     %1
+       sla     %1
        ld      a, %2
        //add   %3, %4
 } by {
        add     a, a
-       ; peephole 42a shifts in accumulator insted of %1
+       add     a, a
+       ; peephole 42b' shifted in accumulator insted of %1
        ld      %1, a
        ld      a, %2
        //add   %3, %4
 }
 
+replace restart {
+       ld      l,%1 (ix)
+       ld      h,%2 (ix)
+       ld      a,(hl)
+       inc     a
+       ld      l,%1 (ix)
+       ld      h,%2 (ix)
+       ld      (hl),a
+} by {
+       ld      l,%1 (ix)
+       ld      h,%2 (ix)
+       inc     (hl)
+       ; peephole 42c incremented in (hl) instead of going through a.
+} if notUsed('a')
+
+replace restart {
+       ld      l,%1 (ix)
+       ld      h,%2 (ix)
+       ld      a,(hl)
+       dec     a
+       ld      l,%1 (ix)
+       ld      h,%2 (ix)
+       ld      (hl),a
+} by {
+       ld      l,%1 (ix)
+       ld      h,%2 (ix)
+       dec     (hl)
+       ; peephole 42d decremented in (hl) instead of going through a.
+} if notUsed('a')
+
 replace restart {
        ld      %1,a
        ld      a,%2
@@ -472,7 +921,40 @@ replace restart {
        ld      %1, a
        ; peephole 43 removed load by exploiting commutativity of addition.
        add     a,%2
-}
+} if operandsNotRelated(%2 '(bc)' '(de)')
+
+replace restart {
+       ld      c,l
+       ld      b,h
+       ld      hl,#%1
+       add     hl,bc
+} by {
+       ; peephole 43a removed loads by exploiting commutativity of addition.
+       ld      bc,#%1
+       add     hl,bc
+} if notUsed('bc')
+
+replace restart {
+       ld      hl,#%1
+       add     hl,%2
+       ld      bc,#%4
+       add     hl,bc
+} by {
+       ; peephole 43b removed loads by exploiting commutativity of addition.
+       ld      hl,#%1 + %4
+       add     hl,%2
+} if notUsed('bc')
+
+replace restart {
+       ld      c,e
+       ld      b,d
+       ld      hl,#%1
+       add     hl,bc
+} by {
+       ; peephole 43c removed loads by exploiting commutativity of addition.
+       ld      hl,#%1
+       add     hl,de
+} if notUsed('bc')
 
 replace restart {
        or      a,%1
@@ -530,29 +1012,29 @@ replace restart {
        ; peephole 48 replaced constant #0x00 by a (which has just been tested to be #0x00).
 }
 
-replace restart {
-       or      a,%1
-       jp      NZ,%2
-       ld      a,%3
-       or      a,a
-} by {
-       or      a,%1
-       jp      NZ,%2
-       or      a,%3
-       ; peephole 49 shortened or using a (which has just been tested to be #0x00).
-}
-
-replace restart {
-       and     a,%1
-       jp      NZ,%2
-       ld      a,%3
-       or      a,a
-} by {
-       and     a,%1
-       jp      NZ,%2
-       or      a,%3
-       ; peephole 50 shortened or using a (which has just been tested to be #0x00).
-}
+//replace restart {
+//     or      a,%1
+//     jp      NZ,%2
+//     ld      a,%3
+//     or      a,a
+//} by {
+//     or      a,%1
+//     jp      NZ,%2
+//     or      a,%3
+//     ; peephole 49 shortened or using a (which has just been tested to be #0x00).
+//} if operandsNotSame3(%3 '(bc)' '(de)')
+
+//replace restart {
+//     and     a,%1
+//     jp      NZ,%2
+//     ld      a,%3
+//     or      a,a
+//} by {
+//     and     a,%1
+//     jp      NZ,%2
+//     or      a,%3
+//     ; peephole 50 shortened or using a (which has just been tested to be #0x00).
+//} if operandsNotSame3(%3 '(bc)' '(de)')
 
 replace restart {
        sub     a,%1
@@ -565,6 +1047,7 @@ replace restart {
        or      a,%3
        ; peephole 51 shortened or using a (which has just been tested to be #0x00).
 }
+//if operandsNotSame3(%3 '(bc)' '(de)')
 
 replace restart {
        dec     a
@@ -577,6 +1060,7 @@ replace restart {
        or      a,%2
        ; peephole 52 shortened or using a (which has just been tested to be #0x00).
 }
+//if operandsNotSame3(%2 '(bc)' '(de)')
 
 replace restart {
        or      a,%1
@@ -630,57 +1114,19 @@ replace restart {
        ; peephole 56 replaced constant #0x00 by a (which has just been tested to be #0x00).
 }
 
-replace restart {
-       ld      de,#%1 + %2
-       inc     de
-       inc     de
-       inc     de
-} by {
-       ld      de,#%1 + %2 + 3
-       ; peephole 57 moved triple increment of de to constant.
-}
-
-replace restart {
-       ld      de,#%1 + %2
-       inc     de
-       inc     de
-} by {
-       ld      de,#%1 + %2 + 2
-       ; peephole 58 moved double increment of de to constant.
-}
-
 replace restart {
        ld      de,#%1 + %2
        inc     de
 } by {
-       ld      de,#%1 + %2 + 1
+       ld      de,#%1 + %2+1
        ; peephole 59 moved increment of de to constant.
 }
 
-replace restart {
-       ld      bc,#%1 + %2
-       inc     bc
-       inc     bc
-       inc     bc
-} by {
-       ld      bc,#%1 + %2 + 3
-       ; peephole 60 moved triple increment of bc to constant.
-}
-
-replace restart {
-       ld      bc,#%1 + %2
-       inc     bc
-       inc     bc
-} by {
-       ld      bc,#%1 + %2 + 2
-       ; peephole 61 moved double increment of bc to constant.
-}
-
 replace restart {
        ld      bc,#%1 + %2
        inc     bc
 } by {
-       ld      bc,#%1 + %2 + 1
+       ld      bc,#%1 + %2+1
        ; peephole 62 moved increment of bc to constant.
 }
 
@@ -697,19 +1143,6 @@ replace restart {
        ; peephole 63 moved addition of constant 0x%3%2 to bc to constant.
 }
 
-replace restart {
-       ld      bc,#%1 + %4
-       ld      a,c
-       add     a,#0x%2
-       ld      c,a
-       ld      a,b
-       adc     a,#0x%3
-       ld      b,a
-} by {
-       ld      bc,#%1 + %4 + 0x%3%2
-       ; peephole 64 moved addition of constant 0x%3%2 to bc to constant.
-}
-
 replace restart {
        call    %1
        ret
@@ -729,6 +1162,174 @@ replace restart {
        ; peephole 66 replaced call at end of function by jump moving call beyond pop ix.
 }
 
+replace restart {
+       ld      %1,a
+       ld      %2,%1
+       ld      %3,%1
+} by {
+       ; peephole 67 loaded %2, %3 from a instead of %1.
+       ld      %1,a
+       ld      %2,a
+       ld      %3,a
+} if notVolatile(%1)
+
+replace restart {
+       ld      %1,a
+       ld      %2,a
+       ld      %3,%1
+} by {
+       ld      %1,a
+       ld      %2,a
+       ; peephole 68 loaded %3 from a instead of %1.
+       ld      %3,a
+} if notVolatile(%1)
+
+replace restart {
+       ld      %1,l
+       xor     a,a
+       or      a,%1
+} by { 
+       ld      %1,l
+       xor     a,a
+       ; peephole 69 used l in or instead of %1.
+       or      a,l
+} if notVolatile(%1)
+
+replace restart {
+       ld      %1,#%2
+       ld      %3,%4
+       ld      %1,#%2
+} by {
+       ld      %1,#%2
+       ld      %3,%4
+       ; peephole 70 removed load of #%2 into %1 since it's still there.
+} if notVolatile(%1), operandsNotRelated(%3 %1)
+
+replace restart {
+       ld      hl,#%1
+       ld      de,#%1
+} by {
+       ; peephole 70a used #%1 from hl for load into de.
+       ld      hl,#%1
+       ld      e,l
+       ld      d,h
+}
+
+replace restart {
+       ld      hl,#%1
+       push    hl
+       ld      l,e
+       ld      h,d
+       jp      (hl)
+%1:
+} by {
+       ; peephole 71 used ex to get de into hl.
+       ex      de,hl
+       ld      de,#%1
+       push    de
+       jp      (hl)
+%1:
+}
+// Lets' hope this is never applied to a jump table. It's fine for calls.
+
+// Should be after 0z.
+replace restart {
+       ld      %1 (ix),l
+       ld      %2 (ix),h
+       ld      %3,%1 (ix)
+       ld      %4,%2 (ix)
+} by { 
+       ld      %1 (ix),l
+       ld      %2 (ix),h
+       ; peephole 72 used hl instead of %2 (ix), %1 (ix) to load %4%3.
+       ld      %3,l
+       ld      %4,h
+} if operandsNotRelated('h' %3)
+// Don't check for volatile since ix points to the stack.
+
+replace restart {
+       ld      %1, a
+       ld      a, %2 (%3)
+       adc     a, #%4
+       ld      l, %1
+} by {
+       ld      l, a
+       ld      a, %2 (%3)
+       adc     a, #%4
+       ; peephole 76 loaded l from a directly instead of going through %1.
+} if notUsed(%1)
+
+replace restart {
+       ld      %1, a
+       ld      a, #%2
+       adc     a, #%3
+       ld      l, %1
+} by {
+       ld      l, a
+       ld      a, #%2
+       adc     a, #%3
+       ; peephole 77 loaded l from a directly instead of going through %1.
+} if notUsed(%1)
+
+replace restart {
+       ld      hl, #%1
+       add     hl, %2
+       ex      de, hl
+       ld      hl, #%3
+       add     hl, de
+} by {
+       ld      hl, #%1+%3
+       add     hl, %2
+       ; peephole 78 removed addition and loads exploiting commutativity of addition.
+} if notUsed('de')
+
+replace restart {
+       ex      de, hl
+       ld      hl, #%1
+       add     hl, de
+} by {
+       ; peephole 78a removed ex exploiting commutativity of addition.
+       ld      de, #%1
+       add     hl, de
+} if notUsed('de')
+
+replace restart {
+       ld      hl, #%1
+       add     hl, %2
+       ex      de, hl
+       inc     de
+} by {
+       ld      hl, #%1+1
+       ; peephole 79 moved increment to constant.
+       add     hl, %2
+       ex      de, hl
+} if notUsed('hl')
+
+// These ex-generating rules should be among the last ones since ex counts as a read from both hl and de for notUsed().
+replace restart {
+       ld      d,h
+       ld      e,l
+} by {
+       ; peephole 80 used ex to load hl into de.
+       ex      de,hl
+} if notUsed('hl')
+
+replace restart {
+       ld      e,l
+       ld      d,h
+} by {
+       ; peephole 81 used ex to load hl into de.
+       ex      de,hl
+} if notUsed('hl')
+
+replace restart {
+       ld      l,e
+       ld      h,d
+} by {
+       ; peephole 82 used ex to load de into hl.
+       ex      de,hl
+} if notUsed('de')
+
 // peeph-z80.def - Z80 peephole rules
 //
 //
@@ -748,34 +1349,25 @@ replace restart {
 // 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      %1,%3
-       ld      %1,%2
-} by {
-       ; 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      a,%3 (%1)
+       ld      %4,a
        ld      %1,#%5
 } by {
-       ld      a,(#%2)
+       ld      a,(#%2 + %3)
        ; peephole z1 used #%2 directly instead of going through %1 using indirect addressing.
-       ld      %3,a
+       ld      %4,a
        ld      %1,#%5
 }
 
 replace restart {
        ld      %1,#%2
-       ld      0(%1),a
+       ld      %3 (%1),a
 %4:
        ld      %1,%5
 } by {
-       ld      (#%2),a
+       ld      (#%2 + %3),a
        ; peephole z2 directly used #%2 instead of going through %1 using indirect addressing.
 %4:
        ld      %1,%5
@@ -784,67 +1376,35 @@ replace restart {
 replace restart {
        pop     af
        ld      %1,#%2
-       ld      0(%1),%3
-       ld      %1,#%4
+       ld      %3 (%1),%4
+       ld      %1,#%5
 } by {
-       ld      a,%3
-       ld      (#%2),a
+       ld      a,%4
+       ld      (#%2 + %3),a
        ; peephole z3 used #%2 directly instead of going through %1 using indirect addressing.
        pop     af
-       ld      %1,#%4
+       ld      %1,#%5
 } 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
-}
+} if notUsed('bc')
 
 replace restart {
        ld      bc,#%1 + %2 + %6
        ld      a,%3
        ld      (bc),a
-       ld      bc,#%4 + %5
 } by {
        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 restart {
-       ld      bc,#%1 + %2
-       ld      a,%3
-       ld      (bc),a
-%7:
-       ld      bc,#%4 + %5
-} by {
-       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
-}
+} if notUsed('bc')
 
 replace restart {
        ld      c,%1
@@ -910,6 +1470,47 @@ replace {
        ; peephole z13 removed unused ret.
 }
 
+// These four need two be here since the peephole optimizer continues to apply rules further down the file even for replace restart rules.
+replace restart {
+       jp      NC,%1
+       jp      %2
+%1:
+} by {
+       jp      C,%2
+       ; peephole 5' removed jp by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+       jp      C,%1
+       jp      %2
+%1:
+} by {
+       jp      NC,%2
+       ; peephole 5' removed jp by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+       jp      NZ,%1
+       jp      %2
+%1:
+} by {
+       jp      Z,%2
+       ; peephole 5' removed jp by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
+replace restart {
+       jp      Z,%1
+       jp      %2
+%1:
+} by {
+       jp      NZ,%2
+       ; peephole 6' removed jp by using inverse jump logic
+%1:
+} if labelRefCountChange(%1 -1)
+
 // These should be the last rules, so that the peepholes above need to look at jp only.
 replace {
        jp      %5