* src/z80/ralloc.c (packRegsForHLUse3): Created and optimised.
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 19 Nov 2001 04:56:44 +0000 (04:56 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 19 Nov 2001 04:56:44 +0000 (04:56 +0000)
(packRegsForIYUse): Created and optimised.

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

13 files changed:
ChangeLog
doc/choices.txt
src/SDCCicode.c
src/SDCCicode.h
src/z80/gen.c
src/z80/peeph-z80.def
src/z80/ralloc.c
src/z80/ralloc.h
src/z80/z80.h
support/regression/failing/bug-435214.c [deleted file]
support/regression/tests/bug-435214.c [new file with mode: 0644]
support/regression/tests/driverstruct.c
support/regression/tests/logic.c

index 4624cb9faf6aa1319ae4e15fed1997f14ef89ad2..966497fd5a5622d6022899b683c12613b4e3d8c3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2001-11-18  Michael Hope  <michaelh@juju.net.nz>
+
+       * src/z80/ralloc.c (packRegsForHLUse3): Created and optimised.
+       (packRegsForIYUse): Created and optimised.
+
+2001-11-07  Michael Hope  <michaelh@juju.net.nz>
+
+       * support/regression/tests/float.c (testFloatAdd): Fixed up warning.
 2001-11-18  Bernhard Held  <bernhard@bernhardheld.de>
 
        * sdcc/support/regression/tests/bug-460010.c: fix seg violation on host
index 9fa79244d309fd21e6a9d491a227ded83bbf179e..fd6cbab859d01cca36a164247512711ee00c6bab 100644 (file)
@@ -105,5 +105,90 @@ Things get better when you access the same set over, as you get rid
 of the setup.  But they get worse when both ops are on the stack/in
 direct space.  Easiest this way for now.  iy may benifit...
 
-       
+cmpGt:
+       ld      l,#0x80         ; 7
+       ld      a,-1(ix)        ; 19
+       xor     a,#0x80         ; 7
+       ld      h,a             ; 4
+       ld      a,#0x02         ; 7
+       sub     a,-2(ix)        ; 19
+       ld      a,l             ; 4
+       sbc     a,h             ; 4 = 71
+
+vs
+        ld      hl,0x8002      ; 10
+        ld      a,-2(ix)       ; 19
+        xor     0x80           ; 7
+        ld      d,a            ; 4
+        ld      e,-1(ix)       ; 19
+        sbc     hl,de          ; 15 = 74
+
+Why is there the whole xor thing going on?
+
+cmpGt using sub:
+        left    right   l-r    c       expect
+        0       0       0       0       false
+        -1      0       -1     0       false
+        1       0       1       0       true
+        0       -1      1       1       true
+        0       1       -1      1       false
+
+With top most bits xored
+        80h     80h     0       0      false
+        7fh     80h     FFh     1       false
+        81h     80h     01h     0       true
+        80h     7fh     01h     0       true
+        80h     81h     FFh     1       false
+
+r-l instead - ah.
+        80h     80h     0       0      false
+        7fh     80h     01h     0       false
+        81h     80h     FFh     1       true
+        80h     7fh     FFh     1       true
+        80h     81h     01h     0       false
+
+How about using the sign bit and no XOR on r-l?
+        0       0        0              false
+        FFh     0       01h            false
+        01h     0        FFh            true
+        0       FFh      FFh            true
+        0       01h      01h            false  - works
+
+cmpEq:
+        ld      hl,#nn         ; 10
+       ld      c,(ix+-5)       ; 19
+       ld      b,(ix+-4)       ; 19
+       or      a               ; 4
+       sbc     hl,bc           ; 15
+       jp      nz,l19          ; 10 = 77
+
+       ld      a,-82(ix)       ; 19
+       cp      a,#0x01         ; 7
+       jp      nz,00129$       ; 10
+       ld      a,-81(ix)       ; 19
+       or      a,a             ; 7
+       jp      nz,00129$       ; 10 - 72
+
+Add:
+       ld      a,c             ; 4
+       add     a,#0x04         ; 7
+       ld      -4(ix),a        ; 19
+       ld      a,b             ; 4
+       adc     a,#0x00         ; 7
+       ld      -3(ix),a        ; 19 = 60
+vs
+        ld      hl,#4           ; 10
+        add     hl,bc           ; 11
+        ld      -4(ix),l        ; 19
+        ld      -3(ix),h        ; 19 = 59
+
+Same argument as above - not worth the extra cycle.
+
+Pending optimisations:
+        iTemp1 = @iTemp2
+        iTemp3 = iTemp1
+
+        iTemp4 = something in direct space
+        ...
+        push    iTemp4
+
index 59bcf886fc8610efcaf5f2ff3a8c2891dbc26187..460fc5d47d3cb28967308acb9d8a576c0b3a3fba 100644 (file)
@@ -858,6 +858,7 @@ isOperandLiteral (operand * op)
 
   return 0;
 }
+
 /*-----------------------------------------------------------------*/
 /* isOperandInFarSpace - will return true if operand is in farSpace */
 /*-----------------------------------------------------------------*/
@@ -886,6 +887,34 @@ isOperandInFarSpace (operand * op)
   return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
 }
 
+/*------------------------------------------------------------------*/
+/* isOperandInDirSpace - will return true if operand is in dirSpace */
+/*------------------------------------------------------------------*/
+bool 
+isOperandInDirSpace (operand * op)
+{
+  sym_link *etype;
+
+  if (!op)
+    return FALSE;
+
+  if (!IS_SYMOP (op))
+    return FALSE;
+
+  if (!IS_TRUE_SYMOP (op))
+    {
+      if (SPIL_LOC (op))
+       etype = SPIL_LOC (op)->etype;
+      else
+       return FALSE;
+    }
+  else
+    {
+      etype = getSpec (operandType (op));
+    }
+  return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
+}
+
 /*-----------------------------------------------------------------*/
 /* isOperandOnStack - will return true if operand is on stack      */
 /*-----------------------------------------------------------------*/
index bd467419e492003d2ff04724826f554e2ad7b856..9a44fbc6013ee67df71c40f64e35ff40b867beba 100644 (file)
@@ -310,6 +310,7 @@ int piCode (void *, FILE *);
 int printOperand (operand *, FILE *);
 void setOperandType (operand *, sym_link *);
 bool isOperandInFarSpace (operand *);
+bool isOperandInDirSpace (operand *);
 operand *opFromOpWithDU (operand *, bitVect *, bitVect *);
 iCode *copyiCode (iCode *);
 operand *newiTempFromOp (operand *);
index 7515252e6f0e69fc3dd40171ea5b5d8f0c72e499..5652ea6b69f50cf6b5ce6ac0b776e9e525a54ae5 100644 (file)
@@ -166,8 +166,8 @@ static struct
   {    "bc", "c", "b" },
   {    "de", "e", "d" },
   {    "hl", "l", "h" },
-  {    "iy", "iy.l?", "iy.h?" },
-  {    "ix", "ix.l?", "ix.h?" }
+  {    "iy", "iyl", "iyh" },
+  {    "ix", "ixl", "ixh" }
 };
 
 // PENDING
@@ -252,6 +252,23 @@ _getTempPairName(void)
   return _pairs[_getTempPairId()].name;
 }
 
+static PAIR_ID
+getFreePairId (iCode *ic)
+{
+  if (!(bitVectBitValue (ic->rMask, B_IDX) || bitVectBitValue(ic->rMask, C_IDX)))
+    {
+      return PAIR_BC;
+    }
+  else if (IS_Z80 && !(bitVectBitValue (ic->rMask, D_IDX) || bitVectBitValue(ic->rMask, E_IDX)))
+    {
+      return PAIR_DE;
+    }
+  else
+    {
+      return PAIR_INVALID;
+    }
+}         
+
 static void
 _tidyUp (char *buf)
 {
@@ -408,18 +425,14 @@ getPairName (asmop * aop)
     }
   else if (aop->type == AOP_STR || aop->type == AOP_HLREG)
     {
-      switch (*aop->aopu.aop_str[0])
-       {
-       case 'c':
-         return "bc";
-         break;
-       case 'e':
-         return "de";
-         break;
-       case 'l':
-         return "hl";
-         break;
-       }
+      int i;
+      for (i = 0; i < NUM_PAIRS; i++)
+        {
+          if (strcmp(aop->aopu.aop_str[0], _pairs[i].l) == 0)
+            {
+              return _pairs[i].name;
+            }
+        }
     }
   wassertl (0, "Tried to get the pair name of something that isn't a pair");
   return NULL;
@@ -445,21 +458,17 @@ getPairId (asmop * aop)
              return PAIR_HL;
            }
        }
-      if (aop->type == AOP_STR || aop->type == AOP_HLREG)
+      else if (aop->type == AOP_STR || aop->type == AOP_HLREG)
        {
-         if (!strcmp (aop->aopu.aop_str[0], "c") && !strcmp (aop->aopu.aop_str[1], "b"))
-           {
-             return PAIR_BC;
-           }
-         if (!strcmp (aop->aopu.aop_str[0], "e") && !strcmp (aop->aopu.aop_str[1], "d"))
-           {
-             return PAIR_DE;
-           }
-         if (!strcmp (aop->aopu.aop_str[0], "l") && !strcmp (aop->aopu.aop_str[1], "h"))
-           {
-             return PAIR_HL;
-           }
-       }
+          int i;
+          for (i = 0; i < NUM_PAIRS; i++)
+            {
+              if (!strcmp (aop->aopu.aop_str[0], _pairs[i].l) && !strcmp (aop->aopu.aop_str[1], _pairs[i].h))
+                {
+                  return i;
+                }
+            }
+        }
     }
   return PAIR_INVALID;
 }
@@ -830,6 +839,16 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a)
          return;
        }
 
+      if (sym->ruonly)
+       {
+         int i;
+         aop = op->aop = sym->aop = newAsmop (AOP_STR);
+         aop->size = getSize (sym->type);
+         for (i = 0; i < 4; i++)
+           aop->aopu.aop_str[i] = _fReturn[i];
+         return;
+       }
+
       if (sym->accuse)
        {
          if (sym->accuse == ACCUSE_A)
@@ -848,6 +867,14 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a)
               aop->aopu.aop_str[0] = _pairs[PAIR_HL].l;
               aop->aopu.aop_str[1] = _pairs[PAIR_HL].h;
            }
+          else if (sym->accuse == ACCUSE_IY)
+            {
+             aop = op->aop = sym->aop = newAsmop (AOP_HLREG);
+             aop->size = getSize (sym->type);
+              wassertl(aop->size <= 2, "Internal error: Caching in IY, but too big to fit in IY");
+              aop->aopu.aop_str[0] = _pairs[PAIR_IY].l;
+              aop->aopu.aop_str[1] = _pairs[PAIR_IY].h;
+            }
          else 
               {
                   wassertl (0, "Marked as being allocated into A or HL but is actually in neither");
@@ -855,16 +882,6 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a)
          return;
        }
 
-      if (sym->ruonly)
-       {
-         int i;
-         aop = op->aop = sym->aop = newAsmop (AOP_STR);
-         aop->size = getSize (sym->type);
-         for (i = 0; i < 4; i++)
-           aop->aopu.aop_str[i] = _fReturn[i];
-         return;
-       }
-
       /* else spill location  */
       sym->aop = op->aop = aop =
        aopForSym (ic, sym->usl.spillLoc, result, requires_a);
@@ -1123,9 +1140,14 @@ fetchPairLong (PAIR_ID pairId, asmop * aop, int offset)
     if (isLitWord (aop)) {
         fetchLitPair (pairId, aop, offset);
     }
-    else {
+    else 
+      {
+        if (getPairId (aop) == pairId)
+          {
+            /* Do nothing */
+          }
         /* we need to get it byte by byte */
-        if (pairId == PAIR_HL && IS_GB && requiresHL (aop)) {
+        else if (pairId == PAIR_HL && IS_GB && requiresHL (aop)) {
             aopGet (aop, offset, FALSE);
             switch (aop->size - offset) {
             case 1:
@@ -1155,6 +1177,24 @@ fetchPairLong (PAIR_ID pairId, asmop * aop, int offset)
                 emit2("ld %s,!zero", _pairs[pairId].h);
             }
         }
+        else if (pairId == PAIR_IY)
+          {
+            if (isPair (aop))
+              {
+                emit2 ("push %s", _pairs[getPairId(aop)].name);
+                emit2 ("pop iy");
+              }
+            else
+              {
+                _push (PAIR_HL);
+                /* Can't load into parts, so load into HL then exchange. */
+                emit2 ("ld %s,%s", _pairs[PAIR_HL].l, aopGet (aop, offset, FALSE));
+                emit2 ("ld %s,%s", _pairs[PAIR_HL].h, aopGet (aop, offset + 1, FALSE));
+                emit2 ("push hl");
+                emit2 ("pop iy");
+                _pop (PAIR_HL);
+              }
+          }
         else {
             emit2 ("ld %s,%s", _pairs[pairId].l, aopGet (aop, offset, FALSE));
             emit2 ("ld %s,%s", _pairs[pairId].h, aopGet (aop, offset + 1, FALSE));
@@ -1563,7 +1603,9 @@ aopPut (asmop * aop, const char *s, int offset)
              emit2 ("ld !*ixx,a", aop->aopu.aop_stk + offset);
            }
          else
-           emit2 ("ld !*ixx,%s", aop->aopu.aop_stk + offset, s);
+            {
+              emit2 ("ld !*ixx,%s", aop->aopu.aop_stk + offset, s);
+            }
        }
       break;
 
@@ -1719,6 +1761,20 @@ movLeft2ResultLong (operand * left, int offl,
           emit2 ("ld h,%s", aopGet (AOP (left), MSB16, FALSE));
           emit2 ("ld l,a");
         }
+      else if ( getPairId ( AOP (result)) == PAIR_IY)
+        {
+          PAIR_ID id = getPairId (AOP (left));
+          if (id != PAIR_INVALID) 
+            {
+              emit2("push %s", _pairs[id].name);
+              emit2("pop iy");
+            }
+          else
+            {
+              /* PENDING */
+              emitDebug("Error");
+            }
+        }
       else
         {
           movLeft2Result (left, offl, result, offr, sign);
@@ -2925,9 +2981,22 @@ genPlusIncr (iCode * ic)
        }
       if (isPair (AOP (IC_LEFT (ic))) && resultId == PAIR_HL && icount > 2)
        {
-         fetchPair (resultId, AOP (IC_RIGHT (ic)));
-         emit2 ("add hl,%s", getPairName (AOP (IC_LEFT (ic))));
-         return TRUE;
+          if (getPairId (AOP (IC_LEFT (ic))) == PAIR_HL)
+            {
+              PAIR_ID freep = getFreePairId (ic);
+              if (freep != PAIR_INVALID)
+                {
+                  fetchPair (freep, AOP (IC_RIGHT (ic)));
+                  emit2 ("add hl,%s", _pairs[freep].name);
+                  return TRUE;
+                }
+            }
+          else
+            {
+              fetchPair (resultId, AOP (IC_RIGHT (ic)));
+              emit2 ("add hl,%s", getPairName (AOP (IC_LEFT (ic))));
+              return TRUE;
+            }
        }
       if (icount > 5)
        return FALSE;
@@ -2945,6 +3014,13 @@ genPlusIncr (iCode * ic)
       return TRUE;
     }
 
+  if (IS_Z80 && isLitWord (AOP (IC_LEFT (ic))) && size == 2)
+    {
+      fetchLitPair (PAIR_HL, AOP (IC_LEFT (ic)), icount);
+      commitPair (AOP (IC_RESULT (ic)), PAIR_HL);
+      return TRUE;
+    }
+
   /* if the literal value of the right hand side
      is greater than 4 then it is not worth it */
   if (icount > 4)
@@ -3178,13 +3254,40 @@ genPlus (iCode * ic)
        }
     }
 
-  if (isPair (AOP (IC_RIGHT (ic))) && getPairId (AOP (IC_RESULT (ic))) == PAIR_HL)
+  if ((isPair (AOP (IC_RIGHT (ic))) || isPair (AOP (IC_LEFT (ic)))) && getPairId (AOP (IC_RESULT (ic))) == PAIR_HL)
     {
       /* Fetch into HL then do the add */
+      PAIR_ID left = getPairId (AOP (IC_LEFT (ic)));
+      PAIR_ID right = getPairId (AOP (IC_RIGHT (ic)));
+
       spillPair (PAIR_HL);
-      fetchPair (PAIR_HL, AOP (IC_LEFT (ic)));
-      emit2 ("add hl,%s", getPairName (AOP (IC_RIGHT (ic))));
-      goto release;
+      
+      if (left == PAIR_HL && right != PAIR_INVALID)
+        {
+          emit2 ("add hl,%s", _pairs[right].name);
+          goto release;
+        }
+      else if (right == PAIR_HL && left != PAIR_INVALID)
+        {
+          emit2 ("add hl,%s", _pairs[left].name);
+          goto release;
+        }
+      else if (right != PAIR_INVALID)
+        {
+          fetchPair (PAIR_HL, AOP (IC_LEFT (ic)));
+          emit2 ("add hl,%s", getPairName (AOP (IC_RIGHT (ic))));
+          goto release;
+        }
+      else if (left != PAIR_INVALID)
+        { 
+          fetchPair (PAIR_HL, AOP (IC_RIGHT (ic)));
+          emit2 ("add hl,%s", getPairName (AOP (IC_LEFT (ic))));
+          goto release;
+        }
+      else
+        {
+          /* Can't do it */
+        }
     }
 
   if (isPair (AOP (IC_RIGHT (ic))) && AOP_TYPE (IC_LEFT (ic)) == AOP_IMMD)
@@ -3643,6 +3746,14 @@ genIfxJump (iCode * ic, char *jval)
        {
          inst = "nc";
        }
+      else if (!strcmp (jval, "m"))
+       {
+         inst = "m";
+       }
+      else if (!strcmp (jval, "p"))
+       {
+         inst = "p";
+       }
       else
        {
          /* The buffer contains the bit on A that we should test */
@@ -3665,6 +3776,14 @@ genIfxJump (iCode * ic, char *jval)
        {
          inst = "c";
        }
+      else if (!strcmp (jval, "m"))
+       {
+         inst = "p";
+       }
+      else if (!strcmp (jval, "p"))
+       {
+         inst = "m";
+       }
       else
        {
          /* The buffer contains the bit on A that we should test */
@@ -3682,6 +3801,12 @@ genIfxJump (iCode * ic, char *jval)
   else if (!strcmp (jval, "nc"))
     {
     }
+  else if (!strcmp (jval, "m"))
+    {
+    }
+  else if (!strcmp (jval, "p"))
+    {
+    }
   else
     {
       emit2 ("bit %s,a", jval);
@@ -3700,30 +3825,7 @@ _getPairIdName (PAIR_ID id)
 }
 #endif
 
-/** Generic compare for > or <
- */
-static void
-genCmp (operand * left, operand * right,
-       operand * result, iCode * ifx, int sign)
-{
-  int size, offset = 0;
-  unsigned long lit = 0L;
-  bool swap_sense = FALSE;
-
-  /* if left & right are bit variables */
-  if (AOP_TYPE (left) == AOP_CRY &&
-      AOP_TYPE (right) == AOP_CRY)
-    {
-      /* Cant happen on the Z80 */
-      wassertl (0, "Tried to compare two bits");
-    }
-  else
-    {
-      /* subtract right from left if at the
-         end the carry flag is set then we know that
-         left is greater than right */
-      size = max (AOP_SIZE (left), AOP_SIZE (right));
-
+#if OLD
       /* if unsigned char cmp with lit, just compare */
       if ((size == 1) &&
          (AOP_TYPE (right) == AOP_LIT && AOP_TYPE (left) != AOP_DIR))
@@ -3898,10 +4000,109 @@ genCmp (operand * left, operand * right,
            }
        }
     }
+#endif
+
+/** Generic compare for > or <
+ */
+static void
+genCmp (operand * left, operand * right,
+       operand * result, iCode * ifx, int sign)
+{
+  int size, offset = 0;
+  unsigned long lit = 0L;
+  bool swap_sense = FALSE;
+
+  /* if left & right are bit variables */
+  if (AOP_TYPE (left) == AOP_CRY &&
+      AOP_TYPE (right) == AOP_CRY)
+    {
+      /* Cant happen on the Z80 */
+      wassertl (0, "Tried to compare two bits");
+    }
+  else
+    {
+      /* Do a long subtract of right from left. */
+      size = max (AOP_SIZE (left), AOP_SIZE (right));
+
+      if (size > 1 && IS_GB && requiresHL(AOP(right)) && requiresHL(AOP(left)))
+        {
+          // On the Gameboy we can't afford to adjust HL as it may trash the carry.
+          // Pull left into DE and right into HL
+          aopGet (AOP(left), LSB, FALSE);
+          emit2 ("ld d,h");
+          emit2 ("ld e,l");
+          aopGet (AOP(right), LSB, FALSE);
+
+          while (size--)
+            {
+              emit2 ("ld a,(de)");
+              emit2 ("%s a,(hl)", offset == 0 ? "sub" : "sbc");
+              
+              if (size != 0)
+                {
+                  emit2 ("inc hl");
+                  emit2 ("inc de");
+                }
+              offset++;
+            }
+          spillPair (PAIR_HL);
+          goto release;
+        }
+
+      if (AOP_TYPE (right) == AOP_LIT)
+        {
+          lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+          /* optimize if(x < 0) or if(x >= 0) */
+          if (lit == 0)
+            {
+              if (!sign)
+                {
+                  /* No sign so it's always false */
+                  _clearCarry();
+                }
+              else
+                {
+                  /* Just load in the top most bit */
+                  _moveA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE));
+                  if (!(AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result)) && ifx)
+                    {
+                      genIfxJump (ifx, "7");
+                      return;
+                    }
+                  else
+                    {
+                      if (!sign) 
+                        {
+                          emit2 ("rlc a");
+                        }
+                      if (ifx)
+                        {
+                          genIfxJump (ifx, swap_sense ? "c" : "nc");
+                          return;
+                        }
+                    }
+                }
+              goto release;
+            }
+        }
+
+      while (size--)
+        {
+          _moveA (aopGet (AOP (left), offset, FALSE));
+          /* Subtract through, propagating the carry */
+          emit2 ("%s a,%s", offset == 0 ? "sub" : "sbc", aopGet (AOP (right), offset, FALSE));
+          offset++;
+        }
+    }
 
 release:
   if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
     {
+      if (sign)
+        {
+          /* Shift the sign bit up into carry */
+          emit2 ("rlca");
+        }
       outBitCLong (result, swap_sense);
     }
   else
@@ -3910,9 +4111,26 @@ release:
          ifx conditional branch then generate
          code a little differently */
       if (ifx)
-       genIfxJump (ifx, swap_sense ? "nc" : "c");
+        {
+          if (IS_GB)
+            {
+              emit2 ("rlca");
+              genIfxJump (ifx, swap_sense ? "nc" : "c");
+            }
+          else
+            {
+              genIfxJump (ifx, swap_sense ? "p" : "m");
+            }
+        }
       else
-       outBitCLong (result, swap_sense);
+        {
+          if (sign)
+            {
+              /* Shift the sign bit up into carry */
+              emit2 ("rlca");
+            }
+          outBitCLong (result, swap_sense);
+        }
       /* leave the result in acc */
     }
 }
@@ -4120,9 +4338,11 @@ genCmpEq (iCode * ic, iCode * ifx)
       else
        {
          tlbl = newiTempLabel (NULL);
+          emitDebug(";1");
          gencjneshort (left, right, tlbl);
          if (IC_TRUE (ifx))
            {
+              emitDebug(";2");
              emit2 ("jp !tlabel", IC_TRUE (ifx)->key + 100);
              emitLabel (tlbl->key + 100);
            }
@@ -4130,6 +4350,7 @@ genCmpEq (iCode * ic, iCode * ifx)
            {
              /* PENDING: do this better */
              symbol *lbl = newiTempLabel (NULL);
+              emitDebug(";3");
              emit2 ("!shortjp !tlabel", lbl->key + 100);
              emitLabel (tlbl->key + 100);
              emit2 ("jp !tlabel", IC_FALSE (ifx)->key + 100);
@@ -4149,6 +4370,8 @@ genCmpEq (iCode * ic, iCode * ifx)
     }
   else
     {
+      emitDebug(";4");
+      
       gencjne (left, right, newiTempLabel (NULL));
       if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
        {
@@ -4156,6 +4379,7 @@ genCmpEq (iCode * ic, iCode * ifx)
        }
       if (ifx)
        {
+          emitDebug(";5");
          genIfxJump (ifx, "a");
          goto release;
        }
@@ -4163,6 +4387,7 @@ genCmpEq (iCode * ic, iCode * ifx)
          then put the result in place */
       if (AOP_TYPE (result) != AOP_CRY)
        {
+          emitDebug(";6");
          outAcc (result);
        }
       /* leave the result in acc */
@@ -5600,7 +5825,9 @@ genGenPointerGet (operand * left,
   aopOp (left, ic, FALSE, FALSE);
   aopOp (result, ic, FALSE, FALSE);
 
-  if (isPair (AOP (left)) && AOP_SIZE (result) == 1)
+  size = AOP_SIZE (result);
+
+  if (isPair (AOP (left)) && size == 1)
     {
       /* Just do it */
       if (isPtrPair (AOP (left)))
@@ -5617,11 +5844,24 @@ genGenPointerGet (operand * left,
       goto release;
     }
 
+  if ( getPairId( AOP (left)) == PAIR_IY)
+    {
+      /* Just do it */
+      offset = 0;
+      while (size--) 
+        {
+          char at[20];
+          tsprintf (at, "!*iyx", offset);
+          aopPut (AOP (result), at, offset);
+          offset++;
+        }
+      goto release;
+    }
+
   /* For now we always load into IY */
   /* if this is remateriazable */
   fetchPair (pair, AOP (left));
 
-  /* so iy now contains the address */
   freeAsmop (left, NULL, ic);
 
   /* if bit then unpack */
@@ -5629,6 +5869,14 @@ genGenPointerGet (operand * left,
     {
       wassert (0);
     }
+  else if ( getPairId( AOP (result)) == PAIR_HL)
+    {
+      wassertl (size == 2, "HL must be of size 2");
+      emit2 ("ld a,!*hl");
+      emit2 ("inc hl");
+      emit2 ("ld h,!*hl");
+      emit2 ("ld l,a");
+    }
   else
     {
       size = AOP_SIZE (result);
@@ -5681,7 +5929,7 @@ genPointerGet (iCode * ic)
 bool
 isRegOrLit (asmop * aop)
 {
-  if (aop->type == AOP_REG || aop->type == AOP_LIT || aop->type == AOP_IMMD)
+  if (aop->type == AOP_REG || aop->type == AOP_LIT || aop->type == AOP_IMMD || aop->type == AOP_HLREG)
     return TRUE;
   return FALSE;
 }
@@ -5696,15 +5944,17 @@ genGenPointerSet (operand * right,
   int size, offset;
   sym_link *retype = getSpec (operandType (right));
   PAIR_ID pairId = PAIR_HL;
-
+  
   aopOp (result, ic, FALSE, FALSE);
   aopOp (right, ic, FALSE, FALSE);
 
   if (IS_GB)
     pairId = PAIR_DE;
 
+  size = AOP_SIZE (right);
+
   /* Handle the exceptions first */
-  if (isPair (AOP (result)) && (AOP_SIZE (right) == 1))
+  if (isPair (AOP (result)) && size == 1)
     {
       /* Just do it */
       const char *l = aopGet (AOP (right), 0, FALSE);
@@ -5720,6 +5970,28 @@ genGenPointerSet (operand * right,
        }
       goto release;
     }
+  
+  if ( getPairId( AOP (result)) == PAIR_IY)
+    {
+      /* Just do it */
+      const char *l = aopGet (AOP (right), 0, FALSE);
+
+      offset = 0;
+      while (size--) 
+        {
+          if (canAssignToPtr (l))
+            {
+              emit2 ("ld !*iyx,%s", offset, aopGet( AOP(right), offset, FALSE));
+            }
+          else
+            {
+              _moveA (aopGet (AOP (right), offset, FALSE));
+              emit2 ("ld !*iyx,a", offset);
+            }
+          offset++;
+        }
+      goto release;
+    }
 
   /* if the operand is already in dptr
      then we do nothing else we move the value to dptr */
@@ -5737,7 +6009,6 @@ genGenPointerSet (operand * right,
     }
   else
     {
-      size = AOP_SIZE (right);
       offset = 0;
 
       while (size--)
@@ -5915,7 +6186,10 @@ genAssign (iCode * ic)
   offset = 0;
 
   if (AOP_TYPE (right) == AOP_LIT)
+    {
     lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+    }
+
   if (isPair (AOP (result)))
     {
       fetchPair (getPairId (AOP (result)), AOP (right));
@@ -5956,6 +6230,12 @@ genAssign (iCode * ic)
          offset++;
        }
     }
+  else if (size == 2 && AOP_TYPE (right) == AOP_IY)
+    {
+      emit2 ("ld hl,(%s)", AOP (right)->aopu.aop_dir);
+      aopPut (AOP (result), "l", LSB);
+      aopPut (AOP (result), "h", MSB16);
+    }
   else if (size == 2 && requiresHL (AOP (right)) && requiresHL (AOP (result)) && IS_GB)
     {
       /* Special case.  Load into a and d, then load out. */
@@ -5991,7 +6271,7 @@ genAssign (iCode * ic)
       while (size--)
        {
          /* PENDING: do this check better */
-         if (requiresHL (AOP (right)) && requiresHL (AOP (result)))
+         if (IS_GB && requiresHL (AOP (right)) && requiresHL (AOP (result)))
            {
              _moveA (aopGet (AOP (right), offset, FALSE));
              aopPut (AOP (result), "a", offset);
index 76fe8cddcaaa51acb48d9214604d291e34bd122b..2bba126095efb9e69a256d089f82ed425b4adece 100644 (file)
@@ -23,3 +23,11 @@ replace {
         or      a,a
        jp      z,%2
 }
+replace {
+       rlca
+       ld      a,#0x00
+       rla
+} by {
+       rlca
+        and     a,#0x01
+}
index 354d1ee1ae51651eca0b996f0fa2d60c0533a1e9..320fa781dbc2e92a43dd1fa64855541547768301 100644 (file)
@@ -44,6 +44,7 @@
 */
 
 #include "z80.h"
+#include "SDCCicode.h"
 
 /* Flags to turn off optimisations.
  */
@@ -51,8 +52,7 @@ enum
   {
     DISABLE_PACK_ACC = 0,
     DISABLE_PACK_ASSIGN = 0,
-    /* Pack for one use is quite broken. */
-    DISABLE_PACK_ONE_USE = 1,
+    DISABLE_PACK_ONE_USE = 0,
     DISABLE_PACK_HL = 0,
   };
 
@@ -64,7 +64,9 @@ enum
     D_ALLOC2 = 0,
     D_ACCUSE2 = 0,
     D_ACCUSE2_VERBOSE = 0,
-    D_HLUSE = 0
+    D_HLUSE = 0,
+    D_HLUSE2 = 0,
+    D_HLUSE2_VERBOSE = 0
   };
 
 #if 1
@@ -383,6 +385,9 @@ noOverLap (set * itmpStack, symbol * fsym)
   for (sym = setFirstItem (itmpStack); sym;
        sym = setNextItem (itmpStack))
     {
+      if (bitVectBitValue(sym->clashes,fsym->key)) 
+        return 0;
+#if 0
             // if sym starts before (or on) our end point
             // and ends after (or on) our start point, 
             // it is an overlap.
@@ -391,6 +396,7 @@ noOverLap (set * itmpStack, symbol * fsym)
            {
                return 0;
            }
+#endif
     }
   return 1;
 }
@@ -1017,6 +1023,8 @@ tryAllocatingRegPair (symbol * sym)
          sym->regs[0] = &regsZ80[i];
          regsZ80[i + 1].isFree = 0;
          sym->regs[1] = &regsZ80[i + 1];
+          sym->regType = REG_PAIR;
+
          if (currFunc)
            {
              currFunc->regsUsed =
@@ -1478,28 +1486,13 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
       return 0;
     }
 
-#if 0
-  /* if the true symbol is defined in far space or on stack
-     then we should not since this will increase register pressure */
-  if (isOperandInFarSpace (IC_RESULT (ic)))
-    {
-      if ((dic = farSpacePackable (ic)))
-       goto pack;
-      else
-       return 0;
-    }
-#endif
-
   /* find the definition of iTempNN scanning backwards if we find a 
      a use of the true symbol in before we find the definition then 
      we cannot */
   for (dic = ic->prev; dic; dic = dic->prev)
     {
-      /* if there is a function call and this is
-         a parameter & not my parameter then don't pack it */
-      if ((dic->op == CALL || dic->op == PCALL) &&
-         (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
-          !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
+      /* PENDING: Don't pack across function calls. */
+      if (dic->op == CALL || dic->op == PCALL)
        {
          dic = NULL;
          break;
@@ -1529,14 +1522,6 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
          dic = NULL;
          break;
        }
-#if 0
-      if (POINTER_SET (dic) &&
-         IC_RESULT (dic)->key == IC_RESULT (ic)->key)
-       {
-         dic = NULL;
-         break;
-       }
-#endif
     }
 
   if (!dic)
@@ -1547,7 +1532,6 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
       OP_SYMBOL (IC_RESULT (ic))->iaccess)
     {
-
       /* the operation has only one symbol
          operator then we can pack */
       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
@@ -1753,8 +1737,10 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
 
   /* only upto 2 bytes since we cannot predict
      the usage of b, & acc */
-  if (getSize (operandType (op)) > 2 &&
-      ic->op != RETURN &&
+  if (getSize (operandType (op)) > 2)
+    return NULL;
+
+  if (ic->op != RETURN &&
       ic->op != SEND)
     return NULL;
 
@@ -2115,8 +2101,267 @@ hluse:
   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_SCRATCH;
 }
 
+static iCode *
+packRegsForHLUse3 (iCode * lic, operand * op, eBBlock * ebp)
+{
+  int i, key;
+  symbol *sym;
+  iCode *ic, *dic;
+  bool isFirst = TRUE;
+
+#if 0
+  printf("Checking:\n");
+  piCode(lic, NULL);
+#endif
+
+  if ( OP_SYMBOL(op)->accuse)
+    {
+      return NULL;
+    }
+
+  if (OP_SYMBOL(op)->remat)
+    {
+      return NULL; 
+    }
+
+  /* Only defined once */
+  if (bitVectnBitsOn (OP_DEFS (op)) > 1)
+    return NULL;
+
+  if (getSize (operandType (op)) != 2)
+    return NULL;
+
+  /* And this is the definition */
+  if (bitVectFirstBit (OP_DEFS (op)) != lic->key)
+    return NULL;
+
+  /* first check if any overlapping liverange has already been
+     assigned to DPTR */
+  if (OP_SYMBOL(op)->clashes) 
+    {
+      for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ ) 
+        {
+          if (bitVectBitValue(OP_SYMBOL(op)->clashes,i)) 
+            {
+              sym = hTabItemWithKey(liveRanges,i);
+              if (sym->accuse == ACCUSE_SCRATCH)
+                {
+                  return NULL;
+                }
+            }
+        }
+    }
+
+  /* Nothing else that clashes with this is using the scratch
+     register.  Scan through all of the intermediate instructions and
+     see if any of them could nuke HL.
+  */
+  dic = ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom);
+
+  for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
+       ic = hTabNextItem(iCodeSeqhTab,&key)) 
+    {
+#if 0
+      piCode(ic, NULL);
+      printf("(op: %u)\n", ic->op);
+#endif
+      if (isFirst)
+        {
+          isFirst = FALSE;
+          if (ic->op == ADDRESS_OF)
+            continue;
+          if (POINTER_GET (ic))
+            continue;
+        }
+
+      /* Handle the non left/right/result ones first */
+      if (ic->op == IFX)
+        continue;
+      if (ic->op == JUMPTABLE)
+        return NULL;
+
+      if (SKIP_IC2(ic))
+        continue;
+
+      if (ic->op == IPUSH && isOperandEqual (op, IC_LEFT (ic)))
+        continue;
+
+      if ((ic->op == '=' && !POINTER_SET(ic)) ||
+          ic->op == UNARYMINUS ||
+          ic->op == '+' ||
+          ic->op == '-' ||
+          0)
+        continue;
+
+      if (POINTER_GET (ic) && isOperandEqual (op, IC_LEFT (ic)))
+        continue;
+
+      if (IS_VALOP (IC_RIGHT (ic)) &&
+          (ic->op == EQ_OP ||
+           0))
+        {
+          continue;
+        }
+
+      /* By default give up */
+      return NULL;
+    }
+
+#if 0
+  printf("Succeeded!\n");
+#endif
+  OP_SYMBOL (op)->accuse = ACCUSE_SCRATCH;
+
+  return dic;
+}
+
+static iCode *
+packRegsForIYUse (iCode * lic, operand * op, eBBlock * ebp)
+{
+  int i, key;
+  symbol *sym;
+  iCode *ic, *dic;
+  bitVect *uses;
+
+#if 0
+  printf("Checking IY on %p lic key %u first def %u:\n", OP_SYMBOL(op), lic->key, bitVectFirstBit(OP_DEFS(op)));
+  piCode(lic, NULL);
+#endif
+
+  if ( OP_SYMBOL(op)->accuse)
+    {
+      return NULL;
+    }
+
+  if (OP_SYMBOL(op)->remat)
+    {
+      return NULL; 
+    }
+
+  /* Only defined once */
+  if (bitVectnBitsOn (OP_DEFS (op)) > 1)
+    return NULL;
+
+  /* And this is the definition */
+  if (bitVectFirstBit (OP_DEFS (op)) != lic->key)
+    return NULL;
+
+  /* first check if any overlapping liverange has already been
+     assigned to DPTR */
+  if (OP_SYMBOL(op)->clashes) 
+    {
+      for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ ) 
+        {
+          if (bitVectBitValue(OP_SYMBOL(op)->clashes,i)) 
+            {
+              sym = hTabItemWithKey(liveRanges,i);
+              if (sym->accuse == ACCUSE_IY)
+                {
+                  return NULL;
+                }
+            }
+        }
+    }
+
+  /* Only a few instructions can load into IY */
+  if (lic->op != '=')
+    {
+      return NULL;
+    }
+
+  /* Nothing else that clashes with this is using the scratch
+     register.  Scan through all of the intermediate instructions and
+     see if any of them could nuke HL.
+  */
+  dic = ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom);
+  uses = OP_USES(op);
+
+  for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
+       ic = hTabNextItem(iCodeSeqhTab,&key)) 
+    {
+#if 0
+      piCode(ic, NULL);
+      printf("(op: %u uses %u)\n", ic->op, bitVectBitValue(uses, ic->key));
+#endif
+
+      if (ic->op == PCALL || 
+          ic->op == CALL ||
+          ic->op == JUMPTABLE
+          )
+        return NULL;
+
+      if (SKIP_IC2(ic))
+        continue;
+
+      /* Only certain rules will work against IY.  Check if this iCode uses
+         this symbol. */
+      if (bitVectBitValue(uses, ic->key) != 0)
+        {
+          if (ic->op == IFX)
+            return NULL;
+
+          if (ic->op == '=' &&
+              isOperandEqual(IC_RESULT(ic), op))
+            continue;
+
+          if (ic->op == GET_VALUE_AT_ADDRESS &&
+              isOperandEqual(IC_LEFT(ic), op))
+            continue;
+
+          if (isOperandEqual(IC_RESULT(ic), IC_LEFT(ic)) == FALSE)
+            return NULL;
+
+          if (IC_RIGHT (ic) && IS_VALOP (IC_RIGHT (ic)))
+            {
+              if (ic->op == '+' ||
+                  ic->op == '-')
+                {
+                  /* Only works if the constant is small */
+                  if (operandLitValue (IC_RIGHT (ic)) < 4)
+                    continue;
+                }
+            }
+
+          return NULL;
+        }
+      else
+        {
+          if (ic->op == IFX)
+            continue;
+
+          /* This iCode doesn't use the sym.  See if this iCode preserves IY.
+           */
+          if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && 
+              isOperandInDirSpace(IC_RESULT(ic)))
+            return NULL;
+          
+          if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && 
+              isOperandInFarSpace(IC_RIGHT(ic)))
+            return NULL;
+
+          if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && 
+              isOperandInFarSpace(IC_LEFT(ic)))
+            return NULL;
+          
+          continue;
+        }
+
+      /* By default give up */
+      return NULL;
+    }
+
+#if 0
+  printf("Succeeded IY!\n");
+#endif
+  OP_SYMBOL (op)->accuse = ACCUSE_IY;
+
+  return dic;
+}
+
+/** Returns TRUE if this operation can use acc and if it preserves the value.
+ */
 static bool 
-opPreservesA (iCode * ic, iCode * uic)
+opPreservesA (iCode * uic)
 {
   if (uic->op == IFX)
     {
@@ -2161,6 +2406,8 @@ opPreservesA (iCode * ic, iCode * uic)
   return FALSE;
 }
 
+/** Returns true if this operand preserves the value of A.
+ */
 static bool
 opIgnoresA (iCode * ic, iCode * uic)
 {
@@ -2180,6 +2427,15 @@ opIgnoresA (iCode * ic, iCode * uic)
           return TRUE;
         }
     }
+  else if (uic->op == '=' && !POINTER_SET (uic))
+    {
+      /* If they are equal and get optimised out then things are OK. */
+      if (isOperandEqual (IC_RESULT (uic), IC_RIGHT (uic)))
+        {
+          /* Straight assign is OK. */
+          return TRUE;
+        }
+    }
 
   return FALSE;
 }
@@ -2246,7 +2502,7 @@ packRegsForAccUse2 (iCode * ic)
 {
   iCode *uic;
 
-  D (D_ALLOC, ("packRegsForAccUse2: running on ic %p\n", ic));
+  D (D_ACCUSE2, ("packRegsForAccUse2: running on ic %p line %u\n", ic, ic->lineno));
 
   /* Filter out all but those 'good' commands */
   if (
@@ -2255,6 +2511,8 @@ packRegsForAccUse2 (iCode * ic)
        !IS_BITWISE_OP (ic) &&
        ic->op != '=' &&
        ic->op != EQ_OP &&
+       ic->op != '<' &&
+       ic->op != '>' &&
        ic->op != CAST &&
        ic->op != GETHBIT &&
        1)
@@ -2312,7 +2570,7 @@ packRegsForAccUse2 (iCode * ic)
 
            bitVectUnSetBit (uses, setBit);
            /* Still contigous. */
-           if (!opPreservesA (ic, next))
+           if (!opPreservesA (next))
              {
                 D (D_ACCUSE2, ("  + Dropping as operation doesn't preserve A\n"));
                return;
@@ -2324,7 +2582,7 @@ packRegsForAccUse2 (iCode * ic)
           {
             if (next->prev == NULL)
               {
-                if (!opPreservesA (ic, next))
+                if (!opPreservesA (next))
                   {
                     D (D_ACCUSE2, ("  + Dropping as operation doesn't preserve A #2\n"));
                     return;
@@ -2364,110 +2622,6 @@ packRegsForAccUse2 (iCode * ic)
     OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_A;
     return;
   }
-
-  /* OLD CODE FOLLOWS */
-  /* if it is a conditional branch then we definitely can
-     MLH: Depends.
-   */
-#if 0
-  if (uic->op == IFX)
-    goto accuse;
-
-  /* MLH: Depends. */
-  if (uic->op == JUMPTABLE)
-    return;
-#endif
-
-  /* if the usage is not is an assignment or an 
-     arithmetic / bitwise / shift operation then not.
-     MLH: Pending:  Invalid.  Our pointer sets are always peechy.
-   */
-#if 0
-  if (POINTER_SET (uic) &&
-      getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
-    {
-      printf ("e5 %u\n", getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)));
-      return;
-    }
-#endif
-
-  printf ("1\n");
-  if (uic->op != '=' &&
-      !IS_ARITHMETIC_OP (uic) &&
-      !IS_BITWISE_OP (uic) &&
-      uic->op != LEFT_OP &&
-      uic->op != RIGHT_OP)
-    {
-      printf ("e6\n");
-      return;
-    }
-
-  /* if used in ^ operation then make sure right is not a 
-     literl */
-  if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
-    return;
-
-  /* if shift operation make sure right side is not a literal */
-  if (uic->op == RIGHT_OP &&
-      (isOperandLiteral (IC_RIGHT (uic)) ||
-       getSize (operandType (IC_RESULT (uic))) > 1))
-    return;
-
-  if (uic->op == LEFT_OP &&
-      (isOperandLiteral (IC_RIGHT (uic)) ||
-       getSize (operandType (IC_RESULT (uic))) > 1))
-    return;
-
-#if 0
-  /* make sure that the result of this icode is not on the
-     stack, since acc is used to compute stack offset */
-  if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
-      OP_SYMBOL (IC_RESULT (uic))->onStack)
-    return;
-#endif
-
-#if 0
-  /* if either one of them in far space then we cannot */
-  if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
-       isOperandInFarSpace (IC_LEFT (uic))) ||
-      (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
-       isOperandInFarSpace (IC_RIGHT (uic))))
-    return;
-#endif
-
-  /* if the usage has only one operand then we can */
-  if (IC_LEFT (uic) == NULL ||
-      IC_RIGHT (uic) == NULL)
-    goto accuse;
-
-  /* make sure this is on the left side if not
-     a '+' since '+' is commutative */
-  if (ic->op != '+' &&
-      IC_LEFT (uic)->key != IC_RESULT (ic)->key)
-    return;
-
-  /* if one of them is a literal then we can */
-  if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
-      (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
-    {
-      goto accuse;
-      return;
-    }
-
-/** 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)))))
-    goto accuse;
-
-  if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
-      (IS_ITEMP (IC_LEFT (uic)) ||
-       (IS_TRUE_SYMOP (IC_LEFT (uic)))))
-    goto accuse;
-  return;
-accuse:
-  printf ("acc ok!\n");
-  OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_A;
 }
 
 /** Does some transformations to reduce register pressure.
@@ -2555,6 +2709,13 @@ packRegisters (eBBlock * ebp)
        packRegsForSupport (ic, ebp);
 #endif
 
+      /* some cases the redundant moves can
+         can be eliminated for return statements */
+      if (ic->op == RETURN || ic->op == SEND)
+        {
+         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
+       }
+
       /* if pointer set & left has a size more than
          one and right is not in far space */
       if (!DISABLE_PACK_ONE_USE &&
@@ -2591,7 +2752,15 @@ packRegisters (eBBlock * ebp)
 
       if (!DISABLE_PACK_HL && IS_ITEMP (IC_RESULT (ic)))
        {
-         packRegsForHLUse (ic);
+          if (IS_GB)
+            packRegsForHLUse (ic);
+          else
+            packRegsForHLUse3 (ic, IC_RESULT (ic), ebp);
+       }
+
+      if (!DISABLE_PACK_HL && IS_ITEMP (IC_RESULT (ic)) && IS_Z80)
+       {
+          packRegsForIYUse (ic, IC_RESULT (ic), ebp);
        }
 
       if (!DISABLE_PACK_ACC && IS_ITEMP (IC_RESULT (ic)) &&
index 2180614276b39131c3c7b92a59b6a010a53eb9d0..fb93bdc993aba1bbebb271212b212f4887d674a2 100644 (file)
@@ -50,9 +50,14 @@ enum
     CND_IDX
   };
 
-#define REG_PTR 0x01
-#define REG_GPR 0x02
-#define REG_CND 0x04
+enum
+  {
+    REG_PTR = 1,
+    REG_GPR = 2,
+    REG_CND = 4,
+    REG_PAIR = 8
+  };
+
 /* definition for the registers */
 typedef struct regs
   {
index 66c5567664873e6b792fa8cd3208d94e02ba0e6f..f34981ec8e2eb83433b351bd2d284cb061b4bbc2 100644 (file)
@@ -26,5 +26,6 @@ extern Z80_OPTS z80_opts;
 enum
   {
     ACCUSE_A = 1,
-    ACCUSE_SCRATCH
+    ACCUSE_SCRATCH,
+    ACCUSE_IY
   };
diff --git a/support/regression/failing/bug-435214.c b/support/regression/failing/bug-435214.c
deleted file mode 100644 (file)
index e19adf1..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* bug-435214.c
- */
-#include <testfwk.h>
-
-static 
-unsigned int divide(long a)
-{
-    return a/512ul;
-}
-
-static void
-testDivide()
-{
-    assert(divide(1300) == 2);
-    assert(divide(0x12345678) == 0x91A2B);
-}
-
diff --git a/support/regression/tests/bug-435214.c b/support/regression/tests/bug-435214.c
new file mode 100644 (file)
index 0000000..a8887ca
--- /dev/null
@@ -0,0 +1,17 @@
+/* bug-435214.c
+ */
+#include <testfwk.h>
+
+static 
+unsigned long divide(long a)
+{
+    return a/512ul;
+}
+
+static void
+testDivide()
+{
+  ASSERT(divide(1300) == 2);
+  ASSERT(divide(0x12345678) == 0x91A2B);
+}
+
index 0a9c4aa660bf15797f1205c3736630bb6e6975c7..9521a28c4aae10230116671e29539e7d62fe2975 100644 (file)
@@ -43,3 +43,8 @@ initProxy(devsw_t *pdrv)
   return (*pdrv->dev_init)(5);
 }
 
+void
+testDriverStruct(void)
+{
+  initProxy(&_sillyDriver);
+}
index 085cd7464bf327d8382a48c2b35eedfb97d7ee15..1636d334c32cca3e41e76f2cc15035d55b7cf0b2 100644 (file)
@@ -51,19 +51,17 @@ testLogicalAnd(void)
     ASSERT(true && !false);
     ASSERT(!false && true);
 
-#if 1
     /* PENDING: Doesn't work. */
     /* Test that the evaluation is aborted on the first false. */
     if (true && false && neverGetHere()) {
         /* Tested using neverGetHere() */
     }
-#else
+
     /* Alternate that is similar. */
     if (true && false) {
         neverGetHere();
         /* Tested using neverGetHere() */
     }
-#endif
 
     resetGetHere();
     /* Test that the evaluation is done left to right. */
@@ -82,15 +80,11 @@ testLogicalOr(void)
     ASSERT(!true || !false);
     ASSERT(false || true);
 
-#if 0
     /* PENDING: Doesn't work in sdcc. */
     /* Test that the evaluation is aborted on the first hit. */
     if (false || true || neverGetHere()) {
         /* Tested using neverGetHere() */
     }
-#else
-    /* No equivalent. */
-#endif
 
     resetGetHere();
     /* Test that the evaluation is done left to right. */