* src/SDCCpeeph.c (callFuncByName): support combined peephole rule
authorepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 2 Dec 2004 08:24:51 +0000 (08:24 +0000)
committerepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 2 Dec 2004 08:24:51 +0000 (08:24 +0000)
  conditions,
  (setFromConditionArgs): friendly operand parser for peephole rules,
  (operandBaseName, operandsNotRelated): new peephole condition
  "operandsNotRelated" -- similar to "operandsNotSame", but takes
  architecture specific register naming into account, handles n-way
  comparisons, and supports quoted literals
* src/mcs51/peeph.def: restored rule 177.d with an extra condition

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

ChangeLog
src/SDCCpeeph.c
src/mcs51/peeph.def

index 720a7a7a53cb34aba983a3813915b23e34145198..3cf387a48f27320a2033233a56ad67496022aaee 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2004-12-02 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
+
+       * src/SDCCpeeph.c (callFuncByName): support combined peephole rule
+         conditions,
+         (setFromConditionArgs): friendly operand parser for peephole rules,
+         (operandBaseName, operandsNotRelated): new peephole condition
+         "operandsNotRelated" -- similar to "operandsNotSame", but takes
+         architecture specific register naming into account, handles n-way
+         comparisons, and supports quoted literals
+       * src/mcs51/peeph.def: restored rule 177.d with an extra condition
+
 2004-12-02 Frieder Ferlemann <Frieder.Ferlemann AT web.de>
 
        * src/mcs51/peeph.def: fixed bug #1076940
index c5534bc2ed69466b94901c1971551695d90bb7bd..2311c2c3b68ce85b931568c200af30356ea216ce 100644 (file)
@@ -51,7 +51,7 @@ 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, \
-       lineNode *head, const char *cmdLine)
+       lineNode *head, char *cmdLine)
 
 #if !OPT_DISABLE_PIC
 void peepRules2pCode(peepRule *);
@@ -757,6 +757,128 @@ error:
            " malformed: %s\n", cmdLine);
   return FALSE;
 }
+
+
+/*------------------------------------------------------------------*/
+/* setFromConditionArgs - parse a peephole condition's arguments    */
+/* to produce a set of strings, one per argument. Variables %x will */
+/* be replaced with their values. String literals (in single or     */
+/* double quotes) are accepted an return in unquoted form.          */
+/*------------------------------------------------------------------*/
+static set *
+setFromConditionArgs (char *cmdLine, hTab * vars)
+{
+  int varNumber;
+  char *var;
+  char *digitend;
+  set *operands = NULL;
+
+  if (!cmdLine)
+    return NULL;
+  
+  while (*cmdLine && isspace(*cmdLine))
+    cmdLine++;
+
+  while (*cmdLine)
+    {
+      if (*cmdLine == '%')
+        {
+          cmdLine++;
+          if (!isdigit(*cmdLine))
+            goto error;
+          varNumber = strtol(cmdLine, &digitend, 10);
+          cmdLine = digitend;
+
+          var = hTabItemWithKey (vars, varNumber);
+
+          if (var)
+            {
+              addSetHead (&operands, var);
+            }
+          else
+            goto error;
+        }
+      else if (*cmdLine == '"' || *cmdLine == '\'' )
+        {
+          char quote = *cmdLine;
+          
+          var = ++cmdLine;
+          while (*cmdLine && *cmdLine != quote)
+            cmdLine++;
+          if (*cmdLine == quote)
+            *cmdLine++ = '\0';
+          else
+            goto error;
+          addSetHead (&operands, var);
+        }
+      else
+        goto error;
+        
+      while (*cmdLine && isspace(*cmdLine))
+        cmdLine++;
+    }
+
+  return operands;
+
+error:
+  deleteSet (&operands);
+  return NULL;
+}
+
+static const char *
+operandBaseName (const char *op)
+{
+  if (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_DS400)
+    {
+      if (!strcmp (op, "acc") || !strncmp (op, "acc.", 4))
+        return "a";
+      if (!strncmp (op, "ar", 2) && isdigit(*(op+2)) && !*(op+3))
+        return op+1;
+    }
+
+  return op;
+}
+
+
+/*-------------------------------------------------------------------*/
+/* operandsNotRelated - returns true of the condition's operands are */
+/* not related (taking into account register name aliases). N-way    */
+/* comparison performed between all operands.                        */
+/*-------------------------------------------------------------------*/
+FBYNAME (operandsNotRelated)
+{
+  set *operands;
+  const char *op1, *op2;
+  
+  operands = setFromConditionArgs (cmdLine, vars);
+
+  if (!operands)
+    {
+      fprintf (stderr,
+               "*** internal error: operandsUnrelated peephole restriction"
+               " malformed: %s\n", cmdLine);
+      return FALSE;
+    }  
+
+  while ((op1 = setFirstItem (operands)))
+    {
+      deleteSetItem (&operands, (void*)op1);
+      op1 = operandBaseName (op1);
+            
+      for (op2 = setFirstItem (operands); op2; op2 = setNextItem (operands))
+        {
+          op2 = operandBaseName (op2);
+          if (strcmp (op1, op2) == 0)
+            {
+              deleteSet (&operands);
+              return FALSE;
+            }
+        }
+    }
+
+  deleteSet (&operands);
+  return TRUE;
+}
     
 
 /*-----------------------------------------------------------------*/
@@ -772,7 +894,7 @@ callFuncByName (char *fname,
   struct ftab
   {
     char *fname;
-    int (*func) (hTab *, lineNode *, lineNode *, lineNode *, const char *);
+    int (*func) (hTab *, lineNode *, lineNode *, lineNode *, char *);
   }
   ftab[] =
   {
@@ -838,40 +960,90 @@ callFuncByName (char *fname,
     },
     {
       "notVolatile", notVolatile
+    },
+    {
+      "operandsNotRelated", operandsNotRelated
     }
   };
   int  i;
-  char  *cmdCopy, *funcName, *funcArgs;
-  int  rc = -1;
+  char  *cmdCopy, *funcName, *funcArgs, *cmdTerm;
+  char  c;
+  int  rc;
     
   /* Isolate the function name part (we are passed the full condition 
    * string including arguments) 
    */
-  cmdCopy = Safe_strdup(fname);
-  funcName = strtok(cmdCopy, " \t");
-  funcArgs = strtok(NULL, "");
-
-    for (i = 0; i < ((sizeof (ftab)) / (sizeof (struct ftab))); i++)
+  cmdTerm = cmdCopy = Safe_strdup(fname);
+  
+  do
     {
-       if (strcmp (ftab[i].fname, funcName) == 0)
-       {
-           rc = (*ftab[i].func) (vars, currPl, endPl, head,
-                                 funcArgs);
-       }
-    }
+      funcArgs = funcName = cmdTerm;
+      while ((c = *funcArgs) && c != ' ' && c != '\t' && c != '(')
+        funcArgs++;
+      *funcArgs = '\0';  /* terminate the function name */
+      if (c)
+        funcArgs++;
+      
+      /* Find the start of the arguments */
+      if (c == ' ' || c == '\t')
+        while ((c = *funcArgs) && (c == ' ' || c == '\t'))
+          funcArgs++;
+      
+      /* If the arguments started with an opening parenthesis,  */
+      /* use the closing parenthesis for the end of the         */
+      /* arguments and look for the start of another condition  */
+      /* that can optionally follow. If there was no opening    */
+      /* parethesis, then everything that follows are arguments */
+      /* and there can be no additional conditions.             */
+      if (c == '(')
+        {
+          cmdTerm = funcArgs;
+          while ((c = *cmdTerm) && c != ')')
+            cmdTerm++;
+          *cmdTerm = '\0';  /* terminate the arguments */
+          if (c == ')')
+            {
+              cmdTerm++;
+              while ((c = *cmdTerm) && (c == ' ' || c == '\t' || c == ','))
+                cmdTerm++;
+              if (!*cmdTerm)
+                cmdTerm = NULL;
+            }
+          else
+            cmdTerm = NULL; /* closing parenthesis missing */
+        }
+      else
+        cmdTerm = NULL;
+
+      if (!*funcArgs)
+        funcArgs = NULL;
+        
+      rc = -1;
+      for (i = 0; i < ((sizeof (ftab)) / (sizeof (struct ftab))); i++)
+        {
+         if (strcmp (ftab[i].fname, funcName) == 0)
+           {
+             rc = (*ftab[i].func) (vars, currPl, endPl, head,
+                                   funcArgs);
+              break;
+           }
+        }
     
-    if (rc == -1)
-    {
-       fprintf (stderr, 
-                "could not find named function \"%s\" in "
-                "peephole function table\n",
-                funcName);
-        // If the function couldn't be found, let's assume it's
-       // a bad rule and refuse it.
-       rc = FALSE;
+      if (rc == -1)
+        {
+         fprintf (stderr, 
+                  "could not find named function \"%s\" in "
+                  "peephole function table\n",
+                  funcName);
+          // If the function couldn't be found, let's assume it's
+         // a bad rule and refuse it.
+         rc = FALSE;
+          break;
+        }
     }
-
-    Safe_free(cmdCopy);
+  while (rc && cmdTerm);
+  
+  Safe_free(cmdCopy);
     
   return rc;
 }
index eae66f0a00f35203722891c1229e3a2e890d9dfc..3af2821a7e6194da7f1cdedbc29654d43ce2219b 100644 (file)
@@ -1082,20 +1082,15 @@ replace {
 
 // applies to f.e. bug-408972.c
 // not before peephole 177.c
-// Bug #1076940, this rule erroneously applies to:
-//     mov     a,r2
-//     mov     acc.0,c
-//     mov     r2,a
-//
-//replace restart {
-//     mov     %1,%2
-//     mov     %3,%4
-//     mov     %2,%1
-//} by {
-//     ;       Peephole 177.d  removed redundant move
-//     mov     %1,%2
-//     mov     %3,%4
-//} if notVolatile %1 %2
+replace restart {
+       mov     %1,%2
+       mov     %3,%4
+       mov     %2,%1
+} by {
+       ;       Peephole 177.d  removed redundant move
+       mov     %1,%2
+       mov     %3,%4
+} if notVolatile(%1 %2),operandsNotRelated(%1 %3)
 
 // applies to f.e. bug-607243.c
 // also check notVolatile %3, as it will return FALSE if it's @r%1