fixed Z80 port - crt0.o: cannot open.
[fw/sdcc] / src / z80 / gen.c
index ee1ddaad71e88253258135f64ec117fb261f6337..b5f0afc975a66fb4c0b35702e14f32b4d27bac53 100644 (file)
@@ -60,7 +60,9 @@
   9. With asm optimised strings                17030 192 2223
 
   10 and below are with asm strings off.
   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 
   Apparent advantage of turning on regparams:
   1.  Cost of push
         Decent case is push of a constant 
 #include <string.h>
 #include <ctype.h>
 
 #include <string.h>
 #include <ctype.h>
 
-#ifdef HAVE_SYS_ISA_DEFS_H
-#include <sys/isa_defs.h>
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
 #endif
 
 #include "z80.h"
 #endif
 
 #include "z80.h"
@@ -203,6 +207,13 @@ static struct
     int pushedBC;
     int pushedDE;
   } stack;
     int pushedBC;
     int pushedDE;
   } stack;
+
+  struct
+  {
+    int pushedBC;
+    int pushedDE;
+  } calleeSaves;
+
   int frameId;
   int receiveOffset;
   bool flushStatics;
   int frameId;
   int receiveOffset;
   bool flushStatics;
@@ -252,6 +263,30 @@ static const char *aopNames[] = {
   "AOP_PAIRPT"
 };
 
   "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)
 {
 static PAIR_ID
 _getTempPairId(void)
 {
@@ -271,14 +306,50 @@ _getTempPairName(void)
   return _pairs[_getTempPairId()].name;
 }
 
   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)
 {
 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;
     }
     {
       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;
     }
     {
       return PAIR_DE;
     }
@@ -327,7 +398,7 @@ _vemit2 (const char *szFormat, va_list ap)
 {
   char buffer[256];
 
 {
   char buffer[256];
 
-  tvsprintf (buffer, szFormat, ap);
+  tvsprintf (buffer, sizeof(buffer), szFormat, ap);
 
   _tidyUp (buffer);
   _G.lines.current = (_G.lines.current ?
 
   _tidyUp (buffer);
   _G.lines.current = (_G.lines.current ?
@@ -400,7 +471,7 @@ _emit2 (const char *inst, const char *fmt,...)
 static void
 _emitMove(const char *to, const char *from)
 {
 static void
 _emitMove(const char *to, const char *from)
 {
-  if (strcasecmp(to, from) != 0) 
+  if (STRCASECMP(to, from) != 0) 
     {
       emit2("ld %s,%s", to, from);
     }
     {
       emit2("ld %s,%s", to, from);
     }
@@ -411,7 +482,7 @@ _emitMove(const char *to, const char *from)
     }
 }
 
     }
 }
 
-static void
+void
 aopDump(const char *plabel, asmop *aop)
 {
   emitDebug("; Dump of %s: type %s size %u", plabel, aopNames[aop->type], aop->size);
 aopDump(const char *plabel, asmop *aop)
 {
   emitDebug("; Dump of %s: type %s size %u", plabel, aopNames[aop->type], aop->size);
@@ -422,6 +493,7 @@ aopDump(const char *plabel, asmop *aop)
       break;
     default:
       /* No information. */
       break;
     default:
       /* No information. */
+      break;
     }
 }
 
     }
 }
 
@@ -920,12 +992,14 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a)
        }
 
       /* else spill location  */
        }
 
       /* else spill location  */
-      op->aop = aop =
+      if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
+         /* force a new aop if sizes differ */
+         sym->usl.spillLoc->aop = NULL;
+      }
+      sym->aop = op->aop = aop =
        aopForSym (ic, sym->usl.spillLoc, result, requires_a);
       wassertl (aop->size >= getSize (sym->type), "Operand doesn't fit in the spill location");
       aop->size = getSize (sym->type);
        aopForSym (ic, sym->usl.spillLoc, result, requires_a);
       wassertl (aop->size >= getSize (sym->type), "Operand doesn't fit in the spill location");
       aop->size = getSize (sym->type);
-      /* PENDING: HACK.  Can have different sizes in the same AOP. */
-      sym->usl.spillLoc->aop = NULL;
       return;
     }
 
       return;
     }
 
@@ -962,6 +1036,11 @@ freeAsmop (operand * op, asmop * aaop, iCode * ic)
       _pop (aop->aopu.aop_pairId);
     }
 
       _pop (aop->aopu.aop_pairId);
     }
 
+  if (getPairId (aop) == PAIR_HL)
+    {
+      spillPair (PAIR_HL);
+    }
+
 dealloc:
   /* all other cases just dealloc */
   if (op)
 dealloc:
   /* all other cases just dealloc */
   if (op)
@@ -996,8 +1075,6 @@ isLitWord (asmop * aop)
 char *
 aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
 {
 char *
 aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
 {
-  char *s = buffer;
-
   /* depending on type */
   switch (aop->type)
     {
   /* depending on type */
   switch (aop->type)
     {
@@ -1007,17 +1084,20 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
       /* PENDING: for re-target */
       if (with_hash)
         {
       /* PENDING: for re-target */
       if (with_hash)
         {
-          tsprintf (s, "!hashedstr + %d", aop->aopu.aop_immd, offset);
+          tsprintf (buffer, sizeof(buffer), 
+                   "!hashedstr + %d", aop->aopu.aop_immd, offset);
         }
       else if (offset == 0)
         {
         }
       else if (offset == 0)
         {
-          tsprintf (s, "%s", aop->aopu.aop_immd);
+          tsprintf (buffer, sizeof(buffer),
+                   "%s", aop->aopu.aop_immd);
         }
       else
         {
         }
       else
         {
-          tsprintf (s, "%s + %d", aop->aopu.aop_immd, offset);
+          tsprintf (buffer, sizeof(buffer), 
+                   "%s + %d", aop->aopu.aop_immd, offset);
         }
         }
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_LIT:
       {
 
     case AOP_LIT:
       {
@@ -1042,9 +1122,9 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
               }
 
            if (with_hash)
               }
 
            if (with_hash)
-             tsprintf (buffer, "!immedword", v);
+             tsprintf (buffer, sizeof(buffer), "!immedword", v);
            else
            else
-             tsprintf (buffer, "!constword", v);
+             tsprintf (buffer, sizeof(buffer), "!constword", v);
 
             return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
          }
 
             return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
          }
@@ -1060,15 +1140,15 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
             /* it is type float */
             fl.f = (float) floatFromVal (val);
 
             /* it is type float */
             fl.f = (float) floatFromVal (val);
 
-#ifdef _BIG_ENDIAN
+#ifdef WORDS_BIGENDIAN
             i = fl.c[3-offset] | (fl.c[3-offset-1]<<8);
 #else
             i = fl.c[offset] | (fl.c[offset+1]<<8);
 #endif
            if (with_hash)
             i = fl.c[3-offset] | (fl.c[3-offset-1]<<8);
 #else
             i = fl.c[offset] | (fl.c[offset+1]<<8);
 #endif
            if (with_hash)
-             tsprintf (buffer, "!immedword", i);
+             tsprintf (buffer, sizeof(buffer), "!immedword", i);
            else
            else
-             tsprintf (buffer, "!constword", i);
+             tsprintf (buffer, sizeof(buffer), "!constword", i);
 
             return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
          }
 
             return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
          }
@@ -1173,8 +1253,36 @@ fetchLitPair (PAIR_ID pairId, asmop * left, int offset)
   emit2 ("ld %s,!hashedstr", pair, l);
 }
 
   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
 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)) {
 {
     /* if this is remateriazable */
     if (isLitWord (aop)) {
@@ -1226,19 +1334,24 @@ fetchPairLong (PAIR_ID pairId, asmop * aop, int offset)
               }
             else
               {
               }
             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. */
                 /* 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");
                 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));
             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);
         /* PENDING: check? */
         if (pairId == PAIR_HL)
             spillPair (PAIR_HL);
@@ -1248,7 +1361,7 @@ fetchPairLong (PAIR_ID pairId, asmop * aop, int offset)
 static void
 fetchPair (PAIR_ID pairId, asmop * aop)
 {
 static void
 fetchPair (PAIR_ID pairId, asmop * aop)
 {
-  fetchPairLong (pairId, aop, 0);
+  fetchPairLong (pairId, aop, NULL, 0);
 }
 
 static void
 }
 
 static void
@@ -1360,15 +1473,15 @@ emitLabel (int key)
 static const char *
 aopGet (asmop * aop, int offset, bool bit16)
 {
 static const char *
 aopGet (asmop * aop, int offset, bool bit16)
 {
-  char *s = buffer;
+  // char *s = buffer;
 
   /* offset is greater than size then zero */
   /* PENDING: this seems a bit screwed in some pointer cases. */
   if (offset > (aop->size - 1) &&
       aop->type != AOP_LIT) 
     {
 
   /* offset is greater than size then zero */
   /* PENDING: this seems a bit screwed in some pointer cases. */
   if (offset > (aop->size - 1) &&
       aop->type != AOP_LIT) 
     {
-      tsprintf (s, "!zero");
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      tsprintf (buffer, sizeof(buffer), "!zero");
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
     }
 
   /* depending on type */
     }
 
   /* depending on type */
@@ -1377,38 +1490,38 @@ aopGet (asmop * aop, int offset, bool bit16)
     case AOP_IMMD:
       /* PENDING: re-target */
       if (bit16)
     case AOP_IMMD:
       /* PENDING: re-target */
       if (bit16)
-       tsprintf (s, "!immedwords", aop->aopu.aop_immd);
+       tsprintf (buffer, sizeof(buffer), "!immedwords", aop->aopu.aop_immd);
       else
        switch (offset)
          {
          case 2:
       else
        switch (offset)
          {
          case 2:
-           tsprintf (s, "!bankimmeds", aop->aopu.aop_immd);
+           tsprintf (buffer, sizeof(buffer), "!bankimmeds", aop->aopu.aop_immd);
            break;
          case 1:
            break;
          case 1:
-           tsprintf (s, "!msbimmeds", aop->aopu.aop_immd);
+           tsprintf (buffer, sizeof(buffer), "!msbimmeds", aop->aopu.aop_immd);
            break;
          case 0:
            break;
          case 0:
-           tsprintf (s, "!lsbimmeds", aop->aopu.aop_immd);
+           tsprintf (buffer, sizeof(buffer), "!lsbimmeds", aop->aopu.aop_immd);
            break;
          default:
            wassertl (0, "Fetching from beyond the limits of an immediate value.");
          }
 
            break;
          default:
            wassertl (0, "Fetching from beyond the limits of an immediate value.");
          }
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_DIR:
       wassert (IS_GB);
       emit2 ("ld a,(%s+%d)", aop->aopu.aop_dir, offset);
 
     case AOP_DIR:
       wassert (IS_GB);
       emit2 ("ld a,(%s+%d)", aop->aopu.aop_dir, offset);
-      sprintf (s, "a");
+      SNPRINTF (buffer, sizeof(buffer), "a");
 
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_SFR:
       wassert (IS_GB);
       emit2 ("ldh a,(%s+%d)", aop->aopu.aop_dir, offset);
 
     case AOP_SFR:
       wassert (IS_GB);
       emit2 ("ldh a,(%s+%d)", aop->aopu.aop_dir, offset);
-      sprintf (s, "a");
+      SNPRINTF (buffer, sizeof(buffer), "a");
 
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_REG:
       return aop->aopu.aop_reg[offset]->name;
 
     case AOP_REG:
       return aop->aopu.aop_reg[offset]->name;
@@ -1416,38 +1529,39 @@ aopGet (asmop * aop, int offset, bool bit16)
     case AOP_HL:
       wassert (IS_GB);
       setupPair (PAIR_HL, aop, offset);
     case AOP_HL:
       wassert (IS_GB);
       setupPair (PAIR_HL, aop, offset);
-      tsprintf (s, "!*hl");
+      tsprintf (buffer, sizeof(buffer), "!*hl");
 
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup (s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup (buffer));
 
     case AOP_IY:
       wassert (IS_Z80);
       setupPair (PAIR_IY, aop, offset);
 
     case AOP_IY:
       wassert (IS_Z80);
       setupPair (PAIR_IY, aop, offset);
-      tsprintf (s, "!*iyx", offset);
+      tsprintf (buffer, sizeof(buffer), "!*iyx", offset);
 
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_EXSTK:
       wassert (IS_Z80);
       setupPair (PAIR_IY, aop, offset);
 
     case AOP_EXSTK:
       wassert (IS_Z80);
       setupPair (PAIR_IY, aop, offset);
-      tsprintf (s, "!*iyx", offset, offset);
+      tsprintf (buffer, sizeof(buffer), "!*iyx", offset, offset);
 
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_STK:
       if (IS_GB)
        {
          setupPair (PAIR_HL, aop, offset);
 
     case AOP_STK:
       if (IS_GB)
        {
          setupPair (PAIR_HL, aop, offset);
-         tsprintf (s, "!*hl");
+         tsprintf (buffer, sizeof(buffer), "!*hl");
        }
       else
        {
          if (aop->aopu.aop_stk >= 0)
            offset += _G.stack.param_offset;
        }
       else
        {
          if (aop->aopu.aop_stk >= 0)
            offset += _G.stack.param_offset;
-         tsprintf (s, "!*ixx", aop->aopu.aop_stk + offset);
+         tsprintf (buffer, sizeof(buffer),
+                   "!*ixx", aop->aopu.aop_stk + offset);
        }
 
        }
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_CRY:
       wassertl (0, "Tried to fetch from a bit variable");
 
     case AOP_CRY:
       wassertl (0, "Tried to fetch from a bit variable");
@@ -1459,8 +1573,8 @@ aopGet (asmop * aop, int offset, bool bit16)
        }
       else
         {
        }
       else
         {
-          tsprintf(s, "!zero");
-          return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+          tsprintf(buffer, sizeof(buffer), "!zero");
+          return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
         }
 
     case AOP_HLREG:
         }
 
     case AOP_HLREG:
@@ -1475,9 +1589,10 @@ aopGet (asmop * aop, int offset, bool bit16)
         unsigned long v = aop->aopu.aop_simplelit;
         
         v >>= (offset * 8);
         unsigned long v = aop->aopu.aop_simplelit;
         
         v >>= (offset * 8);
-        tsprintf (s, "!immedbyte", (unsigned int) v & 0xff);
+        tsprintf (buffer, sizeof(buffer), 
+                 "!immedbyte", (unsigned int) v & 0xff);
         
         
-        return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+        return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
       }
     case AOP_STR:
       aop->coff = offset;
       }
     case AOP_STR:
       aop->coff = offset;
@@ -1485,9 +1600,10 @@ aopGet (asmop * aop, int offset, bool bit16)
 
     case AOP_PAIRPTR:
       setupPair (aop->aopu.aop_pairId, aop, offset);
 
     case AOP_PAIRPTR:
       setupPair (aop->aopu.aop_pairId, aop, offset);
-      sprintf (s, "(%s)", _pairs[aop->aopu.aop_pairId].name);
+      SNPRINTF (buffer, sizeof(buffer), 
+               "(%s)", _pairs[aop->aopu.aop_pairId].name);
 
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     default:
       break;
 
     default:
       break;
@@ -1543,7 +1659,7 @@ aopPut (asmop * aop, const char *s, int offset)
     }
 
   // PENDING
     }
 
   // PENDING
-  tsprintf(buffer2, s);
+  tsprintf(buffer2, sizeof(buffer2), s);
   s = buffer2;
 
   /* will assign value to value */
   s = buffer2;
 
   /* will assign value to value */
@@ -1654,7 +1770,7 @@ aopPut (asmop * aop, const char *s, int offset)
       /* if bit variable */
       if (!aop->aopu.aop_dir)
        {
       /* if bit variable */
       if (!aop->aopu.aop_dir)
        {
-         emit2 ("ld a,#0");
+         emit2 ("ld a,!zero");
          emit2 ("rla");
        }
       else
          emit2 ("rla");
        }
       else
@@ -1801,6 +1917,7 @@ movLeft2ResultLong (operand * left, int offl,
           emit2 ("ld a,%s", aopGet (AOP (left), LSB, FALSE));
           emit2 ("ld h,%s", aopGet (AOP (left), MSB16, FALSE));
           emit2 ("ld l,a");
           emit2 ("ld a,%s", aopGet (AOP (left), LSB, FALSE));
           emit2 ("ld h,%s", aopGet (AOP (left), MSB16, FALSE));
           emit2 ("ld l,a");
+         spillPair (PAIR_HL);
         }
       else if ( getPairId ( AOP (result)) == PAIR_IY)
         {
         }
       else if ( getPairId ( AOP (result)) == PAIR_IY)
         {
@@ -2042,7 +2159,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);
 
   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);
   aopGet (right, MSB24, FALSE);
 
   _pop (PAIR_AF);
@@ -2331,11 +2448,11 @@ genIpush (iCode * ic)
        }
       if (size == 4)
        {
        }
       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;
          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;
          emit2 ("push hl");
          spillPair (PAIR_HL);
          _G.stack.pushed += 2;
@@ -2622,7 +2739,7 @@ emitCall (iCode * ic, bool ispcall)
          spillCached ();
          if (i > 8)
            {
          spillCached ();
          if (i > 8)
            {
-             emit2 ("ld iy,#%d", i);
+             emit2 ("ld iy,!immedword", i);
              emit2 ("add iy,sp");
              emit2 ("ld sp,iy");
            }
              emit2 ("add iy,sp");
              emit2 ("ld sp,iy");
            }
@@ -2750,10 +2867,8 @@ genFunction (iCode * ic)
   symbol *sym = OP_SYMBOL (IC_LEFT (ic));
   sym_link *ftype;
 
   symbol *sym = OP_SYMBOL (IC_LEFT (ic));
   sym_link *ftype;
 
-#if CALLEE_SAVES
   bool bcInUse = FALSE;
   bool deInUse = FALSE;
   bool bcInUse = FALSE;
   bool deInUse = FALSE;
-#endif
 
   setArea (IFFUNC_NONBANKED (sym->type));
 
 
   setArea (IFFUNC_NONBANKED (sym->type));
 
@@ -2767,8 +2882,8 @@ genFunction (iCode * ic)
   
   /* Create the function header */
   emit2 ("!functionheader", sym->name);
   
   /* Create the function header */
   emit2 ("!functionheader", sym->name);
-  /* PENDING: portability. */
-  emit2 ("__%s_start:", sym->rname);
+  sprintf (buffer, "%s_start", sym->rname);
+  emit2 ("!labeldef", buffer);
   emit2 ("!functionlabeldef", sym->rname);
 
   if (options.profile) 
   emit2 ("!functionlabeldef", sym->rname);
 
   if (options.profile) 
@@ -2792,9 +2907,13 @@ genFunction (iCode * ic)
 
   _G.stack.param_offset = 0;
 
 
   _G.stack.param_offset = 0;
 
-#if CALLEE_SAVES
+  if (z80_opts.calleeSavesBC)
+    {
+      bcInUse = TRUE;
+    }
+
   /* Detect which registers are used. */
   /* Detect which registers are used. */
-  if (sym->regsUsed)
+  if (IFFUNC_CALLEESAVES(sym->type) && sym->regsUsed)
     {
       int i;
       for (i = 0; i < sym->regsUsed->size; i++)
     {
       int i;
       for (i = 0; i < sym->regsUsed->size; i++)
@@ -2827,7 +2946,7 @@ genFunction (iCode * ic)
       _G.stack.param_offset += 2;
     }
 
       _G.stack.param_offset += 2;
     }
 
-  _G.stack.pushedBC = bcInUse;
+  _G.calleeSaves.pushedBC = bcInUse;
 
   if (deInUse)
     {
 
   if (deInUse)
     {
@@ -2835,8 +2954,7 @@ genFunction (iCode * ic)
       _G.stack.param_offset += 2;
     }
 
       _G.stack.param_offset += 2;
     }
 
-  _G.stack.pushedDE = deInUse;
-#endif
+  _G.calleeSaves.pushedDE = deInUse;
 
   /* adjust the stack for the function */
   _G.stack.last = sym->stack;
 
   /* adjust the stack for the function */
   _G.stack.last = sym->stack;
@@ -2882,19 +3000,17 @@ genEndFunction (iCode * ic)
           emit2 ("!leave");
         }
 
           emit2 ("!leave");
         }
 
-#if CALLEE_SAVES
-      if (_G.stack.pushedDE) 
+      if (_G.calleeSaves.pushedDE) 
         {
           emit2 ("pop de");
         {
           emit2 ("pop de");
-          _G.stack.pushedDE = FALSE;
+          _G.calleeSaves.pushedDE = FALSE;
         }
 
         }
 
-      if (_G.stack.pushedDE
+      if (_G.calleeSaves.pushedBC
         {
           emit2 ("pop bc");
         {
           emit2 ("pop bc");
-          _G.stack.pushedDE = FALSE;
+          _G.calleeSaves.pushedBC = FALSE;
         }
         }
-#endif
 
       if (options.profile) 
         {
 
       if (options.profile) 
         {
@@ -2905,8 +3021,8 @@ genEndFunction (iCode * ic)
       /* Both baned and non-banked just ret */
       emit2 ("ret");
 
       /* Both baned and non-banked just ret */
       emit2 ("ret");
 
-      /* PENDING: portability. */
-      emit2 ("__%s_end:", sym->rname);
+      sprintf (buffer, "%s_end", sym->rname);
+      emit2 ("!labeldef", buffer);
     }
   _G.flushStatics = 1;
   _G.stack.pushed = 0;
     }
   _G.flushStatics = 1;
   _G.stack.pushed = 0;
@@ -2950,7 +3066,7 @@ genRet (iCode * ic)
       if (IS_GB && size == 4 && requiresHL (AOP (IC_LEFT (ic))))
        {
          fetchPair (PAIR_DE, AOP (IC_LEFT (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
        {
        }
       else
        {
@@ -3338,7 +3454,7 @@ genPlus (iCode * ic)
   if (isPair (AOP (IC_RIGHT (ic))) && AOP_TYPE (IC_LEFT (ic)) == AOP_IMMD && getPairId (AOP (IC_RIGHT (ic))) != PAIR_HL)
     {
       fetchPair (PAIR_HL, AOP (IC_LEFT (ic)));
   if (isPair (AOP (IC_RIGHT (ic))) && AOP_TYPE (IC_LEFT (ic)) == AOP_IMMD && getPairId (AOP (IC_RIGHT (ic))) != PAIR_HL)
     {
       fetchPair (PAIR_HL, AOP (IC_LEFT (ic)));
-      emit2 ("add hl,%s ; 2", getPairName (AOP (IC_RIGHT (ic))));
+      emit2 ("add hl,%s", getPairName (AOP (IC_RIGHT (ic))));
       spillCached();
       commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
       goto release;
       spillCached();
       commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
       goto release;
@@ -3688,8 +3804,9 @@ genMult (iCode * ic)
   //  wassertl (val > 0, "Multiply must be positive");
   wassertl (val != 1, "Can't multiply by 1");
 
   //  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);
     _push (PAIR_DE);
+    _G.stack.pushedDE = TRUE;
   }
 
   if ( AOP_SIZE (IC_LEFT (ic)) == 1 && !SPEC_USIGN (getSpec (operandType ( IC_LEFT (ic)))))
   }
 
   if ( AOP_SIZE (IC_LEFT (ic)) == 1 && !SPEC_USIGN (getSpec (operandType ( IC_LEFT (ic)))))
@@ -3733,9 +3850,10 @@ genMult (iCode * ic)
 
   spillCached();
 
 
   spillCached();
 
-  if (IS_Z80)
+  if (IS_Z80 && _G.stack.pushedDE)
     {
       _pop (PAIR_DE);
     {
       _pop (PAIR_DE);
+      _G.stack.pushedDE = FALSE;
     }
 
   commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
     }
 
   commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
@@ -3901,10 +4019,10 @@ _getPairIdName (PAIR_ID id)
                   // Save the flags
                   emit2 ("push af");
                   emit2 ("ld a,(de)");
                   // Save the flags
                   emit2 ("push af");
                   emit2 ("ld a,(de)");
-                  emit2 ("xor #0x80");
+                  emit2 ("xor !immedbyte", 0x80);
                   emit2 ("ld e,a");
                   emit2 ("ld a,(hl)");
                   emit2 ("ld e,a");
                   emit2 ("ld a,(hl)");
-                  emit2 ("xor #0x80");
+                  emit2 ("xor !immedbyte", 0x80);
                   emit2 ("ld d,a");
                   emit2 ("pop af");
                   emit2 ("ld a,e");
                   emit2 ("ld d,a");
                   emit2 ("pop af");
                   emit2 ("ld a,e");
@@ -3938,10 +4056,10 @@ _getPairIdName (PAIR_ID id)
                   // Save the flags
                   emit2 ("push af");
                   emit2 ("ld a,(hl)");
                   // Save the flags
                   emit2 ("push af");
                   emit2 ("ld a,(hl)");
-                  emit2 ("xor #0x80");
+                  emit2 ("xor !immedbyte", 0x80);
                   emit2 ("ld l,a");
                   emit2 ("ld a,%d(iy)", offset);
                   emit2 ("ld l,a");
                   emit2 ("ld a,%d(iy)", offset);
-                  emit2 ("xor #0x80");
+                  emit2 ("xor !immedbyte", 0x80);
                   emit2 ("ld h,a");
                   emit2 ("pop af");
                   emit2 ("ld a,l");
                   emit2 ("ld h,a");
                   emit2 ("pop af");
                   emit2 ("ld a,l");
@@ -5271,9 +5389,16 @@ shiftL2Left2Result (operand * left, int offl,
       movLeft2Result (left, offl, result, offr, 0);
       movLeft2Result (left, offl + 1, result, offr + 1, 0);
     }
       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 (getPairId (AOP (result)) == PAIR_HL)
+    {
+      while (shCount--)
+       {
+         emit2 ("add hl,hl");
+       }
+    }
+  else
+    {
     int size = 2;
     int offset = 0;
     symbol *tlbl, *tlbl1;
     int size = 2;
     int offset = 0;
     symbol *tlbl, *tlbl1;
@@ -5282,34 +5407,56 @@ shiftL2Left2Result (operand * left, int offl,
     tlbl = newiTempLabel (NULL);
     tlbl1 = newiTempLabel (NULL);
 
     tlbl = newiTempLabel (NULL);
     tlbl1 = newiTempLabel (NULL);
 
-    /* Left is already in result - so now do the shift */
-    if (shCount > 1)
+    if (AOP (result)->type == AOP_REG)
       {
       {
-       emit2 ("ld a,!immedbyte+1", shCount);
-       emit2 ("!shortjp !tlabel", tlbl1->key + 100);
-       emitLabel (tlbl->key + 100);
+       while (shCount--)
+         {
+           for (offset = 0; offset < size; offset++)
+             {
+               l = aopGet (AOP (result), offset, FALSE);
+           
+               if (offset == 0)
+                 {
+                   emit2 ("sla %s", l);
+                 }
+               else
+                 {
+                   emit2 ("rl %s", l);
+                 }
+             }
+         }
       }
       }
-
-    while (size--)
+    else
       {
       {
-       l = aopGet (AOP (result), offset, FALSE);
-
-        if (offset == 0)
-          {
-            emit2 ("sla %s", l);
-          }
-        else
-          {
-            emit2 ("rl %s", l);
-          }
+       /* Left is already in result - so now do the shift */
+       if (shCount > 1)
+         {
+           emit2 ("ld a,!immedbyte+1", shCount);
+           emit2 ("!shortjp !tlabel", tlbl1->key + 100);
+           emitLabel (tlbl->key + 100);
+         }
 
 
-        offset++;
-      }
-    if (shCount > 1)
-      {
-       emitLabel (tlbl1->key + 100);
-       emit2 ("dec a");
-       emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+       while (size--)
+         {
+           l = aopGet (AOP (result), offset, FALSE);
+           
+           if (offset == 0)
+             {
+               emit2 ("sla %s", l);
+             }
+           else
+             {
+               emit2 ("rl %s", l);
+             }
+           
+           offset++;
+         }
+       if (shCount > 1)
+         {
+           emitLabel (tlbl1->key + 100);
+           emit2 ("dec a");
+           emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+         }
       }
   }
 }
       }
   }
 }
@@ -5743,9 +5890,19 @@ genRightShiftLiteral (operand * left,
       wassert (0);
     }
 
       wassert (0);
     }
 
-  else if (shCount >= (size * 8))
+  else if (shCount >= (size * 8)) {
+    const char *s;
+    if (!SPEC_USIGN(getSpec(operandType(left)))) {
+      _moveA(aopGet (AOP (left), 0, FALSE));
+      emit2 ("rlc a");
+      emit2 ("sbc a,a");
+      s=ACC_NAME;
+    } else {
+      s="!zero";
+    }
     while (size--)
     while (size--)
-      aopPut (AOP (result), "!zero", size);
+      aopPut (AOP (result), s, size);
+  }
   else
     {
       switch (size)
   else
     {
       switch (size)
@@ -5883,7 +6040,8 @@ genGenPointerGet (operand * left,
       /* Just do it */
       if (isPtrPair (AOP (left)))
        {
       /* Just do it */
       if (isPtrPair (AOP (left)))
        {
-         tsprintf (buffer, "!*pair", getPairName (AOP (left)));
+         tsprintf (buffer, sizeof(buffer), 
+                   "!*pair", getPairName (AOP (left)));
          aopPut (AOP (result), buffer, 0);
        }
       else
          aopPut (AOP (result), buffer, 0);
        }
       else
@@ -5895,14 +6053,14 @@ genGenPointerGet (operand * left,
       goto release;
     }
 
       goto release;
     }
 
-  if ( getPairId( AOP (left)) == PAIR_IY)
+  if (getPairId (AOP (left)) == PAIR_IY)
     {
       /* Just do it */
       offset = 0;
       while (size--) 
         {
           char at[20];
     {
       /* Just do it */
       offset = 0;
       while (size--) 
         {
           char at[20];
-          tsprintf (at, "!*iyx", offset);
+          tsprintf (at, sizeof(at), "!*iyx", offset);
           aopPut (AOP (result), at, offset);
           offset++;
         }
           aopPut (AOP (result), at, offset);
           offset++;
         }
@@ -5915,20 +6073,48 @@ genGenPointerGet (operand * left,
   /* if this is remateriazable */
   fetchPair (pair, AOP (left));
 
   /* if this is remateriazable */
   fetchPair (pair, AOP (left));
 
-  freeAsmop (left, NULL, ic);
-
   /* if bit then unpack */
   if (IS_BITVAR (retype))
     {
       wassert (0);
     }
   /* 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");
       emit2 ("inc hl");
       emit2 ("ld h,!*hl");
       emit2 ("ld l,a");
     {
       wassertl (size == 2, "HL must be of size 2");
       emit2 ("ld a,!*hl");
       emit2 ("inc hl");
       emit2 ("ld h,!*hl");
       emit2 ("ld l,a");
+      spillPair (PAIR_HL);
+    }
+  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
     {
     }
   else
     {
@@ -5938,7 +6124,8 @@ genGenPointerGet (operand * left,
       while (size--)
        {
          /* PENDING: make this better */
       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++);
            }
            {
              aopPut (AOP (result), "!*hl", offset++);
            }
@@ -5955,6 +6142,8 @@ genGenPointerGet (operand * left,
        }
     }
 
        }
     }
 
+  freeAsmop (left, NULL, ic);
+
 release:
   freeAsmop (result, NULL, ic);
 }
 release:
   freeAsmop (result, NULL, ic);
 }
@@ -6045,6 +6234,37 @@ genGenPointerSet (operand * right,
         }
       goto release;
     }
         }
       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 */
 
   /* if the operand is already in dptr
      then we do nothing else we move the value to dptr */
@@ -6184,14 +6404,14 @@ genAddrOf (iCode * ic)
        {
          /* if it has an offset  then we need to compute it */
          if (sym->stack > 0)
        {
          /* if it has an offset  then we need to compute it */
          if (sym->stack > 0)
-           emit2 ("ld hl,#%d+%d+%d+%d", sym->stack, _G.stack.pushed, _G.stack.offset, _G.stack.param_offset);
+           emit2 ("ld hl,!immedword", sym->stack + _G.stack.pushed + _G.stack.offset + _G.stack.param_offset);
          else
          else
-           emit2 ("ld hl,#%d+%d+%d", sym->stack, _G.stack.pushed, _G.stack.offset);
+           emit2 ("ld hl,!immedword", sym->stack + _G.stack.pushed + _G.stack.offset);
          emit2 ("add hl,sp");
        }
       else
        {
          emit2 ("add hl,sp");
        }
       else
        {
-         emit2 ("ld hl,#%s", sym->rname);
+         emit2 ("ld hl,!hashedstr", sym->rname);
        }
       commitPair (AOP (IC_RESULT (ic)), PAIR_HL);
     }
        }
       commitPair (AOP (IC_RESULT (ic)), PAIR_HL);
     }
@@ -6240,12 +6460,12 @@ genAssign (iCode * ic)
 
   if (AOP_TYPE (right) == AOP_LIT)
     {
 
   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)))
     {
     }
 
   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) &&
     }
   else if ((size > 1) &&
           (AOP_TYPE (result) != AOP_REG) &&
@@ -6382,7 +6602,7 @@ static void
 genCast (iCode * ic)
 {
   operand *result = IC_RESULT (ic);
 genCast (iCode * ic)
 {
   operand *result = IC_RESULT (ic);
-  sym_link *ctype = operandType (IC_LEFT (ic));
+  sym_link *rtype = operandType (IC_RIGHT (ic));
   operand *right = IC_RIGHT (ic);
   int size, offset;
 
   operand *right = IC_RIGHT (ic);
   int size, offset;
 
@@ -6436,7 +6656,7 @@ genCast (iCode * ic)
   /* now depending on the sign of the destination */
   size = AOP_SIZE (result) - AOP_SIZE (right);
   /* Unsigned or not an integral type - right fill with zeros */
   /* now depending on the sign of the destination */
   size = AOP_SIZE (result) - AOP_SIZE (right);
   /* Unsigned or not an integral type - right fill with zeros */
-  if (SPEC_USIGN (ctype) || !IS_SPEC (ctype))
+  if (SPEC_USIGN (rtype) || !IS_SPEC (rtype) || AOP_TYPE(right)==AOP_CRY)
     {
       while (size--)
        aopPut (AOP (result), "!zero", offset++);
     {
       while (size--)
        aopPut (AOP (result), "!zero", offset++);
@@ -6612,7 +6832,7 @@ _rleAppend(RLECTX *self, int c)
           /* Yes, worthwhile. */
           /* Commit whatever was in the buffer. */
           _rleCommit(self);
           /* Yes, worthwhile. */
           /* Commit whatever was in the buffer. */
           _rleCommit(self);
-          emit2(".db -%u,0x%02X", self->runLen, self->last);
+          emit2("!db !immed-%u,!immedbyte", self->runLen, self->last);
         }
       else
         {
         }
       else
         {
@@ -6637,7 +6857,7 @@ _rleAppend(RLECTX *self, int c)
           /* Commit whatever was in the buffer. */
           _rleCommit(self);
 
           /* Commit whatever was in the buffer. */
           _rleCommit(self);
 
-          emit2 (".db -%u,0x%02X", self->runLen, self->last);
+          emit2 ("!db !immed-%u,!immedbyte", self->runLen, self->last);
           self->runLen = 0;
         }
       self->runLen++;
           self->runLen = 0;
         }
       self->runLen++;
@@ -6938,9 +7158,7 @@ static void
 genBuiltInMemcpy (iCode *ic, int nParams, operand **pparams)
 {
   operand *from, *to, *count;
 genBuiltInMemcpy (iCode *ic, int nParams, operand **pparams)
 {
   operand *from, *to, *count;
-  symbol *label;
   bool deInUse;
   bool deInUse;
-  iCode *pcall;
 
   wassertl (nParams == 3, "Built-in memcpy must have two parameters");
   to = pparams[2];
 
   wassertl (nParams == 3, "Built-in memcpy must have two parameters");
   to = pparams[2];
@@ -7031,9 +7249,15 @@ genZ80Code (iCode * lic)
 
       if (cln != ic->lineno)
        {
 
       if (cln != ic->lineno)
        {
-         emit2 ("; %s %d", ic->filename, ic->lineno);
+         if (!options.noCcodeInAsm) {
+           emit2 (";%s:%d: %s", ic->filename, ic->lineno,
+                  printCLine(ic->filename, ic->lineno));
+         }
          cln = ic->lineno;
        }
          cln = ic->lineno;
        }
+      if (options.iCodeInAsm) {
+       emit2 (";ic:%d: %s", ic->key, printILine(ic));
+      }
       /* if the result is marked as
          spilt and rematerializable or code for
          this has already been generated then
       /* if the result is marked as
          spilt and rematerializable or code for
          this has already been generated then
@@ -7354,7 +7578,7 @@ fetchLitSpecial (asmop * aop, bool negate, bool xor)
     v = 0-v;
   v &= 0xFFFF;
 
     v = 0-v;
   v &= 0xFFFF;
 
-  tsprintf (buffer, "!immedword", v);
+  tsprintf (buffer, sizeof(buffer), "!immedword", v);
   return traceAlloc(&_G.trace.aops, Safe_strdup (buffer));
 }
 
   return traceAlloc(&_G.trace.aops, Safe_strdup (buffer));
 }