1// peeph-z80.def - Z80 peephole rules
2//
3// Some of these peepholes could be potentially moved to peeph.def, but a
4// GBZ80 expert should have a look at them before.
5//
6// (c) Philipp Klaus Krause (pkk@spth.de, philipp@colecovision.eu) 2006 - 2015
7//
8// This program is free software; you can redistribute it and/or modify it
9// under the terms of the GNU General Public License as published by the
10// Free Software Foundation; either version 2, or (at your option) any
11// later version.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22replace restart {
23	ld	%1, %1
24} by {
25	; peephole 0 removed redundant load from %1 into %1.
26} if notVolatile(%1)
27
28replace restart {
29	ld	%1, %2
30} by {
31	; peephole 1 removed dead load from %2 into %1.
32} if notVolatile(%1), notUsed(%1), notVolatile(%2)
33
34replace restart {
35	add	ix,sp
36} by {
37	; peephole 2 removed dead frame pointer setup.
38} if notUsed('ix')
39
40replace restart {
41	ld	%1, %2 + %3
42} by {
43	; peephole 3 removed dead load from %2 + %3 into %1.
44} if notVolatile(%1), notUsed(%1)
45// Should probably check for notVolatile(%2), too, but gives many false positives and no regression tests fail.
46
47replace restart {
48	ld	%1, (iy)
49} by {
50	ld	%1, 0 (iy)
51	; peephole 4 made 0 offset explicit.
52}
53
54replace restart {
55	ld	(iy), %1
56} by {
57	ld	0 (iy), %1
58	; peephole 5 made 0 offset explicit.
59}
60
61replace restart {
62	inc	hl
63} by {
64	; peephole 5a removed dead increment of hl.
65} if notUsed('hl')
66
67replace restart {
68	dec	hl
69} by {
70	; peephole 6 removed dead decrement of hl.
71} if notUsed('hl')
72
73replace restart {
74	ld	%1, %2 (iy)
75} by {
76	; peephole 7 removed dead load from %2 (iy) into %1.
77} if notUsed(%1)
78// Should probably check for notVolatile(), but gives many false positives and no regression tests fail.
79
80replace restart {
81	ld	%1, %2 (ix)
82} by {
83	; peephole 8 removed dead load from %2 (ix) into %1.
84} if notUsed(%1)
85
86replace restart {
87	ld	%1, %2
88	ld	%3, %1
89} by {
90	; peephole 9 loaded %3 from %2 directly instead of going through %1.
91	ld	%3, %2
92} if canAssign(%3 %2), notVolatile(%1), notUsed(%1), notSame(%3 '(hl)' '(de)' '(bc)')
93
94replace restart {
95	ld	%1, %2
96	ld	%3, %1
97} by {
98	; peephole 9a loaded %3 from %2 directly instead of going through %1.
99	ld	%3, %2
100} if canAssign(%3 %2), notVolatile(%1), notUsed(%1), canAssign('a' %1)
101
102replace restart {
103	ld	%1, hl
104	ld	hl, %1
105} by {
106	; peephole 9b reused value still in hl.
107	ld	%1, hl
108} if notVolatile(%1)
109
110replace restart {
111	ld	%1, %2
112	ld	%3, %4
113	ld	%5, %1
114} by {
115	ld	%5, %2
116	; peephole 10 loaded %5 from %2 directly instead of going through %1.
117	ld	%3, %4
118} if canAssign(%5 %2), notVolatile(%1), operandsNotRelated(%1 %4), operandsNotRelated(%1 %3), operandsNotRelated(%3 %5), operandsNotRelated(%4 %5), notUsed(%1), notSame(%3 %4 '(hl)' '(de)' '(bc)'), notVolatile(%5)
119// Rule OK unless both %5 and %4 are volatile, but we can't express that directly.
120
121replace restart {
122	ld	%3 (ix), %1
123	ld	%4 (ix), %2
124	ld	%5, %3 (ix)
125	ld	%6, %4 (ix)
126} by {
127	ld	%3 (ix), %1
128	ld	%4 (ix), %2
129	; peephole 11 loaded %5%6 from %1%2 directly instead of going through %3 (ix) %4 (ix).
130	ld	%5, %1
131	ld	%6, %2
132} if canAssign(%5 %1), canAssign(%6 %2), notSame(%5 %2)
133
134replace restart {
135	ld	%1, %2 (%3)
136	ld	%4, %1
137} by {
138	; peephole 12 loaded %2 (%3) into %4 directly instead of going through %1.
139	ld	%4, %2 (%3)
140} if canAssign(%4 %2 %3), notVolatile(%1), notUsed(%1)
141
142replace restart {
143	ld	%1, %2
144	ld	%3 (%4), %1
145} by {
146	; peephole 13 loaded %2 into %3 (%4) directly instead of going through %1.
147	ld	%3 (%4), %2
148} if canAssign(%3 %4 %2), notVolatile(%1), notUsed(%1), canAssign('a' %1)
149// canAssign ('a' %1) checks that %1 is an 8-bit value
150
151replace restart {
152	ld	%1, %2 (%3)
153	ld	%4, %5 (%6)
154	ld	%7, %1
155} by {
156	ld	%7, %2 (%3)
157	; peephole 14 loaded %2 (%3) into %7 directly instead of going through %1.
158	ld	%4, %5 (%6)
159} if canAssign(%7 %2 %3), notVolatile(%1), notUsed(%1), notSame(%1 %4), notSame(%7 %4)
160
161replace restart {
162	ld	%1, %2 (%3)
163	ld	%4, %5
164	ld	%7, %1
165} by {
166	ld	%7, %2 (%3)
167	; peephole 15 loaded %2 (%3) into %7 directly instead of going through %1.
168	ld	%4, %5
169} if canAssign(%7 %2 %3), notVolatile(%1), notUsed(%1), operandsNotRelated(%1 %5), operandsNotRelated(%7 %4), operandsNotRelated(%7 %5), notSame(%4 '(hl)' '(de)' '(bc)'), notSame(%5 '(hl)' '(de)' '(bc)' '(iy)')
170
171replace restart {
172	ld	%1,#%2
173	ld	a,%3 (%1)
174} by {
175	; peephole 16 loaded %2 into a directly instead of going through %1.
176	ld	a,(#%2 + %3)
177} if notUsed(%1)
178
179replace restart {
180	ld	hl, #%1
181	ld	a, (hl)
182} by {
183	ld	a, (#%1)
184	; peephole 17 loaded a from (#%1) directly instead of using hl.
185} if notUsed('hl')
186
187replace restart {
188	ld	hl,#%1 + %2
189	ld	a,(hl)
190} by {
191	; peephole 18 loaded %2 into a directly instead of using hl.
192	ld	a,(#%1 + %2)
193} if notUsed('hl')
194
195replace restart {
196	ld	hl,#%1
197	ld	(hl),a
198} by {
199	ld	(#%1),a
200	; peephole 19 loaded (#%1) from a directly instead of using hl.
201} if notUsed('hl')
202
203replace restart {
204	ld	hl,#%1 + %2
205	ld	(hl),a
206} by {
207	ld	(#%1 + %2),a
208	; peephole 20 loaded (#%1) from a directly instead of using hl.
209} if notUsed('hl')
210
211replace restart {
212	ld	a, %1 (%2)
213	srl	a
214	ld	%1 (%2), a
215} by {
216	srl	%1 (%2)
217	ld	a, %1 (%2)
218	; peephole 21 shifted in (%2) instead of a.
219}
220
221replace restart {
222	ld	%1,(hl)
223	ld	a,%2 (%3)
224	sub	a,%1
225} by {
226	ld	a,%2 (%3)
227	; peephole 22 used (hl) in sub directly instead of going through %1.
228	sub	a,(hl)
229} if notVolatile(%1), notUsed(%1)
230
231replace restart {
232	inc	bc
233	ld	l,c
234	ld	h,b
235} by {
236	ld	l,c
237	ld	h,b
238	; peephole 23 incremented in hl instead of bc.
239	inc	hl
240} if notUsed('bc')
241
242replace restart {
243	inc	de
244	ld	l,e
245	ld	h,d
246} by {
247	ld	l,e
248	ld	h,d
249	; peephole 24 incremented in hl instead of de.
250	inc	hl
251} if notUsed('de')
252
253replace restart {
254	ld	c,l
255	ld	b,h
256	ld	a,#%1
257	ld	(bc),a
258} by {
259	ld	c,l
260	ld	b,h
261	ld	(hl),#%1
262	; peephole 25 loaded #%1 into (hl) instead of (bc).
263} if notUsed('a')
264
265replace restart {
266	ex	de, hl
267	push	de
268} by {
269	; peephole 26 pushed hl directly instead of going through de.
270	push	hl
271} if notUsed('de'), notUsed('hl')
272
273replace restart {
274	ld	l,%1
275	ld	h,d
276	push	hl
277} by {
278	; peephole 27 pushed de instead of hl removing a load.
279	ld	e,%1
280	push	de
281} if notUsed('hl'), notUsed('e')
282
283replace restart {
284	ex	de, hl
285	push	bc
286	push	de
287} by {
288	; peephole 28 pushed hl directly instead of going through de.
289	push	bc
290	push	hl
291} if notUsed('de'), notUsed('hl')
292
293replace restart {
294	ld	l,c
295	ld	h,b
296	push	hl
297} by {
298	; peephole 29 pushed bc directly instead of going through hl.
299	push	bc
300} if notUsed('hl')
301
302replace restart {
303	ld	c,l
304	ld	b,h
305	push	%1
306	push	bc
307} by {
308	; peephole 30 pushed hl directly instead of going through bc.
309	push	%1
310	push	hl
311} if notUsed('bc'), notSame(%1 'bc')
312
313replace restart {
314	pop	de
315	ld	l, e
316	ld	h, d
317} by {
318	; peephole 31 popped hl directly instead of going through de.
319	pop	hl
320} if notUsed('de')
321
322replace restart {
323	pop	bc
324	ld	l, c
325	ld	h, b
326} by {
327	; peephole 32 popped hl directly instead of going through bc.
328	pop	hl
329} if notUsed('bc')
330
331replace restart {
332	ld	%1 (ix), %2
333	ld	%3, %1 (ix)
334} by {
335	; peephole 33 loaded %3 from %2 instead of going through %1 (ix).
336	ld	%1 (ix), %2
337	ld	%3, %2
338} if canAssign(%3 %2)
339// Don't need to check for volatile, since ix is used for the stack.
340
341replace restart {
342	ld	%1 (ix), a
343	push	de
344	ld	%2, %1 (ix)
345} by {
346	ld	%1 (ix), a
347	push	de
348	; peephole 34 loaded %2 from a instead of %1 (ix)
349	ld	%2, a
350} if canAssign(%2 'a')
351
352replace restart {
353	push	af
354	inc	sp
355	ld	a,e
356	push	af
357	inc	sp
358} by {
359	; peephole 35 pushed de instead of pushing a twice.
360	ld	d,a
361	push	de
362} if notUsed('d'), notUsed('a')
363
364replace restart {
365	push	de
366	inc	sp
367	push	af
368	inc	sp
369} by {
370	; peephole 36 pushed de instead of pushing twice.
371	ld	e, a
372	push	de
373} if notUsed('e'), notUsed('a')
374
375replace restart {
376	push	af
377	inc	sp
378	ld	a,#%1
379	push	af
380	inc	sp
381} by {
382	; peephole 37 pushed de instead of pushing a twice.
383	ld	d,a
384	ld	e,#%1
385	push	de
386} if notUsed('de')
387
388replace restart {
389	push	af
390	inc	sp
391	ld	a,#%1
392	push	af
393	inc	sp
394} by {
395	; peephole 38 pushed bc instead of pushing a twice.
396	ld	b,a
397	ld	c,#%1
398	push	bc
399} if notUsed('bc')
400
401replace restart {
402	push	hl
403	inc	sp
404	push	de
405	inc	sp
406} by {
407	ld	l, d
408	; peephole 39 combined pushing of b and d.
409	push	hl
410} if notUsed('l')
411
412replace restart {
413	push	bc
414	inc	sp
415	push	de
416	inc	sp
417} by {
418	ld	c, d
419	; peephole 40 combined pushing of b and d.
420	push	bc
421} if notUsed('c')
422
423replace restart {
424	push	de
425	inc	sp
426	push	bc
427	inc	sp
428} by {
429	ld	e, b
430	; peephole 41 combined pushing of d and b.
431	push	de
432} if notUsed('e')
433
434replace restart {
435	push	af
436	inc	sp
437	ld	a, c
438	push	af
439	inc	sp
440} by {
441	ld	b, a
442	; peephole 42 combined pushing of a and c.
443	push	bc
444} if notUsed('b'), notUsed('a')
445
446replace restart {
447	push	de
448	inc	sp
449	ld	a, c
450	push	af
451	inc	sp
452} by {
453	ld	e, c
454	; peephole 43 combined pushing of d and c.
455	push	de
456} if notUsed('e'), notUsed('a')
457
458replace restart {
459	ld	a, e
460	push	af
461	inc	sp
462	ld	a, %2 (ix)
463	push	af
464	inc	sp
465} by {
466	ld	d, e
467	ld	e, %2 (ix)
468	; peephole 44 combined pushing of e and %2 (ix).
469	push	de
470} if notUsed('d'), notUsed('e'), notUsed('a')
471
472replace restart {
473	ld	a,#%1
474	ld	d,a
475} by {
476	; peephole 45 loaded #%1 into d directly instead of going through a.
477	ld	d,#%1
478} if notUsed('a')
479
480replace restart {
481	ld	%1,a
482	ld	%2,%1
483} by {
484	; peephole 46 loaded %2 from a directly instead of going through %1.
485	ld	%2,a
486} if notUsed(%1)
487
488replace restart {
489	ld	a, %1 (%3)
490	push	af
491	inc	sp
492	ld	a, %2 (%3)
493	push	af
494	inc	sp
495} by {
496	; peephole 47 pushed %1 (%3), %2 (%3) through hl instead of af.
497	ld	h, %1 (%3)
498	ld	l, %2 (%3)
499	push	hl
500} if notUsed('a'), notUsed('hl')
501
502replace restart {
503	ld	c, l
504	ld	b, h
505	push	bc
506} by {
507	; peephole 48 pushed hl instead of bc.
508	push	hl
509} if notUsed('bc')
510
511replace restart {
512	ld	a, (hl)
513	inc	hl
514	ld	h, (hl)
515	ld	l, a
516	push	hl
517} by {
518	; peephole 49 pushed bc instead of hl.
519	ld	c, (hl)
520	inc	hl
521	ld	b, (hl)
522	push	bc
523} if notUsed('bc'), notUsed('hl')
524
525replace restart {
526	pop	%1
527	push	%1
528} by {
529	; peephole 50 eleminated dead pop/push pair.
530} if notUsed(%1)
531
532replace restart {
533	pop	%1
534	ld	%2 (ix), %3
535	push	%1
536} by {
537	; peephole 51 eleminated dead pop/push pair.
538	ld	%2 (ix), %3
539} if notUsed(%1), operandsNotRelated(%1 %3)
540
541replace restart {
542	push	hl
543	pop	bc
544} by {
545	ld	c, l
546	ld	b, h
547	; peephole 52 replaced push/pop pair by loads.
548} if notUsed('hl')
549
550replace restart {
551	push	hl
552	pop	de
553} by {
554	ld	e, l
555	ld	d, h
556	; peephole 53 replaced push/pop pair by loads.
557} if notUsed('hl')
558
559replace restart {
560	ld	iy,#%1
561	or	a,%2 (iy)
562} by {
563	; peephole 54 used hl instead of iy.
564	ld	hl,#%1 + %2
565	or	a,(hl)
566} if notUsed('iy'), notUsed('hl')
567
568replace restart {
569	ld	iy,#%1
570	ld	%2,%3 (iy)
571} by {
572	; peephole 55 used hl instead of iy.
573	ld	hl,#%1 + %3
574	ld	%2, (hl)
575} if notUsed('iy'), notUsed('hl')
576
577replace restart {
578	ld	iy,#%1
579	ld	h,%3 (iy)
580} by {
581	; peephole 56 used hl instead of iy.
582	ld	hl,#%1 + %3
583	ld	h, (hl)
584} if notUsed('iy'), notUsed('l')
585
586replace restart {
587	ld	iy,#%1
588	ld	%2 (iy), %3
589} by {
590	; peephole 57 used hl instead of iy.
591	ld	hl,#%1 + %2
592	ld	(hl), %3
593} if notUsed('iy'), notUsed('hl'), notSame(%3 'h' 'l')
594
595replace restart {
596	ld	iy,#%1
597	ld	%2,0 (iy)
598	ld	%3,1 (iy)
599} by {
600	; peephole 58 used hl instead of iy.
601	ld	hl,#%1
602	ld	%2, (hl)
603	inc	hl
604	ld	%3, (hl)
605} if notUsed('iy'), notUsed('hl'), operandsNotRelated(%2 'hl')
606
607replace restart {
608	ld	iy,#%1
609	ld	%2 (iy),%3
610	ld	l,%2 (iy)
611} by {
612	; peephole 59 used hl instead of iy.
613	ld	hl,#%1 + %2
614	ld	(hl),%3
615	ld	l,(hl)
616} if notUsed('iy'), notUsed('h')
617
618replace restart {
619	ld	iy,#%1
620	ld	%2 (%3), %4
621} by {
622	; peephole 60 used hl instead of iy.
623	ld	hl,#%1 + %2
624	ld	(hl), %4
625} if notUsed('iy'), notUsed('hl'), operandsNotRelated(%4 'hl')
626
627replace restart {
628	ld	iy,#%1
629	bit	%2,%3 (iy)
630} by {
631	; peephole 61 used hl instead of iy.
632	ld	hl,#%1+%3
633	bit	%2, (hl)
634} if notUsed('iy'), notUsed('hl')
635
636replace restart {
637	ld	iy, #%1
638	add	iy, sp
639	ld	%2, %3 (iy)
640} by {
641	; peephole 62 used hl instead of iy.
642	ld	hl, #%1+%3
643	add	hl, sp
644	ld	%2, (hl)
645} if notUsed('iy'), notUsed('hl')
646
647replace restart {
648	ld	iy, #%1
649	add	iy, sp
650	ld	%2, 0 (iy)
651	ld	%3, 1 (iy)
652} by {
653	; peephole 63 used hl instead of iy.
654	ld	hl, #%1
655	add	hl, sp
656	ld	%2, (hl)
657	inc	hl
658	ld	%3, (hl)
659} if notUsed('iy'), notUsed('hl')
660
661replace restart {
662	ld	iy, #%1
663	add	iy, sp
664	ld	l, 0 (iy)
665	ld	h, 1 (iy)
666} by {
667	; peephole 64 used hl instead of iy.
668	ld	hl, #%1
669	add	hl, sp
670	ld	a, (hl)
671	inc	hl
672	ld	h, (hl)
673	ld	l, a
674} if notUsed('iy'), notUsed('a')
675
676replace restart {
677	ld	iy, #%1
678	add	iy, sp
679	ld	0 (iy), #%2
680	ld	1 (iy), #%3
681} by {
682	; peephole 65 used hl instead of iy.
683	ld	hl, #%1
684	add	hl, sp
685	ld	(hl), #%2
686	inc	hl
687	ld	(hl), #%3
688} if notUsed('iy'), notUsed('hl')
689
690replace restart {
691	ld	iy, #%1
692	add	iy, sp
693	ld	a, 1 (iy)
694	or	a, 0 (iy)
695} by {
696	ld	hl, #%1+1
697	add	hl, sp
698	ld	a, (hl)
699	dec	hl
700	or	a, (hl)
701	; peephole 66 used hl instead of iy.
702} if notUsed('iy'), notUsed('hl')
703
704replace restart {
705	ld	iy, #%1
706	add	iy, sp
707	bit	%2, %3 (iy)
708} by {
709	ld	hl, #%1+%3
710	add	hl, sp
711	bit	%2, (hl)
712	; peephole 67 used hl instead of iy.
713} if notUsed('iy'), notUsed('hl')
714
715replace restart {
716	ld	iy, #%1
717	add	iy, sp
718	or	a, %2 (iy)
719} by {
720	ld	hl, #%1+%2
721	add	hl, sp
722	or	a, (hl)
723	; peephole 68 used hl instead of iy.
724} if notUsed('iy'), notUsed('hl')
725
726replace restart {
727	ld	c,l
728	ld	b,h
729	inc	bc
730} by {
731	; peephole 69 incremented in hl instead of bc.
732	inc	hl
733	ld	c,l
734	ld	b,h
735} if notUsed('hl')
736
737replace restart {
738	ld	iy, #%1
739	inc	%2 (iy)
740} by {
741	; peephole 70 incremented in (hl) instead of %2 (iy).
742	ld	hl, #%1+%2
743	inc	(hl)
744} if notUsed('hl'), notUsed('iy')
745
746replace restart {
747	ld	iy, #%1
748	dec	%2 (iy)
749} by {
750	; peephole 71 decremented in (hl) instead of %2 (iy).
751	ld	hl, #%1+%2
752	dec	(hl)
753} if notUsed('hl'), notUsed('iy')
754
755replace restart {
756	ld	a,%1 (%2)
757	bit	%3,a
758} by {
759	; peephole 72 tested bit %3 of %1 (%2) directly instead of going through a.
760	bit	%3,%1 (%2)
761} if notUsed('a')
762
763replace restart {
764	ld	%1, (hl)
765	bit	%2, %1
766} by {
767	; peephole 73 tested bit %2 of (hl) directly instead of going through %1.
768	bit	%2, (hl)
769} if notUsed(%1)
770
771replace restart {
772	ld	a,%1
773	bit	%2,a
774} by {
775	; peephole 74 tested bit %2 of %1 directly instead of going through a.
776	bit	%2,%1
777} if notUsed('a'), canAssign(%1 'b')
778
779replace restart {
780	ld	a, %1
781	set	%2, a
782	ld	%1, a
783} by {
784	; peephole 75 set bit %2 of %1 directly instead of going through a.
785	set	%2, %1
786	ld	a, %1
787} if canAssign(%1 'b')
788// canAssign(%1 'b') is true, iff set b, %1 is possible.
789
790replace restart {
791	ld	a, %1 (%2)
792	set	%3, a
793	ld	%1 (%2), a
794} by {
795	; peephole 76 set bit %3 of %1 (%2) directly instead of going through a.
796	set	%3, %1 (%2)
797	ld	a, %1 (%2)
798}
799
800replace restart {
801	ld	a, %1
802	res	%2, a
803	ld	%1, a
804} by {
805	; peephole 77 reset bit %2 of %1 directly instead of going through a.
806	res	%2, %1
807	ld	a, %1
808} if canAssign(%1 'b')
809// canAssign(%1 'b') is true, iff set b, %1 is possible.
810
811replace restart {
812	ld	a, %1 (%2)
813	res	%3, a
814	ld	%1 (%2), a
815} by {
816	; peephole 78 reset bit %3 of %1 (%2) directly instead of going through a.
817	res	%3, %1 (%2)
818	ld	a, %1 (%2)
819}
820
821replace restart {
822	jp	NC,%1
823	jp	%2
824%1:
825} by {
826	jp	C,%2
827	; peephole 79 removed jp by using inverse jump logic
828%1:
829} if labelRefCountChange(%1 -1)
830
831replace restart {
832	jp	C,%1
833	jp	%2
834%1:
835} by {
836	jp	NC,%2
837	; peephole 80 removed jp by using inverse jump logic
838%1:
839} if labelRefCountChange(%1 -1)
840
841replace restart {
842	jp	NZ,%1
843	jp	%2
844%1:
845} by {
846	jp	Z,%2
847	; peephole 81 removed jp by using inverse jump logic
848%1:
849} if labelRefCountChange(%1 -1)
850
851replace restart {
852	jp	Z,%1
853	jp	%2
854%1:
855} by {
856	jp	NZ,%2
857	; peephole 82 removed jp by using inverse jump logic
858%1:
859} if labelRefCountChange(%1 -1)
860
861replace restart {
862	jp	%5
863} by {
864	jp	%6
865	; peephole 83 jumped to %6 directly instead of via %5.
866} if labelIsUncondJump(), notSame(%5 %6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
867
868replace restart {
869	jp	%1,%5
870} by {
871	jp	%1,%6
872	; peephole 84 jumped to %6 directly instead of via %5.
873} if labelIsUncondJump(), notSame(%5 %6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
874
875replace restart {
876	jp	%1
877%2:
878%1:
879} by {
880   ; peephole 85 eliminated jump.
881%2:
882%1:
883} if labelRefCountChange(%1 -1)
884
885// A peephole that makes the code longer. Let's hope it's worth it in speed gain and further optimization potential.
886replace restart {
887	ld	a,#0x00
888%1:
889	bit	%2,a
890	jp	Z,%3
891} by {
892	ld	a,#0x00
893	jp	%3
894	; peephole 86 jumped directly to %3 instead of testing a first.
895%1:
896	bit	%2,a
897	jp	Z,%3
898} if labelRefCountChange(%3 +1)
899
900replace restart {
901	ld	%1, %2
902	jp	%3
903	jp	%4
904} by {
905	ld	%1, %2
906	jp	%3
907	; peephole 87 removed unreachable jump to %3.
908}
909
910replace restart {
911	ld	%1, %2
912	jp	%3
913%3:
914} by {
915	ld	%1, %2
916%3:
917	; peephole 88 removed redundant jump to %3.
918} if labelRefCountChange(%3 -1)
919
920replace restart {
921	ld	%1, #0x01
922	bit	0, %1
923	jp	Z, %2
924} by {
925	ld	%1, #0x01
926	; peephole 89 removed impossible jump to %2.
927} if labelRefCountChange(%2 -1)
928
929replace restart {
930	rlca
931	and	a, #0x01
932	jp	Z, %1
933} by {
934	rlca
935	; peephole 90 removed and by changing jump condition.
936	jp	NC, %1
937} if notUsed('a'), notUsedFrom(%1 'a')
938
939replace restart {
940	rlca
941	and	a, #0x01
942	jp	NZ, %1
943} by {
944	rlca
945	; peephole 91 removed and by changing jump condition.
946	jp	C, %1
947} if notUsed('a'), notUsedFrom(%1 'a')
948
949replace {
950	ld	e, #0x%1
951	ld	d, #0x%2
952} by {
953	ld	de, #0x%2%1
954	; peephole 92 combined constant loads into register pair.
955}
956
957replace {
958	ld	d, #0x%1
959	ld	e, #0x%2
960} by {
961	ld	de, #0x%1%2
962	; peephole 93 combined constant loads into register pair.
963}
964
965replace {
966	ld	l, #0x%1
967	ld	h, #0x%2
968} by {
969	ld	hl, #0x%2%1
970	; peephole 94 combined constant loads into register pair.
971}
972
973replace {
974	ld	h, #0x%1
975	ld	l, #0x%2
976} by {
977	ld	hl, #0x%1%2
978	; peephole 95 combined constant loads into register pair.
979}
980
981replace {
982	ld	c, #0x%1
983	ld	b, #0x%2
984} by {
985	ld	bc, #0x%2%1
986	; peephole 96 combined constant loads into register pair.
987}
988
989replace {
990	ld	b, #0x%1
991	ld	c, #0x%2
992} by {
993	ld	bc, #0x%1%2
994	; peephole 97 combined constant loads into register pair.
995}
996
997replace restart {
998	ld	%1, a
999	ld	a, %1
1000} by {
1001	ld	%1, a
1002	; peephole 98 removed redundant load from %1 into a.
1003} if notVolatile(%1)
1004// This gives many false negatives and without the test no problems are encountered in the regression tests
1005// Maybe we can try this after 2.7.0 release
1006
1007replace restart {
1008	ld	%2 (ix), %1
1009	ld	%1, %2 (ix)
1010} by {
1011	ld	%2 (ix), %1
1012	; peephole 98a removed redundant load of %1 from %2 (ix)
1013}
1014
1015replace restart {
1016	ld	%1,a
1017	ld	a,%2
1018	or	a,%1
1019} by {
1020	ld	%1,a
1021	or	a,%2
1022	; peephole 99 removed load by reordering or arguments.
1023} if notVolatile(%1), canAssign('b' %2)
1024// canAssign('b' %2) is true, iff or a,%2 is possible.
1025
1026replace restart {
1027	ld	%1, (hl)
1028	inc	hl
1029	ld	a, (hl)
1030	or	a, %1
1031} by {
1032	ld	a, (hl)
1033	inc	hl
1034	; peephole 99a removed load by reordering or arguments.
1035	or	a, (hl)
1036} if notUsed(%1)
1037
1038replace restart {
1039	and	a,%1
1040	or	a,a
1041} by {
1042	and	a,%1
1043	; peephole 100 removed redundant or after and.
1044}
1045
1046replace restart {
1047	xor	a,%1
1048	or	a,a
1049} by {
1050	xor	a,%1
1051	; peephole 101 removed redundant or after xor.
1052}
1053
1054replace restart {
1055	xor	a,%1 (%2)
1056	or	a,a
1057} by {
1058	xor	a,%1 (%2)
1059	; peephole 102 removed redundant or after xor.
1060}
1061
1062replace restart {
1063	dec	a
1064	or	a, a
1065} by {
1066	dec	a
1067	; peephole 102a removed redundant or after dec.
1068}
1069
1070replace restart {
1071	dec	%1
1072	ld	a, %1
1073	or	a, a
1074} by {
1075	dec	%1
1076	ld	a, %1
1077	; peephole 102b removed redundant or after dec.
1078}
1079
1080replace {
1081	ld	%1,%2
1082	ld	a,%2
1083} by {
1084	ld	a,%2
1085	ld	%1,a
1086	; peephole 103 loaded value in a first and used it next
1087} if notVolatile(%1 %2), canAssign(%1 'a'), operandsNotRelated(%1 %2)
1088
1089replace restart {
1090	ld	%1,%2
1091	ld	%3,%4
1092	ld	%2,%1
1093	ld	%4,%3
1094} by {
1095	ld	%1,%2
1096	ld	%3,%4
1097	; peephole 104 removed redundant load from %3%1 into %4%2
1098} if notVolatile(%1 %2 %3 %4)
1099
1100replace restart {
1101	push	de
1102	inc	sp
1103	ld	a,e
1104	push	af
1105	inc	sp
1106} by {
1107	push	de
1108	; peephole 105 pushed de
1109} if notUsed('a')
1110
1111replace restart {
1112	ld	iy,%1
1113	add	iy,sp
1114	ld	sp,iy
1115} by {
1116	ld	hl,%1
1117	add	hl,sp
1118	ld	sp,hl
1119	; peephole 106 fixed stack using hl instead of iy.
1120} if notUsed('hl'), notUsed('iy')
1121
1122replace restart {
1123	ld	a,%1
1124	sub	a,%2
1125	jp	%3,%4
1126	ld	a,%1
1127} by {
1128	ld	a,%1
1129	cp	a,%2
1130	jp	%3,%4
1131	; peephole 107 removed load from %1 into a by replacing sub with cp
1132	assert	a=%1
1133} if notVolatile(%1), notUsedFrom(%4 'a')
1134
1135replace restart {
1136	assert	a=%1
1137	sub	a,%2
1138	jp	%3,%4
1139	ld	a,%1
1140} by {
1141	cp	a,%2
1142	jp	%3,%4
1143	; peephole 108 removed load from %1 into a by replacing sub with cp
1144	assert	a=%1
1145} if notUsedFrom(%4 'a')
1146
1147replace restart {
1148	assert	a=%1
1149} by {
1150}
1151
1152replace restart {
1153	rlca
1154	ld	a,#0x00
1155	rla
1156} by {
1157	rlca
1158	and	a,#0x01
1159	; peephole 109 replaced zero load, rla by and since rlca writes the same value to carry bit and least significant bit.
1160}
1161
1162replace restart {
1163	ld	%1,%2
1164	push	%1
1165	pop	%4
1166	ld	%1,%3
1167} by {
1168	ld	%4,%2
1169	; peephole 110 moved %2 directly into de instead of going through %1.
1170	ld	%1,%3
1171}
1172
1173replace restart {
1174	add	a,#0x00
1175	ld	%2,a
1176	ld	a,%3
1177	adc	a,%4
1178} by {
1179	; peephole 111 removed lower part of multibyte addition.
1180	ld	%2,a
1181	ld	a,%3
1182	add	a,%4
1183}
1184
1185replace restart {
1186	ld	a, l
1187	add	a, #0x%1
1188	ld	e, a
1189	ld	a, h
1190	adc	a, #0x%2
1191	ld	d, a
1192} by {
1193	ld	de, #0x%2%1
1194	add	hl, de
1195	; peephole 112 used 16-bit addition.
1196	ld	e, l
1197	ld	d, h
1198	ld	a, h
1199} if notUsed('hl')
1200
1201replace restart {
1202	ld	a, l
1203	add	a, #0x%1
1204	ld	c, a
1205	ld	a, h
1206	adc	a, #0x%2
1207	ld	b, a
1208} by {
1209	ld	bc, #0x%2%1
1210	add	hl,bc
1211	; peephole 113 used 16-bit addition.
1212	ld	c, l
1213	ld	b, h
1214	ld	a, h
1215} if notUsed('hl')
1216
1217replace restart {
1218	ld	l,%1 (ix)
1219	ld	h,%2 (ix)
1220	ld	a,(hl)
1221	inc	a
1222	ld	l,%1 (ix)
1223	ld	h,%2 (ix)
1224	ld	(hl),a
1225} by {
1226	ld	l,%1 (ix)
1227	ld	h,%2 (ix)
1228	inc	(hl)
1229	; peephole 114 incremented in (hl) instead of going through a.
1230} if notUsed('a')
1231
1232replace restart {
1233	ld	a,(hl)
1234	inc	a
1235	ld	(hl),a
1236} by {
1237	inc	(hl)
1238	; peephole 115 incremented in (hl) instead of going through a.
1239} if notUsed('a')
1240
1241// TODO: Check for volatile?
1242replace restart {
1243	ld	%1, %2 (%3)
1244	inc	%1
1245	ld	%2 (%3), %1
1246} by {
1247	inc	%2 (%3)
1248	ld	%1, %2 (%3)
1249	; peephole 116 incremented in %2 (%3) instead of going through %1.
1250} if canAssign('a' %1)
1251
1252// TODO: Check for volatile?
1253replace restart {
1254	ld	%1, %2 (%3)
1255	dec	%1
1256	ld	%2 (%3), %1
1257} by {
1258	dec	%2 (%3)
1259	ld	%1, %2 (%3)
1260	; peephole 117 decremented in %2 (%3) instead of going through %1.
1261} if canAssign('a' %1)
1262
1263replace restart {
1264	ld	%1,a
1265	ld	a,%2
1266	add	a,%1
1267} by {
1268	ld	%1, a
1269	; peephole 118 removed load by exploiting commutativity of addition.
1270	add	a,%2
1271} if notSame(%2 '(bc)' '(de)'), canAssign('b' %2)
1272// canAssign('b' %2) is true, iff add a,%2 is possible.
1273
1274replace restart {
1275	ld	c,l
1276	ld	b,h
1277	ld	hl,#%1
1278	add	hl,bc
1279} by {
1280	; peephole 119 removed loads by exploiting commutativity of addition.
1281	ld	bc,#%1
1282	add	hl,bc
1283} if notUsed('bc')
1284
1285replace restart {
1286	ld	hl,#%1
1287	add	hl,%2
1288	ld	bc,#%4
1289	add	hl,bc
1290} by {
1291	; peephole 120 removed loads by exploiting commutativity of addition.
1292	ld	hl,#%1 + %4
1293	add	hl,%2
1294} if notUsed('bc')
1295
1296replace restart {
1297	or	a,%1
1298	jp	NZ,%2
1299	ld	%3,#0x00
1300} by {
1301	or	a,%1
1302	jp	NZ,%2
1303	ld	%3,a
1304	; peephole 121 replaced constant #0x00 by a (which has just been tested to be #0x00).
1305}
1306
1307replace restart {
1308	and	a,%1
1309	jp	NZ,%2
1310	ld	%3,#0x00
1311} by {
1312	and	a,%1
1313	jp	NZ,%2
1314	ld	%3,a
1315	; peephole 122 replaced constant #0x00 by a (which has just been tested to be #0x00).
1316}
1317
1318replace restart {
1319	sub	a,%1
1320	jp	NZ,%2
1321	ld	%3,#0x00
1322} by {
1323	sub	a,%1
1324	jp	NZ,%2
1325	ld	%3,a
1326	; peephole 123 replaced constant #0x00 by a (which has just been tested to be #0x00).
1327}
1328
1329replace restart {
1330	inc	a
1331	jp	NZ,%1
1332	ld	%2,#0x00
1333} by {
1334	inc	a
1335	jp	NZ,%1
1336	ld	%2,a
1337	; peephole 124 replaced constant #0x00 by a (which has just been tested to be #0x00).
1338}
1339
1340replace restart {
1341	dec	a
1342	jp	NZ,%1
1343	ld	%2,#0x00
1344} by {
1345	dec	a
1346	jp	NZ,%1
1347	ld	%2,a
1348	; peephole 125 replaced constant #0x00 by a (which has just been tested to be #0x00).
1349}
1350
1351replace restart {
1352	or	a,%1
1353	jp	NZ,%2
1354	ld	a,%3
1355	or	a,a
1356} by {
1357	or	a,%1
1358	jp	NZ,%2
1359	or	a,%3
1360	; peephole 126 shortened or using a (which has just been tested to be #0x00).
1361} if canAssign('b' %3)
1362// canAssign('b' %2) is true, iff or a,%2 is possible.
1363
1364replace restart {
1365	sub	a,%1
1366	jp	NZ,%2
1367	ld	a,%3
1368	or	a,a
1369} by {
1370	sub	a,%1
1371	jp	NZ,%2
1372	or	a,%3
1373	; peephole 127 shortened or using a (which has just been tested to be #0x00).
1374} if canAssign('b' %3)
1375// canAssign('b' %2) is true, iff or a,%2 is possible.
1376
1377replace restart {
1378	ld	hl,#%1
1379	add	hl,%2
1380	inc	hl
1381} by {
1382	ld	hl,#%1+1
1383	add	hl,%2
1384	; peephole 129 moved increment of hl to constant.
1385}
1386
1387replace restart {
1388	push	hl
1389	pop	iy
1390	pop	hl
1391	inc	iy
1392} by {
1393	inc	hl
1394	push	hl
1395	pop	iy
1396	pop	hl
1397	; peephole 130 incremented in hl instead of iy.
1398}
1399
1400replace restart {
1401	push	bc
1402	pop	iy
1403	inc	iy
1404} by {
1405	inc	bc
1406	push	bc
1407	pop	iy
1408	; peephole 131 incremented in bc instead of iy.
1409} if notUsed('bc')
1410
1411replace restart {
1412	ld	hl,%1
1413	add	hl,%2
1414	push	hl
1415	pop	iy
1416} by {
1417	ld	iy,%1
1418	add	iy,%2
1419	; peephole 132 added in iy instead of hl.
1420} if notUsed('hl'), notSame(%2 'hl')
1421
1422replace restart {
1423	pop	af
1424	ld	sp,%1
1425} by {
1426	; peephole 133 removed redundant pop af.
1427	ld	sp,%1
1428} if notUsed('a')
1429
1430replace restart {
1431	inc	sp
1432	ld	sp,%1
1433} by {
1434	; peephole 134 removed redundant inc sp.
1435	ld	sp,%1
1436} if notUsed('a')
1437
1438replace restart {
1439	call    %1
1440	ret
1441} by {
1442	jp  %1
1443	; peephole 135 replaced call at end of function by jump (tail call optimization).
1444} if symmParmStack(%1)
1445
1446// Callee saves ix.
1447replace restart {
1448	call	%1
1449	pop	ix
1450	ret
1451} by {
1452	pop	ix
1453	jp	%1
1454	; peephole 136 replaced call at end of function by jump moving call beyond pop ix (tail call optimization).
1455} if symmParmStack(%1)
1456
1457replace restart {
1458	ld	%1,#%2
1459	ld	%3,%4
1460	ld	%1,#%2
1461} by {
1462	ld	%1,#%2
1463	ld	%3,%4
1464	; peephole 137 removed load of #%2 into %1 since it's still there.
1465} if notVolatile(%1), operandsNotRelated(%3 %1)
1466
1467replace restart {
1468	ld	hl,#%1
1469	ld	de,#%1
1470} by {
1471	; peephole 138 used #%1 from hl for load into de.
1472	ld	hl,#%1
1473	ld	e,l
1474	ld	d,h
1475}
1476
1477replace restart {
1478	ld      sp,hl
1479	ld      hl,#0x0002
1480	add     hl,sp
1481} by {
1482	ld	sp, hl
1483	inc	hl
1484	inc	hl
1485	; peephole 139 replaced addition by increment.
1486}
1487
1488replace restart {
1489	ex	de, hl
1490	ld	hl, #%1
1491	add	hl, de
1492} by {
1493	; peephole 140 removed ex exploiting commutativity of addition.
1494	ld	de, #%1
1495	add	hl, de
1496} if notUsed('de')
1497
1498replace restart {
1499	ld	hl, #%1
1500	add	hl, %2
1501	ex	de, hl
1502	inc	de
1503} by {
1504	ld	hl, #%1+1
1505	; peephole 141 moved increment to constant.
1506	add	hl, %2
1507	ex	de, hl
1508} if notUsed('hl')
1509
1510replace restart {
1511	pop	af
1512	push	hl
1513} by {
1514	; peephole 142 used ex to move hl onto the stack.
1515	ex	(sp),hl
1516} if notUsed('a'), notUsed('hl')
1517
1518replace restart {
1519	pop	af
1520	ld	hl, #%1
1521	push	hl
1522} by {
1523	ld	hl, #%1
1524	; peephole 143 used ex to move hl onto the stack.
1525	ex	(sp),hl
1526} if notUsed('a'), notUsed('hl')
1527
1528replace restart {
1529	pop	af
1530	inc	sp
1531	ld	hl,#%1
1532	push	hl
1533} by {
1534	inc	sp
1535	ld	hl,#%1
1536	; peephole 144 used ex to move #%1 onto the stack.
1537	ex	(sp),hl
1538} if notUsed('a'), notUsed('hl')
1539
1540replace restart {
1541	pop	af
1542	inc	sp
1543	ld	h, %1 (ix)
1544	ld	l, %2 (ix)
1545	push	hl
1546} by {
1547	inc	sp
1548	ld	h, %1 (ix)
1549	ld	l, %2 (ix)
1550	; peephole 145 used ex to move %1 (ix) %2 (ix) onto the stack.
1551	ex	(sp),hl
1552} if notUsed('a'), notUsed('hl')
1553
1554replace restart {
1555	pop	af
1556	ld	a,#%1
1557	push	af
1558	inc	sp
1559} by {
1560	ld	h,#%1
1561	ex	(sp),hl
1562	; peephole 146 used ex to move #%1 onto the stack.
1563	inc	sp
1564} if notUsed('a'), notUsed('hl')
1565
1566replace restart {
1567	ld	%1,#%2
1568	ld	%3 (%1),a
1569%4:
1570	ld	%1,%5
1571} by {
1572	ld	(#%2 + %3),a
1573	; peephole 147 directly used #%2 instead of going through %1 using indirect addressing.
1574%4:
1575	ld	%1,%5
1576}
1577
1578replace restart {
1579	pop	af
1580	ld	%1,#%2
1581	ld	%3 (%1),%4
1582	ld	%1,#%5
1583} by {
1584	ld	a,%4
1585	ld	(#%2 + %3),a
1586	; peephole 148 used #%2 directly instead of going through %1 using indirect addressing.
1587	pop	af
1588	ld	%1,#%5
1589} if notSame(%3 'a')
1590
1591replace restart {
1592	ld	%1,a
1593	bit	%2,%1
1594} by {
1595	bit	%2,a
1596	; peephole 149 tested bit %2 of a directly instead of going through %1.
1597} if notUsed(%1)
1598
1599replace restart {
1600	sbc	a,%1
1601	bit	7,a
1602	jp	NZ,%2
1603} by {
1604	sbc	a,%1
1605	jp	M,%2
1606	; peephole 150 used sign flag instead of testing bit 7.
1607}
1608
1609replace restart {
1610	ld	%1,a
1611	or	a,a
1612	jp	%3,%4
1613	ld	a,%1
1614} by {
1615	ld	%1,a
1616	or	a,a
1617	jp	%3,%4
1618	; peephole 151 used value still in a instead of reloading from %1.
1619}
1620
1621replace {
1622	jp	%5
1623	ret
1624} by {
1625	jp	%5
1626	; peephole 152 removed unused ret.
1627}
1628
1629replace {
1630	jp	%5
1631	ld	sp,ix
1632	pop	ix
1633	ret
1634} by {
1635	jp	%5
1636	; peephole 153 removed unused ret.
1637}
1638
1639replace restart {
1640	or	a,%1
1641	jp	NZ,%2
1642	xor	a,a
1643	jp	%3
1644} by {
1645	or	a,%1
1646	jp	NZ,%2
1647	; peephole 155 removed redundant zeroing of a (which has just been tested to be #0x00).
1648	jp	%3
1649}
1650
1651replace restart {
1652	dec	hl
1653	inc	hl
1654} by {
1655	; peephole 155a removed inc hl / dec hl pair.
1656}
1657
1658replace restart {
1659	dec	hl
1660	inc	bc
1661	inc	hl
1662} by {
1663	inc	bc
1664	; peephole 155b removed inc hl / dec hl pair.
1665}
1666
1667replace restart {
1668	dec	hl
1669	inc	de
1670	inc	hl
1671} by {
1672	inc	de
1673	; peephole 155v removed inc hl / dec hl pair.
1674}
1675
1676replace restart {
1677	jp	Z, %2
1678	ld	a, #%3
1679	jp	%1
1680%2:
1681	ld	a, #%4
1682%1:
1683} by {
1684	ld	a, #%3
1685	jp	NZ, %1
1686%2:
1687	ld	a, #%4
1688	; peephole 168z used double assignment in case of Z condition.
1689%1:
1690} if labelRefCountChange(%2 -1)
1691
1692replace restart {
1693	jp	NZ, %2
1694	ld	a, #%3
1695	jp	%1
1696%2:
1697	ld	a, #%4
1698%1:
1699} by {
1700	ld	a, #%3
1701	jp	Z, %1
1702%2:
1703	ld	a, #%4
1704	; peephole 168nz used double assignment in case of NZ condition.
1705%1:
1706} if labelRefCountChange(%2 -1)
1707
1708replace restart {
1709	jp	Z, %2
1710	ld	a, #%3
1711	jp	%1
1712%2:
1713	xor	a, a
1714%1:
1715} by {
1716	ld	a, #%3
1717	jp	NZ, %1
1718	; peephole 169xz used double assignment in case of Z condition.
1719%2:
1720	xor	a, a
1721%1:
1722} if labelRefCountChange(%2 -1)
1723
1724replace restart {
1725	jp	NZ, %2
1726	ld	a, #%3
1727	jp	%1
1728%2:
1729	xor	a, a
1730%1:
1731} by {
1732	ld	a, #%3
1733	jp	Z, %1
1734	; peephole 169xnz used double assignment in case of NZ condition.
1735%2:
1736	xor	a, a
1737%1:
1738} if labelRefCountChange(%2 -1)
1739
1740replace restart {
1741	jp	Z, %2
1742	ld	c, #%3
1743	jp	%1
1744%2:
1745	ld	c, #%4
1746%1:
1747} by {
1748	ld	c, #%3
1749	jp	NZ, %1
1750%2:
1751	ld	c, #%4
1752	; peephole 170z used double assignment in case of Z condition.
1753%1:
1754} if labelRefCountChange(%2 -1)
1755
1756replace restart {
1757	jp	NZ, %2
1758	ld	c, #%3
1759	jp	%1
1760%2:
1761	ld	c, #%4
1762%1:
1763} by {
1764	ld	c, #%3
1765	jp	Z, %1
1766%2:
1767	ld	c, #%4
1768	; peephole 170nz used double assignment in case of NZ condition.
1769%1:
1770} if labelRefCountChange(%2 -1)
1771
1772replace restart {
1773	jp	Z, %2
1774	ld	e, #%3
1775	jp	%1
1776%2:
1777	ld	e, #%4
1778%1:
1779} by {
1780	ld	e, #%3
1781	jp	NZ, %1
1782%2:
1783	ld	e, #%4
1784	; peephole 171z used double assignment in case of Z condition.
1785%1:
1786} if labelRefCountChange(%2 -1)
1787
1788replace restart {
1789	jp	NZ, %2
1790	ld	e, #%3
1791	jp	%1
1792%2:
1793	ld	e, #%4
1794%1:
1795} by {
1796	ld	e, #%3
1797	jp	Z, %1
1798%2:
1799	ld	e, #%4
1800	; peephole 171nz used double assignment in case of NZ condition.
1801%1:
1802} if labelRefCountChange(%2 -1)
1803
1804replace restart {
1805	jp	Z, %2
1806	ld	l, #%3
1807	jp	%1
1808%2:
1809	ld	l, #%4
1810%1:
1811} by {
1812	ld	l, #%3
1813	jp	NZ, %1
1814%2:
1815	ld	l, #%4
1816	; peephole 172z used double assignment in case of Z condition.
1817%1:
1818} if labelRefCountChange(%2 -1)
1819
1820replace restart {
1821	jp	NZ, %2
1822	ld	l, #%3
1823	jp	%1
1824%2:
1825	ld	l, #%4
1826%1:
1827} by {
1828	ld	l, #%3
1829	jp	Z, %1
1830%2:
1831	ld	l, #%4
1832	; peephole 172nz used double assignment in case of NZ condition.
1833%1:
1834} if labelRefCountChange(%2 -1)
1835
1836// These ex-generating rules should be among the last ones since ex counts as a read from both hl and de for notUsed().
1837barrier
1838
1839replace restart {
1840	ld	e,l
1841	ld	d,h
1842} by {
1843	; peephole 156 used ex to load hl into de.
1844	ex	de,hl
1845} if notUsed('hl')
1846
1847replace restart {
1848	ld	l,e
1849	ld	h,d
1850} by {
1851	; peephole 157 used ex to load de into hl.
1852	ex	de,hl
1853} if notUsed('de')
1854
1855barrier
1856
1857// Should be one of the last ones. Opens the code to further peephole optimization.
1858replace restart {
1859%1:
1860} by {
1861	; peephole 158 removed unused label %1.
1862} if labelRefCount(%1 0)
1863
1864// Ensure that all rules above see only jp, not jr.
1865barrier
1866
1867replace {
1868	add	hl,de
1869	pop	de
1870	jp	(hl)
1871%1:
1872	jp	%5
1873	jp	%6
1874	jp	%7
1875%2:
1876} by {
1877	; peephole 159-3 removed addition using short jumps in jump-table.
1878	pop	de
1879	jp	(hl)
1880%1:
1881	jr	%5
1882	jr	%6
1883	jr	%7
1884%2:
1885} if labelJTInRange
1886
1887replace {
1888	add	hl,de
1889	jp	(hl)
1890%1:
1891	jp	%5
1892	jp	%6
1893	jp	%7
1894%2:
1895} by {
1896	; peephole 159-3' removed addition using short jumps in jump-table.
1897	jp	(hl)
1898%1:
1899	jr	%5
1900	jr	%6
1901	jr	%7
1902%2:
1903} if labelJTInRange
1904
1905replace {
1906	add	hl,de
1907	pop	de
1908	jp	(hl)
1909%1:
1910	jp	%5
1911	jp	%6
1912	jp	%7
1913	jp	%8
1914%2:
1915} by {
1916	; peephole 159-4 removed addition using short jumps in jump-table.
1917	pop	de
1918	jp	(hl)
1919%1:
1920	jr	%5
1921	jr	%6
1922	jr	%7
1923	jr	%8
1924%2:
1925} if labelJTInRange
1926
1927replace {
1928	add	hl,de
1929	jp	(hl)
1930%1:
1931	jp	%5
1932	jp	%6
1933	jp	%7
1934	jp	%8
1935%2:
1936} by {
1937	; peephole 159-4' removed addition using short jumps in jump-table.
1938	jp	(hl)
1939%1:
1940	jr	%5
1941	jr	%6
1942	jr	%7
1943	jr	%8
1944%2:
1945} if labelJTInRange
1946
1947replace {
1948	add	hl,de
1949	pop	de
1950	jp	(hl)
1951%1:
1952	jp	%5
1953	jp	%6
1954	jp	%7
1955	jp	%8
1956	jp	%9
1957%2:
1958} by {
1959	; peephole 159-5 removed addition using short jumps in jump-table.
1960	pop	de
1961	jp	(hl)
1962%1:
1963	jr	%5
1964	jr	%6
1965	jr	%7
1966	jr	%8
1967	jr	%9
1968%2:
1969} if labelJTInRange
1970
1971replace {
1972	add	hl,de
1973	jp	(hl)
1974%1:
1975	jp	%5
1976	jp	%6
1977	jp	%7
1978	jp	%8
1979	jp	%9
1980%2:
1981} by {
1982	; peephole 159-5' removed addition using short jumps in jump-table.
1983	jp	(hl)
1984%1:
1985	jr	%5
1986	jr	%6
1987	jr	%7
1988	jr	%8
1989	jr	%9
1990%2:
1991} if labelJTInRange
1992
1993replace {
1994	add	hl,de
1995	pop	de
1996	jp	(hl)
1997%1:
1998	jp	%5
1999	jp	%6
2000	jp	%7
2001	jp	%8
2002	jp	%9
2003	jp	%10
2004%2:
2005} by {
2006	; peephole 159-6 removed addition using short jumps in jump-table.
2007	pop	de
2008	jp	(hl)
2009%1:
2010	jr	%5
2011	jr	%6
2012	jr	%7
2013	jr	%8
2014	jr	%9
2015	jr	%10
2016%2:
2017} if labelJTInRange
2018
2019replace {
2020	add	hl,de
2021	jp	(hl)
2022%1:
2023	jp	%5
2024	jp	%6
2025	jp	%7
2026	jp	%8
2027	jp	%9
2028	jp	%10
2029%2:
2030} by {
2031	; peephole 159-6' removed addition using short jumps in jump-table.
2032	jp	(hl)
2033%1:
2034	jr	%5
2035	jr	%6
2036	jr	%7
2037	jr	%8
2038	jr	%9
2039	jr	%10
2040%2:
2041} if labelJTInRange
2042
2043replace {
2044	add	hl,de
2045	pop	de
2046	jp	(hl)
2047%1:
2048	jp	%5
2049	jp	%6
2050	jp	%7
2051	jp	%8
2052	jp	%9
2053	jp	%10
2054	jp	%11
2055%2:
2056} by {
2057	; peephole 159-7 removed addition using short jumps in jump-table.
2058	pop	de
2059	jp	(hl)
2060%1:
2061	jr	%5
2062	jr	%6
2063	jr	%7
2064	jr	%8
2065	jr	%9
2066	jr	%10
2067	jr	%11
2068%2:
2069} if labelJTInRange
2070
2071replace {
2072	add	hl,de
2073	jp	(hl)
2074%1:
2075	jp	%5
2076	jp	%6
2077	jp	%7
2078	jp	%8
2079	jp	%9
2080	jp	%10
2081	jp	%11
2082%2:
2083} by {
2084	; peephole 159-7' removed addition using short jumps in jump-table.
2085	jp	(hl)
2086%1:
2087	jr	%5
2088	jr	%6
2089	jr	%7
2090	jr	%8
2091	jr	%9
2092	jr	%10
2093	jr	%11
2094%2:
2095} if labelJTInRange
2096
2097barrier
2098
2099// Do all jump optimizations before replacing by ret.
2100
2101replace restart {
2102	jp	%5
2103} by {
2104	ret
2105	; peephole 160 replaced jump by return.
2106} if labelIsReturnOnly(%5), labelRefCountChange(%5 -1)
2107
2108replace restart {
2109	jp	%1,%5
2110} by {
2111	ret	%1
2112	; peephole 161 replaced jump by return.
2113} if labelIsReturnOnly(%5), labelRefCountChange(%5 -1)
2114
2115// Replace jp by ret before replacing jp by jr outside of jump tables, since using ret can reduce the number of references to jump labels.
2116barrier
2117
2118replace {
2119	jp	%5
2120} by {
2121	jr	%5
2122	; peephole 162 changed absolute to relative unconditional jump.
2123} if labelInRange(%5)
2124
2125replace {
2126	jp	Z,%5
2127} by {
2128	jr	Z,%5
2129	; peephole 163 changed absolute to relative conditional jump.
2130} if labelInRange(%5)
2131
2132replace {
2133	jp	NZ,%5
2134} by {
2135	jr	NZ,%5
2136	; peephole 164 changed absolute to relative conditional jump.
2137} if labelInRange(%5)
2138
2139replace {
2140	jp	C,%5
2141} by {
2142	jr	C,%5
2143	; peephole 165 changed absolute to relative conditional jump.
2144} if labelInRange(%5)
2145
2146replace {
2147	jp	NC,%5
2148} by {
2149	jr	NC,%5
2150	; peephole 166 changed absolute to relative conditional jump.
2151} if labelInRange(%5)
2152
2153replace {
2154	dec b
2155	jr	NZ,	%5
2156} by {
2157	djnz	%5
2158	; peephole 167 used djnz
2159}
2160
2161barrier
2162