More strcpy() strcat() sprintf() squashing
[fw/sdcc] / src / SDCCpeeph.c
index 37b8634bcba38368d5878972564024889f53c83e..a928f3a0e1084f1b0b0a1a5add4c7d6660b5f40a 100644 (file)
 -------------------------------------------------------------------------*/
 
 #include "common.h"
-#include "SDCCpeeph.h"
-#include "newalloc.h"
 
-peepRule *rootRules = NULL;
-peepRule *currRule = NULL;
+static peepRule *rootRules = NULL;
+static peepRule *currRule = NULL;
 
 #define HTAB_SIZE 53
 typedef struct
@@ -38,7 +36,13 @@ typedef struct
   }
 labelHashEntry;
 
-hTab *labelHash = NULL;
+static hTab *labelHash = NULL;
+
+static struct
+{
+  allocTrace values;
+  allocTrace labels;
+} _G;
 
 static int hashSymbolName (const char *name);
 static void buildLabelRefCountHash (lineNode * head);
@@ -48,6 +52,10 @@ static bool matchLine (char *, char *, hTab **);
 #define FBYNAME(x) int x (hTab *vars, lineNode *currPl, lineNode *head, \
         const char *cmdLine)
 
+#if !OPT_DISABLE_PIC
+void  peepRules2pCode(peepRule *);
+#endif
+
 /*-----------------------------------------------------------------*/
 /* pcDistance - afinds a label back ward or forward                */
 /*-----------------------------------------------------------------*/
@@ -58,7 +66,7 @@ pcDistance (lineNode * cpos, char *lbl, bool back)
   char buff[MAX_PATTERN_LEN];
   int dist = 0;
 
-  sprintf (buff, "%s:", lbl);
+  SNPRINTF (buff, sizeof(buff), "%s:", lbl);
   while (pl)
     {
 
@@ -81,6 +89,23 @@ pcDistance (lineNode * cpos, char *lbl, bool back)
   return 0;
 }
 
+/*-----------------------------------------------------------------*/
+/* flat24bitModeAndPortDS390 -                                            */
+/*-----------------------------------------------------------------*/
+FBYNAME (flat24bitModeAndPortDS390)
+{
+    return ((strcmp(port->target,"ds390") == 0) && 
+           (options.model == MODEL_FLAT24));
+}
+
+/*-----------------------------------------------------------------*/
+/* portIsDS390 - return true if port is DS390                             */
+/*-----------------------------------------------------------------*/
+FBYNAME (portIsDS390)
+{
+    return (strcmp(port->target,"ds390") == 0);
+}
+
 /*-----------------------------------------------------------------*/
 /* flat24bitMode - will check to see if we are in flat24 mode      */
 /*-----------------------------------------------------------------*/
@@ -89,6 +114,14 @@ FBYNAME (flat24bitMode)
   return (options.model == MODEL_FLAT24);
 }
 
+/*-----------------------------------------------------------------*/
+/* xramMovcOption - check if using movc to read xram               */
+/*-----------------------------------------------------------------*/
+FBYNAME (xramMovcOption)
+{
+  return (options.xram_movc && (strcmp(port->target,"mcs51") == 0));
+}
+
 /*-----------------------------------------------------------------*/
 /* labelInRange - will check to see if label %5 is within range    */
 /*-----------------------------------------------------------------*/
@@ -101,7 +134,7 @@ FBYNAME (labelInRange)
   if (!lbl)
     return FALSE;
 
-  /* if the previous teo instructions are "ljmp"s then don't
+  /* if the previous two instructions are "ljmp"s then don't
      do it since it can be part of a jump table */
   if (currPl->prev && currPl->prev->prev &&
       strstr (currPl->prev->line, "ljmp") &&
@@ -142,6 +175,190 @@ FBYNAME (operandsNotSame)
     return TRUE;
 }
 
+/*-----------------------------------------------------------------*/
+/* operandsNotSame3- check if any pair of %1,%2,%3 are the same    */
+/*-----------------------------------------------------------------*/
+FBYNAME (operandsNotSame3)
+{
+  char *op1 = hTabItemWithKey (vars, 1);
+  char *op2 = hTabItemWithKey (vars, 2);
+  char *op3 = hTabItemWithKey (vars, 3);
+
+  if ( (strcmp (op1, op2) == 0) ||
+       (strcmp (op1, op3) == 0) ||
+       (strcmp (op2, op3) == 0) )
+    return FALSE;
+  else
+    return TRUE;
+}
+
+/*-----------------------------------------------------------------*/
+/* operandsNotSame4- check if any pair of %1,%2,%3,.. are the same */
+/*-----------------------------------------------------------------*/
+FBYNAME (operandsNotSame4)
+{
+  char *op1 = hTabItemWithKey (vars, 1);
+  char *op2 = hTabItemWithKey (vars, 2);
+  char *op3 = hTabItemWithKey (vars, 3);
+  char *op4 = hTabItemWithKey (vars, 4);
+
+  if ( (strcmp (op1, op2) == 0) ||
+       (strcmp (op1, op3) == 0) ||
+       (strcmp (op1, op4) == 0) ||
+       (strcmp (op2, op3) == 0) ||
+       (strcmp (op2, op4) == 0) ||
+       (strcmp (op3, op4) == 0) )
+    return FALSE;
+  else
+    return TRUE;
+}
+
+/*-----------------------------------------------------------------*/
+/* operandsNotSame5- check if any pair of %1,%2,%3,.. are the same */
+/*-----------------------------------------------------------------*/
+FBYNAME (operandsNotSame5)
+{
+  char *op1 = hTabItemWithKey (vars, 1);
+  char *op2 = hTabItemWithKey (vars, 2);
+  char *op3 = hTabItemWithKey (vars, 3);
+  char *op4 = hTabItemWithKey (vars, 4);
+  char *op5 = hTabItemWithKey (vars, 5);
+
+  if ( (strcmp (op1, op2) == 0) ||
+       (strcmp (op1, op3) == 0) ||
+       (strcmp (op1, op4) == 0) ||
+       (strcmp (op1, op5) == 0) ||
+       (strcmp (op2, op3) == 0) ||
+       (strcmp (op2, op4) == 0) ||
+       (strcmp (op2, op5) == 0) ||
+       (strcmp (op3, op4) == 0) ||
+       (strcmp (op3, op5) == 0) ||
+       (strcmp (op4, op5) == 0) )
+    return FALSE;
+  else
+    return TRUE;
+}
+
+/*-----------------------------------------------------------------*/
+/* operandsNotSame6- check if any pair of %1,%2,%3,.. are the same */
+/*-----------------------------------------------------------------*/
+FBYNAME (operandsNotSame6)
+{
+  char *op1 = hTabItemWithKey (vars, 1);
+  char *op2 = hTabItemWithKey (vars, 2);
+  char *op3 = hTabItemWithKey (vars, 3);
+  char *op4 = hTabItemWithKey (vars, 4);
+  char *op5 = hTabItemWithKey (vars, 5);
+  char *op6 = hTabItemWithKey (vars, 6);
+
+  if ( (strcmp (op1, op2) == 0) ||
+       (strcmp (op1, op3) == 0) ||
+       (strcmp (op1, op4) == 0) ||
+       (strcmp (op1, op5) == 0) ||
+       (strcmp (op1, op6) == 0) ||
+       (strcmp (op2, op3) == 0) ||
+       (strcmp (op2, op4) == 0) ||
+       (strcmp (op2, op5) == 0) ||
+       (strcmp (op2, op6) == 0) ||
+       (strcmp (op3, op4) == 0) ||
+       (strcmp (op3, op5) == 0) ||
+       (strcmp (op3, op6) == 0) ||
+       (strcmp (op4, op5) == 0) ||
+       (strcmp (op4, op6) == 0) ||
+       (strcmp (op5, op6) == 0) )
+    return FALSE;
+  else
+    return TRUE;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* operandsNotSame7- check if any pair of %1,%2,%3,.. are the same */
+/*-----------------------------------------------------------------*/
+FBYNAME (operandsNotSame7)
+{
+  char *op1 = hTabItemWithKey (vars, 1);
+  char *op2 = hTabItemWithKey (vars, 2);
+  char *op3 = hTabItemWithKey (vars, 3);
+  char *op4 = hTabItemWithKey (vars, 4);
+  char *op5 = hTabItemWithKey (vars, 5);
+  char *op6 = hTabItemWithKey (vars, 6);
+  char *op7 = hTabItemWithKey (vars, 7);
+
+  if ( (strcmp (op1, op2) == 0) ||
+       (strcmp (op1, op3) == 0) ||
+       (strcmp (op1, op4) == 0) ||
+       (strcmp (op1, op5) == 0) ||
+       (strcmp (op1, op6) == 0) ||
+       (strcmp (op1, op7) == 0) ||
+       (strcmp (op2, op3) == 0) ||
+       (strcmp (op2, op4) == 0) ||
+       (strcmp (op2, op5) == 0) ||
+       (strcmp (op2, op6) == 0) ||
+       (strcmp (op2, op7) == 0) ||
+       (strcmp (op3, op4) == 0) ||
+       (strcmp (op3, op5) == 0) ||
+       (strcmp (op3, op6) == 0) ||
+       (strcmp (op3, op7) == 0) ||
+       (strcmp (op4, op5) == 0) ||
+       (strcmp (op4, op6) == 0) ||
+       (strcmp (op4, op7) == 0) ||
+       (strcmp (op5, op6) == 0) ||
+       (strcmp (op5, op7) == 0) ||
+       (strcmp (op6, op7) == 0) )
+    return FALSE;
+  else
+    return TRUE;
+}
+
+/*-----------------------------------------------------------------*/
+/* operandsNotSame8- check if any pair of %1,%2,%3,.. are the same */
+/*-----------------------------------------------------------------*/
+FBYNAME (operandsNotSame8)
+{
+  char *op1 = hTabItemWithKey (vars, 1);
+  char *op2 = hTabItemWithKey (vars, 2);
+  char *op3 = hTabItemWithKey (vars, 3);
+  char *op4 = hTabItemWithKey (vars, 4);
+  char *op5 = hTabItemWithKey (vars, 5);
+  char *op6 = hTabItemWithKey (vars, 6);
+  char *op7 = hTabItemWithKey (vars, 7);
+  char *op8 = hTabItemWithKey (vars, 8);
+
+  if ( (strcmp (op1, op2) == 0) ||
+       (strcmp (op1, op3) == 0) ||
+       (strcmp (op1, op4) == 0) ||
+       (strcmp (op1, op5) == 0) ||
+       (strcmp (op1, op6) == 0) ||
+       (strcmp (op1, op7) == 0) ||
+       (strcmp (op1, op8) == 0) ||
+       (strcmp (op2, op3) == 0) ||
+       (strcmp (op2, op4) == 0) ||
+       (strcmp (op2, op5) == 0) ||
+       (strcmp (op2, op6) == 0) ||
+       (strcmp (op2, op7) == 0) ||
+       (strcmp (op2, op8) == 0) ||
+       (strcmp (op3, op4) == 0) ||
+       (strcmp (op3, op5) == 0) ||
+       (strcmp (op3, op6) == 0) ||
+       (strcmp (op3, op7) == 0) ||
+       (strcmp (op3, op8) == 0) ||
+       (strcmp (op4, op5) == 0) ||
+       (strcmp (op4, op6) == 0) ||
+       (strcmp (op4, op7) == 0) ||
+       (strcmp (op4, op8) == 0) ||
+       (strcmp (op5, op6) == 0) ||
+       (strcmp (op5, op7) == 0) ||
+       (strcmp (op5, op8) == 0) ||
+       (strcmp (op6, op7) == 0) ||
+       (strcmp (op6, op8) == 0) ||
+       (strcmp (op7, op8) == 0) )
+    return FALSE;
+  else
+    return TRUE;
+}
+
+
 /* labelRefCount:
 
  * takes two parameters: a variable (bound to a label name)
@@ -237,14 +454,48 @@ callFuncByName (char *fname,
       "operandsNotSame", operandsNotSame
     }
     ,
+    {
+      "operandsNotSame3", operandsNotSame3
+    }
+    ,
+    {
+      "operandsNotSame4", operandsNotSame4
+    }
+    ,
+    {
+      "operandsNotSame5", operandsNotSame5
+    }
+    ,
+    {
+      "operandsNotSame6", operandsNotSame6
+    }
+    ,
+    {
+      "operandsNotSame7", operandsNotSame7
+    }
+    ,
+    {
+      "operandsNotSame8", operandsNotSame8
+    }
+    ,
     {
       "24bitMode", flat24bitMode
     }
     ,
+    {
+      "xramMovcOption", xramMovcOption
+    }
+    ,
     {
       "labelRefCount", labelRefCount
     }
     ,
+    {
+      "portIsDS390", portIsDS390
+    },
+    {
+      "24bitModeAndPortDS390", flat24bitModeAndPortDS390
+    }
   };
   int i;
 
@@ -272,10 +523,15 @@ printLine (lineNode * head, FILE * of)
       /* don't indent comments & labels */
       if (head->line &&
          (*head->line == ';' ||
-          head->line[strlen (head->line) - 1] == ':'))
+          head->line[strlen (head->line) - 1] == ':')) {
        fprintf (of, "%s\n", head->line);
-      else
+      } else {
+       if (head->isInline && *head->line=='#') {
+         // comment out preprocessor directives in inline asm
+         fprintf (of, ";");
+       }
        fprintf (of, "\t%s\n", head->line);
+      }
       head = head->next;
     }
 }
@@ -291,15 +547,14 @@ newPeepRule (lineNode * match,
 {
   peepRule *pr;
 
-  pr = Safe_calloc (1, sizeof (peepRule));
+  pr = Safe_alloc ( sizeof (peepRule));
   pr->match = match;
   pr->replace = replace;
   pr->restart = restart;
 
   if (cond && *cond)
     {
-      pr->cond = Safe_calloc (1, strlen (cond) + 1);
-      strcpy (pr->cond, cond);
+      pr->cond = Safe_strdup (cond);
     }
   else
     pr->cond = NULL;
@@ -323,9 +578,8 @@ newLineNode (char *line)
 {
   lineNode *pl;
 
-  pl = Safe_calloc (1, sizeof (lineNode));
-  pl->line = Safe_calloc (1, strlen (line) + 1);
-  strcpy (pl->line, line);
+  pl = Safe_alloc ( sizeof (lineNode));
+  pl->line = Safe_strdup (line);
   return pl;
 }
 
@@ -552,6 +806,8 @@ bindVar (int key, char **s, hTab ** vtab)
              if (*vvx == ')')
                ubb--;
            }
+         // include the trailing ')'
+         *vv++ = *vvx++;
        }
       else
        *vv++ = *vvx++;
@@ -559,10 +815,9 @@ bindVar (int key, char **s, hTab ** vtab)
   *s = vvx;
   *vv = '\0';
   /* got value */
-  vvx = Safe_calloc (1, strlen (vval) + 1);
-  strcpy (vvx, vval);
-  hTabAddItem (vtab, key, vvx);
+  vvx = traceAlloc (&_G.values, Safe_strdup(vval));
 
+  hTabAddItem (vtab, key, vvx);
 }
 
 /*-----------------------------------------------------------------*/
@@ -650,7 +905,6 @@ matchRule (lineNode * pl,
   lineNode *spl;               /* source pl */
   lineNode *rpl;               /* rule peep line */
 
-  hTabClearAll (pr->vars);
 /*     setToNull((void **) &pr->vars);    */
 /*     pr->vars = newHashTable(100); */
 
@@ -736,6 +990,7 @@ replaceRule (lineNode ** shead, lineNode * stail, peepRule * pr)
       lbp = lb;
 
       l = pl->line;
+
       while (*l)
        {
          /* if the line contains a variable */
@@ -786,8 +1041,7 @@ replaceRule (lineNode ** shead, lineNode * stail, peepRule * pr)
       (*shead)->prev->next = lhead;
       lhead->prev = (*shead)->prev;
     }
-  else
-    *shead = lhead;
+  *shead = lhead;
   /* now for the tail */
   if (stail && stail->next)
     {
@@ -882,7 +1136,7 @@ buildLabelRefCountHash (lineNode * head)
        {
          labelHashEntry *entry;
 
-         entry = Safe_calloc (1, sizeof (labelHashEntry));
+         entry = traceAlloc (&_G.labels, Safe_alloc(sizeof (labelHashEntry)));
 
          memcpy (entry->name, label, labelLen);
          entry->name[labelLen] = 0;
@@ -935,6 +1189,21 @@ buildLabelRefCountHash (lineNode * head)
 #endif
 }
 
+/* How does this work?
+   peepHole
+    For each rule,
+     For each line,
+      Try to match
+      If it matches,
+       replace and restart.
+
+    matchRule
+     matchLine
+
+  Where is stuff allocated?
+  
+*/
+
 /*-----------------------------------------------------------------*/
 /* peepHole - matches & substitutes rules                          */
 /*-----------------------------------------------------------------*/
@@ -944,43 +1213,69 @@ peepHole (lineNode ** pls)
   lineNode *spl;
   peepRule *pr;
   lineNode *mtail = NULL;
+  bool restart;
+
+#if !OPT_DISABLE_PIC
+  /* The PIC port uses a different peep hole optimizer based on "pCode" */
+  if (TARGET_IS_PIC)
+    return;
+#endif
+
+  assert(labelHash == NULL);
+
+  do
+    {
+      restart = FALSE;
+
+      /* for all rules */
+      for (pr = rootRules; pr; pr = pr->next)
+        {
+          for (spl = *pls; spl; spl = spl->next)
+            {
+              /* if inline assembler then no peep hole */
+              if (spl->isInline)
+                continue;
+              
+              mtail = NULL;
+
+              /* Tidy up any data stored in the hTab */
+              
+              /* if it matches */
+              if (matchRule (spl, &mtail, pr, *pls))
+                {
+                  
+                  /* then replace */
+                  if (spl == *pls)
+                    replaceRule (pls, mtail, pr);
+                  else
+                    replaceRule (&spl, mtail, pr);
+                  
+                  /* if restart rule type then
+                     start at the top again */
+                  if (pr->restart)
+                    {
+                      restart = TRUE;
+                    }
+                }
+              
+              if (pr->vars)
+                {
+                  hTabDeleteAll (pr->vars);
+                  Safe_free (pr->vars);
+                  pr->vars = NULL;
+                }
+              
+              freeTrace (&_G.values);
+            }
+        }
+    } while (restart == TRUE);
 
   if (labelHash)
     {
       hTabDeleteAll (labelHash);
+      freeTrace (&_G.labels);
     }
   labelHash = NULL;
-
-top:
-  /* for all rules */
-  for (pr = rootRules; pr; pr = pr->next)
-    {
-
-      for (spl = *pls; spl; spl = spl->next)
-       {
-         /* if inline assembler then no peep hole */
-         if (spl->isInline)
-           continue;
-
-         mtail = NULL;
-
-         /* if it matches */
-         if (matchRule (spl, &mtail, pr, *pls))
-           {
-
-             /* then replace */
-             if (spl == *pls)
-               replaceRule (pls, mtail, pr);
-             else
-               replaceRule (&spl, mtail, pr);
-
-             /* if restart rule type then
-                start at the top again */
-             if (pr->restart)
-               goto top;
-           }
-       }
-    }
 }
 
 
@@ -1014,12 +1309,11 @@ readFileIntoBuffer (char *fname)
          if (rs)
            {
              rs = Safe_realloc (rs, strlen (rs) + strlen (lb) + 1);
-             strcat (rs, lb);
+             strncatz (rs, lb,  strlen (rs) + strlen (lb) + 1);
            }
          else
            {
-             rs = Safe_calloc (1, strlen (lb) + 1);
-             strcpy (rs, lb);
+             rs = Safe_strdup (lb);
            }
          nch = 0;
        }
@@ -1033,19 +1327,18 @@ readFileIntoBuffer (char *fname)
       if (rs)
        {
          rs = Safe_realloc (rs, strlen (rs) + strlen (lb) + 1);
-         strcat (rs, lb);
+         strncatz (rs, lb, strlen (rs) + strlen (lb) + 1);
        }
       else
        {
-         rs = Safe_calloc (1, strlen (lb) + 1);
-         strcpy (rs, lb);
+         rs = Safe_strdup (lb);
        }
     }
   return rs;
 }
 
 /*-----------------------------------------------------------------*/
-/* initPeepHole - initiaises the peep hole optimizer stuff         */
+/* initPeepHole - initialises the peep hole optimizer stuff        */
 /*-----------------------------------------------------------------*/
 void 
 initPeepHole ()
@@ -1061,4 +1354,15 @@ initPeepHole ()
       readRules (s = readFileIntoBuffer (options.peep_file));
       setToNull ((void **) &s);
     }
+
+
+#if !OPT_DISABLE_PIC
+  /* Convert the peep rules into pcode.
+     NOTE: this is only support in the PIC port (at the moment)
+  */
+  if (TARGET_IS_PIC) {
+    peepRules2pCode(rootRules);
+  }
+#endif
+
 }