* src/ds390/main.c (_ds390_genInitStartup): added
authorMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 5 Oct 2008 20:35:35 +0000 (20:35 +0000)
committerMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 5 Oct 2008 20:35:35 +0000 (20:35 +0000)
* src/SDCCpeeph.c (getPatternVar): new, added,
  (labelInRange): fixed bug 2115959
* src/mcs51/peeph.def (rules 193.x to 198.x): check for labelInRange
* src/SDCCicode.h: added newiTempOperand
* src/SDCCcse.c (algebraicOpts): fixed bug for x*-1,
  added optimizations for 0/x and x/-1, see also patch 2142900
* support/regression/tests/onebyte.c (testMul): added test cases

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

ChangeLog
src/SDCCcse.c
src/SDCCicode.h
src/SDCCpeeph.c
src/ds390/main.c
src/mcs51/peeph.def
support/regression/tests/onebyte.c

index f30c728cce97cc530c478ac214e3e90299af28e4..7e0b8201f0b5974ae57b57d999e97998e446e55d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2008-10-05 Maarten Brock <sourceforge.brock AT dse.nl>
+
+       * src/ds390/main.c (_ds390_genInitStartup): added
+       * src/SDCCpeeph.c (getPatternVar): new, added,
+         (labelInRange): fixed bug 2115959
+       * src/mcs51/peeph.def (rules 193.x to 198.x): check for labelInRange
+       * src/SDCCicode.h: added newiTempOperand
+       * src/SDCCcse.c (algebraicOpts): fixed bug for x*-1,
+         added optimizations for 0/x and x/-1, see also patch 2142900
+       * support/regression/tests/onebyte.c (testMul): added test cases
+
 2008-09-20 Borut Razem <borut.razem AT siol.net>
 
        * src/pic16/glue.c:
index dc92aceda7b7c5577d1bbd55b42620927cb42b5a..1b43a42850a335c01fc35c78d708e5cddef2da30 100644 (file)
@@ -1038,6 +1038,25 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
             }
           if (rightValue == -1.0)
             {
+              /* '*' can have two unsigned chars as operands */
+              /* and an unsigned int as result.              */
+              if (IS_INTEGRAL (operandType (IC_LEFT (ic))))
+                {
+                  if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) &&
+                      (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic)))))
+                    {
+                      operand * op;
+                      iCode * newic;
+                      /* Widen to int. */
+                      op = operandFromOperand (IC_RESULT (ic));
+                      op->type = TYPE;
+                      setOperandType (op, INTTYPE);
+                      newic = newiCode (CAST, op, IC_LEFT (ic));
+                      IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE);
+                      addiCodeToeBBlock (ebp, newic, ic);
+                      IC_LEFT (ic) = IC_RESULT (newic);
+                    }
+                }
               /* convert x * -1 to -x */
               ic->op = UNARYMINUS;
               IC_RIGHT (ic) = NULL;
@@ -1054,20 +1073,59 @@ algebraicOpts (iCode * ic, eBBlock * ebp)
           IC_LEFT (ic) = NULL;
           IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
           IC_RESULT (ic)->isaddr = 0;
-          break;
+          return;
         }
-      /* if this is a division then check if right */
-      /* is one then change it to an assignment    */
-      if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
-          operandLitValue (IC_RIGHT (ic)) == 1.0)
+      /* if this is a division then check if left is zero */
+      /* and right is not then change it to an assignment */
+      if (IS_OP_LITERAL (IC_LEFT (ic)) && IS_OP_LITERAL (IC_RIGHT (ic)) &&
+          (operandLitValue (IC_LEFT (ic)) == 0.0) && (operandLitValue (IC_RIGHT (ic)) != 0.0))
         {
-
           ic->op = '=';
           IC_RIGHT (ic) = IC_LEFT (ic);
           IC_LEFT (ic) = NULL;
           SET_RESULT_RIGHT (ic);
           return;
         }
+      /* if this is a division then check if right */
+      /* is one then change it to an assignment    */
+      if (IS_OP_LITERAL (IC_RIGHT (ic)))
+        {
+          double rightValue = operandLitValue (IC_RIGHT (ic));
+          if (rightValue == 1.0)
+            {
+              ic->op = '=';
+              IC_RIGHT (ic) = IC_LEFT (ic);
+              IC_LEFT (ic) = NULL;
+              SET_RESULT_RIGHT (ic);
+              return;
+            }
+          if (rightValue == -1.0)
+            {
+              /* '/' can have two unsigned chars as operands */
+              /* and an unsigned int as result.              */
+              if (IS_INTEGRAL (operandType (IC_LEFT (ic))))
+                {
+                  if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) &&
+                      (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic)))))
+                    {
+                      operand * op;
+                      iCode * newic;
+                      /* Widen to int. */
+                      op = operandFromOperand (IC_RESULT (ic));
+                      op->type = TYPE;
+                      setOperandType (op, INTTYPE);
+                      newic = newiCode (CAST, op, IC_LEFT (ic));
+                      IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE);
+                      addiCodeToeBBlock (ebp, newic, ic);
+                      IC_LEFT (ic) = IC_RESULT (newic);
+                    }
+                }
+              /* convert x / -1 to -x */
+              ic->op = UNARYMINUS;
+              IC_RIGHT (ic) = NULL;
+              return;
+            }
+        }
       break;
       /* if both are the same for an comparison operators */
     case EQ_OP:
@@ -2187,7 +2245,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
          mine and type is a pointer then delete
          pointerGets to take care of aliasing */
       if (ASSIGNMENT (ic) &&
-                  IS_SYMOP (IC_RESULT (ic)) &&
+          IS_SYMOP (IC_RESULT (ic)) &&
           OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) &&
           IS_PTR (operandType (IC_RESULT (ic))))
         {
index 48ef88fea71c8ce411b785fa1963a287f8840523..d2c69a1f10ef2537ff3b1138dfeb8f7918bffa02 100644 (file)
@@ -339,6 +339,7 @@ bool isOperandInDirSpace (operand *);
 bool isOperandInCodeSpace (operand *);
 operand *opFromOpWithDU (operand *, bitVect *, bitVect *);
 iCode *copyiCode (iCode *);
+operand *newiTempOperand (sym_link *, char);
 operand *newiTempFromOp (operand *);
 iCode *getBuiltinParms (iCode *,int *, operand **);
 int isiCodeInFunctionCall (iCode *);
index e413d49930edb78bdfff6292ef757c5aa3eae650..5a7447fff503ce66a2099c3a4ccd4d7da8c5a905 100644 (file)
@@ -60,6 +60,37 @@ void peepRules2pCode(peepRule *);
 void pic16_peepRules2pCode(peepRule *);
 #endif
 
+/*-----------------------------------------------------------------*/
+/* getPatternVar - finds a pattern variable                        */
+/*-----------------------------------------------------------------*/
+
+static char*
+getPatternVar (hTab *vars, char **cmdLine)
+{
+  int varNumber;
+  char *digitend;
+
+  if (!cmdLine || !*cmdLine || !**cmdLine)
+    return NULL; /* no parameters given */
+
+  while (**cmdLine && ISCHARSPACE(**cmdLine))
+    (*cmdLine)++; /* skip whitespace */
+
+  if (**cmdLine != '%')
+    goto error;
+  (*cmdLine)++;
+  if (!ISCHARDIGIT (**cmdLine))
+    goto error;
+  varNumber = strtol (*cmdLine, &digitend, 10);
+  *cmdLine = digitend;
+  return hTabItemWithKey (vars, varNumber);
+
+error:
+  fprintf (stderr,
+           "*** internal error: peephole restriction malformed: %s\n", *cmdLine);
+  return NULL;
+}
+
 /*-----------------------------------------------------------------*/
 /* pcDistance - finds a label backward or forward                  */
 /*-----------------------------------------------------------------*/
@@ -135,40 +166,52 @@ FBYNAME (useAcallAjmp)
 }
 
 /*-----------------------------------------------------------------*/
-/* labelInRange - will check to see if label %5 is within range    */
+/* labelInRange - will check to see if label is within range       */
 /*-----------------------------------------------------------------*/
 FBYNAME (labelInRange)
 {
-  /* assumes that %5 pattern variable has the label name */
-  char *lbl = hTabItemWithKey (vars, 5);
   int dist = 0;
+  char *lbl = getPatternVar (vars, &cmdLine);
 
   if (!lbl)
-    return FALSE;
+    {
+      /* If no parameters given, assume that %5 pattern variable
+         has the label name for backward compatibility */
+      lbl = hTabItemWithKey (vars, 5);
+    }
 
-  /* Don't optimize jumps in a jump table; a more generic test */
-  if (currPl->ic && currPl->ic->op == JUMPTABLE)
+  if (!lbl)
     return FALSE;
 
-  /* 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") &&
-      strstr (currPl->prev->prev->line, "ljmp"))
-    return FALSE;
+  do
+    {
+      /* Don't optimize jumps in a jump table; a more generic test */
+      if (currPl->ic && currPl->ic->op == JUMPTABLE)
+        return FALSE;
 
-  /* calculate the label distance : the jump for reladdr can be
-     +/- 127 bytes, here I am assuming that an average 8051
-     instruction is 2 bytes long, so if the label is more than
-     63 intructions away, the label is considered out of range
-     for a relative jump. we could get more precise this will
-     suffice for now since it catches > 90% cases */
-  dist = (pcDistance (currPl, lbl, TRUE) +
-          pcDistance (currPl, lbl, FALSE));
-
-/*    changed to 127, now that pcDistance return actual number of bytes */
-  if (!dist || dist > 127)
-    return FALSE;
+      /* 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") &&
+          strstr (currPl->prev->prev->line, "ljmp"))
+        return FALSE;
+
+      /* calculate the label distance : the jump for reladdr can be
+         +/- 127 bytes, here I am assuming that an average 8051
+         instruction is 2 bytes long, so if the label is more than
+         63 intructions away, the label is considered out of range
+         for a relative jump. we could get more precise this will
+         suffice for now since it catches > 90% cases */
+      dist = (pcDistance (currPl, lbl, TRUE) +
+              pcDistance (currPl, lbl, FALSE));
+
+      /* changed to 127, now that pcDistance return actual number of bytes */
+      if (!dist || dist > 127)
+        return FALSE;
+
+      lbl = getPatternVar (vars, &cmdLine);
+    }
+  while (lbl);
 
   return TRUE;
 }
@@ -1703,13 +1746,11 @@ bindVar (int key, char **s, hTab ** vtab)
 static bool
 matchLine (char *s, char *d, hTab ** vars)
 {
-
   if (!s || !(*s))
     return FALSE;
 
   while (*s && *d)
     {
-
       /* skip white space in both */
       while (ISCHARSPACE (*s))
         s++;
@@ -2423,7 +2464,7 @@ readFileIntoBuffer (char *fname)
         }
     }
 
-  /* if some charaters left over */
+  /* if some characters left over */
   if (nch)
     {
       lb[nch] = '\0';
index ba67a622c5e3ef569af41be58cb2e1f7ac2264f3..8b82663f35f62346fab4869f82932e867aa0d1b4 100644 (file)
@@ -310,6 +310,44 @@ _ds390_genIVT (struct dbuf_s * oBuf, symbol ** interrupts, int maxInterrupts)
   return TRUE;
 }
 
+static void
+_ds390_genInitStartup (FILE *of)
+{
+  fprintf (of, "__sdcc_gsinit_startup:\n");
+  /* if external stack is specified then the
+     higher order byte of the xdatalocation is
+     going into P2 and the lower order going into
+     spx */
+  if (options.useXstack)
+    {
+      fprintf (of, "\tmov\tP2,#0x%02x\n",
+               (((unsigned int) options.xdata_loc) >> 8) & 0xff);
+      fprintf (of, "\tmov\t_spx,#0x%02x\n",
+               (unsigned int) options.xdata_loc & 0xff);
+    }
+
+  // This should probably be a port option, but I'm being lazy.
+  // on the 400, the firmware boot loader gives us a valid stack
+  // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
+  if (!TARGET_IS_DS400)
+    {
+      /* initialise the stack pointer.  JCF: aslink takes care of the location */
+      fprintf (of, "\tmov\tsp,#__start__stack - 1\n");     /* MOF */
+    }
+
+  fprintf (of, "\tlcall\t__sdcc_external_startup\n");
+  fprintf (of, "\tmov\ta,dpl\n");
+  fprintf (of, "\tjz\t__sdcc_init_data\n");
+  fprintf (of, "\tljmp\t__sdcc_program_startup\n");
+  fprintf (of, "__sdcc_init_data:\n");
+
+  // if the port can copy the XINIT segment to XISEG
+  if (port->genXINIT)
+    {
+      port->genXINIT(of);
+    }
+}
+
 /* Generate code to copy XINIT to XISEG */
 static void _ds390_genXINIT (FILE * of) {
   fprintf (of, ";      _ds390_genXINIT() start\n");
@@ -952,7 +990,7 @@ PORT ds390_port =
   NULL,                         /* no genAssemblerEnd */
   _ds390_genIVT,
   _ds390_genXINIT,
-  NULL,                         /* genInitStartup */
+  _ds390_genInitStartup,
   _ds390_reset_regparm,
   _ds390_regparm,
   NULL,
@@ -1286,7 +1324,7 @@ PORT tininative_port =
   _tininative_genAssemblerEnd,
   _tininative_genIVT,
   NULL,
-  NULL,                         /* genInitStartup */
+  _ds390_genInitStartup,
   _ds390_reset_regparm,
   _ds390_regparm,
   NULL,
@@ -1539,7 +1577,7 @@ PORT ds400_port =
   NULL,                         /* no genAssemblerEnd */
   _ds400_genIVT,
   _ds390_genXINIT,
-  NULL,                         /* genInitStartup */
+  _ds390_genInitStartup,
   _ds390_reset_regparm,
   _ds390_regparm,
   NULL,
index 6f18fc5aad4631496a3d64ed7a16d7d1042b593b..d2206dcb7443a901cb8c639b4d4c51398aaa52e3 100644 (file)
@@ -1743,7 +1743,7 @@ replace {
        cjne    %13,%14,%8
        sjmp    %7
 %3:
-} if labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3)
+} if labelInRange(%8), labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3)
 
 replace {
        cjne    %1,%2,%3
@@ -1767,7 +1767,7 @@ replace {
        cjne    %13,%14,%8
        sjmp    %7
 %3:
-} if labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3)
+} if labelInRange(%8), labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3)
 
 replace {
        cjne    @%1,%2,%3
@@ -1791,7 +1791,7 @@ replace {
        cjne    @%1,%14,%8
        sjmp    %7
 %3:
-} if labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3)
+} if labelInRange(%8), labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3)
 
 replace {
        cjne    %1,%2,%3
@@ -1809,7 +1809,7 @@ replace {
        cjne    %13,%14,%8
        sjmp    %7
 %3:
-} if labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3)
+} if labelInRange(%8), labelRefCount(%3 4), labelRefCountChange(%3 -4), labelRefCountChange(%8 3)
 
 replace {
        jnz     %3
@@ -1829,7 +1829,7 @@ replace {
        cjne    %10,%11,%8
        sjmp    %7
 %3:
-} if labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2)
+} if labelInRange(%8), labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2)
 
 replace {
        cjne    %1,%2,%3
@@ -1849,7 +1849,7 @@ replace {
        cjne    %10,%11,%8
        sjmp    %7
 %3:
-} if labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2)
+} if labelInRange(%8), labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2)
 
 replace {
        cjne    @%1,%2,%3
@@ -1869,7 +1869,7 @@ replace {
        cjne    @%1,%11,%8
        sjmp    %7
 %3:
-} if labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2)
+} if labelInRange(%8), labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2)
 
 replace {
        cjne    %1,%2,%3
@@ -1885,7 +1885,7 @@ replace {
        cjne    %10,%11,%8
        sjmp    %7
 %3:
-} if labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2)
+} if labelInRange(%8), labelRefCount(%3 3), labelRefCountChange(%3 -3), labelRefCountChange(%8 2)
 
 replace {
        jnz     %3
@@ -1901,7 +1901,7 @@ replace {
        cjne    %5,%6,%8
        sjmp    %7
 %3:
-} if labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1)
+} if labelInRange(%8), labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1)
 
 replace {
        cjne    %1,%2,%3
@@ -1917,7 +1917,7 @@ replace {
        cjne    %5,%6,%8
        sjmp    %7
 %3:
-} if labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1)
+} if labelInRange(%8), labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1)
 
 replace {
        cjne     @%1,%2,%3
@@ -1933,7 +1933,7 @@ replace {
        cjne    @%1,%6,%8
        sjmp    %7
 %3:
-} if labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1)
+} if labelInRange(%8), labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1)
 
 replace {
        cjne    %1,%2,%3
@@ -1947,7 +1947,7 @@ replace {
        cjne    %5,%6,%8
        sjmp    %7
 %3:
-} if labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1)
+} if labelInRange(%8), labelRefCount(%3 2), labelRefCountChange(%3 -2), labelRefCountChange(%8 1)
 
 replace {
        cjne    %1,%2,%3
@@ -1959,7 +1959,7 @@ replace {
        cjne    %1,%2,%5
        sjmp    %4
 %3:
-} if labelRefCount(%3 1), labelRefCountChange(%3 -1)
+} if labelInRange(%5), labelRefCount(%3 1), labelRefCountChange(%3 -1)
 
 replace {
        sjmp    %1
index ea5d8147ca8ad8ad5b948305cf68789ba821834b..d44e1b01e267a8756ef517040e744b80a7634383 100644 (file)
@@ -33,6 +33,9 @@ testMul (void)
   ucL = 128;  cR =   1; ur8 = ucL * cR;  ur8b  = cR * ucL; ASSERT (ur8 ==  128); ASSERT (ur8b  ==  128);
   ucL = 128; ucR =   5; r16 = ucL * ucR; r16b = ucR * ucL; ASSERT (r16 ==  640); ASSERT (r16b ==  640);
   ucL = 128; ucR =   1; ur8 = ucL * ucR; ur8b = ucR * ucL; ASSERT (ur8 ==  128); ASSERT (ur8b ==  128);
+
+  ucL =  254;  cR = -1; r16 = ucL *  cR; ASSERT (r16 == -254);
+   cL = -128;  cR = -1; r16 =  cL *  cR; ASSERT (r16 ==  128);
 }
 
 void