* support/regression/tests/fetchoverlap.c: Added new test case.
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 9 Sep 2001 01:47:13 +0000 (01:47 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 9 Sep 2001 01:47:13 +0000 (01:47 +0000)
* support/regression/tests/bp.c: Added new test case.

* support/regression/tests/bug-448984.c: Added new test case.

* support/regression/tests/pow2shifts.c: Added new test case.

* src/z80/gen.c: Turned off the noise it normally generates for the release.
(genlshTwo): Fixed right shift for count > 8.

* src/z80/ralloc.c: Disabled most of the ACC packing rules as they weren't getting hit and weren't at all safe.

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

ChangeLog
src/z80/gen.c
src/z80/ralloc.c
support/regression/tests/bp.c [new file with mode: 0644]
support/regression/tests/bug-448984.c [new file with mode: 0644]
support/regression/tests/fetchoverlap.c [new file with mode: 0644]
support/regression/tests/pow2shifts.c [new file with mode: 0644]
support/tests/dhrystone/Makefile

index cc43b873a255fa2d5e982405d9c99da4cd161d88..12b0ac993bc6cd2b895365f5e09dfa4668f69c5d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2001-09-08  Michael Hope  <michaelh@juju.net.nz>
+
+       * support/regression/tests/fetchoverlap.c: Added new test case.
+
+       * support/regression/tests/bp.c: Added new test case.
+
+       * support/regression/tests/bug-448984.c: Added new test case.
+
+       * support/regression/tests/pow2shifts.c: Added new test case.
+
+       * src/z80/gen.c: Turned off the noise it normally generates for the release.
+       (genlshTwo): Fixed right shift for count > 8.
+
+       * src/z80/ralloc.c: Disabled most of the ACC packing rules as they weren't getting hit and weren't at all safe.
+
 2001-09-08    <johan@FRIJA>
 
        * src/SDCCicode.c (geniCodeCall): a CPOINTER can be used as a function
index d348eb555a2d92fceae56fb43d2e69c11bf1b79e..e0a478f9c81cba11116982faa64e0f8974965587 100644 (file)
@@ -96,7 +96,7 @@
 #include "SDCCglue.h"
 #include "newalloc.h"
 
-/* this is the down and dirty file with all kinds of kludgy & hacky
+/* This is the down and dirty file with all kinds of kludgy & hacky
    stuff. This is what it is all about CODE GENERATION for a specific MCU.
    Some of the routines may be reusable, will have to see */
 
    PENDING: What if the parameter is a long?
    Everything is caller saves. i.e. the caller must save any registers
    that it wants to preserve over the call.
-   The return value is returned in DEHL.  DE is normally used as a
+   GB: The return value is returned in DEHL.  DE is normally used as a
    working register pair.  Caller saves allows it to be used for a
    return value.
    va args functions do not use register parameters.  All arguments
    area.  ix-0 is the top most local variable.
 */
 
-enum {
-  DISABLE_DEBUG = 0
+enum 
+{
+  /* Set to enable debugging trace statements in the output assembly code. */
+  DISABLE_DEBUG = 1
 };
 
 static char *_z80_return[] =
@@ -133,6 +135,8 @@ static char **_fTmp;
 
 extern FILE *codeOutFile;
 
+/** Enum covering all the possible register pairs.
+ */
 typedef enum
   {
     PAIR_INVALID,
@@ -175,8 +179,13 @@ enum
     MSB32
   };
 
+/** Code generator persistent data.
+ */
 static struct 
 {
+  /** Used to optimised setting up of a pair by remebering what it
+      contains and adjusting instead of reloading where possible.
+  */
   struct 
   {
     AOP_TYPE last_type;
@@ -236,23 +245,6 @@ _getTempPairName(void)
   return _pairs[_getTempPairId()].name;
 }
 
-#if 0
-static const char *
-_getTempPairPart(int idx)
-{
-  wassertl (idx == LSB || idx == MSB16, "Invalid pair offset");
-  
-  if (idx == LSB)
-    {
-      return _pairs[_getTempPairId()].l;
-    }
-  else
-    {
-      return _pairs[_getTempPairId()].h;
-    }
-}
-#endif
-
 static void
 _tidyUp (char *buf)
 {
@@ -1475,8 +1467,7 @@ aopPut (asmop * aop, const char *s, int offset)
        break;
       if (offset > 0)
        {
-
-         emitDebug ("; Error aopPut AOP_ACC");
+          wassertl (0, "Tried to access past the end of A");
        }
       else
        {
@@ -1542,7 +1533,7 @@ static void
 movLeft2Result (operand * left, int offl,
                operand * result, int offr, int sign)
 {
-    const char *l;
+  const char *l;
   if (!sameRegs (AOP (left), AOP (result)) || (offl != offr))
     {
       l = aopGet (AOP (left), offl, FALSE);
@@ -1553,7 +1544,11 @@ movLeft2Result (operand * left, int offl,
        }
       else
        {
-         wassert (0);
+          if (getDataSize (left) == offl + 1)
+            {
+              emit2 ("ld a,%s", l);
+              aopPut (AOP (result), "a", offr);
+            }
        }
     }
 }
@@ -1587,7 +1582,6 @@ outBitCLong (operand * result, bool swap_sense)
   /* if the result is bit */
   if (AOP_TYPE (result) == AOP_CRY)
     {
-      emitDebug ("; Note: outBitC form 1");
       aopPut (AOP (result), "blah", 0);
     }
   else
@@ -1841,10 +1835,6 @@ assignResultValue (operand * oper)
   wassert (size <= 4);
   topInA = requiresHL (AOP (oper));
 
-#if 0
-  if (!IS_GB)
-    wassert (size <= 2);
-#endif
   if (IS_GB && size == 4 && requiresHL (AOP (oper)))
     {
       /* We do it the hard way here. */
@@ -1894,19 +1884,7 @@ _saveRegsForCall(iCode *ic, int sendSetSize)
     bool bcInRet = FALSE, deInRet = FALSE;
     bitVect *rInUse;
 
-#if 1
     rInUse = bitVectCplAnd (bitVectCopy (ic->rMask), ic->rUsed);
-#else
-    if (IC_RESULT(ic))
-      {
-        rInUse = bitVectCplAnd (bitVectCopy (ic->rMask), z80_rUmaskForOp (IC_RESULT(ic)));
-      }
-    else 
-      {
-        /* Has no result, so in use is all of in use */
-        rInUse = ic->rMask;
-      }
-#endif
 
     deInUse = bitVectBitValue (rInUse, D_IDX) || bitVectBitValue(rInUse, E_IDX);
     bcInUse = bitVectBitValue (rInUse, B_IDX) || bitVectBitValue(rInUse, C_IDX);
@@ -2223,7 +2201,6 @@ emitCall (iCode * ic, bool ispcall)
 
       if (isLitWord (AOP (IC_LEFT (ic))))
        {
-         emitDebug ("; Special case where the pCall is to a constant");
          emit2 ("call %s", aopGetLitWordLong (AOP (IC_LEFT (ic)), 0, FALSE));
        }
       else
@@ -2425,14 +2402,6 @@ genFunction (iCode * ic)
   */
   _G.receiveOffset = 0;
 
-#if 0
-  /* PENDING: hack */
-  if (!IS_STATIC (sym->etype))
-    {
-      addSetIfnotP (&publics, sym);
-    }
-#endif
-
   /* Record the last function name for debugging. */
   _G.lastFunctionName = sym->rname;
   
@@ -3354,49 +3323,6 @@ genCmp (operand * left, operand * right,
         }
       else
        {
-#if 0
-          // PENDING: Doesn't work around zero
-
-         /* Special cases:
-            On the GB:
-            If the left or the right is a lit:
-            Load -lit into HL, add to right via, check sense.
-          */
-         if (IS_GB && size == 2 && (AOP_TYPE (right) == AOP_LIT || AOP_TYPE (left) == AOP_LIT))
-           {
-             PAIR_ID id = PAIR_DE;
-             asmop *lit = AOP (right);
-             asmop *op = AOP (left);
-             swap_sense = TRUE;
-
-             if (AOP_TYPE (left) == AOP_LIT)
-               {
-                 swap_sense = FALSE;
-                 lit = AOP (left);
-                 op = AOP (right);
-               }
-             if (sign)
-               {
-                 emit2 ("ld e,%s", aopGet (op, 0, 0));
-                 emit2 ("ld a,%s", aopGet (op, 1, 0));
-                 emit2 ("xor a,!immedbyte", 0x80);
-                 emit2 ("ld d,a");
-               }
-             else
-               {
-                 id = getPairId (op);
-                 if (id == PAIR_INVALID)
-                   {
-                     fetchPair (PAIR_DE, op);
-                     id = PAIR_DE;
-                   }
-               }
-             spillPair (PAIR_HL);
-             emit2 ("ld hl,%s", fetchLitSpecial (lit, TRUE, sign));
-             emit2 ("add hl,%s", _getPairIdName (id));
-             goto release;
-           }
-#endif
          if (AOP_TYPE (right) == AOP_LIT)
            {
              lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
@@ -3910,15 +3836,6 @@ genAnd (iCode * ic, iCode * ifx)
   aopOp ((right = IC_RIGHT (ic)), ic, FALSE, FALSE);
   aopOp ((result = IC_RESULT (ic)), ic, TRUE, FALSE);
 
-#ifdef DEBUG_TYPE
-  emitDebug ("; Type res[%d] = l[%d]&r[%d]",
-           AOP_TYPE (result),
-           AOP_TYPE (left), AOP_TYPE (right));
-  emitDebug ("; Size res[%d] = l[%d]&r[%d]",
-           AOP_SIZE (result),
-           AOP_SIZE (left), AOP_SIZE (right));
-#endif
-
   /* if left is a literal & right is not then exchange them */
   if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
       AOP_NEEDSACC (left))
@@ -4142,15 +4059,6 @@ genOr (iCode * ic, iCode * ifx)
   aopOp ((right = IC_RIGHT (ic)), ic, FALSE, FALSE);
   aopOp ((result = IC_RESULT (ic)), ic, TRUE, FALSE);
 
-#if 1
-  emitDebug ("; Type res[%d] = l[%d]&r[%d]",
-           AOP_TYPE (result),
-           AOP_TYPE (left), AOP_TYPE (right));
-  emitDebug ("; Size res[%d] = l[%d]&r[%d]",
-           AOP_SIZE (result),
-           AOP_SIZE (left), AOP_SIZE (right));
-#endif
-
   /* if left is a literal & right is not then exchange them */
   if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
       AOP_NEEDSACC (left))
@@ -4734,7 +4642,7 @@ genlshTwo (operand * result, operand * left, int shCount)
            {
              movLeft2Result (left, LSB, result, MSB16, 0);
              aopPut (AOP (result), "!zero", 0);
-             shiftL1Left2Result (left, MSB16, result, MSB16, shCount);
+             shiftL1Left2Result (left, LSB, result, MSB16, shCount);
            }
          else
            {
@@ -4789,11 +4697,6 @@ genLeftShiftLiteral (operand * left,
 
   size = getSize (operandType (result));
 
-#if VIEW_SIZE
-  emitDebug ("; shift left  result %d, left %d", size,
-           AOP_SIZE (left));
-#endif
-
   /* I suppose that the left size >= result size */
   if (shCount == 0)
     {
@@ -4865,7 +4768,7 @@ genLeftShift (iCode * ic)
 
   /* now move the left to the result if they are not the
      same */
-#if 1
+
   if (!sameRegs (AOP (left), AOP (result)))
     {
 
@@ -4878,17 +4781,6 @@ genLeftShift (iCode * ic)
          offset++;
        }
     }
-#else
-  size = AOP_SIZE (result);
-  offset = 0;
-  while (size--)
-    {
-      l = aopGet (AOP (left), offset, FALSE);
-      aopPut (AOP (result), l, offset);
-      offset++;
-    }
-#endif
-
 
   tlbl = newiTempLabel (NULL);
   size = AOP_SIZE (result);
@@ -4989,7 +4881,10 @@ shiftR1Left2Result (operand * left, int offl,
   _moveA (aopGet (AOP (left), offl, FALSE));
   if (sign)
     {
-      wassert (0);
+      while (shCount--)
+       {
+         emit2 ("%s a", sign ? "sra" : "srl");
+       }
     }
   else
     {
@@ -5047,9 +4942,6 @@ genRightShiftLiteral (operand * left,
 
   size = getSize (operandType (result));
 
-  emitDebug ("; shift right  result %d, left %d", size,
-           AOP_SIZE (left));
-
   /* I suppose that the left size >= result size */
   if (shCount == 0)
     {
@@ -5480,14 +5372,12 @@ genAssign (iCode * ic)
   result = IC_RESULT (ic);
   right = IC_RIGHT (ic);
 
-#if 1
   /* Dont bother assigning if they are the same */
   if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
     {
       emitDebug ("; (operands are equal %u)", operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)));
       return;
     }
-#endif
 
   aopOp (right, ic, FALSE, FALSE);
   aopOp (result, ic, TRUE, FALSE);
@@ -5682,16 +5572,7 @@ genCast (iCode * ic)
       goto release;
     }
 
-  /* PENDING: should be OK. */
-#if 0
-  /* if the result is of type pointer */
-  if (IS_PTR (ctype))
-    {
-      wassert (0);
-    }
-#endif
-
-  /* so we now know that the size of destination is greater
+  /* So we now know that the size of destination is greater
      than the size of the source */
   /* we move to result for the size of source */
   size = AOP_SIZE (right);
@@ -5718,7 +5599,6 @@ genCast (iCode * ic)
         const char *l = aopGet (AOP (right), AOP_SIZE (right) - 1,
                        FALSE);
       _moveA (l);
-      emitDebug ("; genCast: sign extend untested.");
       emit2 ("rla ");
       emit2 ("sbc a,a");
       while (size--)
@@ -6271,13 +6151,11 @@ genZ80Code (iCode * lic)
          break;
 
        case ARRAYINIT:
-           genArrayInit(ic);
-           break;
+          genArrayInit(ic);
+          break;
            
        default:
          ic = ic;
-         /*      piCode(ic,stdout); */
-
        }
     }
 
index 7027e57b046406482c7ad96c5045357c91f12929..d15e042c9b682f26dd810470daa05fc351f2e142 100644 (file)
 
 #include "z80.h"
 
+/* Flags to turn off optimisations.
+ */
 enum
   {
     DISABLE_PACK_ACC = 0,
     DISABLE_PACK_ASSIGN = 0,
     DISABLE_PACK_ONE_USE = 0,
     DISABLE_PACK_HL = 0,
-    LIMITED_PACK_ACC = 1,
   };
 
+/* Flags to turn on debugging code.
+ */
 enum
   {
     D_ALLOC = 0,
@@ -2046,16 +2049,10 @@ opPreservesA (iCode * ic, iCode * uic)
 {
   if (uic->op == IFX)
     {
+      /* If we've gotten this far then the thing to compare must be
+         small enough and must be in A.
+      */
       return TRUE;
-
-      if (getSize (operandType (IC_COND (uic))) == 1 &&
-          IS_OP_LITERAL (IC_COND (uic)))
-        {
-          return TRUE;
-        }
-
-      D (D_ACCUSE2, ("  + Dropping as operation is an IFX\n"));
-      return FALSE;
     }
 
   if (uic->op == JUMPTABLE)
@@ -2086,50 +2083,10 @@ opPreservesA (iCode * ic, iCode * uic)
       return FALSE;
     }
 
-  /*
-     Bad:
-     !IS_ARITHMETIC_OP(uic) (sub requires A)
-   */
-  if (
-       uic->op != '+' &&
-       !IS_BITWISE_OP (uic) &&
-       uic->op != '=' &&
-       uic->op != EQ_OP &&
-       !POINTER_GET (uic) &&
-  /*
-     uic->op != LEFT_OP &&
-     uic->op != RIGHT_OP && */
-       1
-    )
-    {
-      D (D_ACCUSE2, ("  + Dropping as 'its a bad op'\n"));
-      return FALSE;
-    }
-
-  /* PENDING */
-  if (!IC_LEFT (uic) || !IC_RESULT (ic))
-    {
-      D (D_ACCUSE2, ("  + Dropping for some reason #1\n"));
-      return FALSE;
-    }
-
-/** This is confusing :)  Guess for now */
-  if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
-      (IS_ITEMP (IC_RIGHT (uic)) ||
-       (IS_TRUE_SYMOP (IC_RIGHT (uic)))))
-    {
-      return TRUE;
-    }
-
-  if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
-      (IS_ITEMP (IC_LEFT (uic)) ||
-       (IS_TRUE_SYMOP (IC_LEFT (uic)))))
-    {
-      return TRUE;
-    }
-
-  D (D_ACCUSE2, ("  + Dropping as hit default case\n"));
 
+  /* Disabled all of the old rules as they weren't verified and have
+     caused at least one problem.
+   */
   return FALSE;
 }
 
@@ -2244,21 +2201,6 @@ packRegsForAccUse2 (iCode * ic)
       return;
     }
 
-  /* if shift operation make sure right side is not a literal.
-     MLH: depends.
-   */
-#if 0
-  if (ic->op == RIGHT_OP &&
-      (isOperandLiteral (IC_RIGHT (ic)) ||
-       getSize (operandType (IC_RESULT (ic))) > 1))
-    return;
-
-  if (ic->op == LEFT_OP &&
-      (isOperandLiteral (IC_RIGHT (ic)) ||
-       getSize (operandType (IC_RESULT (ic))) > 1))
-    return;
-#endif
-
   /* has only one definition */
   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
     {
diff --git a/support/regression/tests/bp.c b/support/regression/tests/bp.c
new file mode 100644 (file)
index 0000000..bd768a4
--- /dev/null
@@ -0,0 +1,43 @@
+/* Base pointer tests, specifically for the z80.
+ */
+#include <testfwk.h>
+#include <string.h>
+#include <stdio.h>
+
+int
+verifyBlock(char *p, char val, int len)
+{
+  while (len--) {
+    if (*p++ != val) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+char
+spoil(char a)
+{
+  return a;
+}
+
+void
+testBP(void)
+{
+  char above[400];
+  char f;
+  char below[200];
+
+  memset(above, 17, sizeof(above));
+  memset(below, 74, sizeof(below));
+
+  ASSERT(verifyBlock(above, 17, sizeof(above)));
+  ASSERT(verifyBlock(below, 74, sizeof(below)));
+
+  f = spoil(-5);
+  spoil(f);
+
+  ASSERT(verifyBlock(above, 17, sizeof(above)));
+  ASSERT(verifyBlock(below, 74, sizeof(below)));
+}
+
diff --git a/support/regression/tests/bug-448984.c b/support/regression/tests/bug-448984.c
new file mode 100644 (file)
index 0000000..5ec3604
--- /dev/null
@@ -0,0 +1,16 @@
+/* bug-448984.c
+ */
+#include <testfwk.h>
+
+void
+testRshRem(void)
+{
+  volatile int rem, quot;
+
+  quot = 4;
+  rem = 5000;
+
+  rem = rem - (quot*1024);
+
+  ASSERT(rem == 904);
+}
diff --git a/support/regression/tests/fetchoverlap.c b/support/regression/tests/fetchoverlap.c
new file mode 100644 (file)
index 0000000..5039b0a
--- /dev/null
@@ -0,0 +1,33 @@
+/* Test to reproduce a bug in the z80 compiler where A is used as the
+   left and right of an operand.
+*/
+#include <testfwk.h>
+#include <string.h>
+
+/* In the previous bug, both *p and val in the compare operation were
+   assigned into A due to *p being packed for ACC use into A.
+*/
+int
+verifyBlock(char *p, char val, int len)
+{
+  while (len--) {
+    if (*p++ != val) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+void
+testOverlap(void)
+{
+  char buf[20];
+  memset(buf, 12, sizeof(buf));
+
+  buf[12] = 13;
+  ASSERT(!verifyBlock(buf, 12, sizeof(buf)));
+
+  buf[12] = 12;
+  ASSERT(verifyBlock(buf, 12, sizeof(buf)));
+}
+
diff --git a/support/regression/tests/pow2shifts.c b/support/regression/tests/pow2shifts.c
new file mode 100644 (file)
index 0000000..a1884da
--- /dev/null
@@ -0,0 +1,22 @@
+/* Test power of 2 based shifts.
+   sign: signed, unsigned
+ */
+#include <testfwk.h>
+
+void
+testIntShift(void)
+{
+  volatile {sign} int left;
+
+  left = 4;
+  ASSERT(left * 1024 == 4096);
+  ASSERT(left * 2048 == 8192);
+  ASSERT(left * 256 == 1024);
+  ASSERT(left * 64 == 256);
+
+  left = 4096;
+  ASSERT(left / 1024 == 4);
+  ASSERT(left / 2048 == 2);
+  ASSERT(left / 256 == 16);
+  ASSERT(left / 4 == 1024);
+}
index 39fc0dfc98e5e5b6cfac70d610cf3216b4c77545..4361f5e2dc72408062bbca5a3d18b819b382673d 100644 (file)
@@ -1,7 +1,7 @@
 # Simple Makefile for dhrystone and sdcc
 TOPDIR = ../../..
 
-PROC = gbz80
+PROC = z80
 
 CC = $(TOPDIR)/bin/sdcc
 
@@ -27,4 +27,4 @@ native:
        gcc -g -O2 -DREG= -DNOSTRUCTASSIGN -DNOENUM -o dhry dhry.c
 
 clean:
-       rm -f *~ dhry *.o *.gb *.ihx *.rel
+       rm -f *~ dhry *.o *.gb *.ihx *.rel *.dump* *.lst *.sym *.map *.asm *.bin *.gb