]> git.gag.com Git - fw/sdcc/commitdiff
* src/port.h: added TARGET_MCS51_LIKE
authorMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 5 May 2007 13:45:50 +0000 (13:45 +0000)
committerMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 5 May 2007 13:45:50 +0000 (13:45 +0000)
* 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
src/SDCCpeeph.c
src/port.h
src/z80/gen.c
src/z80/peeph-z80.def
src/z80/peeph.def

index 39ff8af875753dace2f808af65d38cb5bccf8a7d..93b3c663554dd4fdd5e7fabf84f3a2f5de003589 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-05-05 Maarten Brock <sourceforge.brock AT dse.nl>
+
+       * 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 <borut.razem AT siol.net>
 
        * device/lib/pic16/Makefile.common.in,
index daf96c3ae5073b396a1b15ffbe10566117f51a85..a4341f1f2e34757362be8b045d44f779c443e498 100644 (file)
@@ -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 */
index 5dfc133509a78caf308b596bdabef290caec16ba..fd32518bf9da274a454b3494b2a67903a0fcb47d 100644 (file)
 /* 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 */
index c02557da51924e57451865c9d97083ca2fb88da1..54ee2b78e34818c81b3ba1995c7cb2e9fb32036c 100644 (file)
@@ -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);
     }
index ee3f701b0a17e209fa91af39f4a35dce52c22186..f717847ad2a11dd08f784864a7cbd5d78ba05909 100644 (file)
+// 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()
index 2fb852b6461d820edfef25446ea3d4ea6792e3b2..e80156af658f24913bef8ad716d4e43887e8fc36 100644 (file)
@@ -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 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.
+}
+
+