Imported Upstream version 2.9.0
[debian/cc1111] / src / z80 / peeph-gbz80.def
1 // Due to major changes in the Z80 peepholes the old peepholes from peeph.def have been moved here.
2 // All new peepholes went into peeph-z80.def. A GBZ80 expert should look into this files and peeph-z80.def
3 // And move peepholes that are useful and correct for both Z80 and GBZ80 into peeph.def.
4
5 // peeph.def - Common Z80 and gbz80 peephole rules
6 //
7 //
8 // (c) Philipp Klaus Krause (pkk@spth.de, philipp@colecovision.eu) 2006 - 2007
9 //
10 // This program is free software; you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by the
12 // Free Software Foundation; either version 2, or (at your option) any
13 // later version.
14 //
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 replace restart {
25         ld      %1,%1
26 } by {
27         ; peephole 1 removed redundant load.
28 } if notVolatile(%1)
29
30 replace restart {
31         jp      NC,%1
32         jp      %2
33 %1:
34 } by {
35         jp      C,%2
36         ; peephole 3 removed jp by using inverse jump logic
37 %1:
38 } if labelRefCountChange(%1 -1)
39
40 replace restart {
41         jp      C,%1
42         jp      %2
43 %1:
44 } by {
45         jp      NC,%2
46         ; peephole 4 removed jp by using inverse jump logic
47 %1:
48 } if labelRefCountChange(%1 -1)
49
50 replace restart {
51         jp      NZ,%1
52         jp      %2
53 %1:
54 } by {
55         jp      Z,%2
56         ; peephole 5 removed jp by using inverse jump logic
57 %1:
58 } if labelRefCountChange(%1 -1)
59
60 replace restart {
61         jp      Z,%1
62         jp      %2
63 %1:
64 } by {
65         jp      NZ,%2
66         ; peephole 6 removed jp by using inverse jump logic
67 %1:
68 } if labelRefCountChange(%1 -1)
69
70 replace restart {
71         jp      %5
72 } by {
73         jp      %6
74         ; peephole 7 redirected jump-to-jump at %5 by jump to %6
75 } if labelIsUncondJump(), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
76
77 replace restart {
78         jp      %1,%5
79 } by {
80         jp      %1,%6
81         ; peephole 8 redirected jump-to-jump at %5 by jump to %6
82 } if labelIsUncondJump(), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
83
84 replace restart {
85         ld      %2,%3
86         jp      %4
87 %5:
88         ld      %2,%3
89 %4:
90 } by {
91         ; peephole 9 removed jump and redundant load.
92 %5:
93         ld      %2,%3
94 %4:
95 } if labelRefCountChange(%4 -1)
96
97 replace restart {
98         xor     a,a
99         ld      a,#0x00
100 } by {
101         xor     a,a
102         ; peephole 10 removed redundant load of 0 into a.
103 }
104
105 replace {
106         ld      e,#0x%1
107         ld      d,#0x%2
108 } by {
109         ld      de,#0x%2%1
110         ; peephole 11 combined constant loads into register pair.
111 }
112
113 replace {
114         ld      l,#0x%1
115         ld      h,#0x%2
116 } by {
117         ld      hl,#0x%2%1
118         ; peephole 12 combined constant loads into register pair.
119 }
120
121 replace {
122         ld      c,#0x%1
123         ld      b,#0x%2
124 } by {
125         ld      bc,#0x%2%1
126         ; peephole 13 combined constant loads into register pair.
127 }
128
129 replace restart {
130         ld      %1,a
131         ld      a,%1
132 } by {
133         ld      %1,a
134         ; peephole 14 removed redundant load from %1 into a.
135 } if notVolatile(%1)
136 // This gives many false negatives and without the test no problems are encountered in the regression tests
137 // Maybe we can try this after 2.7.0 release
138
139 replace restart {
140         ld      a,%1
141         ld      %1,a
142 } by {
143         ld      a,%1
144         ; peephole 15 removed redundant load from a into %1.
145 } if notVolatile(%1)
146 // This gives many false negatives and without the test no problems are encountered in the regression tests
147 // Maybe we can try this after 2.7.0 release
148
149 replace restart {
150         ld      %2,%3
151         ld      a,%2
152         and     a,%1
153         ld      %2,%4
154 } by {
155         ld      a,%3
156         ; peephole 16 moved %3 directly into a instead of going through %2.
157         and     a,%1
158         ld      %2,%4
159 } if notVolatile(%2), operandsNotSame
160
161 replace restart {
162         ld      %1,a
163         ld      a,%2
164         or      a,%1
165 } by {
166         ld      %1,a
167         or      a,%2
168         ; peephole 17 removed load by reordering or arguments.
169 } if notVolatile(%1)
170
171 replace restart {
172         ld      %1,a
173         xor     a,a
174         or      a,%1
175 } by {
176         ld      %1,a
177         or      a,a
178         ; peephole 18 used value still in a instead of loading it from %1.
179 }
180
181 replace restart {
182         or      a,%1
183         or      a,a
184 } by {
185         or      a,%1
186         ; peephole 19 removed redundant or after or.
187 }
188
189 replace restart {
190         and     a,%1
191         or      a,a
192 } by {
193         and     a,%1
194         ; peephole 20 removed redundant or after and.
195 }
196
197 replace restart {
198         xor     a,%1
199         or      a,a
200 } by {
201         xor     a,%1
202         ; peephole 21 removed redundant or after xor.
203 }
204
205 replace restart {
206         ld      %1,a
207         and     a,%2
208         ld      %1,a
209 } by {
210         ; peephole 22 removed redundant load into %1.
211         and     a,%2
212         ld      %1,a
213 } if notVolatile(%1)
214
215 replace {
216         ld      %1,%2
217         ld      a,%2
218 } by {
219         ld      a,%2
220         ld      %1,a
221         ; peephole 23 load value in a first and use it next
222 } if notVolatile(%1 %2)
223
224 replace restart {
225         ld      %1,%2
226         ld      %3,%4
227         ld      %2,%1
228         ld      %4,%3
229 } by {
230         ld      %1,%2
231         ld      %3,%4
232         ; peephole 24 removed redundant load from %3%1 into %4%2
233 } if notVolatile(%1 %2 %3 %4)
234
235 replace restart {
236         ld      b,%1
237         ld      a,b
238         pop     bc
239 } by {
240         ld      a,%1
241         ; peephole 25 removed load into b
242         pop     bc
243 }
244
245 replace restart {
246         ld      c,%1
247         ld      a,c
248         pop     bc
249 } by {
250         ld      a,%1
251         ; peephole 26 removed load into c
252         pop     bc
253 }
254
255 replace restart {
256         ld      d,%1
257         ld      a,d
258         pop     de
259 } by {
260         ld      a,%1
261         ; peephole 27 removed load into d
262         pop     de
263 }
264
265 replace restart {
266         ld      e,%1
267         ld      a,e
268         pop     de
269 } by {
270         ld      a,%1
271         ; peephole 28 removed load into e
272         pop     de
273 }
274
275 replace restart {
276         ld      h,%1
277         ld      a,h
278         pop     hl
279 } by {
280         ld      a,%1
281         ; peephole 29 removed load into h
282         pop     hl
283 }
284
285 replace restart {
286         ld      l,%1
287         ld      a,l
288         pop     hl
289 } by {
290         ld      a,%1
291         ; peephole 30 removed load into l
292         pop     hl
293 }
294
295 replace restart {
296         ld      a,c
297         push    af
298         inc     sp
299         ld      a,#%2
300         push    af
301         inc     sp
302         call    %3
303 } by {
304         ld      b,c
305         ld      c,#%2
306         push    bc
307         ; peephole 31 moved and pushed arguments c and #%2 through bc instead of pushing them individually.
308         call    %3
309 }
310
311 replace restart {
312         ld      a,e
313         push    af
314         inc     sp
315         ld      a,#%2
316         push    af
317         inc     sp
318         call    %3
319 } by {
320         ld      d,e
321         ld      e,#%2
322         push    de
323         ; peephole 32 moved and pushed arguments e and #%2 through de instead of pushing them individually.
324         call    %3
325 }
326
327 replace restart {
328         ld      a,%1
329         sub     a,%2
330         jp      %3,%4
331         ld      a,%1
332 } by {
333         ld      a,%1
334         cp      a,%2
335         jp      %3,%4
336         ; peephole 33 removed load by replacing sub with cp
337         assert  a=%1
338 } if notVolatile(%1)
339
340 replace restart {
341         assert  a=%1
342         sub     a,%2
343         jp      %3,%4
344         ld      a,%1
345 } by {
346         cp      a,#%2
347         jp      %3,%4
348         ; peephole 34 removed load by replacing sub with cp
349         assert  a=%1
350 }
351
352 replace restart {
353         assert  a=%1
354 } by {
355 }
356
357 replace restart {
358         sub     a,#0xFF
359         jp      Z,%1
360 } by {
361         inc     a
362         ; peephole 35 replaced sub a,#0xFF by inc a.
363         jp      Z,%1
364 }
365
366 replace restart {
367         sub     a,#0xFF
368         jp      NZ,%1
369 } by {
370         inc     a
371         ; peephole 36 replaced sub a,#0xFF by inc a.
372         jp      NZ,%1
373 }
374
375 replace restart {
376         ld      bc,#%1 + %2
377         ld      a,c
378         add     a,%3
379         ld      c,a
380         ld      a,b
381         adc     a,%4
382         ld      b,a
383 } by {
384         ld      a,#<(%1 + %2)
385         add     a,%3
386         ld      c,a
387         ld      a,#>(%1 + %2)
388         ; peephole 37 directly used (%1 + %2) in calculation instead of placing it in bc first.
389         adc     a,%4
390         ld      b,a
391 }
392
393 replace restart {
394         ld      de,#%1 + %2
395         ld      a,e
396         add     a,%3
397         ld      e,a
398         ld      a,d
399         adc     a,%4
400         ld      d,a
401 } by {
402         ld      a,#<(%1 + %2)
403         add     a,%3
404         ld      e,a
405         ld      a,#>(%1 + %2)
406         ; peephole 38 directly used (%1 + %2) in calculation instead of placing it in de first.
407         adc     a,%4
408         ld      d,a
409 }
410
411 replace restart {
412         rlca
413         ld      a,#0x00
414         rla
415 } by {
416         rlca
417         and     a,#0x01
418         ; peephole 39 replaced zero load, rla by and since rlca writes the same value to carry bit and least significant bit.
419 }
420
421 replace restart {
422         ld      %1,%2
423         push    %1
424         pop     %4
425         ld      %1,%3
426 } by {
427         ld      %4,%2
428         ; peephole 40 moved %2 directly into de instead of going through %1.
429         ld      %1,%3
430 }
431
432 replace restart {
433         add     a,#0x00
434         ld      %2,a
435         ld      a,%3
436         adc     a,%4
437 } by {
438         ; peephole 41 removed lower part of multibyte addition.
439         ld      %2,a
440         ld      a,%3
441         add     a,%4
442 }
443
444 replace restart {
445         ld      %1,a
446         ld      a,%2
447         add     a,%1
448         ld      %1,a
449 } by {
450         ; peephole 42 removed loads by exploiting commutativity of addition.
451         add     a,%2
452         ld      %1,a
453 } if notVolatile(%1)
454
455 // sdcc does not use the H flag. sla resets it, while add sets it.
456 // To ensure that the state of the H flag is not changed by this
457 // peephole uncomment the add %3, %4 at the end (since it overwrite the H flag).
458 replace restart {
459         ld      %1, a
460         sla     %1
461         ld      a, %2
462         //add   %3, %4
463 } by {
464         add     a, a
465         ; peephole 42a shifts in accumulator insted of %1
466         ld      %1, a
467         ld      a, %2
468         //add   %3, %4
469 }
470
471 replace restart {
472         ld      %1,a
473         ld      a,%2
474         add     a,%1
475 } by {
476         ld      %1, a
477         ; peephole 43 removed load by exploiting commutativity of addition.
478         add     a,%2
479 }
480
481 replace restart {
482         or      a,%1
483         jp      NZ,%2
484         xor     a,a
485         or      a,%3
486 } by {
487         or      a,%1
488         jp      NZ,%2
489         ; peephole 44 removed redundant zeroing of a (which has just been tested to be #0x00).
490         or      a,%3
491 }
492
493 replace restart {
494         or      a,%1
495         jp      NZ,%2
496         ld      %3,#0x00
497 } by {
498         or      a,%1
499         jp      NZ,%2
500         ld      %3,a
501         ; peephole 45 replaced constant #0x00 by a (which has just been tested to be #0x00).
502 }
503
504 replace restart {
505         and     a,%1
506         jp      NZ,%2
507         ld      %3,#0x00
508 } by {
509         and     a,%1
510         jp      NZ,%2
511         ld      %3,a
512         ; peephole 46 replaced constant #0x00 by a (which has just been tested to be #0x00).
513 }
514
515 replace restart {
516         sub     a,%1
517         jp      NZ,%2
518         ld      %3,#0x00
519 } by {
520         sub     a,%1
521         jp      NZ,%2
522         ld      %3,a
523         ; peephole 47 replaced constant #0x00 by a (which has just been tested to be #0x00).
524 }
525
526 replace restart {
527         dec     a
528         jp      NZ,%1
529         ld      %2,#0x00
530 } by {
531         dec     a
532         jp      NZ,%1
533         ld      %2,a
534         ; peephole 48 replaced constant #0x00 by a (which has just been tested to be #0x00).
535 }
536
537 replace restart {
538         or      a,%1
539         jp      NZ,%2
540         ld      a,%3
541         or      a,a
542 } by {
543         or      a,%1
544         jp      NZ,%2
545         or      a,%3
546         ; peephole 49 shortened or using a (which has just been tested to be #0x00).
547 }
548
549 replace restart {
550         and     a,%1
551         jp      NZ,%2
552         ld      a,%3
553         or      a,a
554 } by {
555         and     a,%1
556         jp      NZ,%2
557         or      a,%3
558         ; peephole 50 shortened or using a (which has just been tested to be #0x00).
559 }
560
561 replace restart {
562         sub     a,%1
563         jp      NZ,%2
564         ld      a,%3
565         or      a,a
566 } by {
567         sub     a,%1
568         jp      NZ,%2
569         or      a,%3
570         ; peephole 51 shortened or using a (which has just been tested to be #0x00).
571 }
572
573 replace restart {
574         dec     a
575         jp      NZ,%1
576         ld      a,%2
577         or      a,a
578 } by {
579         dec     a
580         jp      NZ,%1
581         or      a,%2
582         ; peephole 52 shortened or using a (which has just been tested to be #0x00).
583 }
584
585 replace restart {
586         or      a,%1
587         jp      NZ,%2
588         push    %3
589         ld      %4,#0x00
590 } by {
591         or      a,%1
592         jp      NZ,%2
593         push    %3
594         ld      %4,a
595         ; peephole 53 replaced constant #0x00 by a (which has just been tested to be #0x00).
596 }
597
598 replace restart {
599         and     a,%1
600         jp      NZ,%2
601         push    %3
602         ld      %4,#0x00
603 } by {
604         sub     a,%1
605         jp      NZ,%2
606         push    %3
607         ld      %4,a
608         ; peephole 54 replaced constant #0x00 by a (which has just been tested to be #0x00).
609 }
610
611 replace restart {
612         sub     a,%1
613         jp      NZ,%2
614         push    %3
615         ld      %4,#0x00
616 } by {
617         sub     a,%1
618         jp      NZ,%2
619         push    %3
620         ld      %4,a
621         ; peephole 55 replaced constant #0x00 by a (which has just been tested to be #0x00).
622 }
623
624 replace restart {
625         dec     a
626         jp      NZ,%1
627         push    %2
628         ld      %3,#0x00
629 } by {
630         dec     a
631         jp      NZ,%1
632         push    %2
633         ld      %3,a
634         ; peephole 56 replaced constant #0x00 by a (which has just been tested to be #0x00).
635 }
636
637 replace restart {
638         ld      de,#%1 + %2
639         inc     de
640         inc     de
641         inc     de
642 } by {
643         ld      de,#%1 + %2 + 3
644         ; peephole 57 moved triple increment of de to constant.
645 }
646
647 replace restart {
648         ld      de,#%1 + %2
649         inc     de
650         inc     de
651 } by {
652         ld      de,#%1 + %2 + 2
653         ; peephole 58 moved double increment of de to constant.
654 }
655
656 replace restart {
657         ld      de,#%1 + %2
658         inc     de
659 } by {
660         ld      de,#%1 + %2 + 1
661         ; peephole 59 moved increment of de to constant.
662 }
663
664 replace restart {
665         ld      bc,#%1 + %2
666         inc     bc
667         inc     bc
668         inc     bc
669 } by {
670         ld      bc,#%1 + %2 + 3
671         ; peephole 60 moved triple increment of bc to constant.
672 }
673
674 replace restart {
675         ld      bc,#%1 + %2
676         inc     bc
677         inc     bc
678 } by {
679         ld      bc,#%1 + %2 + 2
680         ; peephole 61 moved double increment of bc to constant.
681 }
682
683 replace restart {
684         ld      bc,#%1 + %2
685         inc     bc
686 } by {
687         ld      bc,#%1 + %2 + 1
688         ; peephole 62 moved increment of bc to constant.
689 }
690
691 replace restart {
692         ld      bc,#%1
693         ld      a,c
694         add     a,#0x%2
695         ld      c,a
696         ld      a,b
697         adc     a,#0x%3
698         ld      b,a
699 } by {
700         ld      bc,#%1 + 0x%3%2
701         ; peephole 63 moved addition of constant 0x%3%2 to bc to constant.
702 }
703
704 replace restart {
705         ld      bc,#%1 + %4
706         ld      a,c
707         add     a,#0x%2
708         ld      c,a
709         ld      a,b
710         adc     a,#0x%3
711         ld      b,a
712 } by {
713         ld      bc,#%1 + %4 + 0x%3%2
714         ; peephole 64 moved addition of constant 0x%3%2 to bc to constant.
715 }
716
717 replace restart {
718         call    %1
719         ret
720 } by {
721         jp      %1
722         ; peephole 65 replaced call at end of function by jump.
723 }
724
725 // Callee saves ix.
726 replace restart {
727         call    %1
728         pop     ix
729         ret
730 } by {
731         pop     ix
732         jp      %1
733         ; peephole 66 replaced call at end of function by jump moving call beyond pop ix.
734 }
735
736 // Old gbz80 rules from here onward
737
738 replace {
739         ld      (hl),a
740         dec     hl
741 } by {
742         ld      (hl-),a
743 }
744 replace {
745         ld      (hl),a
746         inc     hl
747 } by {
748         ld      (hl+),a
749 }
750 replace {
751         ld      a,(hl)
752         inc     hl
753 } by {
754         ld      a,(hl+)
755 }
756 replace {
757         ld      a,[hl]
758         inc     hl
759 } by {
760         ld      a,[hl+]
761 }
762 replace {
763         ld      a,[hl]
764         inc     hl
765 } by {
766         ld      a,[hl+]
767 }
768 replace {
769         ld      [hl],a
770         inc     hl
771 } by {
772         ld      [hl+],a
773 }
774 replace {
775         ld      [hl],a
776         dec     hl
777 } by {
778         ld      [hl-],a
779 }
780 replace {
781         ld      (hl+),a
782         ld      (hl),d
783         dec     hl
784         ld      e,(hl)
785         inc     hl
786         ld      d,(hl)
787         ld      a,(de)
788 } by {
789         ld      (hl+),a
790         ld      (hl),d
791         ld      e,a
792         ld      a,(de)
793 }
794 replace {
795         ld      (hl),a
796         ld      %1,(hl)
797 } by {
798         ld      (hl),a
799         ld      %1,a
800 }
801 replace {
802         ld      (hl),a
803         inc     de
804         ld      a,(de)
805         inc     hl
806 } by {
807         ld      (hl+),a
808         inc     de
809         ld      a,(de)
810 }