* src/mcs51/gen.c (genCpl): quick fix for bug #974835
[fw/sdcc] / src / mcs51 / gen.c
index e6a90ffc239d5db5219c49c268b8c179bcf17446..ecd3bf860305d963f9ca599b1542dcedb369bd9b 100644 (file)
@@ -68,6 +68,8 @@ static struct
   {
     short r0Pushed;
     short r1Pushed;
+    short r0InB;
+    short r1InB;
     short accInUse;
     short inLine;
     short debugLine;
@@ -135,7 +137,7 @@ emitcode (char *inst, const char *fmt,...)
   while (isspace (*lbp))
     lbp++;
 
-  // printf ("%s\n", lb);
+  //printf ("%s\n", lb);
   
   if (lbp && *lbp)
     lineCurr = (lineCurr ?
@@ -148,6 +150,18 @@ emitcode (char *inst, const char *fmt,...)
   va_end (ap);
 }
 
+/*-----------------------------------------------------------------*/
+/* mcs51_emitDebuggerSymbol - associate the current code location  */
+/*   with a debugger symbol                                        */
+/*-----------------------------------------------------------------*/
+void
+mcs51_emitDebuggerSymbol (char * debugSym)
+{
+  _G.debugLine = 1;
+  emitcode ("", "%s ==.", debugSym);
+  _G.debugLine = 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* mova - moves specified value into accumulator                   */
 /*-----------------------------------------------------------------*/
@@ -207,7 +221,13 @@ getFreePtr (iCode * ic, asmop ** aopp, bool result)
   if (!r0iu)
     {
       /* push it if not already pushed */
-      if (!_G.r0Pushed)
+      if (ic->op == IPUSH)
+       {
+         emitcode ("mov", "b,%s",
+                   mcs51_regWithIdx (R0_IDX)->dname);
+         _G.r0InB++;
+       }
+      else if (!_G.r0Pushed)
        {
          emitcode ("push", "%s",
                    mcs51_regWithIdx (R0_IDX)->dname);
@@ -225,7 +245,13 @@ getFreePtr (iCode * ic, asmop ** aopp, bool result)
   if (!r1iu)
     {
       /* push it if not already pushed */
-      if (!_G.r1Pushed)
+      if (ic->op == IPUSH)
+       {
+         emitcode ("mov", "b,%s",
+                   mcs51_regWithIdx (R1_IDX)->dname);
+         _G.r1InB++;
+       }
+      else if (!_G.r1Pushed)
        {
          emitcode ("push", "%s",
                    mcs51_regWithIdx (R1_IDX)->dname);
@@ -624,10 +650,10 @@ operandsEqu (operand * op1, operand * op2)
   if (sym1 == sym2)
     return TRUE;
 
-  if (strcmp (sym1->rname, sym2->rname) == 0)
+  if (sym1->rname[0] && sym2->rname[0]
+      && strcmp (sym1->rname, sym2->rname) == 0)
     return TRUE;
 
-
   /* if left is a tmp & right is not */
   if (IS_ITEMP (op1) &&
       !IS_ITEMP (op2) &&
@@ -817,7 +843,12 @@ freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
   switch (aop->type)
     {
     case AOP_R0:
-      if (_G.r0Pushed)
+      if (_G.r0InB)
+        {
+         emitcode ("mov", "r0,b");
+         _G.r0InB--;
+       }
+      else if (_G.r0Pushed)
        {
          if (pop)
            {
@@ -829,6 +860,11 @@ freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
       break;
 
     case AOP_R1:
+      if (_G.r1InB)
+        {
+         emitcode ("mov", "r1,b");
+         _G.r1InB--;
+       }
       if (_G.r1Pushed)
        {
          if (pop)
@@ -899,6 +935,81 @@ dealloc:
     }
 }
 
+/*------------------------------------------------------------------*/
+/* freeForBranchAsmop - partial free up of Asmop for a branch; just */
+/*                      pop r0 or r1 off stack if pushed            */
+/*------------------------------------------------------------------*/
+static void
+freeForBranchAsmop (operand * op)
+{
+  asmop *aop;
+
+  if (!op)
+    return;
+    
+  aop = op->aop;
+
+  if (!aop)
+    return;
+
+  if (aop->freed)
+    return;
+
+  switch (aop->type)
+    {
+    case AOP_R0:
+      if (_G.r0InB)
+       {
+         emitcode ("mov", "r0,b");
+       }
+      else if (_G.r0Pushed)
+       {
+         emitcode ("pop", "ar0");
+       }
+      break;
+
+    case AOP_R1:
+      if (_G.r1InB)
+       {
+         emitcode ("mov", "r1,b");
+       }
+      else if (_G.r1Pushed)
+       {
+         emitcode ("pop", "ar1");
+       }
+      break;
+
+    case AOP_STK:
+      {
+       int sz = aop->size;
+       int stk = aop->aopu.aop_stk + aop->size - 1;
+
+       emitcode ("mov", "b,r0");
+       if (stk)
+         {
+           emitcode ("mov", "a,_bp");
+           emitcode ("add", "a,#0x%02x", ((char) stk) & 0xff);
+           emitcode ("mov", "r0,a");
+         }
+       else
+         {
+           emitcode ("mov", "r0,_bp");
+         }
+
+       while (sz--)
+         {
+           emitcode ("pop", "acc");
+           emitcode ("mov", "@r0,a");
+           if (!sz)
+             break;
+           emitcode ("dec", "r0");
+         }
+       emitcode ("mov", "r0,b");
+      }
+    }
+
+}
+
 /*-----------------------------------------------------------------*/
 /* aopGetUsesAcc - indicates ahead of time whether aopGet() will   */
 /*                 clobber the accumulator                         */
@@ -1500,9 +1611,8 @@ genCpl (iCode * ic)
     {
       if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
        {
-         emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
-         emitcode ("cpl", "c");
-         emitcode ("mov", "%s,c", IC_RESULT (ic)->aop->aopu.aop_dir);
+         /* promotion rules are responsible for this strange result: */
+         emitcode ("setb", "%s", IC_RESULT (ic)->aop->aopu.aop_dir);
          goto release;
        }
 
@@ -1775,7 +1885,7 @@ pushSide (operand * oper, int size)
          AOP_TYPE (oper) != AOP_DIR &&
          strcmp (l, "a"))
        {
-         emitcode ("mov", "a,%s", l);
+         MOVA (l);
          emitcode ("push", "acc");
        }
       else
@@ -1899,7 +2009,7 @@ genIpush (iCode * ic)
          AOP_TYPE (IC_LEFT (ic)) != AOP_DIR &&
          strcmp (l, "a"))
        {
-         emitcode ("mov", "a,%s", l);
+         MOVA (l);
          emitcode ("push", "acc");
        }
       else
@@ -2361,15 +2471,18 @@ inExcludeList (char *s)
 static void
 genFunction (iCode * ic)
 {
-  symbol *sym;
+  symbol *sym = OP_SYMBOL (IC_LEFT (ic));
   sym_link *ftype;
   bool   switchedPSW = FALSE;
   int calleesaves_saved_register = -1;
+  int stackAdjust = sym->stack;
+  int accIsFree = sym->recvSize < 4;
+  iCode * ric = (ic->next && ic->next->op == RECEIVE) ? ic->next : NULL;
 
   _G.nRegsSaved = 0;
   /* create the function header */
   emitcode (";", "-----------------------------------------");
-  emitcode (";", " function %s", (sym = OP_SYMBOL (IC_LEFT (ic)))->name);
+  emitcode (";", " function %s", sym->name);
   emitcode (";", "-----------------------------------------");
 
   emitcode ("", "%s:", sym->rname);
@@ -2381,7 +2494,7 @@ genFunction (iCode * ic)
       emitcode(";", "naked function: no prologue.");
       return;
   }
-
+  
   /* here we need to generate the equates for the
      register bank if required */
   if (FUNC_REGBANK (ftype) != rbank)
@@ -2435,22 +2548,15 @@ genFunction (iCode * ic)
                  /* save the registers used */
                  for (i = 0; i < sym->regsUsed->size; i++)
                    {
-                     if (bitVectBitValue (sym->regsUsed, i) ||
-                         (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
+                     if (bitVectBitValue (sym->regsUsed, i))
                        emitcode ("push", "%s", mcs51_regWithIdx (i)->dname);
                    }
                }
-             else if (mcs51_ptrRegReq)
-               {
-                 emitcode ("push", "%s", mcs51_regWithIdx (R0_IDX)->dname);
-                 emitcode ("push", "%s", mcs51_regWithIdx (R1_IDX)->dname);
-               }
-
            }
          else
            {
 
-             /* this function has  a function call cannot
+             /* this function has a function call. We cannot
                 determines register usage so we will have to push the
                 entire bank */
                saveRBank (0, ic, FALSE);
@@ -2552,9 +2658,20 @@ genFunction (iCode * ic)
            // TODO: this needs a closer look
            SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave;
        }
+      
+      /* Set the register bank to the desired value if nothing else */
+      /* has done so yet. */
+      if (!switchedPSW)
+        {
+          emitcode ("push", "psw");
+          emitcode ("mov", "psw,#0x%02x", (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
+        }
     }
   else
     {
+      /* This is a non-ISR function. The caller has already switched register */
+      /* banks, if necessary, so just handle the callee-saves option. */
+      
       /* if callee-save to be used for this function
          then save the registers being used in this function */
       if (IFFUNC_CALLEESAVES(sym->type))
@@ -2567,8 +2684,7 @@ genFunction (iCode * ic)
              /* save the registers used */
              for (i = 0; i < sym->regsUsed->size; i++)
                {
-                 if (bitVectBitValue (sym->regsUsed, i) ||
-                     (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
+                 if (bitVectBitValue (sym->regsUsed, i))
                    {
                      /* remember one saved register for later usage */
                      if (calleesaves_saved_register < 0)
@@ -2578,31 +2694,23 @@ genFunction (iCode * ic)
                    }
                }
            }
-         else if (mcs51_ptrRegReq)
-           {
-             emitcode ("push", "%s", mcs51_regWithIdx (R0_IDX)->dname);
-             emitcode ("push", "%s", mcs51_regWithIdx (R1_IDX)->dname);
-           }
        }
     }
 
-  /* set the register bank to the desired value */
-  if (( /* FUNC_REGBANK (sym->type) || */ IFFUNC_ISISR (sym->type))
-   && !switchedPSW)
-    {
-      emitcode ("push", "psw");
-      emitcode ("mov", "psw,#0x%02x", (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
-    }
 
   if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
     {
 
       if (options.useXstack)
        {
+         if (!accIsFree)
+           emitcode ("push", "acc");
          emitcode ("mov", "r0,%s", spname);
          emitcode ("mov", "a,_bp");
          emitcode ("movx", "@r0,a");
          emitcode ("inc", "%s", spname);
+         if (!accIsFree)
+           emitcode ("pop", "acc");
        }
       else
        {
@@ -2611,16 +2719,76 @@ genFunction (iCode * ic)
        }
       emitcode ("mov", "_bp,%s", spname);
     }
-
+  
+  /* For some cases it is worthwhile to perform a RECEIVE iCode */
+  /* before setting up the stack frame completely. */
+  if (ric && ric->argreg == 1 && IC_RESULT (ric))
+    {
+      symbol * rsym = OP_SYMBOL (IC_RESULT (ric));
+      
+      if (rsym->isitmp)
+        {
+         if (rsym && rsym->regType == REG_CND)
+           rsym = NULL;
+         if (rsym && (rsym->accuse || rsym->ruonly))
+           rsym = NULL;
+          if (rsym && (rsym->isspilt || rsym->nRegs == 0) && rsym->usl.spillLoc)
+            rsym = rsym->usl.spillLoc;
+       }
+      
+      /* If the RECEIVE operand immediately spills to the first entry on the */
+      /* stack, we can push it directly (since sp = _bp + 1 at this point) */
+      /* rather than the usual @r0/r1 machinations. */
+      if (!options.useXstack && rsym && rsym->onStack && rsym->stack == 1)
+        {
+         int ofs;
+         
+         _G.current_iCode = ric;
+         D(emitcode (";     genReceive",""));
+         for (ofs=0; ofs < sym->recvSize; ofs++)
+           {
+             if (!strcmp (fReturn[ofs], "a"))
+               emitcode ("push", "acc");
+             else
+               emitcode ("push", fReturn[ofs]);
+           }
+         stackAdjust -= sym->recvSize;
+         if (stackAdjust<0)
+           {
+             assert (stackAdjust>=0);
+             stackAdjust = 0;
+           }
+         _G.current_iCode = ic;
+         ric->generated = 1;
+         accIsFree = 1;
+       }
+      /* If the RECEIVE operand is 4 registers, we can do the moves now */
+      /* to free up the accumulator. */
+      else if (rsym && rsym->nRegs && sym->recvSize == 4)
+        {
+         int ofs;
+         
+         _G.current_iCode = ric;
+         D(emitcode (";     genReceive",""));
+         for (ofs=0; ofs < sym->recvSize; ofs++)
+           {
+             emitcode ("mov", "%s,%s", rsym->regs[ofs]->name, fReturn[ofs]);
+           }
+         _G.current_iCode = ic;
+         ric->generated = 1;
+         accIsFree = 1;
+       }
+    }
+  
   /* adjust the stack for the function */
-  if (sym->stack)
+  if (stackAdjust)
     {
 
-      int i = sym->stack;
+      int i = stackAdjust;
       if (i > 256)
        werror (W_STACK_OVERFLOW, sym->name);
 
-      if (i > 3 && sym->recvSize < 4)
+      if (i > 3 && accIsFree)
        {
 
          emitcode ("mov", "a,sp");
@@ -2630,6 +2798,11 @@ genFunction (iCode * ic)
        }
       else if (i > 5)
         {
+         /* The accumulator is not free, so we will need another register */
+         /* to clobber. No need to worry about a possible conflict with */
+         /* the above early RECEIVE optimizations since they would have */
+         /* freed the accumulator if they were generated. */
+         
          if (IFFUNC_CALLEESAVES(sym->type))
            {
              /* if it's a callee-saves function we need a saved register */
@@ -2664,9 +2837,13 @@ genFunction (iCode * ic)
   if (sym->xstack)
     {
 
+      if (!accIsFree)
+        emitcode ("push", "acc");
       emitcode ("mov", "a,_spx");
       emitcode ("add", "a,#0x%02x", ((char) sym->xstack & 0xff));
       emitcode ("mov", "_spx,a");
+      if (!accIsFree)
+        emitcode ("pop", "acc");
     }
 
   /* if critical function then turn interrupts off */
@@ -2698,6 +2875,8 @@ genEndFunction (iCode * ic)
   if (IFFUNC_ISNAKED(sym->type))
   {
       emitcode(";", "naked function: no epilogue.");
+      if (options.debug && currFunc)
+       debugFile->writeEndFunction (currFunc, ic, 0);
       return;
   }
 
@@ -2773,17 +2952,10 @@ genEndFunction (iCode * ic)
                  /* save the registers used */
                  for (i = sym->regsUsed->size; i >= 0; i--)
                    {
-                     if (bitVectBitValue (sym->regsUsed, i) ||
-                         (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
+                     if (bitVectBitValue (sym->regsUsed, i))
                        emitcode ("pop", "%s", mcs51_regWithIdx (i)->dname);
                    }
                }
-             else if (mcs51_ptrRegReq)
-               {
-                 emitcode ("pop", "%s", mcs51_regWithIdx (R1_IDX)->dname);
-                 emitcode ("pop", "%s", mcs51_regWithIdx (R0_IDX)->dname);
-               }
-
            }
          else
            {
@@ -2838,15 +3010,7 @@ genEndFunction (iCode * ic)
       /* if debug then send end of function */
       if (options.debug && currFunc)
        {
-         _G.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);
-         _G.debugLine = 0;
+         debugFile->writeEndFunction (currFunc, ic, 1);
        }
 
       emitcode ("reti", "");
@@ -2879,21 +3043,13 @@ genEndFunction (iCode * ic)
       /* if debug then send end of function */
       if (options.debug && currFunc)
        {
-         _G.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);
-         _G.debugLine = 0;
+         debugFile->writeEndFunction (currFunc, ic, 1);
        }
 
       emitcode ("ret", "");
     }
 
-  if (!port->peep.getRegsRead || !port->peep.getRegsWritten)
+  if (!port->peep.getRegsRead || !port->peep.getRegsWritten || options.nopeep)
     return;
   
   /* If this was an interrupt handler using bank 0 that called another */
@@ -2901,6 +3057,15 @@ genEndFunction (iCode * ic)
   if (IFFUNC_ISISR (sym->type) && IFFUNC_HASFCALL(sym->type)
       && !FUNC_REGBANK(sym->type))
     return;
+
+  /* There are no push/pops to optimize if not callee-saves or ISR */
+  if (!(FUNC_CALLEESAVES (sym->type) || FUNC_ISISR (sym->type)))
+    return;
+  
+  /* If there were stack parameters, we cannot optimize without also    */
+  /* fixing all of the stack offsets; this is too dificult to consider. */
+  if (FUNC_HASSTACKPARM(sym->type))
+    return;
     
   /* Compute the registers actually used */
   regsUsed = newBitVect (mcs51_nRegs);
@@ -2913,7 +3078,7 @@ genEndFunction (iCode * ic)
         regsUsed = bitVectUnion (regsUsed, port->peep.getRegsWritten(lnp));
       
       if (lnp->ic && lnp->ic->op == FUNCTION && lnp->prev
-          && lnp->prev->ic && lnp->prev->ic->op != FUNCTION)
+          && lnp->prev->ic && lnp->prev->ic->op == ENDFUNCTION)
        break;
       if (!lnp->prev)
         break;
@@ -2924,8 +3089,8 @@ genEndFunction (iCode * ic)
       && !bitVectBitValue (regsUsed, CND_IDX))
     {
       regsUsed = bitVectUnion (regsUsed, regsUsedPrologue);
-      if (IFFUNC_ISISR (sym->type) && !FUNC_REGBANK(sym->type)
-          && !sym->stack)
+      if (IFFUNC_ISISR (sym->type) && !FUNC_REGBANK (sym->type)
+          && !sym->stack && !FUNC_ISCRITICAL (sym->type))
         bitVectUnSetBit (regsUsed, CND_IDX);
     }
   else
@@ -4518,7 +4683,7 @@ release:
 /* genIfxJump :- will create a jump depending on the ifx           */
 /*-----------------------------------------------------------------*/
 static void
-genIfxJump (iCode * ic, char *jval)
+genIfxJump (iCode * ic, char *jval, operand *left, operand *right, operand *result)
 {
   symbol *jlbl;
   symbol *tlbl = newiTempLabel (NULL);
@@ -4545,6 +4710,9 @@ genIfxJump (iCode * ic, char *jval)
     emitcode (inst, "%s,%05d$", jval, (tlbl->key + 100));
   else
     emitcode (inst, "%05d$", tlbl->key + 100);
+  freeForBranchAsmop (result);
+  freeForBranchAsmop (right);
+  freeForBranchAsmop (left);
   emitcode ("ljmp", "%05d$", jlbl->key + 100);
   emitcode ("", "%05d$:", tlbl->key + 100);
 
@@ -4607,7 +4775,10 @@ genCmp (operand * left, operand * right,
                      MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE, FALSE));
                      if (!(AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result)) && ifx)
                        {
-                         genIfxJump (ifx, "acc.7");
+                         genIfxJump (ifx, "acc.7", left, right, result);
+                         freeAsmop (right, NULL, ic, TRUE);
+                         freeAsmop (left, NULL, ic, TRUE);
+
                          return;
                        }
                      else
@@ -4666,7 +4837,7 @@ release:
          ifx conditional branch then generate
          code a little differently */
       if (ifx)
-       genIfxJump (ifx, "c");
+       genIfxJump (ifx, "c", NULL, NULL, result);
       else
        outBitC (result);
       /* leave the result in acc */
@@ -4891,11 +5062,17 @@ genCmpEq (iCode * ic, iCode * ifx)
          if (IC_TRUE (ifx))
            {
              emitcode ("jnc", "%05d$", tlbl->key + 100);
+             freeForBranchAsmop (result);
+             freeForBranchAsmop (right);
+             freeForBranchAsmop (left);
              emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
            }
          else
            {
              emitcode ("jc", "%05d$", tlbl->key + 100);
+             freeForBranchAsmop (result);
+             freeForBranchAsmop (right);
+             freeForBranchAsmop (left);
              emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
            }
          emitcode ("", "%05d$:", tlbl->key + 100);
@@ -4906,6 +5083,9 @@ genCmpEq (iCode * ic, iCode * ifx)
          gencjneshort (left, right, tlbl);
          if (IC_TRUE (ifx))
            {
+             freeForBranchAsmop (result);
+             freeForBranchAsmop (right);
+             freeForBranchAsmop (left);
              emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
              emitcode ("", "%05d$:", tlbl->key + 100);
            }
@@ -4914,6 +5094,9 @@ genCmpEq (iCode * ic, iCode * ifx)
              symbol *lbl = newiTempLabel (NULL);
              emitcode ("sjmp", "%05d$", lbl->key + 100);
              emitcode ("", "%05d$:", tlbl->key + 100);
+             freeForBranchAsmop (result);
+             freeForBranchAsmop (right);
+             freeForBranchAsmop (left);
              emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
              emitcode ("", "%05d$:", lbl->key + 100);
            }
@@ -4961,7 +5144,7 @@ genCmpEq (iCode * ic, iCode * ifx)
        }
       if (ifx)
        {
-         genIfxJump (ifx, "c");
+         genIfxJump (ifx, "c", left, right, result);
          goto release;
        }
       /* if the result is used in an arithmetic operation
@@ -4978,7 +5161,7 @@ genCmpEq (iCode * ic, iCode * ifx)
        }
       if (ifx)
        {
-         genIfxJump (ifx, "a");
+         genIfxJump (ifx, "a", left, right, result);
          goto release;
        }
       /* if the result is used in an arithmetic operation
@@ -5184,7 +5367,7 @@ jumpIfTrue (iCode * ic)
 /* jmpTrueOrFalse -                                                */
 /*-----------------------------------------------------------------*/
 static void
-jmpTrueOrFalse (iCode * ic, symbol * tlbl)
+jmpTrueOrFalse (iCode * ic, symbol * tlbl, operand *left, operand *right, operand *result)
 {
   // ugly but optimized by peephole
   if (IC_TRUE (ic))
@@ -5192,11 +5375,17 @@ jmpTrueOrFalse (iCode * ic, symbol * tlbl)
       symbol *nlbl = newiTempLabel (NULL);
       emitcode ("sjmp", "%05d$", nlbl->key + 100);
       emitcode ("", "%05d$:", tlbl->key + 100);
+      freeForBranchAsmop (result);
+      freeForBranchAsmop (right);
+      freeForBranchAsmop (left);
       emitcode ("ljmp", "%05d$", IC_TRUE (ic)->key + 100);
       emitcode ("", "%05d$:", nlbl->key + 100);
     }
   else
     {
+      freeForBranchAsmop (result);
+      freeForBranchAsmop (right);
+      freeForBranchAsmop (left);
       emitcode ("ljmp", "%05d$", IC_FALSE (ic)->key + 100);
       emitcode ("", "%05d$:", tlbl->key + 100);
     }
@@ -5313,7 +5502,7 @@ genAnd (iCode * ic, iCode * ifx)
        outBitC (result);
       // if(bit & ...)
       else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
-       genIfxJump (ifx, "c");
+       genIfxJump (ifx, "c", left, right, result);
       goto release;
     }
 
@@ -5338,7 +5527,7 @@ genAnd (iCode * ic, iCode * ifx)
              if (ifx)
                {
                  sprintf (buffer, "acc.%d", posbit & 0x07);
-                 genIfxJump (ifx, buffer);
+                 genIfxJump (ifx, buffer, left, right, result);
                }
              goto release;
            }
@@ -5377,7 +5566,7 @@ genAnd (iCode * ic, iCode * ifx)
          else
            {
              if (ifx)
-               jmpTrueOrFalse (ifx, tlbl);
+               jmpTrueOrFalse (ifx, tlbl, left, right, result);
               else
                emitcode ("", "%05d$:", tlbl->key + 100);
              goto release;
@@ -5469,7 +5658,7 @@ genAnd (iCode * ic, iCode * ifx)
              outBitC (result);
            }
          else if (ifx)
-           jmpTrueOrFalse (ifx, tlbl);
+           jmpTrueOrFalse (ifx, tlbl, left, right, result);
           else
            emitcode ("", "%05d$:", tlbl->key + 100);
        }
@@ -5622,7 +5811,7 @@ genOr (iCode * ic, iCode * ifx)
              emitcode ("jnz", "%05d$", tlbl->key + 100);
              if ((AOP_TYPE (result) == AOP_CRY) && ifx)
                {
-                 jmpTrueOrFalse (ifx, tlbl);
+                 jmpTrueOrFalse (ifx, tlbl, left, right, result);
                  goto release;
                }
              else
@@ -5638,7 +5827,7 @@ genOr (iCode * ic, iCode * ifx)
        outBitC (result);
       // if(bit | ...)
       else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
-       genIfxJump (ifx, "c");
+       genIfxJump (ifx, "c", left, right, result);
       goto release;
     }
 
@@ -5672,7 +5861,7 @@ genOr (iCode * ic, iCode * ifx)
            }
          else
            {
-             genIfxJump (ifx, "a");
+             genIfxJump (ifx, "a", left, right, result);
              goto release;
            }
        }
@@ -5757,7 +5946,7 @@ genOr (iCode * ic, iCode * ifx)
              outBitC (result);
            }
          else if (ifx)
-           jmpTrueOrFalse (ifx, tlbl);
+           jmpTrueOrFalse (ifx, tlbl, left, right, result);
          else
            emitcode ("", "%05d$:", tlbl->key + 100);
        }
@@ -5937,7 +6126,7 @@ genXor (iCode * ic, iCode * ifx)
        outBitC (result);
       // if(bit | ...)
       else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
-       genIfxJump (ifx, "c");
+       genIfxJump (ifx, "c", left, right, result);
       goto release;
     }
 
@@ -6020,7 +6209,7 @@ genXor (iCode * ic, iCode * ifx)
              outBitC (result);
            }
          else if (ifx)
-           jmpTrueOrFalse (ifx, tlbl);
+           jmpTrueOrFalse (ifx, tlbl, left, right, result);
        }
       else
        for (; (size--); offset++)
@@ -7568,7 +7757,7 @@ genSignedRightShift (iCode * ic)
 
   size = AOP_SIZE (result);
   offset = size - 1;
-  emitcode ("mov", "a,%s", aopGet (AOP (left), offset, FALSE, FALSE));
+  MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
   emitcode ("rlc", "a");
   emitcode ("mov", "ov,c");
   /* if it is only one byte then */
@@ -8962,11 +9151,11 @@ genIfx (iCode * ic, iCode * popIc)
   /* if the condition is  a bit variable */
   if (isbit && IS_ITEMP (cond) &&
       SPIL_LOC (cond))
-    genIfxJump (ic, SPIL_LOC (cond)->rname);
+    genIfxJump (ic, SPIL_LOC (cond)->rname, NULL, NULL, NULL);
   else if (isbit && !IS_ITEMP (cond))
-    genIfxJump (ic, OP_SYMBOL (cond)->rname);
+    genIfxJump (ic, OP_SYMBOL (cond)->rname, NULL, NULL, NULL);
   else
-    genIfxJump (ic, "a");
+    genIfxJump (ic, "a", NULL, NULL, NULL);
 
   ic->generated = 1;
 }
@@ -9460,7 +9649,7 @@ genDjnz (iCode * ic, iCode * ifx)
     {
       emitcode ("dec", "%s",
                aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
-      emitcode ("mov", "a,%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
+      MOVA (aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE));
       emitcode ("jnz", "%05d$", lbl->key + 100);
     }
   else
@@ -9684,7 +9873,6 @@ genEndCritical (iCode *ic)
     }
 }
 
-
 /*-----------------------------------------------------------------*/
 /* gen51Code - generate code for 8051 based controllers            */
 /*-----------------------------------------------------------------*/
@@ -9704,13 +9892,7 @@ gen51Code (iCode * lic)
   /* if debug information required */
   if (options.debug && currFunc)
     {
-      debugFile->writeFunction(currFunc);
-      _G.debugLine = 1;
-      if (IS_STATIC (currFunc->etype))
-       emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
-      else
-       emitcode ("", "G$%s$0$0 ==.", currFunc->name);
-      _G.debugLine = 0;
+      debugFile->writeFunction (currFunc, lic);
     }
   /* stack pointer name */
   if (options.useXstack)
@@ -9727,11 +9909,7 @@ gen51Code (iCode * lic)
        {
          if (options.debug)
            {
-             _G.debugLine = 1;
-             emitcode ("", "C$%s$%d$%d$%d ==.",
-                       FileBaseName (ic->filename), ic->lineno,
-                       ic->level, ic->block);
-             _G.debugLine = 0;
+             debugFile->writeCLine(ic);
            }
          if (!options.noCcodeInAsm) {
            emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno,