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