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