reverting to 1.127
authorjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 16 Nov 2001 14:32:24 +0000 (14:32 +0000)
committerjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 16 Nov 2001 14:32:24 +0000 (14:32 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1603 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/ds390/gen.c

index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3e23ce3e0e50e83a6933c620399434afa8034613 100644 (file)
+/*-------------------------------------------------------------------------
+  gen.c - source file for code generation for DS80C390
+
+  Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
+         and -  Jean-Louis VERN.jlvern@writeme.com (1999)
+  Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
+  DS390 adaptation by Kevin Vigor <kevin@vigor.nu>
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+  In other words, you are welcome to use, share and improve this program.
+  You are forbidden to forbid anyone else to use, share and improve
+  what you give them.   Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <common.h>
+#include "ralloc.h"
+#include "gen.h"
+#include "SDCCglobl.h"
+#include "newalloc.h"
+
+#ifdef HAVE_SYS_ISA_DEFS_H
+#include <sys/isa_defs.h>
+#else
+#ifdef HAVE_MACHINE_ENDIAN_H
+#include <machine/endian.h>
+#else
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
+#else
+#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+#warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
+#warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
+#endif
+#endif
+#endif
+#endif
+
+#define BETTER_LITERAL_SHIFT
+
+char *aopLiteral (value * val, int offset);
+
+/* this is the down and dirty file with all kinds of
+   kludgy & hacky 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 *zero = "#0x00";
+static char *one = "#0x01";
+static char *spname;
+
+#define D(x) x
+
+#define TR_DPTR(s) if (options.model != MODEL_FLAT24) { emitcode(";", " Use_DPTR1 %s ", s); }
+#define TR_AP(s) if (options.model != MODEL_FLAT24) { emitcode(";", " Use_AP %s ", s); }
+
+unsigned fReturnSizeDS390 = 5; /* shared with ralloc.c */
+static char *fReturn24[] =
+{"dpl", "dph", "dpx", "b", "a"};
+static char *fReturn16[] =
+{"dpl", "dph", "b", "a"};
+static char **fReturn = fReturn24;
+static char *accUse[] =
+{"a", "b"};
+
+static short rbank = -1;
+
+static struct
+  {
+    short r0Pushed;
+    short r1Pushed;
+    short accInUse;
+    short inLine;
+    short debugLine;
+    short nRegsSaved;
+    set *sendSet;
+  }
+_G;
+
+static void saveRBank (int, iCode *, bool);
+
+#define RESULTONSTACK(x) \
+                         (IC_RESULT(x) && IC_RESULT(x)->aop && \
+                         IC_RESULT(x)->aop->type == AOP_STK )
+
+/* #define MOVA(x) if (strcmp(x,"a") && strcmp(x,"acc")) emitcode("mov","a,%s",x); */
+#define MOVA(x) { char *_mova_tmp = strdup(x); \
+                 if (strcmp(_mova_tmp,"a") && strcmp(_mova_tmp,"acc")) \
+                 { \
+                    emitcode("mov","a,%s",_mova_tmp); \
+                 } \
+                 free(_mova_tmp); \
+                }
+#define CLRC    emitcode("clr","c")
+#define SETC    emitcode("setb","c")
+
+// A scratch register which will be used to hold
+// result bytes from operands in far space via DPTR2.
+#define DP2_RESULT_REG "ap"
+
+static lineNode *lineHead = NULL;
+static lineNode *lineCurr = NULL;
+
+static unsigned char SLMask[] =
+{0xFF, 0xFE, 0xFC, 0xF8, 0xF0,
+ 0xE0, 0xC0, 0x80, 0x00};
+static unsigned char SRMask[] =
+{0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
+ 0x07, 0x03, 0x01, 0x00};
+
+#define LSB     0
+#define MSB16   1
+#define MSB24   2
+#define MSB32   3
+
+/*-----------------------------------------------------------------*/
+/* emitcode - writes the code into a file : for now it is simple    */
+/*-----------------------------------------------------------------*/
+static void
+emitcode (char *inst, char *fmt,...)
+{
+  va_list ap;
+  char lb[INITIAL_INLINEASM];
+  char *lbp = lb;
+
+  va_start (ap, fmt);
+
+  if (inst && *inst)
+    {
+      if (fmt && *fmt)
+       sprintf (lb, "%s\t", inst);
+      else
+       sprintf (lb, "%s", inst);
+      vsprintf (lb + (strlen (lb)), fmt, ap);
+    }
+  else
+    vsprintf (lb, fmt, ap);
+
+  while (isspace (*lbp))
+    lbp++;
+
+  if (lbp && *lbp)
+    lineCurr = (lineCurr ?
+               connectLine (lineCurr, newLineNode (lb)) :
+               (lineHead = newLineNode (lb)));
+  lineCurr->isInline = _G.inLine;
+  lineCurr->isDebug = _G.debugLine;
+  va_end (ap);
+}
+
+/*-----------------------------------------------------------------*/
+/* getFreePtr - returns r0 or r1 whichever is free or can be pushed */
+/*-----------------------------------------------------------------*/
+static regs *
+getFreePtr (iCode * ic, asmop ** aopp, bool result)
+{
+  bool r0iu = FALSE, r1iu = FALSE;
+  bool r0ou = FALSE, r1ou = FALSE;
+
+  /* the logic: if r0 & r1 used in the instruction
+     then we are in trouble otherwise */
+
+  /* first check if r0 & r1 are used by this
+     instruction, in which case we are in trouble */
+  r0iu = bitVectBitValue (ic->rUsed, R0_IDX);
+  r1iu = bitVectBitValue (ic->rUsed, R1_IDX);
+  if (r0iu && r1iu) {
+      goto endOfWorld;
+    }
+
+  r0ou = bitVectBitValue (ic->rMask, R0_IDX);
+  r1ou = bitVectBitValue (ic->rMask, R1_IDX);
+
+  /* if no usage of r0 then return it */
+  if (!r0iu && !r0ou)
+    {
+      ic->rUsed = bitVectSetBit (ic->rUsed, R0_IDX);
+      (*aopp)->type = AOP_R0;
+
+      return (*aopp)->aopu.aop_ptr = ds390_regWithIdx (R0_IDX);
+    }
+
+  /* if no usage of r1 then return it */
+  if (!r1iu && !r1ou)
+    {
+      ic->rUsed = bitVectSetBit (ic->rUsed, R1_IDX);
+      (*aopp)->type = AOP_R1;
+
+      return (*aopp)->aopu.aop_ptr = ds390_regWithIdx (R1_IDX);
+    }
+
+  /* now we know they both have usage */
+  /* if r0 not used in this instruction */
+  if (!r0iu)
+    {
+      /* push it if not already pushed */
+      if (!_G.r0Pushed)
+       {
+         emitcode ("push", "%s",
+                   ds390_regWithIdx (R0_IDX)->dname);
+         _G.r0Pushed++;
+       }
+
+      ic->rUsed = bitVectSetBit (ic->rUsed, R0_IDX);
+      (*aopp)->type = AOP_R0;
+
+      return (*aopp)->aopu.aop_ptr = ds390_regWithIdx (R0_IDX);
+    }
+
+  /* if r1 not used then */
+
+  if (!r1iu)
+    {
+      /* push it if not already pushed */
+      if (!_G.r1Pushed)
+       {
+         emitcode ("push", "%s",
+                   ds390_regWithIdx (R1_IDX)->dname);
+         _G.r1Pushed++;
+       }
+
+      ic->rUsed = bitVectSetBit (ic->rUsed, R1_IDX);
+      (*aopp)->type = AOP_R1;
+      return ds390_regWithIdx (R1_IDX);
+    }
+
+endOfWorld:
+  /* I said end of world but not quite end of world yet */
+  /* if this is a result then we can push it on the stack */
+  if (result)
+    {
+      (*aopp)->type = AOP_STK;
+      return NULL;
+    }
+
+  /* other wise this is true end of the world */
+  werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+         "getFreePtr should never reach here");
+  exit (1);
+}
+
+/*-----------------------------------------------------------------*/
+/* newAsmop - creates a new asmOp                                  */
+/*-----------------------------------------------------------------*/
+static asmop *
+newAsmop (short type)
+{
+  asmop *aop;
+
+  aop = Safe_calloc (1, sizeof (asmop));
+  aop->type = type;
+  return aop;
+}
+
+static int _currentDPS;                /* Current processor DPS. */
+static int _desiredDPS;                /* DPS value compiler thinks we should be using. */
+static int _lazyDPS = 0;       /* if non-zero, we are doing lazy evaluation of DPS changes. */
+
+/*-----------------------------------------------------------------*/
+/* genSetDPTR: generate code to select which DPTR is in use (zero  */
+/* selects standard DPTR (DPL/DPH/DPX), non-zero selects DS390     */
+/* alternate DPTR (DPL1/DPH1/DPX1).          */
+/*-----------------------------------------------------------------*/
+static void
+genSetDPTR (int n)
+{
+
+  /* If we are doing lazy evaluation, simply note the desired
+   * change, but don't emit any code yet.
+   */
+  if (_lazyDPS)
+    {
+      _desiredDPS = n;
+      return;
+    }
+
+  if (!n)
+    {
+      emitcode ("mov", "dps, #0x00");
+    }
+  else
+    {
+      TR_DPTR("#1");
+      emitcode ("mov", "dps, #0x01");
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* _startLazyDPSEvaluation: call to start doing lazy DPS evaluation */
+/*                   */
+/* Any code that operates on DPTR (NB: not on the individual     */
+/* components, like DPH) *must* call _flushLazyDPS() before using  */
+/* DPTR within a lazy DPS evaluation block.        */
+/*                   */
+/* Note that aopPut and aopGet already contain the proper calls to */
+/* _flushLazyDPS, so it is safe to use these calls within a lazy   */
+/* DPS evaluation block.             */
+/*                   */
+/* Also, _flushLazyDPS must be called before any flow control      */
+/* operations that could potentially branch out of the block.    */
+/*                         */
+/* Lazy DPS evaluation is simply an optimization (though an      */
+/* important one), so if in doubt, leave it out.       */
+/*-----------------------------------------------------------------*/
+static void
+_startLazyDPSEvaluation (void)
+{
+  _currentDPS = 0;
+  _desiredDPS = 0;
+#ifdef BETTER_LITERAL_SHIFT  
+  _lazyDPS++;
+#else
+  _lazyDPS = 1;
+#endif  
+}
+
+/*-----------------------------------------------------------------*/
+/* _flushLazyDPS: emit code to force the actual DPS setting to the */
+/* desired one. Call before using DPTR within a lazy DPS evaluation */
+/* block.                */
+/*-----------------------------------------------------------------*/
+static void
+_flushLazyDPS (void)
+{
+  if (!_lazyDPS)
+    {
+      /* nothing to do. */
+      return;
+    }
+
+  if (_desiredDPS != _currentDPS)
+    {
+      if (_desiredDPS)
+       {
+         emitcode ("inc", "dps");
+       }
+      else
+       {
+         emitcode ("dec", "dps");
+       }
+      _currentDPS = _desiredDPS;
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* _endLazyDPSEvaluation: end lazy DPS evaluation block.     */
+/*                   */
+/* Forces us back to the safe state (standard DPTR selected).    */
+/*-----------------------------------------------------------------*/
+static void
+_endLazyDPSEvaluation (void)
+{
+#ifdef BETTER_LITERAL_SHIFT  
+  _lazyDPS--;
+#else
+  _lazyDPS = 0;
+#endif    
+  if (!_lazyDPS)
+  {
+    if (_currentDPS)
+    {
+      genSetDPTR (0);
+      _flushLazyDPS ();
+    }
+    _currentDPS = 0;
+    _desiredDPS = 0;
+  }
+}
+
+
+
+/*-----------------------------------------------------------------*/
+/* pointerCode - returns the code for a pointer type               */
+/*-----------------------------------------------------------------*/
+static int
+pointerCode (sym_link * etype)
+{
+
+  return PTR_TYPE (SPEC_OCLS (etype));
+
+}
+
+/*-----------------------------------------------------------------*/
+/* aopForSym - for a true symbol                                   */
+/*-----------------------------------------------------------------*/
+static asmop *
+aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
+{
+  asmop *aop;
+  memmap *space = SPEC_OCLS (sym->etype);
+
+  /* if already has one */
+  if (sym->aop)
+    return sym->aop;
+
+  /* assign depending on the storage class */
+  /* if it is on the stack or indirectly addressable */
+  /* space we need to assign either r0 or r1 to it   */
+  if ((sym->onStack && !options.stack10bit) || sym->iaccess)
+    {
+      sym->aop = aop = newAsmop (0);
+      aop->aopu.aop_ptr = getFreePtr (ic, &aop, result);
+      aop->size = getSize (sym->type);
+
+      /* now assign the address of the variable to
+         the pointer register */
+      if (aop->type != AOP_STK)
+       {
+
+         if (sym->onStack)
+           {
+             if (_G.accInUse)
+               emitcode ("push", "acc");
+
+             emitcode ("mov", "a,_bp");
+             emitcode ("add", "a,#0x%02x",
+                       ((sym->stack < 0) ?
+                        ((char) (sym->stack - _G.nRegsSaved)) :
+                        ((char) sym->stack)) & 0xff);
+             emitcode ("mov", "%s,a",
+                       aop->aopu.aop_ptr->name);
+
+             if (_G.accInUse)
+               emitcode ("pop", "acc");
+           }
+         else
+           emitcode ("mov", "%s,#%s",
+                     aop->aopu.aop_ptr->name,
+                     sym->rname);
+         aop->paged = space->paged;
+       }
+      else
+       aop->aopu.aop_stk = sym->stack;
+      return aop;
+    }
+
+  if (sym->onStack && options.stack10bit)
+    {
+      /* It's on the 10 bit stack, which is located in
+       * far data space.
+       */
+
+      if (_G.accInUse)
+       emitcode ("push", "acc");
+
+      emitcode ("mov", "a,_bpx");
+      emitcode ("clr","c");
+      emitcode ("subb", "a,#0x%02x",
+               -((sym->stack < 0) ?
+                 ((short) (sym->stack - _G.nRegsSaved)) :
+                 ((short) sym->stack)) & 0xff);
+      emitcode ("mov","b,a");
+      emitcode ("mov","a,#0x%02x",(-((sym->stack < 0) ?
+                                    ((short) (sym->stack - _G.nRegsSaved)) :
+                                    ((short) sym->stack)) >> 8) & 0xff);
+      emitcode ("subb","a,_bpx+1");
+      if (useDP2) {
+         if (options.model == MODEL_FLAT24)
+             emitcode ("mov", "dpx1,#0x40");
+         TR_DPTR("#2");
+         emitcode ("mov", "dph1,a");
+         emitcode ("mov", "dpl1,b");
+      } else {
+         if (options.model == MODEL_FLAT24)
+             emitcode ("mov", "dpx,#0x40");
+         emitcode ("mov", "dph,a");
+         emitcode ("mov", "dpl,b");
+      }
+
+      if (_G.accInUse)
+       emitcode ("pop", "acc");
+
+      sym->aop = aop = newAsmop ((short) (useDP2 ? AOP_DPTR2 : AOP_DPTR));
+      aop->size = getSize (sym->type);
+      return aop;
+    }
+
+  /* if in bit space */
+  if (IN_BITSPACE (space))
+    {
+      sym->aop = aop = newAsmop (AOP_CRY);
+      aop->aopu.aop_dir = sym->rname;
+      aop->size = getSize (sym->type);
+      return aop;
+    }
+  /* if it is in direct space */
+  if (IN_DIRSPACE (space))
+    {
+      sym->aop = aop = newAsmop (AOP_DIR);
+      aop->aopu.aop_dir = sym->rname;
+      aop->size = getSize (sym->type);
+      return aop;
+    }
+
+  /* special case for a function */
+  if (IS_FUNC (sym->type))
+    {
+      sym->aop = aop = newAsmop (AOP_IMMD);
+      aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (sym->rname) + 1);
+      strcpy (aop->aopu.aop_immd.aop_immd1, sym->rname);
+      aop->size = FPTRSIZE;
+      return aop;
+    }
+
+  /* only remaining is far space */
+  /* in which case DPTR gets the address */
+  sym->aop = aop = newAsmop ((short) (useDP2 ? AOP_DPTR2 : AOP_DPTR));
+  if (useDP2)
+    {
+      genSetDPTR (1);
+      _flushLazyDPS ();
+      emitcode ("mov", "dptr,#%s", sym->rname);
+      genSetDPTR (0);
+    }
+  else
+    {
+      emitcode ("mov", "dptr,#%s", sym->rname);
+    }
+  aop->size = getSize (sym->type);
+
+  /* if it is in code space */
+  if (IN_CODESPACE (space))
+    aop->code = 1;
+
+  return aop;
+}
+
+/*-----------------------------------------------------------------*/
+/* aopForRemat - rematerialzes an object                           */
+/*-----------------------------------------------------------------*/
+static asmop *
+aopForRemat (symbol * sym)
+{
+  iCode *ic = sym->rematiCode;
+  asmop *aop = newAsmop (AOP_IMMD);
+  int ptr_type =0;
+  int val = 0;
+
+  for (;;)
+    {
+      if (ic->op == '+')
+       val += (int) operandLitValue (IC_RIGHT (ic));
+      else if (ic->op == '-')
+       val -= (int) operandLitValue (IC_RIGHT (ic));
+      else if (IS_CAST_ICODE(ic)) {
+             sym_link *from_type = operandType(IC_RIGHT(ic));
+             aop->aopu.aop_immd.from_cast_remat = 1;
+             ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+             ptr_type = DCL_TYPE(from_type);
+             if (ptr_type == IPOINTER) {
+               // bug #481053
+               ptr_type = POINTER;
+             }
+             continue ;
+      } else break;
+      
+      ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+    }
+
+  if (val)
+    sprintf (buffer, "(%s %c 0x%04x)",
+            OP_SYMBOL (IC_LEFT (ic))->rname,
+            val >= 0 ? '+' : '-',
+            abs (val) & 0xffff);
+  else
+    strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
+
+  aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1);
+  strcpy (aop->aopu.aop_immd.aop_immd1, buffer);
+  /* set immd2 field if required */
+  if (aop->aopu.aop_immd.from_cast_remat) {
+         sprintf(buffer,"#0x%02x",ptr_type);
+         aop->aopu.aop_immd.aop_immd2 = Safe_calloc (1, strlen (buffer) + 1);
+         strcpy (aop->aopu.aop_immd.aop_immd2, buffer);
+  }
+
+  return aop;
+}
+
+/*-----------------------------------------------------------------*/
+/* regsInCommon - two operands have some registers in common       */
+/*-----------------------------------------------------------------*/
+static bool
+regsInCommon (operand * op1, operand * op2)
+{
+  symbol *sym1, *sym2;
+  int i;
+
+  /* if they have registers in common */
+  if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
+    return FALSE;
+
+  sym1 = OP_SYMBOL (op1);
+  sym2 = OP_SYMBOL (op2);
+
+  if (sym1->nRegs == 0 || sym2->nRegs == 0)
+    return FALSE;
+
+  for (i = 0; i < sym1->nRegs; i++)
+    {
+      int j;
+      if (!sym1->regs[i])
+       continue;
+
+      for (j = 0; j < sym2->nRegs; j++)
+       {
+         if (!sym2->regs[j])
+           continue;
+
+         if (sym2->regs[j] == sym1->regs[i])
+           return TRUE;
+       }
+    }
+
+  return FALSE;
+}
+
+/*-----------------------------------------------------------------*/
+/* operandsEqu - equivalent                                        */
+/*-----------------------------------------------------------------*/
+static bool
+operandsEqu (operand * op1, operand * op2)
+{
+  symbol *sym1, *sym2;
+
+  /* if they not symbols */
+  if (!IS_SYMOP (op1) || !IS_SYMOP (op2))
+    return FALSE;
+
+  sym1 = OP_SYMBOL (op1);
+  sym2 = OP_SYMBOL (op2);
+
+  /* if both are itemps & one is spilt
+     and the other is not then false */
+  if (IS_ITEMP (op1) && IS_ITEMP (op2) &&
+      sym1->isspilt != sym2->isspilt)
+    return FALSE;
+
+  /* if they are the same */
+  if (sym1 == sym2)
+    return TRUE;
+
+  if (strcmp (sym1->rname, sym2->rname) == 0)
+    return TRUE;
+
+
+  /* if left is a tmp & right is not */
+  if (IS_ITEMP (op1) &&
+      !IS_ITEMP (op2) &&
+      sym1->isspilt &&
+      (sym1->usl.spillLoc == sym2))
+    return TRUE;
+
+  if (IS_ITEMP (op2) &&
+      !IS_ITEMP (op1) &&
+      sym2->isspilt &&
+      sym1->level > 0 &&
+      (sym2->usl.spillLoc == sym1))
+    return TRUE;
+
+  return FALSE;
+}
+
+/*-----------------------------------------------------------------*/
+/* sameRegs - two asmops have the same registers                   */
+/*-----------------------------------------------------------------*/
+static bool
+sameRegs (asmop * aop1, asmop * aop2)
+{
+  int i;
+
+  if (aop1 == aop2)
+    {
+      if (aop1->type == AOP_DPTR || aop1->type == AOP_DPTR2)
+       {
+         return FALSE;
+       }
+      return TRUE;
+    }
+
+  if (aop1->type != AOP_REG ||
+      aop2->type != AOP_REG)
+    return FALSE;
+
+  if (aop1->size != aop2->size)
+    return FALSE;
+
+  for (i = 0; i < aop1->size; i++)
+    if (aop1->aopu.aop_reg[i] !=
+       aop2->aopu.aop_reg[i])
+      return FALSE;
+
+  return TRUE;
+}
+
+/*-----------------------------------------------------------------*/
+/* aopOp - allocates an asmop for an operand  :                    */
+/*-----------------------------------------------------------------*/
+static void
+aopOp (operand * op, iCode * ic, bool result, bool useDP2)
+{
+  asmop *aop;
+  symbol *sym;
+  int i;
+
+  if (!op)
+    return;
+
+  /* if this a literal */
+  if (IS_OP_LITERAL (op))
+    {
+      op->aop = aop = newAsmop (AOP_LIT);
+      aop->aopu.aop_lit = op->operand.valOperand;
+      aop->size = getSize (operandType (op));
+      return;
+    }
+
+  /* if already has a asmop then continue */
+  if (op->aop)
+    return;
+
+  /* if the underlying symbol has a aop */
+  if (IS_SYMOP (op) && OP_SYMBOL (op)->aop)
+    {
+      op->aop = OP_SYMBOL (op)->aop;
+      return;
+    }
+
+  /* if this is a true symbol */
+  if (IS_TRUE_SYMOP (op))
+    {
+      op->aop = aopForSym (ic, OP_SYMBOL (op), result, useDP2);
+      return;
+    }
+
+  /* this is a temporary : this has
+     only four choices :
+     a) register
+     b) spillocation
+     c) rematerialize
+     d) conditional
+     e) can be a return use only */
+
+  sym = OP_SYMBOL (op);
+
+
+  /* if the type is a conditional */
+  if (sym->regType == REG_CND)
+    {
+      aop = op->aop = sym->aop = newAsmop (AOP_CRY);
+      aop->size = 0;
+      return;
+    }
+
+  /* if it is spilt then two situations
+     a) is rematerialize
+     b) has a spill location */
+  if (sym->isspilt || sym->nRegs == 0)
+    {
+
+      /* rematerialize it NOW */
+      if (sym->remat)
+       {
+         sym->aop = op->aop = aop =
+           aopForRemat (sym);
+         aop->size = getSize (sym->type);
+         return;
+       }
+
+      if (sym->accuse)
+       {
+         int i;
+         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];
+         return;
+       }
+
+      if (sym->ruonly)
+       {
+         int i;
+
+         if (useDP2)
+           {
+             /* a AOP_STR uses DPTR, but DPTR is already in use;
+              * we're just hosed.
+              */
+             fprintf (stderr, "*** Internal error: AOP_STR with DPTR in use! for operand %s\n",sym->name);
+           }
+
+         aop = op->aop = sym->aop = newAsmop (AOP_STR);
+         aop->size = getSize (sym->type);
+         for (i = 0; i < (int) fReturnSizeDS390; i++)
+           aop->aopu.aop_str[i] = fReturn[i];
+         return;
+       }
+
+      /* else spill location  */
+      sym->aop = op->aop = aop =
+       aopForSym (ic, sym->usl.spillLoc, result, useDP2);
+      aop->size = getSize (sym->type);
+      return;
+    }
+
+  /* must be in a register */
+  sym->aop = op->aop = aop = newAsmop (AOP_REG);
+  aop->size = sym->nRegs;
+  for (i = 0; i < sym->nRegs; i++)
+    aop->aopu.aop_reg[i] = sym->regs[i];
+}
+
+/*-----------------------------------------------------------------*/
+/* freeAsmop - free up the asmop given to an operand               */
+/*----------------------------------------------------------------*/
+static void
+freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
+{
+  asmop *aop;
+
+  if (!op)
+    aop = aaop;
+  else
+    aop = op->aop;
+
+  if (!aop)
+    return;
+
+  if (aop->freed)
+    goto dealloc;
+
+  aop->freed = 1;
+
+  /* depending on the asmop type only three cases need work AOP_RO
+     , AOP_R1 && AOP_STK */
+  switch (aop->type)
+    {
+    case AOP_R0:
+      if (_G.r0Pushed)
+       {
+         if (pop)
+           {
+             emitcode ("pop", "ar0");
+             _G.r0Pushed--;
+           }
+       }
+      bitVectUnSetBit (ic->rUsed, R0_IDX);
+      break;
+
+    case AOP_R1:
+      if (_G.r1Pushed)
+       {
+         if (pop)
+           {
+             emitcode ("pop", "ar1");
+             _G.r1Pushed--;
+           }
+       }
+      bitVectUnSetBit (ic->rUsed, R1_IDX);
+      break;
+
+    case AOP_STK:
+      {
+       int sz = aop->size;
+       int stk = aop->aopu.aop_stk + aop->size;
+       bitVectUnSetBit (ic->rUsed, R0_IDX);
+       bitVectUnSetBit (ic->rUsed, R1_IDX);
+
+       getFreePtr (ic, &aop, FALSE);
+
+       if (options.stack10bit)
+         {
+           /* I'm not sure what to do here yet... */
+           /* #STUB */
+           fprintf (stderr,
+                    "*** Warning: probably generating bad code for "
+                    "10 bit stack mode.\n");
+         }
+
+       if (stk)
+         {
+           emitcode ("mov", "a,_bp");
+           emitcode ("add", "a,#0x%02x", ((char) stk) & 0xff);
+           emitcode ("mov", "%s,a", aop->aopu.aop_ptr->name);
+         }
+       else
+         {
+           emitcode ("mov", "%s,_bp", aop->aopu.aop_ptr->name);
+         }
+
+       while (sz--)
+         {
+           emitcode ("pop", "acc");
+           emitcode ("mov", "@%s,a", aop->aopu.aop_ptr->name);
+           if (!sz)
+             break;
+           emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
+         }
+       op->aop = aop;
+       freeAsmop (op, NULL, ic, TRUE);
+       if (_G.r0Pushed)
+         {
+           emitcode ("pop", "ar0");
+           _G.r0Pushed--;
+         }
+
+       if (_G.r1Pushed)
+         {
+           emitcode ("pop", "ar1");
+           _G.r1Pushed--;
+         }
+      }
+    }
+
+dealloc:
+  /* all other cases just dealloc */
+  if (op)
+    {
+      op->aop = NULL;
+      if (IS_SYMOP (op))
+       {
+         OP_SYMBOL (op)->aop = NULL;
+         /* if the symbol has a spill */
+         if (SPIL_LOC (op))
+           SPIL_LOC (op)->aop = NULL;
+       }
+    }
+}
+
+/*------------------------------------------------------------------*/
+/* aopGet - for fetching value of the aop                           */
+/*                    */
+/* Set canClobberACC if you are sure it is OK to clobber the value  */
+/* in the accumulator. Set it FALSE otherwise; FALSE is always safe, */
+/* just less efficient.               */
+/*------------------------------------------------------------------*/
+
+static char *
+aopGet (asmop * aop,
+       int offset,
+       bool bit16,
+       bool dname,
+       bool canClobberACC)
+{
+  char *s = buffer;
+  char *rs;
+
+  /* offset is greater than
+     size then zero */
+  if (offset > (aop->size - 1) &&
+      aop->type != AOP_LIT)
+    return zero;
+
+  /* depending on type */
+  switch (aop->type)
+    {
+
+    case AOP_R0:
+    case AOP_R1:
+      /* if we need to increment it */
+      while (offset > aop->coff)
+       {
+         emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
+         aop->coff++;
+       }
+
+      while (offset < aop->coff)
+       {
+         emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
+         aop->coff--;
+       }
+
+      aop->coff = offset;
+      if (aop->paged)
+       {
+         emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name);
+         return (dname ? "acc" : "a");
+       }
+      sprintf (s, "@%s", aop->aopu.aop_ptr->name);
+      rs = Safe_calloc (1, strlen (s) + 1);
+      strcpy (rs, s);
+      return rs;
+
+    case AOP_DPTR:
+    case AOP_DPTR2:
+
+      if (aop->type == AOP_DPTR2)
+       {
+         genSetDPTR (1);
+         if (!canClobberACC)
+           {
+                   TR_AP("#1");
+                   emitcode ("xch", "a, %s", DP2_RESULT_REG);
+           }
+       }
+
+      _flushLazyDPS ();
+
+      while (offset > aop->coff)
+       {
+         emitcode ("inc", "dptr");
+         aop->coff++;
+       }
+
+      while (offset < aop->coff)
+       {
+         emitcode ("lcall", "__decdptr");
+         aop->coff--;
+       }
+
+      aop->coff = offset;
+      if (aop->code)
+       {
+         emitcode ("clr", "a");
+         emitcode ("movc", "a,@a+dptr");
+       }
+      else
+       {
+         emitcode ("movx", "a,@dptr");
+       }
+
+      if (aop->type == AOP_DPTR2)
+       {
+         genSetDPTR (0);
+         if (!canClobberACC)
+           {
+       TR_AP("#2");
+             emitcode ("xch", "a, %s", DP2_RESULT_REG);
+             return DP2_RESULT_REG;
+           }
+       }
+      return (dname ? "acc" : "a");
+
+    case AOP_IMMD:
+      if (aop->aopu.aop_immd.from_cast_remat && (offset == (aop->size-1))) {
+             sprintf(s,"%s",aop->aopu.aop_immd.aop_immd2);
+      } else if (bit16)
+       sprintf (s, "#%s", aop->aopu.aop_immd.aop_immd1);
+      else if (offset)
+       sprintf (s, "#(%s >> %d)",
+                aop->aopu.aop_immd.aop_immd1,
+                offset * 8);
+      else
+       sprintf (s, "#%s",
+                aop->aopu.aop_immd.aop_immd1);
+      rs = Safe_calloc (1, strlen (s) + 1);
+      strcpy (rs, s);
+      return rs;
+
+    case AOP_DIR:
+      if (offset)
+       sprintf (s, "(%s + %d)",
+                aop->aopu.aop_dir,
+                offset);
+      else
+       sprintf (s, "%s", aop->aopu.aop_dir);
+      rs = Safe_calloc (1, strlen (s) + 1);
+      strcpy (rs, s);
+      return rs;
+
+    case AOP_REG:
+      if (dname)
+       return aop->aopu.aop_reg[offset]->dname;
+      else
+       return aop->aopu.aop_reg[offset]->name;
+
+    case AOP_CRY:
+      emitcode ("clr", "a");
+      emitcode ("mov", "c,%s", aop->aopu.aop_dir);
+      emitcode ("rlc", "a");
+      return (dname ? "acc" : "a");
+
+    case AOP_ACC:
+      if (!offset && dname)
+       return "acc";
+      return aop->aopu.aop_str[offset];
+
+    case AOP_LIT:
+      return aopLiteral (aop->aopu.aop_lit, offset);
+
+    case AOP_STR:
+      aop->coff = offset;
+      if (strcmp (aop->aopu.aop_str[offset], "a") == 0 &&
+         dname)
+       return "acc";
+
+      return aop->aopu.aop_str[offset];
+
+    }
+
+  werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+         "aopget got unsupported aop->type");
+  exit (1);
+}
+/*-----------------------------------------------------------------*/
+/* aopPut - puts a string for a aop                                */
+/*-----------------------------------------------------------------*/
+static void
+aopPut (asmop * aop, char *s, int offset)
+{
+  char *d = buffer;
+
+  if (aop->size && offset > (aop->size - 1))
+    {
+      werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+             "aopPut got offset > aop->size");
+      exit (1);
+    }
+
+  /* will assign value to value */
+  /* depending on where it is ofcourse */
+  switch (aop->type)
+    {
+    case AOP_DIR:
+      if (offset)
+       sprintf (d, "(%s + %d)",
+                aop->aopu.aop_dir, offset);
+      else
+       sprintf (d, "%s", aop->aopu.aop_dir);
+
+      if (strcmp (d, s))
+       emitcode ("mov", "%s,%s", d, s);
+
+      break;
+
+    case AOP_REG:
+      if (strcmp (aop->aopu.aop_reg[offset]->name, s) != 0 &&
+         strcmp (aop->aopu.aop_reg[offset]->dname, s) != 0)
+       {
+         if (*s == '@' ||
+             strcmp (s, "r0") == 0 ||
+             strcmp (s, "r1") == 0 ||
+             strcmp (s, "r2") == 0 ||
+             strcmp (s, "r3") == 0 ||
+             strcmp (s, "r4") == 0 ||
+             strcmp (s, "r5") == 0 ||
+             strcmp (s, "r6") == 0 ||
+             strcmp (s, "r7") == 0)
+           emitcode ("mov", "%s,%s",
+                     aop->aopu.aop_reg[offset]->dname, s);
+         else
+           emitcode ("mov", "%s,%s",
+                     aop->aopu.aop_reg[offset]->name, s);
+       }
+      break;
+
+    case AOP_DPTR:
+    case AOP_DPTR2:
+
+      if (aop->type == AOP_DPTR2)
+       {
+         genSetDPTR (1);
+       }
+      _flushLazyDPS ();
+
+      if (aop->code)
+       {
+         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                 "aopPut writting to code space");
+         exit (1);
+       }
+
+      while (offset > aop->coff)
+       {
+         aop->coff++;
+         emitcode ("inc", "dptr");
+       }
+
+      while (offset < aop->coff)
+       {
+         aop->coff--;
+         emitcode ("lcall", "__decdptr");
+       }
+
+      aop->coff = offset;
+
+      /* if not in accumulater */
+      MOVA (s);
+
+      emitcode ("movx", "@dptr,a");
+
+      if (aop->type == AOP_DPTR2)
+       {
+         genSetDPTR (0);
+       }
+      break;
+
+    case AOP_R0:
+    case AOP_R1:
+      while (offset > aop->coff)
+       {
+         aop->coff++;
+         emitcode ("inc", "%s", aop->aopu.aop_ptr->name);
+       }
+      while (offset < aop->coff)
+       {
+         aop->coff--;
+         emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
+       }
+      aop->coff = offset;
+
+      if (aop->paged)
+       {
+         MOVA (s);
+         emitcode ("movx", "@%s,a", aop->aopu.aop_ptr->name);
+
+       }
+      else if (*s == '@')
+       {
+         MOVA (s);
+         emitcode ("mov", "@%s,a", aop->aopu.aop_ptr->name);
+       }
+      else if (strcmp (s, "r0") == 0 ||
+              strcmp (s, "r1") == 0 ||
+              strcmp (s, "r2") == 0 ||
+              strcmp (s, "r3") == 0 ||
+              strcmp (s, "r4") == 0 ||
+              strcmp (s, "r5") == 0 ||
+              strcmp (s, "r6") == 0 ||
+              strcmp (s, "r7") == 0)
+       {
+         char buffer[10];
+         sprintf (buffer, "a%s", s);
+         emitcode ("mov", "@%s,%s",
+                   aop->aopu.aop_ptr->name, buffer);
+       }
+      else
+       emitcode ("mov", "@%s,%s", aop->aopu.aop_ptr->name, s);
+
+      break;
+
+    case AOP_STK:
+      if (strcmp (s, "a") == 0)
+       emitcode ("push", "acc");
+      else
+       if (*s=='@') {
+         MOVA(s);
+         emitcode ("push", "acc");
+       } else {
+         emitcode ("push", s);
+       }
+
+      break;
+
+    case AOP_CRY:
+      /* if bit variable */
+      if (!aop->aopu.aop_dir)
+       {
+         emitcode ("clr", "a");
+         emitcode ("rlc", "a");
+       }
+      else
+       {
+         if (s == zero)
+           emitcode ("clr", "%s", aop->aopu.aop_dir);
+         else if (s == one)
+           emitcode ("setb", "%s", aop->aopu.aop_dir);
+         else if (!strcmp (s, "c"))
+           emitcode ("mov", "%s,c", aop->aopu.aop_dir);
+         else
+           {
+             if (strcmp (s, "a"))
+               {
+                 MOVA (s);
+               }
+             {
+               symbol *lbl = newiTempLabel (NULL);
+               emitcode ("clr", "c");
+               emitcode ("jz", "%05d$", lbl->key + 100);
+               emitcode ("cpl", "c");
+               emitcode ("", "%05d$:", lbl->key + 100);
+               emitcode ("mov", "%s,c", aop->aopu.aop_dir);
+             }
+           }
+       }
+      break;
+
+    case AOP_STR:
+      aop->coff = offset;
+      if (strcmp (aop->aopu.aop_str[offset], s))
+       emitcode ("mov", "%s,%s", aop->aopu.aop_str[offset], s);
+      break;
+
+    case AOP_ACC:
+      aop->coff = offset;
+      if (!offset && (strcmp (s, "acc") == 0))
+       break;
+
+      if (strcmp (aop->aopu.aop_str[offset], s))
+       emitcode ("mov", "%s,%s", aop->aopu.aop_str[offset], s);
+      break;
+
+    default:
+      werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+             "aopPut got unsupported aop->type");
+      exit (1);
+    }
+
+}
+
+
+/*--------------------------------------------------------------------*/
+/* reAdjustPreg - points a register back to where it should (coff==0) */
+/*--------------------------------------------------------------------*/
+static void
+reAdjustPreg (asmop * aop)
+{
+  if ((aop->coff==0) || (aop->size <= 1)) {
+    return;
+  }
+
+  switch (aop->type)
+    {
+    case AOP_R0:
+    case AOP_R1:
+      while (aop->coff--)
+       emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
+      break;
+    case AOP_DPTR:
+    case AOP_DPTR2:
+      if (aop->type == AOP_DPTR2)
+       {
+         genSetDPTR (1);
+         _flushLazyDPS ();
+       }
+      while (aop->coff--)
+       {
+         emitcode ("lcall", "__decdptr");
+       }
+
+      if (aop->type == AOP_DPTR2)
+       {
+         genSetDPTR (0);
+       }
+      break;
+
+    }
+  aop->coff=0;
+}
+
+#define AOP(op) op->aop
+#define AOP_TYPE(op) AOP(op)->type
+#define AOP_SIZE(op) AOP(op)->size
+#define IS_AOP_PREG(x) (AOP(x) && (AOP_TYPE(x) == AOP_R1 || \
+                       AOP_TYPE(x) == AOP_R0))
+
+#define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY ||  \
+                        AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_DPTR2 || \
+                         AOP(x)->paged))
+
+#define AOP_INPREG(x) (x && (x->type == AOP_REG &&                        \
+                      (x->aopu.aop_reg[0] == ds390_regWithIdx(R0_IDX) || \
+                      x->aopu.aop_reg[0] == ds390_regWithIdx(R1_IDX) )))
+
+/* Workaround for DS80C390 bug: div ab may return bogus results
+ * if A is accessed in instruction immediately before the div.
+ *
+ * Will be fixed in B4 rev of processor, Dallas claims.
+ */
+
+#define LOAD_AB_FOR_DIV(LEFT, RIGHT, L)       \
+    if (!AOP_NEEDSACC(RIGHT))         \
+    {               \
+      /* We can load A first, then B, since     \
+       * B (the RIGHT operand) won't clobber A,   \
+       * thus avoiding touching A right before the div. \
+       */             \
+      D(emitcode(";", "DS80C390 div bug: rearranged ops.");); \
+      L = aopGet(AOP(LEFT),0,FALSE,FALSE,TRUE);     \
+      MOVA(L);            \
+      emitcode("mov","b,%s",aopGet(AOP(RIGHT),0,FALSE,FALSE,FALSE));\
+    }               \
+    else              \
+    {               \
+      /* Just stuff in a nop after loading A. */    \
+      emitcode("mov","b,%s",aopGet(AOP(RIGHT),0,FALSE,FALSE,FALSE));\
+      L = aopGet(AOP(LEFT),0,FALSE,FALSE,TRUE);   \
+      MOVA(L);            \
+      emitcode("nop", "; workaround for DS80C390 div bug.");  \
+    }
+
+/*-----------------------------------------------------------------*/
+/* genNotFloat - generates not for float operations              */
+/*-----------------------------------------------------------------*/
+static void
+genNotFloat (operand * op, operand * res)
+{
+  int size, offset;
+  char *l;
+  symbol *tlbl;
+
+  D (emitcode (";", "genNotFloat ");
+    );
+
+  /* we will put 127 in the first byte of
+     the result */
+  aopPut (AOP (res), "#127", 0);
+  size = AOP_SIZE (op) - 1;
+  offset = 1;
+
+  _startLazyDPSEvaluation ();
+  l = aopGet (op->aop, offset++, FALSE, FALSE, TRUE);
+  MOVA (l);
+
+  while (size--)
+    {
+      emitcode ("orl", "a,%s",
+               aopGet (op->aop,
+                       offset++, FALSE, FALSE, FALSE));
+    }
+  _endLazyDPSEvaluation ();
+
+  tlbl = newiTempLabel (NULL);
+  aopPut (res->aop, one, 1);
+  emitcode ("jz", "%05d$", (tlbl->key + 100));
+  aopPut (res->aop, zero, 1);
+  emitcode ("", "%05d$:", (tlbl->key + 100));
+
+  size = res->aop->size - 2;
+  offset = 2;
+  /* put zeros in the rest */
+  while (size--)
+    aopPut (res->aop, zero, offset++);
+}
+
+/*-----------------------------------------------------------------*/
+/* opIsGptr: returns non-zero if the passed operand is       */
+/* a generic pointer type.             */
+/*-----------------------------------------------------------------*/
+static int
+opIsGptr (operand * op)
+{
+  sym_link *type = operandType (op);
+
+  if ((AOP_SIZE (op) == GPTRSIZE) && IS_GENPTR (type))
+    {
+      return 1;
+    }
+  return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* getDataSize - get the operand data size                         */
+/*-----------------------------------------------------------------*/
+static int
+getDataSize (operand * op)
+{
+  int size;
+  size = AOP_SIZE (op);
+  if (size == GPTRSIZE)
+    {
+      sym_link *type = operandType (op);
+      if (IS_GENPTR (type))
+       {
+         /* generic pointer; arithmetic operations
+          * should ignore the high byte (pointer type).
+          */
+         size--;
+       }
+    }
+  return size;
+}
+
+/*-----------------------------------------------------------------*/
+/* outAcc - output Acc                                             */
+/*-----------------------------------------------------------------*/
+static void
+outAcc (operand * result)
+{
+  int size, offset;
+  size = getDataSize (result);
+  if (size)
+    {
+      aopPut (AOP (result), "a", 0);
+      size--;
+      offset = 1;
+      /* unsigned or positive */
+      while (size--)
+       {
+         aopPut (AOP (result), zero, offset++);
+       }
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* outBitC - output a bit C                                        */
+/*-----------------------------------------------------------------*/
+static void
+outBitC (operand * result)
+{
+  /* if the result is bit */
+  if (AOP_TYPE (result) == AOP_CRY)
+    {
+      aopPut (AOP (result), "c", 0);
+    }
+  else
+    {
+      emitcode ("clr", "a");
+      emitcode ("rlc", "a");
+      outAcc (result);
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* toBoolean - emit code for orl a,operator(sizeop)                */
+/*-----------------------------------------------------------------*/
+static void
+toBoolean (operand * oper)
+{
+  int  size = AOP_SIZE (oper) - 1;
+  int  offset = 1;
+  bool usedB = FALSE;
+
+  /* The generic part of a generic pointer should
+   * not participate in it's truth value.
+   *
+   * i.e. 0x10000000 is zero.
+   */
+  if (opIsGptr (oper))
+    {
+      D (emitcode (";", "toBoolean: generic ptr special case.");
+       );
+      size--;
+    }
+
+  _startLazyDPSEvaluation ();
+  if (AOP_NEEDSACC (oper) && size)
+    {
+      usedB = TRUE;
+      emitcode ("push", "b");
+      emitcode ("mov", "b, %s", aopGet (AOP (oper), 0, FALSE, FALSE, FALSE));
+    }
+  else
+    {
+      MOVA (aopGet (AOP (oper), 0, FALSE, FALSE, TRUE));
+    }
+  while (size--)
+    {
+      if (usedB)
+       {
+         emitcode ("orl", "b,%s", aopGet (AOP (oper), offset++, FALSE, FALSE, FALSE));
+       }
+      else
+       {
+         emitcode ("orl", "a,%s", aopGet (AOP (oper), offset++, FALSE, FALSE, FALSE));
+       }
+    }
+  _endLazyDPSEvaluation ();
+
+  if (usedB)
+    {
+      emitcode ("mov", "a,b");
+      emitcode ("pop", "b");
+    }
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genNot - generate code for ! operation                          */
+/*-----------------------------------------------------------------*/
+static void
+genNot (iCode * ic)
+{
+  symbol *tlbl;
+  sym_link *optype = operandType (IC_LEFT (ic));
+
+  D (emitcode (";", "genNot ");
+    );
+
+  /* assign asmOps to operand & result */
+  aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
+  aopOp (IC_RESULT (ic), ic, TRUE, AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR);
+
+  /* if in bit space then a special case */
+  if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
+    {
+      emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
+      emitcode ("cpl", "c");
+      outBitC (IC_RESULT (ic));
+      goto release;
+    }
+
+  /* if type float then do float */
+  if (IS_FLOAT (optype))
+    {
+      genNotFloat (IC_LEFT (ic), IC_RESULT (ic));
+      goto release;
+    }
+
+  toBoolean (IC_LEFT (ic));
+
+  tlbl = newiTempLabel (NULL);
+  emitcode ("cjne", "a,#0x01,%05d$", tlbl->key + 100);
+  emitcode ("", "%05d$:", tlbl->key + 100);
+  outBitC (IC_RESULT (ic));
+
+release:
+  /* release the aops */
+  freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
+  freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genCpl - generate code for complement                           */
+/*-----------------------------------------------------------------*/
+static void
+genCpl (iCode * ic)
+{
+  int offset = 0;
+  int size;
+
+  D (emitcode (";", "genCpl ");
+    );
+
+
+  /* assign asmOps to operand & result */
+  aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
+  aopOp (IC_RESULT (ic), ic, TRUE, AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR);
+
+  /* if both are in bit space then
+     a special case */
+  if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY &&
+      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);
+      goto release;
+    }
+
+  size = AOP_SIZE (IC_RESULT (ic));
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, TRUE);
+      MOVA (l);
+      emitcode ("cpl", "a");
+      aopPut (AOP (IC_RESULT (ic)), "a", offset++);
+    }
+  _endLazyDPSEvaluation ();
+
+
+release:
+  /* release the aops */
+  freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
+  freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genUminusFloat - unary minus for floating points                */
+/*-----------------------------------------------------------------*/
+static void
+genUminusFloat (operand * op, operand * result)
+{
+  int size, offset = 0;
+  char *l;
+  /* for this we just need to flip the
+     first it then copy the rest in place */
+  D (emitcode (";", "genUminusFloat");
+    );
+
+  _startLazyDPSEvaluation ();
+  size = AOP_SIZE (op) - 1;
+  l = aopGet (AOP (op), 3, FALSE, FALSE, TRUE);
+  MOVA (l);
+
+  emitcode ("cpl", "acc.7");
+  aopPut (AOP (result), "a", 3);
+
+  while (size--)
+    {
+      aopPut (AOP (result),
+             aopGet (AOP (op), offset, FALSE, FALSE, FALSE),
+             offset);
+      offset++;
+    }
+  _endLazyDPSEvaluation ();
+}
+
+/*-----------------------------------------------------------------*/
+/* genUminus - unary minus code generation                         */
+/*-----------------------------------------------------------------*/
+static void
+genUminus (iCode * ic)
+{
+  int offset, size;
+  sym_link *optype, *rtype;
+
+  D (emitcode (";", "genUminus ");
+    );
+
+
+  /* assign asmops */
+  aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
+  aopOp (IC_RESULT (ic), ic, TRUE, AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR);
+
+  /* if both in bit space then special
+     case */
+  if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY &&
+      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);
+      goto release;
+    }
+
+  optype = operandType (IC_LEFT (ic));
+  rtype = operandType (IC_RESULT (ic));
+
+  /* if float then do float stuff */
+  if (IS_FLOAT (optype))
+    {
+      genUminusFloat (IC_LEFT (ic), IC_RESULT (ic));
+      goto release;
+    }
+
+  /* otherwise subtract from zero */
+  size = AOP_SIZE (IC_LEFT (ic));
+  offset = 0;
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, TRUE);
+      if (!strcmp (l, "a"))
+       {
+         if (offset == 0)
+           SETC;
+         emitcode ("cpl", "a");
+         emitcode ("addc", "a,#0");
+       }
+      else
+       {
+         if (offset == 0)
+           CLRC;
+         emitcode ("clr", "a");
+         emitcode ("subb", "a,%s", l);
+       }
+      aopPut (AOP (IC_RESULT (ic)), "a", offset++);
+    }
+  _endLazyDPSEvaluation ();
+
+  /* if any remaining bytes in the result */
+  /* we just need to propagate the sign   */
+  if ((size = (AOP_SIZE (IC_RESULT (ic)) - AOP_SIZE (IC_LEFT (ic)))))
+    {
+      emitcode ("rlc", "a");
+      emitcode ("subb", "a,acc");
+      while (size--)
+       aopPut (AOP (IC_RESULT (ic)), "a", offset++);
+    }
+
+release:
+  /* release the aops */
+  freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? 0 : 1));
+  freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* saveRegisters - will look for a call and save the registers     */
+/*-----------------------------------------------------------------*/
+static void
+saveRegisters (iCode * lic)
+{
+  int i;
+  iCode *ic;
+  bitVect *rsave;
+  sym_link *detype;
+
+  /* look for call */
+  for (ic = lic; ic; ic = ic->next)
+    if (ic->op == CALL || ic->op == PCALL)
+      break;
+
+  if (!ic)
+    {
+      fprintf (stderr, "found parameter push with no function call\n");
+      return;
+    }
+
+  /* if the registers have been saved already then
+     do nothing */
+  if (ic->regsSaved || IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic)))) return ;
+
+  /* special case if DPTR alive across a function call then must save it 
+     even though callee saves */
+  if (IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) {
+      int i =0;
+      rsave = newBitVect(ic->rMask->size);
+      for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+         if (bitVectBitValue(ic->rMask,i))
+             rsave = bitVectSetBit(rsave,i);
+      }
+  } else {
+      /* find the registers in use at this time
+        and push them away to safety */
+      rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                            ic->rUsed);
+  }
+  ic->regsSaved = 1;
+  if (options.useXstack)
+    {
+      if (bitVectBitValue (rsave, R0_IDX))
+       emitcode ("mov", "b,r0");
+      emitcode ("mov", "r0,%s", spname);
+      for (i = 0; i < ds390_nRegs; i++)
+       {
+         if (bitVectBitValue (rsave, i))
+           {
+             if (i == R0_IDX)
+               emitcode ("mov", "a,b");
+             else
+               emitcode ("mov", "a,%s", ds390_regWithIdx (i)->name);
+             emitcode ("movx", "@r0,a");
+             emitcode ("inc", "r0");
+           }
+       }
+      emitcode ("mov", "%s,r0", spname);
+      if (bitVectBitValue (rsave, R0_IDX))
+       emitcode ("mov", "r0,b");
+    }
+  else
+    for (i = 0; i < ds390_nRegs; i++)
+      {
+       if (bitVectBitValue (rsave, i))
+         emitcode ("push", "%s", ds390_regWithIdx (i)->dname);
+      }
+
+  detype = getSpec (operandType (IC_LEFT (ic)));
+}
+
+/*-----------------------------------------------------------------*/
+/* unsaveRegisters - pop the pushed registers                      */
+/*-----------------------------------------------------------------*/
+static void
+unsaveRegisters (iCode * ic)
+{
+  int i;
+  bitVect *rsave;
+
+  if (IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) {
+      int i =0;
+      rsave = newBitVect(ic->rMask->size);
+      for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+         if (bitVectBitValue(ic->rMask,i))
+             rsave = bitVectSetBit(rsave,i);
+      }
+  } else {
+      /* find the registers in use at this time
+        and push them away to safety */
+      rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                            ic->rUsed);
+  }
+  if (options.useXstack)
+    {
+      emitcode ("mov", "r0,%s", spname);
+      for (i = ds390_nRegs; i >= 0; i--)
+       {
+         if (bitVectBitValue (rsave, i))
+           {
+             emitcode ("dec", "r0");
+             emitcode ("movx", "a,@r0");
+             if (i == R0_IDX)
+               emitcode ("mov", "b,a");
+             else
+               emitcode ("mov", "%s,a", ds390_regWithIdx (i)->name);
+           }
+
+       }
+      emitcode ("mov", "%s,r0", spname);
+      if (bitVectBitValue (rsave, R0_IDX))
+       emitcode ("mov", "r0,b");
+    }
+  else
+    for (i = ds390_nRegs; i >= 0; i--)
+      {
+       if (bitVectBitValue (rsave, i))
+         emitcode ("pop", "%s", ds390_regWithIdx (i)->dname);
+      }
+
+}
+
+
+/*-----------------------------------------------------------------*/
+/* pushSide -                */
+/*-----------------------------------------------------------------*/
+static void
+pushSide (operand * oper, int size)
+{
+  int offset = 0;
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      char *l = aopGet (AOP (oper), offset++, FALSE, TRUE, FALSE);
+      if (AOP_TYPE (oper) != AOP_REG &&
+         AOP_TYPE (oper) != AOP_DIR &&
+         strcmp (l, "a"))
+       {
+         emitcode ("mov", "a,%s", l);
+         emitcode ("push", "acc");
+       }
+      else
+       emitcode ("push", "%s", l);
+    }
+  _endLazyDPSEvaluation ();
+}
+
+/*-----------------------------------------------------------------*/
+/* assignResultValue -               */
+/*-----------------------------------------------------------------*/
+static void
+assignResultValue (operand * oper)
+{
+  int offset = 0;
+  int size = AOP_SIZE (oper);
+
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      aopPut (AOP (oper), fReturn[offset], offset);
+      offset++;
+    }
+  _endLazyDPSEvaluation ();
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genXpush - pushes onto the external stack                       */
+/*-----------------------------------------------------------------*/
+static void
+genXpush (iCode * ic)
+{
+  asmop *aop = newAsmop (0);
+  regs *r;
+  int size, offset = 0;
+
+  D (emitcode (";", "genXpush ");
+    );
+
+  aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
+  r = getFreePtr (ic, &aop, FALSE);
+
+
+  emitcode ("mov", "%s,_spx", r->name);
+
+  size = AOP_SIZE (IC_LEFT (ic));
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+
+      char *l = aopGet (AOP (IC_LEFT (ic)),
+                       offset++, FALSE, FALSE, TRUE);
+      MOVA (l);
+      emitcode ("movx", "@%s,a", r->name);
+      emitcode ("inc", "%s", r->name);
+
+    }
+  _endLazyDPSEvaluation ();
+
+
+  emitcode ("mov", "_spx,%s", r->name);
+
+  freeAsmop (NULL, aop, ic, TRUE);
+  freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genIpush - genrate code for pushing this gets a little complex  */
+/*-----------------------------------------------------------------*/
+static void
+genIpush (iCode * ic)
+{
+  int size, offset = 0;
+  char *l;
+
+  D (emitcode (";", "genIpush ");
+    );
+
+  /* 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)
+    {
+
+      /* and the item is spilt then do nothing */
+      if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
+       return;
+
+      aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
+      size = AOP_SIZE (IC_LEFT (ic));
+      /* push it on the stack */
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, TRUE, TRUE);
+         if (*l == '#')
+           {
+             MOVA (l);
+             l = "acc";
+           }
+         emitcode ("push", "%s", l);
+       }
+      _endLazyDPSEvaluation ();
+      return;
+    }
+
+  /* this is a paramter push: in this case we call
+     the routine to find the call and save those
+     registers that need to be saved */
+  saveRegisters (ic);
+
+  /* if use external stack then call the external
+     stack pushing routine */
+  if (options.useXstack)
+    {
+      genXpush (ic);
+      return;
+    }
+
+  /* then do the push */
+  aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
+
+  // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
+  size = AOP_SIZE (IC_LEFT (ic));
+
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, TRUE, FALSE);
+      if (AOP_TYPE (IC_LEFT (ic)) != AOP_REG &&
+         AOP_TYPE (IC_LEFT (ic)) != AOP_DIR &&
+         strcmp (l, "a"))
+       {
+         emitcode ("mov", "a,%s", l);
+         emitcode ("push", "acc");
+       }
+      else
+       emitcode ("push", "%s", l);
+    }
+  _endLazyDPSEvaluation ();
+
+  freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genIpop - recover the registers: can happen only for spilling   */
+/*-----------------------------------------------------------------*/
+static void
+genIpop (iCode * ic)
+{
+  int size, offset;
+
+  D (emitcode (";", "genIpop ");
+    );
+
+
+  /* if the temp was not pushed then */
+  if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
+    return;
+
+  aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
+  size = AOP_SIZE (IC_LEFT (ic));
+  offset = (size - 1);
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      emitcode ("pop", "%s", aopGet (AOP (IC_LEFT (ic)), offset--,
+                                    FALSE, TRUE, TRUE));
+    }
+  _endLazyDPSEvaluation ();
+
+  freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* unsaveRBank - restores the resgister bank from stack            */
+/*-----------------------------------------------------------------*/
+static void
+unsaveRBank (int bank, iCode * ic, bool popPsw)
+{
+  int i;
+  asmop *aop = NULL;
+  regs *r = NULL;
+
+  if (options.useXstack)
+  {
+      if (!ic)
+      {
+         /* Assume r0 is available for use. */
+         r = ds390_regWithIdx (R0_IDX);;          
+      }        
+      else
+      {
+         aop = newAsmop (0);
+         r = getFreePtr (ic, &aop, FALSE);
+      }
+      emitcode ("mov", "%s,_spx", r->name);      
+  }
+  
+  if (popPsw)
+    {
+      if (options.useXstack)
+      {
+         emitcode ("movx", "a,@%s", r->name);
+         emitcode ("mov", "psw,a");
+         emitcode ("dec", "%s", r->name);
+       }
+      else
+      {
+       emitcode ("pop", "psw");
+      }
+    }
+
+  for (i = (ds390_nRegs - 1); i >= 0; i--)
+    {
+      if (options.useXstack)
+       {
+         emitcode ("movx", "a,@%s", r->name);
+         emitcode ("mov", "(%s+%d),a",
+                   regs390[i].base, 8 * bank + regs390[i].offset);
+         emitcode ("dec", "%s", r->name);
+
+       }
+      else
+       emitcode ("pop", "(%s+%d)",
+                 regs390[i].base, 8 * bank + regs390[i].offset);
+    }
+
+  if (options.useXstack)
+    {
+      emitcode ("mov", "_spx,%s", r->name);
+    }
+    
+  if (aop)
+  {
+      freeAsmop (NULL, aop, ic, TRUE);  
+  }    
+}
+
+/*-----------------------------------------------------------------*/
+/* saveRBank - saves an entire register bank on the stack          */
+/*-----------------------------------------------------------------*/
+static void
+saveRBank (int bank, iCode * ic, bool pushPsw)
+{
+  int i;
+  asmop *aop = NULL;
+  regs *r = NULL;
+
+  if (options.useXstack)
+    {
+        if (!ic)
+        {
+                 /* Assume r0 is available for use. */
+                 r = ds390_regWithIdx (R0_IDX);;
+        }
+        else
+        {
+                 aop = newAsmop (0);
+                 r = getFreePtr (ic, &aop, FALSE);
+        }
+        emitcode ("mov", "%s,_spx", r->name);    
+    }
+
+  for (i = 0; i < ds390_nRegs; i++)
+    {
+      if (options.useXstack)
+       {
+         emitcode ("inc", "%s", r->name);
+         emitcode ("mov", "a,(%s+%d)",
+                   regs390[i].base, 8 * bank + regs390[i].offset);
+         emitcode ("movx", "@%s,a", r->name);
+       }
+      else
+       emitcode ("push", "(%s+%d)",
+                 regs390[i].base, 8 * bank + regs390[i].offset);
+    }
+
+  if (pushPsw)
+    {
+      if (options.useXstack)
+       {
+         emitcode ("mov", "a,psw");
+         emitcode ("movx", "@%s,a", r->name);
+         emitcode ("inc", "%s", r->name);
+         emitcode ("mov", "_spx,%s", r->name);
+       }
+      else
+      {
+       emitcode ("push", "psw");
+      }
+
+      emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff);
+    }
+  
+  if (aop)
+  {
+       freeAsmop (NULL, aop, ic, TRUE);
+  }    
+    
+  if (ic)
+  {  
+      ic->bankSaved = 1;
+  }
+}
+
+/*-----------------------------------------------------------------*/
+/* genCall - generates a call statement                            */
+/*-----------------------------------------------------------------*/
+static void
+genCall (iCode * ic)
+{
+  sym_link *dtype;
+  bool restoreBank = FALSE;
+  bool swapBanks = FALSE;
+
+  D (emitcode (";", "genCall "););
+
+  /* if we are calling a not _naked function that is not using
+     the same register bank then we need to save the
+     destination registers on the stack */
+  dtype = operandType (IC_LEFT (ic));
+  if (dtype && !IFFUNC_ISNAKED(dtype) &&
+      (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) &&
+      IFFUNC_ISISR (currFunc->type))
+  {
+      if (!ic->bankSaved) 
+      {
+           /* This is unexpected; the bank should have been saved in
+            * genFunction.
+            */
+          saveRBank (FUNC_REGBANK (dtype), ic, FALSE);
+          restoreBank = TRUE;
+      }
+      swapBanks = TRUE;
+  }
+  
+    /* if caller saves & we have not saved then */
+    if (!ic->regsSaved)
+      saveRegisters (ic);
+  
+  /* if send set is not empty the assign */
+  /* We've saved all the registers we care about;
+  * therefore, we may clobber any register not used
+  * in the calling convention (i.e. anything not in
+  * fReturn.
+  */
+  if (_G.sendSet)
+    {
+      iCode *sic;
+
+      for (sic = setFirstItem (_G.sendSet); sic;
+          sic = setNextItem (_G.sendSet))
+       {
+         int size, offset = 0;
+
+#if 0
+         aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
+         size = AOP_SIZE (IC_LEFT (sic));
+
+         _startLazyDPSEvaluation ();
+         while (size--)
+           {
+             char *l = aopGet (AOP(IC_LEFT(sic)), offset,
+                               FALSE, FALSE, TRUE);
+               if ((AOP_TYPE(IC_LEFT(sic)) == AOP_DPTR) && size)
+               {
+                   emitcode("mov", "%s,%s", regs390[offset].name, l);
+               }
+               else if (strcmp (l, fReturn[offset]))
+               {
+                   emitcode ("mov", "%s,%s",
+                             fReturn[offset],
+                             l);
+               }
+             offset++;
+           }
+         _endLazyDPSEvaluation ();
+         if (AOP_TYPE(IC_LEFT(sic)) == AOP_DPTR)
+         {
+             size = AOP_SIZE (IC_LEFT (sic));
+             if (size)
+             {
+                size--;
+             }
+             while (size)
+             {
+                  size--;
+                  emitcode("mov", "%s,%s",
+                                   fReturn[size], regs390[size].name);
+             }
+         }
+#else
+         // we know that dpl(hxb) is the result, so
+         _startLazyDPSEvaluation ();
+         size=getSize(operandType(IC_LEFT(sic)));
+         if (size>1) {
+           aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
+         } else {
+           aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
+         }
+         while (size--)
+           {
+             char *l = aopGet (AOP (IC_LEFT (sic)), offset,
+                               FALSE, FALSE, TRUE);
+             if (strcmp (l, fReturn[offset]))
+               {
+                 emitcode ("mov", "%s,%s",
+                           fReturn[offset],
+                           l);
+               }
+             offset++;
+           }
+         _endLazyDPSEvaluation ();
+#endif
+         freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+       }
+      _G.sendSet = NULL;
+    }  
+    
+  if (swapBanks)
+  {
+        emitcode ("mov", "psw,#0x%02x", 
+           ((FUNC_REGBANK(dtype)) << 3) & 0xff);
+  }
+
+  /* make the call */
+  emitcode ("lcall", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
+                           OP_SYMBOL (IC_LEFT (ic))->rname :
+                           OP_SYMBOL (IC_LEFT (ic))->name));
+
+  if (swapBanks)
+  {
+       emitcode ("mov", "psw,#0x%02x", 
+          ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff);
+  }
+
+  /* if we need assign a result value */
+  if ((IS_ITEMP (IC_RESULT (ic)) &&
+       (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
+       OP_SYMBOL (IC_RESULT (ic))->accuse ||
+       OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
+      IS_TRUE_SYMOP (IC_RESULT (ic)))
+    {
+      if (isOperandInFarSpace (IC_RESULT (ic))
+         && getSize (operandType (IC_RESULT (ic))) <= 2)
+       {
+         int size = getSize (operandType (IC_RESULT (ic)));
+
+         /* Special case for 1 or 2 byte return in far space. */
+         MOVA (fReturn[0]);
+         if (size > 1)
+           {
+             emitcode ("mov", "b,%s", fReturn[1]);
+           }
+
+         aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+         aopPut (AOP (IC_RESULT (ic)), "a", 0);
+
+         if (size > 1)
+           {
+             aopPut (AOP (IC_RESULT (ic)), "b", 1);
+           }
+         freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+       }
+      else
+       {
+         _G.accInUse++;
+         aopOp (IC_RESULT (ic), ic, FALSE, TRUE);
+         _G.accInUse--;
+
+         assignResultValue (IC_RESULT (ic));
+
+         freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+       }
+    }
+
+  /* adjust the stack for parameters if
+     required */
+  if (ic->parmBytes) {
+      if (options.stack10bit) {
+         emitcode ("clr","c");
+         emitcode ("mov","a,sp");
+         emitcode ("subb","a,#0x%02x",ic->parmBytes & 0xff);
+         emitcode ("mov","sp,a");
+         emitcode ("mov","a,#0x%02x",(ic->parmBytes >> 8) & 0xff);
+         emitcode ("subb","a,esp");
+         emitcode ("mov","esp,a");       
+      } else {
+         int i;
+         if (ic->parmBytes > 3) {
+             emitcode ("mov", "a,%s", spname);
+             emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
+             emitcode ("mov", "%s,a", spname);
+         } else
+             for (i = 0; i < ic->parmBytes; i++)
+                 emitcode ("dec", "%s", spname);
+      }
+  }
+
+  /* if we hade saved some registers then unsave them */
+  if (ic->regsSaved)
+    unsaveRegisters (ic);
+
+  /* if register bank was saved then pop them */
+  if (restoreBank)
+    unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genPcall - generates a call by pointer statement                */
+/*-----------------------------------------------------------------*/
+static void
+genPcall (iCode * ic)
+{
+  sym_link *dtype;
+  symbol *rlbl = newiTempLabel (NULL);
+  bool restoreBank=FALSE;
+
+  D (emitcode (";", "genPcall ");
+    );
+
+
+  /* if caller saves & we have not saved then */
+  if (!ic->regsSaved)
+    saveRegisters (ic);
+
+  /* if we are calling a function that is not using
+     the same register bank then we need to save the
+     destination registers on the stack */
+  dtype = operandType (IC_LEFT (ic));
+  if (dtype && !IFFUNC_ISNAKED(dtype) &&
+      IFFUNC_ISISR (currFunc->type) &&
+      (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype))) {
+    saveRBank (FUNC_REGBANK (dtype), ic, TRUE);
+    restoreBank=TRUE;
+  }
+
+  /* push the return address on to the stack */
+  emitcode ("mov", "a,#%05d$", (rlbl->key + 100));
+  emitcode ("push", "acc");
+  emitcode ("mov", "a,#(%05d$ >> 8)", (rlbl->key + 100));
+  emitcode ("push", "acc");
+
+  if (options.model == MODEL_FLAT24)
+    {
+      emitcode ("mov", "a,#(%05d$ >> 16)", (rlbl->key + 100));
+      emitcode ("push", "acc");
+    }
+
+  /* now push the calling address */
+  aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
+
+  pushSide (IC_LEFT (ic), FPTRSIZE);
+
+  freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+
+  /* if send set is not empty the assign */
+  if (_G.sendSet)
+    {
+      iCode *sic;
+
+      for (sic = setFirstItem (_G.sendSet); sic;
+          sic = setNextItem (_G.sendSet))
+       {
+         int size, offset = 0;
+
+         // we know that dpl(hxb) is the result, so
+         _startLazyDPSEvaluation ();
+         size=getSize(operandType(IC_LEFT(sic)));
+         if (size>1) {
+           aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
+         } else {
+           aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
+         }
+         while (size--)
+           {
+             char *l = aopGet (AOP (IC_LEFT (sic)), offset,
+                               FALSE, FALSE, TRUE);
+             if (strcmp (l, fReturn[offset]))
+               {
+                 emitcode ("mov", "%s,%s",
+                           fReturn[offset],
+                           l);
+               }
+             offset++;
+           }
+         _endLazyDPSEvaluation ();
+         freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+       }
+      _G.sendSet = NULL;
+    }
+
+  emitcode ("ret", "");
+  emitcode ("", "%05d$:", (rlbl->key + 100));
+
+
+  /* if we need assign a result value */
+  if ((IS_ITEMP (IC_RESULT (ic)) &&
+       (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
+       OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
+      IS_TRUE_SYMOP (IC_RESULT (ic)))
+    {
+
+      _G.accInUse++;
+      aopOp (IC_RESULT (ic), ic, FALSE, TRUE);
+      _G.accInUse--;
+
+      assignResultValue (IC_RESULT (ic));
+
+      freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+    }
+
+  /* adjust the stack for parameters if
+     required */
+  if (ic->parmBytes)
+    {
+      int i;
+      if (ic->parmBytes > 3)
+       {
+         emitcode ("mov", "a,%s", spname);
+         emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
+         emitcode ("mov", "%s,a", spname);
+       }
+      else
+       for (i = 0; i < ic->parmBytes; i++)
+         emitcode ("dec", "%s", spname);
+
+    }
+
+  /* if register bank was saved then unsave them */
+  if (restoreBank)
+    unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE);
+  
+  /* if we hade saved some registers then
+     unsave them */
+  if (ic->regsSaved)
+    unsaveRegisters (ic);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* resultRemat - result  is rematerializable                       */
+/*-----------------------------------------------------------------*/
+static int
+resultRemat (iCode * ic)
+{
+  if (SKIP_IC (ic) || ic->op == IFX)
+    return 0;
+
+  if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
+    {
+      symbol *sym = OP_SYMBOL (IC_RESULT (ic));
+      if (sym->remat && !POINTER_SET (ic))
+       return 1;
+    }
+
+  return 0;
+}
+
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
+#endif
+
+/*-----------------------------------------------------------------*/
+/* inExcludeList - return 1 if the string is in exclude Reg list   */
+/*-----------------------------------------------------------------*/
+static bool
+inExcludeList (char *s)
+{
+  int i = 0;
+
+  if (options.excludeRegs[i] &&
+      STRCASECMP (options.excludeRegs[i], "none") == 0)
+    return FALSE;
+
+  for (i = 0; options.excludeRegs[i]; i++)
+    {
+      if (options.excludeRegs[i] &&
+         STRCASECMP (s, options.excludeRegs[i]) == 0)
+       return TRUE;
+    }
+  return FALSE;
+}
+
+/*-----------------------------------------------------------------*/
+/* genFunction - generated code for function entry                 */
+/*-----------------------------------------------------------------*/
+static void
+genFunction (iCode * ic)
+{
+  symbol *sym;
+  sym_link *ftype;
+  bool   switchedPSW = FALSE;
+
+  D (emitcode (";", "genFunction "););
+
+  _G.nRegsSaved = 0;
+  /* create the function header */
+  emitcode (";", "-----------------------------------------");
+  emitcode (";", " function %s", (sym = OP_SYMBOL (IC_LEFT (ic)))->name);
+  emitcode (";", "-----------------------------------------");
+
+  emitcode ("", "%s:", sym->rname);
+  ftype = operandType (IC_LEFT (ic));
+
+  if (IFFUNC_ISNAKED(ftype))
+  {
+      emitcode(";", "naked function: no prologue.");
+      return;
+  }
+
+  /* if critical function then turn interrupts off */
+  if (IFFUNC_ISCRITICAL (ftype))
+    emitcode ("clr", "ea");
+
+  /* here we need to generate the equates for the
+     register bank if required */
+  if (FUNC_REGBANK (ftype) != rbank)
+    {
+      int i;
+
+      rbank = FUNC_REGBANK (ftype);
+      for (i = 0; i < ds390_nRegs; i++)
+       {
+         if (regs390[i].print) {
+             if (strcmp (regs390[i].base, "0") == 0)
+                 emitcode ("", "%s = 0x%02x",
+                           regs390[i].dname,
+                           8 * rbank + regs390[i].offset);
+             else
+                 emitcode ("", "%s = %s + 0x%02x",
+                           regs390[i].dname,
+                           regs390[i].base,
+                           8 * rbank + regs390[i].offset);
+         }
+       }
+    }
+
+  /* if this is an interrupt service routine then
+     save acc, b, dpl, dph  */
+  if (IFFUNC_ISISR (sym->type))
+    {
+
+      if (!inExcludeList ("acc"))
+       emitcode ("push", "acc");
+      if (!inExcludeList ("b"))
+       emitcode ("push", "b");
+      if (!inExcludeList ("dpl"))
+       emitcode ("push", "dpl");
+      if (!inExcludeList ("dph"))
+       emitcode ("push", "dph");
+      if (options.model == MODEL_FLAT24 && !inExcludeList ("dpx"))
+       {
+         emitcode ("push", "dpx");
+         /* Make sure we're using standard DPTR */
+         emitcode ("push", "dps");
+         emitcode ("mov", "dps, #0x00");
+         if (options.stack10bit)
+           {
+             /* This ISR could conceivably use DPTR2. Better save it. */
+             emitcode ("push", "dpl1");
+             emitcode ("push", "dph1");
+             emitcode ("push", "dpx1");
+             emitcode ("push",  DP2_RESULT_REG);
+           }
+       }
+      /* if this isr has no bank i.e. is going to
+         run with bank 0 , then we need to save more
+         registers :-) */
+      if (!FUNC_REGBANK (sym->type))
+       {
+
+         /* if this function does not call any other
+            function then we can be economical and
+            save only those registers that are used */
+         if (!IFFUNC_HASFCALL(sym->type))
+           {
+             int i;
+
+             /* if any registers used */
+             if (sym->regsUsed)
+               {
+                 /* save the registers used */
+                 for (i = 0; i < sym->regsUsed->size; i++)
+                   {
+                     if (bitVectBitValue (sym->regsUsed, i) ||
+                         (ds390_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
+                       emitcode ("push", "%s", ds390_regWithIdx (i)->dname);
+                   }
+               }
+
+           }
+         else
+           {
+             /* this function has  a function call cannot
+                determines register usage so we will have to push the
+                entire bank */
+             saveRBank (0, ic, FALSE);
+           }
+       }
+       else
+       {
+           /* This ISR uses a non-zero bank.
+            *
+            * We assume that the bank is available for our
+            * exclusive use.
+            *
+            * However, if this ISR calls a function which uses some
+            * other bank, we must save that bank entirely.
+            */
+           unsigned long banksToSave = 0;
+           
+           if (IFFUNC_HASFCALL(sym->type))
+           {
+
+#define MAX_REGISTER_BANKS 4
+
+               iCode *i;
+               int ix;
+
+               for (i = ic; i; i = i->next)
+               {
+                   if (i->op == ENDFUNCTION)
+                   {
+                       /* we got to the end OK. */
+                       break;
+                   }
+                   
+                   if (i->op == CALL)
+                   {
+                       sym_link *dtype;
+                       
+                       dtype = operandType (IC_LEFT(i));
+                       if (dtype 
+                        && FUNC_REGBANK(dtype) != FUNC_REGBANK(sym->type))
+                       {
+                            /* Mark this bank for saving. */
+                            if (FUNC_REGBANK(dtype) >= MAX_REGISTER_BANKS)
+                            {
+                                werror(E_NO_SUCH_BANK, FUNC_REGBANK(dtype));
+                            }
+                            else
+                            {
+                                banksToSave |= (1 << FUNC_REGBANK(dtype));
+                            }
+                            
+                            /* And note that we don't need to do it in 
+                             * genCall.
+                             */
+                            i->bankSaved = 1;
+                       }
+                   }
+                   if (i->op == PCALL)
+                   {
+                       /* This is a mess; we have no idea what
+                        * register bank the called function might
+                        * use.
+                        *
+                        * The only thing I can think of to do is
+                        * throw a warning and hope.
+                        */
+                       werror(W_FUNCPTR_IN_USING_ISR);   
+                   }
+               }
+
+               if (banksToSave && options.useXstack)
+               {
+                   /* Since we aren't passing it an ic, 
+                    * saveRBank will assume r0 is available to abuse.
+                    *
+                    * So switch to our (trashable) bank now, so
+                    * the caller's R0 isn't trashed.
+                    */
+                   emitcode ("push", "psw");
+                   emitcode ("mov", "psw,#0x%02x", 
+                             (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
+                   switchedPSW = TRUE;
+               }
+               
+               for (ix = 0; ix < MAX_REGISTER_BANKS; ix++)
+               {
+                    if (banksToSave & (1 << ix))
+                    {
+                        saveRBank(ix, NULL, FALSE);
+                    }
+               }
+           }
+           // jwk: this needs a closer look
+           SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave;
+       }
+    }
+  else
+    {
+      /* if callee-save to be used for this function
+         then save the registers being used in this function */
+      if (IFFUNC_CALLEESAVES(sym->type))
+       {
+         int i;
+
+         /* if any registers used */
+         if (sym->regsUsed)
+           {
+             /* save the registers used */
+             for (i = 0; i < sym->regsUsed->size; i++)
+               {
+                 if (bitVectBitValue (sym->regsUsed, i) ||
+                     (ds390_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
+                   {
+                     emitcode ("push", "%s", ds390_regWithIdx (i)->dname);
+                     _G.nRegsSaved++;
+                   }
+               }
+           }
+       }
+    }
+
+  /* set the register bank to the desired value */
+  if ((FUNC_REGBANK (sym->type) || FUNC_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.stack10bit) {
+         emitcode ("push","_bpx");
+         emitcode ("push","_bpx+1");
+         emitcode ("mov","_bpx,%s",spname);
+         emitcode ("mov","_bpx+1,esp");
+         emitcode ("anl","_bpx+1,#3");
+      } else {
+         if (options.useXstack) {
+             emitcode ("mov", "r0,%s", spname);
+             emitcode ("mov", "a,_bp");
+             emitcode ("movx", "@r0,a");
+             emitcode ("inc", "%s", spname);
+         } else {
+             /* set up the stack */
+             emitcode ("push", "_bp"); /* save the callers stack  */
+         }
+         emitcode ("mov", "_bp,%s", spname);
+      }
+  }
+
+  /* adjust the stack for the function */
+  if (sym->stack) {
+      int i = sym->stack;
+      if (options.stack10bit) {
+         if ( i > 1024) werror (W_STACK_OVERFLOW, sym->name);
+         assert (sym->recvSize <= 4);
+         emitcode ("mov","a,sp");
+         emitcode ("add","a,#0x%02x", ((short) sym->stack & 0xff));
+         emitcode ("mov","sp,a");
+         emitcode ("mov","a,esp");
+         emitcode ("addc","a,0x%02x", (((short) sym->stack) >> 8) & 0xff);
+         emitcode ("mov","esp,a");
+      } else {
+         if (i > 256)
+             werror (W_STACK_OVERFLOW, sym->name);
+         
+         if (i > 3 && sym->recvSize < 4) {
+             
+             emitcode ("mov", "a,sp");
+             emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+             emitcode ("mov", "sp,a");
+             
+         } else
+             while (i--)
+                 emitcode ("inc", "sp");
+      }
+  }
+
+  if (sym->xstack)
+    {
+
+      emitcode ("mov", "a,_spx");
+      emitcode ("add", "a,#0x%02x", ((char) sym->xstack & 0xff));
+      emitcode ("mov", "_spx,a");
+    }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genEndFunction - generates epilogue for functions               */
+/*-----------------------------------------------------------------*/
+static void
+genEndFunction (iCode * ic)
+{
+  symbol *sym = OP_SYMBOL (IC_LEFT (ic));
+
+  D (emitcode (";", "genEndFunction "););
+
+  if (IFFUNC_ISNAKED(sym->type))
+  {
+      emitcode(";", "naked function: no epilogue.");
+      return;
+  }
+
+  if (IFFUNC_ISREENT (sym->type) || options.stackAuto) {
+      if (options.stack10bit) {
+         emitcode ("mov", "sp,_bpx", spname);
+         emitcode ("mov", "esp,_bpx+1", spname);
+      } else {
+         emitcode ("mov", "%s,_bp", spname);
+      }
+  }
+
+  /* if use external stack but some variables were
+     added to the local stack then decrement the
+     local stack */
+  if (options.useXstack && sym->stack) {
+      emitcode ("mov", "a,sp");
+      emitcode ("add", "a,#0x%02x", ((char) -sym->stack) & 0xff);
+      emitcode ("mov", "sp,a");
+  }
+
+
+  if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) {
+      if (options.useXstack) {
+         emitcode ("mov", "r0,%s", spname);
+         emitcode ("movx", "a,@r0");
+         emitcode ("mov", "_bp,a");
+         emitcode ("dec", "%s", spname);
+      } else {
+         if (options.stack10bit) {
+             emitcode ("pop", "_bpx+1");
+             emitcode ("pop", "_bpx");
+         } else {
+             emitcode ("pop", "_bp");
+         }
+      }
+  }
+
+  /* restore the register bank  */
+  if (FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type))
+  {
+    if (!FUNC_REGBANK (sym->type) || !IFFUNC_ISISR (sym->type)
+     || !options.useXstack)
+    {
+        /* Special case of ISR using non-zero bank with useXstack
+         * is handled below.
+         */
+        emitcode ("pop", "psw");
+    }
+  }
+
+  if (IFFUNC_ISISR (sym->type))
+    {
+
+      /* now we need to restore the registers */
+      /* if this isr has no bank i.e. is going to
+         run with bank 0 , then we need to save more
+         registers :-) */
+      if (!FUNC_REGBANK (sym->type))
+       {
+         /* if this function does not call any other
+            function then we can be economical and
+            save only those registers that are used */
+         if (!IFFUNC_HASFCALL(sym->type))
+           {
+             int i;
+
+             /* if any registers used */
+             if (sym->regsUsed)
+               {
+                 /* save the registers used */
+                 for (i = sym->regsUsed->size; i >= 0; i--)
+                   {
+                     if (bitVectBitValue (sym->regsUsed, i) ||
+                         (ds390_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
+                       emitcode ("pop", "%s", ds390_regWithIdx (i)->dname);
+                   }
+               }
+
+           }
+         else
+           {
+             /* this function has  a function call cannot
+                determines register usage so we will have to pop the
+                entire bank */
+             unsaveRBank (0, ic, FALSE);
+           }
+       }
+       else
+       {
+           /* This ISR uses a non-zero bank.
+            *
+            * Restore any register banks saved by genFunction
+            * in reverse order.
+            */
+         // jwk: this needs a closer look
+           unsigned savedBanks = SPEC_ISR_SAVED_BANKS(currFunc->etype);
+           int ix;
+         
+           for (ix = MAX_REGISTER_BANKS - 1; ix >= 0; ix--)
+           {
+               if (savedBanks & (1 << ix))
+               {
+                   unsaveRBank(ix, NULL, FALSE);
+               }
+           }
+           
+           if (options.useXstack)
+           {
+               /* Restore bank AFTER calling unsaveRBank,
+                * since it can trash r0.
+                */
+               emitcode ("pop", "psw");
+           }
+       }
+
+      if (options.model == MODEL_FLAT24 && !inExcludeList ("dpx"))
+       {
+         if (options.stack10bit)
+           {
+             emitcode ("pop", DP2_RESULT_REG);
+             emitcode ("pop", "dpx1");
+             emitcode ("pop", "dph1");
+             emitcode ("pop", "dpl1");
+           }
+         emitcode ("pop", "dps");
+         emitcode ("pop", "dpx");
+       }
+      if (!inExcludeList ("dph"))
+       emitcode ("pop", "dph");
+      if (!inExcludeList ("dpl"))
+       emitcode ("pop", "dpl");
+      if (!inExcludeList ("b"))
+       emitcode ("pop", "b");
+      if (!inExcludeList ("acc"))
+       emitcode ("pop", "acc");
+
+      if (IFFUNC_ISCRITICAL (sym->type))
+       emitcode ("setb", "ea");
+
+      /* 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;
+       }
+
+      emitcode ("reti", "");
+    }
+  else
+    {
+      if (IFFUNC_ISCRITICAL (sym->type))
+       emitcode ("setb", "ea");
+
+      if (IFFUNC_CALLEESAVES(sym->type))
+       {
+         int i;
+
+         /* if any registers used */
+         if (sym->regsUsed)
+           {
+             /* save the registers used */
+             for (i = sym->regsUsed->size; i >= 0; i--)
+               {
+                 if (bitVectBitValue (sym->regsUsed, i) ||
+                     (ds390_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
+                   emitcode ("pop", "%s", ds390_regWithIdx (i)->dname);
+               }
+           }
+
+       }
+
+      /* 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;
+       }
+
+      emitcode ("ret", "");
+    }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genRet - generate code for return statement                     */
+/*-----------------------------------------------------------------*/
+static void
+genRet (iCode * ic)
+{
+  int size, offset = 0, pushed = 0;
+
+  D (emitcode (";", "genRet ");
+    );
+
+  /* if we have no return value then
+     just generate the "ret" */
+  if (!IC_LEFT (ic))
+    goto jumpret;
+
+  /* we have something to return then
+     move the return value into place */
+  aopOp (IC_LEFT (ic), ic, FALSE, 
+        (IS_SYMOP(IC_LEFT(ic)) && OP_SYMBOL(IC_LEFT(ic))->ruonly ? FALSE :TRUE));
+  size = AOP_SIZE (IC_LEFT (ic));
+
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      char *l;
+      if (AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR)
+       {
+         l = aopGet (AOP (IC_LEFT (ic)), offset++,
+                     FALSE, TRUE, FALSE);
+         emitcode ("push", "%s", l);
+         pushed++;
+       }
+      else
+       {
+         /* Since A is the last element of fReturn,
+          * is is OK to clobber it in the aopGet.
+          */
+         l = aopGet (AOP (IC_LEFT (ic)), offset,
+                     FALSE, FALSE, TRUE);
+         if (strcmp (fReturn[offset], l))
+           emitcode ("mov", "%s,%s", fReturn[offset++], l);
+       }
+    }
+  _endLazyDPSEvaluation ();
+
+  if (pushed)
+    {
+      while (pushed)
+       {
+         pushed--;
+         if (strcmp (fReturn[pushed], "a"))
+           emitcode ("pop", fReturn[pushed]);
+         else
+           emitcode ("pop", "acc");
+       }
+    }
+  freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+
+jumpret:
+  /* generate a jump to the return label
+     if the next is not the return statement */
+  if (!(ic->next && ic->next->op == LABEL &&
+       IC_LABEL (ic->next) == returnLabel))
+
+    emitcode ("ljmp", "%05d$", (returnLabel->key + 100));
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genLabel - generates a label                                    */
+/*-----------------------------------------------------------------*/
+static void
+genLabel (iCode * ic)
+{
+  /* special case never generate */
+  if (IC_LABEL (ic) == entryLabel)
+    return;
+
+  D (emitcode (";", "genLabel ");
+    );
+
+  emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
+}
+
+/*-----------------------------------------------------------------*/
+/* genGoto - generates a ljmp                                      */
+/*-----------------------------------------------------------------*/
+static void
+genGoto (iCode * ic)
+{
+  D (emitcode (";", "genGoto ");
+    );
+  emitcode ("ljmp", "%05d$", (IC_LABEL (ic)->key + 100));
+}
+
+/*-----------------------------------------------------------------*/
+/* findLabelBackwards: walks back through the iCode chain looking  */
+/* for the given label. Returns number of iCode instructions     */
+/* between that label and given ic.          */
+/* Returns zero if label not found.          */
+/*-----------------------------------------------------------------*/
+static int
+findLabelBackwards (iCode * ic, int key)
+{
+  int count = 0;
+
+  while (ic->prev)
+    {
+      ic = ic->prev;
+      count++;
+
+      if (ic->op == LABEL && IC_LABEL (ic)->key == key)
+       {
+         /* printf("findLabelBackwards = %d\n", count); */
+         return count;
+       }
+    }
+
+  return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* genPlusIncr :- does addition with increment if possible         */
+/*-----------------------------------------------------------------*/
+static bool
+genPlusIncr (iCode * ic)
+{
+  unsigned int icount;
+  unsigned int size = getDataSize (IC_RESULT (ic));
+
+  /* will try to generate an increment */
+  /* if the right side is not a literal
+     we cannot */
+  if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
+    return FALSE;
+
+  /* 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)) > 4)
+    return FALSE;
+
+  /* if increment 16 bits in register */
+  if (
+       AOP_TYPE (IC_LEFT (ic)) == AOP_REG &&
+       AOP_TYPE (IC_RESULT (ic)) == AOP_REG &&
+       sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
+       (size > 1) &&
+       (icount == 1))
+    {
+      symbol *tlbl;
+      int emitTlbl;
+      int labelRange;
+
+      /* If the next instruction is a goto and the goto target
+       * is <= 5 instructions previous to this, we can generate
+       * jumps straight to that target.
+       */
+      if (ic->next && ic->next->op == GOTO
+         && (labelRange = findLabelBackwards (ic, IC_LABEL (ic->next)->key)) != 0
+         && labelRange <= 5)
+       {
+         emitcode (";", "tail increment optimized (range %d)", labelRange);
+         tlbl = IC_LABEL (ic->next);
+         emitTlbl = 0;
+       }
+      else
+       {
+         tlbl = newiTempLabel (NULL);
+         emitTlbl = 1;
+       }
+      emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE));
+      if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+         IS_AOP_PREG (IC_RESULT (ic)))
+       emitcode ("cjne", "%s,#0x00,%05d$"
+                 ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
+                 ,tlbl->key + 100);
+      else
+       {
+         emitcode ("clr", "a");
+         emitcode ("cjne", "a,%s,%05d$"
+                   ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
+                   ,tlbl->key + 100);
+       }
+
+      emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE));
+      if (size > 2)
+       {
+         if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+             IS_AOP_PREG (IC_RESULT (ic)))
+           emitcode ("cjne", "%s,#0x00,%05d$"
+                 ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
+                     ,tlbl->key + 100);
+         else
+           emitcode ("cjne", "a,%s,%05d$"
+                 ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
+                     ,tlbl->key + 100);
+
+         emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE));
+       }
+      if (size > 3)
+       {
+         if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+             IS_AOP_PREG (IC_RESULT (ic)))
+           emitcode ("cjne", "%s,#0x00,%05d$"
+                 ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
+                     ,tlbl->key + 100);
+         else
+           {
+             emitcode ("cjne", "a,%s,%05d$"
+                 ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
+                       ,tlbl->key + 100);
+           }
+         emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, FALSE, FALSE));
+       }
+
+      if (emitTlbl)
+       {
+         emitcode ("", "%05d$:", tlbl->key + 100);
+       }
+      return TRUE;
+    }
+
+  /* if the sizes are greater than 1 then we cannot */
+  if (AOP_SIZE (IC_RESULT (ic)) > 1 ||
+      AOP_SIZE (IC_LEFT (ic)) > 1)
+    return FALSE;
+
+  /* we can if the aops of the left & result match or
+     if they are in registers and the registers are the
+     same */
+  if (
+       AOP_TYPE (IC_LEFT (ic)) == AOP_REG &&
+       AOP_TYPE (IC_RESULT (ic)) == AOP_REG &&
+       sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
+    {
+
+      if (icount > 3)
+       {
+         MOVA (aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE, TRUE));
+         emitcode ("add", "a,#0x%02x", ((char) icount) & 0xff);
+         aopPut (AOP (IC_RESULT (ic)), "a", 0);
+       }
+      else
+       {
+
+         _startLazyDPSEvaluation ();
+         while (icount--)
+           {
+             emitcode ("inc", "%s", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE, FALSE));
+           }
+         _endLazyDPSEvaluation ();
+       }
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+/*-----------------------------------------------------------------*/
+/* outBitAcc - output a bit in acc                                 */
+/*-----------------------------------------------------------------*/
+static void
+outBitAcc (operand * result)
+{
+  symbol *tlbl = newiTempLabel (NULL);
+  /* if the result is a bit */
+  if (AOP_TYPE (result) == AOP_CRY)
+    {
+      aopPut (AOP (result), "a", 0);
+    }
+  else
+    {
+      emitcode ("jz", "%05d$", tlbl->key + 100);
+      emitcode ("mov", "a,%s", one);
+      emitcode ("", "%05d$:", tlbl->key + 100);
+      outAcc (result);
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* genPlusBits - generates code for addition of two bits           */
+/*-----------------------------------------------------------------*/
+static void
+genPlusBits (iCode * ic)
+{
+  D (emitcode (";", "genPlusBits ");
+    );
+  if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
+    {
+      symbol *lbl = newiTempLabel (NULL);
+      emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
+      emitcode ("jnb", "%s,%05d$", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100));
+      emitcode ("cpl", "c");
+      emitcode ("", "%05d$:", (lbl->key + 100));
+      outBitC (IC_RESULT (ic));
+    }
+  else
+    {
+      emitcode ("clr", "a");
+      emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
+      emitcode ("rlc", "a");
+      emitcode ("mov", "c,%s", AOP (IC_RIGHT (ic))->aopu.aop_dir);
+      emitcode ("addc", "a,#0x00");
+      outAcc (IC_RESULT (ic));
+    }
+}
+
+static void
+adjustArithmeticResult (iCode * ic)
+{
+  if (opIsGptr (IC_RESULT (ic)) &&
+      opIsGptr (IC_LEFT (ic)) &&
+      !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))))
+    {
+      aopPut (AOP (IC_RESULT (ic)),
+             aopGet (AOP (IC_LEFT (ic)), GPTRSIZE - 1, FALSE, FALSE, FALSE),
+             GPTRSIZE - 1);
+    }
+
+  if (opIsGptr (IC_RESULT (ic)) &&
+      opIsGptr (IC_RIGHT (ic)) &&
+      !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
+    {
+      aopPut (AOP (IC_RESULT (ic)),
+           aopGet (AOP (IC_RIGHT (ic)), GPTRSIZE - 1, FALSE, FALSE, FALSE),
+             GPTRSIZE - 1);
+    }
+
+  if (opIsGptr (IC_RESULT (ic)) &&
+      AOP_SIZE (IC_LEFT (ic)) < GPTRSIZE &&
+      AOP_SIZE (IC_RIGHT (ic)) < GPTRSIZE &&
+      !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic))) &&
+      !sameRegs (AOP (IC_RESULT (ic)), AOP (IC_RIGHT (ic))))
+    {
+      char buffer[5];
+      sprintf (buffer, "#%d", pointerCode (getSpec (operandType (IC_LEFT (ic)))));
+      aopPut (AOP (IC_RESULT (ic)), buffer, GPTRSIZE - 1);
+    }
+}
+
+#if 0 // AOP_OP_3 is deprecated; nobody likes Ack errors.
+      // Please don't bring it back without a really good reason.
+// Macro to aopOp all three operands of an ic. Will fatal if this cannot be done
+// (because all three operands are in far space).
+#define AOP_OP_3(ic) \
+    aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
+    aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
+    aopOp (IC_RESULT(ic),ic,TRUE, (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) || \
+              (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
+    if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \
+        AOP_TYPE(IC_RESULT(ic)) == AOP_DPTR2) \
+    { \
+        /* werror(E_INTERNAL_ERROR,__FILE__,__LINE__, */ \
+        fprintf(stderr,                                  \
+               "Ack: three operands in far space! (%s:%d %s:%d)\n", __FILE__, __LINE__, ic->filename, ic->lineno);   \
+    }
+#endif
+
+// Macro to aopOp all three operands of an ic. If this cannot be done, 
+// the IC_LEFT and IC_RIGHT operands will be aopOp'd, and the rc parameter
+// will be set TRUE. The caller must then handle the case specially, noting
+// that the IC_RESULT operand is not aopOp'd.
+#define AOP_OP_3_NOFATAL(ic, rc) \
+    aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
+    aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR) || \
+                                  (OP_SYMBOL(IC_RESULT(ic))->ruonly)); \
+    if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \
+        (isOperandInFarSpace(IC_RESULT(ic)) || OP_SYMBOL(IC_RESULT(ic))->ruonly )) \
+    { \
+       /* No can do; DPTR & DPTR2 in use, and we need another. */ \
+       rc = TRUE; \
+    }  \
+    else \
+    { \
+       aopOp (IC_RESULT(ic),ic,TRUE, (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) || \
+                                     (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
+       rc = FALSE; \
+       if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \
+           AOP_TYPE(IC_RESULT(ic)) == AOP_DPTR2) \
+       { \
+            /* werror(E_INTERNAL_ERROR,__FILE__,__LINE__, */ \
+            fprintf(stderr,                                  \
+                    "Ack: got unexpected DP2! (%s:%d %s:%d)\n", __FILE__, __LINE__, ic->filename, ic->lineno);   \
+       } \
+    }
+
+// aopOp the left & right operands of an ic.
+#define AOP_OP_2(ic) \
+    aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
+    aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR));
+
+// convienience macro.
+#define AOP_SET_LOCALS(ic) \
+    left = IC_LEFT(ic); \
+    right = IC_RIGHT(ic); \
+    result = IC_RESULT(ic);
+
+
+// Given an integer value of pushedSize bytes on the stack,
+// adjust it to be resultSize bytes, either by discarding
+// the most significant bytes or by zero-padding.
+//
+// On exit from this macro, pushedSize will have been adjusted to
+// equal resultSize, and ACC may be trashed.
+#define ADJUST_PUSHED_RESULT(pushedSize, resultSize)           \
+      /* If the pushed data is bigger than the result,         \
+       * simply discard unused bytes. Icky, but works.         \
+       */                                                      \
+      while (pushedSize > resultSize)                          \
+      {                                                                \
+         D (emitcode (";", "discarding unused result byte."););\
+         emitcode ("pop", "acc");                              \
+         pushedSize--;                                         \
+      }                                                                \
+      if (pushedSize < resultSize)                             \
+      {                                                                \
+         emitcode ("clr", "a");                                \
+         /* Conversly, we haven't pushed enough here.          \
+          * just zero-pad, and all is well.                    \
+          */                                                   \
+         while (pushedSize < resultSize)                       \
+         {                                                     \
+             emitcode("push", "acc");                          \
+             pushedSize++;                                     \
+         }                                                     \
+      }                                                                \
+      assert(pushedSize == resultSize);
+
+/*-----------------------------------------------------------------*/
+/* genPlus - generates code for addition                           */
+/*-----------------------------------------------------------------*/
+static void
+genPlus (iCode * ic)
+{
+  int size, offset = 0;
+  bool pushResult = FALSE;
+  int rSize;
+
+  D (emitcode (";", "genPlus "););
+
+  /* special cases :- */
+  if (isOperandEqual(IC_LEFT(ic),IC_RESULT(ic)) &&
+      isOperandLiteral(IC_RIGHT(ic)) && OP_SYMBOL(IC_RESULT(ic))->ruonly) {
+      aopOp (IC_RIGHT (ic), ic, TRUE, FALSE);
+      size = floatFromVal (AOP (IC_RIGHT(ic))->aopu.aop_lit);
+      if (size <= 9) {
+         while (size--) emitcode ("inc","dptr");
+      } else {
+         emitcode ("mov","a,dpl");
+         emitcode ("add","a,#0x%02x",size & 0xff);
+         emitcode ("mov","dpl,a");
+         emitcode ("mov","a,dph");
+         emitcode ("addc","a,#0x%02x",(size >> 8) & 0xff);
+         emitcode ("mov","dph,a");
+         emitcode ("mov","a,dpx");
+         emitcode ("addc","a,#0x%02x",(size >> 16) & 0xff);
+         emitcode ("mov","dpx,a");
+      }
+      freeAsmop (IC_RIGHT (ic), NULL, ic, FALSE);
+      return ;
+  }
+  if ( IS_SYMOP(IC_LEFT(ic)) && 
+       OP_SYMBOL(IC_LEFT(ic))->remat &&
+       isOperandInFarSpace(IC_RIGHT(ic))) {
+      operand *op = IC_RIGHT(ic);
+      IC_RIGHT(ic) = IC_LEFT(ic);
+      IC_LEFT(ic) = op;
+  }
+               
+  AOP_OP_3_NOFATAL (ic, pushResult);
+  if (pushResult)
+    {
+      D (emitcode (";", "genPlus: must push result: 3 ops in far space"););
+    }
+
+  if (!pushResult)
+    {
+      /* if literal, literal on the right or
+         if left requires ACC or right is already
+         in ACC */
+      if ((AOP_TYPE (IC_LEFT (ic)) == AOP_LIT)
+       || ((AOP_NEEDSACC (IC_LEFT (ic))) && !(AOP_NEEDSACC (IC_RIGHT (ic))))
+         || AOP_TYPE (IC_RIGHT (ic)) == AOP_ACC)
+       {
+         operand *t = IC_RIGHT (ic);
+         IC_RIGHT (ic) = IC_LEFT (ic);
+         IC_LEFT (ic) = t;
+         emitcode (";", "Swapped plus args.");
+       }
+
+      /* if both left & right are in bit
+         space */
+      if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY &&
+         AOP_TYPE (IC_RIGHT (ic)) == AOP_CRY)
+       {
+         genPlusBits (ic);
+         goto release;
+       }
+
+      /* if left in bit space & right literal */
+      if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY &&
+         AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT)
+       {
+         emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
+         /* if result in bit space */
+         if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
+           {
+             if ((unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) != 0L)
+               emitcode ("cpl", "c");
+             outBitC (IC_RESULT (ic));
+           }
+         else
+           {
+             size = getDataSize (IC_RESULT (ic));
+             _startLazyDPSEvaluation ();
+             while (size--)
+               {
+                 MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, TRUE));
+                 emitcode ("addc", "a,#00");
+                 aopPut (AOP (IC_RESULT (ic)), "a", offset++);
+               }
+             _endLazyDPSEvaluation ();
+           }
+         goto release;
+       }
+
+      /* if I can do an increment instead
+         of add then GOOD for ME */
+      if (genPlusIncr (ic) == TRUE)
+       {
+         emitcode (";", "did genPlusIncr");
+         goto release;
+       }
+
+    }
+  size = getDataSize (pushResult ? IC_LEFT (ic) : IC_RESULT (ic));
+
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC && !AOP_NEEDSACC(IC_RIGHT(ic)))
+       {
+         MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, TRUE));
+         if (offset == 0)
+           emitcode ("add", "a,%s",
+                aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, FALSE));
+         else
+           emitcode ("addc", "a,%s",
+                aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, FALSE));
+       }
+      else
+       {
+         if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC && (offset == 0))
+         {
+             /* right is going to use ACC or we would have taken the
+              * above branch.
+              */
+             assert(AOP_NEEDSACC(IC_RIGHT(ic)));
+       TR_AP("#3");
+             D(emitcode(";", "+ AOP_ACC special case."););
+             emitcode("xch", "a, %s", DP2_RESULT_REG);
+         }
+         MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, TRUE));
+         if (offset == 0)
+         {
+           if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC)
+           {
+         TR_AP("#4");
+               emitcode("add", "a, %s", DP2_RESULT_REG); 
+           }
+           else
+           {
+               emitcode ("add", "a,%s",
+                       aopGet (AOP(IC_LEFT(ic)), offset, FALSE, FALSE, FALSE));
+           }
+          }
+         else
+         {
+           emitcode ("addc", "a,%s",
+                 aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, FALSE));
+         }
+       }
+      if (!pushResult)
+       {
+         aopPut (AOP (IC_RESULT (ic)), "a", offset);
+       }
+      else
+       {
+         emitcode ("push", "acc");
+       }
+      offset++;
+    }
+  _endLazyDPSEvaluation ();
+
+  if (pushResult)
+    {
+      aopOp (IC_RESULT (ic), ic, TRUE, FALSE);
+
+      size = getDataSize (IC_LEFT (ic));
+      rSize = getDataSize (IC_RESULT (ic));
+
+      ADJUST_PUSHED_RESULT(size, rSize);
+
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         emitcode ("pop", "acc");
+         aopPut (AOP (IC_RESULT (ic)), "a", size);
+       }
+      _endLazyDPSEvaluation ();
+    }
+
+  adjustArithmeticResult (ic);
+
+release:
+  freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (IC_RIGHT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genMinusDec :- does subtraction with deccrement if possible     */
+/*-----------------------------------------------------------------*/
+static bool
+genMinusDec (iCode * ic)
+{
+  unsigned int icount;
+  unsigned int size = getDataSize (IC_RESULT (ic));
+
+  /* will try to generate an increment */
+  /* if the right side is not a literal
+     we cannot */
+  if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
+    return FALSE;
+
+  /* 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)) > 4)
+    return FALSE;
+
+  /* if decrement 16 bits in register */
+  if (AOP_TYPE (IC_LEFT (ic)) == AOP_REG &&
+      AOP_TYPE (IC_RESULT (ic)) == AOP_REG &&
+      sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
+      (size > 1) &&
+      (icount == 1))
+    {
+      symbol *tlbl;
+      int emitTlbl;
+      int labelRange;
+
+      /* If the next instruction is a goto and the goto target
+         * is <= 5 instructions previous to this, we can generate
+         * jumps straight to that target.
+       */
+      if (ic->next && ic->next->op == GOTO
+         && (labelRange = findLabelBackwards (ic, IC_LABEL (ic->next)->key)) != 0
+         && labelRange <= 5)
+       {
+         emitcode (";", "tail decrement optimized (range %d)", labelRange);
+         tlbl = IC_LABEL (ic->next);
+         emitTlbl = 0;
+       }
+      else
+       {
+         tlbl = newiTempLabel (NULL);
+         emitTlbl = 1;
+       }
+
+      emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE));
+      if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+         AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
+         IS_AOP_PREG (IC_RESULT (ic)))
+       emitcode ("cjne", "%s,#0xff,%05d$"
+                 ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
+                 ,tlbl->key + 100);
+      else
+       {
+         emitcode ("mov", "a,#0xff");
+         emitcode ("cjne", "a,%s,%05d$"
+                   ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
+                   ,tlbl->key + 100);
+       }
+      emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE));
+      if (size > 2)
+       {
+         if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+             AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
+             IS_AOP_PREG (IC_RESULT (ic)))
+           emitcode ("cjne", "%s,#0xff,%05d$"
+                 ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
+                     ,tlbl->key + 100);
+         else
+           {
+             emitcode ("cjne", "a,%s,%05d$"
+                 ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
+                       ,tlbl->key + 100);
+           }
+         emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE));
+       }
+      if (size > 3)
+       {
+         if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+             AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
+             IS_AOP_PREG (IC_RESULT (ic)))
+           emitcode ("cjne", "%s,#0xff,%05d$"
+                 ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
+                     ,tlbl->key + 100);
+         else
+           {
+             emitcode ("cjne", "a,%s,%05d$"
+                 ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
+                       ,tlbl->key + 100);
+           }
+         emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, FALSE, FALSE));
+       }
+      if (emitTlbl)
+       {
+         emitcode ("", "%05d$:", tlbl->key + 100);
+       }
+      return TRUE;
+    }
+
+  /* if the sizes are greater than 1 then we cannot */
+  if (AOP_SIZE (IC_RESULT (ic)) > 1 ||
+      AOP_SIZE (IC_LEFT (ic)) > 1)
+    return FALSE;
+
+  /* we can if the aops of the left & result match or
+     if they are in registers and the registers are the
+     same */
+  if (
+       AOP_TYPE (IC_LEFT (ic)) == AOP_REG &&
+       AOP_TYPE (IC_RESULT (ic)) == AOP_REG &&
+       sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
+    {
+
+      _startLazyDPSEvaluation ();
+      while (icount--)
+       {
+         emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, FALSE));
+       }
+      _endLazyDPSEvaluation ();
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+/*-----------------------------------------------------------------*/
+/* addSign - complete with sign                                    */
+/*-----------------------------------------------------------------*/
+static void
+addSign (operand * result, int offset, int sign)
+{
+  int size = (getDataSize (result) - offset);
+  if (size > 0)
+    {
+      _startLazyDPSEvaluation();
+      if (sign)
+       {
+         emitcode ("rlc", "a");
+         emitcode ("subb", "a,acc");
+         while (size--)
+         {
+           aopPut (AOP (result), "a", offset++);
+         }
+       }
+      else
+      {
+       while (size--)
+       {
+         aopPut (AOP (result), zero, offset++);
+       }
+      }
+      _endLazyDPSEvaluation();
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* genMinusBits - generates code for subtraction  of two bits      */
+/*-----------------------------------------------------------------*/
+static void
+genMinusBits (iCode * ic)
+{
+  symbol *lbl = newiTempLabel (NULL);
+
+  D (emitcode (";", "genMinusBits "););
+
+  if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
+    {
+      emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
+      emitcode ("jnb", "%s,%05d$", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100));
+      emitcode ("cpl", "c");
+      emitcode ("", "%05d$:", (lbl->key + 100));
+      outBitC (IC_RESULT (ic));
+    }
+  else
+    {
+      emitcode ("mov", "c,%s", AOP (IC_RIGHT (ic))->aopu.aop_dir);
+      emitcode ("subb", "a,acc");
+      emitcode ("jnb", "%s,%05d$", AOP (IC_LEFT (ic))->aopu.aop_dir, (lbl->key + 100));
+      emitcode ("inc", "a");
+      emitcode ("", "%05d$:", (lbl->key + 100));
+      aopPut (AOP (IC_RESULT (ic)), "a", 0);
+      addSign (IC_RESULT (ic), MSB16, SPEC_USIGN (getSpec (operandType (IC_RESULT (ic)))));
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* genMinus - generates code for subtraction                       */
+/*-----------------------------------------------------------------*/
+static void
+genMinus (iCode * ic)
+{
+  int size, offset = 0;
+  int rSize;
+  unsigned long lit = 0L;
+  bool pushResult = FALSE;
+
+  D (emitcode (";", "genMinus "););
+
+  aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
+  aopOp (IC_RIGHT (ic), ic, FALSE, TRUE);
+  if ((AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR) &&
+      (AOP_TYPE (IC_RIGHT (ic)) == AOP_DPTR2))
+    {
+      pushResult = TRUE;
+    }
+  else
+    {
+      aopOp (IC_RESULT (ic), ic, TRUE, AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR);
+
+      /* special cases :- */
+      /* if both left & right are in bit space */
+      if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY &&
+         AOP_TYPE (IC_RIGHT (ic)) == AOP_CRY)
+       {
+         genMinusBits (ic);
+         goto release;
+       }
+
+      /* if I can do an decrement instead
+         of subtract then GOOD for ME */
+      if (genMinusDec (ic) == TRUE)
+       goto release;
+
+    }
+
+  size = getDataSize (pushResult ? IC_LEFT (ic) : IC_RESULT (ic));
+
+  if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
+    {
+      CLRC;
+    }
+  else
+    {
+      lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+      lit = -(long) lit;
+    }
+
+
+  /* if literal, add a,#-lit, else normal subb */
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, TRUE));
+      if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
+       emitcode ("subb", "a,%s",
+                 aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, FALSE));
+      else
+       {
+         /* first add without previous c */
+         if (!offset) {
+           if (!size && lit==-1) {
+             emitcode ("dec", "a");
+           } else {
+             emitcode ("add", "a,#0x%02x",
+                       (unsigned int) (lit & 0x0FFL));
+           }
+         } else {
+           emitcode ("addc", "a,#0x%02x",
+                     (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
+         }
+       }
+
+      if (pushResult)
+       {
+         emitcode ("push", "acc");
+       }
+      else
+       {
+         aopPut (AOP (IC_RESULT (ic)), "a", offset);
+       }
+      offset++;
+    }
+  _endLazyDPSEvaluation ();
+
+  if (pushResult)
+    {
+      aopOp (IC_RESULT (ic), ic, TRUE, FALSE);
+
+      size = getDataSize (IC_LEFT (ic));
+      rSize = getDataSize (IC_RESULT (ic));
+
+      ADJUST_PUSHED_RESULT(size, rSize);
+
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         emitcode ("pop", "acc");
+         aopPut (AOP (IC_RESULT (ic)), "a", size);
+       }
+      _endLazyDPSEvaluation ();
+    }
+
+  adjustArithmeticResult (ic);
+
+release:
+  freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (IC_RIGHT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genMultbits :- multiplication of bits                           */
+/*-----------------------------------------------------------------*/
+static void
+genMultbits (operand * left,
+            operand * right,
+            operand * result,
+            iCode   * ic)
+{
+  emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+  emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
+  aopOp(result, ic, TRUE, FALSE);
+  outBitC (result);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genMultOneByte : 8*8=8/16 bit multiplication                    */
+/*-----------------------------------------------------------------*/
+static void
+genMultOneByte (operand * left,
+               operand * right,
+               operand * result,
+               iCode   * ic)
+{
+  sym_link *opetype = operandType (result);
+  symbol *lbl;
+
+
+  /* (if two literals: the value is computed before) */
+  /* if one literal, literal on the right */
+  if (AOP_TYPE (left) == AOP_LIT)
+    {
+      operand *t = right;
+      right = left;
+      left = t;
+      emitcode (";", "swapped left and right");
+    }
+
+  if (SPEC_USIGN(opetype)
+      // ignore the sign of left and right, what else can we do?
+      || (SPEC_USIGN(operandType(left)) && 
+         SPEC_USIGN(operandType(right)))) {
+    // just an unsigned 8*8=8/16 multiply
+    //emitcode (";","unsigned");
+    emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE));
+    MOVA (aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
+    emitcode ("mul", "ab");
+   
+    _G.accInUse++;
+    aopOp(result, ic, TRUE, FALSE);
+      
+      if (AOP_SIZE(result)<1 || AOP_SIZE(result)>2) 
+      {
+         // this should never happen
+         fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", 
+                  AOP_SIZE(result), __FILE__, lineno);
+         exit (1);
+      }      
+      
+    aopPut (AOP (result), "a", 0);
+    _G.accInUse--;
+    if (AOP_SIZE(result)==2) 
+    {
+      aopPut (AOP (result), "b", 1);
+    }
+    return;
+  }
+
+  // we have to do a signed multiply
+
+  emitcode (";", "signed");
+  emitcode ("clr", "F0"); // reset sign flag
+  MOVA (aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
+
+  lbl=newiTempLabel(NULL);
+  emitcode ("jnb", "acc.7,%05d$",  lbl->key+100);
+  // left side is negative, 8-bit two's complement, this fails for -128
+  emitcode ("setb", "F0"); // set sign flag
+  emitcode ("cpl", "a");
+  emitcode ("inc", "a");
+
+  emitcode ("", "%05d$:", lbl->key+100);
+
+  /* if literal */
+  if (AOP_TYPE(right)==AOP_LIT) {
+    signed char val=floatFromVal (AOP (right)->aopu.aop_lit);
+    /* AND literal negative */
+    if ((int) val < 0) {
+      emitcode ("cpl", "F0"); // complement sign flag
+      emitcode ("mov", "b,#0x%02x", -val);
+    } else {
+      emitcode ("mov", "b,#0x%02x", val);
+    }
+  } else {
+    lbl=newiTempLabel(NULL);
+    emitcode ("mov", "b,a");
+    emitcode ("mov", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE));
+    emitcode ("jnb", "acc.7,%05d$", lbl->key+100);
+    // right side is negative, 8-bit two's complement
+    emitcode ("cpl", "F0"); // complement sign flag
+    emitcode ("cpl", "a");
+    emitcode ("inc", "a");
+    emitcode ("", "%05d$:", lbl->key+100);
+  }
+  emitcode ("mul", "ab");
+    
+  _G.accInUse++;
+  aopOp(result, ic, TRUE, FALSE);
+    
+  if (AOP_SIZE(result)<1 || AOP_SIZE(result)>2) 
+  {
+    // this should never happen
+      fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", 
+              AOP_SIZE(result), __FILE__, lineno);
+      exit (1);
+  }    
+    
+  lbl=newiTempLabel(NULL);
+  emitcode ("jnb", "F0,%05d$", lbl->key+100);
+  // only ONE op was negative, we have to do a 8/16-bit two's complement
+  emitcode ("cpl", "a"); // lsb
+  if (AOP_SIZE(result)==1) {
+    emitcode ("inc", "a");
+  } else {
+    emitcode ("add", "a,#1");
+    emitcode ("xch", "a,b");
+    emitcode ("cpl", "a"); // msb
+    emitcode ("addc", "a,#0");
+    emitcode ("xch", "a,b");
+  }
+
+  emitcode ("", "%05d$:", lbl->key+100);
+  aopPut (AOP (result), "a", 0);
+  _G.accInUse--;
+  if (AOP_SIZE(result)==2) {
+    aopPut (AOP (result), "b", 1);
+  }
+}
+
+/*-----------------------------------------------------------------*/
+/* genMultTwoByte - use the DS390 MAC unit to do 16*16 multiply    */
+/*-----------------------------------------------------------------*/
+static void genMultTwoByte (operand *left, operand *right, 
+                           operand *result, iCode *ic)
+{
+       sym_link *retype = getSpec(operandType(right));
+       sym_link *letype = getSpec(operandType(left));
+       int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype);
+       symbol *lbl;
+
+       if (AOP_TYPE (left) == AOP_LIT) {
+               operand *t = right;
+               right = left;
+               left = t;
+       }
+       /* save EA bit in F1 */
+       lbl = newiTempLabel(NULL);
+       emitcode ("setb","F1");
+       emitcode ("jbc","EA,%05d$",lbl->key+100);
+       emitcode ("clr","F1");
+       emitcode("","%05d$:",lbl->key+100);
+
+       /* load up MB with right */
+       if (!umult) {
+               emitcode("clr","F0");
+               if (AOP_TYPE(right) == AOP_LIT) {
+                       int val=floatFromVal (AOP (right)->aopu.aop_lit);
+                       if (val < 0) {
+                               emitcode("setb","F0");
+                               val = -val;
+                       }
+                       emitcode ("mov","mb,#0x%02x",val & 0xff);
+                       emitcode ("mov","mb,#0x%02x",(val >> 8) & 0xff);                    
+               } else {
+                       lbl = newiTempLabel(NULL);
+                       emitcode ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+                       emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+                       emitcode ("jnb","acc.7,%05d$",lbl->key+100);            
+                       emitcode ("xch", "a,b");
+                       emitcode ("cpl","a");
+                       emitcode ("add", "a,#1");
+                       emitcode ("xch", "a,b");
+                       emitcode ("cpl", "a"); // msb
+                       emitcode ("addc", "a,#0");
+                       emitcode ("setb","F0");
+                       emitcode ("","%05d$:",lbl->key+100);
+                       emitcode ("mov","mb,b");
+                       emitcode ("mov","mb,a");
+               }
+       } else {
+               emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+       }
+       /* load up MA with left */
+       if (!umult) {
+               lbl = newiTempLabel(NULL);
+               emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+               emitcode ("jnb","acc.7,%05d$",lbl->key+100);
+               emitcode ("xch", "a,b");
+               emitcode ("cpl","a");
+               emitcode ("add", "a,#1");
+               emitcode ("xch", "a,b");
+               emitcode ("cpl", "a"); // msb
+               emitcode ("addc","a,#0");
+               emitcode ("jbc","F0,%05d$",lbl->key+100);
+               emitcode ("setb","F0");
+               emitcode ("","%05d$:",lbl->key+100);
+               emitcode ("mov","ma,b");
+               emitcode ("mov","ma,a");
+       } else {
+               emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+       }
+       /* wait for multiplication to finish */
+       lbl = newiTempLabel(NULL);
+       emitcode("","%05d$:", lbl->key+100);
+       emitcode("mov","a,mcnt1");
+       emitcode("anl","a,#0x80");
+       emitcode("jnz","%05d$",lbl->key+100);
+       
+       freeAsmop (left, NULL, ic, TRUE);
+       freeAsmop (right, NULL, ic,TRUE);
+       aopOp(result, ic, TRUE, FALSE);
+
+       /* if unsigned then simple */   
+       if (umult) {
+               emitcode ("mov","a,ma");
+               if (AOP_SIZE(result) >= 4) aopPut(AOP(result),"a",3);
+               emitcode ("mov","a,ma");
+               if (AOP_SIZE(result) >= 3) aopPut(AOP(result),"a",2);
+               aopPut(AOP(result),"ma",1);
+               aopPut(AOP(result),"ma",0);
+       } else {
+               emitcode("push","ma");
+               emitcode("push","ma");
+               emitcode("push","ma");
+               MOVA("ma");
+               /* negate result if needed */
+               lbl = newiTempLabel(NULL);      
+               emitcode("jnb","F0,%05d$",lbl->key+100);
+               emitcode("cpl","a");
+               emitcode("add","a,#1");
+               emitcode("","%05d$:", lbl->key+100);
+               if (AOP_TYPE(result) == AOP_ACC)
+               {
+                   D(emitcode(";", "ACC special case."););
+                   /* We know result is the only live aop, and 
+                    * it's obviously not a DPTR2, so AP is available.
+                    */
+                   emitcode("mov", "%s,acc", DP2_RESULT_REG);
+               }
+               else
+               {
+                   aopPut(AOP(result),"a",0);
+               }
+           
+               emitcode("pop","acc");
+               lbl = newiTempLabel(NULL);      
+               emitcode("jnb","F0,%05d$",lbl->key+100);
+               emitcode("cpl","a");
+               emitcode("addc","a,#0");
+               emitcode("","%05d$:", lbl->key+100);
+               aopPut(AOP(result),"a",1);
+               emitcode("pop","acc");
+               if (AOP_SIZE(result) >= 3) {
+                       lbl = newiTempLabel(NULL);      
+                       emitcode("jnb","F0,%05d$",lbl->key+100);
+                       emitcode("cpl","a");
+                       emitcode("addc","a,#0");                        
+                       emitcode("","%05d$:", lbl->key+100);
+                       aopPut(AOP(result),"a",2);
+               }
+               emitcode("pop","acc");
+               if (AOP_SIZE(result) >= 4) {
+                       lbl = newiTempLabel(NULL);      
+                       emitcode("jnb","F0,%05d$",lbl->key+100);
+                       emitcode("cpl","a");
+                       emitcode("addc","a,#0");                        
+                       emitcode("","%05d$:", lbl->key+100);
+                       aopPut(AOP(result),"a",3);
+               }
+               if (AOP_TYPE(result) == AOP_ACC)
+               {
+                   /* We stashed the result away above. */
+                   emitcode("mov", "acc,%s", DP2_RESULT_REG);
+               }           
+               
+       }
+       freeAsmop (result, NULL, ic, TRUE);
+
+       /* restore EA bit in F1 */
+       lbl = newiTempLabel(NULL);
+       emitcode ("jnb","F1,%05d$",lbl->key+100);
+       emitcode ("setb","EA");
+       emitcode("","%05d$:",lbl->key+100);
+       return ;
+}
+
+/*-----------------------------------------------------------------*/
+/* genMult - generates code for multiplication                     */
+/*-----------------------------------------------------------------*/
+static void
+genMult (iCode * ic)
+{
+  operand *left = IC_LEFT (ic);
+  operand *right = IC_RIGHT (ic);
+  operand *result = IC_RESULT (ic);
+
+  D (emitcode (";", "genMult "););
+
+  /* assign the amsops */
+  AOP_OP_2 (ic);
+
+  /* special cases first */
+  /* both are bits */
+  if (AOP_TYPE (left) == AOP_CRY &&
+      AOP_TYPE (right) == AOP_CRY)
+    {
+      genMultbits (left, right, result, ic);
+      goto release;
+    }
+
+  /* if both are of size == 1 */
+  if (AOP_SIZE (left) == 1 &&
+      AOP_SIZE (right) == 1)
+    {
+      genMultOneByte (left, right, result, ic);
+      goto release;
+    }
+
+  if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) {
+         /* use the ds390 ARITHMETIC accel UNIT */
+         genMultTwoByte (left, right, result, ic);
+         return ;
+  }
+  /* should have been converted to function call */
+  assert (0);
+
+release:
+  freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genDivbits :- division of bits                                  */
+/*-----------------------------------------------------------------*/
+static void
+genDivbits (operand * left,
+           operand * right,
+           operand * result,
+           iCode   * ic)
+{
+
+  char *l;
+
+  /* the result must be bit */
+  LOAD_AB_FOR_DIV (left, right, l);
+  emitcode ("div", "ab");
+  emitcode ("rrc", "a");
+  aopOp(result, ic, TRUE, FALSE);
+    
+  aopPut (AOP (result), "c", 0);
+}
+
+/*-----------------------------------------------------------------*/
+/* genDivOneByte : 8 bit division                                  */
+/*-----------------------------------------------------------------*/
+static void
+genDivOneByte (operand * left,
+              operand * right,
+              operand * result,
+              iCode   * ic)
+{
+  sym_link *opetype = operandType (result);
+  char *l;
+  symbol *lbl;
+  int size, offset;
+
+  offset = 1;
+  /* signed or unsigned */
+  if (SPEC_USIGN (opetype))
+    {
+       /* unsigned is easy */
+       LOAD_AB_FOR_DIV (left, right, l);
+       emitcode ("div", "ab");
+
+       _G.accInUse++;
+       aopOp(result, ic, TRUE, FALSE);
+       aopPut (AOP (result), "a", 0);
+       _G.accInUse--;
+
+       size = AOP_SIZE (result) - 1;
+       
+       while (size--)
+       {
+           aopPut (AOP (result), zero, offset++);
+       }
+      return;
+    }
+
+  /* signed is a little bit more difficult */
+
+  /* save the signs of the operands */
+  l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
+  MOVA (l);
+  emitcode ("xrl", "a,%s", aopGet (AOP (right), 0, FALSE, TRUE, FALSE));
+  emitcode ("push", "acc");    /* save it on the stack */
+
+  /* now sign adjust for both left & right */
+  l = aopGet (AOP (right), 0, FALSE, FALSE, TRUE);
+  MOVA (l);
+  lbl = newiTempLabel (NULL);
+  emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
+  emitcode ("cpl", "a");
+  emitcode ("inc", "a");
+  emitcode ("", "%05d$:", (lbl->key + 100));
+  emitcode ("mov", "b,a");
+
+  /* sign adjust left side */
+  l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
+  MOVA (l);
+
+  lbl = newiTempLabel (NULL);
+  emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
+  emitcode ("cpl", "a");
+  emitcode ("inc", "a");
+  emitcode ("", "%05d$:", (lbl->key + 100));
+
+  /* now the division */
+  emitcode ("nop", "; workaround for DS80C390 div bug.");
+  emitcode ("div", "ab");
+  /* we are interested in the lower order
+     only */
+  emitcode ("mov", "b,a");
+  lbl = newiTempLabel (NULL);
+  emitcode ("pop", "acc");
+  /* if there was an over flow we don't
+     adjust the sign of the result */
+  emitcode ("jb", "ov,%05d$", (lbl->key + 100));
+  emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
+  CLRC;
+  emitcode ("clr", "a");
+  emitcode ("subb", "a,b");
+  emitcode ("mov", "b,a");
+  emitcode ("", "%05d$:", (lbl->key + 100));
+
+  /* now we are done */
+    _G.accInUse++;
+    aopOp(result, ic, TRUE, FALSE);
+    
+    aopPut (AOP (result), "b", 0);
+    
+    size = AOP_SIZE (result) - 1;
+    
+    if (size > 0)
+    {
+      emitcode ("mov", "c,b.7");
+      emitcode ("subb", "a,acc");
+    }
+    while (size--)
+    {
+       aopPut (AOP (result), "a", offset++);
+    }
+    _G.accInUse--;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genDivTwoByte - use the DS390 MAC unit to do 16/16 divide       */
+/*-----------------------------------------------------------------*/
+static void genDivTwoByte (operand *left, operand *right, 
+                           operand *result, iCode *ic)
+{
+       sym_link *retype = getSpec(operandType(right));
+       sym_link *letype = getSpec(operandType(left));
+       int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype);
+       symbol *lbl;
+
+       /* save EA bit in F1 */
+       lbl = newiTempLabel(NULL);
+       emitcode ("setb","F1");
+       emitcode ("jbc","EA,%05d$",lbl->key+100);
+       emitcode ("clr","F1");
+       emitcode("","%05d$:",lbl->key+100);
+
+       /* load up MA with left */
+       if (!umult) {
+               emitcode("clr","F0");
+               lbl = newiTempLabel(NULL);
+               emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+               emitcode ("jnb","acc.7,%05d$",lbl->key+100);
+               emitcode ("xch", "a,b");
+               emitcode ("cpl","a");
+               emitcode ("add", "a,#1");
+               emitcode ("xch", "a,b");
+               emitcode ("cpl", "a"); // msb
+               emitcode ("addc","a,#0");
+               emitcode ("setb","F0");
+               emitcode ("","%05d$:",lbl->key+100);
+               emitcode ("mov","ma,b");
+               emitcode ("mov","ma,a");
+       } else {
+               emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+       }
+
+       /* load up MB with right */
+       if (!umult) {
+               if (AOP_TYPE(right) == AOP_LIT) {
+                       int val=floatFromVal (AOP (right)->aopu.aop_lit);
+                       if (val < 0) {
+                               lbl = newiTempLabel(NULL);
+                               emitcode ("jbc","F0,%05d$",lbl->key+100);
+                               emitcode("setb","F0");
+                               emitcode ("","%05d$:",lbl->key+100);
+                               val = -val;
+                       } 
+                       emitcode ("mov","mb,#0x%02x",val & 0xff);                   
+                       emitcode ("mov","mb,#0x%02x",(val >> 8) & 0xff);
+               } else {
+                       lbl = newiTempLabel(NULL);
+                       emitcode ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+                       emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+                       emitcode ("jnb","acc.7,%05d$",lbl->key+100);            
+                       emitcode ("xch", "a,b");
+                       emitcode ("cpl","a");
+                       emitcode ("add", "a,#1");
+                       emitcode ("xch", "a,b");
+                       emitcode ("cpl", "a"); // msb
+                       emitcode ("addc", "a,#0");
+                       emitcode ("jbc","F0,%05d$",lbl->key+100);
+                       emitcode ("setb","F0");
+                       emitcode ("","%05d$:",lbl->key+100);
+                       emitcode ("mov","mb,b");
+                       emitcode ("mov","mb,a");
+               }
+       } else {
+               emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+       }
+
+       /* wait for multiplication to finish */
+       lbl = newiTempLabel(NULL);
+       emitcode("","%05d$:", lbl->key+100);
+       emitcode("mov","a,mcnt1");
+       emitcode("anl","a,#0x80");
+       emitcode("jnz","%05d$",lbl->key+100);
+       
+       freeAsmop (left, NULL, ic, TRUE);
+       freeAsmop (right, NULL, ic,TRUE);
+       aopOp(result, ic, TRUE, FALSE);
+
+       /* if unsigned then simple */   
+       if (umult) {
+               aopPut(AOP(result),"ma",1);
+               aopPut(AOP(result),"ma",0);
+       } else {
+               emitcode("push","ma");
+               MOVA("ma");
+               /* negate result if needed */
+               lbl = newiTempLabel(NULL);      
+               emitcode("jnb","F0,%05d$",lbl->key+100);
+               emitcode("cpl","a");
+               emitcode("add","a,#1");
+               emitcode("","%05d$:", lbl->key+100);
+               aopPut(AOP(result),"a",0);
+               emitcode("pop","acc");
+               lbl = newiTempLabel(NULL);      
+               emitcode("jnb","F0,%05d$",lbl->key+100);
+               emitcode("cpl","a");
+               emitcode("addc","a,#0");
+               emitcode("","%05d$:", lbl->key+100);
+               aopPut(AOP(result),"a",1);
+       }
+       freeAsmop (result, NULL, ic, TRUE);
+       /* restore EA bit in F1 */
+       lbl = newiTempLabel(NULL);
+       emitcode ("jnb","F1,%05d$",lbl->key+100);
+       emitcode ("setb","EA");
+       emitcode("","%05d$:",lbl->key+100);
+       return ;
+}
+
+/*-----------------------------------------------------------------*/
+/* genDiv - generates code for division                            */
+/*-----------------------------------------------------------------*/
+static void
+genDiv (iCode * ic)
+{
+  operand *left = IC_LEFT (ic);
+  operand *right = IC_RIGHT (ic);
+  operand *result = IC_RESULT (ic);
+
+  D (emitcode (";", "genDiv "););
+
+  /* assign the amsops */
+  AOP_OP_2 (ic);
+
+  /* special cases first */
+  /* both are bits */
+  if (AOP_TYPE (left) == AOP_CRY &&
+      AOP_TYPE (right) == AOP_CRY)
+    {
+      genDivbits (left, right, result, ic);
+      goto release;
+    }
+
+  /* if both are of size == 1 */
+  if (AOP_SIZE (left) == 1 &&
+      AOP_SIZE (right) == 1)
+    {
+      genDivOneByte (left, right, result, ic);
+      goto release;
+    }
+
+  if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) {
+         /* use the ds390 ARITHMETIC accel UNIT */
+         genDivTwoByte (left, right, result, ic);
+         return ;
+  }
+  /* should have been converted to function call */
+  assert (0);
+release:
+  freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genModbits :- modulus of bits                                   */
+/*-----------------------------------------------------------------*/
+static void
+genModbits (operand * left,
+           operand * right,
+           operand * result,
+           iCode   * ic)
+{
+
+  char *l;
+
+  /* the result must be bit */
+  LOAD_AB_FOR_DIV (left, right, l);
+  emitcode ("div", "ab");
+  emitcode ("mov", "a,b");
+  emitcode ("rrc", "a");
+  aopOp(result, ic, TRUE, FALSE);
+  aopPut (AOP (result), "c", 0);
+}
+
+/*-----------------------------------------------------------------*/
+/* genModOneByte : 8 bit modulus                                   */
+/*-----------------------------------------------------------------*/
+static void
+genModOneByte (operand * left,
+              operand * right,
+              operand * result,
+              iCode   * ic)
+{
+  sym_link *opetype = operandType (result);
+  char *l;
+  symbol *lbl;
+
+  /* signed or unsigned */
+  if (SPEC_USIGN (opetype))
+    {
+      /* unsigned is easy */
+      LOAD_AB_FOR_DIV (left, right, l);
+      emitcode ("div", "ab");
+      aopOp(result, ic, TRUE, FALSE);  
+      aopPut (AOP (result), "b", 0);
+      return;
+    }
+
+  /* signed is a little bit more difficult */
+
+  /* save the signs of the operands */
+  l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
+  MOVA (l);
+
+  emitcode ("xrl", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE, FALSE));
+  emitcode ("push", "acc");    /* save it on the stack */
+
+  /* now sign adjust for both left & right */
+  l = aopGet (AOP (right), 0, FALSE, FALSE, TRUE);
+  MOVA (l);
+
+  lbl = newiTempLabel (NULL);
+  emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
+  emitcode ("cpl", "a");
+  emitcode ("inc", "a");
+  emitcode ("", "%05d$:", (lbl->key + 100));
+  emitcode ("mov", "b,a");
+
+  /* sign adjust left side */
+  l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
+  MOVA (l);
+
+  lbl = newiTempLabel (NULL);
+  emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
+  emitcode ("cpl", "a");
+  emitcode ("inc", "a");
+  emitcode ("", "%05d$:", (lbl->key + 100));
+
+  /* now the multiplication */
+  emitcode ("nop", "; workaround for DS80C390 div bug.");
+  emitcode ("div", "ab");
+  /* we are interested in the lower order
+     only */
+  lbl = newiTempLabel (NULL);
+  emitcode ("pop", "acc");
+  /* if there was an over flow we don't
+     adjust the sign of the result */
+  emitcode ("jb", "ov,%05d$", (lbl->key + 100));
+  emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
+  CLRC;
+  emitcode ("clr", "a");
+  emitcode ("subb", "a,b");
+  emitcode ("mov", "b,a");
+  emitcode ("", "%05d$:", (lbl->key + 100));
+
+  /* now we are done */
+  aopOp(result, ic, TRUE, FALSE);    
+  aopPut (AOP (result), "b", 0);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genModTwoByte - use the DS390 MAC unit to do 16%16 modulus      */
+/*-----------------------------------------------------------------*/
+static void genModTwoByte (operand *left, operand *right, 
+                           operand *result, iCode *ic)
+{
+       sym_link *retype = getSpec(operandType(right));
+       sym_link *letype = getSpec(operandType(left));
+       int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype);
+       symbol *lbl;
+
+       /* load up MA with left */
+       /* save EA bit in F1 */
+       lbl = newiTempLabel(NULL);
+       emitcode ("setb","F1");
+       emitcode ("jbc","EA,%05d$",lbl->key+100);
+       emitcode ("clr","F1");
+       emitcode("","%05d$:",lbl->key+100);
+
+       if (!umult) {
+               lbl = newiTempLabel(NULL);
+               emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+               emitcode ("jnb","acc.7,%05d$",lbl->key+100);
+               emitcode ("xch", "a,b");
+               emitcode ("cpl","a");
+               emitcode ("add", "a,#1");
+               emitcode ("xch", "a,b");
+               emitcode ("cpl", "a"); // msb
+               emitcode ("addc","a,#0");
+               emitcode ("","%05d$:",lbl->key+100);
+               emitcode ("mov","ma,b");
+               emitcode ("mov","ma,a");
+       } else {
+               emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+       }
+
+       /* load up MB with right */
+       if (!umult) {
+               if (AOP_TYPE(right) == AOP_LIT) {
+                       int val=floatFromVal (AOP (right)->aopu.aop_lit);
+                       if (val < 0) {
+                               val = -val;
+                       } 
+                       emitcode ("mov","mb,#0x%02x",val & 0xff);
+                       emitcode ("mov","mb,#0x%02x",(val >> 8) & 0xff);                    
+               } else {
+                       lbl = newiTempLabel(NULL);
+                       emitcode ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+                       emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+                       emitcode ("jnb","acc.7,%05d$",lbl->key+100);            
+                       emitcode ("xch", "a,b");
+                       emitcode ("cpl","a");
+                       emitcode ("add", "a,#1");
+                       emitcode ("xch", "a,b");
+                       emitcode ("cpl", "a"); // msb
+                       emitcode ("addc", "a,#0");
+                       emitcode ("","%05d$:",lbl->key+100);
+                       emitcode ("mov","mb,b");
+                       emitcode ("mov","mb,a");
+               }
+       } else {
+               emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+       }
+
+       /* wait for multiplication to finish */
+       lbl = newiTempLabel(NULL);
+       emitcode("","%05d$:", lbl->key+100);
+       emitcode("mov","a,mcnt1");
+       emitcode("anl","a,#0x80");
+       emitcode("jnz","%05d$",lbl->key+100);
+       
+       freeAsmop (left, NULL, ic, TRUE);
+       freeAsmop (right, NULL, ic,TRUE);
+       aopOp(result, ic, TRUE, FALSE);
+
+       aopPut(AOP(result),"mb",1);
+       aopPut(AOP(result),"mb",0);
+       freeAsmop (result, NULL, ic, TRUE);
+
+       /* restore EA bit in F1 */
+       lbl = newiTempLabel(NULL);
+       emitcode ("jnb","F1,%05d$",lbl->key+100);
+       emitcode ("setb","EA");
+       emitcode("","%05d$:",lbl->key+100);
+       return ;
+}
+
+/*-----------------------------------------------------------------*/
+/* genMod - generates code for division                            */
+/*-----------------------------------------------------------------*/
+static void
+genMod (iCode * ic)
+{
+  operand *left = IC_LEFT (ic);
+  operand *right = IC_RIGHT (ic);
+  operand *result = IC_RESULT (ic);
+
+  D (emitcode (";", "genMod "); );
+
+  /* assign the amsops */
+  AOP_OP_2 (ic);
+
+  /* special cases first */
+  /* both are bits */
+  if (AOP_TYPE (left) == AOP_CRY &&
+      AOP_TYPE (right) == AOP_CRY)
+    {
+      genModbits (left, right, result, ic);
+      goto release;
+    }
+
+  /* if both are of size == 1 */
+  if (AOP_SIZE (left) == 1 &&
+      AOP_SIZE (right) == 1)
+    {
+      genModOneByte (left, right, result, ic);
+      goto release;
+    }
+
+  if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) {
+         /* use the ds390 ARITHMETIC accel UNIT */
+         genModTwoByte (left, right, result, ic);
+         return ;
+  }
+
+  /* should have been converted to function call */
+  assert (0);
+
+release:
+  freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genIfxJump :- will create a jump depending on the ifx           */
+/*-----------------------------------------------------------------*/
+static void
+genIfxJump (iCode * ic, char *jval)
+{
+  symbol *jlbl;
+  symbol *tlbl = newiTempLabel (NULL);
+  char *inst;
+
+  D (emitcode (";", "genIfxJump ");
+    );
+
+  /* if true label then we jump if condition
+     supplied is true */
+  if (IC_TRUE (ic))
+    {
+      jlbl = IC_TRUE (ic);
+      inst = ((strcmp (jval, "a") == 0 ? "jz" :
+              (strcmp (jval, "c") == 0 ? "jnc" : "jnb")));
+    }
+  else
+    {
+      /* false label is present */
+      jlbl = IC_FALSE (ic);
+      inst = ((strcmp (jval, "a") == 0 ? "jnz" :
+              (strcmp (jval, "c") == 0 ? "jc" : "jb")));
+    }
+  if (strcmp (inst, "jb") == 0 || strcmp (inst, "jnb") == 0)
+    emitcode (inst, "%s,%05d$", jval, (tlbl->key + 100));
+  else
+    emitcode (inst, "%05d$", tlbl->key + 100);
+  emitcode ("ljmp", "%05d$", jlbl->key + 100);
+  emitcode ("", "%05d$:", tlbl->key + 100);
+
+  /* mark the icode as generated */
+  ic->generated = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* genCmp :- greater or less than comparison                       */
+/*-----------------------------------------------------------------*/
+static void
+genCmp (operand * left, operand * right,
+       iCode * ic, iCode * ifx, int sign)
+{
+  int size, offset = 0;
+  unsigned long lit = 0L;
+  operand *result;
+
+  D (emitcode (";", "genCmp");
+    );
+
+  result = IC_RESULT (ic);
+
+  /* if left & right are bit variables */
+  if (AOP_TYPE (left) == AOP_CRY &&
+      AOP_TYPE (right) == AOP_CRY)
+    {
+      emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+      emitcode ("anl", "c,/%s", AOP (left)->aopu.aop_dir);
+    }
+  else
+    {
+      /* subtract right from left if at the
+         end the carry flag is set then we know that
+         left is greater than right */
+      size = max (AOP_SIZE (left), AOP_SIZE (right));
+
+      /* if unsigned char cmp with lit, do cjne left,#right,zz */
+      if ((size == 1) && !sign &&
+         (AOP_TYPE (right) == AOP_LIT && AOP_TYPE (left) != AOP_DIR))
+       {
+         symbol *lbl = newiTempLabel (NULL);
+         emitcode ("cjne", "%s,%s,%05d$",
+                   aopGet (AOP (left), offset, FALSE, FALSE, FALSE),
+                   aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+                   lbl->key + 100);
+         emitcode ("", "%05d$:", lbl->key + 100);
+       }
+      else
+       {
+         if (AOP_TYPE (right) == AOP_LIT)
+           {
+             lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+             /* optimize if(x < 0) or if(x >= 0) */
+             if (lit == 0L)
+               {
+                 if (!sign)
+                   {
+                     CLRC;
+                   }
+                 else
+                   {
+                     MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE, FALSE, TRUE));
+
+                     freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+                     freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+
+                     aopOp (result, ic, FALSE, FALSE);
+
+                     if (!(AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result)) && ifx)
+                       {
+                         freeAsmop (result, NULL, ic, TRUE);
+                         genIfxJump (ifx, "acc.7");
+                         return;
+                       }
+                     else
+                       {
+                         emitcode ("rlc", "a");
+                       }
+                     goto release_freedLR;
+                   }
+                 goto release;
+               }
+           }
+         CLRC;
+         while (size--)
+           {
+             emitcode (";", "genCmp #1: %d/%d/%d", size, sign, offset);
+             MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+             emitcode (";", "genCmp #2");
+             if (sign && (size == 0))
+               {
+                 emitcode (";", "genCmp #3");
+                 emitcode ("xrl", "a,#0x80");
+                 if (AOP_TYPE (right) == AOP_LIT)
+                   {
+                     unsigned long lit = (unsigned long)
+                     floatFromVal (AOP (right)->aopu.aop_lit);
+                     emitcode (";", "genCmp #3.1");
+                     emitcode ("subb", "a,#0x%02x",
+                               0x80 ^ (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
+                   }
+                 else
+                   {
+                     emitcode (";", "genCmp #3.2");
+                     if (AOP_NEEDSACC (right))
+                       {
+                         emitcode ("push", "acc");
+                       }
+                     emitcode ("mov", "b,%s", aopGet (AOP (right), offset++,
+                                                      FALSE, FALSE, FALSE));
+                     emitcode ("xrl", "b,#0x80");
+                     if (AOP_NEEDSACC (right))
+                       {
+                         emitcode ("pop", "acc");
+                       }
+                     emitcode ("subb", "a,b");
+                   }
+               }
+             else
+               {
+                 const char *s;
+
+                 emitcode (";", "genCmp #4");
+                 if (AOP_NEEDSACC (right))
+                   {
+                     /* Yuck!! */
+                     emitcode (";", "genCmp #4.1");
+                     emitcode ("xch", "a, b");
+                     MOVA (aopGet (AOP (right), offset++, FALSE, FALSE, TRUE));
+                     emitcode ("xch", "a, b");
+                     s = "b";
+                   }
+                 else
+                   {
+                     emitcode (";", "genCmp #4.2");
+                     s = aopGet (AOP (right), offset++, FALSE, FALSE, FALSE);
+                   }
+
+                 emitcode ("subb", "a,%s", s);
+               }
+           }
+       }
+    }
+
+release:
+/* Don't need the left & right operands any more; do need the result. */
+  freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+
+  aopOp (result, ic, FALSE, FALSE);
+
+release_freedLR:
+
+  if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
+    {
+      outBitC (result);
+    }
+  else
+    {
+      /* if the result is used in the next
+         ifx conditional branch then generate
+         code a little differently */
+      if (ifx)
+       {
+         genIfxJump (ifx, "c");
+       }
+      else
+       {
+         outBitC (result);
+       }
+      /* leave the result in acc */
+    }
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genCmpGt :- greater than comparison                             */
+/*-----------------------------------------------------------------*/
+static void
+genCmpGt (iCode * ic, iCode * ifx)
+{
+  operand *left, *right;
+  sym_link *letype, *retype;
+  int sign;
+
+  D (emitcode (";", "genCmpGt ");
+    );
+
+  left = IC_LEFT (ic);
+  right = IC_RIGHT (ic);
+
+  letype = getSpec (operandType (left));
+  retype = getSpec (operandType (right));
+  sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype));
+
+  /* assign the left & right amsops */
+  AOP_OP_2 (ic);
+
+  genCmp (right, left, ic, ifx, sign);
+}
+
+/*-----------------------------------------------------------------*/
+/* genCmpLt - less than comparisons                                */
+/*-----------------------------------------------------------------*/
+static void
+genCmpLt (iCode * ic, iCode * ifx)
+{
+  operand *left, *right;
+  sym_link *letype, *retype;
+  int sign;
+
+  D (emitcode (";", "genCmpLt "););
+
+  left = IC_LEFT (ic);
+  right = IC_RIGHT (ic);
+
+  letype = getSpec (operandType (left));
+  retype = getSpec (operandType (right));
+  sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype));
+
+  /* assign the left & right amsops */
+  AOP_OP_2 (ic);
+
+  genCmp (left, right, ic, ifx, sign);
+}
+
+/*-----------------------------------------------------------------*/
+/* gencjneshort - compare and jump if not equal                    */
+/*-----------------------------------------------------------------*/
+static void
+gencjneshort (operand * left, operand * right, symbol * lbl)
+{
+  int size = max (AOP_SIZE (left), AOP_SIZE (right));
+  int offset = 0;
+  unsigned long lit = 0L;
+
+  D (emitcode (";", "gencjneshort");
+    );
+
+  /* if the left side is a literal or
+     if the right is in a pointer register and left
+     is not */
+  if ((AOP_TYPE (left) == AOP_LIT) ||
+      (IS_AOP_PREG (right) && !IS_AOP_PREG (left)))
+    {
+      operand *t = right;
+      right = left;
+      left = t;
+    }
+
+  if (AOP_TYPE (right) == AOP_LIT)
+    lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+
+  if (opIsGptr (left) || opIsGptr (right))
+    {
+      /* We are comparing a generic pointer to something.
+       * Exclude the generic type byte from the comparison.
+       */
+      size--;
+      D (emitcode (";", "cjneshort: generic ptr special case.");
+       )
+    }
+
+
+  /* if the right side is a literal then anything goes */
+  if (AOP_TYPE (right) == AOP_LIT &&
+      AOP_TYPE (left) != AOP_DIR)
+    {
+      while (size--)
+       {
+         char *l = aopGet (AOP (left), offset, FALSE, FALSE, TRUE);
+         MOVA (l);
+         emitcode ("cjne", "a,%s,%05d$",
+                   aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+                   lbl->key + 100);
+         offset++;
+       }
+    }
+
+  /* if the right side is in a register or in direct space or
+     if the left is a pointer register & right is not */
+  else if (AOP_TYPE (right) == AOP_REG ||
+          AOP_TYPE (right) == AOP_DIR ||
+          (AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) ||
+          (IS_AOP_PREG (left) && !IS_AOP_PREG (right)))
+    {
+      while (size--)
+       {
+         MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+         if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) &&
+             ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
+           emitcode ("jnz", "%05d$", lbl->key + 100);
+         else
+           emitcode ("cjne", "a,%s,%05d$",
+                     aopGet (AOP (right), offset, FALSE, TRUE, FALSE),
+                     lbl->key + 100);
+         offset++;
+       }
+    }
+  else
+    {
+      /* right is a pointer reg need both a & b */
+      while (size--)
+       {
+         char *l = aopGet (AOP (left), offset, FALSE, FALSE, TRUE);
+         if (strcmp (l, "b"))
+           emitcode ("mov", "b,%s", l);
+         MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+         emitcode ("cjne", "a,b,%05d$", lbl->key + 100);
+         offset++;
+       }
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* gencjne - compare and jump if not equal                         */
+/*-----------------------------------------------------------------*/
+static void
+gencjne (operand * left, operand * right, symbol * lbl)
+{
+  symbol *tlbl = newiTempLabel (NULL);
+
+  D (emitcode (";", "gencjne");
+    );
+
+  gencjneshort (left, right, lbl);
+
+  emitcode ("mov", "a,%s", one);
+  emitcode ("sjmp", "%05d$", tlbl->key + 100);
+  emitcode ("", "%05d$:", lbl->key + 100);
+  emitcode ("clr", "a");
+  emitcode ("", "%05d$:", tlbl->key + 100);
+}
+
+/*-----------------------------------------------------------------*/
+/* genCmpEq - generates code for equal to                          */
+/*-----------------------------------------------------------------*/
+static void
+genCmpEq (iCode * ic, iCode * ifx)
+{
+  operand *left, *right, *result;
+
+  D (emitcode (";", "genCmpEq ");
+    );
+
+  AOP_OP_2 (ic);
+  AOP_SET_LOCALS (ic);
+
+  /* if literal, literal on the right or
+     if the right is in a pointer register and left
+     is not */
+  if ((AOP_TYPE (IC_LEFT (ic)) == AOP_LIT) ||
+      (IS_AOP_PREG (right) && !IS_AOP_PREG (left)))
+    {
+      operand *t = IC_RIGHT (ic);
+      IC_RIGHT (ic) = IC_LEFT (ic);
+      IC_LEFT (ic) = t;
+    }
+
+  if (ifx &&                   /* !AOP_SIZE(result) */
+      OP_SYMBOL (result) &&
+      OP_SYMBOL (result)->regType == REG_CND)
+    {
+      symbol *tlbl;
+      /* if they are both bit variables */
+      if (AOP_TYPE (left) == AOP_CRY &&
+         ((AOP_TYPE (right) == AOP_CRY) || (AOP_TYPE (right) == AOP_LIT)))
+       {
+         if (AOP_TYPE (right) == AOP_LIT)
+           {
+             unsigned long lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+             if (lit == 0L)
+               {
+                 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+                 emitcode ("cpl", "c");
+               }
+             else if (lit == 1L)
+               {
+                 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+               }
+             else
+               {
+                 emitcode ("clr", "c");
+               }
+             /* AOP_TYPE(right) == AOP_CRY */
+           }
+         else
+           {
+             symbol *lbl = newiTempLabel (NULL);
+             emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+             emitcode ("jb", "%s,%05d$", AOP (right)->aopu.aop_dir, (lbl->key + 100));
+             emitcode ("cpl", "c");
+             emitcode ("", "%05d$:", (lbl->key + 100));
+           }
+         /* if true label then we jump if condition
+            supplied is true */
+         tlbl = newiTempLabel (NULL);
+         if (IC_TRUE (ifx))
+           {
+             emitcode ("jnc", "%05d$", tlbl->key + 100);
+             emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
+           }
+         else
+           {
+             emitcode ("jc", "%05d$", tlbl->key + 100);
+             emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
+           }
+         emitcode ("", "%05d$:", tlbl->key + 100);
+       }
+      else
+       {
+         tlbl = newiTempLabel (NULL);
+         gencjneshort (left, right, tlbl);
+         if (IC_TRUE (ifx))
+           {
+             emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
+             emitcode ("", "%05d$:", tlbl->key + 100);
+           }
+         else
+           {
+             symbol *lbl = newiTempLabel (NULL);
+             emitcode ("sjmp", "%05d$", lbl->key + 100);
+             emitcode ("", "%05d$:", tlbl->key + 100);
+             emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
+             emitcode ("", "%05d$:", lbl->key + 100);
+           }
+       }
+      /* mark the icode as generated */
+      ifx->generated = 1;
+
+      freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+      freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+      return;
+    }
+
+  /* if they are both bit variables */
+  if (AOP_TYPE (left) == AOP_CRY &&
+      ((AOP_TYPE (right) == AOP_CRY) || (AOP_TYPE (right) == AOP_LIT)))
+    {
+      if (AOP_TYPE (right) == AOP_LIT)
+       {
+         unsigned long lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+         if (lit == 0L)
+           {
+             emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+             emitcode ("cpl", "c");
+           }
+         else if (lit == 1L)
+           {
+             emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+           }
+         else
+           {
+             emitcode ("clr", "c");
+           }
+         /* AOP_TYPE(right) == AOP_CRY */
+       }
+      else
+       {
+         symbol *lbl = newiTempLabel (NULL);
+         emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+         emitcode ("jb", "%s,%05d$", AOP (right)->aopu.aop_dir, (lbl->key + 100));
+         emitcode ("cpl", "c");
+         emitcode ("", "%05d$:", (lbl->key + 100));
+       }
+
+      freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+      freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+
+      aopOp (result, ic, TRUE, FALSE);
+
+      /* c = 1 if egal */
+      if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
+       {
+         outBitC (result);
+         goto release;
+       }
+      if (ifx)
+       {
+         genIfxJump (ifx, "c");
+         goto release;
+       }
+      /* if the result is used in an arithmetic operation
+         then put the result in place */
+      outBitC (result);
+    }
+  else
+    {
+      gencjne (left, right, newiTempLabel (NULL));
+
+      freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+      freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+
+      aopOp (result, ic, TRUE, FALSE);
+
+      if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result))
+       {
+         aopPut (AOP (result), "a", 0);
+         goto release;
+       }
+      if (ifx)
+       {
+         genIfxJump (ifx, "a");
+         goto release;
+       }
+      /* if the result is used in an arithmetic operation
+         then put the result in place */
+      if (AOP_TYPE (result) != AOP_CRY)
+       outAcc (result);
+      /* leave the result in acc */
+    }
+
+release:
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* ifxForOp - returns the icode containing the ifx for operand     */
+/*-----------------------------------------------------------------*/
+static iCode *
+ifxForOp (operand * op, iCode * ic)
+{
+  /* if true symbol then needs to be assigned */
+  if (IS_TRUE_SYMOP (op))
+    return NULL;
+
+  /* if this has register type condition and
+     the next instruction is ifx with the same operand
+     and live to of the operand is upto the ifx only then */
+  if (ic->next &&
+      ic->next->op == IFX &&
+      IC_COND (ic->next)->key == op->key &&
+      OP_SYMBOL (op)->liveTo <= ic->next->seq)
+    return ic->next;
+
+  return NULL;
+}
+/*-----------------------------------------------------------------*/
+/* hasInc - operand is incremented before any other use            */
+/*-----------------------------------------------------------------*/
+static iCode *
+hasInc (operand *op, iCode *ic)
+{
+  sym_link *type = operandType(op);
+  sym_link *retype = getSpec (type);
+  iCode *lic = ic->next;
+  int isize ;
+  
+  /* this could from a cast, e.g.: "(char xdata *) 0x7654;" */
+  if (!IS_SYMOP(op)) return NULL;
+
+  if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
+  isize = getSize(type->next);
+  while (lic) {
+      /* if operand of the form op = op + <sizeof *op> */
+      if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
+         isOperandEqual(IC_RESULT(lic),op) && 
+         isOperandLiteral(IC_RIGHT(lic)) &&
+         operandLitValue(IC_RIGHT(lic)) == isize) {
+         return lic;
+      }
+      /* if the operand used or deffed */
+      if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
+         return NULL;
+      }
+      /* if GOTO or IFX */
+      if (lic->op == IFX || lic->op == GOTO) break;
+      lic = lic->next;
+  }
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* genAndOp - for && operation                                     */
+/*-----------------------------------------------------------------*/
+static void
+genAndOp (iCode * ic)
+{
+  operand *left, *right, *result;
+  symbol *tlbl;
+
+  D (emitcode (";", "genAndOp "););
+
+  /* note here that && operations that are in an
+     if statement are taken away by backPatchLabels
+     only those used in arthmetic operations remain */
+  AOP_OP_2 (ic);
+  AOP_SET_LOCALS (ic);
+
+  /* if both are bit variables */
+  if (AOP_TYPE (left) == AOP_CRY &&
+      AOP_TYPE (right) == AOP_CRY)
+    {
+      emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+      emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
+      freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+      freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  
+      aopOp (result,ic,FALSE, FALSE);
+      outBitC (result);
+    }
+  else
+    {
+      tlbl = newiTempLabel (NULL);
+      toBoolean (left);
+      emitcode ("jz", "%05d$", tlbl->key + 100);
+      toBoolean (right);
+      emitcode ("", "%05d$:", tlbl->key + 100);
+      freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+      freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  
+      aopOp (result,ic,FALSE, FALSE);
+      outBitAcc (result);
+    }
+    freeAsmop (result, NULL, ic, TRUE);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genOrOp - for || operation                                      */
+/*-----------------------------------------------------------------*/
+static void
+genOrOp (iCode * ic)
+{
+  operand *left, *right, *result;
+  symbol *tlbl;
+
+  D (emitcode (";", "genOrOp "););
+
+  /* note here that || operations that are in an
+     if statement are taken away by backPatchLabels
+     only those used in arthmetic operations remain */
+  AOP_OP_2 (ic);
+  AOP_SET_LOCALS (ic);
+
+  /* if both are bit variables */
+  if (AOP_TYPE (left) == AOP_CRY &&
+      AOP_TYPE (right) == AOP_CRY)
+    {
+      emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+      emitcode ("orl", "c,%s", AOP (right)->aopu.aop_dir);
+      freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+      freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  
+      aopOp (result,ic,FALSE, FALSE);
+      
+      outBitC (result);
+    }
+  else
+    {
+      tlbl = newiTempLabel (NULL);
+      toBoolean (left);
+      emitcode ("jnz", "%05d$", tlbl->key + 100);
+      toBoolean (right);
+      emitcode ("", "%05d$:", tlbl->key + 100);
+      freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+      freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  
+      aopOp (result,ic,FALSE, FALSE);
+      
+      outBitAcc (result);
+    }
+
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* isLiteralBit - test if lit == 2^n                               */
+/*-----------------------------------------------------------------*/
+static int
+isLiteralBit (unsigned long lit)
+{
+  unsigned long pw[32] =
+  {1L, 2L, 4L, 8L, 16L, 32L, 64L, 128L,
+   0x100L, 0x200L, 0x400L, 0x800L,
+   0x1000L, 0x2000L, 0x4000L, 0x8000L,
+   0x10000L, 0x20000L, 0x40000L, 0x80000L,
+   0x100000L, 0x200000L, 0x400000L, 0x800000L,
+   0x1000000L, 0x2000000L, 0x4000000L, 0x8000000L,
+   0x10000000L, 0x20000000L, 0x40000000L, 0x80000000L};
+  int idx;
+
+  for (idx = 0; idx < 32; idx++)
+    if (lit == pw[idx])
+      return idx + 1;
+  return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* continueIfTrue -                                                */
+/*-----------------------------------------------------------------*/
+static void
+continueIfTrue (iCode * ic)
+{
+  if (IC_TRUE (ic))
+    emitcode ("ljmp", "%05d$", IC_TRUE (ic)->key + 100);
+  ic->generated = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* jmpIfTrue -                                                     */
+/*-----------------------------------------------------------------*/
+static void
+jumpIfTrue (iCode * ic)
+{
+  if (!IC_TRUE (ic))
+    emitcode ("ljmp", "%05d$", IC_FALSE (ic)->key + 100);
+  ic->generated = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* jmpTrueOrFalse -                                                */
+/*-----------------------------------------------------------------*/
+static void
+jmpTrueOrFalse (iCode * ic, symbol * tlbl)
+{
+  // ugly but optimized by peephole
+  if (IC_TRUE (ic))
+    {
+      symbol *nlbl = newiTempLabel (NULL);
+      emitcode ("sjmp", "%05d$", nlbl->key + 100);
+      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("ljmp", "%05d$", IC_TRUE (ic)->key + 100);
+      emitcode ("", "%05d$:", nlbl->key + 100);
+    }
+  else
+    {
+      emitcode ("ljmp", "%05d$", IC_FALSE (ic)->key + 100);
+      emitcode ("", "%05d$:", tlbl->key + 100);
+    }
+  ic->generated = 1;
+}
+
+// Generate code to perform a bit-wise logic operation
+// on two operands in far space (assumed to already have been 
+// aopOp'd by the AOP_OP_3_NOFATAL macro), storing the result
+// in far space. This requires pushing the result on the stack
+// then popping it into the result.
+static void
+genFarFarLogicOp(iCode *ic, char *logicOp)
+{
+      int size, resultSize, compSize;
+      int offset = 0;
+      
+      TR_AP("#5");
+      D(emitcode(";", "%s special case for 3 far operands.", logicOp););
+      compSize = AOP_SIZE(IC_LEFT(ic)) < AOP_SIZE(IC_RIGHT(ic)) ? 
+                 AOP_SIZE(IC_LEFT(ic)) : AOP_SIZE(IC_RIGHT(ic));
+      
+      _startLazyDPSEvaluation();
+      for (size = compSize; (size--); offset++)
+      {
+         MOVA (aopGet (AOP (IC_LEFT(ic)), offset, FALSE, FALSE, TRUE));
+         emitcode ("mov", "%s, acc", DP2_RESULT_REG);
+         MOVA (aopGet (AOP (IC_RIGHT(ic)), offset, FALSE, FALSE, TRUE));
+         
+         emitcode (logicOp, "a,%s", DP2_RESULT_REG);
+         emitcode ("push", "acc");
+      }
+      _endLazyDPSEvaluation();
+     
+      freeAsmop (IC_LEFT(ic), NULL, ic, RESULTONSTACK (ic) ? FALSE : TRUE);
+      freeAsmop (IC_RIGHT(ic), NULL, ic, RESULTONSTACK (ic) ? FALSE : TRUE);
+      aopOp (IC_RESULT(ic),ic,TRUE, FALSE);
+     
+      resultSize = AOP_SIZE(IC_RESULT(ic));
+
+      ADJUST_PUSHED_RESULT(compSize, resultSize);
+
+      _startLazyDPSEvaluation();
+      while (compSize--)
+      {
+         emitcode ("pop", "acc");
+         aopPut (AOP (IC_RESULT (ic)), "a", compSize);
+      }
+      _endLazyDPSEvaluation();
+      freeAsmop(IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genAnd  - code for and                                          */
+/*-----------------------------------------------------------------*/
+static void
+genAnd (iCode * ic, iCode * ifx)
+{
+  operand *left, *right, *result;
+  int size, offset = 0;
+  unsigned long lit = 0L;
+  int bytelit = 0;
+  char buffer[10];
+  bool pushResult;
+
+  D (emitcode (";", "genAnd "););
+
+  AOP_OP_3_NOFATAL (ic, pushResult);
+  AOP_SET_LOCALS (ic);
+
+  if (pushResult)
+  {
+      genFarFarLogicOp(ic, "anl");
+      return;
+  }  
+
+#ifdef DEBUG_TYPE
+  emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+           AOP_TYPE (result),
+           AOP_TYPE (left), AOP_TYPE (right));
+  emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
+           AOP_SIZE (result),
+           AOP_SIZE (left), AOP_SIZE (right));
+#endif
+
+  /* if left is a literal & right is not then exchange them */
+  if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT)
+#ifdef LOGIC_OPS_BROKEN      
+    ||  AOP_NEEDSACC (left)
+#endif
+    )
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
+
+  /* if result = right then exchange them */
+  if (sameRegs (AOP (result), AOP (right)))
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
+
+  /* if right is bit then exchange them */
+  if (AOP_TYPE (right) == AOP_CRY &&
+      AOP_TYPE (left) != AOP_CRY)
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
+  if (AOP_TYPE (right) == AOP_LIT)
+    lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+
+  size = AOP_SIZE (result);
+
+  // if(bit & yy)
+  // result = bit & yy;
+  if (AOP_TYPE (left) == AOP_CRY)
+    {
+      // c = bit & literal;
+      if (AOP_TYPE (right) == AOP_LIT)
+       {
+         if (lit & 1)
+           {
+             if (size && sameRegs (AOP (result), AOP (left)))
+               // no change
+               goto release;
+             emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+           }
+         else
+           {
+             // bit(result) = 0;
+             if (size && (AOP_TYPE (result) == AOP_CRY))
+               {
+                 emitcode ("clr", "%s", AOP (result)->aopu.aop_dir);
+                 goto release;
+               }
+             if ((AOP_TYPE (result) == AOP_CRY) && ifx)
+               {
+                 jumpIfTrue (ifx);
+                 goto release;
+               }
+             emitcode ("clr", "c");
+           }
+       }
+      else
+       {
+         if (AOP_TYPE (right) == AOP_CRY)
+           {
+             // c = bit & bit;
+             emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+             emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
+           }
+         else
+           {
+             // c = bit & val;
+             MOVA (aopGet (AOP (right), 0, FALSE, FALSE, TRUE));
+             // c = lsb
+             emitcode ("rrc", "a");
+             emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
+           }
+       }
+      // bit = c
+      // val = c
+      if (size)
+       outBitC (result);
+      // if(bit & ...)
+      else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
+       genIfxJump (ifx, "c");
+      goto release;
+    }
+
+  // if(val & 0xZZ)       - size = 0, ifx != FALSE  -
+  // bit = val & 0xZZ     - size = 1, ifx = FALSE -
+  if ((AOP_TYPE (right) == AOP_LIT) &&
+      (AOP_TYPE (result) == AOP_CRY) &&
+      (AOP_TYPE (left) != AOP_CRY))
+    {
+      int posbit = isLiteralBit (lit);
+      /* left &  2^n */
+      if (posbit)
+       {
+         posbit--;
+         MOVA (aopGet (AOP (left), posbit >> 3, FALSE, FALSE, TRUE));
+         // bit = left & 2^n
+         if (size)
+           emitcode ("mov", "c,acc.%d", posbit & 0x07);
+         // if(left &  2^n)
+         else
+           {
+             if (ifx)
+               {
+                 sprintf (buffer, "acc.%d", posbit & 0x07);
+                 genIfxJump (ifx, buffer);
+               }
+             goto release;
+           }
+       }
+      else
+       {
+         symbol *tlbl = newiTempLabel (NULL);
+         int sizel = AOP_SIZE (left);
+         if (size)
+           emitcode ("setb", "c");
+         while (sizel--)
+           {
+             if ((bytelit = ((lit >> (offset * 8)) & 0x0FFL)) != 0x0L)
+               {
+                 MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                 // byte ==  2^n ?
+                 if ((posbit = isLiteralBit (bytelit)) != 0)
+                   emitcode ("jb", "acc.%d,%05d$", (posbit - 1) & 0x07, tlbl->key + 100);
+                 else
+                   {
+                     if (bytelit != 0x0FFL)
+                       emitcode ("anl", "a,%s",
+                         aopGet (AOP (right), offset, FALSE, TRUE, FALSE));
+                     emitcode ("jnz", "%05d$", tlbl->key + 100);
+                   }
+               }
+             offset++;
+           }
+         // bit = left & literal
+         if (size)
+           {
+             emitcode ("clr", "c");
+             emitcode ("", "%05d$:", tlbl->key + 100);
+           }
+         // if(left & literal)
+         else
+           {
+             if (ifx)
+               jmpTrueOrFalse (ifx, tlbl);
+             goto release;
+           }
+       }
+      outBitC (result);
+      goto release;
+    }
+
+  /* if left is same as result */
+  if (sameRegs (AOP (result), AOP (left)))
+    {
+      for (; size--; offset++)
+       {
+         if (AOP_TYPE (right) == AOP_LIT)
+           {
+             if ((bytelit = (int) ((lit >> (offset * 8)) & 0x0FFL)) == 0x0FF)
+               continue;
+             else if (bytelit == 0)
+               aopPut (AOP (result), zero, offset);
+             else if (IS_AOP_PREG (result))
+               {
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 emitcode ("anl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                 aopPut (AOP (result), "a", offset);
+               }
+             else
+               emitcode ("anl", "%s,%s",
+                         aopGet (AOP (left), offset, FALSE, TRUE, FALSE),
+                         aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+           }
+         else
+           {
+             if (AOP_TYPE (left) == AOP_ACC)
+               emitcode ("anl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+             else
+               {
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 if (IS_AOP_PREG (result))
+                   {
+                     emitcode ("anl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                     aopPut (AOP (result), "a", offset);
+
+                   }
+                 else
+                   emitcode ("anl", "%s,a",
+                          aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+               }
+           }
+       }
+    }
+  else
+    {
+      // left & result in different registers
+      if (AOP_TYPE (result) == AOP_CRY)
+       {
+         // result = bit
+         // if(size), result in bit
+         // if(!size && ifx), conditional oper: if(left & right)
+         symbol *tlbl = newiTempLabel (NULL);
+         int sizer = min (AOP_SIZE (left), AOP_SIZE (right));
+         if (size)
+           emitcode ("setb", "c");
+         while (sizer--)
+           {
+             if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+               emitcode ("anl", "a,%s",
+                         aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+             } else {
+               if (AOP_TYPE(left)==AOP_ACC) {
+                 emitcode("mov", "b,a");
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 emitcode("anl", "a,b");
+               }else {
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 emitcode ("anl", "a,%s",
+                           aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+               }
+             }
+             emitcode ("jnz", "%05d$", tlbl->key + 100);
+             offset++;
+           }
+         if (size)
+           {
+             CLRC;
+             emitcode ("", "%05d$:", tlbl->key + 100);
+             outBitC (result);
+           }
+         else if (ifx)
+           jmpTrueOrFalse (ifx, tlbl);
+       }
+      else
+       {
+         for (; (size--); offset++)
+           {
+             // normal case
+             // result = left & right
+             if (AOP_TYPE (right) == AOP_LIT)
+               {
+                 if ((bytelit = (int) ((lit >> (offset * 8)) & 0x0FFL)) == 0x0FF)
+                   {
+                     aopPut (AOP (result),
+                          aopGet (AOP (left), offset, FALSE, FALSE, FALSE),
+                             offset);
+                     continue;
+                   }
+                 else if (bytelit == 0)
+                   {
+                     aopPut (AOP (result), zero, offset);
+                     continue;
+                   }
+                 D (emitcode (";", "better literal AND."););
+                 MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                 emitcode ("anl", "a, %s", aopGet (AOP (right), offset,
+                                                   FALSE, FALSE, FALSE));
+
+               }
+             else
+               {
+                 // faster than result <- left, anl result,right
+                 // and better if result is SFR
+                 if (AOP_TYPE (left) == AOP_ACC)
+                   {
+                     emitcode ("anl", "a,%s", aopGet (AOP (right), offset,
+                                                      FALSE, FALSE, FALSE));
+                   }
+                 else
+                   {
+                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+                     if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
+                     {
+                         emitcode("mov", "b,a");
+                         rOp = "b";
+                     }
+                       
+                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                     emitcode ("anl", "a,%s", rOp);
+                   }                   
+               }
+             aopPut (AOP (result), "a", offset);
+           }
+       }
+    }
+
+release:
+  freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genOr  - code for or                                            */
+/*-----------------------------------------------------------------*/
+static void
+genOr (iCode * ic, iCode * ifx)
+{
+  operand *left, *right, *result;
+  int size, offset = 0;
+  unsigned long lit = 0L;
+  bool            pushResult;
+
+  D (emitcode (";", "genOr "););
+
+  AOP_OP_3_NOFATAL (ic, pushResult);
+  AOP_SET_LOCALS (ic);
+
+  if (pushResult)
+  {
+      genFarFarLogicOp(ic, "orl");
+      return;
+  }
+
+
+#ifdef DEBUG_TYPE
+  emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+           AOP_TYPE (result),
+           AOP_TYPE (left), AOP_TYPE (right));
+  emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
+           AOP_SIZE (result),
+           AOP_SIZE (left), AOP_SIZE (right));
+#endif
+
+  /* if left is a literal & right is not then exchange them */
+  if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT)
+#ifdef LOGIC_OPS_BROKEN
+   || AOP_NEEDSACC (left) // I think this is a net loss now.
+#endif      
+      )
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
+
+  /* if result = right then exchange them */
+  if (sameRegs (AOP (result), AOP (right)))
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
+
+  /* if right is bit then exchange them */
+  if (AOP_TYPE (right) == AOP_CRY &&
+      AOP_TYPE (left) != AOP_CRY)
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
+  if (AOP_TYPE (right) == AOP_LIT)
+    lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+
+  size = AOP_SIZE (result);
+
+  // if(bit | yy)
+  // xx = bit | yy;
+  if (AOP_TYPE (left) == AOP_CRY)
+    {
+      if (AOP_TYPE (right) == AOP_LIT)
+       {
+         // c = bit & literal;
+         if (lit)
+           {
+             // lit != 0 => result = 1
+             if (AOP_TYPE (result) == AOP_CRY)
+               {
+                 if (size)
+                   emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
+                 else if (ifx)
+                   continueIfTrue (ifx);
+                 goto release;
+               }
+             emitcode ("setb", "c");
+           }
+         else
+           {
+             // lit == 0 => result = left
+             if (size && sameRegs (AOP (result), AOP (left)))
+               goto release;
+             emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+           }
+       }
+      else
+       {
+         if (AOP_TYPE (right) == AOP_CRY)
+           {
+             // c = bit | bit;
+             emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+             emitcode ("orl", "c,%s", AOP (left)->aopu.aop_dir);
+           }
+         else
+           {
+             // c = bit | val;
+             symbol *tlbl = newiTempLabel (NULL);
+             if (!((AOP_TYPE (result) == AOP_CRY) && ifx))
+               emitcode ("setb", "c");
+             emitcode ("jb", "%s,%05d$",
+                       AOP (left)->aopu.aop_dir, tlbl->key + 100);
+             toBoolean (right);
+             emitcode ("jnz", "%05d$", tlbl->key + 100);
+             if ((AOP_TYPE (result) == AOP_CRY) && ifx)
+               {
+                 jmpTrueOrFalse (ifx, tlbl);
+                 goto release;
+               }
+             else
+               {
+                 CLRC;
+                 emitcode ("", "%05d$:", tlbl->key + 100);
+               }
+           }
+       }
+      // bit = c
+      // val = c
+      if (size)
+       outBitC (result);
+      // if(bit | ...)
+      else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
+       genIfxJump (ifx, "c");
+      goto release;
+    }
+
+  // if(val | 0xZZ)       - size = 0, ifx != FALSE  -
+  // bit = val | 0xZZ     - size = 1, ifx = FALSE -
+  if ((AOP_TYPE (right) == AOP_LIT) &&
+      (AOP_TYPE (result) == AOP_CRY) &&
+      (AOP_TYPE (left) != AOP_CRY))
+    {
+      if (lit)
+       {
+         // result = 1
+         if (size)
+           emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
+         else
+           continueIfTrue (ifx);
+         goto release;
+       }
+      else
+       {
+         // lit = 0, result = boolean(left)
+         if (size)
+           emitcode ("setb", "c");
+         toBoolean (right);
+         if (size)
+           {
+             symbol *tlbl = newiTempLabel (NULL);
+             emitcode ("jnz", "%05d$", tlbl->key + 100);
+             CLRC;
+             emitcode ("", "%05d$:", tlbl->key + 100);
+           }
+         else
+           {
+             genIfxJump (ifx, "a");
+             goto release;
+           }
+       }
+      outBitC (result);
+      goto release;
+    }
+
+  /* if left is same as result */
+  if (sameRegs (AOP (result), AOP (left)))
+    {
+      for (; size--; offset++)
+       {
+         if (AOP_TYPE (right) == AOP_LIT)
+           {
+             if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
+               {
+                 continue;
+               }
+             else
+               {
+                 if (IS_AOP_PREG (left))
+                   {
+                     MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                     emitcode ("orl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                     aopPut (AOP (result), "a", offset);
+                   }
+                 else
+                   {
+                     emitcode ("orl", "%s,%s",
+                           aopGet (AOP (left), offset, FALSE, TRUE, FALSE),
+                        aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+                   }
+               }
+           }
+         else
+           {
+             if (AOP_TYPE (left) == AOP_ACC)
+               {
+                 emitcode ("orl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+               }
+             else
+               {
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 if (IS_AOP_PREG (left))
+                   {
+                     emitcode ("orl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                     aopPut (AOP (result), "a", offset);
+                   }
+                 else
+                   {
+                     emitcode ("orl", "%s,a",
+                          aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                   }
+               }
+           }
+       }
+    }
+  else
+    {
+      // left & result in different registers
+      if (AOP_TYPE (result) == AOP_CRY)
+       {
+         // result = bit
+         // if(size), result in bit
+         // if(!size && ifx), conditional oper: if(left | right)
+         symbol *tlbl = newiTempLabel (NULL);
+         int sizer = max (AOP_SIZE (left), AOP_SIZE (right));
+         if (size)
+           emitcode ("setb", "c");
+         while (sizer--)
+           {
+             if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+               emitcode ("orl", "a,%s",
+                         aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+             } else {
+               MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+               emitcode ("orl", "a,%s",
+                         aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+             }
+             emitcode ("jnz", "%05d$", tlbl->key + 100);
+             offset++;
+           }
+         if (size)
+           {
+             CLRC;
+             emitcode ("", "%05d$:", tlbl->key + 100);
+             outBitC (result);
+           }
+         else if (ifx)
+           jmpTrueOrFalse (ifx, tlbl);
+       }
+      else
+       {
+           _startLazyDPSEvaluation();
+         for (; (size--); offset++)
+           {
+             // normal case
+             // result = left & right
+             if (AOP_TYPE (right) == AOP_LIT)
+               {
+                 if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
+                   {
+                     aopPut (AOP (result),
+                          aopGet (AOP (left), offset, FALSE, FALSE, FALSE),
+                             offset);
+                     continue;
+                   }
+                 D (emitcode (";", "better literal OR."););
+                 MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                 emitcode ("orl", "a, %s", aopGet (AOP (right), offset,
+                                                   FALSE, FALSE, FALSE));
+
+               }
+             else
+               {
+                 // faster than result <- left, anl result,right
+                 // and better if result is SFR
+                 if (AOP_TYPE (left) == AOP_ACC)
+                   {
+                     emitcode ("orl", "a,%s", aopGet (AOP (right), offset,
+                                                      FALSE, FALSE, FALSE));
+                   }
+                 else
+                   {
+                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+                       
+                     if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
+                     {
+                         emitcode("mov", "b,a");
+                         rOp = "b";
+                     }
+                       
+                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                     emitcode ("orl", "a,%s", rOp);
+                   }
+               }
+             aopPut (AOP (result), "a", offset);
+           }
+           _endLazyDPSEvaluation();
+       }
+    }
+
+release:
+  freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genXor - code for xclusive or                                   */
+/*-----------------------------------------------------------------*/
+static void
+genXor (iCode * ic, iCode * ifx)
+{
+  operand *left, *right, *result;
+  int size, offset = 0;
+  unsigned long lit = 0L;
+  bool pushResult;
+
+  D (emitcode (";", "genXor "););
+
+  AOP_OP_3_NOFATAL (ic, pushResult);
+  AOP_SET_LOCALS (ic);
+
+  if (pushResult)
+  {
+      genFarFarLogicOp(ic, "xrl");
+      return;
+  }  
+
+#ifdef DEBUG_TYPE
+  emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+           AOP_TYPE (result),
+           AOP_TYPE (left), AOP_TYPE (right));
+  emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
+           AOP_SIZE (result),
+           AOP_SIZE (left), AOP_SIZE (right));
+#endif
+
+  /* if left is a literal & right is not ||
+     if left needs acc & right does not */
+  if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) 
+#ifdef LOGIC_OPS_BROKEN      
+      || (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right))
+#endif
+     )
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
+
+  /* if result = right then exchange them */
+  if (sameRegs (AOP (result), AOP (right)))
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
+
+  /* if right is bit then exchange them */
+  if (AOP_TYPE (right) == AOP_CRY &&
+      AOP_TYPE (left) != AOP_CRY)
+    {
+      operand *tmp = right;
+      right = left;
+      left = tmp;
+    }
+  if (AOP_TYPE (right) == AOP_LIT)
+    lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+
+  size = AOP_SIZE (result);
+
+  // if(bit ^ yy)
+  // xx = bit ^ yy;
+  if (AOP_TYPE (left) == AOP_CRY)
+    {
+      if (AOP_TYPE (right) == AOP_LIT)
+       {
+         // c = bit & literal;
+         if (lit >> 1)
+           {
+             // lit>>1  != 0 => result = 1
+             if (AOP_TYPE (result) == AOP_CRY)
+               {
+                 if (size)
+                   emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
+                 else if (ifx)
+                   continueIfTrue (ifx);
+                 goto release;
+               }
+             emitcode ("setb", "c");
+           }
+         else
+           {
+             // lit == (0 or 1)
+             if (lit == 0)
+               {
+                 // lit == 0, result = left
+                 if (size && sameRegs (AOP (result), AOP (left)))
+                   goto release;
+                 emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+               }
+             else
+               {
+                 // lit == 1, result = not(left)
+                 if (size && sameRegs (AOP (result), AOP (left)))
+                   {
+                     emitcode ("cpl", "%s", AOP (result)->aopu.aop_dir);
+                     goto release;
+                   }
+                 else
+                   {
+                     emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+                     emitcode ("cpl", "c");
+                   }
+               }
+           }
+
+       }
+      else
+       {
+         // right != literal
+         symbol *tlbl = newiTempLabel (NULL);
+         if (AOP_TYPE (right) == AOP_CRY)
+           {
+             // c = bit ^ bit;
+             emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+           }
+         else
+           {
+             int sizer = AOP_SIZE (right);
+             // c = bit ^ val
+             // if val>>1 != 0, result = 1
+             emitcode ("setb", "c");
+             while (sizer)
+               {
+                 MOVA (aopGet (AOP (right), sizer - 1, FALSE, FALSE, TRUE));
+                 if (sizer == 1)
+                   // test the msb of the lsb
+                   emitcode ("anl", "a,#0xfe");
+                 emitcode ("jnz", "%05d$", tlbl->key + 100);
+                 sizer--;
+               }
+             // val = (0,1)
+             emitcode ("rrc", "a");
+           }
+         emitcode ("jnb", "%s,%05d$", AOP (left)->aopu.aop_dir, (tlbl->key + 100));
+         emitcode ("cpl", "c");
+         emitcode ("", "%05d$:", (tlbl->key + 100));
+       }
+      // bit = c
+      // val = c
+      if (size)
+       outBitC (result);
+      // if(bit | ...)
+      else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
+       genIfxJump (ifx, "c");
+      goto release;
+    }
+
+  if (sameRegs (AOP (result), AOP (left)))
+    {
+      /* if left is same as result */
+      for (; size--; offset++)
+       {
+         if (AOP_TYPE (right) == AOP_LIT)
+           {
+             if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
+               continue;
+             else if (IS_AOP_PREG (left))
+               {
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                 aopPut (AOP (result), "a", offset);
+               }
+             else
+               emitcode ("xrl", "%s,%s",
+                         aopGet (AOP (left), offset, FALSE, TRUE, FALSE),
+                         aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+           }
+         else
+           {
+             if (AOP_TYPE (left) == AOP_ACC)
+               emitcode ("xrl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+             else
+               {
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 if (IS_AOP_PREG (left))
+                   {
+                     emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                     aopPut (AOP (result), "a", offset);
+                   }
+                 else
+                   emitcode ("xrl", "%s,a",
+                          aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+               }
+           }
+       }
+    }
+  else
+    {
+      // left & result in different registers
+      if (AOP_TYPE (result) == AOP_CRY)
+       {
+         // result = bit
+         // if(size), result in bit
+         // if(!size && ifx), conditional oper: if(left ^ right)
+         symbol *tlbl = newiTempLabel (NULL);
+         int sizer = max (AOP_SIZE (left), AOP_SIZE (right));
+                 
+         if (size)
+           emitcode ("setb", "c");
+         while (sizer--)
+           {
+             if ((AOP_TYPE (right) == AOP_LIT) &&
+                 (((lit >> (offset * 8)) & 0x0FFL) == 0x00L))
+               {
+                 MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+               }
+             else
+               {
+                 if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+                   emitcode ("xrl", "a,%s",
+                             aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+                 } else {
+                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+                     if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
+                     {
+                         emitcode("mov", "b,a");
+                         rOp = "b";
+                     }
+                       
+                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                     emitcode ("xrl", "a,%s", rOp);                  
+                 }
+               }
+             emitcode ("jnz", "%05d$", tlbl->key + 100);
+             offset++;
+           }
+         if (size)
+           {
+             CLRC;
+             emitcode ("", "%05d$:", tlbl->key + 100);
+             outBitC (result);
+           }
+         else if (ifx)
+           jmpTrueOrFalse (ifx, tlbl);
+       }
+      else
+       {
+       for (; (size--); offset++)
+         {
+           // normal case
+           // result = left & right
+           if (AOP_TYPE (right) == AOP_LIT)
+             {
+               if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
+                 {
+                   aopPut (AOP (result),
+                           aopGet (AOP (left), offset, FALSE, FALSE, FALSE),
+                           offset);
+                   continue;
+                 }
+               D (emitcode (";", "better literal XOR."););
+               MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+               emitcode ("xrl", "a, %s", aopGet (AOP (right), offset,
+                                                 FALSE, FALSE, FALSE));
+             }
+           else
+             {
+               // faster than result <- left, anl result,right
+               // and better if result is SFR
+               if (AOP_TYPE (left) == AOP_ACC)
+                 {
+                   emitcode ("xrl", "a,%s", aopGet (AOP (right), offset,
+                                                    FALSE, FALSE, FALSE));
+                 }
+               else
+                 {
+                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+                     if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
+                     {
+                         emitcode("mov", "b,a");
+                         rOp = "b";
+                     }
+                       
+                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                     emitcode ("xrl", "a,%s", rOp);
+                 }
+             }
+           aopPut (AOP (result), "a", offset);
+         }
+       }
+       
+    }
+
+release:
+  freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genInline - write the inline code out                           */
+/*-----------------------------------------------------------------*/
+static void
+genInline (iCode * ic)
+{
+  char *buffer, *bp, *bp1;
+
+  D (emitcode (";", "genInline ");
+    );
+
+  _G.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 */
+  while (*bp)
+    {
+      if (*bp == '\n')
+       {
+         *bp++ = '\0';
+         emitcode (bp1, "");
+         bp1 = bp;
+       }
+      else
+       {
+         if (*bp == ':')
+           {
+             bp++;
+             *bp = '\0';
+             bp++;
+             emitcode (bp1, "");
+             bp1 = bp;
+           }
+         else
+           bp++;
+       }
+    }
+  if (bp1 != bp)
+    emitcode (bp1, "");
+  /*     emitcode("",buffer); */
+  _G.inLine -= (!options.asmpeep);
+}
+
+/*-----------------------------------------------------------------*/
+/* genRRC - rotate right with carry                                */
+/*-----------------------------------------------------------------*/
+static void
+genRRC (iCode * ic)
+{
+  operand *left, *result;
+  int size, offset = 0;
+  char *l;
+
+  D (emitcode (";", "genRRC ");
+    );
+
+  /* rotate right with carry */
+  left = IC_LEFT (ic);
+  result = IC_RESULT (ic);
+  aopOp (left, ic, FALSE, FALSE);
+  aopOp (result, ic, FALSE, AOP_TYPE (left) == AOP_DPTR);
+
+  /* move it to the result */
+  size = AOP_SIZE (result);
+  offset = size - 1;
+  CLRC;
+
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      l = aopGet (AOP (left), offset, FALSE, FALSE, TRUE);
+      MOVA (l);
+      emitcode ("rrc", "a");
+      if (AOP_SIZE (result) > 1)
+       aopPut (AOP (result), "a", offset--);
+    }
+  _endLazyDPSEvaluation ();
+
+  /* now we need to put the carry into the
+     highest order byte of the result */
+  if (AOP_SIZE (result) > 1)
+    {
+      l = aopGet (AOP (result), AOP_SIZE (result) - 1, FALSE, FALSE, TRUE);
+      MOVA (l);
+    }
+  emitcode ("mov", "acc.7,c");
+  aopPut (AOP (result), "a", AOP_SIZE (result) - 1);
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genRLC - generate code for rotate left with carry               */
+/*-----------------------------------------------------------------*/
+static void
+genRLC (iCode * ic)
+{
+  operand *left, *result;
+  int size, offset = 0;
+  char *l;
+
+  D (emitcode (";", "genRLC ");
+    );
+
+  /* rotate right with carry */
+  left = IC_LEFT (ic);
+  result = IC_RESULT (ic);
+  aopOp (left, ic, FALSE, FALSE);
+  aopOp (result, ic, FALSE, AOP_TYPE (left) == AOP_DPTR);
+
+  /* move it to the result */
+  size = AOP_SIZE (result);
+  offset = 0;
+  if (size--)
+    {
+      l = aopGet (AOP (left), offset, FALSE, FALSE, TRUE);
+      MOVA (l);
+      emitcode ("add", "a,acc");
+      if (AOP_SIZE (result) > 1)
+       {
+         aopPut (AOP (result), "a", offset++);
+       }
+
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         l = aopGet (AOP (left), offset, FALSE, FALSE, TRUE);
+         MOVA (l);
+         emitcode ("rlc", "a");
+         if (AOP_SIZE (result) > 1)
+           aopPut (AOP (result), "a", offset++);
+       }
+      _endLazyDPSEvaluation ();
+    }
+  /* now we need to put the carry into the
+     highest order byte of the result */
+  if (AOP_SIZE (result) > 1)
+    {
+      l = aopGet (AOP (result), 0, FALSE, FALSE, TRUE);
+      MOVA (l);
+    }
+  emitcode ("mov", "acc.0,c");
+  aopPut (AOP (result), "a", 0);
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genGetHbit - generates code get highest order bit               */
+/*-----------------------------------------------------------------*/
+static void
+genGetHbit (iCode * ic)
+{
+  operand *left, *result;
+  left = IC_LEFT (ic);
+  result = IC_RESULT (ic);
+  aopOp (left, ic, FALSE, FALSE);
+  aopOp (result, ic, FALSE, AOP_TYPE (left) == AOP_DPTR);
+
+  D (emitcode (";", "genGetHbit ");
+    );
+
+  /* get the highest order byte into a */
+  MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE, FALSE, TRUE));
+  if (AOP_TYPE (result) == AOP_CRY)
+    {
+      emitcode ("rlc", "a");
+      outBitC (result);
+    }
+  else
+    {
+      emitcode ("rl", "a");
+      emitcode ("anl", "a,#0x01");
+      outAcc (result);
+    }
+
+
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* AccRol - rotate left accumulator by known count                 */
+/*-----------------------------------------------------------------*/
+static void
+AccRol (int shCount)
+{
+  shCount &= 0x0007;           // shCount : 0..7
+
+  switch (shCount)
+    {
+    case 0:
+      break;
+    case 1:
+      emitcode ("rl", "a");
+      break;
+    case 2:
+      emitcode ("rl", "a");
+      emitcode ("rl", "a");
+      break;
+    case 3:
+      emitcode ("swap", "a");
+      emitcode ("rr", "a");
+      break;
+    case 4:
+      emitcode ("swap", "a");
+      break;
+    case 5:
+      emitcode ("swap", "a");
+      emitcode ("rl", "a");
+      break;
+    case 6:
+      emitcode ("rr", "a");
+      emitcode ("rr", "a");
+      break;
+    case 7:
+      emitcode ("rr", "a");
+      break;
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* AccLsh - left shift accumulator by known count                  */
+/*-----------------------------------------------------------------*/
+static void
+AccLsh (int shCount)
+{
+  if (shCount != 0)
+    {
+      if (shCount == 1)
+       emitcode ("add", "a,acc");
+      else if (shCount == 2)
+       {
+         emitcode ("add", "a,acc");
+         emitcode ("add", "a,acc");
+       }
+      else
+       {
+         /* rotate left accumulator */
+         AccRol (shCount);
+         /* and kill the lower order bits */
+         emitcode ("anl", "a,#0x%02x", SLMask[shCount]);
+       }
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* AccRsh - right shift accumulator by known count                 */
+/*-----------------------------------------------------------------*/
+static void
+AccRsh (int shCount)
+{
+  if (shCount != 0)
+    {
+      if (shCount == 1)
+       {
+         CLRC;
+         emitcode ("rrc", "a");
+       }
+      else
+       {
+         /* rotate right accumulator */
+         AccRol (8 - shCount);
+         /* and kill the higher order bits */
+         emitcode ("anl", "a,#0x%02x", SRMask[shCount]);
+       }
+    }
+}
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* AccSRsh - signed right shift accumulator by known count                 */
+/*-----------------------------------------------------------------*/
+static void
+AccSRsh (int shCount)
+{
+  symbol *tlbl;
+  if (shCount != 0)
+    {
+      if (shCount == 1)
+       {
+         emitcode ("mov", "c,acc.7");
+         emitcode ("rrc", "a");
+       }
+      else if (shCount == 2)
+       {
+         emitcode ("mov", "c,acc.7");
+         emitcode ("rrc", "a");
+         emitcode ("mov", "c,acc.7");
+         emitcode ("rrc", "a");
+       }
+      else
+       {
+         tlbl = newiTempLabel (NULL);
+         /* rotate right accumulator */
+         AccRol (8 - shCount);
+         /* and kill the higher order bits */
+         emitcode ("anl", "a,#0x%02x", SRMask[shCount]);
+         emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
+         emitcode ("orl", "a,#0x%02x",
+                   (unsigned char) ~SRMask[shCount]);
+         emitcode ("", "%05d$:", tlbl->key + 100);
+       }
+    }
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* shiftR1Left2Result - shift right one byte from left to result   */
+/*-----------------------------------------------------------------*/
+static void
+shiftR1Left2Result (operand * left, int offl,
+                   operand * result, int offr,
+                   int shCount, int sign)
+{
+  MOVA (aopGet (AOP (left), offl, FALSE, FALSE, TRUE));
+  /* shift right accumulator */
+  if (sign)
+    AccSRsh (shCount);
+  else
+    AccRsh (shCount);
+  aopPut (AOP (result), "a", offr);
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* shiftL1Left2Result - shift left one byte from left to result    */
+/*-----------------------------------------------------------------*/
+static void
+shiftL1Left2Result (operand * left, int offl,
+                   operand * result, int offr, int shCount)
+{
+  MOVA(aopGet (AOP (left), offl, FALSE, FALSE, TRUE));
+  /* shift left accumulator */
+  AccLsh (shCount);
+  aopPut (AOP (result), "a", offr);
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* movLeft2Result - move byte from left to result                  */
+/*-----------------------------------------------------------------*/
+static void
+movLeft2Result (operand * left, int offl,
+               operand * result, int offr, int sign)
+{
+  char *l;
+  if (!sameRegs (AOP (left), AOP (result)) || (offl != offr))
+  {
+      l = aopGet (AOP (left), offl, FALSE, FALSE, TRUE);
+
+      if (*l == '@' && (IS_AOP_PREG (result)))
+      {
+         emitcode ("mov", "a,%s", l);
+         aopPut (AOP (result), "a", offr);
+      }
+      else
+      {
+         if (!sign)
+         {
+           aopPut (AOP (result), l, offr);
+         }
+         else
+           {
+             /* MSB sign in acc.7 ! */
+             if (getDataSize (left) == offl + 1)
+               {
+                 emitcode ("mov", "a,%s", l);
+                 aopPut (AOP (result), "a", offr);
+               }
+           }
+      }
+  }
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* AccAXRrl1 - right rotate c->a:x->c by 1                         */
+/*-----------------------------------------------------------------*/
+static void
+AccAXRrl1 (char *x)
+{
+  emitcode ("rrc", "a");
+  emitcode ("xch", "a,%s", x);
+  emitcode ("rrc", "a");
+  emitcode ("xch", "a,%s", x);
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+//REMOVE ME!!!
+/*-----------------------------------------------------------------*/
+/* AccAXLrl1 - left rotate c<-a:x<-c by 1                          */
+/*-----------------------------------------------------------------*/
+static void
+AccAXLrl1 (char *x)
+{
+  emitcode ("xch", "a,%s", x);
+  emitcode ("rlc", "a");
+  emitcode ("xch", "a,%s", x);
+  emitcode ("rlc", "a");
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* AccAXLsh1 - left shift a:x<-0 by 1                              */
+/*-----------------------------------------------------------------*/
+static void
+AccAXLsh1 (char *x)
+{
+  emitcode ("xch", "a,%s", x);
+  emitcode ("add", "a,acc");
+  emitcode ("xch", "a,%s", x);
+  emitcode ("rlc", "a");
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* AccAXLsh - left shift a:x by known count (0..7)                 */
+/*-----------------------------------------------------------------*/
+static void
+AccAXLsh (char *x, int shCount)
+{
+  switch (shCount)
+    {
+    case 0:
+      break;
+    case 1:
+      AccAXLsh1 (x);
+      break;
+    case 2:
+      AccAXLsh1 (x);
+      AccAXLsh1 (x);
+      break;
+    case 3:
+    case 4:
+    case 5:                    // AAAAABBB:CCCCCDDD
+
+      AccRol (shCount);                // BBBAAAAA:CCCCCDDD
+
+      emitcode ("anl", "a,#0x%02x",
+               SLMask[shCount]);       // BBB00000:CCCCCDDD
+
+      emitcode ("xch", "a,%s", x);     // CCCCCDDD:BBB00000
+
+      AccRol (shCount);                // DDDCCCCC:BBB00000
+
+      emitcode ("xch", "a,%s", x);     // BBB00000:DDDCCCCC
+
+      emitcode ("xrl", "a,%s", x);     // (BBB^DDD)CCCCC:DDDCCCCC
+
+      emitcode ("xch", "a,%s", x);     // DDDCCCCC:(BBB^DDD)CCCCC
+
+      emitcode ("anl", "a,#0x%02x",
+               SLMask[shCount]);       // DDD00000:(BBB^DDD)CCCCC
+
+      emitcode ("xch", "a,%s", x);     // (BBB^DDD)CCCCC:DDD00000
+
+      emitcode ("xrl", "a,%s", x);     // BBBCCCCC:DDD00000
+
+      break;
+    case 6:                    // AAAAAABB:CCCCCCDD
+      emitcode ("anl", "a,#0x%02x",
+               SRMask[shCount]);       // 000000BB:CCCCCCDD
+      emitcode ("mov", "c,acc.0");     // c = B
+      emitcode ("xch", "a,%s", x);     // CCCCCCDD:000000BB
+#if 0
+      AccAXRrl1 (x);           // BCCCCCCD:D000000B
+      AccAXRrl1 (x);           // BBCCCCCC:DD000000
+#else
+      emitcode("rrc","a"); 
+      emitcode("xch","a,%s", x); 
+      emitcode("rrc","a"); 
+      emitcode("mov","c,acc.0"); //<< get correct bit 
+      emitcode("xch","a,%s", x); 
+
+      emitcode("rrc","a"); 
+      emitcode("xch","a,%s", x); 
+      emitcode("rrc","a"); 
+      emitcode("xch","a,%s", x); 
+#endif
+      break;
+    case 7:                    // a:x <<= 7
+
+      emitcode ("anl", "a,#0x%02x",
+               SRMask[shCount]);       // 0000000B:CCCCCCCD
+
+      emitcode ("mov", "c,acc.0");     // c = B
+
+      emitcode ("xch", "a,%s", x);     // CCCCCCCD:0000000B
+
+      AccAXRrl1 (x);           // BCCCCCCC:D0000000
+
+      break;
+    default:
+      break;
+    }
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+//REMOVE ME!!!
+/*-----------------------------------------------------------------*/
+/* AccAXRsh - right shift a:x known count (0..7)                   */
+/*-----------------------------------------------------------------*/
+static void
+AccAXRsh (char *x, int shCount)
+{
+  switch (shCount)
+    {
+    case 0:
+      break;
+    case 1:
+      CLRC;
+      AccAXRrl1 (x);           // 0->a:x
+
+      break;
+    case 2:
+      CLRC;
+      AccAXRrl1 (x);           // 0->a:x
+
+      CLRC;
+      AccAXRrl1 (x);           // 0->a:x
+
+      break;
+    case 3:
+    case 4:
+    case 5:                    // AAAAABBB:CCCCCDDD = a:x
+
+      AccRol (8 - shCount);    // BBBAAAAA:DDDCCCCC
+
+      emitcode ("xch", "a,%s", x);     // CCCCCDDD:BBBAAAAA
+
+      AccRol (8 - shCount);    // DDDCCCCC:BBBAAAAA
+
+      emitcode ("anl", "a,#0x%02x",
+               SRMask[shCount]);       // 000CCCCC:BBBAAAAA
+
+      emitcode ("xrl", "a,%s", x);     // BBB(CCCCC^AAAAA):BBBAAAAA
+
+      emitcode ("xch", "a,%s", x);     // BBBAAAAA:BBB(CCCCC^AAAAA)
+
+      emitcode ("anl", "a,#0x%02x",
+               SRMask[shCount]);       // 000AAAAA:BBB(CCCCC^AAAAA)
+
+      emitcode ("xch", "a,%s", x);     // BBB(CCCCC^AAAAA):000AAAAA
+
+      emitcode ("xrl", "a,%s", x);     // BBBCCCCC:000AAAAA
+
+      emitcode ("xch", "a,%s", x);     // 000AAAAA:BBBCCCCC
+
+      break;
+    case 6:                    // AABBBBBB:CCDDDDDD
+
+      emitcode ("mov", "c,acc.7");
+      AccAXLrl1 (x);           // ABBBBBBC:CDDDDDDA
+
+      AccAXLrl1 (x);           // BBBBBBCC:DDDDDDAA
+
+      emitcode ("xch", "a,%s", x);     // DDDDDDAA:BBBBBBCC
+
+      emitcode ("anl", "a,#0x%02x",
+               SRMask[shCount]);       // 000000AA:BBBBBBCC
+
+      break;
+    case 7:                    // ABBBBBBB:CDDDDDDD
+
+      emitcode ("mov", "c,acc.7");     // c = A
+
+      AccAXLrl1 (x);           // BBBBBBBC:DDDDDDDA
+
+      emitcode ("xch", "a,%s", x);     // DDDDDDDA:BBBBBBCC
+
+      emitcode ("anl", "a,#0x%02x",
+               SRMask[shCount]);       // 0000000A:BBBBBBBC
+
+      break;
+    default:
+      break;
+    }
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* AccAXRshS - right shift signed a:x known count (0..7)           */
+/*-----------------------------------------------------------------*/
+static void
+AccAXRshS (char *x, int shCount)
+{
+  symbol *tlbl;
+  switch (shCount)
+    {
+    case 0:
+      break;
+    case 1:
+      emitcode ("mov", "c,acc.7");
+      AccAXRrl1 (x);           // s->a:x
+
+      break;
+    case 2:
+      emitcode ("mov", "c,acc.7");
+      AccAXRrl1 (x);           // s->a:x
+
+      emitcode ("mov", "c,acc.7");
+      AccAXRrl1 (x);           // s->a:x
+
+      break;
+    case 3:
+    case 4:
+    case 5:                    // AAAAABBB:CCCCCDDD = a:x
+
+      tlbl = newiTempLabel (NULL);
+      AccRol (8 - shCount);    // BBBAAAAA:CCCCCDDD
+
+      emitcode ("xch", "a,%s", x);     // CCCCCDDD:BBBAAAAA
+
+      AccRol (8 - shCount);    // DDDCCCCC:BBBAAAAA
+
+      emitcode ("anl", "a,#0x%02x",
+               SRMask[shCount]);       // 000CCCCC:BBBAAAAA
+
+      emitcode ("xrl", "a,%s", x);     // BBB(CCCCC^AAAAA):BBBAAAAA
+
+      emitcode ("xch", "a,%s", x);     // BBBAAAAA:BBB(CCCCC^AAAAA)
+
+      emitcode ("anl", "a,#0x%02x",
+               SRMask[shCount]);       // 000AAAAA:BBB(CCCCC^AAAAA)
+
+      emitcode ("xch", "a,%s", x);     // BBB(CCCCC^AAAAA):000AAAAA
+
+      emitcode ("xrl", "a,%s", x);     // BBBCCCCC:000AAAAA
+
+      emitcode ("xch", "a,%s", x);     // 000SAAAA:BBBCCCCC
+
+      emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
+      emitcode ("orl", "a,#0x%02x",
+               (unsigned char) ~SRMask[shCount]);      // 111AAAAA:BBBCCCCC
+
+      emitcode ("", "%05d$:", tlbl->key + 100);
+      break;                   // SSSSAAAA:BBBCCCCC
+
+    case 6:                    // AABBBBBB:CCDDDDDD
+
+      tlbl = newiTempLabel (NULL);
+      emitcode ("mov", "c,acc.7");
+      AccAXLrl1 (x);           // ABBBBBBC:CDDDDDDA
+
+      AccAXLrl1 (x);           // BBBBBBCC:DDDDDDAA
+
+      emitcode ("xch", "a,%s", x);     // DDDDDDAA:BBBBBBCC
+
+      emitcode ("anl", "a,#0x%02x",
+               SRMask[shCount]);       // 000000AA:BBBBBBCC
+
+      emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
+      emitcode ("orl", "a,#0x%02x",
+               (unsigned char) ~SRMask[shCount]);      // 111111AA:BBBBBBCC
+
+      emitcode ("", "%05d$:", tlbl->key + 100);
+      break;
+    case 7:                    // ABBBBBBB:CDDDDDDD
+
+      tlbl = newiTempLabel (NULL);
+      emitcode ("mov", "c,acc.7");     // c = A
+
+      AccAXLrl1 (x);           // BBBBBBBC:DDDDDDDA
+
+      emitcode ("xch", "a,%s", x);     // DDDDDDDA:BBBBBBCC
+
+      emitcode ("anl", "a,#0x%02x",
+               SRMask[shCount]);       // 0000000A:BBBBBBBC
+
+      emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
+      emitcode ("orl", "a,#0x%02x",
+               (unsigned char) ~SRMask[shCount]);      // 1111111A:BBBBBBBC
+
+      emitcode ("", "%05d$:", tlbl->key + 100);
+      break;
+    default:
+      break;
+    }
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+static void
+_loadLeftIntoAx(char   **lsb, 
+               operand *left, 
+               operand *result,
+               int     offl,
+               int     offr)
+{
+  // Get the initial value from left into a pair of registers.
+  // MSB must be in A, LSB can be any register.
+  //
+  // If the result is held in registers, it is an optimization
+  // if the LSB can be held in the register which will hold the,
+  // result LSB since this saves us from having to copy it into
+  // the result following AccAXLsh.
+  //
+  // If the result is addressed indirectly, this is not a gain.
+  if (AOP_NEEDSACC(result))
+  {
+       char *leftByte;
+       
+       _startLazyDPSEvaluation();
+      if (AOP_TYPE(left) == AOP_DPTR2)
+       {
+           // Get MSB in A.
+                  MOVA(aopGet(AOP(left), offl + MSB16, FALSE, FALSE, TRUE));
+                  // get LSB in DP2_RESULT_REG.
+                  leftByte = aopGet(AOP(left), offl, FALSE, FALSE, FALSE);
+                  assert(!strcmp(leftByte, DP2_RESULT_REG));
+       }
+       else
+       {
+           // get LSB into DP2_RESULT_REG
+                  leftByte = aopGet (AOP(left), offl, FALSE, FALSE, TRUE);
+           if (strcmp(leftByte, DP2_RESULT_REG))
+           {
+               TR_AP("#7");
+               emitcode("mov","%s,%s", DP2_RESULT_REG, leftByte);
+                  }
+                  // And MSB in A.
+                  leftByte = aopGet(AOP(left), offl + MSB16, FALSE, FALSE, TRUE);
+                  assert(strcmp(leftByte, DP2_RESULT_REG));
+                  MOVA(leftByte);
+       }
+       _endLazyDPSEvaluation();
+       *lsb = DP2_RESULT_REG;
+  }
+  else
+  {
+      if (sameRegs (AOP (result), AOP (left)) &&
+       ((offl + MSB16) == offr))
+      {
+         /* don't crash result[offr] */
+         MOVA(aopGet(AOP(left), offl, FALSE, FALSE, TRUE));
+         emitcode ("xch", "a,%s", 
+                   aopGet(AOP(left), offl + MSB16, FALSE, FALSE, FALSE));
+      }
+      else
+      {
+         movLeft2Result (left, offl, result, offr, 0);
+         MOVA (aopGet (AOP (left), offl + MSB16, FALSE, FALSE, TRUE));
+      }
+      *lsb = aopGet(AOP (result), offr, FALSE, FALSE, FALSE);
+      assert(strcmp(*lsb,"a"));      
+  }
+}
+
+static void
+_storeAxResults(char   *lsb,
+               operand *result,
+               int     offr)
+{
+  _startLazyDPSEvaluation();
+  if (AOP_NEEDSACC(result))
+  {
+      /* We have to explicitly update the result LSB.
+       */
+      emitcode("xch","a,%s", lsb);
+      aopPut(AOP(result), "a", offr);
+      emitcode("mov","a,%s", lsb);
+  }
+  if (getDataSize (result) > 1)
+  {
+      aopPut (AOP (result), "a", offr + MSB16);
+  }
+  _endLazyDPSEvaluation();
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftL2Left2Result - shift left two bytes from left to result   */
+/*-----------------------------------------------------------------*/
+static void
+shiftL2Left2Result (operand * left, int offl,
+                   operand * result, int offr, int shCount)
+{
+  char *lsb;
+
+  _loadLeftIntoAx(&lsb, left, result, offl, offr);
+  
+  AccAXLsh (lsb, shCount);
+  
+  _storeAxResults(lsb, result, offr);
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* shiftR2Left2Result - shift right two bytes from left to result  */
+/*-----------------------------------------------------------------*/
+static void
+shiftR2Left2Result (operand * left, int offl,
+                   operand * result, int offr,
+                   int shCount, int sign)
+{
+  char *lsb;
+  
+  _loadLeftIntoAx(&lsb, left, result, offl, offr);
+  
+  /* a:x >> shCount (x = lsb(result)) */
+  if (sign)
+  {
+     AccAXRshS(lsb, shCount);
+  }
+  else
+  {
+    AccAXRsh(lsb, shCount);
+  }
+  
+  _storeAxResults(lsb, result, offr);
+}
+#endif
+
+#if 0
+//REMOVE ME!!!
+/*-----------------------------------------------------------------*/
+/* shiftLLeftOrResult - shift left one byte from left, or to result */
+/*-----------------------------------------------------------------*/
+static void
+shiftLLeftOrResult (operand * left, int offl,
+                   operand * result, int offr, int shCount)
+{
+  MOVA (aopGet (AOP (left), offl, FALSE, FALSE, TRUE));
+  /* shift left accumulator */
+  AccLsh (shCount);
+  /* or with result */
+  emitcode ("orl", "a,%s", aopGet (AOP (result), offr, FALSE, FALSE, FALSE));
+  /* back to result */
+  aopPut (AOP (result), "a", offr);
+}
+#endif
+
+#if 0
+//REMOVE ME!!!
+/*-----------------------------------------------------------------*/
+/* shiftRLeftOrResult - shift right one byte from left,or to result */
+/*-----------------------------------------------------------------*/
+static void
+shiftRLeftOrResult (operand * left, int offl,
+                   operand * result, int offr, int shCount)
+{
+  MOVA (aopGet (AOP (left), offl, FALSE, FALSE, TRUE));
+  /* shift right accumulator */
+  AccRsh (shCount);
+  /* or with result */
+  emitcode ("orl", "a,%s", aopGet (AOP (result), offr, FALSE, FALSE, FALSE));
+  /* back to result */
+  aopPut (AOP (result), "a", offr);
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* genlshOne - left shift a one byte quantity by known count       */
+/*-----------------------------------------------------------------*/
+static void
+genlshOne (operand * result, operand * left, int shCount)
+{
+  D (emitcode (";", "genlshOne "););
+  shiftL1Left2Result (left, LSB, result, LSB, shCount);
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* genlshTwo - left shift two bytes by known amount != 0           */
+/*-----------------------------------------------------------------*/
+static void
+genlshTwo (operand * result, operand * left, int shCount)
+{
+  int size;
+
+  D (emitcode (";", "genlshTwo "););
+
+  size = getDataSize (result);
+
+  /* if shCount >= 8 */
+  if (shCount >= 8)
+  {
+      shCount -= 8;
+
+      _startLazyDPSEvaluation();
+
+      if (size > 1)
+       {
+         if (shCount)
+         {
+           _endLazyDPSEvaluation();
+           shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+           aopPut (AOP (result), zero, LSB);       
+         }
+         else
+         {
+           movLeft2Result (left, LSB, result, MSB16, 0);
+           aopPut (AOP (result), zero, LSB);
+           _endLazyDPSEvaluation();
+         }
+       }
+       else
+       {
+         aopPut (AOP (result), zero, LSB);
+         _endLazyDPSEvaluation();
+       }
+  }
+
+  /*  1 <= shCount <= 7 */
+  else
+    {
+      if (size == 1)
+      {
+       shiftL1Left2Result (left, LSB, result, LSB, shCount);
+      }
+      else
+      {
+       shiftL2Left2Result (left, LSB, result, LSB, shCount);
+      }
+    }
+}
+#endif
+
+#if 0
+//REMOVE ME!!!
+/*-----------------------------------------------------------------*/
+/* shiftLLong - shift left one long from left to result            */
+/* offl = LSB or MSB16                                             */
+/*-----------------------------------------------------------------*/
+static void
+shiftLLong (operand * left, operand * result, int offr)
+{
+  char *l;
+  int size = AOP_SIZE (result);
+
+  if (size >= LSB + offr)
+    {
+      l = aopGet (AOP (left), LSB, FALSE, FALSE, TRUE);
+      MOVA (l);
+      emitcode ("add", "a,acc");
+      if (sameRegs (AOP (left), AOP (result)) &&
+         size >= MSB16 + offr && offr != LSB)
+       emitcode ("xch", "a,%s",
+                 aopGet (AOP (left), LSB + offr, FALSE, FALSE, FALSE));
+      else
+       aopPut (AOP (result), "a", LSB + offr);
+    }
+
+  if (size >= MSB16 + offr)
+    {
+      if (!(sameRegs (AOP (result), AOP (left)) && size >= MSB16 + offr && offr != LSB))
+       {
+         l = aopGet (AOP (left), MSB16, FALSE, FALSE, TRUE);
+         MOVA (l);
+       }
+      emitcode ("rlc", "a");
+      if (sameRegs (AOP (left), AOP (result)) &&
+         size >= MSB24 + offr && offr != LSB)
+       emitcode ("xch", "a,%s",
+                 aopGet (AOP (left), MSB16 + offr, FALSE, FALSE, FALSE));
+      else
+       aopPut (AOP (result), "a", MSB16 + offr);
+    }
+
+  if (size >= MSB24 + offr)
+    {
+      if (!(sameRegs (AOP (left), AOP (left)) && size >= MSB24 + offr && offr != LSB))
+       {
+         l = aopGet (AOP (left), MSB24, FALSE, FALSE, TRUE);
+         MOVA (l);
+       }
+      emitcode ("rlc", "a");
+      if (sameRegs (AOP (left), AOP (result)) &&
+         size >= MSB32 + offr && offr != LSB)
+       emitcode ("xch", "a,%s",
+                 aopGet (AOP (left), MSB24 + offr, FALSE, FALSE, FALSE));
+      else
+       aopPut (AOP (result), "a", MSB24 + offr);
+    }
+
+  if (size > MSB32 + offr)
+    {
+      if (!(sameRegs (AOP (result), AOP (left)) && size >= MSB32 + offr && offr != LSB))
+       {
+         l = aopGet (AOP (left), MSB32, FALSE, FALSE, TRUE);
+         MOVA (l);
+       }
+      emitcode ("rlc", "a");
+      aopPut (AOP (result), "a", MSB32 + offr);
+    }
+  if (offr != LSB)
+    aopPut (AOP (result), zero, LSB);
+}
+#endif
+
+#if 0
+//REMOVE ME!!!
+/*-----------------------------------------------------------------*/
+/* genlshFour - shift four byte by a known amount != 0             */
+/*-----------------------------------------------------------------*/
+static void
+genlshFour (operand * result, operand * left, int shCount)
+{
+  int size;
+
+  D (emitcode (";", "genlshFour ");
+    );
+
+  size = AOP_SIZE (result);
+
+  /* if shifting more that 3 bytes */
+  if (shCount >= 24)
+    {
+      shCount -= 24;
+      if (shCount)
+       /* lowest order of left goes to the highest
+          order of the destination */
+       shiftL1Left2Result (left, LSB, result, MSB32, shCount);
+      else
+       movLeft2Result (left, LSB, result, MSB32, 0);
+      aopPut (AOP (result), zero, LSB);
+      aopPut (AOP (result), zero, MSB16);
+      aopPut (AOP (result), zero, MSB24);
+      return;
+    }
+
+  /* more than two bytes */
+  else if (shCount >= 16)
+    {
+      /* lower order two bytes goes to higher order two bytes */
+      shCount -= 16;
+      /* if some more remaining */
+      if (shCount)
+       shiftL2Left2Result (left, LSB, result, MSB24, shCount);
+      else
+       {
+         movLeft2Result (left, MSB16, result, MSB32, 0);
+         movLeft2Result (left, LSB, result, MSB24, 0);
+       }
+      aopPut (AOP (result), zero, MSB16);
+      aopPut (AOP (result), zero, LSB);
+      return;
+    }
+
+  /* if more than 1 byte */
+  else if (shCount >= 8)
+    {
+      /* lower order three bytes goes to higher order  three bytes */
+      shCount -= 8;
+      if (size == 2)
+       {
+         if (shCount)
+           shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+         else
+           movLeft2Result (left, LSB, result, MSB16, 0);
+       }
+      else
+       {                       /* size = 4 */
+         if (shCount == 0)
+           {
+             movLeft2Result (left, MSB24, result, MSB32, 0);
+             movLeft2Result (left, MSB16, result, MSB24, 0);
+             movLeft2Result (left, LSB, result, MSB16, 0);
+             aopPut (AOP (result), zero, LSB);
+           }
+         else if (shCount == 1)
+           shiftLLong (left, result, MSB16);
+         else
+           {
+             shiftL2Left2Result (left, MSB16, result, MSB24, shCount);
+             shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+             shiftRLeftOrResult (left, LSB, result, MSB24, 8 - shCount);
+             aopPut (AOP (result), zero, LSB);
+           }
+       }
+    }
+
+  /* 1 <= shCount <= 7 */
+  else if (shCount <= 2)
+    {
+      shiftLLong (left, result, LSB);
+      if (shCount == 2)
+       shiftLLong (result, result, LSB);
+    }
+  /* 3 <= shCount <= 7, optimize */
+  else
+    {
+      shiftL2Left2Result (left, MSB24, result, MSB24, shCount);
+      shiftRLeftOrResult (left, MSB16, result, MSB24, 8 - shCount);
+      shiftL2Left2Result (left, LSB, result, LSB, shCount);
+    }
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* genLeftShiftLiteral - left shifting by known count              */
+/*-----------------------------------------------------------------*/
+static bool
+genLeftShiftLiteral (operand * left,
+                    operand * right,
+                    operand * result,
+                    iCode * ic)
+{
+  int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+  int size;
+
+  size = getSize (operandType (result));
+
+  D(emitcode (";", "genLeftShiftLiteral (%d), size %d", shCount, size););
+
+  /* We only handle certain easy cases so far. */
+  if ((shCount != 0)
+   && (shCount < (size * 8))
+   && (size != 1)
+   && (size != 2))
+  {
+      D(emitcode (";", "genLeftShiftLiteral wimping out"););   
+      return FALSE;
+  }
+
+  freeAsmop (right, NULL, ic, TRUE);
+
+  aopOp(left, ic, FALSE, FALSE);
+  aopOp(result, ic, FALSE, (AOP_TYPE(left) == AOP_DPTR));
+
+#if 1 // debug spew
+  if (IS_SYMOP(left) && OP_SYMBOL(left)->aop)
+  {
+       emitcode(";", "left (%s) is %d", OP_SYMBOL(left)->rname, AOP_TYPE(left));
+       if (!IS_TRUE_SYMOP(left) && OP_SYMBOL(left)->usl.spillLoc)
+       {
+          emitcode(";", "\taka %s", OP_SYMBOL(left)->usl.spillLoc->rname);
+       }
+  }
+  if (IS_SYMOP(result) && OP_SYMBOL(result)->aop)
+  {
+       emitcode(";", "result (%s) is %d", OP_SYMBOL(result)->rname, AOP_TYPE(result));
+       if (!IS_TRUE_SYMOP(result) && OP_SYMBOL(result)->usl.spillLoc)
+       {
+          emitcode(";", "\taka %s", OP_SYMBOL(result)->usl.spillLoc->rname);
+       }       
+  }  
+#endif
+  
+#if VIEW_SIZE
+  emitcode ("; shift left ", "result %d, left %d", size,
+           AOP_SIZE (left));
+#endif
+
+  /* I suppose that the left size >= result size */
+  if (shCount == 0)
+  {
+       _startLazyDPSEvaluation();
+       while (size--)
+       {
+         movLeft2Result (left, size, result, size, 0);
+       }
+       _endLazyDPSEvaluation();
+  }
+  else if (shCount >= (size * 8))
+  {
+    _startLazyDPSEvaluation();
+    while (size--)
+    {
+      aopPut (AOP (result), zero, size);
+    }
+    _endLazyDPSEvaluation();
+  }
+  else
+  {
+      switch (size)
+       {
+       case 1:
+         genlshOne (result, left, shCount);
+         break;
+
+       case 2:
+         genlshTwo (result, left, shCount);
+         break;
+#if 0
+       case 4:
+         genlshFour (result, left, shCount);
+         break;
+#endif
+       default:
+         fprintf(stderr, "*** ack! mystery literal shift!\n");   
+         break;
+       }
+    }
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+  return TRUE;
+}
+#endif
+
+/*-----------------------------------------------------------------*/
+/* genLeftShift - generates code for left shifting                 */
+/*-----------------------------------------------------------------*/
+static void
+genLeftShift (iCode * ic)
+{
+  operand *left, *right, *result;
+  int size, offset;
+  char *l;
+  symbol *tlbl, *tlbl1;
+
+  D (emitcode (";", "genLeftShift "););
+
+  right = IC_RIGHT (ic);
+  left = IC_LEFT (ic);
+  result = IC_RESULT (ic);
+
+  aopOp (right, ic, FALSE, FALSE);
+
+
+#ifdef BETTER_LITERAL_SHIFT
+  /* if the shift count is known then do it
+     as efficiently as possible */
+  if (AOP_TYPE (right) == AOP_LIT)
+    {
+      if (genLeftShiftLiteral (left, right, result, ic))
+      {
+       return;
+      }
+    }
+#endif
+
+  /* shift count is unknown then we have to form
+     a loop get the loop 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 ) */
+
+  if (AOP_TYPE (right) == AOP_LIT)
+  {
+      /* Really should be handled by genLeftShiftLiteral,
+       * but since I'm too lazy to fix that today, at least we can make
+       * some small improvement.
+       */
+       emitcode("mov", "b,#0x%02x",
+                       ((int) floatFromVal (AOP (right)->aopu.aop_lit)) + 1);
+  }
+  else
+  {
+       emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, FALSE));
+       emitcode ("inc", "b");
+  }
+  freeAsmop (right, NULL, ic, TRUE);
+  aopOp (left, ic, FALSE, FALSE);
+  aopOp (result, ic, FALSE, AOP_TYPE (left) == AOP_DPTR);
+
+  /* now move the left to the result if they are not the
+     same */
+  if (!sameRegs (AOP (left), AOP (result)) &&
+      AOP_SIZE (result) > 1)
+    {
+
+      size = AOP_SIZE (result);
+      offset = 0;
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         l = aopGet (AOP (left), offset, FALSE, TRUE, FALSE);
+         if (*l == '@' && (IS_AOP_PREG (result)))
+           {
+
+             emitcode ("mov", "a,%s", l);
+             aopPut (AOP (result), "a", offset);
+           }
+         else
+           aopPut (AOP (result), l, offset);
+         offset++;
+       }
+      _endLazyDPSEvaluation ();
+    }
+
+  tlbl = newiTempLabel (NULL);
+  size = AOP_SIZE (result);
+  offset = 0;
+  tlbl1 = newiTempLabel (NULL);
+
+  /* if it is only one byte then */
+  if (size == 1)
+    {
+      symbol *tlbl1 = newiTempLabel (NULL);
+
+      l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
+      MOVA (l);
+      emitcode ("sjmp", "%05d$", tlbl1->key + 100);
+      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("add", "a,acc");
+      emitcode ("", "%05d$:", tlbl1->key + 100);
+      emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+      aopPut (AOP (result), "a", 0);
+      goto release;
+    }
+
+  reAdjustPreg (AOP (result));
+
+  emitcode ("sjmp", "%05d$", tlbl1->key + 100);
+  emitcode ("", "%05d$:", tlbl->key + 100);
+  l = aopGet (AOP (result), offset, FALSE, FALSE, TRUE);
+  MOVA (l);
+  emitcode ("add", "a,acc");
+  aopPut (AOP (result), "a", offset++);
+  _startLazyDPSEvaluation ();
+  while (--size)
+    {
+      l = aopGet (AOP (result), offset, FALSE, FALSE, TRUE);
+      MOVA (l);
+      emitcode ("rlc", "a");
+      aopPut (AOP (result), "a", offset++);
+    }
+  _endLazyDPSEvaluation ();
+  reAdjustPreg (AOP (result));
+
+  emitcode ("", "%05d$:", tlbl1->key + 100);
+  emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+release:
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* genrshOne - right shift a one byte quantity by known count      */
+/*-----------------------------------------------------------------*/
+static void
+genrshOne (operand * result, operand * left,
+          int shCount, int sign)
+{
+  D (emitcode (";", "genrshOne"););
+  shiftR1Left2Result (left, LSB, result, LSB, shCount, sign);
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* genrshTwo - right shift two bytes by known amount != 0          */
+/*-----------------------------------------------------------------*/
+static void
+genrshTwo (operand * result, operand * left,
+          int shCount, int sign)
+{
+  D (emitcode (";", "genrshTwo"););
+
+  /* if shCount >= 8 */
+  if (shCount >= 8)
+    {
+      shCount -= 8;
+      _startLazyDPSEvaluation();
+      if (shCount)
+      {
+       shiftR1Left2Result (left, MSB16, result, LSB,
+                           shCount, sign);
+      }                            
+      else
+      {
+       movLeft2Result (left, MSB16, result, LSB, sign);
+      }
+      addSign (result, MSB16, sign);
+      _endLazyDPSEvaluation();
+    }
+
+  /*  1 <= shCount <= 7 */
+  else
+  {
+    shiftR2Left2Result (left, LSB, result, LSB, shCount, sign);
+  }
+}
+#endif
+
+#if 0
+//REMOVE ME!!!
+/*-----------------------------------------------------------------*/
+/* shiftRLong - shift right one long from left to result           */
+/* offl = LSB or MSB16                                             */
+/*-----------------------------------------------------------------*/
+static void
+shiftRLong (operand * left, int offl,
+           operand * result, int sign)
+{
+  int isSameRegs=sameRegs(AOP(left),AOP(result));
+
+  if (isSameRegs && offl>1) {
+    // we are in big trouble, but this shouldn't happen
+    werror(E_INTERNAL_ERROR, __FILE__, __LINE__);
+  }
+
+  MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE));
+  
+  if (offl==MSB16) {
+    // shift is > 8
+    if (sign) {
+      emitcode ("rlc", "a");
+      emitcode ("subb", "a,acc");
+      emitcode ("xch", "a,%s", aopGet(AOP(left), MSB32, FALSE, FALSE));
+    } else {
+      aopPut (AOP(result), zero, MSB32);
+    }
+  }
+
+  if (!sign) {
+    emitcode ("clr", "c");
+  } else {
+    emitcode ("mov", "c,acc.7");
+  }
+
+  emitcode ("rrc", "a");
+
+  if (isSameRegs && offl==MSB16) {
+    emitcode ("xch", "a,%s",aopGet (AOP (left), MSB24, FALSE, FALSE));
+  } else {
+    aopPut (AOP (result), "a", MSB32);
+    MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE));
+  }
+
+  emitcode ("rrc", "a");
+  if (isSameRegs && offl==1) {
+    emitcode ("xch", "a,%s",aopGet (AOP (left), MSB16, FALSE, FALSE));
+  } else {
+    aopPut (AOP (result), "a", MSB24);
+    MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE));
+  }
+  emitcode ("rrc", "a");
+  aopPut (AOP (result), "a", MSB16 - offl);
+
+  if (offl == LSB)
+    {
+      MOVA (aopGet (AOP (left), LSB, FALSE, FALSE));
+      emitcode ("rrc", "a");
+      aopPut (AOP (result), "a", LSB);
+    }
+}
+#endif
+
+#if 0
+//REMOVE ME!!!
+/*-----------------------------------------------------------------*/
+/* genrshFour - shift four byte by a known amount != 0             */
+/*-----------------------------------------------------------------*/
+static void
+genrshFour (operand * result, operand * left,
+           int shCount, int sign)
+{
+  D (emitcode (";", "genrshFour");
+    );
+
+  /* if shifting more that 3 bytes */
+  if (shCount >= 24)
+    {
+      shCount -= 24;
+      if (shCount)
+       shiftR1Left2Result (left, MSB32, result, LSB, shCount, sign);
+      else
+       movLeft2Result (left, MSB32, result, LSB, sign);
+      addSign (result, MSB16, sign);
+    }
+  else if (shCount >= 16)
+    {
+      shCount -= 16;
+      if (shCount)
+       shiftR2Left2Result (left, MSB24, result, LSB, shCount, sign);
+      else
+       {
+         movLeft2Result (left, MSB24, result, LSB, 0);
+         movLeft2Result (left, MSB32, result, MSB16, sign);
+       }
+      addSign (result, MSB24, sign);
+    }
+  else if (shCount >= 8)
+    {
+      shCount -= 8;
+      if (shCount == 1)
+       shiftRLong (left, MSB16, result, sign);
+      else if (shCount == 0)
+       {
+         movLeft2Result (left, MSB16, result, LSB, 0);
+         movLeft2Result (left, MSB24, result, MSB16, 0);
+         movLeft2Result (left, MSB32, result, MSB24, sign);
+         addSign (result, MSB32, sign);
+       }
+      else
+       {
+         shiftR2Left2Result (left, MSB16, result, LSB, shCount, 0);
+         shiftLLeftOrResult (left, MSB32, result, MSB16, 8 - shCount);
+         /* the last shift is signed */
+         shiftR1Left2Result (left, MSB32, result, MSB24, shCount, sign);
+         addSign (result, MSB32, sign);
+       }
+    }
+  else
+    {                          /* 1 <= shCount <= 7 */
+      if (shCount <= 2)
+       {
+         shiftRLong (left, LSB, result, sign);
+         if (shCount == 2)
+           shiftRLong (result, LSB, result, sign);
+       }
+      else
+       {
+         shiftR2Left2Result (left, LSB, result, LSB, shCount, 0);
+         shiftLLeftOrResult (left, MSB24, result, MSB16, 8 - shCount);
+         shiftR2Left2Result (left, MSB24, result, MSB24, shCount, sign);
+       }
+    }
+}
+#endif
+
+#ifdef BETTER_LITERAL_SHIFT
+/*-----------------------------------------------------------------*/
+/* genRightShiftLiteral - right shifting by known count            */
+/*-----------------------------------------------------------------*/
+static bool
+genRightShiftLiteral (operand * left,
+                     operand * right,
+                     operand * result,
+                     iCode * ic,
+                     int sign)
+{
+  int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+  int size;
+
+  size = getSize (operandType (result));
+
+  D(emitcode (";", "genRightShiftLiteral (%d), size %d", shCount, size););
+
+  /* We only handle certain easy cases so far. */
+  if ((shCount != 0)
+   && (shCount < (size * 8))
+   && (size != 1)
+   && (size != 2))
+  {
+      D(emitcode (";", "genRightShiftLiteral wimping out"););  
+      return FALSE;
+  }
+
+  freeAsmop (right, NULL, ic, TRUE);
+
+  aopOp (left, ic, FALSE, FALSE);
+  aopOp (result, ic, FALSE, AOP_TYPE (left) == AOP_DPTR);
+
+#if VIEW_SIZE
+  emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
+           AOP_SIZE (left));
+#endif
+
+  /* test the LEFT size !!! */
+
+  /* I suppose that the left size >= result size */
+  if (shCount == 0)
+  {
+      size = getDataSize (result);
+      _startLazyDPSEvaluation();
+      while (size--)
+      {
+       movLeft2Result (left, size, result, size, 0);
+      }
+      _endLazyDPSEvaluation();
+  }
+  else if (shCount >= (size * 8))
+    {
+      if (sign)
+      {
+       /* get sign in acc.7 */
+       MOVA (aopGet (AOP (left), size - 1, FALSE, FALSE, TRUE));
+      }
+      addSign (result, LSB, sign);
+    }
+  else
+    {
+      switch (size)
+       {
+       case 1:
+         genrshOne (result, left, shCount, sign);
+         break;
+
+       case 2:
+         genrshTwo (result, left, shCount, sign);
+         break;
+#if 0
+       case 4:
+         genrshFour (result, left, shCount, sign);
+         break;
+#endif   
+       default:
+         break;
+       }
+
+      freeAsmop (left, NULL, ic, TRUE);
+      freeAsmop (result, NULL, ic, TRUE);
+    }
+    return TRUE;
+}
+#endif
+
+/*-----------------------------------------------------------------*/
+/* genSignedRightShift - right shift of signed number              */
+/*-----------------------------------------------------------------*/
+static void
+genSignedRightShift (iCode * ic)
+{
+  operand *right, *left, *result;
+  int size, offset;
+  char *l;
+  symbol *tlbl, *tlbl1;
+
+  D (emitcode (";", "genSignedRightShift "););
+
+  /* we do it the hard way put the shift count in b
+     and loop thru preserving the sign */
+
+  right = IC_RIGHT (ic);
+  left = IC_LEFT (ic);
+  result = IC_RESULT (ic);
+
+  aopOp (right, ic, FALSE, FALSE);
+
+#ifdef BETTER_LITERAL_SHIFT
+  if (AOP_TYPE (right) == AOP_LIT)
+    {
+      if (genRightShiftLiteral (left, right, result, ic, 1))
+      {
+       return;
+      }
+    }
+#endif
+  /* shift count is unknown then we have to form
+     a loop get the loop 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 ) */
+
+  if (AOP_TYPE (right) == AOP_LIT)
+  {
+      /* Really should be handled by genRightShiftLiteral,
+       * but since I'm too lazy to fix that today, at least we can make
+       * some small improvement.
+       */
+       emitcode("mov", "b,#0x%02x",
+                       ((int) floatFromVal (AOP (right)->aopu.aop_lit)) + 1);
+  }
+  else
+  {
+       emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, FALSE));
+       emitcode ("inc", "b");
+  }
+  freeAsmop (right, NULL, ic, TRUE);
+  aopOp (left, ic, FALSE, FALSE);
+  aopOp (result, ic, FALSE, AOP_TYPE (left) == AOP_DPTR);
+
+  /* now move the left to the result if they are not the
+     same */
+  if (!sameRegs (AOP (left), AOP (result)) &&
+      AOP_SIZE (result) > 1)
+    {
+
+      size = AOP_SIZE (result);
+      offset = 0;
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         l = aopGet (AOP (left), offset, FALSE, TRUE, FALSE);
+         if (*l == '@' && IS_AOP_PREG (result))
+           {
+
+             emitcode ("mov", "a,%s", l);
+             aopPut (AOP (result), "a", offset);
+           }
+         else
+           aopPut (AOP (result), l, offset);
+         offset++;
+       }
+      _endLazyDPSEvaluation ();
+    }
+
+  /* mov the highest order bit to OVR */
+  tlbl = newiTempLabel (NULL);
+  tlbl1 = newiTempLabel (NULL);
+
+  size = AOP_SIZE (result);
+  offset = size - 1;
+  emitcode ("mov", "a,%s", aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+  emitcode ("rlc", "a");
+  emitcode ("mov", "ov,c");
+  /* if it is only one byte then */
+  if (size == 1)
+    {
+      l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
+      MOVA (l);
+      emitcode ("sjmp", "%05d$", tlbl1->key + 100);
+      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("mov", "c,ov");
+      emitcode ("rrc", "a");
+      emitcode ("", "%05d$:", tlbl1->key + 100);
+      emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+      aopPut (AOP (result), "a", 0);
+      goto release;
+    }
+
+  reAdjustPreg (AOP (result));
+  emitcode ("sjmp", "%05d$", tlbl1->key + 100);
+  emitcode ("", "%05d$:", tlbl->key + 100);
+  emitcode ("mov", "c,ov");
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      l = aopGet (AOP (result), offset, FALSE, FALSE, TRUE);
+      MOVA (l);
+      emitcode ("rrc", "a");
+      aopPut (AOP (result), "a", offset--);
+    }
+  _endLazyDPSEvaluation ();
+  reAdjustPreg (AOP (result));
+  emitcode ("", "%05d$:", tlbl1->key + 100);
+  emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+
+release:
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genRightShift - generate code for right shifting                */
+/*-----------------------------------------------------------------*/
+static void
+genRightShift (iCode * ic)
+{
+  operand *right, *left, *result;
+  sym_link *retype;
+  int size, offset;
+  char *l;
+  symbol *tlbl, *tlbl1;
+
+  D (emitcode (";", "genRightShift "););
+
+  /* if signed then we do it the hard way preserve the
+     sign bit moving it inwards */
+  retype = getSpec (operandType (IC_RESULT (ic)));
+
+  if (!SPEC_USIGN (retype))
+    {
+      genSignedRightShift (ic);
+      return;
+    }
+
+  /* signed & unsigned types are treated the same : i.e. the
+     signed is NOT propagated inwards : quoting from the
+     ANSI - standard : "for E1 >> E2, is equivalent to division
+     by 2**E2 if unsigned or if it has a non-negative value,
+     otherwise the result is implementation defined ", MY definition
+     is that the sign does not get propagated */
+
+  right = IC_RIGHT (ic);
+  left = IC_LEFT (ic);
+  result = IC_RESULT (ic);
+
+  aopOp (right, ic, FALSE, FALSE);
+
+#ifdef BETTER_LITERAL_SHIFT
+  /* if the shift count is known then do it
+     as efficiently as possible */
+  if (AOP_TYPE (right) == AOP_LIT)
+    {
+      if (genRightShiftLiteral (left, right, result, ic, 0))
+      {
+       return;
+      }
+    }
+#endif
+
+  /* shift count is unknown then we have to form
+     a loop get the loop 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 ) */
+  
+  if (AOP_TYPE (right) == AOP_LIT)
+  {
+      /* Really should be handled by genRightShiftLiteral,
+       * but since I'm too lazy to fix that today, at least we can make
+       * some small improvement.
+       */
+       emitcode("mov", "b,#0x%02x",
+                       ((int) floatFromVal (AOP (right)->aopu.aop_lit)) + 1);
+  }
+  else
+  {
+       emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, FALSE));
+       emitcode ("inc", "b");
+  }
+  freeAsmop (right, NULL, ic, TRUE);
+  aopOp (left, ic, FALSE, FALSE);
+  aopOp (result, ic, FALSE, AOP_TYPE (left) == AOP_DPTR);
+
+  /* now move the left to the result if they are not the
+     same */
+  if (!sameRegs (AOP (left), AOP (result)) &&
+      AOP_SIZE (result) > 1)
+    {
+
+      size = AOP_SIZE (result);
+      offset = 0;
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         l = aopGet (AOP (left), offset, FALSE, TRUE, FALSE);
+         if (*l == '@' && IS_AOP_PREG (result))
+           {
+
+             emitcode ("mov", "a,%s", l);
+             aopPut (AOP (result), "a", offset);
+           }
+         else
+           aopPut (AOP (result), l, offset);
+         offset++;
+       }
+      _endLazyDPSEvaluation ();
+    }
+
+  tlbl = newiTempLabel (NULL);
+  tlbl1 = newiTempLabel (NULL);
+  size = AOP_SIZE (result);
+  offset = size - 1;
+
+  /* if it is only one byte then */
+  if (size == 1)
+    {
+      l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
+      MOVA (l);
+      emitcode ("sjmp", "%05d$", tlbl1->key + 100);
+      emitcode ("", "%05d$:", tlbl->key + 100);
+      CLRC;
+      emitcode ("rrc", "a");
+      emitcode ("", "%05d$:", tlbl1->key + 100);
+      emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+      aopPut (AOP (result), "a", 0);
+      goto release;
+    }
+
+  reAdjustPreg (AOP (result));
+  emitcode ("sjmp", "%05d$", tlbl1->key + 100);
+  emitcode ("", "%05d$:", tlbl->key + 100);
+  CLRC;
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      l = aopGet (AOP (result), offset, FALSE, FALSE, TRUE);
+      MOVA (l);
+      emitcode ("rrc", "a");
+      aopPut (AOP (result), "a", offset--);
+    }
+  _endLazyDPSEvaluation ();
+  reAdjustPreg (AOP (result));
+
+  emitcode ("", "%05d$:", tlbl1->key + 100);
+  emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+
+release:
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genUnpackBits - generates code for unpacking bits               */
+/*-----------------------------------------------------------------*/
+static void
+genUnpackBits (operand * result, char *rname, int ptype)
+{
+  int shCnt;
+  int rlen = 0;
+  sym_link *etype;
+  int offset = 0;
+
+  D (emitcode (";", "genUnpackBits ");
+    );
+
+  etype = getSpec (operandType (result));
+
+  /* read the first byte  */
+  switch (ptype)
+    {
+
+    case POINTER:
+    case IPOINTER:
+      emitcode ("mov", "a,@%s", rname);
+      break;
+
+    case PPOINTER:
+      emitcode ("movx", "a,@%s", rname);
+      break;
+
+    case FPOINTER:
+      emitcode ("movx", "a,@dptr");
+      break;
+
+    case CPOINTER:
+      emitcode ("clr", "a");
+      emitcode ("movc", "a,@a+dptr");
+      break;
+
+    case GPOINTER:
+      emitcode ("lcall", "__gptrget");
+      break;
+    }
+
+  /* if we have bitdisplacement then it fits   */
+  /* into this byte completely or if length is */
+  /* less than a byte                          */
+  if ((shCnt = SPEC_BSTR (etype)) ||
+      (SPEC_BLEN (etype) <= 8))
+    {
+
+      /* shift right acc */
+      AccRsh (shCnt);
+
+      emitcode ("anl", "a,#0x%02x",
+               ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
+      aopPut (AOP (result), "a", offset);
+      return;
+    }
+
+  /* bit field did not fit in a byte  */
+  rlen = SPEC_BLEN (etype) - 8;
+  aopPut (AOP (result), "a", offset++);
+
+  while (1)
+    {
+
+      switch (ptype)
+       {
+       case POINTER:
+       case IPOINTER:
+         emitcode ("inc", "%s", rname);
+         emitcode ("mov", "a,@%s", rname);
+         break;
+
+       case PPOINTER:
+         emitcode ("inc", "%s", rname);
+         emitcode ("movx", "a,@%s", rname);
+         break;
+
+       case FPOINTER:
+         emitcode ("inc", "dptr");
+         emitcode ("movx", "a,@dptr");
+         break;
+
+       case CPOINTER:
+         emitcode ("clr", "a");
+         emitcode ("inc", "dptr");
+         emitcode ("movc", "a,@a+dptr");
+         break;
+
+       case GPOINTER:
+         emitcode ("inc", "dptr");
+         emitcode ("lcall", "__gptrget");
+         break;
+       }
+
+      rlen -= 8;
+      /* if we are done */
+      if (rlen < 8)
+       break;
+
+      aopPut (AOP (result), "a", offset++);
+
+    }
+
+  if (rlen)
+    {
+      emitcode ("anl", "a,#0x%02x", ((unsigned char) -1) >> (rlen));
+      aopPut (AOP (result), "a", offset);
+    }
+
+  return;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genDataPointerGet - generates code when ptr offset is known     */
+/*-----------------------------------------------------------------*/
+static void
+genDataPointerGet (operand * left,
+                  operand * result,
+                  iCode * ic)
+{
+  char *l;
+  char buffer[256];
+  int size, offset = 0;
+  aopOp (result, ic, TRUE, FALSE);
+
+  /* get the string representation of the name */
+  l = aopGet (AOP (left), 0, FALSE, TRUE, FALSE);
+  size = AOP_SIZE (result);
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      if (offset)
+       sprintf (buffer, "(%s + %d)", l + 1, offset);
+      else
+       sprintf (buffer, "%s", l + 1);
+      aopPut (AOP (result), buffer, offset++);
+    }
+  _endLazyDPSEvaluation ();
+
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genNearPointerGet - emitcode for near pointer fetch             */
+/*-----------------------------------------------------------------*/
+static void
+genNearPointerGet (operand * left,
+                  operand * result,
+                  iCode * ic,
+                  iCode *pi)
+{
+  asmop *aop = NULL;
+  regs *preg = NULL;
+  char *rname;
+  sym_link *rtype, *retype, *letype;
+  sym_link *ltype = operandType (left);
+  char buffer[80];
+
+  rtype = operandType (result);
+  retype = getSpec (rtype);
+  letype = getSpec (ltype);
+
+  aopOp (left, ic, FALSE, FALSE);
+
+  /* if left is rematerialisable and
+     result is not bit variable type and
+     the left is pointer to data space i.e
+     lower 128 bytes of space */
+  if (AOP_TYPE (left) == AOP_IMMD &&
+      !IS_BITVAR (retype) &&
+      !IS_BITVAR (letype) &&
+      DCL_TYPE (ltype) == POINTER)
+    {
+      genDataPointerGet (left, result, ic);
+      return;
+    }
+
+  /* if the value is already in a pointer register
+     then don't need anything more */
+  if (!AOP_INPREG (AOP (left)))
+    {
+      /* otherwise get a free pointer register */
+      aop = newAsmop (0);
+      preg = getFreePtr (ic, &aop, FALSE);
+      emitcode ("mov", "%s,%s",
+               preg->name,
+               aopGet (AOP (left), 0, FALSE, TRUE, FALSE));
+      rname = preg->name;
+    }
+  else
+    rname = aopGet (AOP (left), 0, FALSE, FALSE, FALSE);
+
+  freeAsmop (left, NULL, ic, TRUE);
+  aopOp (result, ic, FALSE, FALSE);
+
+  /* if bitfield then unpack the bits */
+  if (IS_BITVAR (retype) || IS_BITVAR (letype))
+    genUnpackBits (result, rname, POINTER);
+  else
+    {
+      /* we have can just get the values */
+      int size = AOP_SIZE (result);
+      int offset = 0;
+
+      while (size--)
+       {
+         if (IS_AOP_PREG (result) || AOP_TYPE (result) == AOP_STK)
+           {
+
+             emitcode ("mov", "a,@%s", rname);
+             aopPut (AOP (result), "a", offset);
+           }
+         else
+           {
+             sprintf (buffer, "@%s", rname);
+             aopPut (AOP (result), buffer, offset);
+           }
+         offset++;
+         if (size || pi)
+           emitcode ("inc", "%s", rname);
+       }
+    }
+
+  /* now some housekeeping stuff */
+  if (aop)
+    {
+      /* we had to allocate for this iCode */
+      if (pi) { /* post increment present */
+       aopPut(AOP ( left ),rname,0);
+      }
+      freeAsmop (NULL, aop, ic, TRUE);
+    }
+  else
+    {
+      /* we did not allocate which means left
+         already in a pointer register, then
+         if size > 0 && this could be used again
+         we have to point it back to where it
+         belongs */
+      if (AOP_SIZE (result) > 1 &&
+         !OP_SYMBOL (left)->remat &&
+         (OP_SYMBOL (left)->liveTo > ic->seq ||
+          ic->depth) &&
+         !pi)
+       {
+         int size = AOP_SIZE (result) - 1;
+         while (size--)
+           emitcode ("dec", "%s", rname);
+       }
+    }
+
+  /* done */
+  freeAsmop (result, NULL, ic, TRUE);
+  if (pi) pi->generated = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* genPagedPointerGet - emitcode for paged pointer fetch           */
+/*-----------------------------------------------------------------*/
+static void
+genPagedPointerGet (operand * left,
+                   operand * result,
+                   iCode * ic,
+                   iCode * pi)
+{
+  asmop *aop = NULL;
+  regs *preg = NULL;
+  char *rname;
+  sym_link *rtype, *retype, *letype;
+
+  rtype = operandType (result);
+  retype = getSpec (rtype);
+  letype = getSpec (operandType (left));
+  aopOp (left, ic, FALSE, FALSE);
+
+  /* if the value is already in a pointer register
+     then don't need anything more */
+  if (!AOP_INPREG (AOP (left)))
+    {
+      /* otherwise get a free pointer register */
+      aop = newAsmop (0);
+      preg = getFreePtr (ic, &aop, FALSE);
+      emitcode ("mov", "%s,%s",
+               preg->name,
+               aopGet (AOP (left), 0, FALSE, TRUE, FALSE));
+      rname = preg->name;
+    }
+  else
+    rname = aopGet (AOP (left), 0, FALSE, FALSE, FALSE);
+
+  freeAsmop (left, NULL, ic, TRUE);
+  aopOp (result, ic, FALSE, FALSE);
+
+  /* if bitfield then unpack the bits */
+  if (IS_BITVAR (retype) || IS_BITVAR (letype))
+    genUnpackBits (result, rname, PPOINTER);
+  else
+    {
+      /* we have can just get the values */
+      int size = AOP_SIZE (result);
+      int offset = 0;
+
+      while (size--)
+       {
+
+         emitcode ("movx", "a,@%s", rname);
+         aopPut (AOP (result), "a", offset);
+
+         offset++;
+
+         if (size || pi)
+           emitcode ("inc", "%s", rname);
+       }
+    }
+
+  /* now some housekeeping stuff */
+  if (aop)
+    {
+      /* we had to allocate for this iCode */
+      if (pi) aopPut ( AOP (left), rname, 0);
+      freeAsmop (NULL, aop, ic, TRUE);
+    }
+  else
+    {
+      /* we did not allocate which means left
+         already in a pointer register, then
+         if size > 0 && this could be used again
+         we have to point it back to where it
+         belongs */
+      if (AOP_SIZE (result) > 1 &&
+         !OP_SYMBOL (left)->remat &&
+         (OP_SYMBOL (left)->liveTo > ic->seq ||
+          ic->depth) &&
+         !pi)
+       {
+         int size = AOP_SIZE (result) - 1;
+         while (size--)
+           emitcode ("dec", "%s", rname);
+       }
+    }
+
+  /* done */
+  freeAsmop (result, NULL, ic, TRUE);
+  if (pi) pi->generated = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* genFarPointerGet - gget value from far space                    */
+/*-----------------------------------------------------------------*/
+static void
+genFarPointerGet (operand * left,
+                 operand * result, iCode * ic, iCode *pi)
+{
+    int size, offset, dopi=1;
+  sym_link *retype = getSpec (operandType (result));
+  sym_link *letype = getSpec (operandType (left));
+  D (emitcode (";", "genFarPointerGet");
+    );
+
+  aopOp (left, ic, FALSE, FALSE);
+
+  /* if the operand is already in dptr
+     then we do nothing else we move the value to dptr */
+  if (AOP_TYPE (left) != AOP_STR)
+    {
+      /* if this is remateriazable */
+      if (AOP_TYPE (left) == AOP_IMMD)
+       {
+         emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, FALSE));
+       }
+      else
+       {
+         /* we need to get it byte by byte */
+         _startLazyDPSEvaluation ();
+         if (AOP_TYPE (left) != AOP_DPTR)
+           {
+             emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
+             emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+           }
+         else
+           {
+             /* We need to generate a load to DPTR indirect through DPTR. */
+             D (emitcode (";", "genFarPointerGet -- indirection special case.");
+               );
+             emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, TRUE));
+             emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+             emitcode ("pop", "dph");
+             emitcode ("pop", "dpl");
+             dopi =0;
+           }
+         _endLazyDPSEvaluation ();
+       }
+    }
+  /* so dptr know contains the address */
+  aopOp (result, ic, FALSE, TRUE);
+
+  /* if bit then unpack */
+  if (IS_BITVAR (retype) || IS_BITVAR (letype))
+    genUnpackBits (result, "dptr", FPOINTER);
+  else
+    {
+      size = AOP_SIZE (result);
+      offset = 0;
+
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+
+         genSetDPTR (0);
+         _flushLazyDPS ();
+
+         emitcode ("movx", "a,@dptr");
+         if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
+           emitcode ("inc", "dptr");
+
+         aopPut (AOP (result), "a", offset++);
+       }
+      _endLazyDPSEvaluation ();
+    }
+  if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) {
+    aopPut ( AOP (left), "dpl", 0);
+    aopPut ( AOP (left), "dph", 1);
+    if (options.model == MODEL_FLAT24)
+           aopPut ( AOP (left), "dpx", 2);
+    pi->generated = 1;
+  } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
+            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (result) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
+  }
+
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* emitcodePointerGet - gget value from code space                  */
+/*-----------------------------------------------------------------*/
+static void
+emitcodePointerGet (operand * left,
+                   operand * result, iCode * ic, iCode *pi)
+{
+  int size, offset, dopi=1;
+  sym_link *retype = getSpec (operandType (result));
+
+  aopOp (left, ic, FALSE, FALSE);
+
+  /* if the operand is already in dptr
+     then we do nothing else we move the value to dptr */
+  if (AOP_TYPE (left) != AOP_STR)
+    {
+      /* if this is remateriazable */
+      if (AOP_TYPE (left) == AOP_IMMD)
+       {
+         emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, FALSE));
+       }
+      else
+       {                       /* we need to get it byte by byte */
+         _startLazyDPSEvaluation ();
+         if (AOP_TYPE (left) != AOP_DPTR)
+           {
+             emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
+             emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+           }
+         else
+           {
+             /* We need to generate a load to DPTR indirect through DPTR. */
+             D (emitcode (";", "gencodePointerGet -- indirection special case.");
+               );
+             emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, TRUE));
+             emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+             emitcode ("pop", "dph");
+             emitcode ("pop", "dpl");
+             dopi=0;
+           }
+         _endLazyDPSEvaluation ();
+       }
+    }
+  /* so dptr know contains the address */
+  aopOp (result, ic, FALSE, TRUE);
+
+  /* if bit then unpack */
+  if (IS_BITVAR (retype))
+    genUnpackBits (result, "dptr", CPOINTER);
+  else
+    {
+      size = AOP_SIZE (result);
+      offset = 0;
+
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         genSetDPTR (0);
+         _flushLazyDPS ();
+
+         emitcode ("clr", "a");
+         emitcode ("movc", "a,@a+dptr");
+         if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
+           emitcode ("inc", "dptr");
+         aopPut (AOP (result), "a", offset++);
+       }
+      _endLazyDPSEvaluation ();
+    }
+  if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) {
+      aopPut ( AOP (left), "dpl", 0);
+      aopPut ( AOP (left), "dph", 1);
+      if (options.model == MODEL_FLAT24)
+         aopPut ( AOP (left), "dpx", 2);
+      pi->generated = 1;
+  } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
+            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (result) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
+  }
+  
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genGenPointerGet - gget value from generic pointer space        */
+/*-----------------------------------------------------------------*/
+static void
+genGenPointerGet (operand * left,
+                 operand * result, iCode * ic, iCode * pi)
+{
+  int size, offset;
+  sym_link *retype = getSpec (operandType (result));
+  sym_link *letype = getSpec (operandType (left));
+
+  D (emitcode (";", "genGenPointerGet "); );
+
+  aopOp (left, ic, FALSE, (OP_SYMBOL(left)->ruonly ? FALSE : TRUE));
+
+  /* if the operand is already in dptr
+     then we do nothing else we move the value to dptr */
+  if (AOP_TYPE (left) != AOP_STR)
+    {
+      /* if this is remateriazable */
+      if (AOP_TYPE (left) == AOP_IMMD)
+       {
+         emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, FALSE));
+         if (AOP(left)->aopu.aop_immd.from_cast_remat) 
+                 emitcode ("mov", "b,%s",aopGet(AOP (left), AOP_SIZE(left)-1, FALSE, FALSE, FALSE));
+         else
+                 emitcode ("mov", "b,#%d", pointerCode (retype));
+       }
+      else
+       {                       /* we need to get it byte by byte */
+         _startLazyDPSEvaluation ();
+         if (AOP(left)->type==AOP_DPTR2) {
+           char *l;
+           l=aopGet(AOP(left),0,FALSE,FALSE,TRUE);
+           genSetDPTR(0);
+           _flushLazyDPS();
+           emitcode ("mov", "dpl,%s", l);
+           l=aopGet(AOP(left),1,FALSE,FALSE,TRUE);
+           genSetDPTR(0);
+           _flushLazyDPS();
+           emitcode ("mov", "dph,%s", l);
+           if (options.model == MODEL_FLAT24) {
+             l=aopGet(AOP(left),2,FALSE,FALSE,TRUE);
+             genSetDPTR(0);
+             _flushLazyDPS();
+             emitcode ("mov", "dpx,%s", l);
+             emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+           } else {
+             emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
+           }
+         } else {
+           emitcode ("mov", "dpl,%s", aopGet (AOP(left),0,FALSE,FALSE,TRUE));
+           emitcode ("mov", "dph,%s", aopGet (AOP(left),1,FALSE,FALSE,TRUE));
+           if (options.model == MODEL_FLAT24) {
+             emitcode ("mov", "dpx,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
+             emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+           } else {
+             emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
+           }
+         }
+         _endLazyDPSEvaluation ();
+       }
+    }
+  /* so dptr know contains the address */
+  aopOp (result, ic, FALSE, TRUE);
+
+  /* if bit then unpack */
+  if (IS_BITVAR (retype) || IS_BITVAR (letype))
+    genUnpackBits (result, "dptr", GPOINTER);
+  else
+    {
+      size = AOP_SIZE (result);
+      offset = 0;
+
+      while (size--)
+       {
+         emitcode ("lcall", "__gptrget");
+         aopPut (AOP (result), "a", offset++);
+         if (size || (pi && AOP_TYPE (left) != AOP_IMMD))
+           emitcode ("inc", "dptr");
+       }
+    }
+
+  if (pi && AOP_TYPE (left) != AOP_IMMD) {
+    aopPut ( AOP (left), "dpl", 0);
+    aopPut ( AOP (left), "dph", 1);
+    if (options.model == MODEL_FLAT24) {
+       aopPut ( AOP (left), "dpx", 2);
+       aopPut ( AOP (left), "b", 3);   
+    } else  aopPut ( AOP (left), "b", 2);      
+    pi->generated = 1;
+  } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
+            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (result) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
+  }
+
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genPointerGet - generate code for pointer get                   */
+/*-----------------------------------------------------------------*/
+static void
+genPointerGet (iCode * ic, iCode *pi)
+{
+  operand *left, *result;
+  sym_link *type, *etype;
+  int p_type;
+
+  D (emitcode (";", "genPointerGet ");
+    );
+
+  left = IC_LEFT (ic);
+  result = IC_RESULT (ic);
+
+  /* depending on the type of pointer we need to
+     move it to the correct pointer register */
+  type = operandType (left);
+  etype = getSpec (type);
+  /* if left is of type of pointer then it is simple */
+  if (IS_PTR (type) && !IS_FUNC (type->next))
+    p_type = DCL_TYPE (type);
+  else
+    {
+      /* we have to go by the storage class */
+      p_type = PTR_TYPE (SPEC_OCLS (etype));
+    }
+  /* special case when cast remat */
+  if (p_type == GPOINTER && OP_SYMBOL(left)->remat &&
+      IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) {
+         left = IC_RIGHT(OP_SYMBOL(left)->rematiCode);
+         type =   type = operandType (left);
+         p_type = DCL_TYPE (type);
+  }
+  /* now that we have the pointer type we assign
+     the pointer values */
+  switch (p_type)
+    {
+
+    case POINTER:
+    case IPOINTER:
+      genNearPointerGet (left, result, ic, pi);
+      break;
+
+    case PPOINTER:
+      genPagedPointerGet (left, result, ic, pi);
+      break;
+
+    case FPOINTER:
+      genFarPointerGet (left, result, ic, pi);
+      break;
+
+    case CPOINTER:
+      emitcodePointerGet (left, result, ic, pi);
+      break;
+
+    case GPOINTER:
+      genGenPointerGet (left, result, ic, pi);
+      break;
+    }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genPackBits - generates code for packed bit storage             */
+/*-----------------------------------------------------------------*/
+static void
+genPackBits (sym_link * etype,
+            operand * right,
+            char *rname, int p_type)
+{
+  int shCount = 0;
+  int offset = 0;
+  int rLen = 0;
+  int blen, bstr;
+  char *l;
+
+  blen = SPEC_BLEN (etype);
+  bstr = SPEC_BSTR (etype);
+
+  l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
+  MOVA (l);
+
+  /* if the bit lenth is less than or    */
+  /* it exactly fits a byte then         */
+  if (SPEC_BLEN (etype) <= 8)
+    {
+      shCount = SPEC_BSTR (etype);
+
+      /* shift left acc */
+      AccLsh (shCount);
+
+      if (SPEC_BLEN (etype) < 8)
+       {                       /* if smaller than a byte */
+
+
+         switch (p_type)
+           {
+           case POINTER:
+             emitcode ("mov", "b,a");
+             emitcode ("mov", "a,@%s", rname);
+             break;
+
+           case FPOINTER:
+             emitcode ("mov", "b,a");
+             emitcode ("movx", "a,@dptr");
+             break;
+
+           case GPOINTER:
+             emitcode ("push", "b");
+             emitcode ("push", "acc");
+             emitcode ("lcall", "__gptrget");
+             emitcode ("pop", "b");
+             break;
+           }
+
+         emitcode ("anl", "a,#0x%02x", (unsigned char)
+                   ((unsigned char) (0xFF << (blen + bstr)) |
+                    (unsigned char) (0xFF >> (8 - bstr))));
+         emitcode ("orl", "a,b");
+         if (p_type == GPOINTER)
+           emitcode ("pop", "b");
+       }
+    }
+
+  switch (p_type)
+    {
+    case POINTER:
+      emitcode ("mov", "@%s,a", rname);
+      break;
+
+    case FPOINTER:
+      emitcode ("movx", "@dptr,a");
+      break;
+
+    case GPOINTER:
+      emitcode ("lcall", "__gptrput");
+      break;
+    }
+
+  /* if we r done */
+  if (SPEC_BLEN (etype) <= 8)
+    return;
+
+  emitcode ("inc", "%s", rname);
+  rLen = SPEC_BLEN (etype);
+
+  /* now generate for lengths greater than one byte */
+  while (1)
+    {
+
+      l = aopGet (AOP (right), offset++, FALSE, TRUE, FALSE);
+
+      rLen -= 8;
+      if (rLen < 8)
+       break;
+
+      switch (p_type)
+       {
+       case POINTER:
+         if (*l == '@')
+           {
+             MOVA (l);
+             emitcode ("mov", "@%s,a", rname);
+           }
+         else
+           emitcode ("mov", "@%s,%s", rname, l);
+         break;
+
+       case FPOINTER:
+         MOVA (l);
+         emitcode ("movx", "@dptr,a");
+         break;
+
+       case GPOINTER:
+         MOVA (l);
+         emitcode ("lcall", "__gptrput");
+         break;
+       }
+      emitcode ("inc", "%s", rname);
+    }
+
+  MOVA (l);
+
+  /* last last was not complete */
+  if (rLen)
+    {
+      /* save the byte & read byte */
+      switch (p_type)
+       {
+       case POINTER:
+         emitcode ("mov", "b,a");
+         emitcode ("mov", "a,@%s", rname);
+         break;
+
+       case FPOINTER:
+         emitcode ("mov", "b,a");
+         emitcode ("movx", "a,@dptr");
+         break;
+
+       case GPOINTER:
+         emitcode ("push", "b");
+         emitcode ("push", "acc");
+         emitcode ("lcall", "__gptrget");
+         emitcode ("pop", "b");
+         break;
+       }
+
+      emitcode ("anl", "a,#0x%02x", ((unsigned char) -1 << rLen));
+      emitcode ("orl", "a,b");
+    }
+
+  if (p_type == GPOINTER)
+    emitcode ("pop", "b");
+
+  switch (p_type)
+    {
+
+    case POINTER:
+      emitcode ("mov", "@%s,a", rname);
+      break;
+
+    case FPOINTER:
+      emitcode ("movx", "@dptr,a");
+      break;
+
+    case GPOINTER:
+      emitcode ("lcall", "__gptrput");
+      break;
+    }
+}
+/*-----------------------------------------------------------------*/
+/* genDataPointerSet - remat pointer to data space                 */
+/*-----------------------------------------------------------------*/
+static void
+genDataPointerSet (operand * right,
+                  operand * result,
+                  iCode * ic)
+{
+  int size, offset = 0;
+  char *l, buffer[256];
+
+  aopOp (right, ic, FALSE, FALSE);
+
+  l = aopGet (AOP (result), 0, FALSE, TRUE, FALSE);
+  size = AOP_SIZE (right);
+  while (size--)
+    {
+      if (offset)
+       sprintf (buffer, "(%s + %d)", l + 1, offset);
+      else
+       sprintf (buffer, "%s", l + 1);
+      emitcode ("mov", "%s,%s", buffer,
+               aopGet (AOP (right), offset++, FALSE, FALSE, FALSE));
+    }
+
+  freeAsmop (right, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genNearPointerSet - emitcode for near pointer put                */
+/*-----------------------------------------------------------------*/
+static void
+genNearPointerSet (operand * right,
+                  operand * result,
+                  iCode * ic,
+                  iCode * pi)
+{
+  asmop *aop = NULL;
+  regs *preg = NULL;
+  char *rname, *l;
+  sym_link *retype, *letype;
+  sym_link *ptype = operandType (result);
+
+  retype = getSpec (operandType (right));
+  letype = getSpec (ptype);
+
+  aopOp (result, ic, FALSE, FALSE);
+
+  /* if the result is rematerializable &
+     in data space & not a bit variable */
+  if (AOP_TYPE (result) == AOP_IMMD &&
+      DCL_TYPE (ptype) == POINTER &&
+      !IS_BITVAR (retype) &&
+      !IS_BITVAR (letype))
+    {
+      genDataPointerSet (right, result, ic);
+      return;
+    }
+
+  /* if the value is already in a pointer register
+     then don't need anything more */
+  if (!AOP_INPREG (AOP (result)))
+    {
+      /* otherwise get a free pointer register */
+      aop = newAsmop (0);
+      preg = getFreePtr (ic, &aop, FALSE);
+      emitcode ("mov", "%s,%s",
+               preg->name,
+               aopGet (AOP (result), 0, FALSE, TRUE, FALSE));
+      rname = preg->name;
+    }
+  else
+    rname = aopGet (AOP (result), 0, FALSE, FALSE, FALSE);
+
+  aopOp (right, ic, FALSE, FALSE);
+
+  /* if bitfield then unpack the bits */
+  if (IS_BITVAR (retype) || IS_BITVAR (letype))
+    genPackBits ((IS_BITVAR (retype) ? retype : letype), right, rname, POINTER);
+  else
+    {
+      /* we have can just get the values */
+      int size = AOP_SIZE (right);
+      int offset = 0;
+
+      while (size--)
+       {
+         l = aopGet (AOP (right), offset, FALSE, TRUE, FALSE);
+         if (*l == '@')
+           {
+             MOVA (l);
+             emitcode ("mov", "@%s,a", rname);
+           }
+         else
+           emitcode ("mov", "@%s,%s", rname, l);
+         if (size || pi)
+           emitcode ("inc", "%s", rname);
+         offset++;
+       }
+    }
+
+  /* now some housekeeping stuff */
+  if (aop)
+    {
+      /* we had to allocate for this iCode */
+      if (pi) aopPut (AOP (result),rname,0);
+      freeAsmop (NULL, aop, ic, TRUE);
+    }
+  else
+    {
+      /* we did not allocate which means left
+         already in a pointer register, then
+         if size > 0 && this could be used again
+         we have to point it back to where it
+         belongs */
+      if (AOP_SIZE (right) > 1 &&
+         !OP_SYMBOL (result)->remat &&
+         (OP_SYMBOL (result)->liveTo > ic->seq ||
+          ic->depth) &&
+         !pi)
+       {
+         int size = AOP_SIZE (right) - 1;
+         while (size--)
+           emitcode ("dec", "%s", rname);
+       }
+    }
+
+  /* done */
+  if (pi) pi->generated = 1;
+  freeAsmop (result, NULL, ic, TRUE);
+  freeAsmop (right, NULL, ic, TRUE);
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genPagedPointerSet - emitcode for Paged pointer put             */
+/*-----------------------------------------------------------------*/
+static void
+genPagedPointerSet (operand * right,
+                   operand * result,
+                   iCode * ic,
+                   iCode *pi)
+{
+  asmop *aop = NULL;
+  regs *preg = NULL;
+  char *rname, *l;
+  sym_link *retype, *letype;
+
+  retype = getSpec (operandType (right));
+  letype = getSpec (operandType (result));
+
+  aopOp (result, ic, FALSE, FALSE);
+
+  /* if the value is already in a pointer register
+     then don't need anything more */
+  if (!AOP_INPREG (AOP (result)))
+    {
+      /* otherwise get a free pointer register */
+      aop = newAsmop (0);
+      preg = getFreePtr (ic, &aop, FALSE);
+      emitcode ("mov", "%s,%s",
+               preg->name,
+               aopGet (AOP (result), 0, FALSE, TRUE, FALSE));
+      rname = preg->name;
+    }
+  else
+    rname = aopGet (AOP (result), 0, FALSE, FALSE, FALSE);
+
+  aopOp (right, ic, FALSE, FALSE);
+
+  /* if bitfield then unpack the bits */
+  if (IS_BITVAR (retype) || IS_BITVAR (letype))
+    genPackBits ((IS_BITVAR (retype) ? retype : letype), right, rname, PPOINTER);
+  else
+    {
+      /* we have can just get the values */
+      int size = AOP_SIZE (right);
+      int offset = 0;
+
+      while (size--)
+       {
+         l = aopGet (AOP (right), offset, FALSE, TRUE, TRUE);
+
+         MOVA (l);
+         emitcode ("movx", "@%s,a", rname);
+
+         if (size || pi)
+           emitcode ("inc", "%s", rname);
+
+         offset++;
+       }
+    }
+
+  /* now some housekeeping stuff */
+  if (aop)
+    {
+      if (pi) aopPut (AOP (result),rname,0);
+      /* we had to allocate for this iCode */
+      freeAsmop (NULL, aop, ic, TRUE);
+    }
+  else
+    {
+      /* we did not allocate which means left
+         already in a pointer register, then
+         if size > 0 && this could be used again
+         we have to point it back to where it
+         belongs */
+      if (AOP_SIZE (right) > 1 &&
+         !OP_SYMBOL (result)->remat &&
+         (OP_SYMBOL (result)->liveTo > ic->seq ||
+          ic->depth) &&
+         !pi)
+       {
+         int size = AOP_SIZE (right) - 1;
+         while (size--)
+           emitcode ("dec", "%s", rname);
+       }
+    }
+
+  /* done */
+  if (pi) pi->generated = 1;
+  freeAsmop (result, NULL, ic, TRUE);
+  freeAsmop (right, NULL, ic, TRUE);
+
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genFarPointerSet - set value from far space                     */
+/*-----------------------------------------------------------------*/
+static void
+genFarPointerSet (operand * right,
+                 operand * result, iCode * ic, iCode *pi)
+{
+  int size, offset, dopi=1;
+  sym_link *retype = getSpec (operandType (right));
+  sym_link *letype = getSpec (operandType (result));
+
+  aopOp (result, ic, FALSE, FALSE);
+
+  /* if the operand is already in dptr
+     then we do nothing else we move the value to dptr */
+  if (AOP_TYPE (result) != AOP_STR)
+    {
+      /* if this is remateriazable */
+      if (AOP_TYPE (result) == AOP_IMMD)
+       emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE, FALSE));
+      else
+       {
+         /* we need to get it byte by byte */
+         _startLazyDPSEvaluation ();
+         if (AOP_TYPE (result) != AOP_DPTR)
+           {
+             emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, TRUE));
+             emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+           }
+         else
+           {
+             /* We need to generate a load to DPTR indirect through DPTR. */
+             D (emitcode (";", "genFarPointerSet -- indirection special case.");
+               );
+             emitcode ("push", "%s", aopGet (AOP (result), 0, FALSE, TRUE, TRUE));
+             emitcode ("push", "%s", aopGet (AOP (result), 1, FALSE, TRUE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+             emitcode ("pop", "dph");
+             emitcode ("pop", "dpl");
+             dopi=0;
+           }
+         _endLazyDPSEvaluation ();
+       }
+    }
+  /* so dptr know contains the address */
+  aopOp (right, ic, FALSE, TRUE);
+
+  /* if bit then unpack */
+  if (IS_BITVAR (retype) || IS_BITVAR (letype))
+    genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", FPOINTER);
+  else
+    {
+      size = AOP_SIZE (right);
+      offset = 0;
+
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         char *l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
+         MOVA (l);
+
+         genSetDPTR (0);
+         _flushLazyDPS ();
+
+         emitcode ("movx", "@dptr,a");
+         if (size || (dopi && pi && AOP_TYPE (result) != AOP_IMMD))
+           emitcode ("inc", "dptr");
+       }
+      _endLazyDPSEvaluation ();
+    }
+
+  if (dopi && pi && AOP_TYPE (result) != AOP_IMMD) {
+      aopPut (AOP(result),"dpl",0);
+      aopPut (AOP(result),"dph",1);
+      if (options.model == MODEL_FLAT24)
+         aopPut (AOP(result),"dpx",2);
+      pi->generated=1;
+  } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 &&
+            (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (right) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
+  }
+  freeAsmop (result, NULL, ic, TRUE);
+  freeAsmop (right, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genGenPointerSet - set value from generic pointer space         */
+/*-----------------------------------------------------------------*/
+static void
+genGenPointerSet (operand * right,
+                 operand * result, iCode * ic, iCode *pi)
+{
+  int size, offset;
+  sym_link *retype = getSpec (operandType (right));
+  sym_link *letype = getSpec (operandType (result));
+
+  aopOp (result, ic, FALSE, OP_SYMBOL(result)->ruonly ? FALSE : TRUE);
+
+  /* if the operand is already in dptr
+     then we do nothing else we move the value to dptr */
+  if (AOP_TYPE (result) != AOP_STR)
+    {
+      _startLazyDPSEvaluation ();
+      /* if this is remateriazable */
+      if (AOP_TYPE (result) == AOP_IMMD)
+       {
+         emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE, FALSE));
+         if (AOP(result)->aopu.aop_immd.from_cast_remat) 
+                 emitcode ("mov", "b,%s",aopGet(AOP (result), AOP_SIZE(result)-1, FALSE, FALSE, FALSE));
+         else
+                 emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE, FALSE));
+       }
+      else
+       {                       /* we need to get it byte by byte */
+         emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, TRUE));
+         emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, TRUE));
+         if (options.model == MODEL_FLAT24) {
+           emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+           emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE, TRUE));
+         } else {
+           emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+         }
+       }
+      _endLazyDPSEvaluation ();
+    }
+  /* so dptr know contains the address */
+  aopOp (right, ic, FALSE, TRUE);
+
+  /* if bit then unpack */
+  if (IS_BITVAR (retype) || IS_BITVAR (letype))
+    genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", GPOINTER);
+  else
+    {
+      size = AOP_SIZE (right);
+      offset = 0;
+
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         char *l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
+         MOVA (l);
+
+         genSetDPTR (0);
+         _flushLazyDPS ();
+
+         emitcode ("lcall", "__gptrput");
+         if (size || (pi && AOP_TYPE (result) != AOP_IMMD))
+           emitcode ("inc", "dptr");
+       }
+      _endLazyDPSEvaluation ();
+    }
+
+  if (pi && AOP_TYPE (result) != AOP_IMMD) {
+      aopPut (AOP(result),"dpl",0);
+      aopPut (AOP(result),"dph",1);
+      if (options.model == MODEL_FLAT24) {
+         aopPut (AOP(result),"dpx",2);
+         aopPut (AOP(result),"b",3);
+      } else {
+         aopPut (AOP(result),"b",2);
+      }
+      pi->generated=1;
+  } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 &&
+            (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (right) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
+  }
+  freeAsmop (result, NULL, ic, TRUE);
+  freeAsmop (right, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genPointerSet - stores the value into a pointer location        */
+/*-----------------------------------------------------------------*/
+static void
+genPointerSet (iCode * ic, iCode *pi)
+{
+  operand *right, *result;
+  sym_link *type, *etype;
+  int p_type;
+
+  D (emitcode (";", "genPointerSet ");
+    );
+
+  right = IC_RIGHT (ic);
+  result = IC_RESULT (ic);
+
+  /* depending on the type of pointer we need to
+     move it to the correct pointer register */
+  type = operandType (result);
+  etype = getSpec (type);
+  /* if left is of type of pointer then it is simple */
+  if (IS_PTR (type) && !IS_FUNC (type->next))
+    {
+      p_type = DCL_TYPE (type);
+    }
+  else
+    {
+      /* we have to go by the storage class */
+      p_type = PTR_TYPE (SPEC_OCLS (etype));
+    }
+  /* special case when cast remat */
+  if (p_type == GPOINTER && OP_SYMBOL(result)->remat &&
+      IS_CAST_ICODE(OP_SYMBOL(result)->rematiCode)) {
+         result = IC_RIGHT(OP_SYMBOL(result)->rematiCode);
+         type =   type = operandType (result);
+         p_type = DCL_TYPE (type);
+  }
+
+  /* now that we have the pointer type we assign
+     the pointer values */
+  switch (p_type)
+    {
+
+    case POINTER:
+    case IPOINTER:
+      genNearPointerSet (right, result, ic, pi);
+      break;
+
+    case PPOINTER:
+      genPagedPointerSet (right, result, ic, pi);
+      break;
+
+    case FPOINTER:
+      genFarPointerSet (right, result, ic, pi);
+      break;
+
+    case GPOINTER:
+      genGenPointerSet (right, result, ic, pi);
+      break;
+    }
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genIfx - generate code for Ifx statement                        */
+/*-----------------------------------------------------------------*/
+static void
+genIfx (iCode * ic, iCode * popIc)
+{
+  operand *cond = IC_COND (ic);
+  int isbit = 0;
+
+  D (emitcode (";", "genIfx "););
+
+  aopOp (cond, ic, FALSE, FALSE);
+
+  /* get the value into acc */
+  if (AOP_TYPE (cond) != AOP_CRY)
+    toBoolean (cond);
+  else
+    isbit = 1;
+  /* the result is now in the accumulator */
+  freeAsmop (cond, NULL, ic, TRUE);
+
+  /* if there was something to be popped then do it */
+  if (popIc)
+    genIpop (popIc);
+
+  /* if the condition is  a bit variable */
+  if (isbit && IS_ITEMP (cond) &&
+      SPIL_LOC (cond))
+    genIfxJump (ic, SPIL_LOC (cond)->rname);
+  else if (isbit && !IS_ITEMP (cond))
+    genIfxJump (ic, OP_SYMBOL (cond)->rname);
+  else
+    genIfxJump (ic, "a");
+
+  ic->generated = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* genAddrOf - generates code for address of                       */
+/*-----------------------------------------------------------------*/
+static void
+genAddrOf (iCode * ic)
+{
+  symbol *sym = OP_SYMBOL (IC_LEFT (ic));
+  int size, offset;
+
+  D (emitcode (";", "genAddrOf ");
+    );
+
+  aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+
+  /* if the operand is on the stack then we
+     need to get the stack offset of this
+     variable */
+  if (sym->onStack) {
+      
+      /* if 10 bit stack */
+      if (options.stack10bit) {
+         /* if it has an offset then we need to compute it */
+      emitcode ("subb", "a,#0x%02x",
+               -((sym->stack < 0) ?
+                 ((short) (sym->stack - _G.nRegsSaved)) :
+                 ((short) sym->stack)) & 0xff);
+      emitcode ("mov","b,a");
+      emitcode ("mov","a,#0x%02x",(-((sym->stack < 0) ?
+                                    ((short) (sym->stack - _G.nRegsSaved)) :
+                                    ((short) sym->stack)) >> 8) & 0xff);
+         if (sym->stack) {
+             emitcode ("mov", "a,_bpx");
+             emitcode ("add", "a,#0x%02x", ((sym->stack < 0) ? 
+                                            ((char) (sym->stack - _G.nRegsSaved)) :
+                                            ((char) sym->stack )) & 0xff);
+             emitcode ("mov", "b,a");
+             emitcode ("mov", "a,_bpx+1");
+             emitcode ("addc","a,#0x%02x", (((sym->stack < 0) ? 
+                                             ((short) (sym->stack - _G.nRegsSaved)) :
+                                             ((short) sym->stack )) >> 8) & 0xff);
+             aopPut (AOP (IC_RESULT (ic)), "b", 0);
+             aopPut (AOP (IC_RESULT (ic)), "a", 1);
+             aopPut (AOP (IC_RESULT (ic)), "#0x40", 2);
+         } else {
+             /* we can just move _bp */
+             aopPut (AOP (IC_RESULT (ic)), "_bpx", 0);
+             aopPut (AOP (IC_RESULT (ic)), "_bpx+1", 1);
+             aopPut (AOP (IC_RESULT (ic)), "#0x40", 2);
+         }       
+      } else {
+         /* if it has an offset then we need to compute it */
+         if (sym->stack) {
+             emitcode ("mov", "a,_bp");
+             emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+             aopPut (AOP (IC_RESULT (ic)), "a", 0);
+         } else {
+             /* we can just move _bp */
+             aopPut (AOP (IC_RESULT (ic)), "_bp", 0);
+         }
+         /* fill the result with zero */
+         size = AOP_SIZE (IC_RESULT (ic)) - 1;
+         
+         
+         if (options.stack10bit && size < (FPTRSIZE - 1)) {
+             fprintf (stderr,
+                      "*** warning: pointer to stack var truncated.\n");
+         }
+
+         offset = 1;
+         while (size--) {
+             aopPut (AOP (IC_RESULT (ic)), zero, offset++);
+         }      
+      }
+      goto release;
+  }
+
+  /* object not on stack then we need the name */
+  size = AOP_SIZE (IC_RESULT (ic));
+  offset = 0;
+
+  while (size--)
+    {
+      char s[SDCC_NAME_MAX];
+      if (offset)
+       sprintf (s, "#(%s >> %d)",
+                sym->rname,
+                offset * 8);
+      else
+       sprintf (s, "#%s", sym->rname);
+      aopPut (AOP (IC_RESULT (ic)), s, offset++);
+    }
+
+release:
+  freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genArrayInit - generates code for address of                       */
+/*-----------------------------------------------------------------*/
+static void
+genArrayInit (iCode * ic)
+{
+    literalList *iLoop;
+    int         ix, count;
+    int         elementSize = 0, eIndex;
+    unsigned    val, lastVal;
+    sym_link    *type;
+    operand     *left=IC_LEFT(ic);
+    
+    D (emitcode (";", "genArrayInit "););
+
+    aopOp (IC_LEFT(ic), ic, FALSE, FALSE);
+    
+    if (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD)
+    {
+       // Load immediate value into DPTR.
+       emitcode("mov", "dptr, %s",
+            aopGet(AOP(IC_LEFT(ic)), 0, TRUE, FALSE, TRUE));
+    }
+    else if (AOP_TYPE(IC_LEFT(ic)) != AOP_DPTR)
+    {
+#if 0
+      werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+             "Unexpected operand to genArrayInit.\n");
+      exit(1);
+#else
+      // a regression because of SDCCcse.c:1.52
+      emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
+      emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE));
+      if (options.model == MODEL_FLAT24)
+       emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+#endif
+    }
+    
+    type = operandType(IC_LEFT(ic));
+    
+    if (type && type->next)
+    {
+       elementSize = getSize(type->next);
+    }
+    else
+    {
+       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                               "can't determine element size in genArrayInit.\n");
+       exit(1);
+    }
+    
+    iLoop = IC_ARRAYILIST(ic);
+    lastVal = 0xffff;
+    
+    while (iLoop)
+    {
+       bool firstpass = TRUE;
+       
+       emitcode(";", "store %d x 0x%x to DPTR (element size %d)", 
+                iLoop->count, (int)iLoop->literalValue, elementSize);
+       
+       ix = iLoop->count;
+       
+       while (ix)
+       {
+           symbol *tlbl = NULL;
+           
+           count = ix > 256 ? 256 : ix;
+           
+           if (count > 1)
+           {
+               tlbl = newiTempLabel (NULL);
+               if (firstpass || (count & 0xff))
+               {
+                   emitcode("mov", "b, #0x%x", count & 0xff);
+               }
+               
+               emitcode ("", "%05d$:", tlbl->key + 100);
+           }
+           
+           firstpass = FALSE;
+               
+           for (eIndex = 0; eIndex < elementSize; eIndex++)
+           {
+               val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff;
+               if (val != lastVal)
+               {
+                   emitcode("mov", "a, #0x%x", val);
+                   lastVal = val;
+               }
+               
+               emitcode("movx", "@dptr, a");
+               emitcode("inc", "dptr");
+           }
+           
+           if (count > 1)
+           {
+               emitcode("djnz", "b, %05d$", tlbl->key + 100);
+           }
+           
+           ix -= count;
+       }
+       
+       iLoop = iLoop->next;
+    }
+    
+    freeAsmop (IC_LEFT(ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genFarFarAssign - assignment when both are in far space         */
+/*-----------------------------------------------------------------*/
+static void
+genFarFarAssign (operand * result, operand * right, iCode * ic)
+{
+  int size = AOP_SIZE (right);
+  int offset = 0;
+  symbol *rSym = NULL;
+
+  if (size == 1)
+  {
+      /* quick & easy case. */
+      D(emitcode(";","genFarFarAssign (1 byte case)"););      
+      MOVA(aopGet(AOP(right), 0, FALSE, FALSE, TRUE));
+      freeAsmop (right, NULL, ic, FALSE);
+      /* now assign DPTR to result */
+      _G.accInUse++;
+      aopOp(result, ic, FALSE, FALSE);
+      _G.accInUse--;
+      aopPut(AOP(result), "a", 0);
+      freeAsmop(result, NULL, ic, FALSE);
+      return;
+  }
+  
+  /* See if we've got an underlying symbol to abuse. */
+  if (IS_SYMOP(result) && OP_SYMBOL(result))
+  {
+      if (IS_TRUE_SYMOP(result))
+      {
+         rSym = OP_SYMBOL(result);
+      }
+      else if (IS_ITEMP(result) && OP_SYMBOL(result)->isspilt && OP_SYMBOL(result)->usl.spillLoc)
+      {
+         rSym = OP_SYMBOL(result)->usl.spillLoc;
+      }
+  }
+            
+  if (size > 1 && rSym && rSym->rname && !rSym->onStack)
+  {
+      /* We can use the '390 auto-toggle feature to good effect here. */
+      
+      D(emitcode(";","genFarFarAssign (390 auto-toggle fun)"););
+      emitcode("mov", "dps, #0x21");   /* Select DPTR2 & auto-toggle. */
+      emitcode ("mov", "dptr,#%s", rSym->rname); 
+      /* DP2 = result, DP1 = right, DP1 is current. */
+      while (size)
+      {
+          emitcode("movx", "a,@dptr");
+          emitcode("movx", "@dptr,a");
+          if (--size)
+          {
+               emitcode("inc", "dptr");
+               emitcode("inc", "dptr");
+          }
+      }
+      emitcode("mov", "dps, #0");
+      freeAsmop (right, NULL, ic, FALSE);
+#if 0
+some alternative code for processors without auto-toggle
+no time to test now, so later well put in...kpb
+        D(emitcode(";","genFarFarAssign (dual-dptr fun)"););
+        emitcode("mov", "dps, #0x01");         /* Select DPTR2. */
+        emitcode ("mov", "dptr,#%s", rSym->rname); 
+        /* DP2 = result, DP1 = right, DP1 is current. */
+        while (size)
+        {
+          --size;
+          emitcode("movx", "a,@dptr");
+          if (size)
+            emitcode("inc", "dptr");
+          emitcode("inc", "dps");
+          emitcode("movx", "@dptr,a");
+          if (size)
+            emitcode("inc", "dptr");
+          emitcode("inc", "dps");
+        }
+        emitcode("mov", "dps, #0");
+        freeAsmop (right, NULL, ic, FALSE);
+#endif
+  }
+  else
+  {
+      D (emitcode (";", "genFarFarAssign"););
+      aopOp (result, ic, TRUE, TRUE);
+
+      _startLazyDPSEvaluation ();
+      
+      while (size--)
+       {
+         aopPut (AOP (result),
+                 aopGet (AOP (right), offset, FALSE, FALSE, FALSE), offset);
+         offset++;
+       }
+      _endLazyDPSEvaluation ();
+      freeAsmop (result, NULL, ic, FALSE);
+      freeAsmop (right, NULL, ic, FALSE);
+  }
+}
+
+/*-----------------------------------------------------------------*/
+/* genAssign - generate code for assignment                        */
+/*-----------------------------------------------------------------*/
+static void
+genAssign (iCode * ic)
+{
+  operand *result, *right;
+  int size, offset;
+  unsigned long lit = 0L;
+
+  D (emitcode (";", "genAssign ");
+    );
+
+  result = IC_RESULT (ic);
+  right = IC_RIGHT (ic);
+
+  /* if they are the same */
+  if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
+    return;
+
+  aopOp (right, ic, FALSE, FALSE);
+
+  emitcode (";", "genAssign: resultIsFar = %s",
+           isOperandInFarSpace (result) ?
+           "TRUE" : "FALSE");
+
+  /* special case both in far space */
+  if ((AOP_TYPE (right) == AOP_DPTR ||
+       AOP_TYPE (right) == AOP_DPTR2) &&
+  /* IS_TRUE_SYMOP(result)       && */
+      isOperandInFarSpace (result))
+    {
+      genFarFarAssign (result, right, ic);
+      return;
+    }
+
+  aopOp (result, ic, TRUE, FALSE);
+
+  /* if they are the same registers */
+  if (sameRegs (AOP (right), AOP (result)))
+    goto release;
+
+  /* if the result is a bit */
+  if (AOP_TYPE (result) == AOP_CRY) /* works only for true symbols */
+    {
+      /* if the right size is a literal then
+         we know what the value is */
+      if (AOP_TYPE (right) == AOP_LIT)
+       {
+         if (((int) operandLitValue (right)))
+           aopPut (AOP (result), one, 0);
+         else
+           aopPut (AOP (result), zero, 0);
+         goto release;
+       }
+
+      /* the right is also a bit variable */
+      if (AOP_TYPE (right) == AOP_CRY)
+       {
+         emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+         aopPut (AOP (result), "c", 0);
+         goto release;
+       }
+
+      /* we need to or */
+      toBoolean (right);
+      aopPut (AOP (result), "a", 0);
+      goto release;
+    }
+
+  /* bit variables done */
+  /* general case */
+  size = AOP_SIZE (result);
+  offset = 0;
+  if (AOP_TYPE (right) == AOP_LIT)
+    lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+
+  if ((size > 1) &&
+      (AOP_TYPE (result) != AOP_REG) &&
+      (AOP_TYPE (right) == AOP_LIT) &&
+      !IS_FLOAT (operandType (right)))
+    {
+      _startLazyDPSEvaluation ();
+      while (size && ((unsigned int) (lit >> (offset * 8)) != 0))
+       {
+         aopPut (AOP (result),
+                 aopGet (AOP (right), offset, FALSE, FALSE, TRUE),
+                 offset);
+         offset++;
+         size--;
+       }
+      /* And now fill the rest with zeros. */
+      if (size)
+       {
+         emitcode ("clr", "a");
+       }
+      while (size--)
+       {
+         aopPut (AOP (result), "a", offset++);
+       }
+      _endLazyDPSEvaluation ();
+    }
+  else
+    {
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         aopPut (AOP (result),
+                 aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+                 offset);
+         offset++;
+       }
+      _endLazyDPSEvaluation ();
+    }
+
+release:
+  freeAsmop (right, NULL, ic, FALSE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genJumpTab - generates code for jump table                      */
+/*-----------------------------------------------------------------*/
+static void
+genJumpTab (iCode * ic)
+{
+  symbol *jtab;
+  char *l;
+
+  D (emitcode (";", "genJumpTab ");
+    );
+
+  aopOp (IC_JTCOND (ic), ic, FALSE, FALSE);
+  /* get the condition into accumulator */
+  l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE, TRUE);
+  MOVA (l);
+  /* multiply by four! */
+  emitcode ("add", "a,acc");
+  emitcode ("add", "a,acc");
+  freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
+
+  jtab = newiTempLabel (NULL);
+  emitcode ("mov", "dptr,#%05d$", jtab->key + 100);
+  emitcode ("jmp", "@a+dptr");
+  emitcode ("", "%05d$:", jtab->key + 100);
+  /* now generate the jump labels */
+  for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab;
+       jtab = setNextItem (IC_JTLABELS (ic)))
+    emitcode ("ljmp", "%05d$", jtab->key + 100);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genCast - gen code for casting                                  */
+/*-----------------------------------------------------------------*/
+static void
+genCast (iCode * ic)
+{
+  operand *result = IC_RESULT (ic);
+  sym_link *ctype = operandType (IC_LEFT (ic));
+  sym_link *rtype = operandType (IC_RIGHT (ic));
+  operand *right = IC_RIGHT (ic);
+  int size, offset;
+
+  D (emitcode (";", "genCast ");
+    );
+
+  /* if they are equivalent then do nothing */
+  if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
+    return;
+
+  aopOp (right, ic, FALSE, FALSE);
+  aopOp (result, ic, FALSE, AOP_TYPE (right) == AOP_DPTR);
+
+  /* if the result is a bit */
+  // if (AOP_TYPE (result) == AOP_CRY) /* works only for true symbols */
+  if (IS_BITVAR(OP_SYMBOL(result)->type))
+    {
+      /* if the right size is a literal then
+         we know what the value is */
+      if (AOP_TYPE (right) == AOP_LIT)
+       {
+         if (((int) operandLitValue (right)))
+           aopPut (AOP (result), one, 0);
+         else
+           aopPut (AOP (result), zero, 0);
+
+         goto release;
+       }
+
+      /* the right is also a bit variable */
+      if (AOP_TYPE (right) == AOP_CRY)
+       {
+         emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+         aopPut (AOP (result), "c", 0);
+         goto release;
+       }
+
+      /* we need to or */
+      toBoolean (right);
+      aopPut (AOP (result), "a", 0);
+      goto release;
+    }
+
+  /* if they are the same size : or less */
+  if (AOP_SIZE (result) <= AOP_SIZE (right))
+    {
+
+      /* if they are in the same place */
+      if (sameRegs (AOP (right), AOP (result)))
+       goto release;
+
+      /* if they in different places then copy */
+      size = AOP_SIZE (result);
+      offset = 0;
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         aopPut (AOP (result),
+                 aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+                 offset);
+         offset++;
+       }
+      _endLazyDPSEvaluation ();
+      goto release;
+    }
+
+
+  /* if the result is of type pointer */
+  if (IS_PTR (ctype))
+    {
+
+      int p_type;
+      sym_link *type = operandType (right);
+
+      /* pointer to generic pointer */
+      if (IS_GENPTR (ctype))
+       {
+         char *l = zero;
+
+         if (IS_PTR (type))
+           {
+             p_type = DCL_TYPE (type);
+           }
+         else
+           {
+#if OLD_CAST_BEHAVIOR
+             /* KV: we are converting a non-pointer type to
+              * a generic pointer. This (ifdef'd out) code
+              * says that the resulting generic pointer
+              * should have the same class as the storage
+              * location of the non-pointer variable.
+              *
+              * For example, converting an int (which happens
+              * to be stored in DATA space) to a pointer results
+              * in a DATA generic pointer; if the original int
+              * in XDATA space, so will be the resulting pointer.
+              *
+              * I don't like that behavior, and thus this change:
+              * all such conversions will be forced to XDATA and
+              * throw a warning. If you want some non-XDATA
+              * type, or you want to suppress the warning, you
+              * must go through an intermediate cast, like so:
+              *
+              * char _generic *gp = (char _xdata *)(intVar);
+              */
+             sym_link *etype = getSpec (type);
+
+             /* we have to go by the storage class */
+             if (SPEC_OCLS (etype) != generic)
+               {
+                 p_type = PTR_TYPE (SPEC_OCLS (etype));
+               }
+             else
+#endif
+               {
+                 /* Converting unknown class (i.e. register variable)
+                  * to generic pointer. This is not good, but
+                  * we'll make a guess (and throw a warning).
+                  */
+                 p_type = FPOINTER;
+                 werror (W_INT_TO_GEN_PTR_CAST);
+               }
+           }
+
+         /* the first two bytes are known */
+         size = GPTRSIZE - 1;
+         offset = 0;
+         _startLazyDPSEvaluation ();
+         while (size--)
+           {
+             aopPut (AOP (result),
+                     aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+                     offset);
+             offset++;
+           }
+         _endLazyDPSEvaluation ();
+
+         /* the last byte depending on type */
+         switch (p_type)
+           {
+           case IPOINTER:
+           case POINTER:
+             l = zero;
+             break;
+           case FPOINTER:
+             l = one;
+             break;
+           case CPOINTER:
+             l = "#0x02";
+             break;
+           case PPOINTER:
+             l = "#0x03";
+             break;
+
+           default:
+             /* this should never happen */
+             werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                     "got unknown pointer type");
+             exit (1);
+           }
+         aopPut (AOP (result), l, GPTRSIZE - 1);
+         goto release;
+       }
+
+      /* just copy the pointers */
+      size = AOP_SIZE (result);
+      offset = 0;
+      _startLazyDPSEvaluation ();
+      while (size--)
+       {
+         aopPut (AOP (result),
+                 aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+                 offset);
+         offset++;
+       }
+      _endLazyDPSEvaluation ();
+      goto release;
+    }
+
+  /* so we now know that the size of destination is greater
+     than the size of the source */
+  /* we move to result for the size of source */
+  size = AOP_SIZE (right);
+  offset = 0;
+  _startLazyDPSEvaluation ();
+  while (size--)
+    {
+      aopPut (AOP (result),
+             aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+             offset);
+      offset++;
+    }
+  _endLazyDPSEvaluation ();
+
+  /* now depending on the sign of the source && destination */
+  size = AOP_SIZE (result) - AOP_SIZE (right);
+  /* if unsigned or not an integral type */
+  /* also, if the source is a bit, we don't need to sign extend, because
+   * it can't possibly have set the sign bit.
+   */
+  if (SPEC_USIGN (rtype) || !IS_SPEC (rtype) || AOP_TYPE (right) == AOP_CRY)
+    {
+      while (size--)
+       {
+         aopPut (AOP (result), zero, offset++);
+       }
+    }
+  else
+    {
+      /* we need to extend the sign :{ */
+      char *l = aopGet (AOP (right), AOP_SIZE (right) - 1,
+                       FALSE, FALSE, TRUE);
+      MOVA (l);
+      emitcode ("rlc", "a");
+      emitcode ("subb", "a,acc");
+      while (size--)
+       aopPut (AOP (result), "a", offset++);
+    }
+
+  /* we are done hurray !!!! */
+
+release:
+  freeAsmop (right, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genDjnz - generate decrement & jump if not zero instrucion      */
+/*-----------------------------------------------------------------*/
+static int
+genDjnz (iCode * ic, iCode * ifx)
+{
+  symbol *lbl, *lbl1;
+  if (!ifx)
+    return 0;
+
+  /* if the if condition has a false label
+     then we cannot save */
+  if (IC_FALSE (ifx))
+    return 0;
+
+  /* if the minus is not of the form
+     a = a - 1 */
+  if (!isOperandEqual (IC_RESULT (ic), IC_LEFT (ic)) ||
+      !IS_OP_LITERAL (IC_RIGHT (ic)))
+    return 0;
+
+  if (operandLitValue (IC_RIGHT (ic)) != 1)
+    return 0;
+
+  /* if the size of this greater than one then no
+     saving */
+  if (getSize (operandType (IC_RESULT (ic))) > 1)
+    return 0;
+
+  /* otherwise we can save BIG */
+  D(emitcode(";", "genDjnz"););
+
+  lbl = newiTempLabel (NULL);
+  lbl1 = newiTempLabel (NULL);
+
+  aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+
+  if (AOP_NEEDSACC(IC_RESULT(ic)))
+  {
+      /* If the result is accessed indirectly via
+       * the accumulator, we must explicitly write
+       * it back after the decrement.
+       */
+      char *rByte = aopGet(AOP(IC_RESULT(ic)), 0, FALSE, FALSE, TRUE);
+      
+      if (strcmp(rByte, "a"))
+      {
+           /* Something is hopelessly wrong */
+           fprintf(stderr, "*** warning: internal error at %s:%d\n",
+                  __FILE__, __LINE__);
+           /* We can just give up; the generated code will be inefficient,
+            * but what the hey.
+            */
+           freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+           return 0;
+      }
+      emitcode ("dec", "%s", rByte);
+      aopPut(AOP(IC_RESULT(ic)), rByte, 0);
+      emitcode ("jnz", "%05d$", lbl->key + 100);
+  }
+  else if (IS_AOP_PREG (IC_RESULT (ic)))
+    {
+      emitcode ("dec", "%s",
+               aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, FALSE));
+      emitcode ("mov", "a,%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, FALSE));
+      emitcode ("jnz", "%05d$", lbl->key + 100);
+    }
+  else
+    {
+      emitcode ("djnz", "%s,%05d$", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, TRUE, FALSE),
+               lbl->key + 100);
+    }
+  emitcode ("sjmp", "%05d$", lbl1->key + 100);
+  emitcode ("", "%05d$:", lbl->key + 100);
+  emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
+  emitcode ("", "%05d$:", lbl1->key + 100);
+
+  freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+  ifx->generated = 1;
+  return 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* genReceive - generate code for a receive iCode                  */
+/*-----------------------------------------------------------------*/
+static void
+genReceive (iCode * ic)
+{
+
+  D (emitcode (";", "genReceive ");
+    );
+
+  if (isOperandInFarSpace (IC_RESULT (ic)) &&
+      (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
+       IS_TRUE_SYMOP (IC_RESULT (ic))))
+    {
+      int size = getSize (operandType (IC_RESULT (ic)));
+      int offset = fReturnSizeDS390 - size;
+      while (size--)
+       {
+         emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeDS390 - offset - 1], "a") ?
+                           fReturn[fReturnSizeDS390 - offset - 1] : "acc"));
+         offset++;
+       }
+      aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+      size = AOP_SIZE (IC_RESULT (ic));
+      offset = 0;
+      while (size--)
+       {
+         emitcode ("pop", "acc");
+         aopPut (AOP (IC_RESULT (ic)), "a", offset++);
+       }
+
+    }
+  else
+    {
+      _G.accInUse++;
+      aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+      _G.accInUse--;
+      assignResultValue (IC_RESULT (ic));
+    }
+
+  freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* gen390Code - generate code for Dallas 390 based controllers     */
+/*-----------------------------------------------------------------*/
+void
+gen390Code (iCode * lic)
+{
+  iCode *ic;
+  int cln = 0;
+
+  lineHead = lineCurr = NULL;
+
+  if (options.model == MODEL_FLAT24) {
+    fReturnSizeDS390 = 5;
+    fReturn = fReturn24;
+  } else {
+    fReturnSizeDS390 = 4;
+    fReturn = fReturn16;
+    options.stack10bit=0;
+  }
+#if 0
+  //REMOVE ME!!!
+  /* print the allocation information */
+  if (allocInfo)
+    printAllocInfo (currFunc, codeOutFile);
+#endif
+  /* if debug information required */
+  if (options.debug && currFunc)
+    {
+      cdbSymbol (currFunc, cdbFile, FALSE, TRUE);
+      _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;
+    }
+  /* stack pointer name */
+  if (options.useXstack)
+    spname = "_spx";
+  else
+    spname = "sp";
+
+
+  for (ic = lic; ic; ic = ic->next)
+    {
+
+      if (cln != ic->lineno)
+       {
+         if (options.debug)
+           {
+             _G.debugLine = 1;
+             emitcode ("", "C$%s$%d$%d$%d ==.",
+                       FileBaseName (ic->filename), ic->lineno,
+                       ic->level, ic->block);
+             _G.debugLine = 0;
+           }
+         emitcode (";", "%s %d", ic->filename, ic->lineno);
+         cln = ic->lineno;
+       }
+      /* if the result is marked as
+         spilt and rematerializable or code for
+         this has already been generated then
+         do nothing */
+      if (resultRemat (ic) || ic->generated)
+       continue;
+
+      /* depending on the operation */
+      switch (ic->op)
+       {
+       case '!':
+         genNot (ic);
+         break;
+
+       case '~':
+         genCpl (ic);
+         break;
+
+       case UNARYMINUS:
+         genUminus (ic);
+         break;
+
+       case IPUSH:
+         genIpush (ic);
+         break;
+
+       case IPOP:
+         /* IPOP happens only when trying to restore a
+            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
+            we need to check for this condition and handle it */
+         if (ic->next &&
+             ic->next->op == IFX &&
+             regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
+           genIfx (ic->next, ic);
+         else
+           genIpop (ic);
+         break;
+
+       case CALL:
+         genCall (ic);
+         break;
+
+       case PCALL:
+         genPcall (ic);
+         break;
+
+       case FUNCTION:
+         genFunction (ic);
+         break;
+
+       case ENDFUNCTION:
+         genEndFunction (ic);
+         break;
+
+       case RETURN:
+         genRet (ic);
+         break;
+
+       case LABEL:
+         genLabel (ic);
+         break;
+
+       case GOTO:
+         genGoto (ic);
+         break;
+
+       case '+':
+         genPlus (ic);
+         break;
+
+       case '-':
+         if (!genDjnz (ic, ifxForOp (IC_RESULT (ic), ic)))
+           genMinus (ic);
+         break;
+
+       case '*':
+         genMult (ic);
+         break;
+
+       case '/':
+         genDiv (ic);
+         break;
+
+       case '%':
+         genMod (ic);
+         break;
+
+       case '>':
+         genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic));
+         break;
+
+       case '<':
+         genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic));
+         break;
+
+       case LE_OP:
+       case GE_OP:
+       case NE_OP:
+
+         /* note these two are xlated by algebraic equivalence
+            during parsing SDCC.y */
+         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                 "got '>=' or '<=' shouldn't have come here");
+         break;
+
+       case EQ_OP:
+         genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic));
+         break;
+
+       case AND_OP:
+         genAndOp (ic);
+         break;
+
+       case OR_OP:
+         genOrOp (ic);
+         break;
+
+       case '^':
+         genXor (ic, ifxForOp (IC_RESULT (ic), ic));
+         break;
+
+       case '|':
+         genOr (ic, ifxForOp (IC_RESULT (ic), ic));
+         break;
+
+       case BITWISEAND:
+         genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
+         break;
+
+       case INLINEASM:
+         genInline (ic);
+         break;
+
+       case RRC:
+         genRRC (ic);
+         break;
+
+       case RLC:
+         genRLC (ic);
+         break;
+
+       case GETHBIT:
+         genGetHbit (ic);
+         break;
+
+       case LEFT_OP:
+         genLeftShift (ic);
+         break;
+
+       case RIGHT_OP:
+         genRightShift (ic);
+         break;
+
+       case GET_VALUE_AT_ADDRESS:
+         genPointerGet (ic,hasInc(IC_LEFT(ic),ic));
+         break;
+
+       case '=':
+         if (POINTER_SET (ic))
+           genPointerSet (ic,hasInc(IC_RESULT(ic),ic));
+         else
+           genAssign (ic);
+         break;
+
+       case IFX:
+         genIfx (ic, NULL);
+         break;
+
+       case ADDRESS_OF:
+         genAddrOf (ic);
+         break;
+
+       case JUMPTABLE:
+         genJumpTab (ic);
+         break;
+
+       case CAST:
+         genCast (ic);
+         break;
+
+       case RECEIVE:
+         genReceive (ic);
+         break;
+
+       case SEND:
+         addSet (&_G.sendSet, ic);
+         break;
+
+       case ARRAYINIT:
+           genArrayInit(ic);
+           break;
+           
+       default:
+         ic = ic;
+       }
+    }
+
+
+  /* now we are ready to call the
+     peep hole optimizer */
+  if (!options.nopeep)
+    peepHole (&lineHead);
+
+  /* now do the actual printing */
+  printLine (lineHead, codeOutFile);
+  return;
+}