* src/SDCCpeeph.c: made labelHashEntry global, made pcDistance, FBYNAME static,
authorbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 26 Dec 2006 21:02:49 +0000 (21:02 +0000)
committerbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 26 Dec 2006 21:02:49 +0000 (21:02 +0000)
(pcDistance): made static, use isComment and isLabel,
(deadMove): added,
(getLabelRef): added, extracted from labelRefCount(),
(labelRefCount): use new getLabelRef(),
(callFuncByName): made static, added deadMove, use isComment and isLabel,
(newPeepRule): made static, set isLabel,
(isLabelDefinition): added parameter isPeepRule to allow '%' in labels from peephole rules,
(buildLabelRefCountHash): speed up by running isLabelDefinition() only when isComment or isLabel is set
* src/SDCCpeeph.h: added "isLabel" and "visited" to struct lineNode, added labelHashEntry, isLabelDefinition, labelHash and getLabelRef to make them global
* src/mcs51/peep.h: added
* src/mcs51/peep.c: added, implements mcs51DeadMove()
* src/port.h: added peep->deadMove to port structure
* src/mcs51/main.c: initialize peep->deadMove with mcs51DeadMove
* src/mcs51/peeph.def: renumbered rule 300 to 400, added new rule 300 deadMove, finally removed no. 1 and 2
* src/mcs51/gen.c,
* src/pic/gen.c,
* src/z80/gen.c,
* src/z80/ralloc.c,
* src/pic16/gen.c,
* src/ds390/gen.c,
* src/hc08/gen.c: mark lines with isComment or isLabel
* sim/ucsim/s51.src/uc390hw.cc: don't waist 65535 ticks before CKRDY
* .version,
* sdcc.spec: bumped version to 2.6.3

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4526 4a8a32a2-be11-0410-ad9d-d568d2c75423

18 files changed:
.version
ChangeLog
sdcc.spec
sim/ucsim/s51.src/uc390hw.cc
src/SDCCpeeph.c
src/SDCCpeeph.h
src/ds390/gen.c
src/hc08/gen.c
src/mcs51/gen.c
src/mcs51/main.c
src/mcs51/peep.c [new file with mode: 0644]
src/mcs51/peep.h [new file with mode: 0644]
src/mcs51/peeph.def
src/pic/gen.c
src/pic16/gen.c
src/port.h
src/z80/gen.c
src/z80/ralloc.c

index 097a15a2af39df14efb57a9212fc648b52746783..ec1cf33c3f6e22d5833bed6199c520a9ee20a0fa 100644 (file)
--- a/.version
+++ b/.version
@@ -1 +1 @@
-2.6.2
+2.6.3
index 7e4e27e9b64e3705cbc6867b09b0925f18f67473..a5ea5897e02f3c0ca8982b7bc71984e5f074dbc7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,39 @@
-2006-12-36 Borut Razem <borut.razem AT siol.net>
+2006-12-26 Bernhard Held <bernhard AT bernhardheld.de>
+
+       * src/SDCCpeeph.c: made labelHashEntry global,
+       made pcDistance, FBYNAME static,
+       (pcDistance): made static, use isComment and isLabel,
+       (deadMove): added,
+       (getLabelRef): added, extracted from labelRefCount(),
+       (labelRefCount): use new getLabelRef(),
+       (callFuncByName): made static, added deadMove,
+       use isComment and isLabel,
+       (newPeepRule): made static, set isLabel,
+       (isLabelDefinition): added parameter isPeepRule to allow '%' in
+       labels from peephole rules,
+       (buildLabelRefCountHash): speed up by running isLabelDefinition() only
+       when isComment or isLabel is set
+       * src/SDCCpeeph.h: added "isLabel" and "visited" to struct lineNode,
+       added labelHashEntry, isLabelDefinition, labelHash and getLabelRef
+       to make them global
+       * src/mcs51/peep.h: added
+       * src/mcs51/peep.c: added, implements mcs51DeadMove()
+       * src/port.h: added peep->deadMove to port structure
+       * src/mcs51/main.c: initialize peep->deadMove with mcs51DeadMove
+       * src/mcs51/peeph.def: renumbered rule 300 to 400, added new rule 300
+       deadMove, finally removed no. 1 and 2
+       * src/mcs51/gen.c,
+       * src/pic/gen.c,
+       * src/z80/gen.c,
+       * src/z80/ralloc.c,
+       * src/pic16/gen.c,
+       * src/ds390/gen.c,
+       * src/hc08/gen.c: mark lines with isComment or isLabel
+       * sim/ucsim/s51.src/uc390hw.cc: don't waist 65535 ticks before CKRDY
+       * .version,
+       * sdcc.spec: bumped version to 2.6.3
+
+2006-12-26 Borut Razem <borut.razem AT siol.net>
 
        * support/cpp2/Makefile.in: added dependency on options.h
        * configure: regenerated
index 5ff92fab8df2f46039b271110621902590be3917..f03ff9c32cc728e2e6de1ba55632a4daa983ea6d 100644 (file)
--- a/sdcc.spec
+++ b/sdcc.spec
@@ -8,7 +8,7 @@ License:       GPL
 Group:         Applications/Engineering
 Summary:       Small Device C Compiler
 Requires:      sdcc-common
-Version:       2.6.0
+Version:       2.6.3
 Release:       2
 Source:        %{name}-src-%{version}.tar.gz
 URL:           http://sdcc.sourceforge.net/
@@ -78,6 +78,10 @@ rm -rf $RPM_BUILD_ROOT
 %doc %{_defaultdocdir}
 
 %changelog
+* Sun Dec 26 2006 - bernhard AT bernhardheld.de
+- version updated
+* Sun Sep 03 2006 - Christer Weinigel
+- fixed build of doc
 * Tue Mar 09 2004 - bernhard AT bernhardheld.de
 - split into two packages
 * Wed Feb 26 2004 - bernhard AT bernhardheld.de
index 5012d676f15f1b04710637a982c32d147797de65..a7155902d26f820f41ffc64a6c9e4c7e6e2d352e 100644 (file)
@@ -92,7 +92,7 @@ cl_uc390_hw::read (class cl_memory_cell *cell)
   if (cell == cell_exif)
     {
       if (ctm_ticks &&
-          uc390->ticks->ticks >= ctm_ticks + 65535)
+          uc390->ticks->ticks >= ctm_ticks + 50 /*65535*/)
         {
           ctm_ticks = 0;
           cell->set (cell->get() | 0x08); /* set CKRDY */
index c38627dc2a7e76bfb81779ad823aead57d3c2198..a831e9f404a386a60de61962a89605bf0b0aa424 100644 (file)
@@ -33,14 +33,8 @@ static peepRule *rootRules = NULL;
 static peepRule *currRule = NULL;
 
 #define HTAB_SIZE 53
-typedef struct
-  {
-    char name[SDCC_NAME_MAX + 1];
-    int refCount;
-  }
-labelHashEntry;
 
-static hTab *labelHash = NULL;
+hTab *labelHash = NULL;
 
 static struct
 {
@@ -52,9 +46,8 @@ static int hashSymbolName (const char *name);
 static void buildLabelRefCountHash (lineNode * head);
 
 static bool matchLine (char *, char *, hTab **);
-bool isLabelDefinition (const char *line, const char **start, int *len);
 
-#define FBYNAME(x) int x (hTab *vars, lineNode *currPl, lineNode *endPl, \
+#define FBYNAME(x) static int x (hTab *vars, lineNode *currPl, lineNode *endPl, \
         lineNode *head, char *cmdLine)
 
 #if !OPT_DISABLE_PIC
@@ -69,7 +62,7 @@ void pic16_peepRules2pCode(peepRule *);
 /* pcDistance - afinds a label back ward or forward                */
 /*-----------------------------------------------------------------*/
 
-int
+static int
 pcDistance (lineNode * cpos, char *lbl, bool back)
 {
   lineNode *pl = cpos;
@@ -81,8 +74,8 @@ pcDistance (lineNode * cpos, char *lbl, bool back)
     {
 
       if (pl->line &&
-          *pl->line != ';' &&
-          pl->line[strlen (pl->line) - 1] != ':' &&
+          !pl->isComment &&
+          !pl->isLabel &&
           !pl->isDebug) {
                 if (port->peep.getSize) {
                         dist += port->peep.getSize(pl);
@@ -248,7 +241,7 @@ FBYNAME (labelIsReturnOnly)
 
   for(pl = currPl; pl; pl = pl->next) {
         if (pl->line && !pl->isDebug && !pl->isComment &&
-          pl->line[strlen(pl->line)-1] == ':') {
+          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)) ||
@@ -310,6 +303,19 @@ FBYNAME (okToRemoveSLOC)
   return TRUE; /* safe for a peephole to remove it :) */
 }
 
+/*-----------------------------------------------------------------*/
+/* deadMove - Check, if a pop/push pair can be removed             */
+/*-----------------------------------------------------------------*/
+FBYNAME (deadMove)
+{
+  char *op = hTabItemWithKey (vars, 1);
+
+  if (port->peep.deadMove)
+    return port->peep.deadMove (op, currPl, head);
+
+  fprintf (stderr, "Function deadMove not initialized in port structure\n"); 
+  return FALSE;
+}
 
 /*-----------------------------------------------------------------*/
 /* operandsNotSame - check if %1 & %2 are the same                 */
@@ -508,6 +514,34 @@ FBYNAME (operandsNotSame8)
     return TRUE;
 }
 
+/*-----------------------------------------------------------------*/
+/* labelHashEntry- searches for a label in the list labelHash      */
+/* Builds labelHash, if it does not yet exist.                     */
+/* Returns the labelHashEntry or NULL                              */
+/*-----------------------------------------------------------------*/
+labelHashEntry *
+getLabelRef (const char *label, lineNode *head)
+{
+  labelHashEntry *entry;
+
+  /* If we don't have the label hash table yet, build it. */
+  if (!labelHash)
+    {
+      buildLabelRefCountHash (head);
+    }
+
+  entry = hTabFirstItemWK (labelHash, hashSymbolName (label));
+
+  while (entry)
+    {
+      if (!strcmp (label, entry->name))
+        {
+          break;
+        }
+      entry = hTabNextItemWK (labelHash);
+    }
+  return entry;
+}
 
 /* labelRefCount:
 
@@ -522,30 +556,14 @@ FBYNAME (labelRefCount)
   int varNumber, expectedRefCount;
   bool rc = FALSE;
 
-  /* If we don't have the label hash table yet, build it. */
-  if (!labelHash)
-    {
-      buildLabelRefCountHash (head);
-    }
-
   if (sscanf (cmdLine, "%*[ \t%]%d %d", &varNumber, &expectedRefCount) == 2)
     {
       char *label = hTabItemWithKey (vars, varNumber);
 
       if (label)
         {
-          labelHashEntry *entry;
-
-          entry = hTabFirstItemWK (labelHash, hashSymbolName (label));
+          labelHashEntry *entry = getLabelRef (label, head);
 
-          while (entry)
-            {
-              if (!strcmp (label, entry->name))
-                {
-                  break;
-                }
-              entry = hTabNextItemWK (labelHash);
-            }
           if (entry)
             {
 #if 0
@@ -1003,7 +1021,7 @@ FBYNAME (operandsLiteral)
 /*-----------------------------------------------------------------*/
 /* callFuncByName - calls a function as defined in the table       */
 /*-----------------------------------------------------------------*/
-int
+static int
 callFuncByName (char *fname,
                 hTab * vars,
                 lineNode * currPl,
@@ -1074,6 +1092,9 @@ callFuncByName (char *fname,
     {
       "okToRemoveSLOC", okToRemoveSLOC
     },
+    {
+      "deadMove", deadMove
+    },
     {
       "24bitModeAndPortDS390", flat24bitModeAndPortDS390
     },
@@ -1202,8 +1223,7 @@ printLine (lineNode * head, FILE * of)
 
       /* don't indent comments & labels */
       if (head->line &&
-          (*head->line == ';' ||
-           head->line[strlen (head->line) - 1] == ':')) {
+          (head->isComment || head->isLabel)) {
         fprintf (of, "%s\n", head->line);
       } else {
         if (head->isInline && *head->line=='#') {
@@ -1219,7 +1239,7 @@ printLine (lineNode * head, FILE * of)
 /*-----------------------------------------------------------------*/
 /* newPeepRule - creates a new peeprule and attach it to the root  */
 /*-----------------------------------------------------------------*/
-peepRule *
+static peepRule *
 newPeepRule (lineNode * match,
              lineNode * replace,
              char *cond,
@@ -1338,11 +1358,16 @@ getPeepLine (lineNode ** head, char **bpp)
 
       if (!isComment || (isComment && !options.noPeepComments))
         {
+          const char *dummy1;
+          int dummy2;
+
           if (!currL)
             *head = currL = newLineNode (lines);
           else
             currL = connectLine (currL, newLineNode (lines));
           currL->isComment = isComment;
+          currL->isLabel = isLabelDefinition (currL->line, &dummy1, &dummy2,
+                                              TRUE);
         }
 
     }
@@ -1820,16 +1845,13 @@ reassociate_ic (lineNode *shead, lineNode *stail,
   csl = shead;
   while (1)
     {
-      const char *labelStart;
-      int labelLength;
-
       /* skip over any comments */
       while (csl!=stail->next && csl->isComment)
         csl = csl->next;
       if (csl==stail->next)
         break;
 
-      if (isLabelDefinition(csl->line, &labelStart, &labelLength))
+      if (csl->isLabel)
         {
           /* found a source line label; look for it in the replacment lines */
           crl = rhead;
@@ -1931,6 +1953,7 @@ replaceRule (lineNode ** shead, lineNode * stail, peepRule * pr)
       else
         lhead = cl = newLineNode (lb);
       cl->isComment = pl->isComment;
+      cl->isLabel   = pl->isLabel;
     }
 
   /* add the comments if any to the head of list */
@@ -1983,7 +2006,8 @@ replaceRule (lineNode ** shead, lineNode * stail, peepRule * pr)
  * and len will be it's length.
  */
 bool
-isLabelDefinition (const char *line, const char **start, int *len)
+isLabelDefinition (const char *line, const char **start, int *len,
+                   bool isPeepRule)
 {
   const char *cp = line;
 
@@ -2004,7 +2028,8 @@ isLabelDefinition (const char *line, const char **start, int *len)
 
   *start = cp;
 
-  while (ISCHARALNUM (*cp) || (*cp == '$') || (*cp == '_'))
+  while (ISCHARALNUM (*cp) || (*cp == '$') || (*cp == '_') ||
+         (isPeepRule && (*cp == '%')))
     {
       cp++;
     }
@@ -2053,30 +2078,35 @@ buildLabelRefCountHash (lineNode * head)
   labelHash = newHashTable (HTAB_SIZE);
 
   /* First pass: locate all the labels. */
-  line = head;
-
-  while (line)
+  for (line = head; line; line = line->next)
     {
-      if (isLabelDefinition (line->line, &label, &labelLen)
-          && labelLen <= SDCC_NAME_MAX)
+      if (line->isLabel  ||
+          line->isInline)
         {
-          labelHashEntry *entry;
+          /* run isLabelDefinition to:
+             - look for labels in inline assembler
+             - calculate labelLen
+          */
+          if (isLabelDefinition (line->line, &label, &labelLen, FALSE) &&
+              labelLen <= SDCC_NAME_MAX)
+            {
+              labelHashEntry *entry;
 
-          entry = traceAlloc (&_G.labels, Safe_alloc(sizeof (labelHashEntry)));
+              entry = traceAlloc (&_G.labels, Safe_alloc(sizeof (labelHashEntry)));
 
-          memcpy (entry->name, label, labelLen);
-          entry->name[labelLen] = 0;
-          entry->refCount = -1;
+              memcpy (entry->name, label, labelLen);
+              entry->name[labelLen] = 0;
+              entry->refCount = -1;
 
-          /* Assume function entry points are referenced somewhere,   */
-          /* even if we can't find a reference (might be from outside */
-          /* the function) */
-          if (line->ic && (line->ic->op == FUNCTION))
-            entry->refCount++;
+              /* Assume function entry points are referenced somewhere,   */
+              /* even if we can't find a reference (might be from outside */
+              /* the function) */
+              if (line->ic && (line->ic->op == FUNCTION))
+                entry->refCount++;
 
-          hTabAddItem (&labelHash, hashSymbolName (entry->name), entry);
+              hTabAddItem (&labelHash, hashSymbolName (entry->name), entry);
+            }
         }
-      line = line->next;
     }
 
 
index 8ada22285ce4353626d5a48a7d90135df1b4276a..d5e38816a47b93ff019882881cbd710ed2b715c7 100644 (file)
@@ -38,6 +38,8 @@ typedef struct lineNode
     unsigned int isInline:1;
     unsigned int isComment:1;
     unsigned int isDebug:1;
+    unsigned int isLabel:1;
+    unsigned int visited:1;
     struct asmLineNode *aln;
     struct lineNode *prev;
     struct lineNode *next;
@@ -55,6 +57,22 @@ typedef struct peepRule
   }
 peepRule;
 
+typedef struct
+  {
+    char name[SDCC_NAME_MAX + 1];
+    int refCount;
+    /* needed for deadMove: */
+    bool passedLabel;
+    int jmpToCount;
+  }
+labelHashEntry;
+
+bool isLabelDefinition (const char *line, const char **start, int *len,
+                        bool isPeepRule);
+
+extern hTab *labelHash;
+labelHashEntry *getLabelRef (const char *label, lineNode *head);
+
 void printLine (lineNode *, FILE *);
 lineNode *newLineNode (char *);
 lineNode *connectLine (lineNode *, lineNode *);
index b43549176e1b3040f3397fbdbd4a02007384c227..b82bdbec4380b6f8af99ead35b02194b603117b6 100644 (file)
@@ -191,7 +191,7 @@ static unsigned char SRMask[] =
                                 emitcode ("setb","F1");                         \
                                 emitcode ("jbc","EA,!tlabel",lbl->key+100);     \
                                 emitcode ("clr","F1");                          \
-                                emitcode ("","!tlabeldef",lbl->key+100);        \
+                                emitLabel (lbl);                                \
                         }}
 #define UNPROTECT_SP    { if (options.protect_sp_update) {                      \
                                 emitcode ("mov","EA,F1");                       \
@@ -247,6 +247,7 @@ emitcode (char *inst, const char *fmt,...)
   lineCurr->isDebug = _G.debugLine;
   lineCurr->ic = _G.current_iCode;
   lineCurr->aln = ds390newAsmLineNode(_currentDPS);
+  lineCurr->isComment = (*lbp == ';');
   va_end (ap);
 }
 
@@ -254,6 +255,7 @@ static void
 emitLabel (symbol *tlbl)
 {
   emitcode ("", "!tlabeldef", tlbl->key + 100);
+  lineCurr->isLabel = 1;
 }
 
 /*-----------------------------------------------------------------*/
@@ -3396,6 +3398,7 @@ genFunction (iCode * ic)
   emitcode (";", "-----------------------------------------");
 
   emitcode ("", "%s:", sym->rname);
+  lineCurr->isLabel = 1;
   ftype = operandType (IC_LEFT (ic));
   _G.currentFunc = sym;
 
@@ -4144,7 +4147,7 @@ genLabel (iCode * ic)
 
   D (emitcode (";", "genLabel"));
 
-  emitcode ("", "!tlabeldef", (IC_LABEL (ic)->key + 100));
+  emitLabel (IC_LABEL (ic));
 }
 
 /*-----------------------------------------------------------------*/
@@ -12627,7 +12630,7 @@ static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc)
         emitcode ("mov","b,%s",aopGet (count, 1, FALSE, TRUE, NULL));
         freeAsmop (count, NULL, ic, FALSE);
         emitcode ("mov", "dps,#!constbyte",0x21);       /* Select DPTR2 & auto-toggle. */
-        emitcode ("","!tlabeldef",lbl->key+100);
+        emitLabel (lbl);
         if (fromc) {
             emitcode ("clr","a");
             emitcode ("movc", "a,@a+dptr");
@@ -12646,7 +12649,7 @@ static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc)
         emitcode ("addc","a,#!constbyte",0xFF);
         emitcode ("mov","b,a");
         emitcode ("sjmp","!tlabel",lbl->key+100);
-        emitcode ("","!tlabeldef",lbl1->key+100);
+        emitLabel (lbl1);
     }
     emitcode ("mov", "dps,#0");
     _G.dptrInUse = _G.dptr1InUse = 0;
@@ -12746,7 +12749,7 @@ static void genMemcmpX2X( iCode *ic, int nparms, operand **parms, int fromc)
         emitcode ("mov","b,%s",aopGet (count, 1, FALSE, TRUE, NULL));
         freeAsmop (count, NULL, ic, FALSE);
         emitcode ("mov", "dps,#!constbyte",0x21);       /* Select DPTR2 & auto-toggle. */
-        emitcode ("","!tlabeldef",lbl->key+100);
+        emitLabel (lbl);
         if (fromc) {
             emitcode ("clr","a");
             emitcode ("movc", "a,@a+dptr");
@@ -12769,9 +12772,9 @@ static void genMemcmpX2X( iCode *ic, int nparms, operand **parms, int fromc)
         emitcode ("addc","a,#!constbyte",0xFF);
         emitcode ("mov","b,a");
         emitcode ("sjmp","!tlabel",lbl->key+100);
-        emitcode ("","!tlabeldef",lbl1->key+100);
+        emitLabel (lbl1);
         emitcode ("clr","a");
-        emitcode ("","!tlabeldef",lbl2->key+100);
+        emitLabel (lbl2);
         aopOp (IC_RESULT(ic), ic, FALSE,FALSE);
         aopPut(IC_RESULT(ic),"a",0);
         freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
@@ -12863,7 +12866,7 @@ static void genInp( iCode *ic, int nparms, operand **parms)
         emitcode ("mov", "dps,#!constbyte",0x1);        /* Select DPTR2 */
         emitcode ("mov", "b,%s",aopGet(count,0,FALSE,FALSE,NULL));
         freeAsmop (count, NULL, ic, FALSE);
-        emitcode ("","!tlabeldef",lbl->key+100);
+        emitLabel (lbl);
         emitcode ("movx", "a,@dptr");   /* read data from port */
         emitcode ("dec","dps");         /* switch to DPTR */
         emitcode ("movx", "@dptr,a");   /* save into location */
@@ -12878,7 +12881,7 @@ static void genInp( iCode *ic, int nparms, operand **parms)
         emitcode ("mov","b,%s",aopGet (count, 1, FALSE, TRUE, NULL));
         freeAsmop (count, NULL, ic, FALSE);
         emitcode ("mov", "dps,#!constbyte",0x1);        /* Select DPTR2 */
-        emitcode ("","!tlabeldef",lbl->key+100);
+        emitLabel (lbl);
         emitcode ("movx", "a,@dptr");
         emitcode ("dec","dps");         /* switch to DPTR */
         emitcode ("movx", "@dptr,a");
@@ -12896,7 +12899,7 @@ static void genInp( iCode *ic, int nparms, operand **parms)
         emitcode ("addc","a,#!constbyte",0xFF);
         emitcode ("mov","b,a");
         emitcode ("sjmp","!tlabel",lbl->key+100);
-        emitcode ("","!tlabeldef",lbl1->key+100);
+        emitLabel (lbl1);
     }
     emitcode ("mov", "dps,#0");
     _G.dptrInUse = _G.dptr1InUse = 0;
@@ -12983,7 +12986,7 @@ static void genOutp( iCode *ic, int nparms, operand **parms)
         emitcode (";","OH  JOY auto increment with djnz (very fast)");
         emitcode ("mov", "dps,#!constbyte",0x0);        /* Select DPTR */
         emitcode ("mov", "b,%s",aopGet(count,0,FALSE,FALSE,NULL));
-        emitcode ("","!tlabeldef",lbl->key+100);
+        emitLabel (lbl);
         emitcode ("movx", "a,@dptr");   /* read data from port */
         emitcode ("inc","dps");         /* switch to DPTR2 */
         emitcode ("movx", "@dptr,a");   /* save into location */
@@ -12999,7 +13002,7 @@ static void genOutp( iCode *ic, int nparms, operand **parms)
         emitcode ("mov","b,%s",aopGet (count, 1, FALSE, TRUE, NULL));
         freeAsmop (count, NULL, ic, FALSE);
         emitcode ("mov", "dps,#!constbyte",0x0);        /* Select DPTR */
-        emitcode ("","!tlabeldef",lbl->key+100);
+        emitLabel (lbl);
         emitcode ("movx", "a,@dptr");
         emitcode ("inc", "dptr");
         emitcode ("inc","dps");         /* switch to DPTR2 */
@@ -13015,7 +13018,7 @@ static void genOutp( iCode *ic, int nparms, operand **parms)
         emitcode ("addc","a,#!constbyte",0xFF);
         emitcode ("mov","b,a");
         emitcode ("sjmp","!tlabel",lbl->key+100);
-        emitcode ("","!tlabeldef",lbl1->key+100);
+        emitLabel (lbl1);
     }
     emitcode ("mov", "dps,#0");
     _G.dptrInUse = _G.dptr1InUse = 0;
@@ -13117,7 +13120,7 @@ static void genMemsetX(iCode *ic, int nparms, operand **parms)
         l = aopGet(val, 0, FALSE, FALSE, NULL);
         emitcode ("mov", "b,%s",aopGet(count,0,FALSE,FALSE,NULL));
         MOVA(l);
-        emitcode ("","!tlabeldef",lbl->key+100);
+        emitLabel (lbl);
         emitcode ("movx", "@dptr,a");
         emitcode ("inc", "dptr");
         emitcode ("djnz","b,!tlabel",lbl->key+100);
@@ -13126,7 +13129,7 @@ static void genMemsetX(iCode *ic, int nparms, operand **parms)
 
         emitcode ("mov","_ap,%s",aopGet (count, 0, FALSE, TRUE, NULL));
         emitcode ("mov","b,%s",aopGet (count, 1, FALSE, TRUE, NULL));
-        emitcode ("","!tlabeldef",lbl->key+100);
+        emitLabel (lbl);
         MOVA (aopGet(val, 0, FALSE, FALSE, NULL));
         emitcode ("movx", "@dptr,a");
         emitcode ("inc", "dptr");
@@ -13140,7 +13143,7 @@ static void genMemsetX(iCode *ic, int nparms, operand **parms)
         emitcode ("addc","a,#!constbyte",0xFF);
         emitcode ("mov","b,a");
         emitcode ("sjmp","!tlabel",lbl->key+100);
-        emitcode ("","!tlabeldef",lbl1->key+100);
+        emitLabel (lbl1);
     }
     freeAsmop (count, NULL, ic, FALSE);
     unsavermask(rsave);
@@ -13326,7 +13329,7 @@ static void genNatLibGetStateBlock(iCode *ic,int nparms,
                 aopPut(IC_RESULT(ic),"r3",1);
         }
         freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
-        emitcode ("","!tlabeldef",lbl->key+100);
+        emitLabel (lbl);
         unsavermask(rsave);
 }
 
@@ -13373,7 +13376,7 @@ static void genMMMalloc (iCode *ic,int nparms, operand **parms,
         emitcode ("jz","!tlabel",lbl->key+100);
         emitcode ("mov","r2,#!constbyte",0xff);
         emitcode ("mov","r3,#!constbyte",0xff);
-        emitcode ("","!tlabeldef",lbl->key+100);
+        emitLabel (lbl);
         /* we don't care about the pointer : we just save the handle */
         rsym = OP_SYMBOL(IC_RESULT(ic));
         if (rsym->liveFrom != rsym->liveTo) {
index c091a41130f4aeb9ba13c3069971a2b364711c55..aa324162b77e4a8d945bdf6ef7838953817e663f 100644 (file)
@@ -193,6 +193,7 @@ static void
 emitLabel (symbol *tlbl)
 {
   emitcode ("", "%05d$:", (tlbl->key +100));
+  lineCurr->isLabel = 1;
 }
 
 /*-----------------------------------------------------------------*/
@@ -2187,7 +2188,7 @@ asmopToBool (asmop *aop, bool resultInA)
             emitcode ("tsta", "");
             emitcode ("bne", "%05d$", (tlbl->key + 100));
             emitcode ("tstx", "");
-            emitcode ("", "%05d$:", (tlbl->key + 100));
+            emitLabel (tlbl);
           }
         else
           {
@@ -2248,7 +2249,7 @@ asmopToBool (asmop *aop, bool resultInA)
                 emitcode ("tst", "%s", aopAdrStr (aop, 0, FALSE));
                 emitcode ("bne", "%05d$", (tlbl->key + 100));
                 emitcode ("tst", "%s", aopAdrStr (aop, 1, FALSE));
-                emitcode ("", "%05d$:", (tlbl->key + 100));
+                emitLabel (tlbl);
                 break;
               }
           }
@@ -2885,6 +2886,7 @@ genFunction (iCode * ic)
   emitcode (";", "-----------------------------------------");
 
   emitcode ("", "%s:", sym->rname);
+  lineCurr->isLabel = 1;
   ftype = operandType (IC_LEFT (ic));
   
   _G.stackOfs = 0;
@@ -3165,7 +3167,7 @@ genLabel (iCode * ic)
          
   debugFile->writeLabel(IC_LABEL (ic), ic);
 
-  emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
+  emitLabel (IC_LABEL (ic));
 
 }
 
index 576d529e25ab66efa3e117a09f809707e0f561dc..ad53c30b2e4eb649a499c9945cee344d72e292ba 100644 (file)
@@ -198,6 +198,7 @@ static void
 emitLabel (symbol *tlbl)
 {
   emitcode ("", "%05d$:", tlbl->key + 100);
+  lineCurr->isLabel = 1;
 }
 
 /*-----------------------------------------------------------------*/
@@ -3255,6 +3256,7 @@ genFunction (iCode * ic)
   emitcode (";", "-----------------------------------------");
 
   emitcode ("", "%s:", sym->rname);
+  lineCurr->isLabel = 1;
   ftype = operandType (IC_LEFT (ic));
   _G.currentFunc = sym;
 
@@ -4020,7 +4022,7 @@ genLabel (iCode * ic)
   if (IC_LABEL (ic) == entryLabel)
     return;
 
-  emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
+  emitLabel (IC_LABEL (ic));
 }
 
 /*-----------------------------------------------------------------*/
index 8f7e4f61d29234eec69a22842c2027c043e8f76f..2307724fcf8286e9b5d548ca79e0165b520960ba 100644 (file)
@@ -729,7 +729,8 @@ PORT mcs51_port =
     _defaultRules,
     getInstructionSize,
     getRegsRead,
-    getRegsWritten
+    getRegsWritten,
+    mcs51DeadMove
   },
   {
     /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
diff --git a/src/mcs51/peep.c b/src/mcs51/peep.c
new file mode 100644 (file)
index 0000000..5453f42
--- /dev/null
@@ -0,0 +1,591 @@
+/*-------------------------------------------------------------------------
+  peep.c - source file for peephole optimizer helper functions
+
+  Written By -  Bernhard Held
+
+  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.
+
+  In other words, you are welcome to use, share and improve this program.
+  You are forbidden to forbid anyone else to use, share and improve
+  what you give them.   Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+
+#include "common.h"
+#include "ralloc.h"
+
+#define D(x) x
+#define DEADMOVEERROR "Internal error: deadmove\n"
+
+typedef enum
+{
+  S4O_FOUNDOPCODE,
+  S4O_PUSHPOP,
+  S4O_CONDJMP,
+  S4O_WR_OP,
+  S4O_RD_OP,
+  S4O_TERM,
+  S4O_VISITED,
+  S4O_ABORT
+} S4O_RET;
+
+static struct
+{
+  lineNode *head;
+} _G;
+
+/*-----------------------------------------------------------------*/
+/* univisitLines - clear "visited" flag in all lines               */
+/*-----------------------------------------------------------------*/
+static void
+unvisitLines (lineNode *pl)
+{
+  for (; pl; pl = pl->next)
+    pl->visited = FALSE;
+}
+
+/*-----------------------------------------------------------------*/
+/* cleanLabelRef - clear label jump-counter and pass-flag          */
+/*-----------------------------------------------------------------*/
+static void
+cleanLabelRef (void)
+{
+  int key;
+  labelHashEntry *entry;
+
+  if (!labelHash)
+    return;
+  for (entry = (labelHashEntry *) hTabFirstItem (labelHash, &key);
+       entry;
+       entry = (labelHashEntry *) hTabNextItem (labelHash, &key))
+    {
+      entry->passedLabel = FALSE;
+      entry->jmpToCount = 0;
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* checkLabelRef - check all entries in labelHash                  */
+/* The path from 'pop' to 'push' must be the only possible path.   */
+/* There must not be any paths in or out of this path.             */
+/* This is checked by counting the label references.               */
+/*-----------------------------------------------------------------*/
+static bool
+checkLabelRef (void)
+{
+  int key;
+  labelHashEntry *entry;
+
+  if (!labelHash)
+    {
+      /* no labels at all: no problems ;-) */
+      return TRUE;
+    }
+
+  for (entry = (labelHashEntry *) hTabFirstItem (labelHash, &key);
+       entry;
+       entry = (labelHashEntry *) hTabNextItem (labelHash, &key))
+    {
+
+      /* In our path we passed a label,
+         but we didn't meet all references (jumps) to this label.
+         This means that the code jumps from outside into this path. */
+      if (entry->passedLabel &&
+          entry->jmpToCount != entry->refCount)
+        {
+          return FALSE;
+        }
+
+      /* In our path we jumped to (referenced) a label,
+         but we we didn't pass it.
+         This means that there's a code path into our path. */
+      if (!entry->passedLabel &&
+          entry->jmpToCount != 0)
+        {
+          return FALSE;
+        }
+    }
+  return TRUE;
+}
+
+/*-----------------------------------------------------------------*/
+/* setLabelRefPassedLabel - set flag "passedLabel" in entry        */
+/* of the list labelHash                                           */
+/*-----------------------------------------------------------------*/
+static bool
+setLabelRefPassedLabel (const char *label)
+{
+  labelHashEntry *entry;
+
+  entry = getLabelRef (label, _G.head);
+  if (!entry)
+    return FALSE;
+  entry->passedLabel = TRUE;
+  return TRUE;
+}
+
+/*-----------------------------------------------------------------*/
+/* incLabelJmpToCount - increment counter "jmpToCount" in entry    */
+/* of the list labelHash                                           */
+/*-----------------------------------------------------------------*/
+static bool
+incLabelJmpToCount (const char *label)
+{
+  labelHashEntry *entry;
+
+  entry = getLabelRef (label, _G.head);
+  if (!entry)
+    return FALSE;
+  entry->jmpToCount++;
+  return TRUE;
+}
+
+/*-----------------------------------------------------------------*/
+/* findLabel -                                                     */
+/* 1. extracts label in the opcode pl                              */
+/* 2. increment "label jump-to count" in labelHash                 */
+/* 3. search lineNode with label definition and return it          */
+/*-----------------------------------------------------------------*/
+static lineNode *
+findLabel (const lineNode *pl)
+{
+  char *p;
+  lineNode *cpl;
+
+  /* 1. extract label in opcode */
+
+  /* In each mcs51 jumping opcode the label is at the end of the opcode */
+  p = strlen (pl->line) - 1 + pl->line;
+
+  /* scan backward until ',' or '\t' */
+  for (; p > pl->line; p--)
+    if (*p == ',' || *p == '\t')
+      break;
+
+  /* sanity check */
+  if (p == pl->line)
+    {
+      D(fprintf (stderr, DEADMOVEERROR);)
+      return NULL;
+    }
+
+  /* skip ',' resp. '\t' */
+  ++p;
+
+  /* 2. increment "label jump-to count" */
+  if (!incLabelJmpToCount (p))
+    return NULL;
+
+  /* 3. search lineNode with label definition and return it */
+  for (cpl = _G.head; cpl; cpl = cpl->next)
+    {
+      if (   cpl->isLabel
+          && strcmp (p, cpl->line) == 0)
+        {
+          return cpl;
+        }
+    }
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* scan4op - "executes" and examines the assembler opcodes,        */
+/* follows conditional and un-conditional jumps.                   */
+/* Moreover it registers all passed labels.                        */
+/*                                                                 */
+/* Parameter:                                                      */
+/*    lineNode **pl                                                */
+/*       scanning starts from pl;                                  */
+/*       pl also returns the last scanned line                     */
+/*    const char *pReg                                             */
+/*       points to a register (e.g. "ar0"). scan4op() tests for    */
+/*       read or write operations with this register               */
+/*    const char *untilOp                                          */
+/*       points to NULL or a opcode (e.g. "push").                 */
+/*       scan4op() returns if it hits this opcode.                 */
+/*    lineNode **plCond                                            */
+/*       If a conditional branch is met plCond points to the       */
+/*       lineNode of the conditional branch                        */
+/*                                                                 */
+/* Returns:                                                        */
+/*    S4O_ABORT                                                    */
+/*       on error                                                  */
+/*    S4O_VISITED                                                  */
+/*       hit lineNode with "visited" flag set: scan4op() already   */
+/*       scanned this opcode.                                      */
+/*    S4O_FOUNDOPCODE                                              */
+/*       found opcode and operand, to which untilOp and pReg are   */
+/*       pointing to.                                              */
+/*    S4O_RD_OP, S4O_WR_OP                                         */
+/*       hit an opcode reading or writing from pReg                */
+/*    S4O_PUSHPOP                                                  */
+/*       hit a "push" or "pop" opcode                              */
+/*    S4O_CONDJMP                                                  */
+/*       hit a conditional jump opcode. pl and plCond return the   */
+/*       two possible branches.                                    */
+/*    S4O_TERM                                                     */
+/*       acall, lcall, ret and reti "terminate" a scan.            */
+/*-----------------------------------------------------------------*/
+static S4O_RET
+scan4op (lineNode **pl, const char *pReg, const char *untilOp,
+         lineNode **plCond)
+{
+  char *p;
+  int len;
+  bool isConditionalJump;
+
+  /* pReg points to e.g. "ar0"..."ar7" */
+  len = strlen (pReg);
+
+  for (; *pl; *pl = (*pl)->next)
+    {
+      if (!(*pl)->line || (*pl)->isDebug || (*pl)->isComment)
+        continue;
+
+      /* don't optimize across inline assembler,
+         e.g. isLabel doesn't work there */
+      if ((*pl)->isInline)
+        return S4O_ABORT;
+
+      if ((*pl)->visited)
+        return S4O_VISITED;
+      (*pl)->visited = TRUE;
+
+      /* found untilOp? */
+      if (untilOp && strncmp ((*pl)->line, untilOp, strlen (untilOp)) == 0)
+        {
+          p = (*pl)->line + strlen (untilOp);
+          if (*p == '\t' && strncmp (p + 1, pReg, len) == 0)
+            return S4O_FOUNDOPCODE;
+          else
+            {
+              /* found untilOp but without our pReg */
+              return S4O_ABORT;
+            }
+        }
+
+      /* found pReg? */
+      p = strchr ((*pl)->line, '\t');
+      if (p)
+        {
+          /* skip '\t' */
+          p++;
+
+          /* course search */
+          if (strstr (p, pReg + 1))
+            {
+              /* ok, let's have a closer look */
+
+              /* get index into pReg table */
+              int rIdx;
+
+              for (rIdx = 0; rIdx < mcs51_nRegs; ++rIdx)
+                if (strcmp (regs8051[rIdx].name, pReg + 1) == 0)
+                  break;
+
+              /* sanity check */
+              if (rIdx >= mcs51_nRegs)
+                {
+                  D(fprintf (stderr, DEADMOVEERROR);)
+                  return S4O_ABORT;
+                }
+
+              /* does opcode read from pReg? */
+              if (bitVectBitValue (port->peep.getRegsRead ((*pl)), rIdx))
+                return S4O_RD_OP;
+              /* does opcode write to pReg? */
+              if (bitVectBitValue (port->peep.getRegsWritten ((*pl)), rIdx))
+                return S4O_WR_OP;
+
+              /* should never reach here */
+              D(fprintf (stderr, DEADMOVEERROR);)
+              return S4O_ABORT;
+            }
+        }
+
+      /* found label? */
+      if ((*pl)->isLabel)
+        {
+          const char *start;
+          char label[SDCC_NAME_MAX + 1];
+          int len;
+
+          if (!isLabelDefinition ((*pl)->line, &start, &len, FALSE))
+            return S4O_ABORT;
+          memcpy (label, start, len);
+          label[len] = '\0';
+          /* register passing this label */
+          if (!setLabelRefPassedLabel (label))
+            {
+              D(fprintf (stderr, DEADMOVEERROR);)
+              return S4O_ABORT;
+            }
+          continue;
+        }
+
+      /* branch or terminate? */
+      isConditionalJump = FALSE;
+      switch ((*pl)->line[0])
+        {
+          case 'a':
+            if (strncmp ("acall", (*pl)->line, 5) == 0)
+              return S4O_TERM;
+            if (strncmp ("ajmp", (*pl)->line, 4) == 0)
+              {
+                *pl = findLabel (*pl);
+                if (!*pl)
+                  return S4O_ABORT;
+              }
+            break;
+          case 'c':
+            if (strncmp ("cjne", (*pl)->line, 4) == 0)
+              {
+                isConditionalJump = TRUE;
+                break;
+              }
+            break;
+          case 'd':
+            if (strncmp ("djnz", (*pl)->line, 4) == 0)
+              {
+                isConditionalJump = TRUE;
+                break;
+              }
+            break;
+          case 'j':
+            if (strncmp ("jmp", (*pl)->line, 3) == 0)
+              /* "jmp @a+dptr": no chance to trace execution */
+              return S4O_ABORT;
+            if (strncmp ("jc",  (*pl)->line, 2) == 0 ||
+                strncmp ("jnc", (*pl)->line, 3) == 0 ||
+                strncmp ("jz",  (*pl)->line, 2) == 0 ||
+                strncmp ("jnz", (*pl)->line, 3) == 0)
+              {
+                isConditionalJump = TRUE;
+                break;
+              }
+            if (strncmp ("jbc", (*pl)->line, 3) == 0 ||
+                strncmp ("jb",  (*pl)->line, 2) == 0 ||
+                strncmp ("jnb", (*pl)->line, 3) == 0)
+              {
+                isConditionalJump = TRUE;
+                break;
+              }
+            break;
+          case 'l':
+            if (strncmp ("lcall", (*pl)->line, 5) == 0)
+              return S4O_TERM;
+            if (strncmp ("ljmp", (*pl)->line, 4) == 0)
+              {
+                *pl = findLabel (*pl);
+                if (!*pl)
+                  return S4O_ABORT;
+              }
+            break;
+          case 'p':
+            if (strncmp ("pop", (*pl)->line, 3) == 0 ||
+                strncmp ("push", (*pl)->line, 4) == 0)
+              return S4O_PUSHPOP;
+            break;
+          case 'r':
+            /* pcall uses ret */
+            if (strncmp ("ret", (*pl)->line, 3) == 0) /* catches "reti" too */
+              return S4O_TERM;
+            break;
+          case 's':
+            if (strncmp ("sjmp", (*pl)->line, 4) == 0)
+              {
+                *pl = findLabel (*pl);
+                if (!*pl)
+                  return S4O_ABORT;
+              }
+            break;
+          default:
+            break;
+        } /* switch ((*pl)->line[0]) */
+
+      if (isConditionalJump)
+        {
+          *plCond = findLabel (*pl);
+          if (!*plCond)
+            return S4O_ABORT;
+          return S4O_CONDJMP;
+        }
+    } /* for (; *pl; *pl = (*pl)->next) */
+  return S4O_ABORT;
+}
+
+/*-----------------------------------------------------------------*/
+/* doPushScan - scan through area 1. This small wrapper handles:   */
+/* - action required on different return values                    */
+/* - recursion in case of conditional branches                     */
+/*-----------------------------------------------------------------*/
+static bool
+doPushScan (lineNode **pl, const char *pReg)
+{
+  lineNode *plConditional, *pushPl = NULL;
+
+  for (;; *pl = (*pl)->next)
+    {
+      switch (scan4op (pl, pReg, "push", &plConditional))
+        {
+          case S4O_FOUNDOPCODE:
+            /* this is what we're looking for */
+            return TRUE;
+          case S4O_VISITED:
+            if (!pushPl)
+              {
+                D(fprintf (stderr, DEADMOVEERROR);)
+                return FALSE;
+              }
+            *pl = pushPl;
+            /* already checked */
+            return TRUE;
+          case S4O_CONDJMP:
+            /* two possible destinations: recurse */
+              {
+                lineNode *pushPl2 = plConditional;
+
+                if (!doPushScan (&pushPl2, pReg))
+                  return FALSE;
+                pushPl = pushPl2;
+              }
+            continue;
+          default:
+            return FALSE;
+        }
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* doTermScan - scan through area 2. This small wrapper handles:   */
+/* - action required on different return values                    */
+/* - recursion in case of conditional branches                     */
+/*-----------------------------------------------------------------*/
+static bool
+doTermScan (lineNode **pl, const char *pReg)
+{
+  lineNode *plConditional;
+
+  for (;; *pl = (*pl)->next)
+    {
+      switch (scan4op (pl, pReg, NULL, &plConditional))
+        {
+          case S4O_TERM:
+          case S4O_VISITED:
+          case S4O_WR_OP:
+            /* all these are terminating condtions */
+            return TRUE;
+          case S4O_PUSHPOP:
+            /* don't care, go on */
+            continue;
+          case S4O_CONDJMP:
+            /* two possible destinations: recurse */
+              {
+                lineNode *pl2 = plConditional;
+
+                if (!doTermScan (&pl2, pReg))
+                  return FALSE;
+              }
+            continue;
+          case S4O_RD_OP:
+          default:
+            /* no go */
+            return FALSE;
+        }
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* -                                                               */
+/*-----------------------------------------------------------------*/
+bool
+mcs51DeadMove (const char *op1, lineNode *currPl, lineNode *head)
+{
+  char pReg[5] = "ar";
+  lineNode *pushPl, *pl;
+
+  /* A pop/push pair can be removed, if these criteria are met
+     (ar0 is just an example here, ar0...ar7 are possible):
+
+     pop ar0
+
+      ; area 1
+
+      ; There must not be in area 1:
+      ;    - read or write access of ar0
+      ;    - "acall", "lcall", "pop", "ret", "reti" or "jmp @a+dptr" opcodes
+      ;    - "push" opcode, which doesn't push ar0 
+      ;    - inline assembly
+      ;    - a jump in or out of area 1 (see checkLabelRef())
+
+      ; Direct manipulation of sp is not detected. This isn't necessary
+      ; as long as sdcc doesn't emit such code in area 1.
+
+      ; area 1 must be terminated by a:
+     push ar0
+
+      ; area 2
+
+      ; There must not be:
+      ;    - read access of ar0
+      ;    - "jmp @a+dptr" opcode
+      ;    - inline assembly
+      ;    - a jump in or out of area 2 (see checkLabelRef())
+
+      ; An "acall", "lcall", "ret", "reti" or write access of ar0 terminate
+      ; the search, and the pop/push pair can safely be removed.
+  */
+
+  _G.head = head;
+  strcat (pReg, op1);
+
+  unvisitLines (_G.head);
+  cleanLabelRef();
+
+  /* area 1 */
+  pushPl = currPl->next;
+  if (!doPushScan (&pushPl, pReg))
+    return FALSE;
+
+  if (!checkLabelRef())
+    return FALSE;
+
+  /* area 2 */
+  pl = pushPl->next;
+  if (!doTermScan (&pl, pReg))
+    return FALSE;
+  if (!checkLabelRef())
+    return FALSE;
+
+  /* Success! */
+  if (options.noPeepComments)
+    {
+      /* remove pushPl from list */
+      pushPl->prev->next = pushPl->next;
+      pushPl->next->prev = pushPl->prev;
+    }
+  else
+    {
+      /* replace 'push ar0' by comment */
+      #define STR ";\tPeephole\tpush %s removed"
+      int size = sizeof(STR) + 2;
+
+      pushPl->line = Safe_alloc (size);
+      SNPRINTF (pushPl->line, size, STR, pReg);
+      pushPl->isComment = TRUE;
+    }
+
+  /* 'pop ar0' will be removed by peephole framework after returning TRUE */
+  return TRUE;
+}
diff --git a/src/mcs51/peep.h b/src/mcs51/peep.h
new file mode 100644 (file)
index 0000000..4958dea
--- /dev/null
@@ -0,0 +1,25 @@
+/*-------------------------------------------------------------------------
+  peep.h - header file for peephole optimizer helper functions
+
+  Written By -  Bernhard Held
+
+  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.
+
+  In other words, you are welcome to use, share and improve this program.
+  You are forbidden to forbid anyone else to use, share and improve
+  what you give them.   Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+
+bool mcs51DeadMove (const char *op, lineNode *currPl, lineNode *head);
index feab2599b201b4e814aa9cad9fffbbdb123c41dd..8369811dd5f9a9e481bfc4543e798ea09de5020a 100644 (file)
@@ -1,20 +1,3 @@
-//replace restart {
-//       pop  %1
-//       push %1
-//} by {
-//       ;       Peephole 1     removed pop %1 push %1 (not push pop)
-//}
-
-//replace restart {
-//       pop  %1
-//       mov  %2,%3
-//       push %1
-//} by {
-//       ;       Peephole 2     removed pop %1 push %1 (not push pop)
-//       mov  %2,%3
-//}
-
-//
 // added by Jean Louis VERN for
 // his shift stuff
 replace {
@@ -4608,10 +4591,15 @@ replace {
 %3:
 } if labelRefCount(%3 1), labelRefCountChange(%3 -1)
 
+replace restart {
+       pop     ar%1
+} by {
+       ;       Peephole 300    pop ar%1 removed
+} if deadMove %1
 
 // should be one of the last peepholes
 replace{
 %1:
 } by {
-       ;       Peephole 300    removed redundant label %1
+       ;       Peephole 400    removed redundant label %1
 } if labelRefCount(%1 0)
index 0f97a41d7865426e369cfde6c430ba0640c9894d..2fa2fccc9ab55bbdc025031554ee31da1f414ce6 100644 (file)
@@ -301,7 +301,7 @@ void pic14_emitcode (char *inst,char *fmt, ...)
 {
        va_list ap;
        char lb[INITIAL_INLINEASM];  
-       unsigned char *lbp = (unsigned char *)lb;
+       char *lbp = lb;
        
        va_start(ap,fmt);   
        
@@ -322,6 +322,7 @@ void pic14_emitcode (char *inst,char *fmt, ...)
        (lineHead = newLineNode(lb)));
        lineCurr->isInline = _G.inLine;
        lineCurr->isDebug  = _G.debugLine;
+       lineCurr->isLabel = (lbp[strlen (lbp) - 1] == ':');
        
        if(debug_verbose)
                addpCode2pBlock(pb,newpCodeCharP(lb));
index 3c2cb78292d50ec13495537ec972fc534cbf9dc4..00ffa03838faa168bf1fa0b3b5d3fb709d9a4fda 100644 (file)
@@ -266,6 +266,7 @@ void pic16_emitpcomment (char *fmt, ...)
                     (lineHead = newLineNode(lb)));
     lineCurr->isInline = _G.inLine;
     lineCurr->isDebug  = _G.debugLine;
+    lineCurr->isComment = 1;
 
     pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
     va_end(ap);
@@ -378,6 +379,8 @@ void pic16_emitcode (char *inst,char *fmt, ...)
                     (lineHead = newLineNode(lb)));
     lineCurr->isInline = _G.inLine;
     lineCurr->isDebug  = _G.debugLine;
+    lineCurr->isLabel = (lbp[strlen (lbp) - 1] == ':');
+    lineCurr->isComment = (*lbp == ';');
 
 // VR    fprintf(stderr, "lb = <%s>\n", lbp);
 
index e07d7a95ee00eda51d910c82275240e18723fc39..af16bfcf2698fa9218fb8ea7cc806edeecc89a3b 100644 (file)
@@ -8,6 +8,7 @@
 #include "SDCCicode.h"
 #include "SDCCargs.h"
 #include "SDCCpeeph.h"
+#include "mcs51/peep.h"
 
 #define TARGET_ID_MCS51    1
 #define TARGET_ID_GBZ80    2
@@ -131,6 +132,7 @@ typedef struct
         int (*getSize)(lineNode *line);
         bitVect * (*getRegsRead)(lineNode *line);
         bitVect * (*getRegsWritten)(lineNode *line);
+        bool (*deadMove) (const char *op, lineNode *currPl, lineNode *head);
       }
     peep;
 
index d2d02ba740cd46451b841ea5f523ddf1a7fa1812..98d02c801e98b6ab36a4c256bfea41597671d781 100644 (file)
@@ -413,6 +413,7 @@ _vemit2 (const char *szFormat, va_list ap)
   _G.lines.current->isInline = _G.lines.isInline;
   _G.lines.current->isDebug = _G.lines.isDebug;
   _G.lines.current->ic = _G.current_iCode;
+  _G.lines.current->isComment = (*buffer == ';');
 }
 
 static void
@@ -1636,6 +1637,7 @@ static void
 emitLabel (int key)
 {
   emit2 ("!tlabeldef", key);
+  _G.lines.current->isLabel = 1;
   spillCached ();
 }
 
@@ -2899,6 +2901,7 @@ emitCall (iCode * ic, bool ispcall)
           fetchHL (AOP (IC_LEFT (ic)));
           emit2 ("jp !*hl");
           emit2 ("!tlabeldef", (rlbl->key + 100));
+          _G.lines.current->isLabel = 1;
           _G.stack.pushed -= 2;
         }
       freeAsmop (IC_LEFT (ic), NULL, ic);
@@ -3112,8 +3115,10 @@ genFunction (iCode * ic)
     {
       sprintf (buffer, "%s_start", sym->rname);
       emit2 ("!labeldef", buffer);
+      _G.lines.current->isLabel = 1;
     }
   emit2 ("!functionlabeldef", sym->rname);
+  _G.lines.current->isLabel = 1;
 
   ftype = operandType (IC_LEFT (ic));
 
@@ -3332,6 +3337,7 @@ genEndFunction (iCode * ic)
               emit2 ("jp PO,!tlabel", tlbl->key + 100);
               emit2 ("!ei");
               emit2 ("!tlabeldef", (tlbl->key + 100));
+              _G.lines.current->isLabel = 1;
             }
         }
     }
@@ -3359,6 +3365,7 @@ genEndFunction (iCode * ic)
     {
       sprintf (buffer, "%s_end", sym->rname);
       emit2 ("!labeldef", buffer);
+      _G.lines.current->isLabel = 1;
     }
 
   _G.flushStatics = 1;
@@ -5169,6 +5176,7 @@ genAnd (iCode * ic, iCode * ifx)
         {
           emit2 ("clr c");
           emit2 ("!tlabeldef", tlbl->key + 100);
+          _G.lines.current->isLabel = 1;
         }
       // if(left & literal)
       else
@@ -7469,6 +7477,7 @@ genCritical (iCode *ic)
       emit2 ("jp PO,!tlabel", tlbl->key + 100);
       aopPut (AOP (IC_RESULT (ic)), "!one", 0);
       emit2 ("!tlabeldef", (tlbl->key + 100));
+      _G.lines.current->isLabel = 1;
       freeAsmop (IC_RESULT (ic), NULL, ic);
     }
   else
@@ -7513,6 +7522,7 @@ genEndCritical (iCode *ic)
       emit2 ("jp PO,!tlabel", tlbl->key + 100);
       emit2 ("!ei");
       emit2 ("!tlabeldef", (tlbl->key + 100));
+      _G.lines.current->isLabel = 1;
     }
 }
 
index 18e3d77e5b6c33faf977b7b604f4fc8b549c2853..b8ad485a655deca9ea0efc3ef4fc3a98e344b6dc 100644 (file)
@@ -1538,6 +1538,7 @@ createRegMask (eBBlock ** ebbs, int count)
     }
 }
 
+#if 0
 /** Returns the rematerialized string for a remat var.
  */
 static char *
@@ -1587,6 +1588,7 @@ rematStr (symbol * sym)
     }
   return buffer;
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* regTypeNum - computes the type & number of registers required   */