c88c3a781d1995af81fb4a6e5d7e402e5a22756e
[fw/sdcc] / src / z80 / peeph.def
1 // peeph.def - Common Z80 and gbz80 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 replace restart {
21         ld      %1,%1
22 } by {
23         ; peephole 1 removed redundant load.
24 } if notVolatile(%1)
25
26 replace restart {
27         ld      %1,%3
28         ld      %1,%2
29 } by {
30         ; peephole 2 removed dead load into %1
31         ld      %1,%2
32 } if notVolatile(%1 %3), operandsNotSame
33
34 replace restart {
35         jp      NC,%1
36         jp      %2
37 %1:
38 } by {
39         jp      C,%2
40         ; peephole 3 removed jp by using inverse jump logic
41 %1:
42 } if labelRefCountChange(%1 -1)
43
44 replace restart {
45         jp      C,%1
46         jp      %2
47 %1:
48 } by {
49         jp      NC,%2
50         ; peephole 4 removed jp by using inverse jump logic
51 %1:
52 } if labelRefCountChange(%1 -1)
53
54 replace restart {
55         jp      NZ,%1
56         jp      %2
57 %1:
58 } by {
59         jp      Z,%2
60         ; peephole 5 removed jp by using inverse jump logic
61 %1:
62 } if labelRefCountChange(%1 -1)
63
64 replace restart {
65         jp      Z,%1
66         jp      %2
67 %1:
68 } by {
69         jp      NZ,%2
70         ; peephole 6 removed jp by using inverse jump logic
71 %1:
72 } if labelRefCountChange(%1 -1)
73
74 replace restart {
75         jp      %5
76 } by {
77         jp      %6
78         ; peephole 7 redirected jump-to-jump at %5 by jump to %6
79 } if labelIsUncondJump(), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
80
81 replace restart {
82         jp      %1,%5
83 } by {
84         jp      %1,%6
85         ; peephole 8 redirected jump-to-jump at %5 by jump to %6
86 } if labelIsUncondJump(), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
87
88 replace restart {
89         ld      %2,%3
90         jp      %4
91 %5:
92         ld      %2,%3
93 %4:
94 } by {
95         ; peephole 9 removed jump and redundant load.
96 %5:
97         ld      %2,%3
98 %4:
99 } if labelRefCountChange(%4 -1)
100
101 replace restart {
102         xor     a,a
103         ld      a,#0x00
104 } by {
105         xor     a,a
106         ; peephole 10 removed redundant load of 0 into a.
107 }
108
109 replace {
110         ld      e,#0x%1
111         ld      d,#0x%2
112 } by {
113         ld      de,#0x%2%1
114         ; peephole 11 combined constant loads into register pair.
115 }
116
117 replace {
118         ld      l,#0x%1
119         ld      h,#0x%2
120 } by {
121         ld      hl,#0x%2%1
122         ; peephole 12 combined constant loads into register pair.
123 }
124
125 replace {
126         ld      c,#0x%1
127         ld      b,#0x%2
128 } by {
129         ld      bc,#0x%2%1
130         ; peephole 13 combined constant loads into register pair.
131 }
132
133 replace restart {
134         ld      %1,a
135         ld      a,%1
136 } by {
137         ld      %1,a
138         ; peephole 14 removed redundant load from %1 into a.
139 } if notVolatile(%1)
140 // This gives many false negatives and without the test no problems are encountered in the regression tests
141 // Maybe we can try this after 2.7.0 release
142
143 replace restart {
144         ld      a,%1
145         ld      %1,a
146 } by {
147         ld      a,%1
148         ; peephole 15 removed redundant load from a into %1.
149 } if notVolatile(%1)
150 // This gives many false negatives and without the test no problems are encountered in the regression tests
151 // Maybe we can try this after 2.7.0 release
152
153 replace restart {
154         ld      %2,%3
155         ld      a,%2
156         and     a,%1
157         ld      %2,%4
158 } by {
159         ld      a,%3
160         ; peephole 16 moved %3 directly into a instead of going through %2.
161         and     a,%1
162         ld      %2,%4
163 } if notVolatile(%2), operandsNotSame
164
165 replace restart {
166         ld      %1,a
167         ld      a,%2
168         or      a,%1
169 } by {
170         ld      %1,a
171         or      a,%2
172         ; peephole 17 removed load by reordering or arguments.
173 } if notVolatile(%1)
174
175 replace restart {
176         ld      %1,a
177         xor     a,a
178         or      a,%1
179 } by {
180         ld      %1,a
181         or      a,a
182         ; peephole 18 used value still in a instead of loading it from %1.
183 }
184
185 replace restart {
186         or      a,%1
187         or      a,a
188 } by {
189         or      a,%1
190         ; peephole 19 removed redundant or after or.
191 }
192
193 replace restart {
194         and     a,%1
195         or      a,a
196 } by {
197         and     a,%1
198         ; peephole 20 removed redundant or after and.
199 }
200
201 replace restart {
202         xor     a,%1
203         or      a,a
204 } by {
205         xor     a,%1
206         ; peephole 21 removed redundant or after xor.
207 }
208
209 replace restart {
210         ld      %1,a
211         and     a,%2
212         ld      %1,a
213 } by {
214         ; peephole 22 removed redundant load into %1.
215         and     a,%2
216         ld      %1,a
217 } if notVolatile(%1)
218
219 replace {
220         ld      %1,%2
221         ld      a,%2
222 } by {
223         ld      a,%2
224         ld      %1,a
225         ; peephole 23 load value in a first and use it next
226 } if notVolatile(%1 %2)
227
228 replace restart {
229         ld      %1,%2
230         ld      %3,%4
231         ld      %2,%1
232         ld      %4,%3
233 } by {
234         ld      %1,%2
235         ld      %3,%4
236         ; peephole 24 removed redundant load from %3%1 into %4%2
237 } if notVolatile(%1 %2 %3 %4)
238
239 replace restart {
240         ld      b,%1
241         ld      a,b
242         pop     bc
243 } by {
244         ld      a,%1
245         ; peephole 25 removed load into b
246         pop     bc
247 }
248
249 replace restart {
250         ld      c,%1
251         ld      a,c
252         pop     bc
253 } by {
254         ld      a,%1
255         ; peephole 26 removed load into c
256         pop     bc
257 }
258
259 replace restart {
260         ld      d,%1
261         ld      a,d
262         pop     de
263 } by {
264         ld      a,%1
265         ; peephole 27 removed load into d
266         pop     de
267 }
268
269 replace restart {
270         ld      e,%1
271         ld      a,e
272         pop     de
273 } by {
274         ld      a,%1
275         ; peephole 28 removed load into e
276         pop     de
277 }
278
279 replace restart {
280         ld      h,%1
281         ld      a,h
282         pop     hl
283 } by {
284         ld      a,%1
285         ; peephole 29 removed load into h
286         pop     hl
287 }
288
289 replace restart {
290         ld      l,%1
291         ld      a,l
292         pop     hl
293 } by {
294         ld      a,%1
295         ; peephole 30 removed load into l
296         pop     hl
297 }
298
299 replace restart {
300         ld      a,c
301         push    af
302         inc     sp
303         ld      a,#%2
304         push    af
305         inc     sp
306         call    %3
307 } by {
308         ld      b,c
309         ld      c,#%2
310         push    bc
311         ; peephole 31 moved and pushed arguments c and #%2 through bc instead of pushing them individually.
312         call    %3
313 }
314
315 replace restart {
316         ld      a,e
317         push    af
318         inc     sp
319         ld      a,#%2
320         push    af
321         inc     sp
322         call    %3
323 } by {
324         ld      d,e
325         ld      e,#%2
326         push    de
327         ; peephole 32 moved and pushed arguments e and #%2 through de instead of pushing them individually.
328         call    %3
329 }
330
331 replace restart {
332         ld      a,%1
333         sub     a,%2
334         jp      %3,%4
335         ld      a,%1
336 } by {
337         ld      a,%1
338         cp      a,%2
339         jp      %3,%4
340         ; peephole 33 removed load by replacing sub with cp
341         assert  a=%1
342 } if notVolatile(%1)
343
344 replace restart {
345         assert  a=%1
346         sub     a,%2
347         jp      %3,%4
348         ld      a,%1
349 } by {
350         cp      a,#%2
351         jp      %3,%4
352         ; peephole 34 removed load by replacing sub with cp
353         assert  a=%1
354 }
355
356 replace restart {
357         assert  a=%1
358 } by {
359 }
360
361 replace restart {
362         sub     a,#0xFF
363         jp      Z,%1
364 } by {
365         inc     a
366         ; peephole 35 replaced sub a,#0xFF by inc a.
367         jp      Z,%1
368 }
369
370 replace restart {
371         sub     a,#0xFF
372         jp      NZ,%1
373 } by {
374         inc     a
375         ; peephole 36 replaced sub a,#0xFF by inc a.
376         jp      NZ,%1
377 }
378
379 replace restart {
380         ld      bc,#%1 + %2
381         ld      a,c
382         add     a,%3
383         ld      c,a
384         ld      a,b
385         adc     a,%4
386         ld      b,a
387 } by {
388         ld      a,#<(%1 + %2)
389         add     a,%3
390         ld      c,a
391         ld      a,#>(%1 + %2)
392         ; peephole 37 directly used (%1 + %2) in calculation instead of placing it in bc first.
393         adc     a,%4
394         ld      b,a
395 }
396
397 replace restart {
398         ld      de,#%1 + %2
399         ld      a,e
400         add     a,%3
401         ld      e,a
402         ld      a,d
403         adc     a,%4
404         ld      d,a
405 } by {
406         ld      a,#<(%1 + %2)
407         add     a,%3
408         ld      e,a
409         ld      a,#>(%1 + %2)
410         ; peephole 38 directly used (%1 + %2) in calculation instead of placing it in de first.
411         adc     a,%4
412         ld      d,a
413 }
414
415 replace restart {
416         rlca
417         ld      a,#0x00
418         rla
419 } by {
420         rlca
421         and     a,#0x01
422         ; peephole 39 replaced zero load, rla by and since rlca writes the same value to carry bit and least significant bit.
423 }
424
425 replace restart {
426         ld      %1,%2
427         push    %1
428         pop     %4
429         ld      %1,%3
430 } by {
431         ld      %4,%2
432         ; peephole 40 moved %2 directly into de instead of going through %1.
433         ld      %1,%3
434 }
435
436 replace restart {
437         add     a,#0x00
438         ld      %2,a
439         ld      a,%3
440         adc     a,%4
441 } by {
442         ; peephole 41 removed lower part of multibyte addition.
443         ld      %2,a
444         ld      a,%3
445         add     a,%4
446 }
447
448 replace restart {
449         ld      %1,a
450         ld      a,%2
451         add     a,%1
452         ld      %1,a
453 } by {
454         ; peephole 42 removed loads by exploiting commutativity of addition.
455         add     a,%2
456         ld      %1,a
457 } if notVolatile(%1)
458
459 replace restart {
460         ld      %1,a
461         ld      a,%2
462         add     a,%1
463 } by {
464         ld      %1, a
465         ; peephole 43 removed load by exploiting commutativity of addition.
466         add     a,%2
467 }
468
469 replace restart {
470         or      a,%1
471         jp      NZ,%2
472         xor     a,a
473         or      a,%3
474 } by {
475         or      a,%1
476         jp      NZ,%2
477         ; peephole 44 removed redundant zeroing of a (which has just been tested to be #0x00).
478         or      a,%3
479 }
480
481 replace restart {
482         or      a,%1
483         jp      NZ,%2
484         ld      %3,#0x00
485 } by {
486         or      a,%1
487         jp      NZ,%2
488         ld      %3,a
489         ; peephole 45 replaced constant #0x00 by a (which has just been tested to be #0x00).
490 }
491
492 replace restart {
493         and     a,%1
494         jp      NZ,%2
495         ld      %3,#0x00
496 } by {
497         and     a,%1
498         jp      NZ,%2
499         ld      %3,a
500         ; peephole 46 replaced constant #0x00 by a (which has just been tested to be #0x00).
501 }
502
503 replace restart {
504         sub     a,%1
505         jp      NZ,%2
506         ld      %3,#0x00
507 } by {
508         sub     a,%1
509         jp      NZ,%2
510         ld      %3,a
511         ; peephole 47 replaced constant #0x00 by a (which has just been tested to be #0x00).
512 }
513
514 replace restart {
515         dec     a
516         jp      NZ,%1
517         ld      %2,#0x00
518 } by {
519         dec     a
520         jp      NZ,%1
521         ld      %2,a
522         ; peephole 48 replaced constant #0x00 by a (which has just been tested to be #0x00).
523 }
524
525 replace restart {
526         or      a,%1
527         jp      NZ,%2
528         ld      a,%3
529         or      a,a
530 } by {
531         or      a,%1
532         jp      NZ,%2
533         or      a,%3
534         ; peephole 49 shortened or using a (which has just been tested to be #0x00).
535 }
536
537 replace restart {
538         and     a,%1
539         jp      NZ,%2
540         ld      a,%3
541         or      a,a
542 } by {
543         and     a,%1
544         jp      NZ,%2
545         or      a,%3
546         ; peephole 50 shortened or using a (which has just been tested to be #0x00).
547 }
548
549 replace restart {
550         sub     a,%1
551         jp      NZ,%2
552         ld      a,%3
553         or      a,a
554 } by {
555         sub     a,%1
556         jp      NZ,%2
557         or      a,%3
558         ; peephole 51 shortened or using a (which has just been tested to be #0x00).
559 }
560
561 replace restart {
562         dec     a
563         jp      NZ,%1
564         ld      a,%2
565         or      a,a
566 } by {
567         dec     a
568         jp      NZ,%1
569         or      a,%2
570         ; peephole 52 shortened or using a (which has just been tested to be #0x00).
571 }
572
573 replace restart {
574         or      a,%1
575         jp      NZ,%2
576         push    %3
577         ld      %4,#0x00
578 } by {
579         or      a,%1
580         jp      NZ,%2
581         push    %3
582         ld      %4,a
583         ; peephole 53 replaced constant #0x00 by a (which has just been tested to be #0x00).
584 }
585
586 replace restart {
587         and     a,%1
588         jp      NZ,%2
589         push    %3
590         ld      %4,#0x00
591 } by {
592         sub     a,%1
593         jp      NZ,%2
594         push    %3
595         ld      %4,a
596         ; peephole 54 replaced constant #0x00 by a (which has just been tested to be #0x00).
597 }
598
599 replace restart {
600         sub     a,%1
601         jp      NZ,%2
602         push    %3
603         ld      %4,#0x00
604 } by {
605         sub     a,%1
606         jp      NZ,%2
607         push    %3
608         ld      %4,a
609         ; peephole 55 replaced constant #0x00 by a (which has just been tested to be #0x00).
610 }
611
612 replace restart {
613         dec     a
614         jp      NZ,%1
615         push    %2
616         ld      %3,#0x00
617 } by {
618         dec     a
619         jp      NZ,%1
620         push    %2
621         ld      %3,a
622         ; peephole 56 replaced constant #0x00 by a (which has just been tested to be #0x00).
623 }
624
625 replace restart {
626         ld      de,#%1 + %2
627         inc     de
628         inc     de
629         inc     de
630 } by {
631         ld      de,#%1 + %2 + 3
632         ; peephole 57 moved triple increment of de to constant.
633 }
634
635 replace restart {
636         ld      de,#%1 + %2
637         inc     de
638         inc     de
639 } by {
640         ld      de,#%1 + %2 + 2
641         ; peephole 58 moved double increment of de to constant.
642 }
643
644 replace restart {
645         ld      de,#%1 + %2
646         inc     de
647 } by {
648         ld      de,#%1 + %2 + 1
649         ; peephole 59 moved increment of de to constant.
650 }
651
652 replace restart {
653         ld      bc,#%1 + %2
654         inc     bc
655         inc     bc
656         inc     bc
657 } by {
658         ld      bc,#%1 + %2 + 3
659         ; peephole 60 moved triple increment of bc to constant.
660 }
661
662 replace restart {
663         ld      bc,#%1 + %2
664         inc     bc
665         inc     bc
666 } by {
667         ld      bc,#%1 + %2 + 2
668         ; peephole 61 moved double increment of bc to constant.
669 }
670
671 replace restart {
672         ld      bc,#%1 + %2
673         inc     bc
674 } by {
675         ld      bc,#%1 + %2 + 1
676         ; peephole 62 moved increment of bc to constant.
677 }
678
679 replace restart {
680         ld      bc,#%1
681         ld      a,c
682         add     a,#0x%2
683         ld      c,a
684         ld      a,b
685         adc     a,#0x%3
686         ld      b,a
687 } by {
688         ld      bc,#%1 + 0x%3%2
689         ; peephole 63 moved addition of constant 0x%3%2 to bc to constant.
690 }
691
692 replace restart {
693         ld      bc,#%1 + %4
694         ld      a,c
695         add     a,#0x%2
696         ld      c,a
697         ld      a,b
698         adc     a,#0x%3
699         ld      b,a
700 } by {
701         ld      bc,#%1 + %4 + 0x%3%2
702         ; peephole 64 moved addition of constant 0x%3%2 to bc to constant.
703 }
704
705