From 3d5f7dfa8edf8ea9a0e1b0d74ab0daadbf7e819c Mon Sep 17 00:00:00 2001 From: MaartenBrock Date: Sat, 5 May 2007 13:45:50 +0000 Subject: [PATCH] * src/port.h: added TARGET_MCS51_LIKE * src/SDCCpeeph.c (labelIsUncondJump): new, added, other targets could take advantage of it too * src/z80/gen.c (genIpush): push b, d or h directly instead of using a, (shiftR2Left2Result): Optimized: don't check shifting by 0 * src/z80/peeph-z80.def, * src/z80/peeph.def: whole set of new rules by Philipp Krause with some modifications, see patch 1700823 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4786 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 11 + src/SDCCpeeph.c | 131 +++++++-- src/port.h | 23 +- src/z80/gen.c | 27 +- src/z80/peeph-z80.def | 256 +++++++++++------ src/z80/peeph.def | 631 +++++++++++++++++++++++++++++------------- 6 files changed, 751 insertions(+), 328 deletions(-) diff --git a/ChangeLog b/ChangeLog index 39ff8af8..93b3c663 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-05-05 Maarten Brock + + * src/port.h: added TARGET_MCS51_LIKE + * src/SDCCpeeph.c (labelIsUncondJump): new, added, other targets could + take advantage of it too + * src/z80/gen.c (genIpush): push b, d or h directly instead of using a, + (shiftR2Left2Result): Optimized: don't check shifting by 0 + * src/z80/peeph-z80.def, + * src/z80/peeph.def: whole set of new rules by Philipp Krause with some + modifications, see patch 1700823 + 2007-05-05 Borut Razem * device/lib/pic16/Makefile.common.in, diff --git a/src/SDCCpeeph.c b/src/SDCCpeeph.c index daf96c3a..a4341f1f 100644 --- a/src/SDCCpeeph.c +++ b/src/SDCCpeeph.c @@ -45,6 +45,7 @@ static struct static int hashSymbolName (const char *name); static void buildLabelRefCountHash (lineNode * head); +static void bindVar (int key, char **s, hTab ** vtab); static bool matchLine (char *, char *, hTab **); @@ -237,26 +238,32 @@ FBYNAME (labelIsReturnOnly) return FALSE; label = hTabItemWithKey (vars, 5); - if (!label) return FALSE; + if (!label) + return FALSE; len = strlen(label); - for(pl = currPl; pl; pl = pl->next) { - if (pl->line && !pl->isDebug && !pl->isComment && - pl->isLabel) { - if (strncmp(pl->line, label, len) == 0) break; /* Found Label */ - if (strlen(pl->line) != 7 || !ISCHARDIGIT(*(pl->line)) || - !ISCHARDIGIT(*(pl->line+1)) || !ISCHARDIGIT(*(pl->line+2)) || - !ISCHARDIGIT(*(pl->line+3)) || !ISCHARDIGIT(*(pl->line+4)) || - *(pl->line+5) != '$') { - return FALSE; /* non-local label encountered */ - } + for(pl = currPl; pl; pl = pl->next) + { + if (pl->line && !pl->isDebug && !pl->isComment && pl->isLabel) + { + if (strncmp(pl->line, label, len) == 0) + break; /* Found Label */ + if (strlen(pl->line) != 7 || !ISCHARDIGIT(*(pl->line)) || + !ISCHARDIGIT(*(pl->line+1)) || !ISCHARDIGIT(*(pl->line+2)) || + !ISCHARDIGIT(*(pl->line+3)) || !ISCHARDIGIT(*(pl->line+4)) || + *(pl->line+5) != '$') + { + return FALSE; /* non-local label encountered */ + } } - } - if (!pl) return FALSE; /* did not find the label */ + } + if (!pl) + return FALSE; /* did not find the label */ pl = pl->next; while (pl && (pl->isDebug || pl->isComment)) pl = pl->next; - if (!pl || !pl->line || pl->isDebug) return FALSE; /* next line not valid */ + if (!pl || !pl->line || pl->isDebug) + return FALSE; /* next line not valid */ p = pl->line; for (p = pl->line; *p && ISCHARSPACE(*p); p++) ; @@ -264,11 +271,94 @@ FBYNAME (labelIsReturnOnly) retInst = "ret"; if (TARGET_IS_HC08) retInst = "rts"; - if (strcmp(p, retInst) == 0) return TRUE; + if (strcmp(p, retInst) == 0) + return TRUE; return FALSE; } +/*-----------------------------------------------------------------*/ +/* labelIsUncondJump - Check if label %5 is followed by an */ +/* unconditional jump and put the destination of that jump in %6 */ +/*-----------------------------------------------------------------*/ +FBYNAME (labelIsUncondJump) +{ + /* assumes that %5 pattern variable has the label name */ + const char *label; + char *p, *q; + const lineNode *pl; + int len; + char * jpInst = NULL; + + /* Don't optimize jumps in a jump table; a more generic test */ + if (currPl->ic && currPl->ic->op == JUMPTABLE) + return FALSE; + + label = hTabItemWithKey (vars, 5); + if (!label) + return FALSE; + len = strlen(label); + + for (pl = currPl; pl; pl = pl->next) + { + if (pl->line && !pl->isDebug && !pl->isComment && pl->isLabel) + { + if (strncmp(pl->line, label, len) == 0) + break; /* Found Label */ + if (strlen(pl->line) != 7 || !ISCHARDIGIT(*(pl->line)) || + !ISCHARDIGIT(*(pl->line+1)) || !ISCHARDIGIT(*(pl->line+2)) || + !ISCHARDIGIT(*(pl->line+3)) || !ISCHARDIGIT(*(pl->line+4)) || + *(pl->line+5) != '$') + { + return FALSE; /* non-local label encountered */ + } + } + } + if (!pl) + return FALSE; /* did not find the label */ + pl = pl->next; + while (pl && (pl->isDebug || pl->isComment)) + pl = pl->next; + if (!pl || !pl->line) + return FALSE; /* next line not valid */ + p = pl->line; + while (*p && ISCHARSPACE(*p)) + p++; + + if (TARGET_MCS51_LIKE) + jpInst = "ljmp"; + if (TARGET_IS_HC08) + jpInst = "jmp"; + if (TARGET_Z80_LIKE) + jpInst = "jp"; + len = strlen(jpInst); + if (strncmp(p, jpInst, len) != 0) + return FALSE; /* next line is no jump */ + p += len; + while (*p && ISCHARSPACE(*p)) + p++; + + q = p; + while (*q && *q!=';') + q++; + while (q>p && ISCHARSPACE(*q)) + q--; + len = q-p; + if (len == 0) + return FALSE; /* no destination? */ + if (TARGET_Z80_LIKE) + { + while (q>p && *q!=',') + q--; + if (*q==',') + return FALSE; /* conditional jump */ + } + /* now put the destination in %6 */ + bindVar (6, &p, &vars); + return TRUE; +} + + /*-----------------------------------------------------------------*/ /* okToRemoveSLOC - Check if label %1 is a SLOC and not other */ /* usage of it in the code depends on a value from this section */ @@ -946,7 +1036,7 @@ operandBaseName (const char *op) /*-------------------------------------------------------------------*/ -/* operandsNotRelated - returns true of the condition's operands are */ +/* operandsNotRelated - returns true if the condition's operands are */ /* not related (taking into account register name aliases). N-way */ /* comparison performed between all operands. */ /*-------------------------------------------------------------------*/ @@ -1090,6 +1180,9 @@ callFuncByName (char *fname, { "labelIsReturnOnly", labelIsReturnOnly }, + { + "labelIsUncondJump", labelIsUncondJump + }, { "okToRemoveSLOC", okToRemoveSLOC }, @@ -1170,8 +1263,7 @@ callFuncByName (char *fname, { if (strcmp (ftab[i].fname, funcName) == 0) { - rc = (*ftab[i].func) (vars, currPl, endPl, head, - funcArgs); + rc = (*ftab[i].func) (vars, currPl, endPl, head, funcArgs); break; } } @@ -1596,8 +1688,7 @@ matchLine (char *s, char *d, hTab ** vars) return FALSE; } else - /* variable not bound we need to - bind it */ + /* variable not bound we need to bind it */ bindVar (keyForVar (d + 1), &s, vars); /* in either case go past the variable */ diff --git a/src/port.h b/src/port.h index 5dfc1335..fd32518b 100644 --- a/src/port.h +++ b/src/port.h @@ -25,17 +25,18 @@ /* Macro to test the target we are compiling for. Can only be used after SDCCmain has defined the port */ -#define TARGET_IS_MCS51 (port->id==TARGET_ID_MCS51) -#define TARGET_IS_GBZ80 (port->id==TARGET_ID_GBZ80) -#define TARGET_IS_Z80 (port->id==TARGET_ID_Z80) -#define TARGET_Z80_LIKE ((port->id==TARGET_ID_Z80) || (port->id==TARGET_ID_GBZ80)) -#define TARGET_IS_AVR (port->id==TARGET_ID_AVR) -#define TARGET_IS_DS390 (port->id==TARGET_ID_DS390) -#define TARGET_IS_DS400 (port->id==TARGET_ID_DS400) -#define TARGET_IS_PIC (port->id==TARGET_ID_PIC) -#define TARGET_IS_PIC16 (port->id==TARGET_ID_PIC16) -#define TARGET_IS_XA51 (port->id==TARGET_ID_XA51) -#define TARGET_IS_HC08 (port->id==TARGET_ID_HC08) +#define TARGET_IS_MCS51 (port->id==TARGET_ID_MCS51) +#define TARGET_IS_GBZ80 (port->id==TARGET_ID_GBZ80) +#define TARGET_IS_Z80 (port->id==TARGET_ID_Z80) +#define TARGET_Z80_LIKE (TARGET_IS_Z80 || TARGET_IS_GBZ80) +#define TARGET_IS_AVR (port->id==TARGET_ID_AVR) +#define TARGET_IS_DS390 (port->id==TARGET_ID_DS390) +#define TARGET_IS_DS400 (port->id==TARGET_ID_DS400) +#define TARGET_IS_PIC (port->id==TARGET_ID_PIC) +#define TARGET_IS_PIC16 (port->id==TARGET_ID_PIC16) +#define TARGET_IS_XA51 (port->id==TARGET_ID_XA51) +#define TARGET_IS_HC08 (port->id==TARGET_ID_HC08) +#define TARGET_MCS51_LIKE (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_DS400) #define MAX_BUILTIN_ARGS 16 /* definition of builtin functions */ diff --git a/src/z80/gen.c b/src/z80/gen.c index c02557da..54ee2b78 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -2697,13 +2697,23 @@ genIpush (iCode * ic) char *l = aopGetLitWordLong (AOP (IC_LEFT (ic)), --offset, FALSE); wassert (l); emit2 ("ld a,(%s)", l); + emit2 ("push af"); } else { l = aopGet (AOP (IC_LEFT (ic)), --offset, FALSE); - emit2 ("ld a,%s", l); + if (!strcmp(l, "b")) + emit2 ("push bc"); + else if (!strcmp(l, "d")) + emit2 ("push de"); + else if (!strcmp(l, "h")) + emit2 ("push hl"); + else + { + emit2 ("ld a,%s", l); + emit2 ("push af"); + } } - emit2 ("push af"); emit2 ("inc sp"); _G.stack.pushed++; } @@ -3770,8 +3780,6 @@ genPlus (iCode * ic) if (genPlusIncr (ic) == TRUE) goto release; - emitDebug ("; Can't optimise plus by inc, falling back to the normal way"); - size = getDataSize (IC_RESULT (ic)); /* Special case when left and right are constant */ @@ -5750,7 +5758,7 @@ shiftR2Left2Result (operand * left, int offl, int shCount, int is_signed) { int size = 2; - symbol *tlbl, *tlbl1; + symbol *tlbl; movLeft2Result (left, offl, result, offr, 0); movLeft2Result (left, offl + 1, result, offr + 1, 0); @@ -5761,10 +5769,10 @@ shiftR2Left2Result (operand * left, int offl, /* if (AOP(result)->type == AOP_REG) { */ tlbl = newiTempLabel (NULL); - tlbl1 = newiTempLabel (NULL); /* Left is already in result - so now do the shift */ - if (shCount <= 4) + /* Optimizing for speed by default. */ + if (!optimize.codeSize || shCount <= 2) { while (shCount--) { @@ -5773,13 +5781,12 @@ shiftR2Left2Result (operand * left, int offl, } else { - emit2 ("ld a,!immedbyte+1", shCount); - emit2 ("!shortjp !tlabel", tlbl1->key + 100); + emit2 ("ld a,!immedbyte", shCount); + emitLabel (tlbl->key + 100); emitRsh2 (AOP (result), size, is_signed); - emitLabel (tlbl1->key + 100); emit2 ("dec a"); emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); } diff --git a/src/z80/peeph-z80.def b/src/z80/peeph-z80.def index ee3f701b..f717847a 100644 --- a/src/z80/peeph-z80.def +++ b/src/z80/peeph-z80.def @@ -1,126 +1,198 @@ +// peeph-z80.def - Z80 peephole rules +// +// +// (c) Philipp Klaus Krause (pkk@spth.de, philipp@colecovision.eu) 2006 - 2007 +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) any +// later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + replace restart { - ld a,%1(%2) - bit %3,a - jp %4,%5 + ld %1,#%2 + ld a,0(%1) + ld %3,a + ld %1,#%5 } by { - bit %3,%1(%2) - jp %4,%5 + ld a,(#%2) + ; peephole z1 used #%2 directly instead of going through %1 using indirect addressing. + ld %3,a + ld %1,#%5 } -replace { - ld %1,%2 - ld a,%2 + +replace restart { + ld %1,#%2 + ld 0(%1),a +%4: + ld %1,%5 } by { - ld %1,%2 - ld a,%1 + ld (#%2),a + ; peephole z2 directly used #%2 instead of going through %1 using indirect addressing. +%4: + ld %1,%5 } -replace { - ld %1,a - xor a,a - or a,%1 + +replace restart { + pop af + ld %1,#%2 + ld 0(%1),%3 + ld %1,#%4 +} by { + ld a,%3 + ld (#%2),a + ; peephole z3 used #%2 directly instead of going through %1 using indirect addressing. + pop af + ld %1,#%4 +} if operandsNotRelated(%3 'a') + +replace restart { + ld bc,#%1 + %2 + ld a,%3 + ld (bc),a + ld bc,#%4 + %5 } by { - ld %1,a - or a,a + ld a,%3 + ld (#%1 + %2),a + ; peephole z4 directly used address #%1 + %2 instead of placing it in bc first. + ld bc,#%4 + %5 } -replace { - rlca - ld a,#0x00 - rla + +replace restart { + ld bc,#%1 + %2 + %6 + ld a,%3 + ld (bc),a + ld bc,#%4 + %5 } by { - rlca - and a,#0x01 + ld a,%3 + ld (#%1 + %2 + %6),a + ; peephole z5 directly used address #%1 + %2 + %6 instead of placing it in bc first. + ld bc,#%4 + %5 } -replace { - ld %3,a - ld l,%1 - ld h,%2 - ld l,(hl) + +replace restart { + ld bc,#%1 + %2 ld a,%3 + ld (bc),a +%7: + ld bc,#%4 + %5 } by { - ld %3,a - ld l,%1 - ld h,%2 - ld l,(hl) -} if notVolatile %3 + ld a,%3 + ld (#%1 + %2),a + ; peephole z6 directly used address #%1 + %2 instead of placing it in bc first. +%7: + ld bc,#%4 + %5 +} -; -;-------------------------- -; replace restart { - pop %1 - push %1 - ld %1,%2 + ld bc,#%1 + %2 + %6 + ld a,%3 + ld (bc),a +%7: + ld bc,#%4 + %5 } by { - ; z80 removed redundant pop/push - ld %1,%2 + ld a,%3 + ld (#%1 + %2 + %6),a + ; peephole z7 directly used address #%1 + %2 + %6 instead of placing it in bc first. +%7: + ld bc,#%4 + %5 } replace restart { - ld l,a ld c,%1 - ld a,l + ld l,c + ret } by { - ld l,a - ld c,%1 + ld l,%1 + ; peephole z8 moved %1 directly into l instead of going through c. + ret } replace restart { + ld b,h ld c,l - ld a,c - and a,#%1 - ld c,a - or a,a -} by { - ; z80 stream lining 'and' logic - ld a,#%1 - and a,l - ld c,a + pop af + push bc + call %1 +} by { + ex (sp),hl + ; peephole z9 moved hl directly to the stack instead of going through bc. + call %1 } replace restart { - ld a,c - and a,#%1 - ld c,a - or a,a -} by { - ; z80 stream lining 'and' logic - ld a,#%1 - and a,c - ld c,a + ld d,h + ld e,l + pop af + push de + call %1 +} by { + ex (sp),hl + ; peephole z10 moved hl directly to the stack instead of going through de. + call %1 } replace restart { - ld a,c - or a,#%1 - ld c,a -} by { - ; z80 stream lining 'or' logic - ld a,#%1 - or a,c - ld c,a -} + jp %5 +} by { + ret + ; peephole z11 replaced jump by return. +} if labelIsReturnOnly(), labelRefCountChange(%5 -1) +replace restart { + jp %1,%5 +} by { + ret %1 + ; peephole z12 replaced jump by return. +} if labelIsReturnOnly(), labelRefCountChange(%5 -1) -replace { +// Should be one of the last ones. Opens the code to further peephole optimization. +replace restart { %1: - in0 a,(%2) - and a,#%3 - jp Z,%4 -%5: - jp %6 -%4: - call %7 - jp %1 -%6: - ret } by { -%1: - in0 a,(%2) - and a,#%3 + ; peephole z13 removed unused label %1. +} if labelRefCount(%1 0) + +// These should be the last rules, so that the peepholes above need to look at jp only. +replace { + jp %5 +} by { + jr %5 + ; peephole z14 changed absolute to relative conditional jump. +} if labelInRange() + +replace { + jp Z,%5 +} by { + jr Z,%5 + ; peephole z15 changed absolute to relative conditional jump. +} if labelInRange() + +replace { jp NZ,%5 -%4: - call %7 - jp %1 -%5: -%6: - ret -} +} by { + jr NZ,%5 + ; peephole z16 changed absolute to relative conditional jump. +} if labelInRange() + +replace { + jp C,%5 +} by { + jr C,%5 + ; peephole z17 changed absolute to relative conditional jump. +} if labelInRange() + +replace { + jp NC,%5 +} by { + jr NC,%5 + ; peephole z18 changed absolute to relative conditional jump. +} if labelInRange() diff --git a/src/z80/peeph.def b/src/z80/peeph.def index 2fb852b6..e80156af 100644 --- a/src/z80/peeph.def +++ b/src/z80/peeph.def @@ -1,37 +1,54 @@ -replace { - ld (hl),(hl) -} by { - ERROR - peephole - caught (hl),(hl) -} +// peeph.def - Common Z80 and gbz80 peephole rules +// +// +// (c) Philipp Klaus Krause (pkk@spth.de, philipp@colecovision.eu) 2006 - 2007 +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) any +// later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. replace restart { ld %1,%1 } by { - ; peephole removed redundant load. -} + ; peephole 1 removed redundant load. +} if notVolatile(%1) replace restart { - xor a,a - or a,%1 - or a,a - jp %2,%3 + ld %1,%2 + ld %1,%3 } by { - xor a,a - or a,%1 - jp %2,%3 -} + ; peephole 2 removed dead load into %1 + ld %1,%3 +} if notVolatile(%1) replace restart { - jp NZ,%1 + jp NC,%1 jp %2 %1: - jp %3 -%2: } by { - jp Z,%2 + jp C,%2 + ; peephole 3 removed jp by using inverse jump logic +%1: +} if labelRefCountChange(%1 -1) + +replace restart { + jp C,%1 + jp %2 +%1: +} by { + jp NC,%2 + ; peephole 4 removed jp by using inverse jump logic %1: - jp %3 -%2: } if labelRefCountChange(%1 -1) replace restart { @@ -40,6 +57,7 @@ replace restart { %1: } by { jp Z,%2 + ; peephole 5 removed jp by using inverse jump logic %1: } if labelRefCountChange(%1 -1) @@ -49,76 +67,67 @@ replace restart { %1: } by { jp NZ,%2 + ; peephole 6 removed jp by using inverse jump logic %1: } if labelRefCountChange(%1 -1) replace restart { - or a,%1 - or a,a + jp %5 } by { - or a,%1 -} + jp %6 + ; peephole 7 redirected jump-to-jump at %5 by jump to %6 +} if labelIsUncondJump(), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1) replace restart { - or a,%1) - or a,a -} by { - or a,%1) -} - -replace restart { - xor a,a - or a,%1 - jp NZ,%2 - xor a,a - or a,%3 - jp Z,%2 + jp %1,%5 } by { - xor a,a - or a,%1 - jp NZ,%2 - or a,%3 - jp Z,%2 -} + jp %1,%6 + ; peephole 8 redirected jump-to-jump at %5 by jump to %6 +} if labelIsUncondJump(), labelRefCountChange(%5 -1), labelRefCountChange(%6 +1) replace restart { - jp NZ,%1 - inc %3) -%1: - jp %2 + ld %2,%3 + jp %4 +%5: + ld %2,%3 +%4: } by { - jp NZ,%2 - inc %3) -%1: - jp %2 -} if labelRefCountChange(%1 -1), labelRefCountChange(%2 1) + ; peephole 9 removed jump and redundant load. +%5: + ld %2,%3 +%4: +} if labelRefCountChange(%4 -1) replace restart { xor a,a ld a,#0x00 } by { xor a,a + ; peephole 10 removed redundant load of 0 into a. } replace { - ld e,#0x00 - ld d,#0x00 + ld e,#0x%1 + ld d,#0x%2 } by { - ld de,#0x0000 + ld de,#0x%2%1 + ; peephole 11 combined constant loads into register pair. } replace { - ld l,#0x00 - ld h,#0x00 + ld l,#0x%1 + ld h,#0x%2 } by { - ld hl,#0x0000 + ld hl,#0x%2%1 + ; peephole 12 combined constant loads into register pair. } replace { - ld c,#0x00 - ld b,#0x00 + ld c,#0x%1 + ld b,#0x%2 } by { - ld bc,#0x0000 + ld bc,#0x%2%1 + ; peephole 13 combined constant loads into register pair. } replace restart { @@ -126,139 +135,350 @@ replace restart { ld a,%1 } by { ld %1,a -} if notVolatile %1 + ; peephole 14 removed redundant load from %1 into a. +} if notVolatile(%1) +// This gives many false negatives and without the test no problems are encountered in the regression tests +// Maybe we can try this after 2.7.0 release replace restart { - jp %1,%2 - jr %3 -%2: - jp %4 + ld a,%1 + ld %1,a } by { - jp %1,%4 - jr %3 -%2: - jp %4 -} if labelRefCountChange(%2 -1), labelRefCountChange(%4 1) + ld a,%1 + ; peephole 15 removed redundant load from a into %1. +} if notVolatile(%1) +// This gives many false negatives and without the test no problems are encountered in the regression tests +// Maybe we can try this after 2.7.0 release -replace { - ld l,e - ld h,d - push hl - ld l,c - ld h,b - push hl +replace restart { + ld %2,%3 + ld a,%2 + and a,%1 + ld %2,%4 } by { - push de - push bc + ld a,%3 + ; peephole 16 moved %3 directly into a instead of going through %2. + and a,%1 + ld %2,%4 +} if notVolatile(%2), operandsNotSame + +replace restart { + ld %1,a + ld a,%2 + or a,%1 +} by { + ld %1,a + or a,%2 + ; peephole 17 removed load by reordering or arguments. +} if notVolatile(%1) + +replace restart { + ld %1,a + xor a,a + or a,%1 +} by { + ld %1,a + or a,a + ; peephole 18 used value still in a instead of loading it from %1. } -replace { - and a,#%1 +replace restart { + or a,%1 or a,a } by { - and a,#%1 + or a,%1 + ; peephole 19 removed redundant or after or. +} + +replace restart { + and a,%1 + or a,a +} by { + and a,%1 + ; peephole 20 removed redundant or after and. } +replace restart { + xor a,%1 + or a,a +} by { + xor a,%1 + ; peephole 21 removed redundant or after xor. +} + +replace restart { + ld %1,a + and a,%2 + ld %1,a +} by { + ; peephole 22 removed redundant load into %1. + and a,%2 + ld %1,a +} if notVolatile(%1) + replace { - ld b,l + ld %1,%2 + ld a,%2 +} by { + ld a,%2 + ld %1,a + ; peephole 23 load value in a first and use it next +} if notVolatile(%1 %2) + +replace restart { + ld %1,%2 + ld %3,%4 + ld %2,%1 + ld %4,%3 +} by { + ld %1,%2 + ld %3,%4 + ; peephole 24 removed redundant load from %3%1 into %4%2 +} if notVolatile(%1 %2 %3 %4) + +replace restart { + ld b,%1 ld a,b pop bc - ld b,a } by { - ld a,l + ld a,%1 + ; peephole 25 removed load into b pop bc - ld b,a } -replace { - ld d,l +replace restart { + ld c,%1 + ld a,c + pop bc +} by { + ld a,%1 + ; peephole 26 removed load into c + pop bc +} + +replace restart { + ld d,%1 ld a,d pop de - ld d,a } by { - ld a,l + ld a,%1 + ; peephole 27 removed load into d pop de - ld d,a } -replace { - ld a,b +replace restart { + ld e,%1 + ld a,e + pop de +} by { + ld a,%1 + ; peephole 28 removed load into e + pop de +} + +replace restart { + ld h,%1 + ld a,h + pop hl +} by { + ld a,%1 + ; peephole 29 removed load into h + pop hl +} + +replace restart { + ld l,%1 + ld a,l + pop hl +} by { + ld a,%1 + ; peephole 30 removed load into l + pop hl +} + +replace restart { + ld a,c push af inc sp + ld a,#%2 + push af + inc sp + call %3 } by { + ld b,c + ld c,#%2 push bc - inc sp + ; peephole 31 moved and pushed arguments c and #%2 through bc instead of pushing them individually. + call %3 } -replace { - ld a,d +replace restart { + ld a,e + push af + inc sp + ld a,#%2 push af inc sp + call %3 } by { + ld d,e + ld e,#%2 push de - inc sp + ; peephole 32 moved and pushed arguments e and #%2 through de instead of pushing them individually. + call %3 } -replace { +replace restart { ld a,%1 - sub a,#%2 - jp M,%3 + sub a,%2 + jp %3,%4 ld a,%1 - sub a,#%4 - jp P,%5 } by { ld a,%1 + cp a,%2 + jp %3,%4 + ; peephole 33 removed load by replacing sub with cp + assert a=%1 +} if notVolatile(%1) + +replace restart { + assert a=%1 + sub a,%2 + jp %3,%4 + ld a,%1 +} by { cp a,#%2 - jp M,%3 - cp a,#%4 - jp P,%5 + jp %3,%4 + ; peephole 34 removed load by replacing sub with cp + assert a=%1 } -replace { - ld e,l - ld d,h - ld l,e - ld h,d +replace restart { + assert a=%1 } by { - ld e,l - ld d,h } -replace { - ld %1,%2 - ld %3,%4 - ld %2,%1 - ld %4,%3 +replace restart { + sub a,#0xFF + jp Z,%1 +} by { + inc a + ; peephole 35 replaced sub a,#0xFF by inc a. + jp Z,%1 +} + +replace restart { + sub a,#0xFF + jp NZ,%1 +} by { + inc a + ; peephole 36 replaced sub a,#0xFF by inc a. + jp NZ,%1 +} + +replace restart { + ld bc,#%1 + %2 + ld a,c + add a,%3 + ld c,a + ld a,b + adc a,%4 + ld b,a } by { + ld a,#<(%1 + %2) + add a,%3 + ld c,a + ld a,#>(%1 + %2) + ; peephole 37 directly used (%1 + %2) in calculation instead of placing it in bc first. + adc a,%4 + ld b,a +} + +replace restart { + ld de,#%1 + %2 + ld a,e + add a,%3 + ld e,a + ld a,d + adc a,%4 + ld d,a +} by { + ld a,#<(%1 + %2) + add a,%3 + ld e,a + ld a,#>(%1 + %2) + ; peephole 38 directly used (%1 + %2) in calculation instead of placing it in de first. + adc a,%4 + ld d,a +} + +replace restart { + rlca + ld a,#0x00 + rla +} by { + rlca + and a,#0x01 + ; peephole 39 replaced zero load, rla by and since rlca writes the same value to carry bit and least significant bit. +} + +replace restart { ld %1,%2 - ld %3,%4 + push %1 + pop %4 + ld %1,%3 +} by { + ld %4,%2 + ; peephole 40 moved %2 directly into de instead of going through %1. + ld %1,%3 +} + +replace restart { + add a,#0x00 + ld %2,a + ld a,%3 + adc a,%4 +} by { + ; peephole 41 removed lower part of multibyte addition. + ld %2,a + ld a,%3 + add a,%4 } -// From: Philipp Klaus Krause replace restart { ld %1,a ld a,%2 add a,%1 ld %1,a } by { - ; peephole removed loads by exploiting commutativity of addition. + ; peephole 42 removed loads by exploiting commutativity of addition. add a,%2 ld %1,a -} +} if notVolatile(%1) -// From: Philipp Klaus Krause replace restart { ld %1,a ld a,%2 add a,%1 } by { ld %1, a - ; peephole removed load by exploiting commutativity of addition. - add a, %2 + ; peephole 43 removed load by exploiting commutativity of addition. + add a,%2 } -// From: Philipp Klaus Krause -replace { +replace restart { + or a,%1 + jp NZ,%2 + xor a,a + or a,%3 +} by { + or a,%1 + jp NZ,%2 + ; peephole 44 removed redundant zeroing of a (which has just been tested to be #0x00). + or a,%3 +} + +replace restart { or a,%1 jp NZ,%2 ld %3,#0x00 @@ -266,11 +486,10 @@ replace { or a,%1 jp NZ,%2 ld %3,a - ; peephole replaced constant #0x00 by a (which has just been tested to be #0x00). + ; peephole 45 replaced constant #0x00 by a (which has just been tested to be #0x00). } -// From: Philipp Klaus Krause -replace { +replace restart { and a,%1 jp NZ,%2 ld %3,#0x00 @@ -278,11 +497,10 @@ replace { and a,%1 jp NZ,%2 ld %3,a - ; peephole replaced constant #0x00 by a (which has just been tested to be #0x00). + ; peephole 46 replaced constant #0x00 by a (which has just been tested to be #0x00). } -// From: Philipp Klaus Krause -replace { +replace restart { sub a,%1 jp NZ,%2 ld %3,#0x00 @@ -290,11 +508,10 @@ replace { sub a,%1 jp NZ,%2 ld %3,a - ; peephole replaced constant #0x00 by a (which has just been tested to be #0x00). + ; peephole 47 replaced constant #0x00 by a (which has just been tested to be #0x00). } -// From: Philipp Klaus Krause -replace { +replace restart { dec a jp NZ,%1 ld %2,#0x00 @@ -302,11 +519,10 @@ replace { dec a jp NZ,%1 ld %2,a - ; peephole replaced constant #0x00 by a (which has just been tested to be #0x00). + ; peephole 48 replaced constant #0x00 by a (which has just been tested to be #0x00). } -// From: Philipp Klaus Krause -replace { +replace restart { or a,%1 jp NZ,%2 ld a,%3 @@ -315,11 +531,10 @@ replace { or a,%1 jp NZ,%2 or a,%3 - ; peephole shortened or using a (which has just been tested to be #0x00). + ; peephole 49 shortened or using a (which has just been tested to be #0x00). } -// From: Philipp Klaus Krause -replace { +replace restart { and a,%1 jp NZ,%2 ld a,%3 @@ -328,11 +543,10 @@ replace { and a,%1 jp NZ,%2 or a,%3 - ; peephole shortened or using a (which has just been tested to be #0x00). + ; peephole 50 shortened or using a (which has just been tested to be #0x00). } -// From: Philipp Klaus Krause -replace { +replace restart { sub a,%1 jp NZ,%2 ld a,%3 @@ -341,11 +555,10 @@ replace { sub a,%1 jp NZ,%2 or a,%3 - ; peephole shortened or using a (which has just been tested to be #0x00). + ; peephole 51 shortened or using a (which has just been tested to be #0x00). } -// From: Philipp Klaus Krause -replace { +replace restart { dec a jp NZ,%1 ld a,%2 @@ -354,10 +567,9 @@ replace { dec a jp NZ,%1 or a,%2 - ; peephole shortened or using a (which has just been tested to be #0x00). + ; peephole 52 shortened or using a (which has just been tested to be #0x00). } -// From: Philipp Klaus Krause replace restart { or a,%1 jp NZ,%2 @@ -368,10 +580,9 @@ replace restart { jp NZ,%2 push %3 ld %4,a - ; peephole replaced constant #0x00 by a (which has just been tested to be #0x00). + ; peephole 53 replaced constant #0x00 by a (which has just been tested to be #0x00). } -// From: Philipp Klaus Krause replace restart { and a,%1 jp NZ,%2 @@ -382,10 +593,9 @@ replace restart { jp NZ,%2 push %3 ld %4,a - ; peephole replaced constant #0x00 by a (which has just been tested to be #0x00). + ; peephole 54 replaced constant #0x00 by a (which has just been tested to be #0x00). } -// From: Philipp Klaus Krause replace restart { sub a,%1 jp NZ,%2 @@ -396,10 +606,9 @@ replace restart { jp NZ,%2 push %3 ld %4,a - ; peephole replaced constant #0x00 by a (which has just been tested to be #0x00). + ; peephole 55 replaced constant #0x00 by a (which has just been tested to be #0x00). } -// From: Philipp Klaus Krause replace restart { dec a jp NZ,%1 @@ -410,55 +619,87 @@ replace restart { jp NZ,%1 push %2 ld %3,a - ; peephole replaced constant #0x00 by a (which has just been tested to be #0x00). + ; peephole 56 replaced constant #0x00 by a (which has just been tested to be #0x00). } -// From: Philipp Klaus Krause -replace restart{ - jp NZ,%1 - or a,%2 - jp Z,%3 -%1: - jp %4 -%3: +replace restart { + ld de,#%1 + %2 + inc de + inc de + inc de } by { - jp NZ,%4 - ; peephole redirected jump - or a,%2 - jp NZ,%4 - ; peephole redirected jump -%3: -} if labelRefCount(%1 1), labelRefCountChange(%1 -1), labelRefCountChange(%3 -1), labelRefCountChange(%4 1) + ld de,#%1 + %2 + 3 + ; peephole 57 moved triple increment of de to constant. +} -// Should be one of the last ones. Opens the code to further peephole optimization. -// From: Philipp Klaus Krause replace restart { -%1: + ld de,#%1 + %2 + inc de + inc de } by { - ; peephole removed unused label %1. -} if labelRefCount(%1 0) + ld de,#%1 + %2 + 2 + ; peephole 58 moved double increment of de to constant. +} -// From: Philipp Klaus Krause -replace { - jp Z,%5 +replace restart { + ld de,#%1 + %2 + inc de } by { - jr Z,%5 -} if labelInRange() + ld de,#%1 + %2 + 1 + ; peephole 59 moved increment of de to constant. +} -replace { - jp NZ,%5 +replace restart { + ld bc,#%1 + %2 + inc bc + inc bc + inc bc } by { - jr NZ,%5 -} if labelInRange() + ld bc,#%1 + %2 + 3 + ; peephole 60 moved triple increment of bc to constant. +} -replace { - jp C,%5 +replace restart { + ld bc,#%1 + %2 + inc bc + inc bc } by { - jr C,%5 -} if labelInRange() + ld bc,#%1 + %2 + 2 + ; peephole 61 moved double increment of bc to constant. +} -replace { - jp NC,%5 +replace restart { + ld bc,#%1 + %2 + inc bc } by { - jr NC,%5 -} if labelInRange() + ld bc,#%1 + %2 + 1 + ; peephole 62 moved increment of bc to constant. +} + +replace restart { + ld bc,#%1 + ld a,c + add a,#0x%2 + ld c,a + ld a,b + adc a,#0x%3 + ld b,a +} by { + ld bc,#%1 + 0x%3%2 + ; peephole 63 moved addition of constant 0x%3%2 to bc to constant. +} + +replace restart { + ld bc,#%1 + %4 + ld a,c + add a,#0x%2 + ld c,a + ld a,b + adc a,#0x%3 + ld b,a +} by { + ld bc,#%1 + %4 + 0x%3%2 + ; peephole 64 moved addition of constant 0x%3%2 to bc to constant. +} + + -- 2.47.2