* src/diff.1 (Index): Many, many optmisiations. Dhrystone up to 201.
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 6 Dec 2001 03:07:04 +0000 (03:07 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 6 Dec 2001 03:07:04 +0000 (03:07 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1663 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
doc/choices.txt
src/z80/gen.c
src/z80/peeph-z80.def
src/z80/peeph.def
src/z80/ralloc.c

index 4590279114e6d28aa43af2aad6033c337c3ce560..164cf7777a21c0dc29c7954e062e95f848c5dfb2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2001-12-05  Michael Hope  <michaelh@juju.net.nz>
+
+       * src/diff.1 (Index): Many, many optmisiations.  Dhrystone up to 201.
+
+1904-01-06  Michael Hope  <michaelh@juju.net.nz>
+
+       * src/z80/ralloc.c (packRegsForIYUse): Fixed the case where an operand is in direct space.
+
+       * src/z80/gen.c (makeFreePairId): Optimised IY load by using a spare pair.
+
 2001-12-02  Bernhard Held  <bernhard@bernhardheld.de>
 
        * src/mcs51/gen.c (genFunction): avoid excess "inc sp"
index d6fbe90c9b05b3e43273b0616e16ccffae8c351c..1442eca452e5bed8306897b5062f5c87fce84d0b 100644 (file)
@@ -218,4 +218,25 @@ Cleaning up the arguments to a call:
          pop    af              ; 5/byte
 
 
-So for 8 bytes and above use the first form.
\ No newline at end of file
+So for 8 bytes and above use the first form.
+
+Pointer assign:
+        ld      hl,bc           ; 4+4
+        ld      e,(hl)          ; 7
+        inc     hl              ; 6
+        ld      d,(hl)          ; 7
+
+vs:
+        ld      a,(bc)          ; 7
+        ld      e,a             ; 4
+        inc     bc              ; 6
+        ld      a,(bc)          ; 7
+        ld      d,a             ; 4
+
+Same cost.  Not worth it, although is does free up HL.
+
+Shift left signed on HL
+      sla  l
+      rl   h                    ; 8+8 = 16
+
+      add  hl,hl                ; 11
index 76345de7343a5bceb258c931099238aa31b68887..1ac58abf97b3b3da1baf7cb53cf2766f53c449d5 100644 (file)
@@ -60,7 +60,9 @@
   9. With asm optimised strings                17030 192 2223
 
   10 and below are with asm strings off.
-  
+
+  10 Mucho optimisations               13562 201 1FCC
+
   Apparent advantage of turning on regparams:
   1.  Cost of push
         Decent case is push of a constant 
@@ -252,6 +254,30 @@ static const char *aopNames[] = {
   "AOP_PAIRPT"
 };
 
+static bool
+isLastUse (iCode *ic, operand *op)
+{
+  bitVect *uses = bitVectCopy (OP_USES (op));
+
+  while (!bitVectIsZero (uses))
+    {
+      if (bitVectFirstBit (uses) == ic->key)
+        {
+          if (bitVectnBitsOn (uses) == 1)
+            {
+              return TRUE;
+            }
+          else
+            {
+              return FALSE;
+            }
+        }
+      bitVectUnSetBit (uses, bitVectFirstBit (uses));
+    }
+
+  return FALSE;
+}
+
 static PAIR_ID
 _getTempPairId(void)
 {
@@ -271,14 +297,50 @@ _getTempPairName(void)
   return _pairs[_getTempPairId()].name;
 }
 
+static bool
+isPairInUse (PAIR_ID id, iCode *ic)
+{
+  if (id == PAIR_DE)
+    {
+      return bitVectBitValue (ic->rMask, D_IDX) || bitVectBitValue(ic->rMask, E_IDX);
+    }
+  else if (id == PAIR_BC)
+    {
+      return bitVectBitValue (ic->rMask, B_IDX) || bitVectBitValue(ic->rMask, C_IDX);
+    }
+  else
+    {
+      wassertl (0, "Only implemented for DE and BC");
+      return TRUE;
+    }
+}
+
+static bool
+isPairInUseNotInRet(PAIR_ID id, iCode *ic)
+{
+  bitVect *rInUse;
+  
+  rInUse = bitVectCplAnd (bitVectCopy (ic->rMask), ic->rUsed);
+  
+  if (id == PAIR_DE)
+    {
+      return bitVectBitValue (rInUse, D_IDX) || bitVectBitValue(rInUse, E_IDX);
+    }
+  else
+    {
+      wassertl (0, "Only implemented for DE");
+      return TRUE;
+    }
+}
+
 static PAIR_ID
 getFreePairId (iCode *ic)
 {
-  if (!(bitVectBitValue (ic->rMask, B_IDX) || bitVectBitValue(ic->rMask, C_IDX)))
+  if (!isPairInUse (PAIR_BC, ic))
     {
       return PAIR_BC;
     }
-  else if (IS_Z80 && !(bitVectBitValue (ic->rMask, D_IDX) || bitVectBitValue(ic->rMask, E_IDX)))
+  else if (IS_Z80 && !isPairInUse (PAIR_DE, ic))
     {
       return PAIR_DE;
     }
@@ -1175,8 +1237,36 @@ fetchLitPair (PAIR_ID pairId, asmop * left, int offset)
   emit2 ("ld %s,!hashedstr", pair, l);
 }
 
+static PAIR_ID
+makeFreePairId (iCode *ic, bool *pisUsed)
+{
+  *pisUsed = FALSE;
+
+  if (ic != NULL)
+    {
+      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
+        {
+          *pisUsed = TRUE;
+          return PAIR_HL;
+        }
+    }
+  else
+    {
+      *pisUsed = TRUE;
+      return PAIR_HL;
+    }
+}
+
 static void
-fetchPairLong (PAIR_ID pairId, asmop * aop, int offset)
+fetchPairLong (PAIR_ID pairId, asmop * aop, iCode *ic, int offset)
 {
     /* if this is remateriazable */
     if (isLitWord (aop)) {
@@ -1228,19 +1318,24 @@ fetchPairLong (PAIR_ID pairId, asmop * aop, int offset)
               }
             else
               {
-                _push (PAIR_HL);
+                bool isUsed;
+                PAIR_ID id = makeFreePairId (ic, &isUsed);
+                if (isUsed)
+                  _push (id);
                 /* 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 ("ld %s,%s", _pairs[id].l, aopGet (aop, offset, FALSE));
+                emit2 ("ld %s,%s", _pairs[id].h, aopGet (aop, offset + 1, FALSE));
+                emit2 ("push %s", _pairs[id].name);
                 emit2 ("pop iy");
-                _pop (PAIR_HL);
+                if (isUsed)
+                  _pop (id);
               }
           }
-        else {
+        else 
+          {
             emit2 ("ld %s,%s", _pairs[pairId].l, aopGet (aop, offset, FALSE));
             emit2 ("ld %s,%s", _pairs[pairId].h, aopGet (aop, offset + 1, FALSE));
-        }
+          }
         /* PENDING: check? */
         if (pairId == PAIR_HL)
             spillPair (PAIR_HL);
@@ -1250,7 +1345,7 @@ fetchPairLong (PAIR_ID pairId, asmop * aop, int offset)
 static void
 fetchPair (PAIR_ID pairId, asmop * aop)
 {
-  fetchPairLong (pairId, aop, 0);
+  fetchPairLong (pairId, aop, NULL, 0);
 }
 
 static void
@@ -2044,7 +2139,7 @@ _gbz80_emitAddSubLongLong (iCode *ic, asmop *left, asmop *right, bool isAdd)
   aopPut ( AOP (IC_RESULT (ic)), "a", MSB16);
   aopPut ( AOP (IC_RESULT (ic)), "e", LSB);
 
-  fetchPairLong (PAIR_DE, left, MSB24);
+  fetchPairLong (PAIR_DE, left, NULL, MSB24);
   aopGet (right, MSB24, FALSE);
 
   _pop (PAIR_AF);
@@ -2333,11 +2428,11 @@ genIpush (iCode * ic)
        }
       if (size == 4)
        {
-         fetchPairLong (PAIR_HL, AOP (IC_LEFT (ic)), 2);
+         fetchPairLong (PAIR_HL, AOP (IC_LEFT (ic)), ic, 2);
          emit2 ("push hl");
          spillPair (PAIR_HL);
          _G.stack.pushed += 2;
-         fetchPairLong (PAIR_HL, AOP (IC_LEFT (ic)), 0);
+         fetchPairLong (PAIR_HL, AOP (IC_LEFT (ic)), ic, 0);
          emit2 ("push hl");
          spillPair (PAIR_HL);
          _G.stack.pushed += 2;
@@ -2952,7 +3047,7 @@ genRet (iCode * ic)
       if (IS_GB && size == 4 && requiresHL (AOP (IC_LEFT (ic))))
        {
          fetchPair (PAIR_DE, AOP (IC_LEFT (ic)));
-         fetchPairLong (PAIR_HL, AOP (IC_LEFT (ic)), 2);
+         fetchPairLong (PAIR_HL, AOP (IC_LEFT (ic)), ic, 2);
        }
       else
        {
@@ -3690,8 +3785,9 @@ genMult (iCode * ic)
   //  wassertl (val > 0, "Multiply must be positive");
   wassertl (val != 1, "Can't multiply by 1");
 
-  if (IS_Z80) {
+  if (IS_Z80 && isPairInUseNotInRet (PAIR_DE, ic)) {
     _push (PAIR_DE);
+    _G.stack.pushedDE = TRUE;
   }
 
   if ( AOP_SIZE (IC_LEFT (ic)) == 1 && !SPEC_USIGN (getSpec (operandType ( IC_LEFT (ic)))))
@@ -3735,9 +3831,10 @@ genMult (iCode * ic)
 
   spillCached();
 
-  if (IS_Z80)
+  if (IS_Z80 && _G.stack.pushedDE)
     {
       _pop (PAIR_DE);
+      _G.stack.pushedDE = FALSE;
     }
 
   commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
@@ -5273,9 +5370,13 @@ shiftL2Left2Result (operand * left, int offl,
       movLeft2Result (left, offl, result, offr, 0);
       movLeft2Result (left, offl + 1, result, offr + 1, 0);
     }
-  /* PENDING: for now just see if it'll work. */
-  /*if (AOP(result)->type == AOP_REG) { */
-  {
+
+  if (shCount == 1 && getPairId (AOP (result)) == PAIR_HL)
+    {
+      emit2 ("add hl,hl");
+    }
+  else
+    {
     int size = 2;
     int offset = 0;
     symbol *tlbl, *tlbl1;
@@ -5897,7 +5998,7 @@ genGenPointerGet (operand * left,
       goto release;
     }
 
-  if ( getPairId( AOP (left)) == PAIR_IY)
+  if (getPairId (AOP (left)) == PAIR_IY)
     {
       /* Just do it */
       offset = 0;
@@ -5917,14 +6018,12 @@ genGenPointerGet (operand * left,
   /* if this is remateriazable */
   fetchPair (pair, AOP (left));
 
-  freeAsmop (left, NULL, ic);
-
   /* if bit then unpack */
   if (IS_BITVAR (retype))
     {
       wassert (0);
     }
-  else if ( getPairId( AOP (result)) == PAIR_HL)
+  else if (getPairId (AOP (result)) == PAIR_HL)
     {
       wassertl (size == 2, "HL must be of size 2");
       emit2 ("ld a,!*hl");
@@ -5932,6 +6031,35 @@ genGenPointerGet (operand * left,
       emit2 ("ld h,!*hl");
       emit2 ("ld l,a");
     }
+  else if (getPairId (AOP (left)) == PAIR_HL && !isLastUse (ic, left))
+    {
+      size = AOP_SIZE (result);
+      offset = 0;
+
+      while (size--)
+       {
+         /* PENDING: make this better */
+         if (!IS_GB && AOP_TYPE (result) == AOP_REG)
+           {
+             aopPut (AOP (result), "!*hl", offset++);
+           }
+         else
+           {
+             emit2 ("ld a,!*pair", _pairs[pair].name);
+             aopPut (AOP (result), "a", offset++);
+           }
+         if (size)
+           {
+             emit2 ("inc %s", _pairs[pair].name);
+             _G.pairs[pair].offset++;
+           }
+       }
+      /* Fixup HL back down */
+      for (size = AOP_SIZE (result)-1; size; size--)
+        {
+          emit2 ("dec %s", _pairs[pair].name);
+        }
+    }
   else
     {
       size = AOP_SIZE (result);
@@ -5940,7 +6068,8 @@ genGenPointerGet (operand * left,
       while (size--)
        {
          /* PENDING: make this better */
-         if (!IS_GB && AOP (result)->type == AOP_REG)
+         if (!IS_GB && 
+              (AOP_TYPE (result) == AOP_REG || AOP_TYPE (result) == AOP_HLREG))
            {
              aopPut (AOP (result), "!*hl", offset++);
            }
@@ -5957,6 +6086,8 @@ genGenPointerGet (operand * left,
        }
     }
 
+  freeAsmop (left, NULL, ic);
+
 release:
   freeAsmop (result, NULL, ic);
 }
@@ -6047,6 +6178,37 @@ genGenPointerSet (operand * right,
         }
       goto release;
     }
+  else if (getPairId (AOP (result)) == PAIR_HL && !isLastUse (ic, result))
+    {
+      offset = 0;
+
+      while (size--)
+       {
+         const char *l = aopGet (AOP (right), offset, FALSE);
+         if (isRegOrLit (AOP (right)) && !IS_GB)
+           {
+             emit2 ("ld !*pair,%s", _pairs[PAIR_HL].name, l);
+           }
+         else
+           {
+             _moveA (l);
+             emit2 ("ld !*pair,a", _pairs[PAIR_HL].name);
+           }
+         if (size)
+           {
+             emit2 ("inc %s", _pairs[PAIR_HL].name);
+             _G.pairs[PAIR_HL].offset++;
+           }
+         offset++;
+       }
+
+      /* Fixup HL back down */
+      for (size = AOP_SIZE (right)-1; size; size--)
+        {
+          emit2 ("dec %s", _pairs[PAIR_HL].name);
+        }
+      goto release;
+    }
 
   /* if the operand is already in dptr
      then we do nothing else we move the value to dptr */
@@ -6242,12 +6404,12 @@ genAssign (iCode * ic)
 
   if (AOP_TYPE (right) == AOP_LIT)
     {
-    lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+      lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
     }
 
   if (isPair (AOP (result)))
     {
-      fetchPair (getPairId (AOP (result)), AOP (right));
+      fetchPairLong (getPairId (AOP (result)), AOP (right), ic, LSB);
     }
   else if ((size > 1) &&
           (AOP_TYPE (result) != AOP_REG) &&
index 2bba126095efb9e69a256d089f82ed425b4adece..63c89a44e18ccf4087ba132d937af645417b868b 100644 (file)
@@ -31,3 +31,15 @@ replace {
        rlca
         and     a,#0x01
 }
+replace {
+       ld      %3,a
+       ld      l,%1)
+       ld      h,%2)
+       ld      l,(hl)
+       ld      a,%3
+} by {
+       ld      %3,a
+       ld      l,%1)
+       ld      h,%2)
+       ld      l,(hl)
+}
index d865c3a93031f86ea982e4c0951466745d992bac..ee3597876774958cbecbefd1aae2be36fa12f299 100644 (file)
@@ -3,7 +3,7 @@ replace {
 } by {
        ERROR - peephole - caught (hl),(hl)
 }
-replace {
+replace restart {
        ld %1,%1
 } by {
         ; Removed redundent load
@@ -192,3 +192,12 @@ replace {
        cp      a,#%4
        jp      p,%5
 }
+replace {
+       ld      e,l
+       ld      d,h
+       ld      l,e
+       ld      h,d
+} by {
+       ld      e,l
+       ld      d,h
+}
index e8d338fa9d409da4f53d03dff5114c8457b231af..9d58ded2361927dd8445fdcd0910ed2dd9f21ad8 100644 (file)
@@ -54,6 +54,7 @@ enum
     DISABLE_PACK_ASSIGN = 0,
     DISABLE_PACK_ONE_USE = 0,
     DISABLE_PACK_HL = 0,
+    DISABLE_PACK_IY = 0
   };
 
 /* Flags to turn on debugging code.
@@ -67,7 +68,9 @@ enum
     D_HLUSE = 0,
     D_HLUSE2 = 0,
     D_HLUSE2_VERBOSE = 0,
-    D_FILL_GAPS = 0
+    D_FILL_GAPS = 0,
+    D_PACK_IY = 0,
+    D_PACK_HLUSE3 = 0
   };
 
 #if 1
@@ -2232,10 +2235,9 @@ packRegsForHLUse3 (iCode * lic, operand * op, eBBlock * ebp)
   iCode *ic, *dic;
   bool isFirst = TRUE;
 
-#if 0
-  printf("Checking:\n");
-  piCode(lic, NULL);
-#endif
+  D (D_PACK_HLUSE3, ("Checking HL on %p lic key %u first def %u line %u:\n", OP_SYMBOL(op), lic->key, bitVectFirstBit(OP_DEFS(op)), lic->lineno));
+  if (D_PACK_HLUSE3)
+    piCode(lic, NULL);
 
   if ( OP_SYMBOL(op)->accuse)
     {
@@ -2282,12 +2284,12 @@ packRegsForHLUse3 (iCode * lic, operand * op, eBBlock * ebp)
   dic = ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom);
 
   for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
-       ic = hTabNextItem(iCodeSeqhTab,&key)) 
+       ic = hTabNextItem(iCodeSeqhTab, &key)) 
     {
-#if 0
-      piCode(ic, NULL);
-      printf("(op: %u)\n", ic->op);
-#endif
+      if (D_PACK_HLUSE3)
+        piCode(ic, NULL);
+      D (D_PACK_HLUSE3, ("(On %p: op: %u next: %p)\n", ic, ic->op, ic->next));
+
       if (isFirst)
         {
           isFirst = FALSE;
@@ -2295,6 +2297,8 @@ packRegsForHLUse3 (iCode * lic, operand * op, eBBlock * ebp)
             continue;
           if (POINTER_GET (ic))
             continue;
+          if (ic->op == '=' && !POINTER_SET(ic))
+            continue;
         }
 
       if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic))
@@ -2330,13 +2334,25 @@ packRegsForHLUse3 (iCode * lic, operand * op, eBBlock * ebp)
       if (ic->op == CALL && isOperandEqual (op, IC_RESULT (ic)))
         continue;
 
+      if (ic->op == LEFT_OP && isOperandLiteral (IC_RIGHT (ic)))
+        continue;
+
       if ((ic->op == '=' && !POINTER_SET(ic)) ||
           ic->op == UNARYMINUS ||
           ic->op == '+' ||
           ic->op == '-' ||
+          ic->op == '>' ||
+          ic->op == '<' ||
+          ic->op == EQ_OP ||
           0)
         continue;
 
+      if (ic->op == '*' && isOperandEqual (op, IC_LEFT (ic)))
+        continue;
+
+      if (POINTER_SET (ic) && isOperandEqual (op, IC_RESULT (ic)))
+        continue;
+
       if (POINTER_GET (ic) && isOperandEqual (op, IC_LEFT (ic)))
         continue;
 
@@ -2351,11 +2367,9 @@ packRegsForHLUse3 (iCode * lic, operand * op, eBBlock * ebp)
       return NULL;
     }
 
-#if 0
-  printf("Succeeded!\n");
-#endif
-  OP_SYMBOL (op)->accuse = ACCUSE_SCRATCH;
+  D (D_PACK_HLUSE3, ("Succeeded!\n"))
 
+  OP_SYMBOL (op)->accuse = ACCUSE_SCRATCH;
   return dic;
 }
 
@@ -2367,10 +2381,9 @@ packRegsForIYUse (iCode * lic, operand * op, eBBlock * ebp)
   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
+  D (D_PACK_IY, ("Checking IY on %p lic key %u first def %u line %u:\n", OP_SYMBOL(op), lic->key, bitVectFirstBit(OP_DEFS(op)), lic->lineno));
+  if (D_PACK_IY)
+    piCode(lic, NULL);
 
   if ( OP_SYMBOL(op)->accuse)
     {
@@ -2423,10 +2436,8 @@ packRegsForIYUse (iCode * lic, operand * op, eBBlock * ebp)
   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 (D_PACK_IY)
+        piCode(ic, NULL);
 
       if (ic->op == PCALL || 
           ic->op == CALL ||
@@ -2437,13 +2448,32 @@ packRegsForIYUse (iCode * lic, operand * op, eBBlock * ebp)
       if (SKIP_IC2(ic))
         continue;
 
+      /* Be pessamistic. */
+      if (ic->op == IFX)
+        return NULL;
+
+      D (D_PACK_IY, ("  op: %u uses %u result: %d left: %d right: %d\n", ic->op, bitVectBitValue(uses, ic->key),
+                     IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) ? isOperandInDirSpace(IC_RESULT(ic)) : -1,
+                     IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) ? isOperandInDirSpace(IC_LEFT(ic)) : -1,
+                     IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) ? isOperandInDirSpace(IC_RIGHT(ic)) : -1
+                     ));
+
+      if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && 
+          isOperandInDirSpace(IC_RESULT(ic)))
+        return NULL;
+      
+      if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && 
+          isOperandInDirSpace(IC_RIGHT(ic)))
+        return NULL;
+      
+      if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && 
+          isOperandInDirSpace(IC_LEFT(ic)))
+        return NULL;
+
       /* 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;
@@ -2470,23 +2500,8 @@ packRegsForIYUse (iCode * lic, operand * op, eBBlock * ebp)
         }
       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;
         }
 
@@ -2494,11 +2509,9 @@ packRegsForIYUse (iCode * lic, operand * op, eBBlock * ebp)
       return NULL;
     }
 
-#if 0
-  printf("Succeeded IY!\n");
-#endif
-  OP_SYMBOL (op)->accuse = ACCUSE_IY;
+  D (D_PACK_IY, ("Succeeded IY!\n"));
 
+  OP_SYMBOL (op)->accuse = ACCUSE_IY;
   return dic;
 }
 
@@ -2647,11 +2660,14 @@ packRegsForAccUse2 (iCode * ic)
   iCode *uic;
 
   D (D_ACCUSE2, ("packRegsForAccUse2: running on ic %p line %u\n", ic, ic->lineno));
+  if (D_ACCUSE2)
+    piCode (ic, NULL);
 
   /* Filter out all but those 'good' commands */
   if (
        !POINTER_GET (ic) &&
        ic->op != '+' &&
+       ic->op != '-' &&
        !IS_BITWISE_OP (ic) &&
        ic->op != '=' &&
        ic->op != EQ_OP &&
@@ -2902,7 +2918,7 @@ packRegisters (eBBlock * ebp)
             packRegsForHLUse3 (ic, IC_RESULT (ic), ebp);
        }
 
-      if (!DISABLE_PACK_HL && IS_ITEMP (IC_RESULT (ic)) && IS_Z80)
+      if (!DISABLE_PACK_IY && IS_ITEMP (IC_RESULT (ic)) && IS_Z80)
        {
           packRegsForIYUse (ic, IC_RESULT (ic), ebp);
        }