// 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 %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 %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 restart { ld %1,#%2 ld 0(%1),a %4: ld %1,%5 } by { ld (#%2),a ; peephole z2 directly used #%2 instead of going through %1 using indirect addressing. %4: ld %1,%5 } replace restart { pop af ld %1,#%2 ld 0(%1),%3 ld %1,#%4 } by { 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 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 } 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()