* as/hc08/lkaomf51.c (OutputName): made name unsigned char,
[fw/sdcc] / src / z80 / gen.c
index f9a678e917ea0af0ebe5140c5af892288252701e..72d5726683ebcc6742b85efb135b77742e0331a3 100644 (file)
@@ -221,7 +221,8 @@ static struct
   bool in_home;
   const char *lastFunctionName;
   iCode *current_iCode;
-
+  bool preserveCarry;
+  
   set *sendSet;
 
   struct
@@ -235,6 +236,7 @@ static struct
     lineNode *head;
     lineNode *current;
     int isInline;
+    int isDebug;
     allocTrace trace;
   } lines;
 
@@ -409,6 +411,7 @@ _vemit2 (const char *szFormat, va_list ap)
              (_G.lines.head = _newLineNode (buffer)));
 
   _G.lines.current->isInline = _G.lines.isInline;
+  _G.lines.current->isDebug = _G.lines.isDebug;
   _G.lines.current->ic = _G.current_iCode;
 }
 
@@ -439,6 +442,19 @@ emitDebug (const char *szFormat,...)
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* z80_emitDebuggerSymbol - associate the current code location    */
+/*   with a debugger symbol                                        */
+/*-----------------------------------------------------------------*/
+void
+z80_emitDebuggerSymbol (char * debugSym)
+{
+  _G.lines.isDebug = 1;
+  emit2 ("%s !equ .", debugSym);
+  emit2 ("!global", debugSym);
+  _G.lines.isDebug = 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* emit2 - writes the code into a file : for now it is simple    */
 /*-----------------------------------------------------------------*/
@@ -447,7 +463,7 @@ _emit2 (const char *inst, const char *fmt,...)
 {
   va_list ap;
   char lb[INITIAL_INLINEASM];
-  char *lbp = lb;
+  unsigned char *lbp = lb;
 
   va_start (ap, fmt);
 
@@ -787,18 +803,34 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool requires_a)
       return aop;
     }
 
-  if (IS_GB)
+  if( IN_REGSP( space ))
+  { /*.p.t.20030716 minor restructure to add SFR support to the Z80 */
+    if (IS_GB)
     {
       /* if it is in direct space */
-      if (IN_REGSP (space) && !requires_a)
-       {
-         sym->aop = aop = newAsmop (AOP_SFR);
-         aop->aopu.aop_dir = sym->rname;
-         aop->size = getSize (sym->type);
+      if( !requires_a )
+      {
+        sym->aop = aop = newAsmop (AOP_SFR);
+        aop->aopu.aop_dir = sym->rname;
+        aop->size = getSize (sym->type);
          emitDebug ("; AOP_SFR for %s", sym->rname);
-         return aop;
-       }
+        return aop;
+      }
+    }
+    else
+    { /*.p.t.20030716 adding SFR support to the Z80 port */
+      aop = newAsmop (AOP_SFR);
+      sym->aop          = aop;
+      aop->aopu.aop_dir = sym->rname;
+      aop->size         = getSize( sym->type );
+      aop->paged        = FUNC_REGBANK(sym->type);
+      aop->bcInUse      = isPairInUse( PAIR_BC, ic );
+      aop->deInUse      = isPairInUse( PAIR_DE, ic );
+      emitDebug( ";Z80 AOP_SFR for %s banked:%d bc:%d de:%d", sym->rname, FUNC_REGBANK(sym->type), aop->bcInUse, aop->deInUse );
+
+      return( aop );
     }
+  }
 
   /* only remaining is far space */
   /* in which case DPTR gets the address */
@@ -915,10 +947,10 @@ operandsEqu (operand * op1, operand * op2)
   if (sym1 == sym2)
     return 1;
 
-  if (strcmp (sym1->rname, sym2->rname) == 0)
+  if (sym1->rname[0] && sym2->rname[0]
+      && strcmp (sym1->rname, sym2->rname) == 0)
     return 2;
 
-
   /* if left is a tmp & right is not */
   if (IS_ITEMP (op1) &&
       !IS_ITEMP (op2) &&
@@ -991,6 +1023,11 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a)
   /* if already has a asmop then continue */
   if (op->aop)
     {
+      if (op->aop->type == AOP_SFR)
+        {
+          op->aop->bcInUse = isPairInUse( PAIR_BC, ic );
+          op->aop->deInUse = isPairInUse( PAIR_DE, ic );
+        }
       return;
     }
 
@@ -998,6 +1035,11 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a)
   if (IS_SYMOP (op) && OP_SYMBOL (op)->aop)
     {
       op->aop = OP_SYMBOL (op)->aop;
+      if (op->aop->type == AOP_SFR)
+        {
+          op->aop->bcInUse = isPairInUse( PAIR_BC, ic );
+          op->aop->deInUse = isPairInUse( PAIR_DE, ic );
+        }
       return;
     }
 
@@ -1479,6 +1521,12 @@ setupPairFromSP (PAIR_ID id, int offset)
 {
   wassertl (id == PAIR_HL, "Setup relative to SP only implemented for HL");
 
+  if (_G.preserveCarry)
+    {
+      _push (PAIR_AF);
+      offset += 2;
+    }
+  
   if (offset < INT8MIN || offset > INT8MAX)
     {
       emit2 ("ld hl,!immedword", offset);
@@ -1486,7 +1534,13 @@ setupPairFromSP (PAIR_ID id, int offset)
     }
   else
     {
-      emit2 ("!ldahlsp", offset);
+          emit2 ("!ldahlsp", offset);
+    }
+
+  if (_G.preserveCarry)
+    {
+      _pop (PAIR_AF);
+      offset -= 2;
     }
 }
 
@@ -1522,11 +1576,15 @@ setupPair (PAIR_ID pairId, asmop * aop, int offset)
         else
           {
             /* PENDING: Do this better. */
+            if (_G.preserveCarry)
+              _push (PAIR_AF);
             sprintf (buffer, "%d", offset + _G.stack.pushed);
             emit2 ("ld %s,!hashedstr", _pairs[pairId].name, buffer);
             emit2 ("add %s,sp", _pairs[pairId].name);
             _G.pairs[pairId].last_type = aop->type;
             _G.pairs[pairId].offset = offset;
+            if (_G.preserveCarry)
+              _pop (PAIR_AF);
           }
       }
       break;
@@ -1627,11 +1685,35 @@ aopGet (asmop * aop, int offset, bool bit16)
       return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_SFR:
-      wassert (IS_GB);
-      emit2 ("ldh a,(%s+%d)", aop->aopu.aop_dir, offset);
-      SNPRINTF (buffer, sizeof(buffer), "a");
+      if( IS_GB )
+      {
+        // wassert (IS_GB);
+        emit2 ("ldh a,(%s+%d)", aop->aopu.aop_dir, offset);
+        SNPRINTF (buffer, sizeof(buffer), "a");
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
+        return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
+      }
+      else
+      { /*.p.t.20030716 handling for i/o port read access for Z80 */
+        if( aop->paged )
+        { /* banked mode */
+         /* reg A goes to address bits 15-8 during "in a,(x)" instruction */
+         emit2( "ld a,!msbimmeds", aop->aopu.aop_dir);
+         emit2( "in a,(!lsbimmeds)", aop->aopu.aop_dir);
+        }
+        else if( z80_opts.port_mode == 180 )
+        { /* z180 in0/out0 mode */
+          emit2( "in0 a,(%s)", aop->aopu.aop_dir );
+        }
+        else
+        { /* 8 bit mode */
+          emit2( "in a,(%s)", aop->aopu.aop_dir );
+        }
+        
+        SNPRINTF (buffer, sizeof(buffer), "a");
+
+        return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
+      }
 
     case AOP_REG:
       return aop->aopu.aop_reg[offset]->name;
@@ -1796,10 +1878,47 @@ aopPut (asmop * aop, const char *s, int offset)
       break;
 
     case AOP_SFR:
-      wassert (IS_GB);
-      if (strcmp (s, "a"))
-       emit2 ("ld a,%s", s);
-      emit2 ("ldh (%s+%d),a", aop->aopu.aop_dir, offset);
+      if( IS_GB )
+        {
+          //  wassert (IS_GB);
+          if (strcmp (s, "a"))
+            emit2 ("ld a,%s", s);
+          emit2 ("ldh (%s+%d),a", aop->aopu.aop_dir, offset);
+        }
+      else
+        { /*.p.t.20030716 handling for i/o port read access for Z80 */
+          if (aop->paged)
+            { /* banked mode */
+              if (aop->bcInUse)
+                emit2( "push bc" );
+
+              if (strlen(s) != 1
+                  || (s[0] != 'a' && s[0] != 'd' && s[0] != 'e'
+                      && s[0] != 'h' && s[0] != 'l'))
+                {
+                  emit2( "ld a,%s", s );
+                  s = "a";
+                }
+              
+              emit2( "ld bc,#%s", aop->aopu.aop_dir );
+              emit2( "out (c),%s", s );
+        
+              if( aop->bcInUse )
+                emit2( "pop bc"    );
+              else
+                spillPair (PAIR_BC);
+            }
+          else if( z80_opts.port_mode == 180 )
+            { /* z180 in0/out0 mode */
+              emit2( "ld a,%s", s );
+              emit2( "out0 (%s),a", aop->aopu.aop_dir );
+            }
+          else
+            { /* 8 bit mode */
+              emit2( "ld a,%s", s );
+              emit2( "out (%s),a", aop->aopu.aop_dir );
+            }
+        }
       break;
 
     case AOP_REG:
@@ -1955,7 +2074,7 @@ aopPut (asmop * aop, const char *s, int offset)
 #define AOP(op) op->aop
 #define AOP_TYPE(op) AOP(op)->type
 #define AOP_SIZE(op) AOP(op)->size
-#define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY))
+#define AOP_NEEDSACC(x) (AOP(x) && ((AOP_TYPE(x) == AOP_CRY) || (AOP_TYPE(x) == AOP_SFR)))
 
 static void
 commitPair (asmop * aop, PAIR_ID id)
@@ -2276,7 +2395,7 @@ genUminusFloat (operand * op, operand * result)
   emitDebug("; genUminusFloat");
 
   /* for this we just need to flip the
-     first it then copy the rest in place */
+     first bit then copy the rest in place */
   size = AOP_SIZE (op) - 1;
 
   _moveA(aopGet (AOP (op), MSB32, FALSE));
@@ -2795,7 +2914,7 @@ emitCall (iCode * ic, bool ispcall)
     }
   spillCached ();
 
-  /* Mark the regsiters as restored. */
+  /* Mark the registers as restored. */
   _G.saves.saved = FALSE;
 
   /* if we need assign a result value */
@@ -2981,8 +3100,11 @@ genFunction (iCode * ic)
   
   /* Create the function header */
   emit2 ("!functionheader", sym->name);
-  sprintf (buffer, "%s_start", sym->rname);
-  emit2 ("!labeldef", buffer);
+  if (!IS_STATIC(sym->etype))
+    {
+      sprintf (buffer, "%s_start", sym->rname);
+      emit2 ("!labeldef", buffer);
+    }
   emit2 ("!functionlabeldef", sym->rname);
 
   if (options.profile) 
@@ -2992,14 +3114,21 @@ genFunction (iCode * ic)
 
   ftype = operandType (IC_LEFT (ic));
 
-  /* if critical function then turn interrupts off */
-  if (IFFUNC_ISCRITICAL (ftype))
-    emit2 ("!di");
-
   /* if this is an interrupt service routine then save all potentially used registers. */
   if (IFFUNC_ISISR (sym->type))
     {
-      emit2 ("!pusha");
+      if (!FUNC_ISNAKED( sym->type ))
+        {
+          emit2 ("!pusha");
+       }
+    }
+  else
+    {
+      /* if critical function then turn interrupts off */
+      if (IFFUNC_ISCRITICAL (sym->type))
+        {
+          emit2 ("!di");
+       }
     }
 
   /* PENDING: callee-save etc */
@@ -3083,8 +3212,9 @@ genFunction (iCode * ic)
     emit2 ("!enterxl", sym->stack);
   else if (sym->stack)
     emit2 ("!enterx", sym->stack);
-  else
+  else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */
     emit2 ("!enter");
+
   _G.stack.offset = sym->stack;
 }
 
@@ -3096,59 +3226,83 @@ genEndFunction (iCode * ic)
 {
   symbol *sym = OP_SYMBOL (IC_LEFT (ic));
 
-  if (IFFUNC_ISISR (sym->type))
+
+  /* PENDING: calleeSave */
+  if (IS_Z80 && _G.omitFramePtr)
     {
-      wassertl (0, "Tried to close an interrupt support function");
+      if (_G.stack.offset)
+        emit2 ("!ldaspsp", _G.stack.offset);
     }
-  else
+  else if (_G.stack.offset && IS_GB && _G.stack.offset > INT8MAX)
     {
-      if (IFFUNC_ISCRITICAL (sym->type))
-       emit2 ("!ei");
-
-      /* PENDING: calleeSave */
-
-      if (IS_Z80 && _G.omitFramePtr)
-        {
-          if (_G.stack.offset)
-            emit2 ("!ldaspsp", _G.stack.offset);
-        }
-      else if (_G.stack.offset && IS_GB && _G.stack.offset > INT8MAX)
-        {
-          emit2 ("!leavexl", _G.stack.offset);
-        }
-      else if (_G.stack.offset)
-        {
-          emit2 ("!leavex", _G.stack.offset);
-        }
-      else
-        {
-          emit2 ("!leave");
-        }
+      emit2 ("!leavexl", _G.stack.offset);
+    }
+  else if (_G.stack.offset)
+    {
+      emit2 ("!leavex", _G.stack.offset);
+    }
+  else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */
+    {
+      emit2 ("!leave");
+    }
+      
+  if (_G.calleeSaves.pushedDE) 
+    {
+      emit2 ("pop de");
+      _G.calleeSaves.pushedDE = FALSE;
+    }
 
-      if (_G.calleeSaves.pushedDE
-        {
-          emit2 ("pop de");
-          _G.calleeSaves.pushedDE = FALSE;
-        }
+  if (_G.calleeSaves.pushedBC
+    {
+      emit2 ("pop bc");
+      _G.calleeSaves.pushedBC = FALSE;
+    }
 
-      if (_G.calleeSaves.pushedBC) 
-        {
-          emit2 ("pop bc");
-          _G.calleeSaves.pushedBC = FALSE;
-        }
+  if (options.profile) 
+    {
+      emit2 ("!profileexit");
+    }
 
-      if (options.profile) 
+  /* if this is an interrupt service routine then restore all potentially used registers. */
+  if (IFFUNC_ISISR (sym->type))
+    {
+      if (!FUNC_ISNAKED( sym->type ))
         {
-          emit2 ("!profileexit");
+          emit2 ("!popa");
         }
+    }
+  else
+    {
+      /* if critical function then turn interrupts back on */
+      if (IFFUNC_ISCRITICAL (sym->type))
+        emit2 ("!ei");
+    }
 
-
-      /* Both baned and non-banked just ret */
+  if (options.debug && currFunc)
+    {
+      debugFile->writeEndFunction (currFunc, ic, 1);
+    }
+      
+  if (IFFUNC_ISISR (sym->type))
+    {
+      /* "critical interrupt" is used to imply NMI handler */
+      if (IS_Z80 && IFFUNC_ISCRITICAL (sym->type))
+        emit2 ("retn");
+      else
+        emit2 ("reti");
+    }
+  else
+    {
+      /* Both banked and non-banked just ret */
       emit2 ("ret");
-
+    }
+      
+  if (!IS_STATIC(sym->etype))
+    {
       sprintf (buffer, "%s_end", sym->rname);
       emit2 ("!labeldef", buffer);
     }
+  
   _G.flushStatics = 1;
   _G.stack.pushed = 0;
   _G.stack.offset = 0;
@@ -3464,7 +3618,10 @@ setupToPreserveCarry (asmop *result, asmop *left, asmop *right)
         }
       else if (couldDestroyCarry (right))
         {
-          shiftIntoPair (0, right);
+          if (getPairId (result) == PAIR_HL)
+            _G.preserveCarry = TRUE;
+          else
+            shiftIntoPair (0, right);
         }
       else if (couldDestroyCarry (result))
         {
@@ -3498,7 +3655,7 @@ genPlus (iCode * ic)
      in ACC */
 
   if ((AOP_TYPE (IC_LEFT (ic)) == AOP_LIT) ||
-      (AOP_NEEDSACC (IC_LEFT (ic))) ||
+      (AOP_NEEDSACC (IC_RIGHT (ic))) ||
       AOP_TYPE (IC_RIGHT (ic)) == AOP_ACC)
     {
       operand *t = IC_RIGHT (ic);
@@ -3695,6 +3852,7 @@ genPlus (iCode * ic)
     }
 
 release:
+  _G.preserveCarry = FALSE;
   freeAsmop (IC_LEFT (ic), NULL, ic);
   freeAsmop (IC_RIGHT (ic), NULL, ic);
   freeAsmop (IC_RESULT (ic), NULL, ic);
@@ -3898,6 +4056,7 @@ genMinus (iCode * ic)
     }
 
 release:
+  _G.preserveCarry = FALSE;
   freeAsmop (IC_LEFT (ic), NULL, ic);
   freeAsmop (IC_RIGHT (ic), NULL, ic);
   freeAsmop (IC_RESULT (ic), NULL, ic);
@@ -3913,11 +4072,14 @@ genMult (iCode * ic)
   int count, i;
   /* If true then the final operation should be a subtract */
   bool active = FALSE;
+  bool byteResult;
 
   /* Shouldn't occur - all done through function calls */
   aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
   aopOp (IC_RIGHT (ic), ic, FALSE, FALSE);
   aopOp (IC_RESULT (ic), ic, TRUE, FALSE);
+  
+  byteResult =  (AOP_SIZE (IC_RESULT (ic)) == 1);
 
   if (AOP_SIZE (IC_LEFT (ic)) > 2 ||
       AOP_SIZE (IC_RIGHT (ic)) > 2 ||
@@ -3948,10 +4110,13 @@ genMult (iCode * ic)
   if ( AOP_SIZE (IC_LEFT (ic)) == 1 && !SPEC_USIGN (getSpec (operandType ( IC_LEFT (ic)))))
     {
       emit2 ("ld e,%s", aopGet (AOP (IC_LEFT (ic)), LSB, FALSE));
-      emit2 ("ld a,e");
-      emit2 ("rlc a");
-      emit2 ("sbc a,a");
-      emit2 ("ld d,a");
+      if (!byteResult)
+        {
+          emit2 ("ld a,e");
+          emit2 ("rlc a");
+          emit2 ("sbc a,a");
+          emit2 ("ld d,a");
+       }
     }
   else
     {
@@ -3973,7 +4138,8 @@ genMult (iCode * ic)
           if (active == FALSE)
             {
               emit2 ("ld l,e");
-              emit2 ("ld h,d");
+              if (!byteResult)
+               emit2 ("ld h,d");
             }
           else
             {
@@ -3992,7 +4158,10 @@ genMult (iCode * ic)
       _G.stack.pushedDE = FALSE;
     }
 
-  commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
+  if (byteResult)
+    aopPut (AOP (IC_RESULT (ic)), _pairs[PAIR_HL].l, 0);
+  else
+    commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
 
   freeAsmop (IC_LEFT (ic), NULL, ic);
   freeAsmop (IC_RIGHT (ic), NULL, ic);
@@ -4862,7 +5031,7 @@ genAnd (iCode * ic, iCode * ifx)
 
   /* 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))
+      (AOP_NEEDSACC (right) && !AOP_NEEDSACC (left)))
     {
       operand *tmp = right;
       right = left;
@@ -5052,7 +5221,7 @@ genOr (iCode * ic, iCode * ifx)
 
   /* 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))
+      (AOP_NEEDSACC (right) && !AOP_NEEDSACC (left)))
     {
       operand *tmp = right;
       right = left;
@@ -5210,7 +5379,7 @@ genXor (iCode * ic, iCode * ifx)
 
   /* 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))
+      (AOP_NEEDSACC (right) && !AOP_NEEDSACC (left)))
     {
       operand *tmp = right;
       right = left;
@@ -5287,9 +5456,9 @@ genXor (iCode * ic, iCode * ifx)
                continue;
              else
                {
-                 _moveA (aopGet (AOP (right), offset, FALSE));
+                 _moveA (aopGet (AOP (left), offset, FALSE));
                  emit2 ("xor a,%s",
-                           aopGet (AOP (left), offset, FALSE));
+                           aopGet (AOP (right), offset, FALSE));
                  aopPut (AOP (result), "a", offset);
                }
            }
@@ -5301,9 +5470,9 @@ genXor (iCode * ic, iCode * ifx)
                 }
              else
                {
-                 _moveA (aopGet (AOP (right), offset, FALSE));
+                 _moveA (aopGet (AOP (left), offset, FALSE));
                  emit2 ("xor a,%s",
-                           aopGet (AOP (left), offset, FALSE));
+                           aopGet (AOP (right), offset, FALSE));
                  aopPut (AOP (result), "a", offset);
                }
            }
@@ -5339,9 +5508,9 @@ genXor (iCode * ic, iCode * ifx)
               }
            else
              {
-               _moveA (aopGet (AOP (right), offset, FALSE));
+               _moveA (aopGet (AOP (left), offset, FALSE));
                emit2 ("xor a,%s",
-                         aopGet (AOP (left), offset, FALSE));
+                         aopGet (AOP (right), offset, FALSE));
              }
            aopPut (AOP (result), "a", offset);
          }
@@ -5872,6 +6041,9 @@ genLeftShift (iCode * ic)
   aopOp (left, ic, FALSE, FALSE);
   aopOp (result, ic, FALSE, FALSE);
 
+  if (AOP_TYPE (left) != AOP_REG || AOP_TYPE (result) != AOP_REG)
+     _push (PAIR_AF);
+  
   /* now move the left to the result if they are not the
      same */
 
@@ -5893,6 +6065,9 @@ genLeftShift (iCode * ic)
   offset = 0;
   tlbl1 = newiTempLabel (NULL);
 
+  if (AOP_TYPE (left) != AOP_REG || AOP_TYPE (result) != AOP_REG)
+     _pop (PAIR_AF);
+  
   emit2 ("!shortjp !tlabel", tlbl1->key + 100);
   emitLabel (tlbl->key + 100);
   l = aopGet (AOP (result), offset, FALSE);
@@ -6146,6 +6321,9 @@ genRightShift (iCode * ic)
   aopOp (left, ic, FALSE, FALSE);
   aopOp (result, ic, FALSE, FALSE);
 
+  if (AOP_TYPE (left) != AOP_REG || AOP_TYPE (result) != AOP_REG)
+     _push (PAIR_AF);
+  
   /* now move the left to the result if they are not the
      same */
   if (!sameRegs (AOP (left), AOP (result)))
@@ -6165,6 +6343,9 @@ genRightShift (iCode * ic)
   tlbl1 = newiTempLabel (NULL);
   size = AOP_SIZE (result);
   offset = size - 1;
+  
+  if (AOP_TYPE (left) != AOP_REG || AOP_TYPE (result) != AOP_REG)
+     _pop (PAIR_AF);
 
   emit2 ("!shortjp !tlabel", tlbl1->key + 100);
   emitLabel (tlbl->key + 100);
@@ -6673,7 +6854,7 @@ genGenPointerSet (operand * right,
     {
       fetchPair (pairId, AOP (result));
     }
-  /* so hl know contains the address */
+  /* so hl now contains the address */
   freeAsmop (result, NULL, ic);
 
   /* if bit then unpack */
@@ -7116,23 +7297,44 @@ genReceive (iCode * ic)
 static void
 genDummyRead (iCode * ic)
 {
-  operand *right;
+  operand *op;
   int size, offset;
 
-  right = IC_RIGHT (ic);
-  aopOp (right, ic, FALSE, FALSE);
+  op = IC_RIGHT (ic);
+  if (op && IS_SYMOP (op))
+    {
+      aopOp (op, ic, FALSE, FALSE);
   
-  /* general case */
-  size = AOP_SIZE (right);
-  offset = 0;
+      /* general case */
+      size = AOP_SIZE (op);
+      offset = 0;
 
-  while (size--)
-    {
-      _moveA (aopGet (AOP (right), offset, FALSE));
-      offset++;
+      while (size--)
+       {
+         _moveA (aopGet (AOP (op), offset, FALSE));
+         offset++;
+       }
+
+      freeAsmop (op, NULL, ic);
     }
+  
+  op = IC_LEFT (ic);
+  if (op && IS_SYMOP (op))
+    {
+      aopOp (op, ic, FALSE, FALSE);
+  
+      /* general case */
+      size = AOP_SIZE (op);
+      offset = 0;
 
-  freeAsmop (right, NULL, ic);
+      while (size--)
+       {
+         _moveA (aopGet (AOP (op), offset, FALSE));
+         offset++;
+       }
+
+      freeAsmop (op, NULL, ic);
+    }
 }
 
 enum
@@ -7245,7 +7447,7 @@ _rleCommit(RLECTX *self)
     chunks.
 */
 static void
-_rleAppend(RLECTX *self, int c)
+_rleAppend(RLECTX *self, unsigned c)
 {
   int i;
 
@@ -7328,13 +7530,27 @@ genArrayInit (iCode * ic)
     
   if (type && type->next)
     {
-      elementSize = getSize(type->next);
+      if (IS_SPEC(type->next) || IS_PTR(type->next))
+        {
+          elementSize = getSize(type->next);
+        }
+      else if (IS_ARRAY(type->next) && type->next->next)
+        {
+          elementSize = getSize(type->next->next);
+        }
+      else
+        {
+         printTypeChainRaw (type, NULL);
+          wassertl (0, "Can't determine element size in genArrayInit.");
+        }
     }
   else
     {
       wassertl (0, "Can't determine element size in genArrayInit.");
     }
 
+  wassertl ((elementSize > 0) && (elementSize <= 4), "Illegal element size in genArrayInit.");
+
   iLoop = IC_ARRAYILIST(ic);
   lastVal = (unsigned)-1;
 
@@ -7347,17 +7563,14 @@ genArrayInit (iCode * ic)
     {
       ix = iLoop->count;
 
-      if (ix != 0)
+      for (i = 0; i < ix; i++)
         {
-          for (i = 0; i < ix; i++)
+          for (eIndex = 0; eIndex < elementSize; eIndex++)
             {
-              for (eIndex = 0; eIndex < elementSize; eIndex++)
-                {
-                  val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff;
-                  _rleAppend(&rle, val);
-                }
+              val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff;
+              _rleAppend(&rle, val);
             }
-       }
+        }
        
       iLoop = iLoop->next;
     }
@@ -7671,13 +7884,23 @@ genZ80Code (iCode * lic)
     }
 
   _G.lines.head = _G.lines.current = NULL;
+  
+  /* if debug information required */
+  if (options.debug && currFunc)
+    {
+      debugFile->writeFunction (currFunc, lic);
+    }
 
   for (ic = lic; ic; ic = ic->next)
     {
       _G.current_iCode = ic;
 
-      if (cln != ic->lineno)
+      if (ic->lineno && cln != ic->lineno)
        {
+         if (options.debug)
+           {
+             debugFile->writeCLine (ic);
+           }
          if (!options.noCcodeInAsm) {
            emit2 (";%s:%d: %s", ic->filename, ic->lineno,
                   printCLine(ic->filename, ic->lineno));