* src/z80/gen.c, src/z80/peeph.def: applied patch
[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 // sdcc does not use the H flag. sla resets it, while add sets it.
460 // To ensure that the state of the H flag is not changed by this
461 // peephole uncomment the add %3, %4 at the end (since it overwrite the H flag).
462 replace restart {
463         ld      %1, a
464         sla     %1
465         ld      a, %2
466         //add   %3, %4
467 } by {
468         add     a, a
469         ; peephole 42a shifts in accumulator insted of %1
470         ld      %1, a
471         ld      a, %2
472         //add   %3, %4
473 }
474
475 replace restart {
476         ld      %1,a
477         ld      a,%2
478         add     a,%1
479 } by {
480         ld      %1, a
481         ; peephole 43 removed load by exploiting commutativity of addition.
482         add     a,%2
483 }
484
485 replace restart {
486         or      a,%1
487         jp      NZ,%2
488         xor     a,a
489         or      a,%3
490 } by {
491         or      a,%1
492         jp      NZ,%2
493         ; peephole 44 removed redundant zeroing of a (which has just been tested to be #0x00).
494         or      a,%3
495 }
496
497 replace restart {
498         or      a,%1
499         jp      NZ,%2
500         ld      %3,#0x00
501 } by {
502         or      a,%1
503         jp      NZ,%2
504         ld      %3,a
505         ; peephole 45 replaced constant #0x00 by a (which has just been tested to be #0x00).
506 }
507
508 replace restart {
509         and     a,%1
510         jp      NZ,%2
511         ld      %3,#0x00
512 } by {
513         and     a,%1
514         jp      NZ,%2
515         ld      %3,a
516         ; peephole 46 replaced constant #0x00 by a (which has just been tested to be #0x00).
517 }
518
519 replace restart {
520         sub     a,%1
521         jp      NZ,%2
522         ld      %3,#0x00
523 } by {
524         sub     a,%1
525         jp      NZ,%2
526         ld      %3,a
527         ; peephole 47 replaced constant #0x00 by a (which has just been tested to be #0x00).
528 }
529
530 replace restart {
531         dec     a
532         jp      NZ,%1
533         ld      %2,#0x00
534 } by {
535         dec     a
536         jp      NZ,%1
537         ld      %2,a
538         ; peephole 48 replaced constant #0x00 by a (which has just been tested to be #0x00).
539 }
540
541 replace restart {
542         or      a,%1
543         jp      NZ,%2
544         ld      a,%3
545         or      a,a
546 } by {
547         or      a,%1
548         jp      NZ,%2
549         or      a,%3
550         ; peephole 49 shortened or using a (which has just been tested to be #0x00).
551 }
552
553 replace restart {
554         and     a,%1
555         jp      NZ,%2
556         ld      a,%3
557         or      a,a
558 } by {
559         and     a,%1
560         jp      NZ,%2
561         or      a,%3
562         ; peephole 50 shortened or using a (which has just been tested to be #0x00).
563 }
564
565 replace restart {
566         sub     a,%1
567         jp      NZ,%2
568         ld      a,%3
569         or      a,a
570 } by {
571         sub     a,%1
572         jp      NZ,%2
573         or      a,%3
574         ; peephole 51 shortened or using a (which has just been tested to be #0x00).
575 }
576
577 replace restart {
578         dec     a
579         jp      NZ,%1
580         ld      a,%2
581         or      a,a
582 } by {
583         dec     a
584         jp      NZ,%1
585         or      a,%2
586         ; peephole 52 shortened or using a (which has just been tested to be #0x00).
587 }
588
589 replace restart {
590         or      a,%1
591         jp      NZ,%2
592         push    %3
593         ld      %4,#0x00
594 } by {
595         or      a,%1
596         jp      NZ,%2
597         push    %3
598         ld      %4,a
599         ; peephole 53 replaced constant #0x00 by a (which has just been tested to be #0x00).
600 }
601
602 replace restart {
603         and     a,%1
604         jp      NZ,%2
605         push    %3
606         ld      %4,#0x00
607 } by {
608         sub     a,%1
609         jp      NZ,%2
610         push    %3
611         ld      %4,a
612         ; peephole 54 replaced constant #0x00 by a (which has just been tested to be #0x00).
613 }
614
615 replace restart {
616         sub     a,%1
617         jp      NZ,%2
618         push    %3
619         ld      %4,#0x00
620 } by {
621         sub     a,%1
622         jp      NZ,%2
623         push    %3
624         ld      %4,a
625         ; peephole 55 replaced constant #0x00 by a (which has just been tested to be #0x00).
626 }
627
628 replace restart {
629         dec     a
630         jp      NZ,%1
631         push    %2
632         ld      %3,#0x00
633 } by {
634         dec     a
635         jp      NZ,%1
636         push    %2
637         ld      %3,a
638         ; peephole 56 replaced constant #0x00 by a (which has just been tested to be #0x00).
639 }
640
641 replace restart {
642         ld      de,#%1 + %2
643         inc     de
644         inc     de
645         inc     de
646 } by {
647         ld      de,#%1 + %2 + 3
648         ; peephole 57 moved triple increment of de to constant.
649 }
650
651 replace restart {
652         ld      de,#%1 + %2
653         inc     de
654         inc     de
655 } by {
656         ld      de,#%1 + %2 + 2
657         ; peephole 58 moved double increment of de to constant.
658 }
659
660 replace restart {
661         ld      de,#%1 + %2
662         inc     de
663 } by {
664         ld      de,#%1 + %2 + 1
665         ; peephole 59 moved increment of de to constant.
666 }
667
668 replace restart {
669         ld      bc,#%1 + %2
670         inc     bc
671         inc     bc
672         inc     bc
673 } by {
674         ld      bc,#%1 + %2 + 3
675         ; peephole 60 moved triple increment of bc to constant.
676 }
677
678 replace restart {
679         ld      bc,#%1 + %2
680         inc     bc
681         inc     bc
682 } by {
683         ld      bc,#%1 + %2 + 2
684         ; peephole 61 moved double increment of bc to constant.
685 }
686
687 replace restart {
688         ld      bc,#%1 + %2
689         inc     bc
690 } by {
691         ld      bc,#%1 + %2 + 1
692         ; peephole 62 moved increment of bc to constant.
693 }
694
695 replace restart {
696         ld      bc,#%1
697         ld      a,c
698         add     a,#0x%2
699         ld      c,a
700         ld      a,b
701         adc     a,#0x%3
702         ld      b,a
703 } by {
704         ld      bc,#%1 + 0x%3%2
705         ; peephole 63 moved addition of constant 0x%3%2 to bc to constant.
706 }
707
708 replace restart {
709         ld      bc,#%1 + %4
710         ld      a,c
711         add     a,#0x%2
712         ld      c,a
713         ld      a,b
714         adc     a,#0x%3
715         ld      b,a
716 } by {
717         ld      bc,#%1 + %4 + 0x%3%2
718         ; peephole 64 moved addition of constant 0x%3%2 to bc to constant.
719 }
720
721 replace restart {
722         call    %1
723         ret
724 } by {
725         jp      %1
726         ; peephole 65 replaced call at end of function by jump.
727 }
728
729 // Callee saves ix.
730 replace restart {
731         call    %1
732         pop     ix
733         ret
734 } by {
735         pop     ix
736         jp      %1
737         ; peephole 66 replaced call at end of function by jump moving call beyond pop ix.
738 }