corrected date in Changelog
[fw/sdcc] / src / SDCCpeeph.c
index ed9e4bdfabb86db89a82dc774bb4378841eb14b7..c5534bc2ed69466b94901c1971551695d90bb7bd 100644 (file)
@@ -178,6 +178,51 @@ FBYNAME (labelInRange)
   return TRUE;
 }
 
+
+/*-----------------------------------------------------------------*/
+/* labelJTInRange - will check to see if label %5 and up are       */
+/* within range.                                                   */
+/* Specifically meant to optimize long (3-byte) jumps to short     */
+/* (2-byte) jumps in jumptables                                    */
+/*-----------------------------------------------------------------*/
+FBYNAME (labelJTInRange)
+{
+  char *lbl;
+  int dist, count, i;
+
+  if (!getenv("SDCC_SJMP_JUMPTABLE"))
+    return FALSE;
+  
+  /* Only optimize within a jump table */
+  if (currPl->ic && currPl->ic->op != JUMPTABLE)
+    return FALSE;
+  
+  count = elementsInSet( IC_JTLABELS (currPl->ic) );
+  
+  /* check all labels (this is needed if the case statements are unsorted) */
+  for (i=0; i<count; i++)
+    {
+      /* assumes that the %5 pattern variable has the first ljmp label */
+      lbl = hTabItemWithKey (vars, 5+i);
+      if (!lbl)
+        return FALSE;
+    
+      dist = pcDistance (currPl, lbl, FALSE);
+
+      /* three terms used to calculate allowable distance */
+// printf("\nlabel %s %i dist %i cdist 0x%02x 0x%02x\n", lbl, i, dist, dist -(count-i-1)-(7+3*i), 127+(count-i-1)+(7+3*i) - dist);
+      if (!dist ||
+          dist > 127+           /* range of sjmp */
+                 (7+3*i)+       /* offset between this jump and currPl, 
+                                   should use pcDistance instead? */
+                 (count-i-1)    /* if peephole applies distance is shortened */
+         )
+        return FALSE;
+    }
+  return TRUE;
+}
+
+
 /*-----------------------------------------------------------------*/
 /* labelIsReturnOnly - Check if label %5 is followed by RET        */
 /*-----------------------------------------------------------------*/
@@ -187,13 +232,14 @@ FBYNAME (labelIsReturnOnly)
   const char *label, *p;
   const lineNode *pl;
   int len;
+  char * retInst;
 
   label = hTabItemWithKey (vars, 5);
   if (!label) return FALSE;
   len = strlen(label);
 
   for(pl = currPl; pl; pl = pl->next) {
-       if (pl->line && !pl->isDebug &&
+       if (pl->line && !pl->isDebug && !pl->isComment &&
          pl->line[strlen(pl->line)-1] == ':') {
                if (strncmp(pl->line, label, len) == 0) break; /* Found Label */
                if (strlen(pl->line) != 7 || !isdigit(*(pl->line)) ||
@@ -206,11 +252,17 @@ FBYNAME (labelIsReturnOnly)
   }
   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 */
   p = pl->line;
   for (p = pl->line; *p && isspace(*p); p++)
          ;
-  if (strcmp(p, "ret") == 0) return TRUE;
+  
+  retInst = "ret";
+  if (TARGET_IS_HC08)
+    retInst = "rts";
+  if (strcmp(p, retInst) == 0) return TRUE;
   return FALSE;
 }
 
@@ -728,6 +780,10 @@ callFuncByName (char *fname,
       "labelInRange", labelInRange
     }
     ,
+    {
+      "labelJTInRange", labelJTInRange
+    }
+    ,
     {
       "operandsNotSame", operandsNotSame
     }
@@ -945,6 +1001,7 @@ getPeepLine (lineNode ** head, char **bpp)
 {
   char lines[MAX_PATTERN_LEN];
   char *lp;
+  int isComment;
 
   lineNode *currL = NULL;
   char *bp = *bpp;
@@ -975,18 +1032,22 @@ getPeepLine (lineNode ** head, char **bpp)
       lp = lines;
       while ((*bp != '\n' && *bp != '}') && *bp)
        *lp++ = *bp++;
-
       *lp = '\0';
-      if (!currL)
-       *head = currL = newLineNode (lines);
-      else
-       currL = connectLine (currL, newLineNode (lines));
-
+      
       lp = lines;
       while (*lp && isspace(*lp))
         lp++;
-      if (*lp==';')
-        currL->isComment = 1;
+      isComment = (*lp == ';');
+        
+      if (!isComment || (isComment && !options.noPeepComments))
+       {
+         if (!currL)
+           *head = currL = newLineNode (lines);
+         else
+           currL = connectLine (currL, newLineNode (lines));
+         currL->isComment = isComment;
+       }
+
     }
 
   *bpp = bp;
@@ -1558,23 +1619,35 @@ replaceRule (lineNode ** shead, lineNode * stail, peepRule * pr)
       lhead = comment;
     }
 
-  /* determine which iCodes the replacment lines relate to */
-  reassociate_ic(*shead,stail,lhead,cl);
-
-  /* now we need to connect / replace the original chain */
-  /* if there is a prev then change it */
-  if ((*shead)->prev)
+  if (lhead)
     {
-      (*shead)->prev->next = lhead;
-      lhead->prev = (*shead)->prev;
+      /* determine which iCodes the replacment lines relate to */
+      reassociate_ic(*shead,stail,lhead,cl);
+
+      /* now we need to connect / replace the original chain */
+      /* if there is a prev then change it */
+      if ((*shead)->prev)
+       {
+         (*shead)->prev->next = lhead;
+         lhead->prev = (*shead)->prev;
+       }
+      *shead = lhead;
+      /* now for the tail */
+      if (stail && stail->next)
+       {
+         stail->next->prev = cl;
+         if (cl)
+           cl->next = stail->next;
+       }
     }
-  *shead = lhead;
-  /* now for the tail */
-  if (stail && stail->next)
+  else
     {
-      stail->next->prev = cl;
-      if (cl)
-       cl->next = stail->next;
+      /* the replacement is empty - delete the source lines */
+      if ((*shead)->prev)
+        (*shead)->prev->next = stail->next;
+      if (stail->next)
+        stail->next->prev = (*shead)->prev;
+      *shead = stail->next;
     }
 }
 
@@ -1668,6 +1741,12 @@ buildLabelRefCountHash (lineNode * head)
          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++;
 
          hTabAddItem (&labelHash, hashSymbolName (entry->name), entry);
        }