Regression tests now pass on z80
[fw/sdcc] / src / z80 / gen.c
index f52e8e4e183c748eee00f8e7f047a7b8fd08b340..342dac243c8a9c162e76d297aed855d1c8cb40ef 100644 (file)
@@ -4,20 +4,20 @@
   Benchmarks on dhry.c 2.1 with 32766 loops and a 10ms clock:
             ticks dhry  size
   Base with asm strcpy / strcmp / memcpy: 23198 141 1A14
-  Improved WORD push        22784 144 19AE
-  With label1 on        22694 144 197E
-  With label2 on        22743 144 198A
-  With label3 on        22776 144 1999
-  With label4 on        22776 144 1999
-  With all 'label' on       22661 144 196F
-  With loopInvariant on       20919 156 19AB
-  With loopInduction on       Breaks    198B
-  With all working on       20796 158 196C
-  Slightly better genCmp(signed)    20597 159 195B
+  Improved WORD push                    22784 144 19AE
+  With label1 on                        22694 144 197E
+  With label2 on                        22743 144 198A
+  With label3 on                        22776 144 1999
+  With label4 on                        22776 144 1999
+  With all 'label' on                   22661 144 196F
+  With loopInvariant on                 20919 156 19AB
+  With loopInduction on                 Breaks    198B
+  With all working on                   20796 158 196C
+  Slightly better genCmp(signed)        20597 159 195B
   Better reg packing, first peephole    20038 163 1873
-  With assign packing       19281 165 1849
-  5/3/00          17741 185 17B6
-  With reg params for mul and div   16234 202 162D
+  With assign packing                   19281 165 1849
+  5/3/00                                17741 185 17B6
+  With reg params for mul and div       16234 202 162D
 
   Michael Hope <michaelh@earthling.net> 2000
   Based on the mcs51 generator -
    stuff. This is what it is all about CODE GENERATION for a specific MCU.
    Some of the routines may be reusable, will have to see */
 
-static char *spname;
+/* Z80 calling convention description.
+   Parameters are passed right to left.  As the stack grows downwards,
+   the parameters are arranged in left to right in memory.
+   Parameters may be passed in the HL and DE registers with one
+   parameter per pair.
+   PENDING: What if the parameter is a long?
+   Everything is caller saves. i.e. the caller must save any registers
+   that it wants to preserve over the call.
+   The return value is returned in DEHL.  DE is normally used as a
+   working register pair.  Caller saves allows it to be used for a
+   return value.
+   va args functions do not use register parameters.  All arguments
+   are passed on the stack.
+   IX is used as an index register to the top of the local variable
+   area.  ix-0 is the top most local variable.
+*/
 static char *_z80_return[] =
 {"l", "h", "e", "d"};
 static char *_gbz80_return[] =
 {"e", "d", "l", "h"};
+static char *_fReceive[] =
+  { "c", "b", "e", "d" };
+
 static char **_fReturn;
 static char **_fTmp;
 
-/* PENDING: messy */
-static char zero[20];
-
-static char *accUse[] =
-{"a"};
-static char *hlUse[] =
-{"l", "h"};
-short rbank = -1;
-short accInUse = 0;
-short inLine = 0;
-short debugLine = 0;
-short nregssaved = 0;
-extern int ptrRegReq;
-extern int nRegs;
 extern FILE *codeOutFile;
-set *sendSet = NULL;
 
 typedef enum
   {
     PAIR_INVALID,
+    PAIR_AF,
     PAIR_BC,
     PAIR_DE,
     PAIR_HL,
     PAIR_IY,
     PAIR_IX,
     NUM_PAIRS
-  }
-PAIR_ID;
+  } PAIR_ID;
 
 static struct
-  {
-    const char *name;
-    const char *l;
-    const char *h;
-  }
-_pairs[NUM_PAIRS] =
 {
-  {
-    "??", "?", "?"
-  }
-  ,
-  {
-    "bc", "c", "b"
-  }
-  ,
-  {
-    "de", "e", "d"
-  }
-  ,
-  {
-    "hl", "l", "h"
-  }
-  ,
-  {
-    "iy", "iy.l?", "iy.h?"
-  }
-  ,
-  {
-    "ix", "ix.l?", "ix.h?"
-  }
+  const char *name;
+  const char *l;
+  const char *h;
+} _pairs[NUM_PAIRS] = {
+  {    "??1", "?2", "?3" },
+  {    "af", "f", "a" },
+  {    "bc", "c", "b" },
+  {    "de", "e", "d" },
+  {    "hl", "l", "h" },
+  {    "iy", "iy.l?", "iy.h?" },
+  {    "ix", "ix.l?", "ix.h?" }
 };
 
+// PENDING
+#define ACC_NAME       _pairs[PAIR_AF].h
+
 #define RESULTONSTACK(x) \
                          (IC_RESULT(x) && IC_RESULT(x)->aop && \
                          IC_RESULT(x)->aop->type == AOP_STK )
 
-#define MOVA(x) if (strcmp(x,"a")) emitcode("ld","a,%s",x);
-#define CLRC    emitcode("xor","a,a");
-
-lineNode *lineHead = NULL;
-lineNode *lineCurr = NULL;
-
-static const unsigned char SLMask[] =
-{0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00};
-static const unsigned char SRMask[] =
-{0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00};
-
-#define LSB     0
-#define MSB16   1
-#define MSB24   2
-#define MSB32   3
+enum 
+  {
+    LSB,
+    MSB16,
+    MSB24,
+    MSB32
+  };
 
-/* Stack frame:
-   IX+4   param0  LH
-   IX+2   ret LH
-   IX+0   ix  LH
-   IX-2   temp0 LH
- */
+static struct 
+{
+  struct 
+  {
+    AOP_TYPE last_type;
+    const char *lit;
+    int offset;
+  } pairs[NUM_PAIRS];
+  struct 
+  {
+    int last;
+    int pushed;
+    int param_offset;
+    int offset;
+    int pushedBC;
+    int pushedDE;
+  } stack;
+  int frameId;
+  int receiveOffset;
+  bool flushStatics;
+  bool in_home;
+  const char *lastFunctionName;
+
+  set *sendSet;
+
+  struct
+  {
+    /** TRUE if the registers have already been saved. */
+    bool saved;
+  } saves;
 
-static struct
+  struct 
   {
-    struct
-      {
-       AOP_TYPE last_type;
-       const char *lit;
-       int offset;
-      }
-    pairs[NUM_PAIRS];
-    struct
-      {
-       int last;
-       int pushed;
-       int param_offset;
-       int offset;
-       int pushed_bc;
-       int pushed_de;
-      }
-    stack;
-    int frameId;
-    bool flush_statics;
-    bool in_home;
-  }
-_G;
+    lineNode *head;
+    lineNode *current;
+    int isInline;
+  } lines;
+
+} _G;
 
-static char *aopGet (asmop * aop, int offset, bool bit16);
+static const char *aopGet (asmop * aop, int offset, bool bit16);
 
 static void
 _tidyUp (char *buf)
@@ -200,14 +188,14 @@ _tidyUp (char *buf)
     }
   /* Change the first (and probably only) ' ' to a tab so
      everything lines up.
-   */
+  */
   while (*buf)
     {
       if (*buf == ' ')
-       {
-         *buf = '\t';
-         return;
-       }
+        {
+          *buf = '\t';
+          break;
+        }
       buf++;
     }
 }
@@ -223,22 +211,21 @@ emit2 (const char *szFormat,...)
   tvsprintf (buffer, szFormat, ap);
 
   _tidyUp (buffer);
-  lineCurr = (lineCurr ?
-             connectLine (lineCurr, newLineNode (buffer)) :
-             (lineHead = newLineNode (buffer)));
+  _G.lines.current = (_G.lines.current ?
+             connectLine (_G.lines.current, newLineNode (buffer)) :
+             (_G.lines.head = newLineNode (buffer)));
 
-  lineCurr->isInline = inLine;
-  lineCurr->isDebug = debugLine;
+  _G.lines.current->isInline = _G.lines.isInline;
 }
 
 /*-----------------------------------------------------------------*/
-/* emitcode - writes the code into a file : for now it is simple    */
+/* emit2 - writes the code into a file : for now it is simple    */
 /*-----------------------------------------------------------------*/
 void
-emitcode (const char *inst, const char *fmt,...)
+_emit2 (const char *inst, const char *fmt,...)
 {
   va_list ap;
-  char lb[MAX_INLINEASM];
+  char lb[INITIAL_INLINEASM];
   char *lbp = lb;
 
   va_start (ap, fmt);
@@ -255,33 +242,41 @@ emitcode (const char *inst, const char *fmt,...)
     lbp++;
 
   if (lbp && *lbp)
-    lineCurr = (lineCurr ?
-               connectLine (lineCurr, newLineNode (lb)) :
-               (lineHead = newLineNode (lb)));
-  lineCurr->isInline = inLine;
-  lineCurr->isDebug = debugLine;
+    {
+      _G.lines.current = (_G.lines.current ?
+                  connectLine (_G.lines.current, newLineNode (lb)) :
+                  (_G.lines.head = newLineNode (lb)));
+    }
+  _G.lines.current->isInline = _G.lines.isInline;
   va_end (ap);
 }
 
-/* Z80:
-   { "adjustsp",
-   "\tld hl,#-%d\n"
-   "\tadd hl,sp\n"
-   "\tld sp,hl"
-   }
-   { "prelude",
-   "push bc"
-   "push de"
-   "push ix"
-   "ld ix,#0"
-   "add ix,sp"
-   { "leave"
-   emitcode("ld", "sp,ix");
-   emitcode("pop", "ix");
-   emitcode("pop", "de");
-   }
-   }
- */
+static void
+_emitMove(const char *to, const char *from)
+{
+  if (strcasecmp(to, from) != 0) 
+    {
+      emit2("ld %s,%s", to, from);
+    }
+  else 
+    {
+      // Optimise it out.
+      // Could leave this to the peephole, but sometimes the peephole is inhibited.
+    }
+}
+
+static void
+_moveA(const char *moveFrom)
+{
+    // Let the peephole optimiser take care of redundent loads
+    _emitMove(ACC_NAME, moveFrom);
+}
+
+static void
+_clearCarry(void)
+{
+    emit2("xor a,a");
+}
 
 const char *
 getPairName (asmop * aop)
@@ -384,7 +379,7 @@ isPtrPair (asmop * aop)
 void
 genPairPush (asmop * aop)
 {
-  emitcode ("push", "%s", getPairName (aop));
+  emit2 ("push %s", getPairName (aop));
 }
 
 
@@ -423,7 +418,7 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool requires_a)
   /* Assign depending on the storage class */
   if (sym->onStack || sym->iaccess)
     {
-      emitcode ("", "; AOP_STK for %s", sym->rname);
+      emit2 ("; AOP_STK for %s", sym->rname);
       sym->aop = aop = newAsmop (AOP_STK);
       aop->size = getSize (sym->type);
       aop->aopu.aop_stk = sym->stack;
@@ -448,7 +443,7 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool requires_a)
          sym->aop = aop = newAsmop (AOP_SFR);
          aop->aopu.aop_dir = sym->rname;
          aop->size = getSize (sym->type);
-         emitcode ("", "; AOP_SFR for %s", sym->rname);
+         emit2 ("; AOP_SFR for %s", sym->rname);
          return aop;
        }
     }
@@ -457,7 +452,7 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool requires_a)
   /* in which case DPTR gets the address */
   if (IS_GB)
     {
-      emitcode ("", "; AOP_HL for %s", sym->rname);
+      emit2 ("; AOP_HL for %s", sym->rname);
       sym->aop = aop = newAsmop (AOP_HL);
     }
   else
@@ -694,24 +689,27 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a)
 
       if (sym->accuse)
        {
-         int i;
          if (sym->accuse == ACCUSE_A)
            {
              aop = op->aop = sym->aop = newAsmop (AOP_ACC);
              aop->size = getSize (sym->type);
-             for (i = 0; i < 2; i++)
-               aop->aopu.aop_str[i] = accUse[i];
+              wassertl(aop->size == 1, "Internal error: Caching in A, but too big to fit in A");
+
+              aop->aopu.aop_str[0] = _pairs[PAIR_AF].h;
            }
          else if (sym->accuse == ACCUSE_HL)
            {
              wassert (!IS_GB);
              aop = op->aop = sym->aop = newAsmop (AOP_HLREG);
              aop->size = getSize (sym->type);
-             for (i = 0; i < 2; i++)
-               aop->aopu.aop_str[i] = hlUse[i];
+              wassertl(aop->size <= 2, "Internal error: Caching in HL, but too big to fit in HL");
+              aop->aopu.aop_str[0] = _pairs[PAIR_HL].l;
+              aop->aopu.aop_str[1] = _pairs[PAIR_HL].h;
            }
-         else
-           wassert (0);
+         else 
+              {
+                  wassert (0);
+              }
          return;
        }
 
@@ -821,7 +819,7 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
        /* otherwise it is fairly simple */
        if (!IS_FLOAT (val->type))
          {
-           unsigned long v = floatFromVal (val);
+           unsigned long v = (unsigned long) floatFromVal (val);
 
            if (offset == 2)
              v >>= 16;
@@ -876,12 +874,12 @@ adjustPair (const char *pair, int *pold, int new)
 
   while (*pold < new)
     {
-      emitcode ("inc", "%s", pair);
+      emit2 ("inc %s", pair);
       (*pold)++;
     }
   while (*pold > new)
     {
-      emitcode ("dec", "%s", pair);
+      emit2 ("dec %s", pair);
       (*pold)--;
     }
 }
@@ -905,6 +903,7 @@ requiresHL (asmop * aop)
 {
   switch (aop->type)
     {
+    case AOP_IY:
     case AOP_HL:
     case AOP_STK:
       return TRUE;
@@ -922,12 +921,12 @@ fetchLitSpecial (asmop * aop, bool negate, bool xor)
   wassert (aop->type == AOP_LIT);
   wassert (!IS_FLOAT (val->type));
 
-  v = floatFromVal (val);
+  v = (unsigned long) floatFromVal (val);
 
   if (xor)
     v ^= 0x8000;
   if (negate)
-    v = -v;
+    v = 0-v;
   v &= 0xFFFF;
 
   tsprintf (buffer, "!immedword", v);
@@ -990,47 +989,46 @@ fetchLitPair (PAIR_ID pairId, asmop * left, int offset)
 static void
 fetchPairLong (PAIR_ID pairId, asmop * aop, int offset)
 {
-  /* if this is remateriazable */
-  if (isLitWord (aop))
-    {
-      fetchLitPair (pairId, aop, offset);
-    }
-  else
-    {                          /* we need to get it byte by byte */
-      if (pairId == PAIR_HL && IS_GB && requiresHL (aop))
-       {
-         aopGet (aop, offset, FALSE);
-         switch (aop->size)
-           {
-           case 1:
-             emit2 ("ld l,!*hl");
-             emit2 ("ld h,!immedbyte", 0);
-             break;
-           case 2:
-             emit2 ("!ldahli");
-             emit2 ("ld h,!*hl");
-             emit2 ("ld l,a");
-             break;
-           default:
-             emit2 ("; WARNING: mlh woosed out.  This code is invalid.");
-           }
-       }
-      else if (IS_Z80 && aop->type == AOP_IY)
-       {
-         /* Instead of fetching relative to IY, just grab directly
-            from the address IY refers to */
-         char *l = aopGetLitWordLong (aop, offset, FALSE);
-         wassert (l);
-         emit2 ("ld %s,(%s)", _pairs[pairId].name, l);
-       }
-      else
-       {
-         emitcode ("ld", "%s,%s", _pairs[pairId].l, aopGet (aop, offset, FALSE));
-         emitcode ("ld", "%s,%s", _pairs[pairId].h, aopGet (aop, offset + 1, FALSE));
-       }
-      /* PENDING: check? */
-      if (pairId == PAIR_HL)
-       spillPair (PAIR_HL);
+    /* if this is remateriazable */
+    if (isLitWord (aop)) {
+        fetchLitPair (pairId, aop, offset);
+    }
+    else {
+        /* we need to get it byte by byte */
+        if (pairId == PAIR_HL && IS_GB && requiresHL (aop)) {
+            aopGet (aop, offset, FALSE);
+            switch (aop->size) {
+            case 1:
+                emit2 ("ld l,!*hl");
+                emit2 ("ld h,!immedbyte", 0);
+                            break;
+            case 2:
+                emit2 ("!ldahli");
+                emit2 ("ld h,!*hl");
+                emit2 ("ld l,a");
+                break;
+            default:
+                emit2 ("; WARNING: mlh woosed out.  This code is invalid.");
+            }
+        }
+        else if (IS_Z80 && aop->type == AOP_IY) {
+            /* Instead of fetching relative to IY, just grab directly
+               from the address IY refers to */
+            char *l = aopGetLitWordLong (aop, offset, FALSE);
+            wassert (l);
+            emit2 ("ld %s,(%s)", _pairs[pairId].name, l);
+
+            if (aop->size < 2) {
+                emit2("ld %s,!zero", _pairs[pairId].h);
+            }
+        }
+        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);
     }
 }
 
@@ -1097,17 +1095,19 @@ emitLabel (int key)
 /*-----------------------------------------------------------------*/
 /* aopGet - for fetching value of the aop                          */
 /*-----------------------------------------------------------------*/
-static char *
+static const char *
 aopGet (asmop * aop, int offset, bool bit16)
 {
   char *s = buffer;
-  char *rs;
 
   /* 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)
-    return zero;
+      aop->type != AOP_LIT) 
+    {
+      tsprintf (s, "!zero");
+      return gc_strdup(s);
+    }
 
   /* depending on type */
   switch (aop->type)
@@ -1131,25 +1131,22 @@ aopGet (asmop * aop, int offset, bool bit16)
          default:
            wassert (0);
          }
-      rs = Safe_calloc (1, strlen (s) + 1);
-      strcpy (rs, s);
-      return rs;
+
+      return gc_strdup(s);
 
     case AOP_DIR:
       wassert (IS_GB);
-      emitcode ("ld", "a,(%s+%d) ; x", aop->aopu.aop_dir, offset);
+      emit2 ("ld a,(%s+%d) ; x", aop->aopu.aop_dir, offset);
       sprintf (s, "a");
-      rs = Safe_calloc (1, strlen (s) + 1);
-      strcpy (rs, s);
-      return rs;
+
+      return gc_strdup(s);
 
     case AOP_SFR:
       wassert (IS_GB);
-      emitcode ("ldh", "a,(%s+%d) ; x", aop->aopu.aop_dir, offset);
+      emit2 ("ldh a,(%s+%d) ; x", aop->aopu.aop_dir, offset);
       sprintf (s, "a");
-      rs = Safe_calloc (1, strlen (s) + 1);
-      strcpy (rs, s);
-      return rs;
+
+      return gc_strdup(s);
 
     case AOP_REG:
       return aop->aopu.aop_reg[offset]->name;
@@ -1158,15 +1155,15 @@ aopGet (asmop * aop, int offset, bool bit16)
       wassert (IS_GB);
       setupPair (PAIR_HL, aop, offset);
       tsprintf (s, "!*hl");
+
       return gc_strdup (s);
 
     case AOP_IY:
       wassert (IS_Z80);
       setupPair (PAIR_IY, aop, offset);
       tsprintf (s, "!*iyx", offset);
-      rs = Safe_calloc (1, strlen (s) + 1);
-      strcpy (rs, s);
-      return rs;
+
+      return gc_strdup(s);
 
     case AOP_STK:
       if (IS_GB)
@@ -1180,9 +1177,8 @@ aopGet (asmop * aop, int offset, bool bit16)
            offset += _G.stack.param_offset;
          tsprintf (s, "!*ixx ; x", aop->aopu.aop_stk + offset);
        }
-      rs = Safe_calloc (1, strlen (s) + 1);
-      strcpy (rs, s);
-      return rs;
+
+      return gc_strdup(s);
 
     case AOP_CRY:
       wassert (0);
@@ -1192,7 +1188,11 @@ aopGet (asmop * aop, int offset, bool bit16)
        {
          return "a";
        }
-      return "!zero";
+      else
+        {
+          tsprintf(s, "!zero");
+          return gc_strdup(s);
+        }
 
     case AOP_HLREG:
       wassert (offset < 2);
@@ -1204,6 +1204,7 @@ aopGet (asmop * aop, int offset, bool bit16)
     case AOP_STR:
       aop->coff = offset;
       return aop->aopu.aop_str[offset];
+
     default:
       break;
     }
@@ -1248,6 +1249,8 @@ canAssignToPtr (const char *s)
 static void
 aopPut (asmop * aop, const char *s, int offset)
 {
+  char buffer2[256];
+
   if (aop->size && offset > (aop->size - 1))
     {
       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
@@ -1255,6 +1258,10 @@ aopPut (asmop * aop, const char *s, int offset)
       exit (0);
     }
 
+  // PENDING
+  tsprintf(buffer2, s);
+  s = buffer2;
+
   /* will assign value to value */
   /* depending on where it is ofcourse */
   switch (aop->type)
@@ -1263,15 +1270,15 @@ aopPut (asmop * aop, const char *s, int offset)
       /* Direct.  Hmmm. */
       wassert (IS_GB);
       if (strcmp (s, "a"))
-       emitcode ("ld", "a,%s", s);
-      emitcode ("ld", "(%s+%d),a", aop->aopu.aop_dir, offset);
+       emit2 ("ld a,%s", s);
+      emit2 ("ld (%s+%d),a", aop->aopu.aop_dir, offset);
       break;
 
     case AOP_SFR:
       wassert (IS_GB);
       if (strcmp (s, "a"))
-       emitcode ("ld", "a,%s", s);
-      emitcode ("ldh", "(%s+%d),a", aop->aopu.aop_dir, offset);
+       emit2 ("ld a,%s", s);
+      emit2 ("ldh (%s+%d),a", aop->aopu.aop_dir, offset);
       break;
 
     case AOP_REG:
@@ -1357,7 +1364,7 @@ aopPut (asmop * aop, const char *s, int offset)
       aop->coff = offset;
       if (strcmp (aop->aopu.aop_str[offset], s))
        {
-         emitcode ("ld", "%s,%s", aop->aopu.aop_str[offset], s);
+         emit2 ("ld %s,%s", aop->aopu.aop_str[offset], s);
        }
       break;
 
@@ -1368,12 +1375,12 @@ aopPut (asmop * aop, const char *s, int offset)
       if (offset > 0)
        {
 
-         emitcode ("", "; Error aopPut AOP_ACC");
+         emit2 ("; Error aopPut AOP_ACC");
        }
       else
        {
          if (strcmp (aop->aopu.aop_str[offset], s))
-           emitcode ("ld", "%s,%s", aop->aopu.aop_str[offset], s);
+           emit2 ("ld %s,%s", aop->aopu.aop_str[offset], s);
        }
       break;
 
@@ -1434,7 +1441,7 @@ static void
 movLeft2Result (operand * left, int offl,
                operand * result, int offr, int sign)
 {
-  char *l;
+    const char *l;
   if (!sameRegs (AOP (left), AOP (result)) || (offl != offr))
     {
       l = aopGet (AOP (left), offl, FALSE);
@@ -1466,7 +1473,7 @@ outAcc (operand * result)
       /* unsigned or positive */
       while (size--)
        {
-         aopPut (AOP (result), zero, offset++);
+         aopPut (AOP (result), "!zero", offset++);
        }
     }
 }
@@ -1479,7 +1486,7 @@ outBitCLong (operand * result, bool swap_sense)
   /* if the result is bit */
   if (AOP_TYPE (result) == AOP_CRY)
     {
-      emitcode ("", "; Note: outBitC form 1");
+      emit2 ("; Note: outBitC form 1");
       aopPut (AOP (result), "blah", 0);
     }
   else
@@ -1508,17 +1515,17 @@ toBoolean (operand * oper)
   int offset = 0;
   if (size > 1)
     {
-      emitcode ("ld", "a,%s", aopGet (AOP (oper), offset++, FALSE));
+      emit2 ("ld a,%s", aopGet (AOP (oper), offset++, FALSE));
       size--;
       while (size--)
-       emitcode ("or", "a,%s", aopGet (AOP (oper), offset++, FALSE));
+       emit2 ("or a,%s", aopGet (AOP (oper), offset++, FALSE));
     }
   else
     {
       if (AOP (oper)->type != AOP_ACC)
        {
-         CLRC;
-         emitcode ("or", "a,%s", aopGet (AOP (oper), 0, FALSE));
+         _clearCarry();
+         emit2 ("or a,%s", aopGet (AOP (oper), 0, FALSE));
        }
     }
 }
@@ -1586,9 +1593,9 @@ genCpl (iCode * ic)
   size = AOP_SIZE (IC_RESULT (ic));
   while (size--)
     {
-      char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE);
-      MOVA (l);
-      emitcode ("cpl", "");
+      const char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE);
+      _moveA (l);
+      emit2("cpl");
       aopPut (AOP (IC_RESULT (ic)), "a", offset++);
     }
 
@@ -1632,10 +1639,10 @@ genUminus (iCode * ic)
   /* otherwise subtract from zero */
   size = AOP_SIZE (IC_LEFT (ic));
   offset = 0;
-  CLRC;
+  _clearCarry();
   while (size--)
     {
-      char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE);
+      const char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE);
       emit2 ("ld a,!zero");
       emit2 ("sbc a,%s", l);
       aopPut (AOP (IC_RESULT (ic)), "a", offset++);
@@ -1694,7 +1701,7 @@ assignResultValue (operand * oper)
       _push (PAIR_HL);
       aopPut (AOP (oper), _fReturn[0], 0);
       aopPut (AOP (oper), _fReturn[1], 1);
-      emitcode ("pop", "de");
+      emit2 ("pop de");
       _G.stack.pushed -= 2;
       aopPut (AOP (oper), _fReturn[0], 2);
       aopPut (AOP (oper), _fReturn[1], 3);
@@ -1708,6 +1715,73 @@ assignResultValue (operand * oper)
     }
 }
 
+static void
+_saveRegsForCall(iCode *ic, int sendSetSize)
+{
+  /* Rules:
+      o Stack parameters are pushed before this function enters
+      o DE and BC may be used in this function.
+      o HL and DE may be used to return the result.
+      o HL and DE may be used to send variables.
+      o DE and BC may be used to store the result value.
+      o HL may be used in computing the sent value of DE
+      o The iPushes for other parameters occur before any addSets
+
+     Logic: (to be run inside the first iPush or if none, before sending)
+      o Compute if DE and/or BC are in use over the call
+      o Compute if DE is used in the send set
+      o Compute if DE and/or BC are used to hold the result value
+      o If (DE is used, or in the send set) and is not used in the result, push.
+      o If BC is used and is not in the result, push
+      o 
+      o If DE is used in the send set, fetch
+      o If HL is used in the send set, fetch
+      o Call
+      o ...
+  */
+  if (_G.saves.saved == FALSE) {
+    bool deInUse, bcInUse;
+    bool deSending;
+    bool bcInRet = FALSE, deInRet = FALSE;
+    bitVect *rInUse;
+
+#if 1
+    rInUse = bitVectCplAnd (bitVectCopy (ic->rMask), ic->rUsed);
+#else
+    if (IC_RESULT(ic))
+      {
+        rInUse = bitVectCplAnd (bitVectCopy (ic->rMask), z80_rUmaskForOp (IC_RESULT(ic)));
+      }
+    else 
+      {
+        /* Has no result, so in use is all of in use */
+        rInUse = ic->rMask;
+      }
+#endif
+
+    deInUse = bitVectBitValue (rInUse, D_IDX) || bitVectBitValue(rInUse, E_IDX);
+    bcInUse = bitVectBitValue (rInUse, B_IDX) || bitVectBitValue(rInUse, C_IDX);
+
+    deSending = (sendSetSize > 1);
+
+    emit2 ("; _saveRegsForCall: sendSetSize: %u deInUse: %u bcInUse: %u deSending: %u", sendSetSize, deInUse, bcInUse, deSending);
+
+    if (bcInUse && bcInRet == FALSE) {
+      _push(PAIR_BC);
+      _G.stack.pushedBC = TRUE;
+    }
+    if (deInUse && deInRet == FALSE) {
+      _push(PAIR_DE);
+      _G.stack.pushedDE = TRUE;
+    }
+
+    _G.saves.saved = TRUE;
+  }
+  else {
+    /* Already saved. */
+  }
+}
+
 /*-----------------------------------------------------------------*/
 /* genIpush - genrate code for pushing this gets a little complex  */
 /*-----------------------------------------------------------------*/
@@ -1715,12 +1789,14 @@ static void
 genIpush (iCode * ic)
 {
   int size, offset = 0;
-  char *l;
+  const char *l;
 
   /* if this is not a parm push : ie. it is spill push
      and spill push is always done on the local stack */
   if (!ic->parmPush)
     {
+      wassertl(0, "Encountered an unsupported spill push.");
+#if 0
       /* and the item is spilt then do nothing */
       if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
        return;
@@ -1730,7 +1806,7 @@ genIpush (iCode * ic)
       /* push it on the stack */
       if (isPair (AOP (IC_LEFT (ic))))
        {
-         emitcode ("push", getPairName (AOP (IC_LEFT (ic))));
+         emit2 ("push %s", getPairName (AOP (IC_LEFT (ic))));
          _G.stack.pushed += 2;
        }
       else
@@ -1755,11 +1831,37 @@ genIpush (iCode * ic)
              _G.stack.pushed++;
            }
        }
+#endif
       return;
     }
 
-  /* Hmmm... what about saving the currently used registers
-     at this point? */
+  if (_G.saves.saved == FALSE) {
+    /* Caller saves, and this is the first iPush. */
+    /* Scan ahead until we find the function that we are pushing parameters to.
+       Count the number of addSets on the way to figure out what registers
+       are used in the send set.
+    */
+    int nAddSets = 0;
+    iCode *walk = ic->next;
+    
+    while (walk) {
+      if (walk->op == SEND) {
+        nAddSets++;
+      }
+      else if (walk->op == CALL || walk->op == PCALL) {
+        /* Found it. */
+        break;
+      }
+      else {
+        /* Keep looking. */
+      }
+      walk = walk->next;
+    }
+    _saveRegsForCall(walk, nAddSets);
+  }
+  else {
+    /* Already saved by another iPush. */
+  }
 
   /* then do the push */
   aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
@@ -1769,14 +1871,14 @@ genIpush (iCode * ic)
   if (isPair (AOP (IC_LEFT (ic))))
     {
       _G.stack.pushed += 2;
-      emitcode ("push", "%s", getPairName (AOP (IC_LEFT (ic))));
+      emit2 ("push %s", getPairName (AOP (IC_LEFT (ic))));
     }
   else
     {
       if (size == 2)
        {
          fetchHL (AOP (IC_LEFT (ic)));
-         emitcode ("push", "hl");
+         emit2 ("push hl");
          spillPair (PAIR_HL);
          _G.stack.pushed += 2;
          goto release;
@@ -1784,11 +1886,11 @@ genIpush (iCode * ic)
       if (size == 4)
        {
          fetchPairLong (PAIR_HL, AOP (IC_LEFT (ic)), 2);
-         emitcode ("push", "hl");
+         emit2 ("push hl");
          spillPair (PAIR_HL);
          _G.stack.pushed += 2;
          fetchPairLong (PAIR_HL, AOP (IC_LEFT (ic)), 0);
-         emitcode ("push", "hl");
+         emit2 ("push hl");
          spillPair (PAIR_HL);
          _G.stack.pushed += 2;
          goto release;
@@ -1807,8 +1909,8 @@ genIpush (iCode * ic)
              l = aopGet (AOP (IC_LEFT (ic)), --offset, FALSE);
              emit2 ("ld a,%s", l);
            }
-         emitcode ("push", "af");
-         emitcode ("inc", "sp");
+         emit2 ("push af");
+         emit2 ("inc sp");
          _G.stack.pushed++;
        }
     }
@@ -1834,14 +1936,14 @@ genIpop (iCode * ic)
   offset = (size - 1);
   if (isPair (AOP (IC_LEFT (ic))))
     {
-      emitcode ("pop", getPairName (AOP (IC_LEFT (ic))));
+      emit2 ("pop %s", getPairName (AOP (IC_LEFT (ic))));
     }
   else
     {
       while (size--)
        {
-         emitcode ("dec", "sp");
-         emitcode ("pop", "hl");
+         emit2 ("dec sp");
+         emit2 ("pop hl");
          spillPair (PAIR_HL);
          aopPut (AOP (IC_LEFT (ic)), "l", offset--);
        }
@@ -1850,22 +1952,30 @@ genIpop (iCode * ic)
   freeAsmop (IC_LEFT (ic), NULL, ic);
 }
 
-static int
-_isPairUsed (iCode * ic, PAIR_ID pairId)
+/* This is quite unfortunate */
+static void
+setArea (int inHome)
 {
-  int ret = 0;
-  switch (pairId)
-    {
-    case PAIR_DE:
-      if (bitVectBitValue (ic->rUsed, D_IDX))
-       ret++;
-      if (bitVectBitValue (ic->rUsed, E_IDX))
-       ret++;
-      break;
-    default:
-      wassert (0);
-    }
-  return ret;
+  /*
+    static int lastArea = 0;
+
+     if (_G.in_home != inHome) {
+     if (inHome) {
+     const char *sz = port->mem.code_name;
+     port->mem.code_name = "HOME";
+     emit2("!area", CODE_NAME);
+     port->mem.code_name = sz;
+     }
+     else
+     emit2("!area", CODE_NAME); */
+  _G.in_home = inHome;
+  //    }
+}
+
+static bool
+isInHome (void)
+{
+  return _G.in_home;
 }
 
 static int
@@ -1894,6 +2004,14 @@ _opUsesPair (operand * op, iCode * ic, PAIR_ID pairId)
              if (!strcmp (aop->aopu.aop_reg[i]->name, "d"))
                ret++;
            }
+          else if (pairId == PAIR_BC)
+            {
+             emit2 ("; name %s", aop->aopu.aop_reg[i]->name);
+             if (!strcmp (aop->aopu.aop_reg[i]->name, "c"))
+               ret++;
+             if (!strcmp (aop->aopu.aop_reg[i]->name, "b"))
+               ret++;
+            }
          else
            {
              wassert (0);
@@ -1905,117 +2023,81 @@ _opUsesPair (operand * op, iCode * ic, PAIR_ID pairId)
   return ret;
 }
 
-/* This is quite unfortunate */
-static void
-setArea (int inHome)
-{
-  static int lastArea = 0;
-
-  /*
-     if (_G.in_home != inHome) {
-     if (inHome) {
-     const char *sz = port->mem.code_name;
-     port->mem.code_name = "HOME";
-     emit2("!area", CODE_NAME);
-     port->mem.code_name = sz;
-     }
-     else
-     emit2("!area", CODE_NAME); */
-  _G.in_home = inHome;
-  //    }
-}
-
-static bool
-isInHome (void)
-{
-  return _G.in_home;
-}
-
 /** Emit the code for a call statement
  */
 static void
 emitCall (iCode * ic, bool ispcall)
 {
-  int pushed_de = 0;
   sym_link *detype = getSpec (operandType (IC_LEFT (ic)));
 
+  bitVect *rInUse = bitVectCplAnd (bitVectCopy (ic->rMask), ic->rUsed);
+
   /* if caller saves & we have not saved then */
   if (!ic->regsSaved)
     {
       /* PENDING */
     }
 
+  _saveRegsForCall(ic, _G.sendSet ? elementsInSet(_G.sendSet) : 0);
+
   /* if send set is not empty then assign */
-  if (sendSet)
+  if (_G.sendSet)
     {
       iCode *sic;
       int send = 0;
-      int n = elementsInSet (sendSet);
-      if (IS_Z80 && n == 2 && _isPairUsed (ic, PAIR_DE))
-       {
-         /* Only push de if it is used and if it's not used
-            in the return value */
-         /* Panic if partly used */
-         if (_opUsesPair (IC_RESULT (ic), ic, PAIR_DE) == 1)
-           {
-             emit2 ("; Warning: de crossover");
-           }
-         else if (!_opUsesPair (IC_RESULT (ic), ic, PAIR_DE))
-           {
-             /* Store away de */
-             _push (PAIR_DE);
-             pushed_de = 1;
-           }
-       }
-      /* PENDING: HACK */
-      if (IS_Z80 && n == 2)
-       {
-         /* Want to load HL first, then DE as HL may = DE */
-         sic = setFirstItem (sendSet);
-         sic = setNextItem (sendSet);
-         aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
-         fetchPair (PAIR_HL, AOP (IC_LEFT (sic)));
-         send++;
-         freeAsmop (IC_LEFT (sic), NULL, sic);
-         sic = setFirstItem (sendSet);
-         aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
-         fetchPair (PAIR_DE, AOP (IC_LEFT (sic)));
-         send++;
-         freeAsmop (IC_LEFT (sic), NULL, sic);
-       }
-      else
-       {
-         for (sic = setFirstItem (sendSet); sic;
-              sic = setNextItem (sendSet))
-           {
-             int size;
-             aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
-             size = AOP_SIZE (IC_LEFT (sic));
-             wassert (size <= 2);
-             /* Always send in pairs */
-             switch (send)
-               {
-               case 0:
-                 if (IS_Z80 && n == 1)
-                   fetchPair (PAIR_HL, AOP (IC_LEFT (sic)));
-                 else
-                   fetchPair (PAIR_DE, AOP (IC_LEFT (sic)));
-                 break;
-               case 1:
-                 fetchPair (PAIR_HL, AOP (IC_LEFT (sic)));
-                 break;
-               default:
-                 /* Send set too big */
-                 wassert (0);
-               }
-             send++;
-             freeAsmop (IC_LEFT (sic), NULL, sic);
-           }
-       }
-      sendSet = NULL;
-      if (pushed_de)
-       {
-       }
+      int nSend = elementsInSet(_G.sendSet);
+      bool swapped = FALSE;
+
+      int _z80_sendOrder[] = {
+        PAIR_BC, PAIR_DE
+      };
+
+      if (nSend > 1) {
+        /* Check if the parameters are swapped.  If so route through hl instead. */
+        wassertl (nSend == 2, "Pedantic check.  Code only checks for the two send items case.");
+
+        sic = setFirstItem(_G.sendSet);
+        sic = setNextItem(_G.sendSet);
+
+        if (_opUsesPair (IC_LEFT(sic), sic, _z80_sendOrder[0])) {
+          /* The second send value is loaded from one the one that holds the first
+             send, i.e. it is overwritten. */
+          /* Cache the first in HL, and load the second from HL instead. */
+          emit2 ("ld h,%s", _pairs[_z80_sendOrder[0]].h);
+          emit2 ("ld l,%s", _pairs[_z80_sendOrder[0]].l);
+
+          swapped = TRUE;
+        }
+      }
+
+      for (sic = setFirstItem (_G.sendSet); sic;
+           sic = setNextItem (_G.sendSet))
+        {
+          int size;
+          aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
+
+          size = AOP_SIZE (IC_LEFT (sic));
+          wassertl (size <= 2, "Tried to send a parameter that is bigger than two bytes");
+          wassertl (_z80_sendOrder[send] != PAIR_INVALID, "Tried to send more parameters than we have registers for");
+
+          // PENDING: Mild hack
+          if (swapped == TRUE && send == 1) {
+            if (size > 1) {
+              emit2 ("ld %s,h", _pairs[_z80_sendOrder[send]].h);
+            }
+            else {
+              emit2 ("ld %s,!zero", _pairs[_z80_sendOrder[send]].h);
+            }
+            emit2 ("ld %s,l", _pairs[_z80_sendOrder[send]].l);
+          }
+          else {
+            fetchPair(_z80_sendOrder[send], AOP (IC_LEFT (sic)));
+          }
+
+          send++;
+          freeAsmop (IC_LEFT (sic), NULL, sic);
+        }
+      _G.sendSet = NULL;
     }
 
   if (ispcall)
@@ -2028,15 +2110,15 @@ emitCall (iCode * ic, bool ispcall)
 
       if (isLitWord (AOP (IC_LEFT (ic))))
        {
-         emitcode ("", "; Special case where the pCall is to a constant");
-         emitcode ("call", aopGetLitWordLong (AOP (IC_LEFT (ic)), 0, FALSE));
+         emit2 ("; Special case where the pCall is to a constant");
+         emit2 ("call %s", aopGetLitWordLong (AOP (IC_LEFT (ic)), 0, FALSE));
        }
       else
        {
          symbol *rlbl = newiTempLabel (NULL);
          spillPair (PAIR_HL);
          emit2 ("ld hl,!immed!tlabel", (rlbl->key + 100));
-         emitcode ("push", "hl");
+         emit2 ("push hl");
          _G.stack.pushed += 2;
 
          fetchHL (AOP (IC_LEFT (ic)));
@@ -2065,6 +2147,9 @@ emitCall (iCode * ic, bool ispcall)
     }
   spillCached ();
 
+  /* Mark the regsiters as restored. */
+  _G.saves.saved = FALSE;
+
   /* if we need assign a result value */
   if ((IS_ITEMP (IC_RESULT (ic)) &&
        (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
@@ -2072,9 +2157,7 @@ emitCall (iCode * ic, bool ispcall)
       IS_TRUE_SYMOP (IC_RESULT (ic)))
     {
 
-      accInUse++;
       aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
-      accInUse--;
 
       assignResultValue (IC_RESULT (ic));
 
@@ -2082,9 +2165,10 @@ emitCall (iCode * ic, bool ispcall)
     }
 
   /* adjust the stack for parameters if required */
-  if (IC_LEFT (ic)->parmBytes)
+  if (ic->parmBytes)
     {
-      int i = IC_LEFT (ic)->parmBytes;
+      int i = ic->parmBytes;
+
       _G.stack.pushed -= i;
       if (IS_GB)
        {
@@ -2095,25 +2179,77 @@ emitCall (iCode * ic, bool ispcall)
          spillCached ();
          if (i > 6)
            {
-             emitcode ("ld", "hl,#%d", i);
-             emitcode ("add", "hl,sp");
-             emitcode ("ld", "sp,hl");
+             emit2 ("ld hl,#%d", i);
+             emit2 ("add hl,sp");
+             emit2 ("ld sp,hl");
            }
          else
            {
              while (i > 1)
                {
-                 emitcode ("pop", "hl");
+                 emit2 ("pop hl");
                  i -= 2;
                }
              if (i)
-               emitcode ("inc", "sp");
+               emit2 ("inc sp");
            }
          spillCached ();
        }
     }
-  if (pushed_de)
-    _pop (PAIR_DE);
+
+  if (_G.stack.pushedDE) 
+    {
+      bool dInUse = bitVectBitValue(rInUse, D_IDX);
+      bool eInUse = bitVectBitValue(rInUse, E_IDX);
+
+      if (dInUse && eInUse) 
+        {
+          _pop (PAIR_DE);
+        }
+      else if (dInUse)
+        {
+          _pop(PAIR_HL);
+          emit2 ("ld d,h");
+        }
+      else if (eInUse)
+        {
+          _pop(PAIR_HL);
+          emit2 ("ld e,l");
+        }
+      else
+        {
+          wassertl (0, "Neither D or E were in use but it was pushed.");
+        }
+      _G.stack.pushedDE = FALSE;
+    }
+  
+  if (_G.stack.pushedBC) 
+    {
+      bool bInUse = bitVectBitValue(rInUse, B_IDX);
+      bool cInUse = bitVectBitValue(rInUse, C_IDX);
+
+      // If both B and C are used in the return value, then we won't get
+      // here.
+      if (bInUse && cInUse) 
+        {
+          _pop (PAIR_BC);
+        }
+      else if (bInUse)
+        {
+          _pop(PAIR_HL);
+          emit2 ("ld b,h");
+        }
+      else if (cInUse)
+        {
+          _pop(PAIR_HL);
+          emit2 ("ld c,l");
+        }
+      else
+        {
+          wassertl (0, "Neither B or C were in use but it was pushed.");
+        }
+      _G.stack.pushedBC = FALSE;
+    }
 }
 
 /*-----------------------------------------------------------------*/
@@ -2122,7 +2258,6 @@ emitCall (iCode * ic, bool ispcall)
 static void
 genCall (iCode * ic)
 {
-  sym_link *detype = getSpec (operandType (IC_LEFT (ic)));
   emitCall (ic, FALSE);
 }
 
@@ -2156,6 +2291,15 @@ resultRemat (iCode * ic)
 
 extern set *publics;
 
+/* Steps:
+    o Check genFunction
+    o Check emitCall and clean up
+    o Check genReturn
+    o Check return puller
+
+    PENDING: Remove this.
+*/
+
 /*-----------------------------------------------------------------*/
 /* genFunction - generated code for function entry                 */
 /*-----------------------------------------------------------------*/
@@ -2165,16 +2309,30 @@ genFunction (iCode * ic)
   symbol *sym = OP_SYMBOL (IC_LEFT (ic));
   sym_link *fetype;
 
-  nregssaved = 0;
+#if CALLEE_SAVES
+  bool bcInUse = FALSE;
+  bool deInUse = FALSE;
+#endif
+
   setArea (IS_NONBANKED (sym->etype));
 
+  /* PENDING: Reset the receive offset as it doesn't seem to get reset anywhere
+     else.
+  */
+  _G.receiveOffset = 0;
+
+#if 0
   /* PENDING: hack */
   if (!IS_STATIC (sym->etype))
     {
       addSetIfnotP (&publics, sym);
     }
+#endif
 
-  /* create the function header */
+  /* Record the last function name for debugging. */
+  _G.lastFunctionName = sym->rname;
+  
+  /* Create the function header */
   emit2 ("!functionheader", sym->name);
   /* PENDING: portability. */
   emit2 ("__%s_start:", sym->rname);
@@ -2186,18 +2344,18 @@ genFunction (iCode * ic)
   if (SPEC_CRTCL (fetype))
     emit2 ("!di");
 
-  /* if this is an interrupt service routine then
-     save acc, b, dpl, dph  */
+  /* if this is an interrupt service routine then save all potentially used registers. */
   if (IS_ISR (sym->etype))
     {
       emit2 ("!pusha");
     }
+
   /* PENDING: callee-save etc */
 
-  /* If BC or DE are used, then push */
-  _G.stack.pushed_bc = 0;
-  _G.stack.pushed_de = 0;
   _G.stack.param_offset = 0;
+
+#if CALLEE_SAVES
+  /* Detect which registers are used. */
   if (sym->regsUsed)
     {
       int i;
@@ -2209,28 +2367,39 @@ genFunction (iCode * ic)
                {
                case C_IDX:
                case B_IDX:
-                 _G.stack.pushed_bc = 1;
+                  bcInUse = TRUE;
                  break;
                case D_IDX:
                case E_IDX:
-                 if (IS_Z80)
-                   _G.stack.pushed_de = 1;
+                 if (IS_Z80) {
+                    deInUse = TRUE;
+                  }
+                  else {
+                    /* Other systems use DE as a temporary. */
+                  }
                  break;
                }
            }
        }
-      if (_G.stack.pushed_bc)
-       {
-         emit2 ("push bc");
-         _G.stack.param_offset += 2;
-       }
-      if (_G.stack.pushed_de)
-       {
-         emit2 ("push de");
-         _G.stack.param_offset += 2;
-       }
     }
 
+  if (bcInUse) 
+    {
+      emit2 ("push bc");
+      _G.stack.param_offset += 2;
+    }
+
+  _G.stack.pushedBC = bcInUse;
+
+  if (deInUse)
+    {
+      emit2 ("push de");
+      _G.stack.param_offset += 2;
+    }
+
+  _G.stack.pushedDE = deInUse;
+#endif
+
   /* adjust the stack for the function */
   _G.stack.last = sym->stack;
 
@@ -2260,35 +2429,36 @@ genEndFunction (iCode * ic)
 
       /* PENDING: calleeSave */
 
-      /* if debug then send end of function */
-      if (options.debug && currFunc)
-       {
-         debugLine = 1;
-         emitcode ("", "C$%s$%d$%d$%d ==.",
-                   FileBaseName (ic->filename), currFunc->lastLine,
-                   ic->level, ic->block);
-         if (IS_STATIC (currFunc->etype))
-           emitcode ("", "XF%s$%s$0$0 ==.", moduleName, currFunc->name);
-         else
-           emitcode ("", "XG$%s$0$0 ==.", currFunc->name);
-         debugLine = 0;
-       }
       if (_G.stack.offset)
-       emit2 ("!leavex", _G.stack.offset);
+        {
+          emit2 ("!leavex", _G.stack.offset);
+        }
       else
-       emit2 ("!leave");
+        {
+          emit2 ("!leave");
+        }
+
+#if CALLEE_SAVES
+      if (_G.stack.pushedDE) 
+        {
+          emit2 ("pop de");
+          _G.stack.pushedDE = FALSE;
+        }
+
+      if (_G.stack.pushedDE) 
+        {
+          emit2 ("pop bc");
+          _G.stack.pushedDE = FALSE;
+        }
+#endif
 
-      if (_G.stack.pushed_de)
-       emit2 ("pop de");
-      if (_G.stack.pushed_bc)
-       emit2 ("pop bc");
       /* Both baned and non-banked just ret */
       emit2 ("ret");
 
       /* PENDING: portability. */
       emit2 ("__%s_end:", sym->rname);
     }
-  _G.flush_statics = 1;
+  _G.flushStatics = 1;
   _G.stack.pushed = 0;
   _G.stack.offset = 0;
 }
@@ -2299,7 +2469,7 @@ genEndFunction (iCode * ic)
 static void
 genRet (iCode * ic)
 {
-  char *l;
+    const char *l;
   /* Errk.  This is a hack until I can figure out how
      to cause dehl to spill on a call */
   int size, offset = 0;
@@ -2318,11 +2488,11 @@ genRet (iCode * ic)
     {
       if (IS_GB)
        {
-         emitcode ("ld", "de,%s", l);
+         emit2 ("ld de,%s", l);
        }
       else
        {
-         emitcode ("ld", "hl,%s", l);
+         emit2 ("ld hl,%s", l);
        }
     }
   else
@@ -2339,7 +2509,7 @@ genRet (iCode * ic)
              l = aopGet (AOP (IC_LEFT (ic)), offset,
                          FALSE);
              if (strcmp (_fReturn[offset], l))
-               emitcode ("ld", "%s,%s", _fReturn[offset++], l);
+               emit2 ("ld %s,%s", _fReturn[offset++], l);
            }
        }
     }
@@ -2392,9 +2562,9 @@ genPlusIncr (iCode * ic)
   if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
     return FALSE;
 
-  emitcode ("", "; genPlusIncr");
+  emit2 ("; genPlusIncr");
 
-  icount = floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+  icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
 
   /* If result is a pair */
   if (resultId != PAIR_INVALID)
@@ -2407,7 +2577,7 @@ genPlusIncr (iCode * ic)
       if (isPair (AOP (IC_LEFT (ic))) && resultId == PAIR_HL && icount > 2)
        {
          fetchPair (resultId, AOP (IC_RIGHT (ic)));
-         emitcode ("add", "hl,%s", getPairName (AOP (IC_LEFT (ic))));
+         emit2 ("add hl,%s", getPairName (AOP (IC_LEFT (ic))));
          return TRUE;
        }
       if (icount > 5)
@@ -2422,7 +2592,7 @@ genPlusIncr (iCode * ic)
        }
       while (icount--)
        {
-         emitcode ("inc", "%s", getPairName (AOP (IC_RESULT (ic))));
+         emit2 ("inc %s", getPairName (AOP (IC_RESULT (ic))));
        }
       return TRUE;
     }
@@ -2443,7 +2613,7 @@ genPlusIncr (iCode * ic)
       tlbl = newiTempLabel (NULL);
       while (size--)
        {
-         emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), offset++, FALSE));
+         emit2 ("inc %s", aopGet (AOP (IC_RESULT (ic)), offset++, FALSE));
          if (size)
            {
              emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
@@ -2464,7 +2634,7 @@ genPlusIncr (iCode * ic)
   if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
     {
       while (icount--)
-       emitcode ("inc", "%s", aopGet (AOP (IC_LEFT (ic)), 0, FALSE));
+       emit2 ("inc %s", aopGet (AOP (IC_LEFT (ic)), 0, FALSE));
       return TRUE;
     }
 
@@ -2560,7 +2730,7 @@ genPlus (iCode * ic)
          /* PENDING: fix */
          char buffer[100];
          sprintf (buffer, "#(%s + %s)", left, right);
-         emitcode ("ld", "%s,%s", getPairName (AOP (IC_RESULT (ic))), buffer);
+         emit2 ("ld %s,%s", getPairName (AOP (IC_RESULT (ic))), buffer);
          goto release;
        }
     }
@@ -2570,7 +2740,7 @@ genPlus (iCode * ic)
       /* Fetch into HL then do the add */
       spillPair (PAIR_HL);
       fetchPair (PAIR_HL, AOP (IC_LEFT (ic)));
-      emitcode ("add", "hl,%s", getPairName (AOP (IC_RIGHT (ic))));
+      emit2 ("add hl,%s", getPairName (AOP (IC_RIGHT (ic))));
       goto release;
     }
 
@@ -2645,7 +2815,7 @@ genPlus (iCode * ic)
     {
       if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC)
        {
-         MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
+         _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
          if (offset == 0)
            emit2 ("add a,%s",
                   aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
@@ -2655,7 +2825,7 @@ genPlus (iCode * ic)
        }
       else
        {
-         MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
+         _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
          if (offset == 0)
            emit2 ("add a,%s",
                   aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
@@ -2701,10 +2871,10 @@ genMinusDec (iCode * ic)
       (icount == 1))
     {
       symbol *tlbl = newiTempLabel (NULL);
-      emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE));
-      emitcode ("jp", "np," LABEL_STR, tlbl->key + 100);
+      emit2 ("dec %s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE));
+      emit2 ("jp np," LABEL_STR, tlbl->key + 100);
 
-      emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE));
+      emit2 ("dec %s", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE));
       if (size == 4)
        {
          wassert (0);
@@ -2719,7 +2889,7 @@ genMinusDec (iCode * ic)
       (size > 1) && isPair (AOP (IC_RESULT (ic))))
     {
       while (icount--)
-       emitcode ("dec", "%s", getPairName (AOP (IC_RESULT (ic))));
+       emit2 ("dec %s", getPairName (AOP (IC_RESULT (ic))));
       return TRUE;
     }
 
@@ -2729,7 +2899,7 @@ genMinusDec (iCode * ic)
       movLeft2Result (IC_LEFT (ic), 0, IC_RESULT (ic), 0, 0);
       movLeft2Result (IC_LEFT (ic), 1, IC_RESULT (ic), 1, 0);
       while (icount--)
-       emitcode ("dec", "%s", getPairName (AOP (IC_RESULT (ic))));
+       emit2 ("dec %s", getPairName (AOP (IC_RESULT (ic))));
       return TRUE;
     }
 
@@ -2743,7 +2913,7 @@ genMinusDec (iCode * ic)
   if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
     {
       while (icount--)
-       emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE));
+       emit2 ("dec %s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE));
       return TRUE;
     }
 
@@ -2836,14 +3006,14 @@ genMinus (iCode * ic)
   /* if literal, add a,#-lit, else normal subb */
   while (size--)
     {
-      MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
+      _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
       if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
        {
          if (!offset)
-           emitcode ("sub", "a,%s",
+           emit2 ("sub a,%s",
                      aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
          else
-           emitcode ("sbc", "a,%s",
+           emit2 ("sbc a,%s",
                      aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
        }
       else
@@ -2955,7 +3125,7 @@ genIfxJump (iCode * ic, char *jval)
   /* Z80 can do a conditional long jump */
   if (!strcmp (jval, "a"))
     {
-      emitcode ("or", "a,a");
+      emit2 ("or a,a");
     }
   else if (!strcmp (jval, "c"))
     {
@@ -2965,7 +3135,7 @@ genIfxJump (iCode * ic, char *jval)
     }
   else
     {
-      emitcode ("bit", "%s,a", jval);
+      emit2 ("bit %s,a", jval);
     }
   emit2 ("jp %s,!tlabel", inst, jlbl->key + 100);
 
@@ -3007,14 +3177,14 @@ genCmp (operand * left, operand * right,
       if ((size == 1) &&
          (AOP_TYPE (right) == AOP_LIT && AOP_TYPE (left) != AOP_DIR))
        {
-         emitcode ("ld", "a,%s", aopGet (AOP (left), offset, FALSE));
+         emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE));
          if (sign)
            {
              emit2 ("xor a,!immedbyte", 0x80);
              emit2 ("cp %s^!constbyte", aopGet (AOP (right), offset, FALSE), 0x80);
            }
          else
-           emitcode ("cp", "%s", aopGet (AOP (right), offset, FALSE));
+           emit2 ("cp %s", aopGet (AOP (right), offset, FALSE));
        }
       else
        {
@@ -3023,7 +3193,7 @@ genCmp (operand * left, operand * right,
             If the left or the right is a lit:
             Load -lit into HL, add to right via, check sense.
           */
-         if (size == 2 && (AOP_TYPE (right) == AOP_LIT || AOP_TYPE (left) == AOP_LIT))
+         if (IS_GB && size == 2 && (AOP_TYPE (right) == AOP_LIT || AOP_TYPE (left) == AOP_LIT))
            {
              PAIR_ID id = PAIR_DE;
              asmop *lit = AOP (right);
@@ -3066,19 +3236,19 @@ genCmp (operand * left, operand * right,
                  if (!sign)
                    {
                      /* No sign so it's always false */
-                     CLRC;
+                     _clearCarry();
                    }
                  else
                    {
                      /* Just load in the top most bit */
-                     MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE));
+                     _moveA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE));
                      if (!(AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result)) && ifx)
                        {
                          genIfxJump (ifx, "7");
                          return;
                        }
                      else
-                       emitcode ("rlc", "a");
+                       emit2 ("rlc a");
                    }
                  goto release;
                }
@@ -3096,9 +3266,9 @@ genCmp (operand * left, operand * right,
                }
              else
                {
-                 emitcode ("ld", "a,%s", aopGet (AOP (left), size - 1, FALSE));
+                 emit2 ("ld a,%s", aopGet (AOP (left), size - 1, FALSE));
                  emit2 ("xor a,!immedbyte", 0x80);
-                 emitcode ("ld", "%s,a", _fTmp[0]);
+                 emit2 ("ld %s,a", _fTmp[0]);
                  fDidXor = TRUE;
                }
              if (AOP_TYPE (right) == AOP_LIT)
@@ -3110,34 +3280,34 @@ genCmp (operand * left, operand * right,
                }
              else
                {
-                 emitcode ("ld", "a,%s", aopGet (AOP (right), size - 1, FALSE));
+                 emit2 ("ld a,%s", aopGet (AOP (right), size - 1, FALSE));
                  emit2 ("xor a,!immedbyte", 0x80);
-                 emitcode ("ld", "%s,a", _fTmp[1]);
+                 emit2 ("ld %s,a", _fTmp[1]);
                  fDidXor = TRUE;
                }
              if (!fDidXor)
-               CLRC;
+               _clearCarry();
            }
          else
            {
-             CLRC;
+             _clearCarry();
            }
          while (size--)
            {
              /* Do a long subtract */
              if (!sign || size)
                {
-                 MOVA (aopGet (AOP (left), offset, FALSE));
+                 _moveA (aopGet (AOP (left), offset, FALSE));
                }
              if (sign && size == 0)
                {
-                 emitcode ("ld", "a,%s", _fTmp[0]);
-                 emitcode ("sbc", "a,%s", _fTmp[1]);
+                 emit2 ("ld a,%s", _fTmp[0]);
+                 emit2 ("sbc a,%s", _fTmp[1]);
                }
              else
                {
                  /* Subtract through, propagating the carry */
-                 emitcode ("sbc", "a,%s ; 2", aopGet (AOP (right), offset++, FALSE));
+                 emit2 ("sbc a,%s ; 2", aopGet (AOP (right), offset++, FALSE));
                }
            }
        }
@@ -3247,19 +3417,19 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
     {
       if (lit == 0)
        {
-         emitcode ("ld", "a,%s", aopGet (AOP (left), offset, FALSE));
+         emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE));
          if (size > 1)
            {
              size--;
              offset++;
              while (size--)
                {
-                 emitcode ("or", "a,%s", aopGet (AOP (left), offset, FALSE));
+                 emit2 ("or a,%s", aopGet (AOP (left), offset, FALSE));
                }
            }
          else
            {
-             emitcode ("or", "a,a");
+             emit2 ("or a,a");
            }
          emit2 ("jp nz,!tlabel", lbl->key + 100);
        }
@@ -3267,11 +3437,11 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
        {
          while (size--)
            {
-             emitcode ("ld", "a,%s ; 2", aopGet (AOP (left), offset, FALSE));
+             emit2 ("ld a,%s ; 2", aopGet (AOP (left), offset, FALSE));
              if ((AOP_TYPE (right) == AOP_LIT) && lit == 0)
-               emitcode ("or", "a,a");
+               emit2 ("or a,a");
              else
-               emitcode ("cp", "a,%s", aopGet (AOP (right), offset, FALSE));
+               emit2 ("cp a,%s", aopGet (AOP (right), offset, FALSE));
              emit2 ("jp nz,!tlabel", lbl->key + 100);
              offset++;
            }
@@ -3285,14 +3455,14 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
     {
       while (size--)
        {
-         MOVA (aopGet (AOP (left), offset, FALSE));
+         _moveA (aopGet (AOP (left), offset, FALSE));
          if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) &&
              ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
            /* PENDING */
            emit2 ("jp nz,!tlabel", lbl->key + 100);
          else
            {
-             emitcode ("cp", "%s ; 4", aopGet (AOP (right), offset, FALSE));
+             emit2 ("cp %s ; 4", aopGet (AOP (right), offset, FALSE));
              emit2 ("jp nz,!tlabel", lbl->key + 100);
            }
          offset++;
@@ -3304,8 +3474,8 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
       /* PENDING: is this required? */
       while (size--)
        {
-         MOVA (aopGet (AOP (right), offset, FALSE));
-         emitcode ("cp", "%s ; 5", aopGet (AOP (left), offset, FALSE));
+         _moveA (aopGet (AOP (right), offset, FALSE));
+         emit2 ("cp %s ; 5", aopGet (AOP (left), offset, FALSE));
          emit2 ("!shortjp nz,!tlabel", lbl->key + 100);
          offset++;
        }
@@ -3326,7 +3496,7 @@ gencjne (operand * left, operand * right, symbol * lbl)
   emit2 ("ld a,!one");
   emit2 ("!shortjp !tlabel", tlbl->key + 100);
   emitLabel (lbl->key + 100);
-  emitcode ("xor", "a,a");
+  emit2 ("xor a,a");
   emitLabel (tlbl->key + 100);
 }
 
@@ -3342,6 +3512,8 @@ genCmpEq (iCode * ic, iCode * ifx)
   aopOp ((right = IC_RIGHT (ic)), ic, FALSE, FALSE);
   aopOp ((result = IC_RESULT (ic)), ic, TRUE, FALSE);
 
+  emit2("; genCmpEq: left %u, right %u, result %u\n", AOP_SIZE(IC_LEFT(ic)), AOP_SIZE(IC_RIGHT(ic)), AOP_SIZE(IC_RESULT(ic)));
+
   /* Swap operands if it makes the operation easier. ie if:
      1.  Left is a literal.
    */
@@ -3575,10 +3747,10 @@ genAnd (iCode * ic, iCode * ifx)
   aopOp ((result = IC_RESULT (ic)), ic, TRUE, FALSE);
 
 #ifdef DEBUG_TYPE
-  emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+  emit2 ("; Type res[%d] = l[%d]&r[%d]",
            AOP_TYPE (result),
            AOP_TYPE (left), AOP_TYPE (right));
-  emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
+  emit2 ("; Size res[%d] = l[%d]&r[%d]",
            AOP_SIZE (result),
            AOP_SIZE (left), AOP_SIZE (right));
 #endif
@@ -3630,12 +3802,12 @@ genAnd (iCode * ic, iCode * ifx)
       if (posbit)
        {
          posbit--;
-         MOVA (aopGet (AOP (left), posbit >> 3, FALSE));
+         _moveA (aopGet (AOP (left), posbit >> 3, FALSE));
          // bit = left & 2^n
          if (size)
            {
              wassert (0);
-             emitcode ("mov", "c,acc.%d", posbit & 0x07);
+             emit2 ("mov c,acc.%d", posbit & 0x07);
            }
          // if(left &  2^n)
          else
@@ -3659,23 +3831,23 @@ genAnd (iCode * ic, iCode * ifx)
          if (size)
            {
              wassert (0);
-             emitcode ("setb", "c");
+             emit2 ("setb c");
            }
          while (sizel--)
            {
              if ((bytelit = ((lit >> (offset * 8)) & 0x0FFL)) != 0x0L)
                {
-                 MOVA (aopGet (AOP (left), offset, FALSE));
+                 _moveA (aopGet (AOP (left), offset, FALSE));
                  // byte ==  2^n ?
                  if ((posbit = isLiteralBit (bytelit)) != 0)
                    {
                      wassert (0);
-                     emitcode ("jb", "acc.%d,%05d$", (posbit - 1) & 0x07, tlbl->key + 100);
+                     emit2 ("jb acc.%d,%05d$", (posbit - 1) & 0x07, tlbl->key + 100);
                    }
                  else
                    {
                      if (bytelit != 0x0FFL)
-                       emitcode ("and", "a,%s",
+                       emit2 ("and a,%s",
                                  aopGet (AOP (right), offset, FALSE));
                      else
                        /* For the flags */
@@ -3688,7 +3860,7 @@ genAnd (iCode * ic, iCode * ifx)
          // bit = left & literal
          if (size)
            {
-             emitcode ("clr", "c");
+             emit2 ("clr c");
              emit2 ("!tlabeldef", tlbl->key + 100);
            }
          // if(left & literal)
@@ -3715,11 +3887,11 @@ genAnd (iCode * ic, iCode * ifx)
              else
                {
                  if (bytelit == 0)
-                   aopPut (AOP (result), zero, offset);
+                   aopPut (AOP (result), "!zero", offset);
                  else
                    {
-                     MOVA (aopGet (AOP (left), offset, FALSE));
-                     emitcode ("and", "a,%s",
+                     _moveA (aopGet (AOP (left), offset, FALSE));
+                     emit2 ("and a,%s",
                                aopGet (AOP (right), offset, FALSE));
                      aopPut (AOP (left), "a", offset);
                    }
@@ -3734,8 +3906,8 @@ genAnd (iCode * ic, iCode * ifx)
                }
              else
                {
-                 MOVA (aopGet (AOP (left), offset, FALSE));
-                 emitcode ("and", "a,%s",
+                 _moveA (aopGet (AOP (left), offset, FALSE));
+                 emit2 ("and a,%s",
                            aopGet (AOP (right), offset, FALSE));
                  aopPut (AOP (left), "a", offset);
                }
@@ -3766,18 +3938,18 @@ genAnd (iCode * ic, iCode * ifx)
                    }
                  else if (bytelit == 0)
                    {
-                     aopPut (AOP (result), zero, offset);
+                     aopPut (AOP (result), "!zero", offset);
                      continue;
                    }
                }
              // faster than result <- left, anl result,right
              // and better if result is SFR
              if (AOP_TYPE (left) == AOP_ACC)
-               emitcode ("and", "a,%s", aopGet (AOP (right), offset, FALSE));
+               emit2 ("and a,%s", aopGet (AOP (right), offset, FALSE));
              else
                {
-                 MOVA (aopGet (AOP (left), offset, FALSE));
-                 emitcode ("and", "a,%s",
+                 _moveA (aopGet (AOP (left), offset, FALSE));
+                 emit2 ("and a,%s",
                            aopGet (AOP (right), offset, FALSE));
                }
              aopPut (AOP (result), "a", offset);
@@ -3807,10 +3979,10 @@ genOr (iCode * ic, iCode * ifx)
   aopOp ((result = IC_RESULT (ic)), ic, TRUE, FALSE);
 
 #if 1
-  emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+  emit2 ("; Type res[%d] = l[%d]&r[%d]",
            AOP_TYPE (result),
            AOP_TYPE (left), AOP_TYPE (right));
-  emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
+  emit2 ("; Size res[%d] = l[%d]&r[%d]",
            AOP_SIZE (result),
            AOP_SIZE (left), AOP_SIZE (right));
 #endif
@@ -3870,8 +4042,8 @@ genOr (iCode * ic, iCode * ifx)
                continue;
              else
                {
-                 MOVA (aopGet (AOP (left), offset, FALSE));
-                 emitcode ("or", "a,%s",
+                 _moveA (aopGet (AOP (left), offset, FALSE));
+                 emit2 ("or a,%s",
                            aopGet (AOP (right), offset, FALSE));
                  aopPut (AOP (result), "a", offset);
                }
@@ -3879,11 +4051,11 @@ genOr (iCode * ic, iCode * ifx)
          else
            {
              if (AOP_TYPE (left) == AOP_ACC)
-               emitcode ("or", "a,%s", aopGet (AOP (right), offset, FALSE));
+               emit2 ("or a,%s", aopGet (AOP (right), offset, FALSE));
              else
                {
-                 MOVA (aopGet (AOP (left), offset, FALSE));
-                 emitcode ("or", "a,%s",
+                 _moveA (aopGet (AOP (left), offset, FALSE));
+                 emit2 ("or a,%s",
                            aopGet (AOP (right), offset, FALSE));
                  aopPut (AOP (result), "a", offset);
                }
@@ -3915,11 +4087,11 @@ genOr (iCode * ic, iCode * ifx)
            // faster than result <- left, anl result,right
            // and better if result is SFR
            if (AOP_TYPE (left) == AOP_ACC)
-             emitcode ("or", "a,%s", aopGet (AOP (right), offset, FALSE));
+             emit2 ("or a,%s", aopGet (AOP (right), offset, FALSE));
            else
              {
-               MOVA (aopGet (AOP (left), offset, FALSE));
-               emitcode ("or", "a,%s",
+               _moveA (aopGet (AOP (left), offset, FALSE));
+               emit2 ("or a,%s",
                          aopGet (AOP (right), offset, FALSE));
              }
            aopPut (AOP (result), "a", offset);
@@ -4004,20 +4176,22 @@ genXor (iCode * ic, iCode * ifx)
                continue;
              else
                {
-                 MOVA (aopGet (AOP (right), offset, FALSE));
-                 emitcode ("xor", "a,%s",
+                 _moveA (aopGet (AOP (right), offset, FALSE));
+                 emit2 ("xor a,%s",
                            aopGet (AOP (left), offset, FALSE));
-                 aopPut (AOP (result), "a", 0);
+                 aopPut (AOP (result), "a", offset);
                }
            }
          else
            {
              if (AOP_TYPE (left) == AOP_ACC)
-               emitcode ("xor", "a,%s", aopGet (AOP (right), offset, FALSE));
+                {
+                  emit2 ("xor a,%s", aopGet (AOP (right), offset, FALSE));
+                }
              else
                {
-                 MOVA (aopGet (AOP (right), offset, FALSE));
-                 emitcode ("xor", "a,%s",
+                 _moveA (aopGet (AOP (right), offset, FALSE));
+                 emit2 ("xor a,%s",
                            aopGet (AOP (left), offset, FALSE));
                  aopPut (AOP (result), "a", 0);
                }
@@ -4048,14 +4222,15 @@ genXor (iCode * ic, iCode * ifx)
              }
            // faster than result <- left, anl result,right
            // and better if result is SFR
-           if (AOP_TYPE (left) == AOP_ACC)
-             emitcode ("xor", "a,%s", aopGet (AOP (right), offset, FALSE));
+           if (AOP_TYPE (left) == AOP_ACC) 
+              {
+                emit2 ("xor a,%s", aopGet (AOP (right), offset, FALSE));
+              }
            else
              {
-               MOVA (aopGet (AOP (right), offset, FALSE));
-               emitcode ("xor", "a,%s",
+               _moveA (aopGet (AOP (right), offset, FALSE));
+               emit2 ("xor a,%s",
                          aopGet (AOP (left), offset, FALSE));
-               aopPut (AOP (result), "a", 0);
              }
            aopPut (AOP (result), "a", offset);
          }
@@ -4073,11 +4248,11 @@ release:
 static void
 genInline (iCode * ic)
 {
-  char buffer[MAX_INLINEASM];
-  char *bp = buffer;
-  char *bp1 = buffer;
+  char *buffer, *bp, *bp1;
+
+  _G.lines.isInline += (!options.asmpeep);
 
-  inLine += (!options.asmpeep);
+  buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
   strcpy (buffer, IC_INLINE (ic));
 
   /* emit each line as a code */
@@ -4086,7 +4261,7 @@ genInline (iCode * ic)
       if (*bp == '\n')
        {
          *bp++ = '\0';
-         emitcode (bp1, "");
+         emit2 (bp1);
          bp1 = bp;
        }
       else
@@ -4096,7 +4271,7 @@ genInline (iCode * ic)
              bp++;
              *bp = '\0';
              bp++;
-             emitcode (bp1, "");
+             emit2 (bp1);
              bp1 = bp;
            }
          else
@@ -4104,9 +4279,9 @@ genInline (iCode * ic)
        }
     }
   if (bp1 != bp)
-    emitcode (bp1, "");
-  /*     emitcode("",buffer); */
-  inLine -= (!options.asmpeep);
+    emit2 (bp1);
+  _G.lines.isInline -= (!options.asmpeep);
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -4148,7 +4323,7 @@ shiftR2Left2Result (operand * left, int offl,
       int size = 2;
       int offset = 0;
       symbol *tlbl, *tlbl1;
-      char *l;
+      const char *l;
 
       tlbl = newiTempLabel (NULL);
       tlbl1 = newiTempLabel (NULL);
@@ -4161,17 +4336,17 @@ shiftR2Left2Result (operand * left, int offl,
          emitLabel (tlbl->key + 100);
        }
 
-      emitcode ("or", "a,a");
+      emit2 ("or a,a");
       offset = size;
       while (size--)
        {
          l = aopGet (AOP (result), --offset, FALSE);
-         emitcode ("rr", "%s", l);
+         emit2 ("rr %s", l);
        }
       if (shCount > 1)
        {
          emitLabel (tlbl1->key + 100);
-         emitcode ("dec", "a");
+         emit2 ("dec a");
          emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
        }
     }
@@ -4201,7 +4376,7 @@ shiftL2Left2Result (operand * left, int offl,
     int size = 2;
     int offset = 0;
     symbol *tlbl, *tlbl1;
-    char *l;
+    const char *l;
 
     tlbl = newiTempLabel (NULL);
     tlbl1 = newiTempLabel (NULL);
@@ -4214,16 +4389,16 @@ shiftL2Left2Result (operand * left, int offl,
        emitLabel (tlbl->key + 100);
       }
 
-    emitcode ("or", "a,a");
+    emit2 ("or a,a");
     while (size--)
       {
        l = aopGet (AOP (result), offset++, FALSE);
-       emitcode ("rl", "%s", l);
+       emit2 ("rl %s", l);
       }
     if (shCount > 1)
       {
        emitLabel (tlbl1->key + 100);
-       emitcode ("dec", "a");
+       emit2 ("dec a");
        emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
       }
   }
@@ -4242,34 +4417,34 @@ AccRol (int shCount)
     case 0:
       break;
     case 1:
-      emitcode ("rl", "a");
+      emit2 ("rl a");
       break;
     case 2:
-      emitcode ("rl", "a");
-      emitcode ("rl", "a");
+      emit2 ("rl a");
+      emit2 ("rl a");
       break;
     case 3:
-      emitcode ("rl", "a");
-      emitcode ("rl", "a");
-      emitcode ("rl", "a");
+      emit2 ("rl a");
+      emit2 ("rl a");
+      emit2 ("rl a");
       break;
     case 4:
-      emitcode ("rl", "a");
-      emitcode ("rl", "a");
-      emitcode ("rl", "a");
-      emitcode ("rl", "a");
+      emit2 ("rl a");
+      emit2 ("rl a");
+      emit2 ("rl a");
+      emit2 ("rl a");
       break;
     case 5:
-      emitcode ("rr", "a");
-      emitcode ("rr", "a");
-      emitcode ("rr", "a");
+      emit2 ("rr a");
+      emit2 ("rr a");
+      emit2 ("rr a");
       break;
     case 6:
-      emitcode ("rr", "a");
-      emitcode ("rr", "a");
+      emit2 ("rr a");
+      emit2 ("rr a");
       break;
     case 7:
-      emitcode ("rr", "a");
+      emit2 ("rr a");
       break;
     }
 }
@@ -4280,16 +4455,21 @@ AccRol (int shCount)
 static void
 AccLsh (int shCount)
 {
+  static const unsigned char SLMask[] =
+    {
+      0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00
+    };
+
   if (shCount != 0)
     {
       if (shCount == 1)
        {
-         emitcode ("add", "a,a");
+         emit2 ("add a,a");
        }
       else if (shCount == 2)
        {
-         emitcode ("add", "a,a");
-         emitcode ("add", "a,a");
+         emit2 ("add a,a");
+         emit2 ("add a,a");
        }
       else
        {
@@ -4308,9 +4488,9 @@ static void
 shiftL1Left2Result (operand * left, int offl,
                    operand * result, int offr, int shCount)
 {
-  char *l;
+  const char *l;
   l = aopGet (AOP (left), offl, FALSE);
-  MOVA (l);
+  _moveA (l);
   /* shift left accumulator */
   AccLsh (shCount);
   aopPut (AOP (result), "a", offr);
@@ -4336,18 +4516,18 @@ genlshTwo (operand * result, operand * left, int shCount)
          if (shCount)
            {
              movLeft2Result (left, LSB, result, MSB16, 0);
-             aopPut (AOP (result), zero, 0);
+             aopPut (AOP (result), "!zero", 0);
              shiftL1Left2Result (left, MSB16, result, MSB16, shCount);
            }
          else
            {
              movLeft2Result (left, LSB, result, MSB16, 0);
-             aopPut (AOP (result), zero, 0);
+             aopPut (AOP (result), "!zero", 0);
            }
        }
       else
        {
-         aopPut (AOP (result), zero, LSB);
+         aopPut (AOP (result), "!zero", LSB);
        }
     }
   /*  1 <= shCount <= 7 */
@@ -4393,7 +4573,7 @@ genLeftShiftLiteral (operand * left,
   size = getSize (operandType (result));
 
 #if VIEW_SIZE
-  emitcode ("; shift left ", "result %d, left %d", size,
+  emit2 ("; shift left  result %d, left %d", size,
            AOP_SIZE (left));
 #endif
 
@@ -4405,7 +4585,7 @@ genLeftShiftLiteral (operand * left,
 
   else if (shCount >= (size * 8))
     while (size--)
-      aopPut (AOP (result), zero, size);
+      aopPut (AOP (result), "!zero", size);
   else
     {
       switch (size)
@@ -4434,7 +4614,7 @@ static void
 genLeftShift (iCode * ic)
 {
   int size, offset;
-  char *l;
+  const char *l;
   symbol *tlbl, *tlbl1;
   operand *left, *right, *result;
 
@@ -4456,8 +4636,8 @@ genLeftShift (iCode * ic)
      count in B : Note: we take only the lower order byte since
      shifting more that 32 bits make no sense anyway, ( the largest
      size of an object can be only 32 bits ) */
-  emitcode ("ld", "a,%s", aopGet (AOP (right), 0, FALSE));
-  emitcode ("inc", "a");
+  emit2 ("ld a,%s", aopGet (AOP (right), 0, FALSE));
+  emit2 ("inc a");
   freeAsmop (right, NULL, ic);
   aopOp (left, ic, FALSE, FALSE);
   aopOp (result, ic, FALSE, FALSE);
@@ -4497,14 +4677,14 @@ genLeftShift (iCode * ic)
   emit2 ("!shortjp !tlabel", tlbl1->key + 100);
   emitLabel (tlbl->key + 100);
   l = aopGet (AOP (result), offset, FALSE);
-  emitcode ("or", "a,a");
+  emit2 ("or a,a");
   while (size--)
     {
       l = aopGet (AOP (result), offset++, FALSE);
-      emitcode ("rl", "%s", l);
+      emit2 ("rl %s", l);
     }
   emitLabel (tlbl1->key + 100);
-  emitcode ("dec", "a");
+  emit2 ("dec a");
   emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
 
   freeAsmop (left, NULL, ic);
@@ -4519,7 +4699,7 @@ genrshOne (operand * result, operand * left, int shCount)
 {
   /* Errk */
   int size = AOP_SIZE (result);
-  char *l;
+  const char *l;
 
   wassert (size == 1);
   wassert (shCount < 8);
@@ -4530,14 +4710,14 @@ genrshOne (operand * result, operand * left, int shCount)
       aopPut (AOP (result), l, 0);
       l = aopGet (AOP (result), 0, FALSE);
       while (shCount--)
-       emitcode ("srl", "%s", l);
+       emit2 ("srl %s", l);
     }
   else
     {
-      MOVA (l);
+      _moveA (l);
       while (shCount--)
        {
-         emitcode ("srl", "a");
+         emit2 ("srl a");
        }
       aopPut (AOP (result), "a", 0);
     }
@@ -4549,6 +4729,11 @@ genrshOne (operand * result, operand * left, int shCount)
 static void
 AccRsh (int shCount)
 {
+  static const unsigned char SRMask[] =
+    {
+      0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00
+    };
+
   if (shCount != 0)
     {
       /* rotate right accumulator */
@@ -4566,7 +4751,7 @@ shiftR1Left2Result (operand * left, int offl,
                    operand * result, int offr,
                    int shCount, int sign)
 {
-  MOVA (aopGet (AOP (left), offl, FALSE));
+  _moveA (aopGet (AOP (left), offl, FALSE));
   if (sign)
     {
       wassert (0);
@@ -4598,7 +4783,7 @@ genrshTwo (operand * result, operand * left,
        {
          movLeft2Result (left, MSB16, result, LSB, sign);
        }
-      aopPut (AOP (result), zero, 1);
+      aopPut (AOP (result), "!zero", 1);
     }
   /*  1 <= shCount <= 7 */
   else
@@ -4626,7 +4811,7 @@ genRightShiftLiteral (operand * left,
 
   size = getSize (operandType (result));
 
-  emitcode ("; shift right ", "result %d, left %d", size,
+  emit2 ("; shift right  result %d, left %d", size,
            AOP_SIZE (left));
 
   /* I suppose that the left size >= result size */
@@ -4637,7 +4822,7 @@ genRightShiftLiteral (operand * left,
 
   else if (shCount >= (size * 8))
     while (size--)
-      aopPut (AOP (result), zero, size);
+      aopPut (AOP (result), "!zero", size);
   else
     {
       switch (size)
@@ -4669,7 +4854,7 @@ genRightShift (iCode * ic)
   operand *right, *left, *result;
   sym_link *retype;
   int size, offset, first = 1;
-  char *l;
+  const char *l;
   bool is_signed;
 
   symbol *tlbl, *tlbl1;
@@ -4720,8 +4905,8 @@ genRightShift (iCode * ic)
        }
     }
 
-  emitcode ("ld", "a,%s", aopGet (AOP (right), 0, FALSE));
-  emitcode ("inc", "a");
+  emit2 ("ld a,%s", aopGet (AOP (right), 0, FALSE));
+  emit2 ("inc a");
   freeAsmop (right, NULL, ic);
 
   tlbl = newiTempLabel (NULL);
@@ -4737,16 +4922,16 @@ genRightShift (iCode * ic)
       if (first)
        {
          if (is_signed)
-           emitcode ("sra", "%s", l);
+           emit2 ("sra %s", l);
          else
-           emitcode ("srl", "%s", l);
+           emit2 ("srl %s", l);
          first = 0;
        }
       else
-       emitcode ("rr", "%s", l);
+       emit2 ("rr %s", l);
     }
   emitLabel (tlbl1->key + 100);
-  emitcode ("dec", "a");
+  emit2 ("dec a");
   emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
 
   freeAsmop (left, NULL, ic);
@@ -4877,7 +5062,7 @@ genGenPointerSet (operand * right,
   if (isPair (AOP (result)) && (AOP_SIZE (right) == 1))
     {
       /* Just do it */
-      char *l = aopGet (AOP (right), 0, FALSE);
+      const char *l = aopGet (AOP (right), 0, FALSE);
       const char *pair = getPairName (AOP (result));
       if (canAssignToPtr (l) && isPtr (pair))
        {
@@ -4885,7 +5070,7 @@ genGenPointerSet (operand * right,
        }
       else
        {
-         MOVA (l);
+         _moveA (l);
          emit2 ("ld !*pair,a", pair);
        }
       goto release;
@@ -4912,19 +5097,19 @@ genGenPointerSet (operand * right,
 
       while (size--)
        {
-         char *l = aopGet (AOP (right), offset, FALSE);
+         const char *l = aopGet (AOP (right), offset, FALSE);
          if (isRegOrLit (AOP (right)) && !IS_GB)
            {
              emit2 ("ld !*pair,%s", _pairs[pairId].name, l);
            }
          else
            {
-             MOVA (l);
+             _moveA (l);
              emit2 ("ld !*pair,a", _pairs[pairId].name);
            }
          if (size)
            {
-             emitcode ("inc", _pairs[pairId].name);
+             emit2 ("inc %s", _pairs[pairId].name);
              _G.pairs[pairId].offset++;
            }
          offset++;
@@ -5015,8 +5200,8 @@ genAddrOf (iCode * ic)
            {
              emit2 ("!ldahlsp", sym->stack + _G.stack.pushed + _G.stack.offset + _G.stack.param_offset);
            }
-         emitcode ("ld", "d,h");
-         emitcode ("ld", "e,l");
+         emit2 ("ld d,h");
+         emit2 ("ld e,l");
        }
       else
        {
@@ -5032,14 +5217,14 @@ genAddrOf (iCode * ic)
        {
          /* if it has an offset  then we need to compute it */
          if (sym->stack > 0)
-           emitcode ("ld", "hl,#%d+%d+%d+%d", sym->stack, _G.stack.pushed, _G.stack.offset, _G.stack.param_offset);
+           emit2 ("ld hl,#%d+%d+%d+%d", sym->stack, _G.stack.pushed, _G.stack.offset, _G.stack.param_offset);
          else
-           emitcode ("ld", "hl,#%d+%d+%d", sym->stack, _G.stack.pushed, _G.stack.offset);
-         emitcode ("add", "hl,sp");
+           emit2 ("ld hl,#%d+%d+%d", sym->stack, _G.stack.pushed, _G.stack.offset);
+         emit2 ("add hl,sp");
        }
       else
        {
-         emitcode ("ld", "hl,#%s", sym->rname);
+         emit2 ("ld hl,#%s", sym->rname);
        }
       aopPut (AOP (IC_RESULT (ic)), "l", 0);
       aopPut (AOP (IC_RESULT (ic)), "h", 1);
@@ -5064,7 +5249,7 @@ genAssign (iCode * ic)
   /* Dont bother assigning if they are the same */
   if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
     {
-      emitcode ("", "; (operands are equal %u)", operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)));
+      emit2 ("; (operands are equal %u)", operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)));
       return;
     }
 #endif
@@ -5075,7 +5260,7 @@ genAssign (iCode * ic)
   /* if they are the same registers */
   if (sameRegs (AOP (right), AOP (result)))
     {
-      emitcode ("", "; (registers are the same)");
+      emit2 ("; (registers are the same)");
       goto release;
     }
 
@@ -5112,7 +5297,7 @@ genAssign (iCode * ic)
            {
              if (!fXored && size > 1)
                {
-                 emitcode ("xor", "a,a");
+                 emit2 ("xor a,a");
                  fXored = TRUE;
                }
              if (fXored)
@@ -5121,7 +5306,7 @@ genAssign (iCode * ic)
                }
              else
                {
-                 aopPut (AOP (result), zero, offset);
+                 aopPut (AOP (result), "!zero", offset);
                }
            }
          else
@@ -5134,8 +5319,8 @@ genAssign (iCode * ic)
   else if (size == 2 && requiresHL (AOP (right)) && requiresHL (AOP (result)) && IS_GB)
     {
       /* Special case.  Load into a and d, then load out. */
-      MOVA (aopGet (AOP (right), 0, FALSE));
-      emitcode ("ld", "e,%s", aopGet (AOP (right), 1, FALSE));
+      _moveA (aopGet (AOP (right), 0, FALSE));
+      emit2 ("ld e,%s", aopGet (AOP (right), 1, FALSE));
       aopPut (AOP (result), "a", 0);
       aopPut (AOP (result), "e", 1);
     }
@@ -5146,7 +5331,7 @@ genAssign (iCode * ic)
          /* PENDING: do this check better */
          if (requiresHL (AOP (right)) && requiresHL (AOP (result)))
            {
-             MOVA (aopGet (AOP (right), offset, FALSE));
+             _moveA (aopGet (AOP (right), offset, FALSE));
              aopPut (AOP (result), "a", offset);
            }
          else
@@ -5169,24 +5354,24 @@ static void
 genJumpTab (iCode * ic)
 {
   symbol *jtab;
-  char *l;
+  const char *l;
 
   aopOp (IC_JTCOND (ic), ic, FALSE, FALSE);
   /* get the condition into accumulator */
   l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE);
   if (!IS_GB)
-    emitcode ("push", "de");
-  emitcode ("ld", "e,%s", l);
+    emit2 ("push de");
+  emit2 ("ld e,%s", l);
   emit2 ("ld d,!zero");
   jtab = newiTempLabel (NULL);
   spillCached ();
   emit2 ("ld hl,!immed!tlabel", jtab->key + 100);
-  emitcode ("add", "hl,de");
-  emitcode ("add", "hl,de");
-  emitcode ("add", "hl,de");
+  emit2 ("add hl,de");
+  emit2 ("add hl,de");
+  emit2 ("add hl,de");
   freeAsmop (IC_JTCOND (ic), NULL, ic);
   if (!IS_GB)
-    emitcode ("pop", "de");
+    emit2 ("pop de");
   emit2 ("jp !*hl");
   emitLabel (jtab->key + 100);
   /* now generate the jump labels */
@@ -5268,17 +5453,17 @@ genCast (iCode * ic)
   if (SPEC_USIGN (ctype) || !IS_SPEC (ctype))
     {
       while (size--)
-       aopPut (AOP (result), zero, offset++);
+       aopPut (AOP (result), "!zero", offset++);
     }
   else
     {
       /* we need to extend the sign :{ */
-      char *l = aopGet (AOP (right), AOP_SIZE (right) - 1,
+        const char *l = aopGet (AOP (right), AOP_SIZE (right) - 1,
                        FALSE);
-      MOVA (l);
-      emitcode ("", "; genCast: sign extend untested.");
-      emitcode ("rla", "");
-      emitcode ("sbc", "a,a");
+      _moveA (l);
+      emit2 ("; genCast: sign extend untested.");
+      emit2 ("rla ");
+      emit2 ("sbc a,a");
       while (size--)
        aopPut (AOP (result), "a", offset++);
     }
@@ -5302,10 +5487,16 @@ genReceive (iCode * ic)
     }
   else
     {
-      accInUse++;
-      aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
-      accInUse--;
-      assignResultValue (IC_RESULT (ic));
+        // PENDING: HACK
+        int size;
+        int i;
+
+        aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+        size = AOP_SIZE(IC_RESULT(ic));
+
+        for (i = 0; i < size; i++) {
+            aopPut(AOP(IC_RESULT(ic)), _fReceive[_G.receiveOffset++], i);
+       }
     }
 
   freeAsmop (IC_RESULT (ic), NULL, ic);
@@ -5331,39 +5522,15 @@ genZ80Code (iCode * lic)
       _fReturn = _z80_return;
       _fTmp = _z80_return;
     }
-  tsprintf (zero, "!zero");
-
-  lineHead = lineCurr = NULL;
-
-  /* if debug information required */
-  if (options.debug && currFunc)
-    {
-      cdbSymbol (currFunc, cdbFile, FALSE, TRUE);
-      debugLine = 1;
-      if (IS_STATIC (currFunc->etype))
-       emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
-      else
-       emitcode ("", "G$%s$0$0 ==.", currFunc->name);
-      debugLine = 0;
-    }
-  /* stack pointer name */
-  spname = "sp";
 
+  _G.lines.head = _G.lines.current = NULL;
 
   for (ic = lic; ic; ic = ic->next)
     {
 
       if (cln != ic->lineno)
        {
-         if (options.debug)
-           {
-             debugLine = 1;
-             emitcode ("", "C$%s$%d$%d$%d ==.",
-                       FileBaseName (ic->filename), ic->lineno,
-                       ic->level, ic->block);
-             debugLine = 0;
-           }
-         emitcode (";", "%s %d", ic->filename, ic->lineno);
+         emit2 ("; %s %d", ic->filename, ic->lineno);
          cln = ic->lineno;
        }
       /* if the result is marked as
@@ -5377,22 +5544,22 @@ genZ80Code (iCode * lic)
       switch (ic->op)
        {
        case '!':
-         emitcode ("", "; genNot");
+         emit2 ("; genNot");
          genNot (ic);
          break;
 
        case '~':
-         emitcode ("", "; genCpl");
+         emit2 ("; genCpl");
          genCpl (ic);
          break;
 
        case UNARYMINUS:
-         emitcode ("", "; genUminus");
+         emit2 ("; genUminus");
          genUminus (ic);
          break;
 
        case IPUSH:
-         emitcode ("", "; genIpush");
+         emit2 ("; genIpush");
          genIpush (ic);
          break;
 
@@ -5407,83 +5574,83 @@ genZ80Code (iCode * lic)
              ic->next->op == IFX &&
              regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
            {
-             emitcode ("", "; genIfx");
+             emit2 ("; genIfx");
              genIfx (ic->next, ic);
            }
          else
            {
-             emitcode ("", "; genIpop");
+             emit2 ("; genIpop");
              genIpop (ic);
            }
          break;
 
        case CALL:
-         emitcode ("", "; genCall");
+         emit2 ("; genCall");
          genCall (ic);
          break;
 
        case PCALL:
-         emitcode ("", "; genPcall");
+         emit2 ("; genPcall");
          genPcall (ic);
          break;
 
        case FUNCTION:
-         emitcode ("", "; genFunction");
+         emit2 ("; genFunction");
          genFunction (ic);
          break;
 
        case ENDFUNCTION:
-         emitcode ("", "; genEndFunction");
+         emit2 ("; genEndFunction");
          genEndFunction (ic);
          break;
 
        case RETURN:
-         emitcode ("", "; genRet");
+         emit2 ("; genRet");
          genRet (ic);
          break;
 
        case LABEL:
-         emitcode ("", "; genLabel");
+         emit2 ("; genLabel");
          genLabel (ic);
          break;
 
        case GOTO:
-         emitcode ("", "; genGoto");
+         emit2 ("; genGoto");
          genGoto (ic);
          break;
 
        case '+':
-         emitcode ("", "; genPlus");
+         emit2 ("; genPlus");
          genPlus (ic);
          break;
 
        case '-':
-         emitcode ("", "; genMinus");
+         emit2 ("; genMinus");
          genMinus (ic);
          break;
 
        case '*':
-         emitcode ("", "; genMult");
+         emit2 ("; genMult");
          genMult (ic);
          break;
 
        case '/':
-         emitcode ("", "; genDiv");
+         emit2 ("; genDiv");
          genDiv (ic);
          break;
 
        case '%':
-         emitcode ("", "; genMod");
+         emit2 ("; genMod");
          genMod (ic);
          break;
 
        case '>':
-         emitcode ("", "; genCmpGt");
+         emit2 ("; genCmpGt");
          genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic));
          break;
 
        case '<':
-         emitcode ("", "; genCmpLt");
+         emit2 ("; genCmpLt");
          genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic));
          break;
 
@@ -5498,66 +5665,66 @@ genZ80Code (iCode * lic)
          break;
 
        case EQ_OP:
-         emitcode ("", "; genCmpEq");
+         emit2 ("; genCmpEq");
          genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic));
          break;
 
        case AND_OP:
-         emitcode ("", "; genAndOp");
+         emit2 ("; genAndOp");
          genAndOp (ic);
          break;
 
        case OR_OP:
-         emitcode ("", "; genOrOp");
+         emit2 ("; genOrOp");
          genOrOp (ic);
          break;
 
        case '^':
-         emitcode ("", "; genXor");
+         emit2 ("; genXor");
          genXor (ic, ifxForOp (IC_RESULT (ic), ic));
          break;
 
        case '|':
-         emitcode ("", "; genOr");
+         emit2 ("; genOr");
          genOr (ic, ifxForOp (IC_RESULT (ic), ic));
          break;
 
        case BITWISEAND:
-         emitcode ("", "; genAnd");
+         emit2 ("; genAnd");
          genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
          break;
 
        case INLINEASM:
-         emitcode ("", "; genInline");
+         emit2 ("; genInline");
          genInline (ic);
          break;
 
        case RRC:
-         emitcode ("", "; genRRC");
+         emit2 ("; genRRC");
          genRRC (ic);
          break;
 
        case RLC:
-         emitcode ("", "; genRLC");
+         emit2 ("; genRLC");
          genRLC (ic);
          break;
 
        case GETHBIT:
-         emitcode ("", "; genHBIT");
+         emit2 ("; genHBIT");
          wassert (0);
 
        case LEFT_OP:
-         emitcode ("", "; genLeftShift");
+         emit2 ("; genLeftShift");
          genLeftShift (ic);
          break;
 
        case RIGHT_OP:
-         emitcode ("", "; genRightShift");
+         emit2 ("; genRightShift");
          genRightShift (ic);
          break;
 
        case GET_VALUE_AT_ADDRESS:
-         emitcode ("", "; genPointerGet");
+         emit2 ("; genPointerGet");
          genPointerGet (ic);
          break;
 
@@ -5565,44 +5732,44 @@ genZ80Code (iCode * lic)
 
          if (POINTER_SET (ic))
            {
-             emitcode ("", "; genAssign (pointer)");
+             emit2 ("; genAssign (pointer)");
              genPointerSet (ic);
            }
          else
            {
-             emitcode ("", "; genAssign");
+             emit2 ("; genAssign");
              genAssign (ic);
            }
          break;
 
        case IFX:
-         emitcode ("", "; genIfx");
+         emit2 ("; genIfx");
          genIfx (ic, NULL);
          break;
 
        case ADDRESS_OF:
-         emitcode ("", "; genAddrOf");
+         emit2 ("; genAddrOf");
          genAddrOf (ic);
          break;
 
        case JUMPTABLE:
-         emitcode ("", "; genJumpTab");
+         emit2 ("; genJumpTab");
          genJumpTab (ic);
          break;
 
        case CAST:
-         emitcode ("", "; genCast");
+         emit2 ("; genCast");
          genCast (ic);
          break;
 
        case RECEIVE:
-         emitcode ("", "; genReceive");
+         emit2 ("; genReceive");
          genReceive (ic);
          break;
 
        case SEND:
-         emitcode ("", "; addSet");
-         addSet (&sendSet, ic);
+         emit2 ("; addSet");
+         addSet (&_G.sendSet, ic);
          break;
 
        default:
@@ -5616,7 +5783,7 @@ genZ80Code (iCode * lic)
   /* now we are ready to call the
      peep hole optimizer */
   if (!options.nopeep)
-    peepHole (&lineHead);
+    peepHole (&_G.lines.head);
 
   /* This is unfortunate */
   /* now do the actual printing */
@@ -5624,12 +5791,34 @@ genZ80Code (iCode * lic)
     FILE *fp = codeOutFile;
     if (isInHome () && codeOutFile == code->oFile)
       codeOutFile = home->oFile;
-    printLine (lineHead, codeOutFile);
-    if (_G.flush_statics)
+    printLine (_G.lines.head, codeOutFile);
+    if (_G.flushStatics)
       {
        flushStatics ();
-       _G.flush_statics = 0;
+       _G.flushStatics = 0;
       }
     codeOutFile = fp;
   }
 }
+
+/*
+  Attic
+static int
+_isPairUsed (iCode * ic, PAIR_ID pairId)
+{
+  int ret = 0;
+  switch (pairId)
+    {
+    case PAIR_DE:
+      if (bitVectBitValue (ic->rMask, D_IDX))
+       ret++;
+      if (bitVectBitValue (ic->rMask, E_IDX))
+       ret++;
+      break;
+    default:
+      wassert (0);
+    }
+  return ret;
+}
+
+*/