Fixed bugs #1596270, #1736867
[fw/sdcc] / src / z80 / gen.c
index f1c6a241a5471ea7a6c2d56861d2b7ab6335e33a..9e995211db9a99afdbd95bf0cb03cf2e35f2e4c0 100644 (file)
 #include <string.h>
 #include <ctype.h>
 
 #include <string.h>
 #include <ctype.h>
 
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
-#endif
-
 #include "z80.h"
 #include "SDCCglobl.h"
 #include "SDCCpeeph.h"
 #include "z80.h"
 #include "SDCCglobl.h"
 #include "SDCCpeeph.h"
@@ -128,16 +122,16 @@ enum
 };
 
 static char *_z80_return[] =
 };
 
 static char *_z80_return[] =
-{"l", "h", "e", "d"};
+  {"l", "h", "e", "d"};
 static char *_gbz80_return[] =
 static char *_gbz80_return[] =
-{"e", "d", "l", "h"};
+  {"e", "d", "l", "h"};
 static char *_fReceive[] =
   { "c", "b", "e", "d" };
 
 static char **_fReturn;
 static char **_fTmp;
 
 static char *_fReceive[] =
   { "c", "b", "e", "d" };
 
 static char **_fReturn;
 static char **_fTmp;
 
-extern FILE *codeOutFile;
+extern struct dbuf_s *codeOutBuf;
 
 enum
   {
 
 enum
   {
@@ -388,7 +382,7 @@ _tidyUp (char *buf)
 }
 
 static lineNode *
 }
 
 static lineNode *
-_newLineNode (char *line)
+_newLineNode (const char *line)
 {
   lineNode *pl;
 
 {
   lineNode *pl;
 
@@ -401,11 +395,16 @@ _newLineNode (char *line)
 static void
 _vemit2 (const char *szFormat, va_list ap)
 {
 static void
 _vemit2 (const char *szFormat, va_list ap)
 {
-  char buffer[INITIAL_INLINEASM];
+  struct dbuf_s dbuf;
+  const char *buffer;
+
+  dbuf_init(&dbuf, INITIAL_INLINEASM);
+
+  dbuf_tvprintf (&dbuf, szFormat, ap);
 
 
-  tvsprintf (buffer, sizeof(buffer), szFormat, ap);
+  buffer = dbuf_c_str(&dbuf);
 
 
-  _tidyUp (buffer);
+  _tidyUp ((char *)buffer);
   _G.lines.current = (_G.lines.current ?
               connectLine (_G.lines.current, _newLineNode (buffer)) :
               (_G.lines.head = _newLineNode (buffer)));
   _G.lines.current = (_G.lines.current ?
               connectLine (_G.lines.current, _newLineNode (buffer)) :
               (_G.lines.head = _newLineNode (buffer)));
@@ -413,6 +412,9 @@ _vemit2 (const char *szFormat, va_list ap)
   _G.lines.current->isInline = _G.lines.isInline;
   _G.lines.current->isDebug = _G.lines.isDebug;
   _G.lines.current->ic = _G.current_iCode;
   _G.lines.current->isInline = _G.lines.isInline;
   _G.lines.current->isDebug = _G.lines.isDebug;
   _G.lines.current->ic = _G.current_iCode;
+  _G.lines.current->isComment = (*buffer == ';');
+
+  dbuf_destroy(&dbuf);
 }
 
 static void
 }
 
 static void
@@ -463,7 +465,7 @@ _emit2 (const char *inst, const char *fmt,...)
 {
   va_list ap;
   char lb[INITIAL_INLINEASM];
 {
   va_list ap;
   char lb[INITIAL_INLINEASM];
-  unsigned char *lbp = lb;
+  char *lbp = lb;
 
   va_start (ap, fmt);
 
 
   va_start (ap, fmt);
 
@@ -699,9 +701,12 @@ _push (PAIR_ID pairId)
 static void
 _pop (PAIR_ID pairId)
 {
 static void
 _pop (PAIR_ID pairId)
 {
-  emit2 ("pop %s", _pairs[pairId].name);
-  _G.stack.pushed -= 2;
-  spillPair (pairId);
+  if (pairId != PAIR_INVALID)
+    {
+      emit2 ("pop %s", _pairs[pairId].name);
+      _G.stack.pushed -= 2;
+      spillPair (pairId);
+    }
 }
 
 void
 }
 
 void
@@ -1255,7 +1260,7 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
         /* otherwise it is fairly simple */
         if (!IS_FLOAT (val->type))
           {
         /* otherwise it is fairly simple */
         if (!IS_FLOAT (val->type))
           {
-            unsigned long v = (unsigned long) floatFromVal (val);
+            unsigned long v = ulFromVal (val);
 
             if (offset == 2)
               {
 
             if (offset == 2)
               {
@@ -1503,8 +1508,18 @@ fetchPairLong (PAIR_ID pairId, asmop * aop, iCode *ic, int offset)
           }
         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));
+            /* Swapping register contents within register pair */
+            if(!strcmp(aopGet (aop, offset, FALSE), _pairs[pairId].h))
+              {
+                emit2 ("ld a,%s",aopGet (aop, offset + 1, FALSE));
+                emit2 ("ld %s,%s", _pairs[pairId].l, aopGet (aop, offset, FALSE));
+                emit2 ("ld %s,a", _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)
           }
         /* PENDING: check? */
         if (pairId == PAIR_HL)
@@ -1636,6 +1651,7 @@ static void
 emitLabel (int key)
 {
   emit2 ("!tlabeldef", key);
 emitLabel (int key)
 {
   emit2 ("!tlabeldef", key);
+  _G.lines.current->isLabel = 1;
   spillCached ();
 }
 
   spillCached ();
 }
 
@@ -2067,7 +2083,7 @@ aopPut (asmop * aop, const char *s, int offset)
       if (aop->aopu.aop_pairId==PAIR_IX)
         emit2 ("ld !*ixx,%s", 0, s);
       else if (aop->aopu.aop_pairId==PAIR_IY)
       if (aop->aopu.aop_pairId==PAIR_IX)
         emit2 ("ld !*ixx,%s", 0, s);
       else if (aop->aopu.aop_pairId==PAIR_IY)
-        emit2 ("ld !*ixy,%s", 0, s);
+        emit2 ("ld !*iyx,%s", 0, s);
       else
         emit2 ("ld (%s),%s", _pairs[aop->aopu.aop_pairId].name, s);
       break;
       else
         emit2 ("ld (%s),%s", _pairs[aop->aopu.aop_pairId].name, s);
       break;
@@ -2083,6 +2099,7 @@ aopPut (asmop * aop, const char *s, int offset)
 #define AOP_TYPE(op) AOP(op)->type
 #define AOP_SIZE(op) AOP(op)->size
 #define AOP_NEEDSACC(x) (AOP(x) && ((AOP_TYPE(x) == AOP_CRY) || (AOP_TYPE(x) == AOP_SFR)))
 #define AOP_TYPE(op) AOP(op)->type
 #define AOP_SIZE(op) AOP(op)->size
 #define AOP_NEEDSACC(x) (AOP(x) && ((AOP_TYPE(x) == AOP_CRY) || (AOP_TYPE(x) == AOP_SFR)))
+#define AOP_IS_PAIRPTR(x, p) (AOP_TYPE (x) == AOP_PAIRPTR && AOP (x)->aopu.aop_pairId == p)
 
 static void
 commitPair (asmop * aop, PAIR_ID id)
 
 static void
 commitPair (asmop * aop, PAIR_ID id)
@@ -2223,29 +2240,22 @@ outAcc (operand * result)
 /** Take the value in carry and put it into a register
  */
 void
 /** Take the value in carry and put it into a register
  */
 void
-outBitCLong (operand * result, bool swap_sense)
+outBitC (operand * result)
 {
   /* if the result is bit */
   if (AOP_TYPE (result) == AOP_CRY)
     {
 {
   /* if the result is bit */
   if (AOP_TYPE (result) == AOP_CRY)
     {
-      wassertl (0, "Tried to write carry to a bit");
+      if (!IS_OP_RUONLY (result))
+        aopPut (AOP (result), "c", 0);
     }
   else
     {
       emit2 ("ld a,!zero");
       emit2 ("rla");
     }
   else
     {
       emit2 ("ld a,!zero");
       emit2 ("rla");
-      if (swap_sense)
-        emit2 ("xor a,!immedbyte", 1);
       outAcc (result);
     }
 }
 
       outAcc (result);
     }
 }
 
-void
-outBitC (operand * result)
-{
-  outBitCLong (result, FALSE);
-}
-
 /*-----------------------------------------------------------------*/
 /* toBoolean - emit code for orl a,operator(sizeop)                */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* toBoolean - emit code for orl a,operator(sizeop)                */
 /*-----------------------------------------------------------------*/
@@ -2513,6 +2523,16 @@ assignResultValue (operand * oper)
     }
   else
     {
     }
   else
     {
+      if ((AOP_TYPE (oper) == AOP_REG) && (AOP_SIZE (oper) == 4) &&
+          !strcmp (AOP (oper)->aopu.aop_reg[size-1]->name, _fReturn[size-2]))
+        {
+          size--;
+          _emitMove ("a", _fReturn[size-1]);
+          _emitMove (_fReturn[size-1], _fReturn[size]);
+          _emitMove (_fReturn[size], "a");
+          aopPut (AOP (oper), _fReturn[size], size-1);
+          size--;
+        }
       while (size--)
         {
           aopPut (AOP (oper), _fReturn[size], size);
       while (size--)
         {
           aopPut (AOP (oper), _fReturn[size], size);
@@ -2680,13 +2700,23 @@ genIpush (iCode * ic)
               char *l = aopGetLitWordLong (AOP (IC_LEFT (ic)), --offset, FALSE);
               wassert (l);
               emit2 ("ld a,(%s)", l);
               char *l = aopGetLitWordLong (AOP (IC_LEFT (ic)), --offset, FALSE);
               wassert (l);
               emit2 ("ld a,(%s)", l);
+              emit2 ("push af");
             }
           else
             {
               l = aopGet (AOP (IC_LEFT (ic)), --offset, FALSE);
             }
           else
             {
               l = aopGet (AOP (IC_LEFT (ic)), --offset, FALSE);
-              emit2 ("ld a,%s", l);
+              if (!strcmp(l, "b"))
+                emit2 ("push bc");
+              else if (!strcmp(l, "d"))
+                emit2 ("push de");
+              else if (!strcmp(l, "h"))
+                emit2 ("push hl");
+              else
+                {
+                  emit2 ("ld a,%s", l);
+                  emit2 ("push af");
+                }
             }
             }
-          emit2 ("push af");
           emit2 ("inc sp");
           _G.stack.pushed++;
         }
           emit2 ("inc sp");
           _G.stack.pushed++;
         }
@@ -2899,6 +2929,7 @@ emitCall (iCode * ic, bool ispcall)
           fetchHL (AOP (IC_LEFT (ic)));
           emit2 ("jp !*hl");
           emit2 ("!tlabeldef", (rlbl->key + 100));
           fetchHL (AOP (IC_LEFT (ic)));
           emit2 ("jp !*hl");
           emit2 ("!tlabeldef", (rlbl->key + 100));
+          _G.lines.current->isLabel = 1;
           _G.stack.pushed -= 2;
         }
       freeAsmop (IC_LEFT (ic), NULL, ic);
           _G.stack.pushed -= 2;
         }
       freeAsmop (IC_LEFT (ic), NULL, ic);
@@ -2931,7 +2962,6 @@ emitCall (iCode * ic, bool ispcall)
         OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
       IS_TRUE_SYMOP (IC_RESULT (ic)))
     {
         OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
       IS_TRUE_SYMOP (IC_RESULT (ic)))
     {
-
       aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
 
       assignResultValue (IC_RESULT (ic));
       aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
 
       assignResultValue (IC_RESULT (ic));
@@ -3112,8 +3142,10 @@ genFunction (iCode * ic)
     {
       sprintf (buffer, "%s_start", sym->rname);
       emit2 ("!labeldef", buffer);
     {
       sprintf (buffer, "%s_start", sym->rname);
       emit2 ("!labeldef", buffer);
+      _G.lines.current->isLabel = 1;
     }
   emit2 ("!functionlabeldef", sym->rname);
     }
   emit2 ("!functionlabeldef", sym->rname);
+  _G.lines.current->isLabel = 1;
 
   ftype = operandType (IC_LEFT (ic));
 
 
   ftype = operandType (IC_LEFT (ic));
 
@@ -3329,9 +3361,10 @@ genEndFunction (iCode * ic)
               emit2 ("pop af");
               //parity odd <==> P/O=0 <==> interrupt enable flag IFF2 was 0 <==>
               //don't enable interrupts as they were off before
               emit2 ("pop af");
               //parity odd <==> P/O=0 <==> interrupt enable flag IFF2 was 0 <==>
               //don't enable interrupts as they were off before
-              emit2 ("jp po,!tlabel", tlbl->key + 100);
+              emit2 ("jp PO,!tlabel", tlbl->key + 100);
               emit2 ("!ei");
               emit2 ("!tlabeldef", (tlbl->key + 100));
               emit2 ("!ei");
               emit2 ("!tlabeldef", (tlbl->key + 100));
+              _G.lines.current->isLabel = 1;
             }
         }
     }
             }
         }
     }
@@ -3359,6 +3392,7 @@ genEndFunction (iCode * ic)
     {
       sprintf (buffer, "%s_end", sym->rname);
       emit2 ("!labeldef", buffer);
     {
       sprintf (buffer, "%s_end", sym->rname);
       emit2 ("!labeldef", buffer);
+      _G.lines.current->isLabel = 1;
     }
 
   _G.flushStatics = 1;
     }
 
   _G.flushStatics = 1;
@@ -3476,7 +3510,7 @@ genPlusIncr (iCode * ic)
 
   emitDebug ("; genPlusIncr");
 
 
   emitDebug ("; genPlusIncr");
 
-  icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+  icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
 
   /* If result is a pair */
   if (resultId != PAIR_INVALID)
 
   /* If result is a pair */
   if (resultId != PAIR_INVALID)
@@ -3547,7 +3581,7 @@ genPlusIncr (iCode * ic)
           emit2 ("inc %s", aopGet (AOP (IC_RESULT (ic)), offset++, FALSE));
           if (size)
             {
           emit2 ("inc %s", aopGet (AOP (IC_RESULT (ic)), offset++, FALSE));
           if (size)
             {
-              emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+              emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
             }
         }
       emitLabel (tlbl->key + 100);
             }
         }
       emitLabel (tlbl->key + 100);
@@ -3600,7 +3634,7 @@ outBitAcc (operand * result)
     }
   else
     {
     }
   else
     {
-      emit2 ("!shortjp z,!tlabel", tlbl->key + 100);
+      emit2 ("!shortjp Z,!tlabel", tlbl->key + 100);
       emit2 ("ld a,!one");
       emitLabel (tlbl->key + 100);
       outAcc (result);
       emit2 ("ld a,!one");
       emitLabel (tlbl->key + 100);
       outAcc (result);
@@ -3628,30 +3662,27 @@ shiftIntoPair (int idx, asmop *aop)
   wassertl (IS_Z80, "Only implemented for the Z80");
   //  wassertl (aop->type == AOP_EXSTK, "Only implemented for EXSTK");
 
   wassertl (IS_Z80, "Only implemented for the Z80");
   //  wassertl (aop->type == AOP_EXSTK, "Only implemented for EXSTK");
 
+  emitDebug ("; Shift into pair idx %u", idx);
+
   switch (idx)
     {
     case 0:
       id = PAIR_HL;
   switch (idx)
     {
     case 0:
       id = PAIR_HL;
+      setupPair (PAIR_HL, aop, 0);
       break;
     case 1:
       id = PAIR_DE;
       _push (PAIR_DE);
       break;
     case 1:
       id = PAIR_DE;
       _push (PAIR_DE);
-      break;
-    default:
-      wassertl (0, "Internal error - hit default case");
-    }
-
-  emitDebug ("; Shift into pair idx %u", idx);
-
-  if (id == PAIR_HL)
-    {
-      setupPair (PAIR_HL, aop, 0);
-    }
-  else
-    {
       setupPair (PAIR_IY, aop, 0);
       emit2 ("push iy");
       emit2 ("pop %s", _pairs[id].name);
       setupPair (PAIR_IY, aop, 0);
       emit2 ("push iy");
       emit2 ("pop %s", _pairs[id].name);
+      break;
+    case 2:
+      id = PAIR_IY;
+      setupPair (PAIR_IY, aop, 0);
+      break;
+    default:
+      wassertl (0, "Internal error - hit default case");
     }
 
   aop->type = AOP_PAIRPTR;
     }
 
   aop->type = AOP_PAIRPTR;
@@ -3661,8 +3692,12 @@ shiftIntoPair (int idx, asmop *aop)
 }
 
 static void
 }
 
 static void
-setupToPreserveCarry (asmop *result, asmop *left, asmop *right)
+setupToPreserveCarry (iCode * ic)
 {
 {
+  asmop *left   = AOP (IC_LEFT (ic));
+  asmop *right  = AOP (IC_RIGHT (ic));
+  asmop *result = AOP (IC_RESULT (ic));
+
   wassert (left && right);
 
   if (IS_Z80)
   wassert (left && right);
 
   if (IS_Z80)
@@ -3672,7 +3707,12 @@ setupToPreserveCarry (asmop *result, asmop *left, asmop *right)
           shiftIntoPair (0, right);
           /* check result again, in case right == result */
           if (couldDestroyCarry (result))
           shiftIntoPair (0, right);
           /* check result again, in case right == result */
           if (couldDestroyCarry (result))
-            shiftIntoPair (1, result);
+            {
+              if (!isPairInUse (PAIR_DE, ic))
+                shiftIntoPair (1, result);
+              else
+                shiftIntoPair (2, result);
+            }
         }
       else if (couldDestroyCarry (right))
         {
         }
       else if (couldDestroyCarry (right))
         {
@@ -3743,8 +3783,6 @@ genPlus (iCode * ic)
   if (genPlusIncr (ic) == TRUE)
     goto release;
 
   if (genPlusIncr (ic) == TRUE)
     goto release;
 
-  emitDebug ("; Can't optimise plus by inc, falling back to the normal way");
-
   size = getDataSize (IC_RESULT (ic));
 
   /* Special case when left and right are constant */
   size = getDataSize (IC_RESULT (ic));
 
   /* Special case when left and right are constant */
@@ -3812,8 +3850,8 @@ genPlus (iCode * ic)
     }
 
   /* Special case:
     }
 
   /* Special case:
-     ld hl,sp+n trashes C so we cant afford to do it during an
-     add with stack based varibles.  Worst case is:
+     ld hl,sp+n trashes C so we can't afford to do it during an
+     add with stack based variables.  Worst case is:
      ld  hl,sp+left
      ld  a,(hl)
      ld  hl,sp+right
      ld  hl,sp+left
      ld  a,(hl)
      ld  hl,sp+right
@@ -3826,7 +3864,7 @@ genPlus (iCode * ic)
      adc (hl)
      ld  hl,sp+result+1
      ld  (hl),a
      adc (hl)
      ld  hl,sp+result+1
      ld  (hl),a
-     So you cant afford to load up hl if either left, right, or result
+     So you can't afford to load up hl if either left, right, or result
      is on the stack (*sigh*)  The alt is:
      ld  hl,sp+left
      ld  de,(hl)
      is on the stack (*sigh*)  The alt is:
      ld  hl,sp+left
      ld  de,(hl)
@@ -3882,30 +3920,59 @@ genPlus (iCode * ic)
         }
     }
 
         }
     }
 
-  setupToPreserveCarry (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)), AOP (IC_RIGHT (ic)));
+  setupToPreserveCarry (ic);
 
 
-  while (size--)
+  /* This is ugly, but it fixes the worst code generation bug on Z80. */
+  /* Probably something similar has to be done for addition of larger numbers, too. */
+  if(size == 2)
     {
     {
-      if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC)
+      _moveA (aopGet (AOP (IC_LEFT (ic)), 0, FALSE));
+      emit2 ("add a,%s", aopGet (AOP (IC_RIGHT (ic)), 0, FALSE));
+      if(strcmp (aopGet (AOP (IC_RESULT (ic)), 0, FALSE), aopGet (AOP (IC_LEFT (ic)), 1, FALSE)))
         {
         {
-          _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
-          if (offset == 0)
-            emit2 ("add a,%s",
-                   aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
-          else
-            emit2 ("adc a,%s",
-                   aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
+          aopPut (AOP (IC_RESULT (ic)), "a", 0);
+          _moveA (aopGet (AOP (IC_LEFT (ic)), 1, FALSE));
         }
       else
         {
         }
       else
         {
-          _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
-          if (offset == 0)
-            emit2 ("add a,%s",
-                   aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
+          emitDebug ("; Addition result is in same register as operand of next addition.");
+          if(strchr (aopGet (AOP (IC_RESULT (ic)), 0, FALSE), 'c') ||
+             strchr (aopGet (AOP (IC_RESULT (ic)), 0, FALSE), 'b') )
+            {
+              emit2 ("push de");
+              emit2 ("ld e, a");
+              emit2 ("ld a, %s", aopGet (AOP (IC_LEFT (ic)), 1, FALSE));
+              emit2 ("ld d, a");
+              emit2 ("ld a, e");
+              emit2 ("ld %s, a", aopGet (AOP (IC_RESULT (ic)), 0, FALSE));
+              emit2 ("ld a, d");
+              emit2 ("pop de");
+            }
           else
           else
-            emit2 ("adc a,%s",
-                   aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
+            {
+              emit2 ("push bc");
+              emit2 ("ld c, a");
+              emit2 ("ld a, %s", aopGet (AOP (IC_LEFT (ic)), 1, FALSE));
+              emit2 ("ld b, a");
+              emit2 ("ld a, c");
+              emit2 ("ld %s, a", aopGet (AOP (IC_RESULT (ic)), 0, FALSE));
+              emit2 ("ld a, b");
+              emit2 ("pop bc");
+            }
+          
         }
         }
+      emit2 ("adc a,%s", aopGet (AOP (IC_RIGHT (ic)), 1, FALSE));
+      aopPut (AOP (IC_RESULT (ic)), "a", 1);
+      goto release;
+    }
+
+  while (size--)
+    {
+      _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE));
+      if (offset == 0)
+        emit2 ("add a,%s", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
+      else
+        emit2 ("adc a,%s", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE));
       aopPut (AOP (IC_RESULT (ic)), "a", offset++);
     }
 
       aopPut (AOP (IC_RESULT (ic)), "a", offset++);
     }
 
@@ -3914,7 +3981,6 @@ release:
   freeAsmop (IC_LEFT (ic), NULL, ic);
   freeAsmop (IC_RIGHT (ic), NULL, ic);
   freeAsmop (IC_RESULT (ic), NULL, ic);
   freeAsmop (IC_LEFT (ic), NULL, ic);
   freeAsmop (IC_RIGHT (ic), NULL, ic);
   freeAsmop (IC_RESULT (ic), NULL, ic);
-
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -3933,7 +3999,7 @@ genMinusDec (iCode * ic)
 
   /* if the literal value of the right hand side
      is greater than 4 then it is not worth it */
 
   /* if the literal value of the right hand side
      is greater than 4 then it is not worth it */
-  if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 2)
+  if ((icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 2)
     return FALSE;
 
   size = getDataSize (IC_RESULT (ic));
     return FALSE;
 
   size = getDataSize (IC_RESULT (ic));
@@ -4023,7 +4089,7 @@ genMinus (iCode * ic)
     }
   else
     {
     }
   else
     {
-      lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+      lit = ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
       lit = -(long) lit;
     }
 
       lit = -(long) lit;
     }
 
@@ -4080,7 +4146,7 @@ genMinus (iCode * ic)
         }
     }
 
         }
     }
 
-  setupToPreserveCarry (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)), AOP (IC_RIGHT (ic)));
+  setupToPreserveCarry (ic);
 
   /* if literal, add a,#-lit, else normal subb */
   while (size--)
 
   /* if literal, add a,#-lit, else normal subb */
   while (size--)
@@ -4156,7 +4222,7 @@ genMult (iCode * ic)
 
   wassertl (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT, "Right must be a literal");
 
 
   wassertl (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT, "Right must be a literal");
 
-  val = (int)floatFromVal ( AOP (IC_RIGHT (ic))->aopu.aop_lit);
+  val = (int) ulFromVal ( AOP (IC_RIGHT (ic))->aopu.aop_lit);
   //  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");
 
@@ -4262,28 +4328,28 @@ genIfxJump (iCode * ic, char *jval)
       jlbl = IC_TRUE (ic);
       if (!strcmp (jval, "a"))
         {
       jlbl = IC_TRUE (ic);
       if (!strcmp (jval, "a"))
         {
-          inst = "nz";
+          inst = "NZ";
         }
       else if (!strcmp (jval, "c"))
         {
         }
       else if (!strcmp (jval, "c"))
         {
-          inst = "c";
+          inst = "C";
         }
       else if (!strcmp (jval, "nc"))
         {
         }
       else if (!strcmp (jval, "nc"))
         {
-          inst = "nc";
+          inst = "NC";
         }
       else if (!strcmp (jval, "m"))
         {
         }
       else if (!strcmp (jval, "m"))
         {
-          inst = "m";
+          inst = "M";
         }
       else if (!strcmp (jval, "p"))
         {
         }
       else if (!strcmp (jval, "p"))
         {
-          inst = "p";
+          inst = "P";
         }
       else
         {
           /* The buffer contains the bit on A that we should test */
         }
       else
         {
           /* The buffer contains the bit on A that we should test */
-          inst = "nz";
+          inst = "NZ";
         }
     }
   else
         }
     }
   else
@@ -4292,28 +4358,28 @@ genIfxJump (iCode * ic, char *jval)
       jlbl = IC_FALSE (ic);
       if (!strcmp (jval, "a"))
         {
       jlbl = IC_FALSE (ic);
       if (!strcmp (jval, "a"))
         {
-          inst = "z";
+          inst = "Z";
         }
       else if (!strcmp (jval, "c"))
         {
         }
       else if (!strcmp (jval, "c"))
         {
-          inst = "nc";
+          inst = "NC";
         }
       else if (!strcmp (jval, "nc"))
         {
         }
       else if (!strcmp (jval, "nc"))
         {
-          inst = "c";
+          inst = "C";
         }
       else if (!strcmp (jval, "m"))
         {
         }
       else if (!strcmp (jval, "m"))
         {
-          inst = "p";
+          inst = "P";
         }
       else if (!strcmp (jval, "p"))
         {
         }
       else if (!strcmp (jval, "p"))
         {
-          inst = "m";
+          inst = "M";
         }
       else
         {
           /* The buffer contains the bit on A that we should test */
         }
       else
         {
           /* The buffer contains the bit on A that we should test */
-          inst = "z";
+          inst = "Z";
         }
     }
   /* Z80 can do a conditional long jump */
         }
     }
   /* Z80 can do a conditional long jump */
@@ -4447,7 +4513,7 @@ _getPairIdName (PAIR_ID id)
         {
           if (AOP_TYPE (right) == AOP_LIT)
             {
         {
           if (AOP_TYPE (right) == AOP_LIT)
             {
-              lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+              lit = ulFromVal (AOP (right)->aopu.aop_lit);
               /* optimize if(x < 0) or if(x >= 0) */
               if (lit == 0L)
                 {
               /* optimize if(x < 0) or if(x >= 0) */
               if (lit == 0L)
                 {
@@ -4478,8 +4544,7 @@ _getPairIdName (PAIR_ID id)
               bool fDidXor = FALSE;
               if (AOP_TYPE (left) == AOP_LIT)
                 {
               bool fDidXor = FALSE;
               if (AOP_TYPE (left) == AOP_LIT)
                 {
-                  unsigned long lit = (unsigned long)
-                  floatFromVal (AOP (left)->aopu.aop_lit);
+                  unsigned long lit = ulFromVal (AOP (left)->aopu.aop_lit);
                   emit2 ("ld %s,!immedbyte", _fTmp[0],
                          0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL));
                 }
                   emit2 ("ld %s,!immedbyte", _fTmp[0],
                          0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL));
                 }
@@ -4492,8 +4557,7 @@ _getPairIdName (PAIR_ID id)
                 }
               if (AOP_TYPE (right) == AOP_LIT)
                 {
                 }
               if (AOP_TYPE (right) == AOP_LIT)
                 {
-                  unsigned long lit = (unsigned long)
-                  floatFromVal (AOP (right)->aopu.aop_lit);
+                  unsigned long lit = ulFromVal (AOP (right)->aopu.aop_lit);
                   emit2 ("ld %s,!immedbyte", _fTmp[1],
                          0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL));
                 }
                   emit2 ("ld %s,!immedbyte", _fTmp[1],
                          0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL));
                 }
@@ -4536,7 +4600,6 @@ genCmp (operand * left, operand * right,
 {
   int size, offset = 0;
   unsigned long lit = 0L;
 {
   int size, offset = 0;
   unsigned long lit = 0L;
-  bool swap_sense = FALSE;
 
   /* if left & right are bit variables */
   if (AOP_TYPE (left) == AOP_CRY &&
 
   /* if left & right are bit variables */
   if (AOP_TYPE (left) == AOP_CRY &&
@@ -4577,7 +4640,7 @@ genCmp (operand * left, operand * right,
 
       if (AOP_TYPE (right) == AOP_LIT)
         {
 
       if (AOP_TYPE (right) == AOP_LIT)
         {
-          lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+          lit = ulFromVal (AOP (right)->aopu.aop_lit);
           /* optimize if(x < 0) or if(x >= 0) */
           if (lit == 0)
             {
           /* optimize if(x < 0) or if(x >= 0) */
           if (lit == 0)
             {
@@ -4603,7 +4666,7 @@ genCmp (operand * left, operand * right,
                         }
                       if (ifx)
                         {
                         }
                       if (ifx)
                         {
-                          genIfxJump (ifx, swap_sense ? "c" : "nc");
+                          genIfxJump (ifx, "nc");
                           return;
                         }
                     }
                           return;
                         }
                     }
@@ -4629,7 +4692,7 @@ release:
           /* Shift the sign bit up into carry */
           emit2 ("rlca");
         }
           /* Shift the sign bit up into carry */
           emit2 ("rlca");
         }
-      outBitCLong (result, swap_sense);
+      outBitC (result);
     }
   else
     {
     }
   else
     {
@@ -4643,16 +4706,16 @@ release:
               if (IS_GB)
                 {
                   emit2 ("rlca");
               if (IS_GB)
                 {
                   emit2 ("rlca");
-                  genIfxJump (ifx, swap_sense ? "nc" : "c");
+                  genIfxJump (ifx, "c");
                 }
               else
                 {
                 }
               else
                 {
-                  genIfxJump (ifx, swap_sense ? "p" : "m");
+                  genIfxJump (ifx, "m");
                 }
             }
           else
             {
                 }
             }
           else
             {
-              genIfxJump (ifx, swap_sense ? "nc" : "c");
+              genIfxJump (ifx, "c");
             }
         }
       else
             }
         }
       else
@@ -4662,7 +4725,7 @@ release:
               /* Shift the sign bit up into carry */
               emit2 ("rlca");
             }
               /* Shift the sign bit up into carry */
               emit2 ("rlca");
             }
-          outBitCLong (result, swap_sense);
+          outBitC (result);
         }
       /* leave the result in acc */
     }
         }
       /* leave the result in acc */
     }
@@ -4729,8 +4792,9 @@ genCmpLt (iCode * ic, iCode * ifx)
 
 /*-----------------------------------------------------------------*/
 /* gencjneshort - compare and jump if not equal                    */
 
 /*-----------------------------------------------------------------*/
 /* gencjneshort - compare and jump if not equal                    */
+/* returns pair that still needs to be popped                      */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-static void
+static PAIR_ID
 gencjneshort (operand * left, operand * right, symbol * lbl)
 {
   int size = max (AOP_SIZE (left), AOP_SIZE (right));
 gencjneshort (operand * left, operand * right, symbol * lbl)
 {
   int size = max (AOP_SIZE (left), AOP_SIZE (right));
@@ -4745,18 +4809,13 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
       left = t;
     }
 
       left = t;
     }
 
-  if (AOP_TYPE (right) == AOP_LIT)
-    {
-      lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
-    }
-
   /* if the right side is a literal then anything goes */
   /* if the right side is a literal then anything goes */
-  if (AOP_TYPE (right) == AOP_LIT &&
-      AOP_TYPE (left) != AOP_DIR)
+  if (AOP_TYPE (right) == AOP_LIT)
     {
     {
+      lit = ulFromVal (AOP (right)->aopu.aop_lit);
       if (lit == 0)
         {
       if (lit == 0)
         {
-          emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE));
+          _moveA (aopGet (AOP (left), offset, FALSE));
           if (size > 1)
             {
               while (--size)
           if (size > 1)
             {
               while (--size)
@@ -4768,55 +4827,74 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
             {
               emit2 ("or a,a");
             }
             {
               emit2 ("or a,a");
             }
-          emit2 ("jp nz,!tlabel", lbl->key + 100);
+          emit2 ("jp NZ,!tlabel", lbl->key + 100);
         }
       else
         {
           while (size--)
             {
         }
       else
         {
           while (size--)
             {
-              emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE));
-              if ((AOP_TYPE (right) == AOP_LIT) && lit == 0)
+              _moveA (aopGet (AOP (left), offset, FALSE));
+              if ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0)
                 emit2 ("or a,a");
               else
                 emit2 ("or a,a");
               else
-                emit2 ("cp a,%s", aopGet (AOP (right), offset, FALSE));
-              emit2 ("jp nz,!tlabel", lbl->key + 100);
+                emit2 ("sub a,%s", aopGet (AOP (right), offset, FALSE));
+              emit2 ("jp NZ,!tlabel", lbl->key + 100);
               offset++;
             }
         }
     }
               offset++;
             }
         }
     }
-  /* if the right side is in a register or in direct space or
-     if the left is a pointer register & right is not */
+  /* if the right side is in a register or
+     pointed to by HL, IX or IY */
   else if (AOP_TYPE (right) == AOP_REG ||
   else if (AOP_TYPE (right) == AOP_REG ||
-           AOP_TYPE (right) == AOP_DIR ||
-           (AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT))
+           AOP_TYPE (right) == AOP_HL  ||
+           AOP_TYPE (right) == AOP_IY  ||
+           AOP_TYPE (right) == AOP_STK ||
+           AOP_IS_PAIRPTR (right, PAIR_HL) ||
+           AOP_IS_PAIRPTR (right, PAIR_IX) ||
+           AOP_IS_PAIRPTR (right, PAIR_IY))
     {
       while (size--)
         {
           _moveA (aopGet (AOP (left), offset, FALSE));
     {
       while (size--)
         {
           _moveA (aopGet (AOP (left), offset, FALSE));
-          if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) &&
+          if (AOP_TYPE (right) == AOP_LIT &&
               ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
               ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
-            /* PENDING */
-            emit2 ("jp nz,!tlabel", lbl->key + 100);
+            {
+              emit2 ("or a,a");
+              emit2 ("jp NZ,!tlabel", lbl->key + 100);
+            }
           else
             {
           else
             {
-              emit2 ("cp %s", aopGet (AOP (right), offset, FALSE));
-              emit2 ("jp nz,!tlabel", lbl->key + 100);
+              emit2 ("sub %s", aopGet (AOP (right), offset, FALSE));
+              emit2 ("jp NZ,!tlabel", lbl->key + 100);
             }
           offset++;
         }
     }
             }
           offset++;
         }
     }
+  /* right is in direct space or a pointer reg, need both a & b */
   else
     {
   else
     {
-      /* right is a pointer reg need both a & b */
-      /* PENDING: is this required? */
+      PAIR_ID pair;
+      for (pair = PAIR_BC; pair <= PAIR_HL; pair++)
+        {
+          if (((AOP_TYPE (left)  != AOP_PAIRPTR) || (AOP (left)->aopu.aop_pairId  != pair)) &&
+              ((AOP_TYPE (right) != AOP_PAIRPTR) || (AOP (right)->aopu.aop_pairId != pair)))
+            {
+              break;
+            }
+        }
+      _push (pair);
       while (size--)
         {
       while (size--)
         {
+          emit2 ("; direct compare");
+          _emitMove (_pairs[pair].l, aopGet (AOP (left), offset, FALSE));
           _moveA (aopGet (AOP (right), offset, FALSE));
           _moveA (aopGet (AOP (right), offset, FALSE));
-          emit2 ("cp %s", aopGet (AOP (left), offset, FALSE));
-          emit2 ("!shortjp nz,!tlabel", lbl->key + 100);
+          emit2 ("sub %s", _pairs[pair].l);
+          emit2 ("!shortjp NZ,!tlabel", lbl->key + 100);
           offset++;
         }
           offset++;
         }
+      return pair;
     }
     }
+  return PAIR_INVALID;
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -4827,7 +4905,7 @@ gencjne (operand * left, operand * right, symbol * lbl)
 {
   symbol *tlbl = newiTempLabel (NULL);
 
 {
   symbol *tlbl = newiTempLabel (NULL);
 
-  gencjneshort (left, right, lbl);
+  PAIR_ID pop = gencjneshort (left, right, lbl);
 
   /* PENDING: ?? */
   emit2 ("ld a,!one");
 
   /* PENDING: ?? */
   emit2 ("ld a,!one");
@@ -4835,6 +4913,7 @@ gencjne (operand * left, operand * right, symbol * lbl)
   emitLabel (lbl->key + 100);
   emit2 ("xor a,a");
   emitLabel (tlbl->key + 100);
   emitLabel (lbl->key + 100);
   emit2 ("xor a,a");
   emitLabel (tlbl->key + 100);
+  _pop (pop);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -4872,19 +4951,24 @@ genCmpEq (iCode * ic, iCode * ifx)
         }
       else
         {
         }
       else
         {
+          PAIR_ID pop;
           tlbl = newiTempLabel (NULL);
           tlbl = newiTempLabel (NULL);
-          gencjneshort (left, right, tlbl);
+          pop = gencjneshort (left, right, tlbl);
           if (IC_TRUE (ifx))
             {
           if (IC_TRUE (ifx))
             {
+              _pop (pop);
               emit2 ("jp !tlabel", IC_TRUE (ifx)->key + 100);
               emitLabel (tlbl->key + 100);
               emit2 ("jp !tlabel", IC_TRUE (ifx)->key + 100);
               emitLabel (tlbl->key + 100);
+              _pop (pop);
             }
           else
             {
               /* PENDING: do this better */
               symbol *lbl = newiTempLabel (NULL);
             }
           else
             {
               /* PENDING: do this better */
               symbol *lbl = newiTempLabel (NULL);
+              _pop (pop);
               emit2 ("!shortjp !tlabel", lbl->key + 100);
               emitLabel (tlbl->key + 100);
               emit2 ("!shortjp !tlabel", lbl->key + 100);
               emitLabel (tlbl->key + 100);
+              _pop (pop);
               emit2 ("jp !tlabel", IC_FALSE (ifx)->key + 100);
               emitLabel (lbl->key + 100);
             }
               emit2 ("jp !tlabel", IC_FALSE (ifx)->key + 100);
               emitLabel (lbl->key + 100);
             }
@@ -4979,7 +5063,7 @@ genAndOp (iCode * ic)
     {
       tlbl = newiTempLabel (NULL);
       _toBoolean (left);
     {
       tlbl = newiTempLabel (NULL);
       _toBoolean (left);
-      emit2 ("!shortjp z,!tlabel", tlbl->key + 100);
+      emit2 ("!shortjp Z,!tlabel", tlbl->key + 100);
       _toBoolean (right);
       emitLabel (tlbl->key + 100);
       outBitAcc (result);
       _toBoolean (right);
       emitLabel (tlbl->key + 100);
       outBitAcc (result);
@@ -5016,7 +5100,7 @@ genOrOp (iCode * ic)
     {
       tlbl = newiTempLabel (NULL);
       _toBoolean (left);
     {
       tlbl = newiTempLabel (NULL);
       _toBoolean (left);
-      emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+      emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
       _toBoolean (right);
       emitLabel (tlbl->key + 100);
       outBitAcc (result);
       _toBoolean (right);
       emitLabel (tlbl->key + 100);
       outBitAcc (result);
@@ -5113,7 +5197,7 @@ genAnd (iCode * ic, iCode * ifx)
       left = tmp;
     }
   if (AOP_TYPE (right) == AOP_LIT)
       left = tmp;
     }
   if (AOP_TYPE (right) == AOP_LIT)
-    lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+    lit = ulFromVal (AOP (right)->aopu.aop_lit);
 
   size = AOP_SIZE (result);
 
 
   size = AOP_SIZE (result);
 
@@ -5150,7 +5234,7 @@ genAnd (iCode * ic, iCode * ifx)
                   /* For the flags */
                   emit2 ("or a,a");
                 }
                   /* For the flags */
                   emit2 ("or a,a");
                 }
-              emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+              emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
             }
               offset++;
         }
             }
               offset++;
         }
@@ -5159,6 +5243,7 @@ genAnd (iCode * ic, iCode * ifx)
         {
           emit2 ("clr c");
           emit2 ("!tlabeldef", tlbl->key + 100);
         {
           emit2 ("clr c");
           emit2 ("!tlabeldef", tlbl->key + 100);
+          _G.lines.current->isLabel = 1;
         }
       // if(left & literal)
       else
         }
       // if(left & literal)
       else
@@ -5303,7 +5388,7 @@ genOr (iCode * ic, iCode * ifx)
       left = tmp;
     }
   if (AOP_TYPE (right) == AOP_LIT)
       left = tmp;
     }
   if (AOP_TYPE (right) == AOP_LIT)
-    lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+    lit = ulFromVal (AOP (right)->aopu.aop_lit);
 
   size = AOP_SIZE (result);
 
 
   size = AOP_SIZE (result);
 
@@ -5334,7 +5419,7 @@ genOr (iCode * ic, iCode * ifx)
           _moveA (aopGet (AOP (left), offset, FALSE));
           /* OR with any literal is the same as OR with itself. */
           emit2 ("or a,a");
           _moveA (aopGet (AOP (left), offset, FALSE));
           /* OR with any literal is the same as OR with itself. */
           emit2 ("or a,a");
-          emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+          emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
 
           offset++;
         }
 
           offset++;
         }
@@ -5461,7 +5546,7 @@ genXor (iCode * ic, iCode * ifx)
       left = tmp;
     }
   if (AOP_TYPE (right) == AOP_LIT)
       left = tmp;
     }
   if (AOP_TYPE (right) == AOP_LIT)
-    lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+    lit = ulFromVal (AOP (right)->aopu.aop_lit);
 
   size = AOP_SIZE (result);
 
 
   size = AOP_SIZE (result);
 
@@ -5489,7 +5574,7 @@ genXor (iCode * ic, iCode * ifx)
         {
           _moveA (aopGet (AOP (left), offset, FALSE));
           emit2 ("xor a,%s", aopGet (AOP (right), offset, FALSE));
         {
           _moveA (aopGet (AOP (left), offset, FALSE));
           emit2 ("xor a,%s", aopGet (AOP (right), offset, FALSE));
-          emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+          emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
           offset++;
         }
       if (ifx)
           offset++;
         }
       if (ifx)
@@ -5587,37 +5672,49 @@ static void
 genInline (iCode * ic)
 {
   char *buffer, *bp, *bp1;
 genInline (iCode * ic)
 {
   char *buffer, *bp, *bp1;
+  bool inComment = FALSE;
 
   _G.lines.isInline += (!options.asmpeep);
 
 
   _G.lines.isInline += (!options.asmpeep);
 
-  buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
-  strcpy (buffer, IC_INLINE (ic));
+  buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic));
 
   /* emit each line as a code */
   while (*bp)
     {
 
   /* emit each line as a code */
   while (*bp)
     {
-      if (*bp == '\n')
+      switch (*bp)
         {
         {
+        case ';':
+          inComment = TRUE;
+          ++bp;
+          break;
+
+        case '\n':
+          inComment = FALSE;
           *bp++ = '\0';
           emit2 (bp1);
           bp1 = bp;
           *bp++ = '\0';
           emit2 (bp1);
           bp1 = bp;
-        }
-      else
-        {
-          if (*bp == ':')
+          break;
+
+        default:
+          /* Add \n for labels, not dirs such as c:\mydir */
+          if (!inComment && (*bp == ':') && (isspace((unsigned char)bp[1])))
             {
             {
-              bp++;
+              ++bp;
               *bp = '\0';
               *bp = '\0';
-              bp++;
+              ++bp;
               emit2 (bp1);
               bp1 = bp;
             }
           else
               emit2 (bp1);
               bp1 = bp;
             }
           else
-            bp++;
+            ++bp;
+          break;
         }
     }
   if (bp1 != bp)
     emit2 (bp1);
         }
     }
   if (bp1 != bp)
     emit2 (bp1);
+
+  Safe_free (buffer);
+
   _G.lines.isInline -= (!options.asmpeep);
 
 }
   _G.lines.isInline -= (!options.asmpeep);
 
 }
@@ -5702,18 +5799,21 @@ shiftR2Left2Result (operand * left, int offl,
                     int shCount, int is_signed)
 {
   int size = 2;
                     int shCount, int is_signed)
 {
   int size = 2;
-  symbol *tlbl, *tlbl1;
+  symbol *tlbl;
 
   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);
 
+  if (shCount == 0)
+    return;
+
   /*  if (AOP(result)->type == AOP_REG) { */
 
   tlbl = newiTempLabel (NULL);
   /*  if (AOP(result)->type == AOP_REG) { */
 
   tlbl = newiTempLabel (NULL);
-  tlbl1 = newiTempLabel (NULL);
 
   /* Left is already in result - so now do the shift */
 
   /* Left is already in result - so now do the shift */
-  if (shCount <= 4)
+  /* Optimizing for speed by default. */
+  if (!optimize.codeSize || shCount <= 2)
     {
       while (shCount--)
         {
     {
       while (shCount--)
         {
@@ -5722,15 +5822,14 @@ shiftR2Left2Result (operand * left, int offl,
     }
   else
     {
     }
   else
     {
-      emit2 ("ld a,!immedbyte+1", shCount);
-      emit2 ("!shortjp !tlabel", tlbl1->key + 100);
+      emit2 ("ld a,!immedbyte", shCount);
+
       emitLabel (tlbl->key + 100);
 
       emitRsh2 (AOP (result), size, is_signed);
 
       emitLabel (tlbl->key + 100);
 
       emitRsh2 (AOP (result), size, is_signed);
 
-      emitLabel (tlbl1->key + 100);
       emit2 ("dec a");
       emit2 ("dec a");
-      emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+      emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
     }
 }
 
     }
 }
 
@@ -5753,6 +5852,9 @@ shiftL2Left2Result (operand * left, int offl,
       movLeft2Result (left, offl + 1, result, offr + 1, 0);
     }
 
       movLeft2Result (left, offl + 1, result, offr + 1, 0);
     }
 
+  if (shCount == 0)
+    return;
+
   if (getPairId (AOP (result)) == PAIR_HL)
     {
       while (shCount--)
   if (getPairId (AOP (result)) == PAIR_HL)
     {
       while (shCount--)
@@ -5818,7 +5920,7 @@ shiftL2Left2Result (operand * left, int offl,
           {
             emitLabel (tlbl1->key + 100);
             emit2 ("dec a");
           {
             emitLabel (tlbl1->key + 100);
             emit2 ("dec a");
-            emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+            emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
           }
       }
   }
           }
       }
   }
@@ -5947,16 +6049,28 @@ shiftL1Left2Result (operand * left, int offl,
                     operand * result, int offr, int shCount)
 {
   const char *l;
                     operand * result, int offr, int shCount)
 {
   const char *l;
-  l = aopGet (AOP (left), offl, FALSE);
-  _moveA (l);
-  /* shift left accumulator */
-  AccLsh (shCount);
-  aopPut (AOP (result), "a", offr);
-}
 
 
+  /* If operand and result are the same we can shift in place.
+     However shifting in acc using add is cheaper than shifting
+     in place using sla; when shifting by more than 2 shifting in
+     acc is worth the additional effort for loading from/to acc. */
+  if (sameRegs (AOP (left), AOP (result)) && shCount <= 2 && offr == offl)
+    {
+      while (shCount--)
+        emit2 ("sla %s", aopGet (AOP (result), 0, FALSE));
+    }
+  else
+    {
+      l = aopGet (AOP (left), offl, FALSE);
+      _moveA (l);
+      /* shift left accumulator */
+      AccLsh (shCount);
+      aopPut (AOP (result), "a", offr);
+    }
+}
 
 /*-----------------------------------------------------------------*/
 
 /*-----------------------------------------------------------------*/
-/* genlshTwo - left shift two bytes by known amount != 0           */
+/* genlshTwo - left shift two bytes by known amount                */
 /*-----------------------------------------------------------------*/
 static void
 genlshTwo (operand * result, operand * left, int shCount)
 /*-----------------------------------------------------------------*/
 static void
 genlshTwo (operand * result, operand * left, int shCount)
@@ -5974,8 +6088,8 @@ genlshTwo (operand * result, operand * left, int shCount)
           if (shCount)
             {
               movLeft2Result (left, LSB, result, MSB16, 0);
           if (shCount)
             {
               movLeft2Result (left, LSB, result, MSB16, 0);
-              aopPut (AOP (result), "!zero", 0);
               shiftL1Left2Result (left, LSB, result, MSB16, shCount);
               shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+              aopPut (AOP (result), "!zero", LSB);
             }
           else
             {
             }
           else
             {
@@ -5988,7 +6102,7 @@ genlshTwo (operand * result, operand * left, int shCount)
           aopPut (AOP (result), "!zero", LSB);
         }
     }
           aopPut (AOP (result), "!zero", LSB);
         }
     }
-  /*  1 <= shCount <= 7 */
+  /*  0 <= shCount <= 7 */
   else
     {
       if (size == 1)
   else
     {
       if (size == 1)
@@ -6020,7 +6134,7 @@ genLeftShiftLiteral (operand * left,
                      operand * result,
                      iCode * ic)
 {
                      operand * result,
                      iCode * ic)
 {
-  int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+  int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
   int size;
 
   freeAsmop (right, NULL, ic);
   int size;
 
   freeAsmop (right, NULL, ic);
@@ -6031,12 +6145,8 @@ genLeftShiftLiteral (operand * left,
   size = getSize (operandType (result));
 
   /* I suppose that the left size >= result size */
   size = getSize (operandType (result));
 
   /* I suppose that the left size >= result size */
-  if (shCount == 0)
-    {
-      wassert (0);
-    }
 
 
-  else if (shCount >= (size * 8))
+  if (shCount >= (size * 8))
     {
       while (size--)
         {
     {
       while (size--)
         {
@@ -6146,7 +6256,7 @@ genLeftShift (iCode * ic)
     }
   emitLabel (tlbl1->key + 100);
   emit2 ("dec a");
     }
   emitLabel (tlbl1->key + 100);
   emit2 ("dec a");
-  emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+  emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
 
   freeAsmop (left, NULL, ic);
   freeAsmop (result, NULL, ic);
 
   freeAsmop (left, NULL, ic);
   freeAsmop (result, NULL, ic);
@@ -6231,7 +6341,7 @@ shiftR1Left2Result (operand * left, int offl,
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
-/* genrshTwo - right shift two bytes by known amount != 0          */
+/* genrshTwo - right shift two bytes by known amount               */
 /*-----------------------------------------------------------------*/
 static void
 genrshTwo (operand * result, operand * left,
 /*-----------------------------------------------------------------*/
 static void
 genrshTwo (operand * result, operand * left,
@@ -6264,7 +6374,7 @@ genrshTwo (operand * result, operand * left,
           aopPut (AOP (result), "!zero", 1);
         }
     }
           aopPut (AOP (result), "!zero", 1);
         }
     }
-  /*  1 <= shCount <= 7 */
+  /*  0 <= shCount <= 7 */
   else
     {
       shiftR2Left2Result (left, LSB, result, LSB, shCount, sign);
   else
     {
       shiftR2Left2Result (left, LSB, result, LSB, shCount, sign);
@@ -6281,7 +6391,7 @@ genRightShiftLiteral (operand * left,
                       iCode * ic,
                       int sign)
 {
                       iCode * ic,
                       int sign)
 {
-  int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+  int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit);
   int size;
 
   freeAsmop (right, NULL, ic);
   int size;
 
   freeAsmop (right, NULL, ic);
@@ -6292,12 +6402,8 @@ genRightShiftLiteral (operand * left,
   size = getSize (operandType (result));
 
   /* I suppose that the left size >= result size */
   size = getSize (operandType (result));
 
   /* I suppose that the left size >= result size */
-  if (shCount == 0)
-    {
-      wassert (0);
-    }
 
 
-  else if (shCount >= (size * 8)) {
+  if (shCount >= (size * 8)) {
     const char *s;
     if (!SPEC_USIGN(getSpec(operandType(left)))) {
       _moveA(aopGet (AOP (left), 0, FALSE));
     const char *s;
     if (!SPEC_USIGN(getSpec(operandType(left)))) {
       _moveA(aopGet (AOP (left), 0, FALSE));
@@ -6422,7 +6528,7 @@ genRightShift (iCode * ic)
     }
   emitLabel (tlbl1->key + 100);
   emit2 ("dec a");
     }
   emitLabel (tlbl1->key + 100);
   emit2 ("dec a");
-  emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+  emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
 
   freeAsmop (left, NULL, ic);
   freeAsmop (result, NULL, ic);
 
   freeAsmop (left, NULL, ic);
   freeAsmop (result, NULL, ic);
@@ -6461,7 +6567,7 @@ genUnpackBits (operand * result, int pair)
           symbol *tlbl = newiTempLabel (NULL);
 
           emit2 ("bit %d,a", blen - 1);
           symbol *tlbl = newiTempLabel (NULL);
 
           emit2 ("bit %d,a", blen - 1);
-          emit2 ("jp z,!tlabel", tlbl->key + 100);
+          emit2 ("jp Z,!tlabel", tlbl->key + 100);
           emit2 ("or a,!immedbyte", (unsigned char) (0xff << blen));
           emitLabel (tlbl->key + 100);
         }
           emit2 ("or a,!immedbyte", (unsigned char) (0xff << blen));
           emitLabel (tlbl->key + 100);
         }
@@ -6485,7 +6591,7 @@ genUnpackBits (operand * result, int pair)
           symbol *tlbl = newiTempLabel (NULL);
 
           emit2 ("bit %d,a", blen - 1);
           symbol *tlbl = newiTempLabel (NULL);
 
           emit2 ("bit %d,a", blen - 1);
-          emit2 ("jp z,!tlabel", tlbl->key + 100);
+          emit2 ("jp Z,!tlabel", tlbl->key + 100);
           emit2 ("or a,!immedbyte", (unsigned char) (0xff << blen));
           emitLabel (tlbl->key + 100);
         }
           emit2 ("or a,!immedbyte", (unsigned char) (0xff << blen));
           emitLabel (tlbl->key + 100);
         }
@@ -6518,7 +6624,7 @@ genUnpackBits (operand * result, int pair)
           symbol *tlbl = newiTempLabel (NULL);
 
           emit2 ("bit %d,a", rlen - 1);
           symbol *tlbl = newiTempLabel (NULL);
 
           emit2 ("bit %d,a", rlen - 1);
-          emit2 ("jp z,!tlabel", tlbl->key + 100);
+          emit2 ("jp Z,!tlabel", tlbl->key + 100);
           emit2 ("or a,!immedbyte", (unsigned char) (0xff << rlen));
           emitLabel (tlbl->key + 100);
         }
           emit2 ("or a,!immedbyte", (unsigned char) (0xff << rlen));
           emitLabel (tlbl->key + 100);
         }
@@ -6743,7 +6849,7 @@ genPackBits (sym_link * etype,
         {
           /* Case with a bitfield length <8 and literal source
           */
         {
           /* Case with a bitfield length <8 and literal source
           */
-          litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+          litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
           litval <<= bstr;
           litval &= (~mask) & 0xff;
           emit2 ("ld a,!*pair", _pairs[pair].name);
           litval <<= bstr;
           litval &= (~mask) & 0xff;
           emit2 ("ld a,!*pair", _pairs[pair].name);
@@ -6808,7 +6914,7 @@ genPackBits (sym_link * etype,
         {
           /* Case with partial byte and literal source
           */
         {
           /* Case with partial byte and literal source
           */
-          litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+          litval = (int) ulFromVal (AOP (right)->aopu.aop_lit);
           litval >>= (blen-rlen);
           litval &= (~mask) & 0xff;
           emit2 ("ld a,!*pair", _pairs[pair].name);
           litval >>= (blen-rlen);
           litval &= (~mask) & 0xff;
           emit2 ("ld a,!*pair", _pairs[pair].name);
@@ -7144,7 +7250,7 @@ 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 = ulFromVal (AOP (right)->aopu.aop_lit);
     }
 
   if (isPair (AOP (result)))
     }
 
   if (isPair (AOP (result)))
@@ -7458,9 +7564,10 @@ genCritical (iCode *ic)
       //disable interrupt
       emit2 ("!di");
       //parity odd <==> P/O=0 <==> interrupt enable flag IFF2=0
       //disable interrupt
       emit2 ("!di");
       //parity odd <==> P/O=0 <==> interrupt enable flag IFF2=0
-      emit2 ("jp po,!tlabel", tlbl->key + 100);
+      emit2 ("jp PO,!tlabel", tlbl->key + 100);
       aopPut (AOP (IC_RESULT (ic)), "!one", 0);
       emit2 ("!tlabeldef", (tlbl->key + 100));
       aopPut (AOP (IC_RESULT (ic)), "!one", 0);
       emit2 ("!tlabeldef", (tlbl->key + 100));
+      _G.lines.current->isLabel = 1;
       freeAsmop (IC_RESULT (ic), NULL, ic);
     }
   else
       freeAsmop (IC_RESULT (ic), NULL, ic);
     }
   else
@@ -7491,7 +7598,7 @@ genEndCritical (iCode *ic)
       aopOp (IC_RIGHT (ic), ic, FALSE, TRUE);
       _toBoolean (IC_RIGHT (ic));
       //don't enable interrupts if they were off before
       aopOp (IC_RIGHT (ic), ic, FALSE, TRUE);
       _toBoolean (IC_RIGHT (ic));
       //don't enable interrupts if they were off before
-      emit2 ("!shortjp z,!tlabel", tlbl->key + 100);
+      emit2 ("!shortjp Z,!tlabel", tlbl->key + 100);
       emit2 ("!ei");
       emitLabel (tlbl->key + 100);
       freeAsmop (IC_RIGHT (ic), NULL, ic);
       emit2 ("!ei");
       emitLabel (tlbl->key + 100);
       freeAsmop (IC_RIGHT (ic), NULL, ic);
@@ -7502,9 +7609,10 @@ genEndCritical (iCode *ic)
       emit2 ("pop af");
       //parity odd <==> P/O=0 <==> interrupt enable flag IFF2 was 0 <==>
       //don't enable interrupts as they were off before
       emit2 ("pop af");
       //parity odd <==> P/O=0 <==> interrupt enable flag IFF2 was 0 <==>
       //don't enable interrupts as they were off before
-      emit2 ("jp po,!tlabel", tlbl->key + 100);
+      emit2 ("jp PO,!tlabel", tlbl->key + 100);
       emit2 ("!ei");
       emit2 ("!tlabeldef", (tlbl->key + 100));
       emit2 ("!ei");
       emit2 ("!tlabeldef", (tlbl->key + 100));
+      _G.lines.current->isLabel = 1;
     }
 }
 
     }
 }
 
@@ -7960,7 +8068,7 @@ genBuiltInStrcpy (iCode *ic, int nParams, operand **pparams)
   emit2 ("ld a,(hl)");
   emit2 ("ldi");
   emit2 ("or a");
   emit2 ("ld a,(hl)");
   emit2 ("ldi");
   emit2 ("or a");
-  emit2 ("!shortjp nz,!tlabel ; 1", label->key);
+  emit2 ("!shortjp NZ,!tlabel ; 1", label->key);
 
   freeAsmop (from, NULL, ic->next);
   freeAsmop (to, NULL, ic);
 
   freeAsmop (from, NULL, ic->next);
   freeAsmop (to, NULL, ic);
@@ -8081,7 +8189,9 @@ genZ80Code (iCode * lic)
         }
       if (options.iCodeInAsm)
         {
         }
       if (options.iCodeInAsm)
         {
-          emit2 (";ic:%d: %s", ic->key, printILine(ic));
+          const char *iLine = printILine(ic);
+          emit2 (";ic:%d: %s", ic->key, iLine);
+          dbuf_free(iLine);
         }
       /* if the result is marked as
          spilt and rematerializable or code for
         }
       /* if the result is marked as
          spilt and rematerializable or code for
@@ -8118,7 +8228,7 @@ genZ80Code (iCode * lic)
              spilt live range, if there is an ifx statement
              following this pop then the if statement might
              be using some of the registers being popped which
              spilt live range, if there is an ifx statement
              following this pop then the if statement might
              be using some of the registers being popped which
-             would destory the contents of the register so
+             would destroy the contents of the register so
              we need to check for this condition and handle it */
           if (ic->next &&
               ic->next->op == IFX &&
              we need to check for this condition and handle it */
           if (ic->next &&
               ic->next->op == IFX &&
@@ -8365,16 +8475,16 @@ genZ80Code (iCode * lic)
   /* This is unfortunate */
   /* now do the actual printing */
   {
   /* This is unfortunate */
   /* now do the actual printing */
   {
-    FILE *fp = codeOutFile;
-    if (isInHome () && codeOutFile == code->oFile)
-      codeOutFile = home->oFile;
-    printLine (_G.lines.head, codeOutFile);
+    struct dbuf_s *buf = codeOutBuf;
+    if (isInHome () && codeOutBuf == &code->oBuf)
+      codeOutBuf = &home->oBuf;
+    printLine (_G.lines.head, codeOutBuf);
     if (_G.flushStatics)
       {
         flushStatics ();
         _G.flushStatics = 0;
       }
     if (_G.flushStatics)
       {
         flushStatics ();
         _G.flushStatics = 0;
       }
-    codeOutFile = fp;
+    codeOutBuf = buf;
   }
 
   freeTrace(&_G.lines.trace);
   }
 
   freeTrace(&_G.lines.trace);
@@ -8410,7 +8520,7 @@ fetchLitSpecial (asmop * aop, bool negate, bool xor)
   wassert (aop->type == AOP_LIT);
   wassert (!IS_FLOAT (val->type));
 
   wassert (aop->type == AOP_LIT);
   wassert (!IS_FLOAT (val->type));
 
-  v = (unsigned long) floatFromVal (val);
+  v = ulFromVal (val);
 
   if (xor)
     v ^= 0x8000;
 
   if (xor)
     v ^= 0x8000;