Announce SDCC 4.5.0 RC3.
[sdcc.git] / sdcc / src / f8 / peeph.def
blobe33c5c0268d939295e1720fd27803de1f5b46991
1 // peeph.def - F8 peephole rules
3 replace restart {
4 %1 %2, %3
5 } by {
6 ; peephole 0 removed dead load into %2 from %3.
7 } if same(%1 'ld' 'ldw'), notUsed(%2), notVolatile(%3), notUsed('nf' 'zf')
9 replace restart {
10 %1 %2
11 } by {
12 ; peephole 0a removed dead clear of %2.
13 } if same(%1 'clr' 'clrw'), notUsed(%2)
15 replace restart {
16 pop %1
17 push %1
18 } by {
19 ; peephole 0a' removed dead pop / push pair.
20 } if notUsed(%1)
22 replace restart {
23 popw %1
24 pushw %1
25 } by {
26 ; peephole 0a'' removed dead popw / pushw pair.
27 } if notUsed(%1)
29 replace restart {
30 clrw x
31 } by {
32 clr xl
33 ; peephole 0b cleared xl instead of x.
34 } if notUsed('xh')
36 replace restart {
37 ldw x, (%1, sp)
38 } by {
39 ld xl, (%1, sp)
40 ; peephole 0c loaded xl instead of x.
41 } if notUsed('xh'), notUsed('nf' 'zf')
43 replace restart {
44 ldw x, (y)
45 } by {
46 ld xl, (y)
47 ; peephole 0d loaded xl instead of x.
48 } if notUsed('xh'), notUsed('nf' 'zf')
50 replace restart {
51 ld %1, (y)
52 ld xl, %1
53 } by {
54 ld xl, (y)
55 ; peephole 0e loaded xl directly instead of via %1
56 } if notUsed(%1)
58 replace restart {
59 ldw %1, (y)
60 ldw y, %1
61 } by {
62 ldw y, (y)
63 ; peephole 0f loaded xl directly instead of via %1
64 } if notUsed(%1)
66 replace restart {
67 %1 (%3, sp), %2
68 %1 %2, (%3, sp)
69 } by {
70 %1 (%3, sp), %2
71 ; peephole 1 removed redundant %1 from (%3, sp) into %2.
72 } if same(%1 'ld' 'ldw'), notUsed('nf' 'zf')
74 replace restart {
75 push %1
76 ld (0, sp), %1
77 } by {
78 push %1
79 ; peephole 1b removed redundant ld.
82 replace restart {
83 pushw %1
84 ldw (0, sp), %1
85 } by {
86 pushw %1
87 ; peephole 1c removed redundant ldw.
90 replace restart {
91 %1 %2
92 } by {
93 ; peephole 1d removed dead %1 %2.
94 } if same(%1 'tst' 'tstw'), notVolatile(%2), notUsed('cf' 'zf' 'nf' 'of')
96 replace restart {
97 ldw %1, y
98 ldw y, %1
99 } by {
100 ldw %1, y
101 ; peephole 1e removed redundant ldw.
102 } if same(%1 'x' 'z' 'sp')
104 replace restart {
105 ldw %1, y
106 ldw (%2, sp), %1
107 } by {
108 ldw %1, y
109 ldw (%2, sp), y
110 ; peephole 1f loaded (%2, sp) from y instead of %1.
113 replace restart {
114 ldw (%2, sp), y
115 ldw %1, (%2, sp)
116 } by {
117 ldw (%2, sp), y
118 ldw %1, y
119 ; peephole 1g loaded %1 from y instead of (%2, sp).
120 } if same(%1 'x' 'z')
122 replace restart {
123 %1 %2, %3
124 tst %2
125 } by {
126 %1 %2, %3
127 ; peephole 2 removed redundant tst after %1
128 } if same(%1 'and' 'or' 'xor'), notVolatile(%2)
130 replace restart {
131 ld %1, xl
132 tst %1
133 } by {
134 ld %1, xl
135 tst xl
136 ; peephole 3 tested xl instead of %1
137 } if notVolatile(%1)
139 replace restart {
140 ld xl, %1
141 tst %1
142 } by {
143 ld xl, %1
144 tst xl
145 ; peephole 4 tested xl instead of %1
146 } if notVolatile(%1)
148 replace restart {
149 ld (%1, sp), xl
150 tst (%1, sp)
151 } by {
152 ld (%1, sp), xl
153 tst xl
154 ; peephole 5 tested xl instead of (%1, sp)
157 replace restart {
158 ldw %1, y
159 tstw %1
160 } by {
161 ldw %1, y
162 tstw y
163 ; peephole 6 tested y instead of %1
164 } if notVolatile(%1)
166 replace restart {
167 ldw y, %1
168 tstw %1
169 } by {
170 ldw y, %1
171 tstw y
172 ; peephole 7 tested y instead of %1
173 } if notVolatile(%1)
175 replace restart {
176 ldw (%1, sp), y
177 tstw (%1, sp)
178 } by {
179 ldw (%1, sp), y
180 tstw y
181 ; peephole 7 tested y instead of (%1, sp)
184 replace restart {
185 %1 %2, %3
186 tstw %2
187 } by {
188 %1 %2, %3
189 ; peephole 8 removed redundant tstw after %1.
190 } if same(%1 'orw' 'xorw'), notVolatile(%2), notUsed('cf' 'of')
192 replace restart {
193 %1 %3, (%4, sp)
194 %2 %3
195 } by {
196 %1 %3, (%4, sp)
197 ; peephole 8a removed redundant %2 %3 after %1.
198 } if same(%1 'ld' 'ldw'), same(%2 'tst' 'tstw'), notUsed('cf' 'of')
200 replace restart {
201 %1 %3, (y)
202 %2 %3
203 } by {
204 %1 %3, (y)
205 ; peephole 8b removed redundant %2 %3 after %1.
206 } if same(%1 'ld' 'ldw'), same(%2 'tst' 'tstw'), notUsed('cf' 'of')
208 replace restart {
209 ld %1, %2
210 dec %2
211 tst %1
212 jrnz #%5
213 } by {
214 ld %1, %2
215 dec %2
216 jrc #%5
217 ; peephole 9a removed tst by adjusting jump condition
218 } if notVolatile(%1), notVolatile(%2), notUsed('cf' 'nf' 'zf' 'of'), notUsedFrom(%5 'cf' 'nf' 'zf' 'of')
220 replace restart {
221 ld %1, %2
222 dec %2
223 tst %1
224 jrz #%5
225 } by {
226 ld %1, %2
227 dec %2
228 jrnc #%5
229 ; peephole 9b removed tst by adjusting jump condition
230 } if notVolatile(%1), notVolatile(%2), notUsed('cf' 'nf' 'zf' 'of'), notUsedFrom(%5 'cf' 'nf' 'zf' 'of')
232 replace restart {
233 ld %1, xl
234 dec xl
235 tst zh
236 jrz #%2
237 } by {
238 ld %1, xl
239 dec xl
240 jrnc #%2
241 ; peephole 10 removed tst by adjusting jump condition
242 } if notVolatile(%1), notUsed('cf' 'nf' 'zf' 'of'), notUsedFrom(%2 'cf' 'nf' 'zf' 'of')
244 replace restart {
245 clr %1
246 srl %1
247 } by {
248 tst %1
249 ; peephole 11 replaced clr-srl by tst.
250 } if notVolatile(%1), notUsed(%1), notUsed('cf' 'of')
252 replace restart {
253 %2 %1
254 tst %1
255 } by {
256 %2 %1
257 ; peephole 12 removed redundant tst.
258 } if same(%2 'da' 'dec' 'inc' 'sll' 'sra' 'srl' 'tst' 'rlc' 'rrc'), notVolatile(%1), notUsed('cf' 'of')
260 replace restart {
261 %2 %1
262 tstw %1
263 } by {
264 %2 %1
265 ; peephole 13 removed redundant tstw.
266 } if same(%2 'adcw' 'decw' 'incw' 'mul' 'negw' 'rlcw' 'sbcw' 'sllw' 'sraw' 'srlw' 'rrcw' 'sbcw' 'tstw'), notVolatile(%1), notUsed('cf' 'of')
268 replace restart {
269 %2 %1, %3
270 tst %1
271 } by {
272 %2 %1, %3
273 ; peephole 14 removed redundant tst.
274 } if same(%2 'adc' 'add' 'and' 'cp' 'or' 'rot' 'sbc' 'sub' 'xor'), notVolatile(%1), notUsed('cf' 'of')
276 ; addw sp, #d does not set flags, but there is no tstw sp, either.
277 replace restart {
278 %2 %1, %3
279 tstw %1
280 } by {
281 %2 %1, %3
282 ; peephole 15 removed redundant tstw.
283 } if same(%2 'adcw' 'addw' 'cpw' 'orw' 'sbcw' 'sllw' 'subw' 'xorw'), notVolatile(%1), notUsed('cf' 'of')
285 replace restart {
286 tstw (%1, sp)
287 %2 #%3
288 ldw y, (%1, sp)
289 } by {
290 ldw y, (%1, sp)
291 ; peephole 16 moved ldw to replace tstw.
292 %2 #%3
294 } if same(%2 'jr' 'jrc' 'jrgt' 'jrle' 'jrn' 'jrnc' 'jrnn' 'jrno' 'jrnz' 'jro' 'jrsge' 'jrsgt' 'jrsle' 'jrslt' 'jrz'), notUsedFrom(%3 'y' 'cf' 'of'), notUsed('cf' 'of')
296 replace restart {
297 clr xh
298 clr xl
299 } by {
300 clrw x
301 ; peephole 17a merged clr into clrw
304 replace restart {
305 clr xl
306 clr xh
307 } by {
308 clrw x
309 ; peephole 17b merged clr into clrw
312 replace restart {
313 clr (%1, sp)
314 clr (%2, sp)
315 } by {
316 clrw (%1, sp)
317 ; peephole 17c merged clr to clrw
318 } if immdInRange(1 1 '-' %2 %1 %3)
320 replace restart {
321 ld %1, (%2)
322 incw %2
323 tst %1
324 } by {
325 ld %1, (%2)
326 incnw %2
327 ; peephole 18a removed tst by using incnw.
328 } if notUsed('cf' 'of')
330 replace restart {
331 ldw %1, (%2)
332 incw %2
333 tstw %1
334 } by {
335 ldw %1, (%2)
336 incnw %2
337 ; peephole 18b removed tstw by using incnw.
338 } if notUsed('cf' 'of')
340 replace restart {
341 ldw %1, #%2
342 ld %3, %2
343 } by {
344 ldw %1, #%2
345 ; peephole 19 reused adddress in %1.
346 ld %3, (%1)
349 replace restart {
350 ldw %1, sp
351 ldw y, sp
352 } by {
353 ldw y, sp
354 ; peephole 20 used sp from y.
355 ldw %1, y
358 replace restart {
359 jp #%5
360 } by {
361 jp #%6
362 ; peephole j0 jumped to %6 directly instead of via %5.
363 } if labelIsUncondJump(), notSame(%5 %6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
365 replace restart {
366 jp #%1
368 } by {
370 ; peephole j1 removed redundant jump.
371 } if labelRefCountChange(%1 -1)
373 replace restart {
374 jp #%1
377 } by {
380 ; peephole j2 removed redundant jump.
381 } if labelRefCountChange(%1 -1)
383 replace restart {
384 jp #%1
385 jp #%2
386 } by {
387 jp #%1
388 ; peephole j3a removed unreachable jump to %2.
389 } if labelRefCountChange(%2 -1)
391 replace restart {
392 jr #%1
393 jp #%2
394 } by {
395 jr #%1
396 ; peephole j3b removed unreachable jump to %2.
397 } if labelRefCountChange(%2 -1)
399 replace restart {
400 jp #%1
401 jr #%2
402 } by {
403 jp #%1
404 ; peephole j3c removed unreachable jump to %2.
405 } if labelRefCountChange(%2 -1)
407 replace restart {
408 jr #%1
409 jr #%2
410 } by {
411 jr #%1
412 ; peephole j3d removed unreachable jump to %2.
413 } if labelRefCountChange(%2 -1)
415 replace {
416 jp #%5
418 } by {
419 jp #%5
420 ; peephole j4 removed unreachable ret.
423 replace restart {
424 jp #%5
425 addw sp, %1
426 } by {
427 jp #%5
428 ; peephole j5 removed unreachable addw.
431 // Ensure jump-to-jump optimization of absolute jumps above is done before other jump-related optimizations.
432 barrier
434 replace restart {
435 jp #%5
436 } by {
437 jr #%5
438 ; peephole j6 changed absolute to relative unconditional jump.
439 } if labelInRange(%5)
441 replace restart {
442 jrz #%1
443 jr #%5
445 } by {
446 jrnz #%5
447 ; peephole j7a removed jr by using inverse jump logic
449 } if labelRefCountChange(%1 -1)
451 replace restart {
452 jrnz #%1
453 jr #%5
455 } by {
456 jrz #%5
457 ; peephole j7b removed jr by using inverse jump logic
459 } if labelRefCountChange(%1 -1)
461 replace restart {
462 jrc #%1
463 jr #%5
465 } by {
466 jrnc #%5
467 ; peephole j7c removed jr by using inverse jump logic
469 } if labelRefCountChange(%1 -1)
471 replace restart {
472 jrnc #%1
473 jr #%5
475 } by {
476 jrc #%5
477 ; peephole j7d removed jr by using inverse jump logic
479 } if labelRefCountChange(%1 -1)
481 replace restart {
482 jrn #%1
483 jr #%5
485 } by {
486 jrnn #%5
487 ; peephole j7e removed jr by using inverse jump logic
489 } if labelRefCountChange(%1 -1)
491 replace restart {
492 jrnn #%1
493 jr #%5
495 } by {
496 jrn #%5
497 ; peephole j7f removed jr by using inverse jump logic
499 } if labelRefCountChange(%1 -1)
501 replace restart {
502 jro #%1
503 jr #%5
505 } by {
506 jrno #%5
507 ; peephole j7g removed jr by using inverse jump logic
509 } if labelRefCountChange(%1 -1)
511 replace restart {
512 jrno #%1
513 jr #%5
515 } by {
516 jro #%5
517 ; peephole j7h removed jr by using inverse jump logic
519 } if labelRefCountChange(%1 -1)
521 replace restart {
522 jrsge #%1
523 jr #%5
525 } by {
526 jrslt #%5
527 ; peephole j7i removed jr by using inverse jump logic
529 } if labelRefCountChange(%1 -1)
531 replace restart {
532 jrslt #%1
533 jr #%5
535 } by {
536 jrsge #%5
537 ; peephole j7j removed jr by using inverse jump logic
539 } if labelRefCountChange(%1 -1)
541 replace restart {
542 jrsgt #%1
543 jr #%5
545 } by {
546 jrsle #%5
547 ; peephole j7k removed jr by using inverse jump logic
549 } if labelRefCountChange(%1 -1)
551 replace restart {
552 jrsle #%1
553 jr #%5
555 } by {
556 jrsgt #%5
557 ; peephole j7l removed jr by using inverse jump logic
559 } if labelRefCountChange(%1 -1)
561 replace restart {
562 jrgt #%1
563 jr #%5
565 } by {
566 jrle #%5
567 ; peephole j7m removed jr by using inverse jump logic
569 } if labelRefCountChange(%1 -1)
571 replace restart {
572 jrle #%1
573 jr #%5
575 } by {
576 jrgt #%5
577 ; peephole j7n removed jr by using inverse jump logic
579 } if labelRefCountChange(%1 -1)
581 replace restart {
582 %1 #%5
583 } by {
584 %1 #%6
585 ; peephole j8 jumped to %6 directly instead of via %5.
586 } if same(%1 'jr' 'jrc' 'jrgt' 'jrle' 'jrn' 'jrnc' 'jrnn' 'jrno' 'jrnz' 'jro' 'jrsge' 'jrsgt' 'jrsle' 'jrslt' 'jrz'), labelIsUncondJump(), notSame(%5 %6), labelInRange(%6), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1)
588 // Do the jump-to-ret optimization after all jump inversion optimizations, to optimize jr z, %1; jp %retlabel; %1: into jr nz, %retlabel instead of jr z, %1; ret; %1:.
589 barrier
591 replace restart {
592 jp #%5
593 } by {
595 ; peephole j9 replaced jump by return.
596 } if labelIsReturnOnly(%5), labelRefCountChange(%5 -1)
598 replace restart {
599 jr #%5
600 } by {
602 ; peephole j10 replaced jump by return.
603 } if labelIsReturnOnly(%5), labelRefCountChange(%5 -1)
605 // Should be one of the last ones. Opens the code to further peephole optimization.
606 replace restart {
608 } by {
609 ; peephole j21 removed unused label %1.
610 } if labelRefCount(%1 0)