Fixed #1806565
[fw/sdcc] / src / z80 / peeph-z80.def
1 // peeph-z80.def - Z80 peephole rules
2 //
3 //
4 // (c) Philipp Klaus Krause (pkk@spth.de, philipp@colecovision.eu) 2006 - 2007
5 //
6 // This program is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option) any
9 // later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 // This can't go into peeph.def since %1 could be (hl+) on gbz80.
21 replace restart {
22         ld      %1,%3
23         ld      %1,%2
24 } by {
25         ; peephole z0 removed dead load into %1
26         ld      %1,%2
27 } if notVolatile(%1 %3), operandsNotSame
28
29 replace restart {
30         ld      %1,#%2
31         ld      a,0(%1)
32         ld      %3,a
33         ld      %1,#%5
34 } by {
35         ld      a,(#%2)
36         ; peephole z1 used #%2 directly instead of going through %1 using indirect addressing.
37         ld      %3,a
38         ld      %1,#%5
39 }
40
41 replace restart {
42         ld      %1,#%2
43         ld      0(%1),a
44 %4:
45         ld      %1,%5
46 } by {
47         ld      (#%2),a
48         ; peephole z2 directly used #%2 instead of going through %1 using indirect addressing.
49 %4:
50         ld      %1,%5
51 }
52
53 replace restart {
54         pop     af
55         ld      %1,#%2
56         ld      0(%1),%3
57         ld      %1,#%4
58 } by {
59         ld      a,%3
60         ld      (#%2),a
61         ; peephole z3 used #%2 directly instead of going through %1 using indirect addressing.
62         pop     af
63         ld      %1,#%4
64 } if operandsNotRelated(%3 'a')
65
66 replace restart {
67         ld      bc,#%1 + %2
68         ld      a,%3
69         ld      (bc),a
70         ld      bc,#%4 + %5
71 } by {
72         ld      a,%3
73         ld      (#%1 + %2),a
74         ; peephole z4 directly used address #%1 + %2 instead of placing it in bc first.
75         ld      bc,#%4 + %5
76 }
77
78 replace restart {
79         ld      bc,#%1 + %2 + %6
80         ld      a,%3
81         ld      (bc),a
82         ld      bc,#%4 + %5
83 } by {
84         ld      a,%3
85         ld      (#%1 + %2 + %6),a
86         ; peephole z5 directly used address #%1 + %2 + %6 instead of placing it in bc first.
87         ld      bc,#%4 + %5
88 }
89
90 replace restart {
91         ld      bc,#%1 + %2
92         ld      a,%3
93         ld      (bc),a
94 %7:
95         ld      bc,#%4 + %5
96 } by {
97         ld      a,%3
98         ld      (#%1 + %2),a
99         ; peephole z6 directly used address #%1 + %2 instead of placing it in bc first.
100 %7:
101         ld      bc,#%4 + %5
102 }
103
104 replace restart {
105         ld      bc,#%1 + %2 + %6
106         ld      a,%3
107         ld      (bc),a
108 %7:
109         ld      bc,#%4 + %5
110 } by {
111         ld      a,%3
112         ld      (#%1 + %2 + %6),a
113         ; peephole z7 directly used address #%1 + %2 + %6 instead of placing it in bc first.
114 %7:
115         ld      bc,#%4 + %5
116 }
117
118 replace restart {
119         ld      c,%1
120         ld      l,c
121         ret
122 } by {
123         ld      l,%1
124         ; peephole z8 moved %1 directly into l instead of going through c.
125         ret
126 }
127
128 replace restart {
129         ld      b,h
130         ld      c,l
131         pop     af
132         push    bc
133         call    %1
134 } by {
135         ex      (sp),hl
136         ; peephole z9 moved hl directly to the stack instead of going through bc.
137         call    %1
138 }
139
140 replace restart {
141         ld      d,h
142         ld      e,l
143         pop     af
144         push    de
145         call    %1
146 } by {
147         ex      (sp),hl
148         ; peephole z10 moved hl directly to the stack instead of going through de.
149         call    %1
150 }
151
152 replace restart {
153         jp      %5
154 } by {
155         ret
156         ; peephole z11 replaced jump by return.
157 } if labelIsReturnOnly(), labelRefCountChange(%5 -1)
158
159 replace restart {
160         jp      %1,%5
161 } by {
162         ret     %1
163         ; peephole z11a replaced jump by return.
164 } if labelIsReturnOnly(), labelRefCountChange(%5 -1)
165
166 // Should be one of the last ones. Opens the code to further peephole optimization.
167 replace restart {
168 %1:
169 } by {
170         ; peephole z12 removed unused label %1.
171 } if labelRefCount(%1 0)
172
173 // Applying z11 or z11a followed by z12 will often leave a dead ret at the end of the function. Remove it.
174 replace {
175         jp      %5
176         ret
177 } by {
178         jp      %5
179         ; peephole z13 removed unused ret.
180 }
181
182 // These should be the last rules, so that the peepholes above need to look at jp only.
183 replace {
184         jp      %5
185 } by {
186         jr      %5
187         ; peephole z14 changed absolute to relative unconditional jump.
188 } if labelInRange()
189
190 replace {
191         jp      Z,%5
192 } by {
193         jr      Z,%5
194         ; peephole z15 changed absolute to relative conditional jump.
195 } if labelInRange()
196
197 replace {
198         jp      NZ,%5
199 } by {
200         jr      NZ,%5
201         ; peephole z16 changed absolute to relative conditional jump.
202 } if labelInRange()
203
204 replace {
205         jp      C,%5
206 } by {
207         jr      C,%5
208         ; peephole z17 changed absolute to relative conditional jump.
209 } if labelInRange()
210
211 replace {
212         jp      NC,%5
213 } by {
214         jr      NC,%5
215         ; peephole z18 changed absolute to relative conditional jump.
216 } if labelInRange()