* src/mcs51/gen.c (genFunction): optimize RECEIVE in reentrant
[fw/sdcc] / src / ds390 / gen.c
index d5c29aa6505e10e8c5fc7df2e4153a306fc6392f..e5670acc03530c9791114e466cfdc17316beaeed 100644 (file)
 #include <string.h>
 #include <ctype.h>
 
-#include <common.h>
+#include "common.h"
+#include "main.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);
@@ -96,6 +80,7 @@ static struct
     short dptrInUse;
     short dptr1InUse;
     set *sendSet;
+    iCode *current_iCode;
   }
 _G;
 
@@ -109,14 +94,9 @@ static void saveRBank (int, iCode *, bool);
                          (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 MOVA(x) _movA(x)
+#define MOVB(x) _movB(x)
+                
 #define CLRC    emitcode("clr","c")
 #define SETC    emitcode("setb","c")
 
@@ -152,6 +132,9 @@ static unsigned char SRMask[] =
                                emitcode ("","!tlabeldef",lbl->key+100);        \
                        }}
 
+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. */
 
 /*-----------------------------------------------------------------*/
 /* emitcode - writes the code into a file : for now it is simple    */
@@ -159,33 +142,73 @@ static unsigned char SRMask[] =
 static void
 emitcode (char *inst, char *fmt,...)
 {
-  va_list ap;
-  char lb[INITIAL_INLINEASM];
-  char *lbp = lb;
+    va_list ap;
+    char lb[INITIAL_INLINEASM];
+    char *lbp = lb;
+    
+    va_start (ap, fmt);
+    
+    if (inst && *inst)
+    {
+       if (fmt && *fmt)
+       {
+           SNPRINTF (lb, sizeof(lb), "%s\t", inst);
+       }
+       else
+       {
+           SNPRINTF (lb, sizeof(lb), "%s", inst);
+       }
+       
+       tvsprintf (lb + strlen(lb), sizeof(lb) - strlen(lb), 
+                  fmt, ap);
+    }
+    else
+    {
+       tvsprintf (lb, sizeof(lb), fmt, ap);
+    }
+    
 
-  va_start (ap, fmt);
+    while (isspace (*lbp))
+    {
+       lbp++;
+    }
 
-  if (inst && *inst)
+    if (lbp && *lbp)
     {
-      if (fmt && *fmt)
-       sprintf (lb, "%s\t", inst);
-      else
-       sprintf (lb, "%s", inst);
-      tvsprintf (lb + (strlen (lb)), fmt, ap);
+       lineCurr = (lineCurr ?
+                   connectLine (lineCurr, newLineNode (lb)) :
+                   (lineHead = newLineNode (lb)));
     }
-  else
-    tvsprintf (lb, fmt, ap);
+    
+    lineCurr->isInline = _G.inLine;
+    lineCurr->isDebug = _G.debugLine;
+    lineCurr->ic = _G.current_iCode;
+    lineCurr->aln = ds390newAsmLineNode(_currentDPS);
+    va_end (ap);
+}
 
-  while (isspace (*lbp))
-    lbp++;
+//
+// Move the passed value into A unless it is already there.
+// 
+static void
+_movA(const char *s)
+{
+    if (strcmp(s,"a") && strcmp(s,"acc"))
+    { 
+       emitcode("mov","a,%s",s);
+    } 
+}
 
-  if (lbp && *lbp)
-    lineCurr = (lineCurr ?
-               connectLine (lineCurr, newLineNode (lb)) :
-               (lineHead = newLineNode (lb)));
-  lineCurr->isInline = _G.inLine;
-  lineCurr->isDebug = _G.debugLine;
-  va_end (ap);
+//
+// Move the passed value into B unless it is already there.
+// 
+static void
+_movB(const char *s)
+{
+    if (strcmp(s,"b"))
+    { 
+       emitcode("mov","b,%s",s);
+    } 
 }
 
 /*-----------------------------------------------------------------*/
@@ -194,8 +217,8 @@ emitcode (char *inst, char *fmt,...)
 static regs *
 getFreePtr (iCode * ic, asmop ** aopp, bool result)
 {
-  bool r0iu = FALSE, r1iu = FALSE;
-  bool r0ou = FALSE, r1ou = FALSE;
+  bool r0iu, r1iu;
+  bool r0ou, r1ou;
 
   /* the logic: if r0 & r1 used in the instruction
      then we are in trouble otherwise */
@@ -277,6 +300,8 @@ endOfWorld:
   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
          "getFreePtr should never reach here");
   exit (1);
+    
+  return NULL; // notreached, but makes compiler happy.
 }
 
 /*-----------------------------------------------------------------*/
@@ -292,9 +317,6 @@ newAsmop (short 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  */
@@ -420,6 +442,72 @@ pointerCode (sym_link * etype)
 
 }
 
+/*-----------------------------------------------------------------*/
+/* leftRightUseAcc - returns size of accumulator use by operands   */
+/*-----------------------------------------------------------------*/
+static int
+leftRightUseAcc(iCode *ic)
+{
+  operand *op;
+  int size;
+  int accuseSize = 0;
+  int accuse = 0;
+  
+  if (!ic)
+    {
+      werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+             "null iCode pointer");
+      return 0;
+    }
+
+  if (ic->op == IFX)
+    {
+      op = IC_COND (ic);
+      if (IS_SYMOP (op) && OP_SYMBOL (op) && OP_SYMBOL (op)->accuse)
+        {
+          accuse = 1;
+          size = getSize (OP_SYMBOL (op)->type);
+          if (size>accuseSize)
+            accuseSize = size;
+        }
+    }
+  else if (ic->op == JUMPTABLE)
+    {
+      op = IC_JTCOND (ic);
+      if (IS_SYMOP (op) && OP_SYMBOL (op) && OP_SYMBOL (op)->accuse)
+        {
+          accuse = 1;
+          size = getSize (OP_SYMBOL (op)->type);
+          if (size>accuseSize)
+            accuseSize = size;
+        }
+    }
+  else
+    {
+      op = IC_LEFT (ic);
+      if (IS_SYMOP (op) && OP_SYMBOL (op) && OP_SYMBOL (op)->accuse)
+        {
+          accuse = 1;
+          size = getSize (OP_SYMBOL (op)->type);
+          if (size>accuseSize)
+            accuseSize = size;
+        }
+      op = IC_RIGHT (ic);
+      if (IS_SYMOP (op) && OP_SYMBOL (op) && OP_SYMBOL (op)->accuse)
+        {
+          accuse = 1;
+          size = getSize (OP_SYMBOL (op)->type);
+          if (size>accuseSize)
+            accuseSize = size;
+        }
+    }
+  
+  if (accuseSize)
+    return accuseSize;
+  else
+    return accuse;
+}
+
 /*-----------------------------------------------------------------*/
 /* aopForSym - for a true symbol                                   */
 /*-----------------------------------------------------------------*/
@@ -428,10 +516,17 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
 {
   asmop *aop;
   memmap *space = SPEC_OCLS (sym->etype);
+  int accuse = leftRightUseAcc (ic);
 
   /* if already has one */
   if (sym->aop)
-    return sym->aop;
+    {
+      if ((sym->aop->type == AOP_DPTR && useDP2)
+          || (sym->aop->type == AOP_DPTR2 && !useDP2))
+       sym->aop = NULL;
+      else
+        return sym->aop;
+    }
 
   /* assign depending on the storage class */
   /* if it is on the stack or indirectly addressable */
@@ -449,10 +544,10 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
 
          if (sym->onStack)
            {
-             if (_G.accInUse)
+             if (_G.accInUse || accuse)
                emitcode ("push", "acc");
 
-             if (_G.bInUse)
+             if (_G.bInUse || (accuse>1))
                emitcode ("push", "b");
 
              emitcode ("mov", "a,_bp");
@@ -463,10 +558,10 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
              emitcode ("mov", "%s,a",
                        aop->aopu.aop_ptr->name);
 
-             if (_G.bInUse)
+             if (_G.bInUse || (accuse>1))
                emitcode ("pop", "b");
 
-             if (_G.accInUse)
+             if (_G.accInUse || accuse)
                emitcode ("pop", "acc");
            }
          else
@@ -500,14 +595,20 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
        if (stack_val < 0 && stack_val > -5) { /* between -5 & -1 */
            if (useDP2) {
                if (options.model == MODEL_FLAT24)
-                   emitcode ("mov", "dpx1,#!constbyte", (options.stack_loc >> 16) & 0xff);
-               TR_DPTR("#2");
+               {
+                   emitcode ("mov", "dpx1,#!constbyte",
+                             (options.stack_loc >> 16) & 0xff);
+               }
                emitcode ("mov", "dph1,_bpx+1");
+               
                emitcode ("mov", "dpl1,_bpx");
                emitcode ("mov","dps,#1");
            } else {
                if (options.model == MODEL_FLAT24)
-                   emitcode ("mov", "dpx,#!constbyte", (options.stack_loc >> 16) & 0xff);
+               {
+                   emitcode ("mov", "dpx,#!constbyte",
+                             (options.stack_loc >> 16) & 0xff);
+               }
                emitcode ("mov", "dph,_bpx+1");
                emitcode ("mov", "dpl,_bpx");
            }
@@ -519,10 +620,10 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
                emitcode("mov","dps,#0");
            }
        }  else {
-           if (_G.accInUse)
+           if (_G.accInUse || accuse)
                emitcode ("push", "acc");
            
-           if (_G.bInUse)
+           if (_G.bInUse || (accuse>1))
                emitcode ("push", "b");
        
            emitcode ("mov", "a,_bpx");
@@ -533,21 +634,26 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
            emitcode ("subb","a,#!constbyte",(stack_val >> 8) & 0xff);
            if (useDP2) {
                if (options.model == MODEL_FLAT24)
-                   emitcode ("mov", "dpx1,#!constbyte", (options.stack_loc >> 16) & 0xff);
-               TR_DPTR("#2");
+               {
+                   emitcode ("mov", "dpx1,#!constbyte",
+                             (options.stack_loc >> 16) & 0xff);
+               }
                emitcode ("mov", "dph1,a");
                emitcode ("mov", "dpl1,b");
            } else {
                if (options.model == MODEL_FLAT24)
-                   emitcode ("mov", "dpx,#!constbyte", (options.stack_loc >> 16) & 0xff);
+               {
+                   emitcode ("mov", "dpx,#!constbyte",
+                             (options.stack_loc >> 16) & 0xff);
+               }
                emitcode ("mov", "dph,a");
                emitcode ("mov", "dpl,b");
            }
            
-           if (_G.bInUse)
+           if (_G.bInUse || (accuse>1))
                emitcode ("pop", "b");
            
-           if (_G.accInUse)
+           if (_G.accInUse || accuse)
                emitcode ("pop", "acc");
        }
        sym->aop = aop = newAsmop ((short) (useDP2 ? AOP_DPTR2 : AOP_DPTR));
@@ -573,15 +679,14 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
     }
 
   /* special case for a function */
-  if (IS_FUNC (sym->type))
+  if (IS_FUNC (sym->type) && !(sym->isitmp))
     {
       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->aopu.aop_immd.aop_immd1 = Safe_strdup(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));
@@ -638,24 +743,32 @@ aopForRemat (symbol * sym)
     }
 
   if (val)
-    sprintf (buffer, "(%s %c 0x%04x)",
-            OP_SYMBOL (IC_LEFT (ic))->rname,
-            val >= 0 ? '+' : '-',
-            abs (val) & 0xffff);
-  else {
+  {
+      SNPRINTF (buffer, sizeof(buffer),
+               "(%s %c 0x%04x)",
+               OP_SYMBOL (IC_LEFT (ic))->rname,
+               val >= 0 ? '+' : '-',
+               abs (val) & 0xffffff);
+  }
+  else 
+  {
       if (IS_ASSIGN_ICODE(ic) && isOperandLiteral(IC_RIGHT(ic)))
-         sprintf(buffer,"0x%x",(int) operandLitValue (IC_RIGHT (ic)));
+      {
+         SNPRINTF(buffer, sizeof(buffer), 
+                  "0x%x",(int) operandLitValue (IC_RIGHT (ic)));
+      }
       else
-         strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
+      {
+         strncpyz (buffer, OP_SYMBOL (IC_LEFT (ic))->rname, sizeof(buffer));
+      }
   }
 
-  aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1);
-  strcpy (aop->aopu.aop_immd.aop_immd1, buffer);
+  aop->aopu.aop_immd.aop_immd1 = Safe_strdup(buffer);  
   /* set immd2 field if required */
-  if (aop->aopu.aop_immd.from_cast_remat) {
-         tsprintf(buffer,"#!constbyte",ptr_type);
-         aop->aopu.aop_immd.aop_immd2 = Safe_calloc (1, strlen (buffer) + 1);
-         strcpy (aop->aopu.aop_immd.aop_immd2, buffer);
+  if (aop->aopu.aop_immd.from_cast_remat) 
+  {
+      tsprintf(buffer, sizeof(buffer), "#!constbyte",ptr_type);
+      aop->aopu.aop_immd.aop_immd2 = Safe_strdup(buffer);
   }
 
   return aop;
@@ -759,6 +872,14 @@ operandsEqu (operand * op1, operand * op2)
       (sym2->usl.spillLoc == sym1))
     return TRUE;
 
+  /* are they spilt to the same location */
+  if (IS_ITEMP (op2) &&
+      IS_ITEMP (op1) &&
+      sym2->isspilt &&
+      sym1->isspilt &&
+      (sym1->usl.spillLoc == sym2->usl.spillLoc))
+    return TRUE;
+    
   return FALSE;
 }
 
@@ -818,13 +939,23 @@ aopOp (operand * op, iCode * ic, bool result, bool useDP2)
 
   /* if already has a asmop then continue */
   if (op->aop)
-    return;
+    {
+      if ((op->aop->type == AOP_DPTR && useDP2)
+          || (op->aop->type == AOP_DPTR2 && !useDP2))
+       op->aop = NULL;
+      else
+        return;
+    }
 
   /* if the underlying symbol has a aop */
   if (IS_SYMOP (op) && OP_SYMBOL (op)->aop)
     {
       op->aop = OP_SYMBOL (op)->aop;
-      return;
+      if ((op->aop->type == AOP_DPTR && useDP2)
+          || (op->aop->type == AOP_DPTR2 && !useDP2))
+       op->aop = NULL;
+      else
+        return;
     }
 
   /* if this is a true symbol */
@@ -903,13 +1034,22 @@ aopOp (operand * op, iCode * ic, bool result, bool useDP2)
          aop->aopu.dptr = sym->dptr;
          return ;
       }
-      /* else spill location  */
-      if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
-         /* force a new aop if sizes differ */
-         sym->usl.spillLoc->aop = NULL;
-      }
-      sym->aop = op->aop = aop =
-       aopForSym (ic, sym->usl.spillLoc, result, useDP2);
+      
+      if (sym->usl.spillLoc)
+        {
+          if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
+            {
+             /* force a new aop if sizes differ */
+             sym->usl.spillLoc->aop = NULL;
+           }
+         sym->aop = op->aop = aop =
+                    aopForSym (ic, sym->usl.spillLoc, result, useDP2);
+         aop->size = getSize (sym->type);
+         return;
+        }
+      
+      /* else must be a dummy iTemp */
+      sym->aop = op->aop = aop = newAsmop (AOP_DUMMY);
       aop->size = getSize (sym->type);
       return;
     }
@@ -1051,24 +1191,25 @@ dealloc:
     }
 }
 
-/*------------------------------------------------------------------*/
-/* 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.               */
-/*------------------------------------------------------------------*/
+#define DEFAULT_ACC_WARNING 0
+static int saveAccWarn = DEFAULT_ACC_WARNING;
+
+/*-------------------------------------------------------------------*/
+/* aopGet - for fetching value of the aop                            */
+/*                                                                  */
+/* Set saveAcc to NULL if you are sure it is OK to clobber the value */
+/* in the accumulator. Set it to the name of a free register         */
+/* if acc must be preserved; the register will be used to preserve   */
+/* acc temporarily and to return the result byte.                   */
+/*-------------------------------------------------------------------*/
 
 static char *
-aopGet (asmop * aop,
-       int offset,
-       bool bit16,
-       bool dname,
-       bool canClobberACC)
+aopGet (asmop *aop,
+       int   offset,
+       bool  bit16,
+       bool  dname,
+       char  *saveAcc)
 {
-  char *s = buffer;
-  char *rs;
-
   /* offset is greater than
      size then zero */
   if (offset > (aop->size - 1) &&
@@ -1078,6 +1219,8 @@ aopGet (asmop * aop,
   /* depending on type */
   switch (aop->type)
     {
+    case AOP_DUMMY:
+      return zero;
 
     case AOP_R0:
     case AOP_R1:
@@ -1100,10 +1243,8 @@ aopGet (asmop * aop,
          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;
+      SNPRINTF (buffer, sizeof(buffer), "@%s", aop->aopu.aop_ptr->name);
+      return Safe_strdup(buffer);      
 
     case AOP_DPTRn:
        assert(offset <= 3);
@@ -1115,11 +1256,18 @@ aopGet (asmop * aop,
       if (aop->type == AOP_DPTR2)
        {
          genSetDPTR (1);
-         if (!canClobberACC)
-           {
-                   TR_AP("#1");
-                   emitcode ("xch", "a, %s", DP2_RESULT_REG);
-           }
+       }
+       
+      if (saveAcc)
+       {
+           TR_AP("#1");
+//         if (aop->type != AOP_DPTR2)
+//         {
+//             if (saveAccWarn) { fprintf(stderr, "saveAcc for DPTR...\n"); }
+//             emitcode(";", "spanky: saveAcc for DPTR");
+//         }
+           
+           emitcode ("xch", "a, %s", saveAcc);
        }
 
       _flushLazyDPS ();
@@ -1150,54 +1298,76 @@ aopGet (asmop * aop,
       if (aop->type == AOP_DPTR2)
        {
          genSetDPTR (0);
-         if (!canClobberACC)
-           {
+       }
+       
+       if (saveAcc)
+       {
        TR_AP("#2");
-             emitcode ("xch", "a, %s", DP2_RESULT_REG);
-             return DP2_RESULT_REG;
-           }
+             emitcode ("xch", "a, %s", saveAcc);
+//           if (strcmp(saveAcc, "_ap"))
+//           {
+//               emitcode(";", "spiffy: non _ap return from aopGet.");
+//           }
+                 
+             return saveAcc;
        }
       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) {
+      if (aop->aopu.aop_immd.from_cast_remat && (offset == (aop->size-1))) 
+      {
+         SNPRINTF(buffer, sizeof(buffer), 
+                  "%s",aop->aopu.aop_immd.aop_immd2);
+      } 
+      else if (bit16)
+      {
+        SNPRINTF(buffer, sizeof(buffer), 
+                 "#%s", aop->aopu.aop_immd.aop_immd1);
+      }
+      else if (offset) 
+      {
          switch (offset) {
          case 1:
-             tsprintf(s,"#!his",aop->aopu.aop_immd.aop_immd1);
+             tsprintf(buffer, sizeof(buffer),
+                      "#!his",aop->aopu.aop_immd.aop_immd1);
              break;
          case 2:
-             tsprintf(s,"#!hihis",aop->aopu.aop_immd.aop_immd1);
+             tsprintf(buffer, sizeof(buffer), 
+                      "#!hihis",aop->aopu.aop_immd.aop_immd1);
              break;
          case 3:
-             tsprintf(s,"#!hihihis",aop->aopu.aop_immd.aop_immd1);
+             tsprintf(buffer, sizeof(buffer),
+                      "#!hihihis",aop->aopu.aop_immd.aop_immd1);
              break;
          default: /* should not need this (just in case) */
-             sprintf (s, "#(%s >> %d)",
+             SNPRINTF (buffer, sizeof(buffer), 
+                       "#(%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;
+      {
+       SNPRINTF (buffer, sizeof(buffer), 
+                 "#%s", aop->aopu.aop_immd.aop_immd1);
+      }
+      return Safe_strdup(buffer);      
 
     case AOP_DIR:
       if (offset)
-       sprintf (s, "(%s + %d)",
+      {
+       SNPRINTF (buffer, sizeof(buffer),
+                 "(%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;
+      {
+       SNPRINTF(buffer, sizeof(buffer), 
+                "%s", aop->aopu.aop_dir);
+      }
+
+      return Safe_strdup(buffer);
 
     case AOP_REG:
       if (dname)
@@ -1232,6 +1402,8 @@ aopGet (asmop * aop,
   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
          "aopget got unsupported aop->type");
   exit (1);
+    
+  return NULL;  // not reached, but makes compiler happy.
 }
 /*-----------------------------------------------------------------*/
 /* aopPut - puts a string for a aop                                */
@@ -1239,8 +1411,6 @@ aopGet (asmop * 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__,
@@ -1252,16 +1422,28 @@ aopPut (asmop * aop, char *s, int offset)
   /* depending on where it is ofcourse */
   switch (aop->type)
     {
+    case AOP_DUMMY:
+      MOVA (s);                /* read s in case it was volatile */
+      break;
+      
     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);
+        if (offset)
+       {
+           SNPRINTF (buffer, sizeof(buffer),
+                     "(%s + %d)",
+                     aop->aopu.aop_dir, offset);
+       }
+       else
+       {
+           SNPRINTF (buffer, sizeof(buffer), 
+                    "%s", aop->aopu.aop_dir);
+       }
+       
 
+       if (strcmp (buffer, s))
+       {
+           emitcode ("mov", "%s,%s", buffer, s);
+       }
       break;
 
     case AOP_REG:
@@ -1277,11 +1459,15 @@ aopPut (asmop * aop, char *s, int offset)
              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);
+           {
+               emitcode ("mov", "%s,%s",
+                         aop->aopu.aop_reg[offset]->dname, s);
+           }
+           else
+           {
+               emitcode ("mov", "%s,%s",
+                         aop->aopu.aop_reg[offset]->name, s);
+           }
        }
       break;
 
@@ -1364,14 +1550,16 @@ aopPut (asmop * aop, char *s, int offset)
               strcmp (s, "r6") == 0 ||
               strcmp (s, "r7") == 0)
        {
-         char buffer[10];
-         sprintf (buffer, "a%s", s);
+         char buff[10];
+         SNPRINTF(buff, sizeof(buff), 
+                  "a%s", s);
          emitcode ("mov", "@%s,%s",
-                   aop->aopu.aop_ptr->name, buffer);
+                   aop->aopu.aop_ptr->name, buff);
+       }
+       else
+       {
+           emitcode ("mov", "@%s,%s", aop->aopu.aop_ptr->name, s);
        }
-      else
-       emitcode ("mov", "@%s,%s", aop->aopu.aop_ptr->name, s);
-
       break;
 
     case AOP_STK:
@@ -1494,7 +1682,12 @@ reAdjustPreg (asmop * aop)
                       (x->aopu.aop_reg[0] == ds390_regWithIdx(R0_IDX) || \
                       x->aopu.aop_reg[0] == ds390_regWithIdx(R1_IDX) )))
 #define AOP_INDPTRn(x) (AOP_TYPE(x) == AOP_DPTRn)
-#define AOP_USESDPTR(x) (AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_STR)
+#define AOP_USESDPTR(x) ((AOP_TYPE(x) == AOP_DPTR) || (AOP_TYPE(x) == AOP_STR))
+#define AOP_USESDPTR2(x) ((AOP_TYPE(x) == AOP_DPTR2) || (AOP_TYPE(x) == AOP_DPTRn))
+
+// The following two macros can be used even if the aop has not yet been aopOp'd.
+#define AOP_IS_STR(x) (IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
+#define AOP_IS_DPTRn(x) (IS_SYMOP(x) && OP_SYMBOL(x)->dptr)
 
 /* Workaround for DS80C390 bug: div ab may return bogus results
  * if A is accessed in instruction immediately before the div.
@@ -1510,62 +1703,20 @@ reAdjustPreg (asmop * aop)
        * thus avoiding touching A right before the div. \
        */             \
       D(emitcode(";", "DS80C390 div bug: rearranged ops.");); \
-      L = aopGet(AOP(LEFT),0,FALSE,FALSE,TRUE);     \
+      L = aopGet(AOP(LEFT),0,FALSE,FALSE,NULL);     \
       MOVA(L);            \
-      emitcode("mov","b,%s",aopGet(AOP(RIGHT),0,FALSE,FALSE,FALSE));\
+      L = aopGet(AOP(RIGHT),0,FALSE,FALSE,"b"); \
+      MOVB(L); \
     }               \
     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);   \
+      emitcode("mov","b,%s",aopGet(AOP(RIGHT),0,FALSE,FALSE,NULL));\
+      L = aopGet(AOP(LEFT),0,FALSE,FALSE,NULL);   \
       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", "!tlabel", (tlbl->key + 100));
-  aopPut (res->aop, zero, 1);
-  emitcode ("", "!tlabeldef", (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       */
@@ -1662,8 +1813,7 @@ toBoolean (operand * oper)
    */
   if (opIsGptr (oper))
     {
-      D (emitcode (";", "toBoolean: generic ptr special case.");
-       );
+      D (emitcode (";", "toBoolean: generic ptr special case."););
       size--;
     }
 
@@ -1671,22 +1821,28 @@ toBoolean (operand * oper)
   if (AOP_NEEDSACC (oper) && size)
     {
       usedB = TRUE;
-      emitcode ("push", "b");
-      emitcode ("mov", "b, %s", aopGet (AOP (oper), 0, FALSE, FALSE, FALSE));
+      if (_G.bInUse)
+      {
+         emitcode ("push", "b");
+      }
+      MOVB (aopGet (AOP (oper), 0, FALSE, FALSE, NULL));
     }
   else
     {
-      MOVA (aopGet (AOP (oper), 0, FALSE, FALSE, TRUE));
+      MOVA (aopGet (AOP (oper), 0, FALSE, FALSE, NULL));
     }
+    
   while (size--)
     {
       if (usedB)
        {
-         emitcode ("orl", "b,%s", aopGet (AOP (oper), offset++, FALSE, FALSE, FALSE));
+         emitcode ("orl", "b,%s",
+                   aopGet (AOP (oper), offset++, FALSE, FALSE, NULL));
        }
       else
        {
-         emitcode ("orl", "a,%s", aopGet (AOP (oper), offset++, FALSE, FALSE, FALSE));
+         emitcode ("orl", "a,%s",
+                   aopGet (AOP (oper), offset++, FALSE, FALSE, NULL));
        }
     }
   _endLazyDPSEvaluation ();
@@ -1694,7 +1850,11 @@ toBoolean (operand * oper)
   if (usedB)
     {
       emitcode ("mov", "a,b");
-      emitcode ("pop", "b");
+      if (_G.bInUse)
+      {
+         emitcode ("pop", "b");
+      }
+       
     }
 }
 
@@ -1706,14 +1866,12 @@ static void
 genNot (iCode * ic)
 {
   symbol *tlbl;
-  sym_link *optype = operandType (IC_LEFT (ic));
 
-  D (emitcode (";", "genNot ");
-    );
+  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);
+  aopOp (IC_RESULT (ic), ic, TRUE, AOP_USESDPTR(IC_LEFT (ic)));
 
   /* if in bit space then a special case */
   if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
@@ -1724,13 +1882,6 @@ genNot (iCode * 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);
@@ -1755,13 +1906,12 @@ genCpl (iCode * ic)
   int size;
   symbol *tlbl;
 
-  D (emitcode (";", "genCpl ");
-    );
+  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);
+  aopOp (IC_RESULT (ic), ic, TRUE, AOP_USESDPTR(IC_LEFT (ic)));
 
   /* special case if in bit space */
   if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY) {
@@ -1773,7 +1923,7 @@ genCpl (iCode * ic)
     }
     tlbl=newiTempLabel(NULL);
     emitcode ("cjne", "%s,#0x01,%05d$", 
-             aopGet(AOP(IC_LEFT(ic)), 0, FALSE,FALSE,TRUE), tlbl->key+100);
+             aopGet(AOP(IC_LEFT(ic)), 0, FALSE,FALSE,NULL), tlbl->key+100);
     emitcode ("", "%05d$:", tlbl->key+100);
     outBitC (IC_RESULT(ic));
     goto release;
@@ -1783,8 +1933,7 @@ genCpl (iCode * ic)
   _startLazyDPSEvaluation ();
   while (size--)
     {
-      char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, TRUE);
-      MOVA (l);
+      MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, NULL));
       emitcode ("cpl", "a");
       aopPut (AOP (IC_RESULT (ic)), "a", offset++);
     }
@@ -1804,27 +1953,26 @@ 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");
-    );
-
+    
+  D(emitcode (";", "genUminusFloat"););
+  
+  /* for this we just copy and then flip the bit */
+    
   _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),
+             aopGet (AOP (op), offset, FALSE, FALSE, NULL),
              offset);
       offset++;
     }
+  
+  MOVA(aopGet (AOP (op), offset, FALSE, FALSE, NULL));
+
+  emitcode ("cpl", "acc.7");
+  aopPut (AOP (result), "a", offset);    
   _endLazyDPSEvaluation ();
 }
 
@@ -1835,15 +1983,13 @@ static void
 genUminus (iCode * ic)
 {
   int offset, size;
-  sym_link *optype, *rtype;
-
-  D (emitcode (";", "genUminus ");
-    );
+  sym_link *optype;
 
+  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);
+  aopOp (IC_RESULT (ic), ic, TRUE, (AOP_TYPE(IC_LEFT (ic)) == AOP_DPTR));
 
   /* if both in bit space then special
      case */
@@ -1858,7 +2004,6 @@ genUminus (iCode * ic)
     }
 
   optype = operandType (IC_LEFT (ic));
-  rtype = operandType (IC_RESULT (ic));
 
   /* if float then do float stuff */
   if (IS_FLOAT (optype))
@@ -1873,7 +2018,7 @@ genUminus (iCode * ic)
   _startLazyDPSEvaluation ();
   while (size--)
     {
-      char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, TRUE);
+      char *l = aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, NULL);
       if (!strcmp (l, "a"))
        {
          if (offset == 0)
@@ -1894,7 +2039,7 @@ genUminus (iCode * ic)
 
   /* 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)))))
+  if ((size = (AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_LEFT(ic)))) != 0)
     {
       emitcode ("rlc", "a");
       emitcode ("subb", "a,acc");
@@ -1961,12 +2106,15 @@ saveRegisters (iCode * lic)
 
   /* if the registers have been saved already then
      do nothing */
-  if (ic->regsSaved || IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic)))) return ;
+  if (ic->regsSaved 
+      || (IS_SYMOP(IC_LEFT(ic)) && IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic))) && !TARGET_IS_DS400) )
+    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;
+  if (IS_SYMOP(IC_LEFT(ic)) &&
+      IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) {
+      int i;
       rsave = newBitVect(ic->rMask->size);
       for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
          if (bitVectBitValue(ic->rMask,i))
@@ -2021,7 +2169,7 @@ unsaveRegisters (iCode * ic)
   bitVect *rsave;
 
   if (IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) {
-      int i =0;
+      int i;
       rsave = newBitVect(ic->rMask->size);
       for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
          if (bitVectBitValue(ic->rMask,i))
@@ -2048,7 +2196,7 @@ pushSide (operand * oper, int size)
   _startLazyDPSEvaluation ();
   while (size--)
     {
-      char *l = aopGet (AOP (oper), offset++, FALSE, TRUE, FALSE);
+      char *l = aopGet (AOP (oper), offset++, FALSE, TRUE, NULL);
       if (AOP_TYPE (oper) != AOP_REG &&
          AOP_TYPE (oper) != AOP_DIR &&
          strcmp (l, "a"))
@@ -2070,7 +2218,24 @@ assignResultValue (operand * oper)
 {
   int offset = 0;
   int size = AOP_SIZE (oper);
+  bool pushedAcc = FALSE;
 
+  if (size == fReturnSizeDS390)
+  {
+      /* I don't think this case can ever happen... */
+      /* ACC is the last part of this. If writing the result
+       * uses AC, we must preserve it.
+       */
+      if (AOP_NEEDSACC(oper))
+      {
+         emitcode(";", "assignResultValue special case for ACC.");
+         emitcode("push", "acc");
+         pushedAcc = TRUE;
+         size--;
+      }
+  }
+    
+    
   _startLazyDPSEvaluation ();
   while (size--)
     {
@@ -2078,6 +2243,12 @@ assignResultValue (operand * oper)
       offset++;
     }
   _endLazyDPSEvaluation ();
+    
+  if (pushedAcc)
+    {
+       emitcode("pop", "acc");
+       aopPut(AOP(oper), "a", offset);
+    }
 }
 
 
@@ -2105,9 +2276,8 @@ genXpush (iCode * ic)
   while (size--)
     {
 
-      char *l = aopGet (AOP (IC_LEFT (ic)),
-                       offset++, FALSE, FALSE, TRUE);
-      MOVA (l);
+      MOVA (aopGet (AOP (IC_LEFT (ic)),
+                       offset++, FALSE, FALSE, NULL));
       emitcode ("movx", "@%s,a", r->name);
       emitcode ("inc", "%s", r->name);
 
@@ -2122,7 +2292,7 @@ genXpush (iCode * ic)
 }
 
 /*-----------------------------------------------------------------*/
-/* genIpush - genrate code for pushing this gets a little complex  */
+/* genIpush - generate code for pushing this gets a little complex  */
 /*-----------------------------------------------------------------*/
 static void
 genIpush (iCode * ic)
@@ -2148,7 +2318,7 @@ genIpush (iCode * ic)
       _startLazyDPSEvaluation ();
       while (size--)
        {
-         l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, TRUE, TRUE);
+         l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, TRUE, NULL);
          if (*l == '#')
            {
              MOVA (l);
@@ -2182,16 +2352,18 @@ genIpush (iCode * ic)
   _startLazyDPSEvaluation ();
   while (size--)
     {
-      l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, TRUE, FALSE);
+      l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, TRUE, NULL);
       if (AOP_TYPE (IC_LEFT (ic)) != AOP_REG &&
          AOP_TYPE (IC_LEFT (ic)) != AOP_DIR &&
-         strcmp (l, "a"))
+         strcmp (l, "acc"))
        {
          emitcode ("mov", "a,%s", l);
          emitcode ("push", "acc");
        }
       else
-       emitcode ("push", "%s", l);
+       {
+           emitcode ("push", "%s", l);
+       }
     }
   _endLazyDPSEvaluation ();
 
@@ -2221,7 +2393,7 @@ genIpop (iCode * ic)
   while (size--)
     {
       emitcode ("pop", "%s", aopGet (AOP (IC_LEFT (ic)), offset--,
-                                    FALSE, TRUE, TRUE));
+                                    FALSE, TRUE, NULL));
     }
   _endLazyDPSEvaluation ();
 
@@ -2381,13 +2553,13 @@ static void genSend(set *sendSet)
            _startLazyDPSEvaluation ();
            if (size>1) {
                aopOp (IC_LEFT (sic), sic, FALSE, 
-                      (IS_SYMOP(IC_LEFT(sic)) && OP_SYMBOL(IC_LEFT(sic))->ruonly ? FALSE : TRUE));
+                      (AOP_IS_STR(IC_LEFT(sic)) ? FALSE : TRUE));
            } else {
                aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
            }
            while (size--) {
                char *l = aopGet (AOP (IC_LEFT (sic)), offset,
-                                 FALSE, FALSE, TRUE);
+                                 FALSE, FALSE, NULL);
                if (strcmp (l, fReturn[offset])) {
                    emitcode ("mov", "%s,%s",
                              fReturn[offset],
@@ -2402,7 +2574,7 @@ static void genSend(set *sendSet)
            aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
            while (size--) {
                emitcode ("mov","b1_%d,%s",rb1_count++,aopGet (AOP (IC_LEFT (sic)), offset++,
-                                                               FALSE, FALSE, TRUE));
+                                                               FALSE, FALSE, NULL));
            }
            freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
        }
@@ -2410,6 +2582,18 @@ static void genSend(set *sendSet)
     }
 }
 
+static void
+adjustEsp(const char *reg)
+{
+    emitcode ("anl","%s,#3", reg);
+    if (TARGET_IS_DS400)
+    {
+       emitcode ("orl","%s,#!constbyte",
+                 reg,
+                 (options.stack_loc >> 8) & 0xff);
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* genCall - generates a call statement                            */
 /*-----------------------------------------------------------------*/
@@ -2426,7 +2610,7 @@ genCall (iCode * ic)
      the same register bank then we need to save the
      destination registers on the stack */
   dtype = operandType (IC_LEFT (ic));
-  if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) &&
+  if (currFunc && dtype && (!IFFUNC_ISNAKED(dtype) || TARGET_IS_DS400) &&
       (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) &&
       IFFUNC_ISISR (currFunc->type))
   {
@@ -2495,9 +2679,16 @@ genCall (iCode * ic)
          if (size > 1)
            {
              emitcode ("mov", "b,%s", fReturn[1]);
+             _G.bInUse++;
            }
 
+         _G.accInUse++;
          aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+         _G.accInUse--;
+         
+         if (size > 1)
+           _G.bInUse--;
+
          aopPut (AOP (IC_RESULT (ic)), "a", 0);
 
          if (size > 1)
@@ -2508,9 +2699,9 @@ genCall (iCode * ic)
        }
       else
        {
-         _G.accInUse++;
+         _G.bInUse++;
          aopOp (IC_RESULT (ic), ic, FALSE, TRUE);
-         _G.accInUse--;
+         _G.bInUse--;
 
          assignResultValue (IC_RESULT (ic));
 
@@ -2535,7 +2726,7 @@ genCall (iCode * ic)
              emitcode ("subb","a,#!constbyte",ic->parmBytes & 0xff);
              emitcode ("mov","sp,a");
              emitcode ("mov","a,esp");
-             emitcode ("anl","a,#3");
+             adjustEsp("a");
              emitcode ("subb","a,#!constbyte",(ic->parmBytes >> 8) & 0xff);
              emitcode ("mov","esp,a");   
              UNPROTECT_SP;
@@ -2582,7 +2773,7 @@ genPcall (iCode * ic)
      the same register bank then we need to save the
      destination registers on the stack */
   dtype = operandType (IC_LEFT (ic));
-  if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) &&
+  if (currFunc && dtype && (!IFFUNC_ISNAKED(dtype) || TARGET_IS_DS400) &&
       IFFUNC_ISISR (currFunc->type) &&
       (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype))) {
     saveRBank (FUNC_REGBANK (dtype), ic, TRUE);
@@ -2653,7 +2844,7 @@ genPcall (iCode * ic)
              emitcode ("subb","a,#!constbyte",ic->parmBytes & 0xff);
              emitcode ("mov","sp,a");
              emitcode ("mov","a,esp");
-             emitcode ("anl","a,#3");
+             adjustEsp("a");
              emitcode ("subb","a,#!constbyte",(ic->parmBytes >> 8) & 0xff);
              emitcode ("mov","esp,a");   
              UNPROTECT_SP;
@@ -2709,22 +2900,22 @@ resultRemat (iCode * ic)
 /*-----------------------------------------------------------------*/
 /* inExcludeList - return 1 if the string is in exclude Reg list   */
 /*-----------------------------------------------------------------*/
+static int
+regsCmp(void *p1, void *p2)
+{
+  return (STRCASECMP((char *)p1, (char *)(p2)) == 0);
+}
+
 static bool
 inExcludeList (char *s)
 {
-  int i = 0;
+  const char *p = setFirstItem(options.excludeRegsSet);
 
-  if (options.excludeRegs[i] &&
-      STRCASECMP (options.excludeRegs[i], "none") == 0)
+  if (p == NULL || STRCASECMP(p, "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;
+
+  return isinSetWith(options.excludeRegsSet, s, regsCmp);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2756,9 +2947,6 @@ genFunction (iCode * ic)
   
   if (options.stack_probe) 
       emitcode ("lcall","__stack_probe");
-  /* 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 */
@@ -2829,12 +3017,10 @@ genFunction (iCode * ic)
                  /* 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)))
+                     if (bitVectBitValue (sym->regsUsed, i))
                        emitcode ("push", "%s", ds390_regWithIdx (i)->dname);
                    }
                }
-
            }
          else
            {
@@ -2936,7 +3122,7 @@ genFunction (iCode * ic)
                     }
                }
            }
-           // jwk: this needs a closer look
+           // TODO: this needs a closer look
            SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave;
        }
     }
@@ -2954,8 +3140,7 @@ genFunction (iCode * ic)
              /* 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)))
+                 if (bitVectBitValue (sym->regsUsed, i))
                    {
                      emitcode ("push", "%s", ds390_regWithIdx (i)->dname);
                      _G.nRegsSaved++;
@@ -2980,7 +3165,7 @@ genFunction (iCode * ic)
          emitcode ("push","_bpx+1");
          emitcode ("mov","_bpx,%s",spname);
          emitcode ("mov","_bpx+1,esp");
-         emitcode ("anl","_bpx+1,#3");
+         adjustEsp("_bpx+1");
       } else {
          if (options.useXstack) {
              emitcode ("mov", "r0,%s", spname);
@@ -3009,7 +3194,7 @@ genFunction (iCode * ic)
              emitcode ("add","a,#!constbyte", ((short) sym->stack & 0xff));
              emitcode ("mov","sp,a");
              emitcode ("mov","a,esp");
-             emitcode ("anl","a,#3");
+             adjustEsp("a");
              emitcode ("addc","a,#!constbyte", (((short) sym->stack) >> 8) & 0xff);
              emitcode ("mov","esp,a");
              UNPROTECT_SP;
@@ -3037,6 +3222,17 @@ genFunction (iCode * ic)
       emitcode ("add", "a,#!constbyte", ((char) sym->xstack & 0xff));
       emitcode ("mov", "_spx,a");
     }
+  
+  /* if critical function then turn interrupts off */
+  if (IFFUNC_ISCRITICAL (ftype))
+    {
+      symbol *tlbl = newiTempLabel (NULL);
+      emitcode ("setb", "c");
+      emitcode ("jbc", "ea,%05d$", (tlbl->key + 100)); /* atomic test & clear */
+      emitcode ("clr", "c");
+      emitcode ("", "%05d$:", (tlbl->key + 100));
+      emitcode ("push", "psw"); /* save old ea via c in psw */
+    }
 
 }
 
@@ -3047,6 +3243,11 @@ static void
 genEndFunction (iCode * ic)
 {
   symbol *sym = OP_SYMBOL (IC_LEFT (ic));
+  lineNode *lnp = lineCurr;
+  bitVect *regsUsed;
+  bitVect *regsUsedPrologue;
+  bitVect *regsUnneeded;
+  int idx;
 
   D (emitcode (";", "genEndFunction "););
 
@@ -3056,6 +3257,12 @@ genEndFunction (iCode * ic)
       return;
   }
 
+  if (IFFUNC_ISCRITICAL (sym->type))
+    {
+      emitcode ("pop", "psw"); /* restore ea via c in psw */
+      emitcode ("mov", "ea,c");
+    }
+  
   if ((IFFUNC_ISREENT (sym->type) || options.stackAuto) &&
        (sym->stack || FUNC_HASSTACKPARM(sym->type))) {
 
@@ -3132,12 +3339,10 @@ genEndFunction (iCode * ic)
                  /* 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)))
+                     if (bitVectBitValue (sym->regsUsed, i))
                        emitcode ("pop", "%s", ds390_regWithIdx (i)->dname);
                    }
                }
-
            }
          else
            {
@@ -3159,7 +3364,6 @@ genEndFunction (iCode * ic)
             * 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;
          
@@ -3201,9 +3405,6 @@ genEndFunction (iCode * ic)
       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;
@@ -3221,9 +3422,6 @@ genEndFunction (iCode * ic)
     }
   else
     {
-      if (IFFUNC_ISCRITICAL (sym->type))
-       emitcode ("setb", "ea");
-
       if (IFFUNC_CALLEESAVES(sym->type))
        {
          int i;
@@ -3234,12 +3432,10 @@ genEndFunction (iCode * ic)
              /* 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)))
+                 if (bitVectBitValue (sym->regsUsed, i))
                    emitcode ("pop", "%s", ds390_regWithIdx (i)->dname);
                }
            }
-
        }
 
       /* if debug then send end of function */
@@ -3259,6 +3455,111 @@ genEndFunction (iCode * ic)
       emitcode ("ret", "");
     }
 
+  if (!port->peep.getRegsRead || !port->peep.getRegsWritten)
+    return;
+  
+  /* If this was an interrupt handler using bank 0 that called another */
+  /* function, then all registers must be saved; nothing to optimized. */
+  if (IFFUNC_ISISR (sym->type) && IFFUNC_HASFCALL(sym->type)
+      && !FUNC_REGBANK(sym->type))
+    return;
+    
+  /* There are no push/pops to optimize if not callee-saves or ISR */
+  if (!(FUNC_CALLEESAVES (sym->type) || FUNC_ISISR (sym->type)))
+    return;
+  
+  /* If there were stack parameters, we cannot optimize without also    */
+  /* fixing all of the stack offsets; this is too dificult to consider. */
+  if (FUNC_HASSTACKPARM(sym->type))
+    return;
+  
+  /* Compute the registers actually used */
+  regsUsed = newBitVect (ds390_nRegs);
+  regsUsedPrologue = newBitVect (ds390_nRegs);
+  while (lnp)
+    {
+      if (lnp->ic && lnp->ic->op == FUNCTION)
+        regsUsedPrologue = bitVectUnion (regsUsedPrologue, port->peep.getRegsWritten(lnp));
+      else
+        regsUsed = bitVectUnion (regsUsed, port->peep.getRegsWritten(lnp));
+      
+      if (lnp->ic && lnp->ic->op == FUNCTION && lnp->prev
+          && lnp->prev->ic && lnp->prev->ic->op == ENDFUNCTION)
+       break;
+      if (!lnp->prev)
+        break;
+      lnp = lnp->prev;
+    }
+
+  if (bitVectBitValue (regsUsedPrologue, DPS_IDX)
+      && !bitVectBitValue (regsUsed, DPS_IDX))
+    {
+      bitVectUnSetBit (regsUsedPrologue, DPS_IDX);
+    }
+    
+  if (bitVectBitValue (regsUsedPrologue, CND_IDX)
+      && !bitVectBitValue (regsUsed, CND_IDX))
+    {
+      regsUsed = bitVectUnion (regsUsed, regsUsedPrologue);
+      if (IFFUNC_ISISR (sym->type) && !FUNC_REGBANK(sym->type)
+          && !sym->stack)
+        bitVectUnSetBit (regsUsed, CND_IDX);
+    }
+  else
+    regsUsed = bitVectUnion (regsUsed, regsUsedPrologue);
+    
+  /* If this was an interrupt handler that called another function */
+  /* function, then assume working registers may be modified by it. */
+  if (IFFUNC_ISISR (sym->type) && IFFUNC_HASFCALL(sym->type))
+    {
+      regsUsed = bitVectSetBit (regsUsed, AP_IDX);
+      regsUsed = bitVectSetBit (regsUsed, DPX1_IDX);
+      regsUsed = bitVectSetBit (regsUsed, DPL1_IDX);
+      regsUsed = bitVectSetBit (regsUsed, DPH1_IDX);
+      regsUsed = bitVectSetBit (regsUsed, DPX_IDX);
+      regsUsed = bitVectSetBit (regsUsed, DPL_IDX);
+      regsUsed = bitVectSetBit (regsUsed, DPH_IDX);
+      regsUsed = bitVectSetBit (regsUsed, DPS_IDX);
+      regsUsed = bitVectSetBit (regsUsed, B_IDX);
+      regsUsed = bitVectSetBit (regsUsed, A_IDX);
+      regsUsed = bitVectSetBit (regsUsed, CND_IDX);
+    }
+
+  /* Remove the unneeded push/pops */
+  regsUnneeded = newBitVect (ds390_nRegs);
+  while (lnp)
+    {
+      if (lnp->ic && (lnp->ic->op == FUNCTION || lnp->ic->op == ENDFUNCTION))
+        {
+         if (!strncmp(lnp->line, "push", 4))
+           {
+             idx = bitVectFirstBit (port->peep.getRegsRead(lnp));
+             if (idx>=0 && !bitVectBitValue (regsUsed, idx))
+               {
+                 connectLine (lnp->prev, lnp->next);
+                 regsUnneeded = bitVectSetBit (regsUnneeded, idx);
+               }
+           }
+         if (!strncmp(lnp->line, "pop", 3) || !strncmp(lnp->line, "mov", 3))
+           {
+             idx = bitVectFirstBit (port->peep.getRegsWritten(lnp));
+             if (idx>=0 && !bitVectBitValue (regsUsed, idx))
+               {
+                 connectLine (lnp->prev, lnp->next);
+                 regsUnneeded = bitVectSetBit (regsUnneeded, idx);
+               }
+           }
+       }
+      lnp = lnp->next;
+    }  
+  
+  for (idx = 0; idx < regsUnneeded->size; idx++)
+    if (bitVectBitValue (regsUnneeded, idx))
+      emitcode ("", ";\teliminated unneeded push/pop %s", ds390_regWithIdx (idx)->dname);
+  
+  freeBitVect (regsUnneeded);
+  freeBitVect (regsUsed);
+  freeBitVect (regsUsedPrologue);
 }
 
 /*-----------------------------------------------------------------*/
@@ -3269,7 +3570,7 @@ static void genJavaNativeRet(iCode *ic)
     int i, size;
 
     aopOp (IC_LEFT (ic), ic, FALSE, 
-          (IS_SYMOP(IC_LEFT(ic)) && OP_SYMBOL(IC_LEFT(ic))->ruonly ? FALSE :TRUE));
+          AOP_IS_STR(IC_LEFT(ic)) ? FALSE :TRUE);
     size = AOP_SIZE (IC_LEFT (ic));
 
     assert (size <= 4);
@@ -3278,14 +3579,16 @@ static void genJavaNativeRet(iCode *ic)
     if (aopHasRegs(AOP(IC_LEFT(ic)),R0_IDX,R1_IDX) ||
        aopHasRegs(AOP(IC_LEFT(ic)),R2_IDX,R3_IDX)) {
        for (i = 0 ; i < size ; i++ ) {
-           emitcode ("push","%s",aopGet(AOP(IC_LEFT(ic)),i,FALSE,TRUE,FALSE));     
+           emitcode ("push","%s",
+                     aopGet(AOP(IC_LEFT(ic)),i,FALSE,TRUE,DP2_RESULT_REG));
        }
        for (i = (size-1) ; i >= 0 ; i--) {
            emitcode ("pop","a%s",javaRet[i]);
        }
     } else {
        for (i = 0 ; i < size ; i++) 
-           emitcode ("mov","%s,%s",javaRet[i],aopGet(AOP(IC_LEFT(ic)),i,FALSE,TRUE,FALSE));
+           emitcode ("mov","%s,%s",javaRet[i],
+                     aopGet(AOP(IC_LEFT(ic)),i,FALSE,TRUE,DP2_RESULT_REG));
     }
     for (i = size ; i < 4 ; i++ )
            emitcode ("mov","%s,#0",javaRet[i]);
@@ -3300,8 +3603,7 @@ genRet (iCode * ic)
 {
   int size, offset = 0, pushed = 0;
 
-  D (emitcode (";", "genRet ");
-    );
+  D (emitcode (";", "genRet "););
 
   /* if we have no return value then
      just generate the "ret" */
@@ -3317,7 +3619,7 @@ genRet (iCode * ic)
   /* 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));
+        (AOP_IS_STR(IC_LEFT(ic)) ? FALSE :TRUE));
   size = AOP_SIZE (IC_LEFT (ic));
 
   _startLazyDPSEvaluation ();
@@ -3327,7 +3629,7 @@ genRet (iCode * ic)
       if (AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR)
        {
          l = aopGet (AOP (IC_LEFT (ic)), offset++,
-                     FALSE, TRUE, FALSE);
+                     FALSE, TRUE, NULL);
          emitcode ("push", "%s", l);
          pushed++;
        }
@@ -3337,7 +3639,7 @@ genRet (iCode * ic)
           * is is OK to clobber it in the aopGet.
           */
          l = aopGet (AOP (IC_LEFT (ic)), offset,
-                     FALSE, FALSE, TRUE);
+                     FALSE, FALSE, NULL);
          if (strcmp (fReturn[offset], l))
            emitcode ("mov", "%s,%s", fReturn[offset++], l);
        }
@@ -3450,7 +3752,7 @@ genPlusIncr (iCode * ic)
   if (size == 1 && AOP(IC_LEFT(ic)) == AOP(IC_RESULT(ic)) &&
       AOP_TYPE(IC_LEFT(ic)) == AOP_DIR ) {
       while (icount--) {
-         emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE,FALSE));
+         emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE,NULL));
       }
       return TRUE;
   }
@@ -3462,9 +3764,10 @@ genPlusIncr (iCode * ic)
        (size > 1) &&
        (icount == 1))
     {
-      symbol *tlbl;
-      int emitTlbl;
-      int labelRange;
+      symbol  *tlbl;
+      int     emitTlbl;
+      int     labelRange;
+      char    *l;
 
       /* If the next instruction is a goto and the goto target
        * is <= 5 instructions previous to this, we can generate
@@ -3474,7 +3777,7 @@ genPlusIncr (iCode * ic)
          && (labelRange = findLabelBackwards (ic, IC_LABEL (ic->next)->key)) != 0
          && labelRange <= 5)
        {
-         emitcode (";", "tail increment optimized (range %d)", labelRange);
+         D(emitcode (";", "tail increment optimized (range %d)", labelRange););
          tlbl = IC_LABEL (ic->next);
          emitTlbl = 0;
        }
@@ -3483,50 +3786,60 @@ genPlusIncr (iCode * ic)
          tlbl = newiTempLabel (NULL);
          emitTlbl = 1;
        }
-      emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE));
+       
+      l = aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, NULL);
+      emitcode ("inc", "%s", l);
+      
       if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
          IS_AOP_PREG (IC_RESULT (ic)))
-       emitcode ("cjne", "%s,#0,!tlabel"
-                 ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
-                 ,tlbl->key + 100);
+      {          
+       emitcode ("cjne", "%s,#0,!tlabel", l, tlbl->key + 100);
+      }
       else
-       {
+      {
          emitcode ("clr", "a");
-         emitcode ("cjne", "a,%s,!tlabel"
-                   ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
-                   ,tlbl->key + 100);
-       }
+         emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
+      }
 
-      emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE));
+      l = aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, NULL); 
+      emitcode ("inc", "%s", l);
       if (size > 2)
        {
-         if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
-             IS_AOP_PREG (IC_RESULT (ic)))
-           emitcode ("cjne", "%s,#0,!tlabel"
-                 ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
-                     ,tlbl->key + 100);
-         else
-           emitcode ("cjne", "a,%s,!tlabel"
-                 ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
-                     ,tlbl->key + 100);
+           if (!strcmp(l, "acc"))
+           {
+               emitcode("jnz", "!tlabel", tlbl->key + 100);
+           }
+           else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+                    IS_AOP_PREG (IC_RESULT (ic)))
+           {
+               emitcode ("cjne", "%s,#0,!tlabel", l, tlbl->key + 100);
+           }
+           else
+           {
+               emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
+           }
 
-         emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE));
+           l = aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, NULL);
+           emitcode ("inc", "%s", l);
        }
       if (size > 3)
        {
-         if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
-             IS_AOP_PREG (IC_RESULT (ic)))
-           emitcode ("cjne", "%s,#0,!tlabel"
-                 ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
-                     ,tlbl->key + 100);
-         else
+           if (!strcmp(l, "acc"))
            {
-             emitcode ("cjne", "a,%s,!tlabel"
-                 ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
-                       ,tlbl->key + 100);
+               emitcode("jnz", "!tlabel", tlbl->key + 100);
            }
-         emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, FALSE, FALSE));
-       }
+           else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+                    IS_AOP_PREG (IC_RESULT (ic)))
+           {
+               emitcode ("cjne", "%s,#0,!tlabel", l, tlbl->key + 100);
+           }
+           else
+           {
+               emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
+           }
+
+           l = aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, FALSE, NULL);
+           emitcode ("inc", "%s", l);  }
 
       if (emitTlbl)
        {
@@ -3541,11 +3854,11 @@ genPlusIncr (iCode * ic)
 
       switch (size) {
       case 3:
-         emitcode ("mov","dpx,%s",aopGet(AOP (IC_LEFT (ic)), 2, FALSE, FALSE, FALSE));
+         emitcode ("mov","dpx,%s",aopGet(AOP (IC_LEFT (ic)), 2, FALSE, FALSE, NULL));
       case 2:
-         emitcode ("mov","dph,%s",aopGet(AOP (IC_LEFT (ic)), 1, FALSE, FALSE, FALSE));
+         emitcode ("mov","dph,%s",aopGet(AOP (IC_LEFT (ic)), 1, FALSE, FALSE, NULL));
       case 1:
-         emitcode ("mov","dpl,%s",aopGet(AOP (IC_LEFT (ic)), 0, FALSE, FALSE, FALSE));
+         emitcode ("mov","dpl,%s",aopGet(AOP (IC_LEFT (ic)), 0, FALSE, FALSE, NULL));
          break;
       }
       while (icount--) emitcode ("inc","dptr");      
@@ -3577,7 +3890,7 @@ genPlusIncr (iCode * ic)
 
       if (icount > 3)
        {
-         MOVA (aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE, TRUE));
+         MOVA (aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE, NULL));
          emitcode ("add", "a,#!constbyte", ((char) icount) & 0xff);
          aopPut (AOP (IC_RESULT (ic)), "a", 0);
        }
@@ -3587,7 +3900,7 @@ genPlusIncr (iCode * ic)
          _startLazyDPSEvaluation ();
          while (icount--)
            {
-             emitcode ("inc", "%s", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE, FALSE));
+             emitcode ("inc", "%s", aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE, NULL));
            }
          _endLazyDPSEvaluation ();
        }
@@ -3625,8 +3938,8 @@ outBitAcc (operand * result)
 static void
 genPlusBits (iCode * ic)
 {
-  D (emitcode (";", "genPlusBits ");
-    );
+  D (emitcode (";", "genPlusBits "););
+    
   if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
     {
       symbol *lbl = newiTempLabel (NULL);
@@ -3655,7 +3968,7 @@ adjustArithmeticResult (iCode * 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),
+             aopGet (AOP (IC_LEFT (ic)), GPTRSIZE - 1, FALSE, FALSE, NULL),
              GPTRSIZE - 1);
     }
 
@@ -3664,7 +3977,7 @@ adjustArithmeticResult (iCode * 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),
+           aopGet (AOP (IC_RIGHT (ic)), GPTRSIZE - 1, FALSE, FALSE, NULL),
              GPTRSIZE - 1);
     }
 
@@ -3674,44 +3987,162 @@ adjustArithmeticResult (iCode * ic)
       !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);
+      char buff[5];
+      SNPRINTF (buff, sizeof(buff), 
+               "#%d", pointerCode (getSpec (operandType (IC_LEFT (ic)))));
+      aopPut (AOP (IC_RESULT (ic)), buff, GPTRSIZE - 1);
     }
 }
 
+// The guts of AOP_OP_3_NOFATAL. Generates the left & right opcodes of an IC,
+// generates the result if possible. If result is generated, returns TRUE; otherwise
+// returns false and caller must deal with fact that result isn't aopOp'd.
+bool aopOp3(iCode * ic)
+{
+    bool dp1InUse, dp2InUse;
+    bool useDp2;
+
+    // First, generate the right opcode. DPTR may be used if neither left nor result are
+    // of type AOP_STR.
+    
+//    D(emitcode(";", "aopOp3: AOP_IS_STR left: %s right: %s result: %s",
+//            AOP_IS_STR(IC_LEFT(ic)) ? "true" : "false",
+//            AOP_IS_STR(IC_RIGHT(ic)) ? "true" : "false",
+//            AOP_IS_STR(IC_RESULT(ic)) ? "true" : "false");
+//      );
+//    D(emitcode(";", "aopOp3: AOP_IS_DPTRn left: %s right: %s result: %s",
+//            AOP_IS_DPTRn(IC_LEFT(ic)) ? "true" : "false",
+//            AOP_IS_DPTRn(IC_RIGHT(ic)) ? "true" : "false",
+//            AOP_IS_DPTRn(IC_RESULT(ic)) ? "true" : "false");
+//      );
+    
+    // Right uses DPTR unless left or result is an AOP_STR; however,
+    // if right is an AOP_STR, it must use DPTR regardless.
+    if ((AOP_IS_STR(IC_LEFT(ic)) || AOP_IS_STR(IC_RESULT(ic)))
+     && !AOP_IS_STR(IC_RIGHT(ic)))
+    {
+       useDp2 = TRUE;
+    }
+    else
+    {
+       useDp2 = FALSE;
+    }
+       
+    aopOp (IC_RIGHT(ic),ic,FALSE, useDp2);
+    
+    // if the right used DPTR, left MUST use DPTR2.
+    // if the right used DPTR2, left MUST use DPTR.
+    // if both are still available, we prefer to use DPTR. But if result is an AOP_STR
+    // and left is not an AOP_STR, then we will get better code if we use DP2 for left,
+    // enabling us to assign DPTR to result.
+     
+    if (AOP_USESDPTR(IC_RIGHT(ic)))
+    {
+       useDp2 = TRUE;
+    }
+    else if (AOP_USESDPTR2(IC_RIGHT(ic)))
+    {
+       useDp2 = FALSE;
+    }
+    else
+    {
+       if (AOP_IS_STR(IC_RESULT(ic)) && !AOP_IS_STR(IC_LEFT(ic)))
+       {
+           useDp2 = TRUE;
+       }
+       else
+       {
+           useDp2 = FALSE;
+       }
+    }
+
+    aopOp(IC_LEFT(ic), ic, FALSE, useDp2);
+
+        
+    // We've op'd the left & right. So, if left or right are the same operand as result, 
+    // we know aopOp will succeed, and we can just do it & bail.
+    if (isOperandEqual(IC_LEFT(ic),IC_RESULT(ic)))
+      {
+       aopOp (IC_RESULT (ic), ic, TRUE, AOP_USESDPTR2 (IC_LEFT (ic)));
+       return TRUE;
+      }
+    if (isOperandEqual(IC_RIGHT(ic),IC_RESULT(ic)))
+      {
+//     D(emitcode(";", "aopOp3: (left | right) & result equal"););
+       aopOp(IC_RESULT(ic),ic,TRUE, AOP_USESDPTR2 (IC_RIGHT (ic)));
+       return TRUE;
+      }
+    
+    // Operands may be equivalent (but not equal) if they share a spill location. If
+    // so, use the same DPTR or DPTR2.
+    if (operandsEqu (IC_LEFT(ic), IC_RESULT(ic)))
+      {
+        aopOp (IC_RESULT (ic), ic, TRUE, AOP_USESDPTR2 (IC_LEFT (ic)));
+       return TRUE;
+      }
+    if (operandsEqu (IC_RIGHT(ic), IC_RESULT(ic)))
+      {
+        aopOp (IC_RESULT (ic), ic, TRUE, AOP_USESDPTR2 (IC_RIGHT (ic)));
+       return TRUE;
+      }
+    
+    // Note which dptrs are currently in use.
+    dp1InUse = AOP_USESDPTR(IC_LEFT(ic)) || AOP_USESDPTR(IC_RIGHT(ic));
+    dp2InUse = AOP_USESDPTR2(IC_LEFT(ic)) || AOP_USESDPTR2(IC_RIGHT(ic));
+    
+    // OK, now if either left or right uses DPTR and the result is an AOP_STR, we cannot 
+    // generate it.
+    if (dp1InUse && AOP_IS_STR(IC_RESULT(ic)))
+    {
+       return FALSE;
+    }
+    
+    // Likewise, if left or right uses DPTR2 and the result is a DPTRn, we cannot generate it.
+    if (dp2InUse && AOP_IS_DPTRn(IC_RESULT(ic)))
+    {
+       return FALSE;
+    }
+    
+    // or, if both dp1 & dp2 are in use and the result needs a dptr, we're out of luck    
+    if (dp1InUse && dp2InUse && isOperandInFarSpace(IC_RESULT(ic)))
+    {
+       return FALSE;
+    }
+
+    aopOp (IC_RESULT(ic),ic,TRUE, dp1InUse);
+
+    // Some sanity checking...
+    if (dp1InUse && AOP_USESDPTR(IC_RESULT(ic)))
+    {
+       fprintf(stderr,
+               "Internal error: got unexpected DPTR (%s:%d %s:%d)\n",
+               __FILE__, __LINE__, ic->filename, ic->lineno);  
+       emitcode(";", ">>> unexpected DPTR here.");
+    }
+    
+    if (dp2InUse && AOP_USESDPTR2(IC_RESULT(ic)))
+    {
+       fprintf(stderr,
+               "Internal error: got unexpected DPTR2 (%s:%d %s:%d)\n",
+               __FILE__, __LINE__, ic->filename, ic->lineno);  
+       emitcode(";", ">>> unexpected DPTR2 here.");
+    }    
+    
+    return TRUE;
+}
+
 // 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) && !isOperandEqual(IC_LEFT(ic),IC_RESULT(ic)))); \
-    if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \
-        (isOperandInFarSpace(IC_RESULT(ic)) || (OP_SYMBOL(IC_RESULT(ic))->ruonly && !isOperandEqual(IC_LEFT(ic),IC_RESULT(ic))))) \
-    { \
-       /* 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);   \
-       } \
-    }
+           do { rc = !aopOp3(ic); } while (0)
 
 // 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));
+    aopOp (IC_RIGHT(ic),ic,FALSE, AOP_IS_STR(IC_LEFT(ic))); \
+    aopOp (IC_LEFT(ic),ic,FALSE, AOP_USESDPTR(IC_RIGHT(ic)));
 
 // convienience macro.
 #define AOP_SET_LOCALS(ic) \
@@ -3757,16 +4188,16 @@ static void
 genPlus (iCode * ic)
 {
   int size, offset = 0;
-  bool pushResult = FALSE;
+  bool pushResult;
   int rSize;
 
   D (emitcode (";", "genPlus "););
 
   /* special cases :- */
-  if ( IS_SYMOP(IC_LEFT(ic)) && OP_SYMBOL(IC_LEFT(ic))->ruonly &&
+  if ( AOP_IS_STR(IC_LEFT(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);
+      size = (int)floatFromVal (AOP (IC_RIGHT(ic))->aopu.aop_lit);
       if (size <= 9) {
          while (size--) emitcode ("inc","dptr");
       } else {
@@ -3792,6 +4223,7 @@ genPlus (iCode * ic)
   }
                
   AOP_OP_3_NOFATAL (ic, pushResult);
+    
   if (pushResult)
     {
       D (emitcode (";", "genPlus: must push result: 3 ops in far space"););
@@ -3839,7 +4271,7 @@ genPlus (iCode * ic)
              _startLazyDPSEvaluation ();
              while (size--)
                {
-                 MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, TRUE));
+                 MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, NULL));
                  emitcode ("addc", "a,#0");
                  aopPut (AOP (IC_RESULT (ic)), "a", offset++);
                }
@@ -3864,13 +4296,13 @@ genPlus (iCode * ic)
     {
       if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC && !AOP_NEEDSACC(IC_RIGHT(ic)))
        {
-         MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, TRUE));
+         MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, NULL));
          if (offset == 0)
            emitcode ("add", "a,%s",
-                aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, FALSE));
+                aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, NULL));
          else
            emitcode ("addc", "a,%s",
-                aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, FALSE));
+                aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, NULL));
        }
       else
        {
@@ -3884,7 +4316,7 @@ genPlus (iCode * ic)
              D(emitcode(";", "+ AOP_ACC special case."););
              emitcode("xch", "a, %s", DP2_RESULT_REG);
          }
-         MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, TRUE));
+         MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, NULL));
          if (offset == 0)
          {
            if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC)
@@ -3895,13 +4327,15 @@ genPlus (iCode * ic)
            else
            {
                emitcode ("add", "a,%s",
-                       aopGet (AOP(IC_LEFT(ic)), offset, FALSE, FALSE, FALSE));
+                         aopGet (AOP(IC_LEFT(ic)), offset, FALSE, FALSE,
+                                 DP2_RESULT_REG));
            }
           }
          else
          {
            emitcode ("addc", "a,%s",
-                 aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, FALSE));
+                 aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE,
+                         DP2_RESULT_REG));
          }
        }
       if (!pushResult)
@@ -3965,7 +4399,7 @@ genMinusDec (iCode * ic)
   if (size == 1 && AOP(IC_LEFT(ic)) == AOP(IC_RESULT(ic)) &&
       AOP_TYPE(IC_LEFT(ic)) == AOP_DIR ) {
       while (icount--) {
-         emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE,FALSE));
+         emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE,NULL));
       }
       return TRUE;
   }
@@ -3977,8 +4411,9 @@ genMinusDec (iCode * ic)
       (icount == 1))
     {
       symbol *tlbl;
-      int emitTlbl;
-      int labelRange;
+      int    emitTlbl;
+      int    labelRange;
+      char   *l;
 
       /* If the next instruction is a goto and the goto target
          * is <= 5 instructions previous to this, we can generate
@@ -3998,52 +4433,61 @@ genMinusDec (iCode * ic)
          emitTlbl = 1;
        }
 
-      emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE));
+      l = aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, NULL);
+      emitcode ("dec", "%s", l);
       if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
          AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
          IS_AOP_PREG (IC_RESULT (ic)))
-       emitcode ("cjne", "%s,#!constbyte,!tlabel"
-                 ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE), 0xff
-                 ,tlbl->key + 100);
+      {            
+         emitcode ("cjne", "%s,#!constbyte,!tlabel", l, 0xff, tlbl->key + 100);
+      }
       else
-       {
+      {
          emitcode ("mov", "a,#!constbyte",0xff);
-         emitcode ("cjne", "a,%s,!tlabel"
-                   ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
-                   ,tlbl->key + 100);
-       }
-      emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE));
+         emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
+      }
+      l = aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, NULL);
+      emitcode ("dec", "%s", l);
       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,#!constbyte,!tlabel"
-                     ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE),0xff
-                     ,tlbl->key + 100);
-         else
+           if (!strcmp(l, "acc"))
+           {
+               emitcode("jnz", "!tlabel", tlbl->key + 100);
+           }
+           else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+                    AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
+                    IS_AOP_PREG (IC_RESULT (ic)))
+           {       
+               emitcode ("cjne", "%s,#!constbyte,!tlabel", l, 0xff, tlbl->key + 100);
+           }
+           else
            {
-             emitcode ("cjne", "a,%s,!tlabel"
-                 ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
-                       ,tlbl->key + 100);
+               emitcode ("mov", "a,#!constbyte",0xff);
+               emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
            }
-         emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE));
+           l = aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, NULL);
+           emitcode ("dec", "%s", l);
        }
       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,#!constbyte,!tlabel"
-                     ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE),0xff
-                     ,tlbl->key + 100);
-         else
+           if (!strcmp(l, "acc"))
            {
-             emitcode ("cjne", "a,%s,!tlabel"
-                 ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
-                       ,tlbl->key + 100);
+               emitcode("jnz", "!tlabel", tlbl->key + 100);
+           }
+           else if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+                    AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
+                    IS_AOP_PREG (IC_RESULT (ic)))
+           {       
+               emitcode ("cjne", "%s,#!constbyte,!tlabel", l, 0xff, tlbl->key + 100);
            }
-         emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, FALSE, FALSE));
+           else
+           {
+               emitcode ("mov", "a,#!constbyte",0xff);
+               emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
+           }       
+           l = aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, FALSE, NULL);
+           emitcode ("dec", "%s", l);
        }
       if (emitTlbl)
        {
@@ -4069,7 +4513,8 @@ genMinusDec (iCode * ic)
       _startLazyDPSEvaluation ();
       while (icount--)
        {
-         emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, FALSE));
+         emitcode ("dec", "%s",
+                   aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, NULL));
        }
       _endLazyDPSEvaluation ();
 
@@ -4145,26 +4590,17 @@ genMinusBits (iCode * ic)
 static void
 genMinus (iCode * ic)
 {
-  int size, offset = 0;
-  int rSize;
-  unsigned long lit = 0L;
-  bool pushResult = FALSE;
+    int size, offset = 0;
+    int rSize;
+    long lit = 0L;
+    bool pushResult;
 
-  D (emitcode (";", "genMinus "););
+    D (emitcode (";", "genMinus "););
 
-  aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
-  aopOp (IC_RIGHT (ic), ic, FALSE, 
-        (AOP_INDPTRn(IC_LEFT(ic)) ? FALSE : (AOP_USESDPTR(IC_LEFT(ic)) ? TRUE : FALSE)));
-  if ((AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR) &&
-      ((AOP_TYPE (IC_RIGHT (ic)) == AOP_DPTR2)
-       || OP_SYMBOL(IC_RESULT(ic))->ruonly))
-    {
-      pushResult = TRUE;
-    }
-  else
-    {
-      aopOp (IC_RESULT (ic), ic, TRUE, AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR);
+    AOP_OP_3_NOFATAL(ic, pushResult);  
 
+    if (!pushResult)
+    {
       /* special cases :- */
       /* if both left & right are in bit space */
       if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY &&
@@ -4189,26 +4625,28 @@ genMinus (iCode * ic)
     }
   else
     {
-      lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
-      lit = -(long) lit;
+      lit = (long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
+      lit = -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) {
          if (AOP_USESDPTR(IC_RIGHT(ic))) {
-             emitcode ("mov","b,a");
-             MOVA(aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, FALSE));
-             emitcode ("xch","a,b");
+             emitcode ("mov","b,%s",
+                       aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, NULL));
+             MOVA(aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, NULL));
              emitcode ("subb","a,b");
          } else {
+             MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, NULL));
              emitcode ("subb", "a,%s",
-                       aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, FALSE));
+                       aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, 
+                               DP2_RESULT_REG));
          }
       } else {
+         MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, NULL));
          /* first add without previous c */
          if (!offset) {
              if (!size && lit==-1) {
@@ -4284,9 +4722,11 @@ genMultOneByte (operand * left,
                operand * result,
                iCode   * ic)
 {
-  sym_link *opetype = operandType (result);
+  int size;
   symbol *lbl;
-
+  bool runtimeSign, compiletimeSign;
+  bool lUnsigned, rUnsigned;
+  
 
   /* (if two literals: the value is computed before) */
   /* if one literal, literal on the right */
@@ -4298,105 +4738,197 @@ genMultOneByte (operand * left,
       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++; _G.bInUse++;
-    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--; _G.bInUse--;
-    if (AOP_SIZE(result)==2) 
+  /* (if two literals: the value is computed before) */
+  /* if one literal, literal on the right */
+  if (AOP_TYPE (left) == AOP_LIT)
     {
-      aopPut (AOP (result), "b", 1);
+      operand *t = right;
+      right = left;
+      left = t;
+      /* emitcode (";", "swapped left and right"); */
+    }
+  /* if no literal, unsigned on the right: shorter code */
+  if (   AOP_TYPE (right) != AOP_LIT
+      && SPEC_USIGN (getSpec (operandType (left))))
+    {
+      operand *t = right;
+      right = left;
+      left = t;
     }
-    return;
-  }
 
-  // we have to do a signed multiply
+  lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
+  rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
 
-  emitcode (";", "signed");
-  emitcode ("clr", "F0"); // reset sign flag
-  MOVA (aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
+  if ((lUnsigned && rUnsigned)
+/* sorry, I don't know how to get size
+   without calling aopOp (result,...);
+   see Feature Request  */
+      /* || size == 1 */ ) /* no, this is not a bug; with a 1 byte result there's
+                  no need to take care about the signedness! */
+    {
+      /* just an unsigned 8 * 8 = 8 multiply
+         or 8u * 8u = 16u */
+      /* emitcode (";","unsigned"); */
+      emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, NULL));
+      MOVA (aopGet (AOP (left), 0, FALSE, FALSE, NULL));
+      emitcode ("mul", "ab");
+    
+      _G.accInUse++; _G.bInUse++;
+      aopOp (result, ic, TRUE, FALSE);
+      size = AOP_SIZE (result);
+  
+      if (size < 1 || size > 2)
+        {
+          /* this should never happen */
+          fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n",
+                  size, __FILE__, lineno);
+          exit (1);
+        }
+  
+      aopPut (AOP (result), "a", 0);
+      _G.accInUse--; _G.bInUse--;
+      if (size == 2) 
+       aopPut (AOP (result), "b", 1);
+      return;
+    }
 
-  lbl=newiTempLabel(NULL);
-  emitcode ("jnb", "acc.7,!tlabel",  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");
+  /* we have to do a signed multiply */
+  /* emitcode (";", "signed"); */
+  
+  /* now sign adjust for both left & right */
 
-  emitcode ("", "!tlabeldef", lbl->key+100);
+  /* let's see what's needed: */
+  /* apply negative sign during runtime */
+  runtimeSign = FALSE;
+  /* negative sign from literals */
+  compiletimeSign = FALSE;
 
-  /* 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,#!constbyte", -val);
-    } else {
-      emitcode ("mov", "b,#!constbyte", val);
+  if (!lUnsigned)
+    {
+      if (AOP_TYPE(left) == AOP_LIT)
+        {
+          /* signed literal */
+          signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+          if (val < 0)
+            compiletimeSign = TRUE;
+        }
+      else
+        /* signed but not literal */
+        runtimeSign = TRUE;
     }
-  } else {
-    lbl=newiTempLabel(NULL);
-    emitcode ("mov", "b,a");
-    emitcode ("mov", "a,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE));
-    emitcode ("jnb", "acc.7,!tlabel", 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 ("", "!tlabeldef", lbl->key+100);
-  }
+
+  if (!rUnsigned)
+    {
+      if (AOP_TYPE(right) == AOP_LIT)
+        {
+          /* signed literal */
+          signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+          if (val < 0)
+            compiletimeSign ^= TRUE;
+        }
+      else
+        /* signed but not literal */
+        runtimeSign = TRUE;
+    }
+
+  /* initialize F0, which stores the runtime sign */
+  if (runtimeSign)
+    {
+      if (compiletimeSign)
+       emitcode ("setb", "F0"); /* set sign flag */
+      else
+       emitcode ("clr", "F0"); /* reset sign flag */
+    }
+  
+  /* save the signs of the operands */
+  if (AOP_TYPE(right) == AOP_LIT)
+    {
+      signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+
+      if (!rUnsigned && val < 0)
+        emitcode ("mov", "b,#!constbyte", -val);
+      else
+        emitcode ("mov", "b,#!constbyte", (unsigned char) val);
+    }
+  else /* ! literal */
+    {
+      if (rUnsigned)  /* emitcode (";", "signed"); */
+        emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, NULL));
+      else
+        {
+         MOVA (aopGet (AOP (right), 0, FALSE, FALSE, NULL));
+         lbl = newiTempLabel (NULL);
+         emitcode ("jnb", "acc.7,!tlabel", lbl->key + 100);
+         emitcode ("cpl", "F0"); /* complement sign flag */
+         emitcode ("cpl", "a");  /* 2's complement */
+         emitcode ("inc", "a");
+         emitcode ("", "!tlabeldef", lbl->key + 100);
+         emitcode ("mov", "b,a");
+       }
+    }
+
+  if (AOP_TYPE(left) == AOP_LIT)
+    {
+      signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+
+      if (!lUnsigned && val < 0)
+        emitcode ("mov", "a,#!constbyte", -val);
+      else
+        emitcode ("mov", "a,#!constbyte", (unsigned char) val);
+    }
+  else /* ! literal */
+    {
+      if (lUnsigned)  /* emitcode (";", "signed"); */
+
+        emitcode ("mov", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE, NULL));
+      else
+        {
+         MOVA (aopGet (AOP (left), 0, FALSE, FALSE, NULL));
+         lbl = newiTempLabel (NULL);
+         emitcode ("jnb", "acc.7,!tlabel", lbl->key + 100);
+         emitcode ("cpl", "F0"); /* complement sign flag */
+         emitcode ("cpl", "a");  /* 2's complement */
+         emitcode ("inc", "a");
+         emitcode ("", "!tlabeldef", lbl->key + 100);
+       }
+    }
+
+  /* now the multiplication */
   emitcode ("mul", "ab");
-    
   _G.accInUse++;_G.bInUse++;
   aopOp(result, ic, TRUE, FALSE);
-    
-  if (AOP_SIZE(result)<1 || AOP_SIZE(result)>2) 
-  {
-    // this should never happen
+  size = AOP_SIZE (result);
+
+  if (size < 1 || size > 2) 
+    {
+      /* this should never happen */
       fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", 
-              AOP_SIZE(result), __FILE__, lineno);
+               size, __FILE__, lineno);
       exit (1);
-  }    
+    }    
     
-  lbl=newiTempLabel(NULL);
-  emitcode ("jnb", "F0,!tlabel", 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 ("", "!tlabeldef", lbl->key+100);
+  if (runtimeSign || compiletimeSign)
+    {
+      lbl = newiTempLabel (NULL);
+      if (runtimeSign)
+        emitcode ("jnb", "F0,!tlabel", lbl->key + 100);
+      emitcode ("cpl", "a"); /* lsb 2's complement */
+      if (size != 2)
+        emitcode ("inc", "a"); /* inc doesn't set carry flag */
+      else
+        {
+          emitcode ("add", "a,#1"); /* this sets carry flag */
+          emitcode ("xch", "a,b");
+          emitcode ("cpl", "a"); /* msb 2's complement */
+          emitcode ("addc", "a,#0");
+          emitcode ("xch", "a,b");
+        }
+      emitcode ("", "!tlabeldef", lbl->key + 100);
+    }
   aopPut (AOP (result), "a", 0);
   _G.accInUse--;_G.bInUse--;
-  if (AOP_SIZE(result)==2) {
+  if (size == 2)
     aopPut (AOP (result), "b", 1);
-  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -4426,7 +4958,7 @@ static void genMultTwoByte (operand *left, operand *right,
        if (!umult) {
                emitcode("clr","F0");
                if (AOP_TYPE(right) == AOP_LIT) {
-                       int val=floatFromVal (AOP (right)->aopu.aop_lit);
+                       int val=(int)floatFromVal (AOP (right)->aopu.aop_lit);
                        if (val < 0) {
                                emitcode("setb","F0");
                                val = -val;
@@ -4435,8 +4967,8 @@ static void genMultTwoByte (operand *left, operand *right,
                        emitcode ("mov","mb,#!constbyte",(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 ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,NULL));
+                       emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,NULL));
                        emitcode ("jnb","acc.7,!tlabel",lbl->key+100);          
                        emitcode ("xch", "a,b");
                        emitcode ("cpl","a");
@@ -4450,14 +4982,14 @@ static void genMultTwoByte (operand *left, operand *right,
                        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));
+               emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,NULL));
+               emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,NULL));
        }
        /* 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 ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,NULL));
+               emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,NULL));
                emitcode ("jnb","acc.7,!tlabel",lbl->key+100);
                emitcode ("xch", "a,b");
                emitcode ("cpl","a");
@@ -4471,8 +5003,8 @@ static void genMultTwoByte (operand *left, operand *right,
                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));
+               emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,NULL));
+               emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,NULL));
        }
        /* wait for multiplication to finish */
        lbl = newiTempLabel(NULL);
@@ -4635,97 +5167,182 @@ genDivOneByte (operand * left,
               operand * result,
               iCode   * ic)
 {
-  sym_link *opetype = operandType (result);
+  bool lUnsigned, rUnsigned;
+  bool runtimeSign, compiletimeSign;
   char *l;
   symbol *lbl;
   int size, offset;
 
   offset = 1;
+  lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
+  rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
+  
   /* signed or unsigned */
-  if (SPEC_USIGN (opetype))
+  if (lUnsigned && rUnsigned)
     {
-       /* unsigned is easy */
-       LOAD_AB_FOR_DIV (left, right, l);
-       emitcode ("div", "ab");
+      /* 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--;
+      _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++);
-       }
+      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,!tlabel", (lbl->key + 100));
-  emitcode ("cpl", "a");
-  emitcode ("inc", "a");
-  emitcode ("", "!tlabeldef", (lbl->key + 100));
-  emitcode ("mov", "b,a");
 
-  /* sign adjust left side */
-  l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
-  MOVA (l);
+  /* let's see what's needed: */
+  /* apply negative sign during runtime */
+  runtimeSign = FALSE;
+  /* negative sign from literals */
+  compiletimeSign = FALSE;
 
-  lbl = newiTempLabel (NULL);
-  emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100));
-  emitcode ("cpl", "a");
-  emitcode ("inc", "a");
-  emitcode ("", "!tlabeldef", (lbl->key + 100));
+  if (!lUnsigned)
+    {
+      if (AOP_TYPE(left) == AOP_LIT)
+        {
+          /* signed literal */
+          signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+          if (val < 0)
+            compiletimeSign = TRUE;
+        }
+      else
+        /* signed but not literal */
+        runtimeSign = TRUE;
+    }
+
+  if (!rUnsigned)
+    {
+      if (AOP_TYPE(right) == AOP_LIT)
+        {
+          /* signed literal */
+          signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+          if (val < 0)
+            compiletimeSign ^= TRUE;
+        }
+      else
+        /* signed but not literal */
+        runtimeSign = TRUE;
+    }
 
+  /* initialize F0, which stores the runtime sign */
+  if (runtimeSign)
+    {
+      if (compiletimeSign)
+       emitcode ("setb", "F0"); /* set sign flag */
+      else
+       emitcode ("clr", "F0"); /* reset sign flag */
+    }
+
+  /* save the signs of the operands */
+  if (AOP_TYPE(right) == AOP_LIT)
+    {
+      signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
+
+      if (!rUnsigned && val < 0)
+        emitcode ("mov", "b,#0x%02x", -val);
+      else
+        emitcode ("mov", "b,#0x%02x", (unsigned char) val);
+    }
+  else /* ! literal */
+    {
+      if (rUnsigned)
+        emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, NULL));
+      else
+        {
+          MOVA (aopGet (AOP (right), 0, FALSE, FALSE, NULL));
+         lbl = newiTempLabel (NULL);
+         emitcode ("jnb", "acc.7,!tlabel", lbl->key + 100);
+         emitcode ("cpl", "F0"); /* complement sign flag */
+         emitcode ("cpl", "a");  /* 2's complement */
+         emitcode ("inc", "a");
+         emitcode ("", "!tlabeldef", lbl->key + 100);
+          emitcode ("mov", "b,a");
+       }
+    }
+
+  if (AOP_TYPE(left) == AOP_LIT)
+    {
+      signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
+
+      if (!lUnsigned && val < 0)
+        emitcode ("mov", "a,#0x%02x", -val);
+      else
+        emitcode ("mov", "a,#0x%02x", (unsigned char) val);
+    }
+  else /* ! literal */
+    {
+      if (lUnsigned)
+        emitcode ("mov", "a,%s", aopGet (AOP (left), 0, FALSE, FALSE, NULL));
+      else
+        {
+          MOVA (aopGet (AOP (left), 0, FALSE, FALSE, NULL));
+         lbl = newiTempLabel (NULL);
+         emitcode ("jnb", "acc.7,!tlabel", lbl->key + 100);
+         emitcode ("cpl", "F0"); /* complement sign flag */
+         emitcode ("cpl", "a");  /* 2's complement */
+         emitcode ("inc", "a");
+         emitcode ("", "!tlabeldef", 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,!tlabel", (lbl->key + 100));
-  emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100));
-  CLRC;
-  emitcode ("clr", "a");
-  emitcode ("subb", "a,b");
-  emitcode ("mov", "b,a");
-  emitcode ("", "!tlabeldef", (lbl->key + 100));
-
-  /* now we are done */
-  _G.accInUse++;     _G.bInUse++;
-    aopOp(result, ic, TRUE, FALSE);
-    
-    aopPut (AOP (result), "b", 0);
-    
-    size = AOP_SIZE (result) - 1;
-    
-    if (size > 0)
+  
+  if (runtimeSign || compiletimeSign)
     {
-      emitcode ("mov", "c,b.7");
-      emitcode ("subb", "a,acc");
+      lbl = newiTempLabel (NULL);
+      if (runtimeSign)
+        emitcode ("jnb", "F0,!tlabel", lbl->key + 100);
+      emitcode ("cpl", "a"); /* lsb 2's complement */
+      emitcode ("inc", "a");
+      emitcode ("", "!tlabeldef", lbl->key + 100);
+
+      _G.accInUse++;     _G.bInUse++;
+      aopOp (result, ic, TRUE, FALSE);
+      size = AOP_SIZE (result) - 1;
+
+      if (size > 0)
+       {
+         /* 123 look strange, but if (OP_SYMBOL (op)->accuse == 1)
+            then the result will be in b, a */
+         emitcode ("mov", "b,a"); /* 1 */
+         /* msb is 0x00 or 0xff depending on the sign */
+         if (runtimeSign)
+           {
+             emitcode ("mov",  "c,F0");
+             emitcode ("subb", "a,acc");
+             emitcode ("xch",  "a,b"); /* 2 */
+             while (size--)
+               aopPut (AOP (result), "b", offset++); /* write msb's */
+           }
+         else /* compiletimeSign */
+           while (size--)
+             aopPut (AOP (result), "#0xff", offset++); /* write msb's */
+       }
+      aopPut (AOP (result), "a", 0); /* 3: write lsb */
     }
-    while (size--)
+  else
     {
-       aopPut (AOP (result), "a", offset++);
+      _G.accInUse++;     _G.bInUse++;
+      aopOp(result, ic, TRUE, FALSE);
+      size = AOP_SIZE (result) - 1;
+      
+      aopPut (AOP (result), "a", 0);
+      while (size--)
+       aopPut (AOP (result), zero, offset++);
     }
-    _G.accInUse--;     _G.bInUse--;
+  _G.accInUse--;     _G.bInUse--;
 
 }
 
@@ -4751,8 +5368,8 @@ static void genDivTwoByte (operand *left, operand *right,
        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 ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,NULL));
+               emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,NULL));
                emitcode ("jnb","acc.7,!tlabel",lbl->key+100);
                emitcode ("xch", "a,b");
                emitcode ("cpl","a");
@@ -4765,14 +5382,14 @@ static void genDivTwoByte (operand *left, operand *right,
                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));
+               emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,NULL));
+               emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,NULL));
        }
 
        /* load up MB with right */
        if (!umult) {
                if (AOP_TYPE(right) == AOP_LIT) {
-                       int val=floatFromVal (AOP (right)->aopu.aop_lit);
+                       int val=(int)floatFromVal (AOP (right)->aopu.aop_lit);
                        if (val < 0) {
                                lbl = newiTempLabel(NULL);
                                emitcode ("jbc","F0,!tlabel",lbl->key+100);
@@ -4784,8 +5401,8 @@ static void genDivTwoByte (operand *left, operand *right,
                        emitcode ("mov","mb,#!constbyte",(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 ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,NULL));
+                       emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,NULL));
                        emitcode ("jnb","acc.7,!tlabel",lbl->key+100);          
                        emitcode ("xch", "a,b");
                        emitcode ("cpl","a");
@@ -4800,8 +5417,8 @@ static void genDivTwoByte (operand *left, operand *right,
                        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));
+               emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,NULL));
+               emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,NULL));
        }
 
        /* wait for multiplication to finish */
@@ -4921,73 +5538,146 @@ genModOneByte (operand * left,
               operand * result,
               iCode   * ic)
 {
-  sym_link *opetype = operandType (result);
+  bool lUnsigned, rUnsigned;
+  bool runtimeSign, compiletimeSign;
   char *l;
   symbol *lbl;
+  int size, offset;
 
+  offset = 1;
+  lUnsigned = SPEC_USIGN (getSpec (operandType (left)));
+  rUnsigned = SPEC_USIGN (getSpec (operandType (right)));
+  
   /* signed or unsigned */
-  if (SPEC_USIGN (opetype))
+  if (lUnsigned && rUnsigned)
     {
       /* unsigned is easy */
       LOAD_AB_FOR_DIV (left, right, l);
       emitcode ("div", "ab");
-      aopOp(result, ic, TRUE, FALSE);  
+      aopOp (result, ic, TRUE, FALSE); 
       aopPut (AOP (result), "b", 0);
+
+      for (size = AOP_SIZE (result) - 1; 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, 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,!tlabel", (lbl->key + 100));
-  emitcode ("cpl", "a");
-  emitcode ("inc", "a");
-  emitcode ("", "!tlabeldef", (lbl->key + 100));
-  emitcode ("mov", "b,a");
+  /* modulus: sign of the right operand has no influence on the result! */
+  if (AOP_TYPE(right) == AOP_LIT)
+    {
+      signed char val = (char) floatFromVal (AOP (right)->aopu.aop_lit);
 
-  /* sign adjust left side */
-  l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
-  MOVA (l);
+      if (!rUnsigned && val < 0)
+        emitcode ("mov", "b,#0x%02x", -val);
+      else
+        emitcode ("mov", "b,#0x%02x", (unsigned char) val);
+    }
+  else /* ! literal */
+    {
+      if (rUnsigned)
+        emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, NULL));
+      else
+        {
+          MOVA (aopGet (AOP (right), 0, FALSE, FALSE, NULL));
+         lbl = newiTempLabel (NULL);
+         emitcode ("jnb", "acc.7,!tlabel", lbl->key + 100);
+         emitcode ("cpl", "a");  /* 2's complement */
+         emitcode ("inc", "a");
+         emitcode ("", "!tlabeldef", lbl->key + 100);
+          emitcode ("mov", "b,a");
+       }
+    }
+  
+  /* let's see what's needed: */
+  /* apply negative sign during runtime */
+  runtimeSign = FALSE;
+  /* negative sign from literals */
+  compiletimeSign = FALSE;
 
-  lbl = newiTempLabel (NULL);
-  emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100));
-  emitcode ("cpl", "a");
-  emitcode ("inc", "a");
-  emitcode ("", "!tlabeldef", (lbl->key + 100));
+  /* sign adjust left side */
+  if (AOP_TYPE(left) == AOP_LIT)
+    {
+      signed char val = (char) floatFromVal (AOP (left)->aopu.aop_lit);
 
-  /* now the multiplication */
+      if (!lUnsigned && val < 0)
+       {
+         compiletimeSign = TRUE; /* set sign flag */
+         emitcode ("mov", "a,#0x%02x", -val);
+       }
+      else
+        emitcode ("mov", "a,#0x%02x", (unsigned char) val);
+    }
+  else /* ! literal */
+    {
+      MOVA (aopGet (AOP (left), 0, FALSE, FALSE, NULL));
+      
+      if (!lUnsigned)
+        {
+         runtimeSign = TRUE;
+         emitcode ("clr", "F0"); /* clear sign flag */
+         
+         lbl = newiTempLabel (NULL);
+         emitcode ("jnb", "acc.7,!tlabel", lbl->key + 100);
+         emitcode ("setb", "F0"); /* set sign flag */
+         emitcode ("cpl", "a");   /* 2's complement */
+         emitcode ("inc", "a");
+         emitcode ("", "!tlabeldef", lbl->key + 100);
+       }
+    }
+  
+  /* now the modulus */
   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,!tlabel", (lbl->key + 100));
-  emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100));
-  CLRC;
-  emitcode ("clr", "a");
-  emitcode ("subb", "a,b");
-  emitcode ("mov", "b,a");
-  emitcode ("", "!tlabeldef", (lbl->key + 100));
   
-  _G.bInUse++;
-  /* now we are done */
-  aopOp(result, ic, TRUE, FALSE);    
-  aopPut (AOP (result), "b", 0);
-  _G.bInUse--;
+  if (runtimeSign || compiletimeSign)
+    {
+      emitcode ("mov", "a,b");
+      lbl = newiTempLabel (NULL);
+      if (runtimeSign)
+        emitcode ("jnb", "F0,!tlabel", lbl->key + 100);
+      emitcode ("cpl", "a"); /* lsb 2's complement */
+      emitcode ("inc", "a");
+      emitcode ("", "!tlabeldef", lbl->key + 100);
+
+      _G.accInUse++;     _G.bInUse++;
+      aopOp (result, ic, TRUE, FALSE);
+      size = AOP_SIZE (result) - 1;
+      
+      if (size > 0)
+       {
+         /* 123 look strange, but if (OP_SYMBOL (op)->accuse == 1)
+            then the result will be in b, a */
+         emitcode ("mov", "b,a"); /* 1 */
+         /* msb is 0x00 or 0xff depending on the sign */
+         if (runtimeSign)
+           {
+             emitcode ("mov",  "c,F0");
+             emitcode ("subb", "a,acc");
+             emitcode ("xch",  "a,b"); /* 2 */
+             while (size--)
+               aopPut (AOP (result), "b", offset++); /* write msb's */
+           }
+         else /* compiletimeSign */
+           while (size--)
+             aopPut (AOP (result), "#0xff", offset++); /* write msb's */
+       }
+      aopPut (AOP (result), "a", 0); /* 3: write lsb */
+    }
+  else
+    {
+      _G.accInUse++;     _G.bInUse++;
+      aopOp(result, ic, TRUE, FALSE);
+      size = AOP_SIZE (result) - 1;
+      
+      aopPut (AOP (result), "b", 0);
+      while (size--)
+       aopPut (AOP (result), zero, offset++);
+    }
+  _G.accInUse--;     _G.bInUse--;
 
 }
 
@@ -5012,8 +5702,8 @@ static void genModTwoByte (operand *left, operand *right,
 
        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 ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,NULL));
+               emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,NULL));
                emitcode ("jnb","acc.7,!tlabel",lbl->key+100);
                emitcode ("xch", "a,b");
                emitcode ("cpl","a");
@@ -5025,14 +5715,14 @@ static void genModTwoByte (operand *left, operand *right,
                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));
+               emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,NULL));
+               emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,NULL));
        }
 
        /* load up MB with right */
        if (!umult) {
                if (AOP_TYPE(right) == AOP_LIT) {
-                       int val=floatFromVal (AOP (right)->aopu.aop_lit);
+                       int val=(int)floatFromVal (AOP (right)->aopu.aop_lit);
                        if (val < 0) {
                                val = -val;
                        } 
@@ -5040,8 +5730,8 @@ static void genModTwoByte (operand *left, operand *right,
                        emitcode ("mov","mb,#!constbyte",(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 ("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE,NULL));
+                       emitcode ("mov","a,%s",aopGet(AOP(right),1,FALSE,FALSE,NULL));
                        emitcode ("jnb","acc.7,!tlabel",lbl->key+100);          
                        emitcode ("xch", "a,b");
                        emitcode ("cpl","a");
@@ -5054,8 +5744,8 @@ static void genModTwoByte (operand *left, operand *right,
                        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));
+               emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,NULL));
+               emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,NULL));
        }
 
        /* wait for multiplication to finish */
@@ -5138,8 +5828,7 @@ genIfxJump (iCode * ic, char *jval)
   symbol *tlbl = newiTempLabel (NULL);
   char *inst;
 
-  D (emitcode (";", "genIfxJump ");
-    );
+  D (emitcode (";", "genIfxJump"););
 
   /* if true label then we jump if condition
      supplied is true */
@@ -5178,8 +5867,7 @@ genCmp (operand * left, operand * right,
   unsigned long lit = 0L;
   operand *result;
 
-  D (emitcode (";", "genCmp");
-    );
+  D (emitcode (";", "genCmp"););
 
   result = IC_RESULT (ic);
 
@@ -5188,7 +5876,7 @@ genCmp (operand * left, operand * right,
       AOP_TYPE (right) == AOP_CRY)
     {
       emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
-      emitcode ("anl", "c,/%s", AOP (left)->aopu.aop_dir);
+      emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
     }
   else
     {
@@ -5198,13 +5886,13 @@ genCmp (operand * left, operand * 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 && AOP_TYPE (left) != AOP_STR))
+      if ((size == 1) && !sign 
+         && (AOP_TYPE (right) == AOP_LIT && AOP_TYPE (left) != AOP_DIR && AOP_TYPE (left) != AOP_STR))
        {
          symbol *lbl = newiTempLabel (NULL);
          emitcode ("cjne", "%s,%s,!tlabel",
-                   aopGet (AOP (left), offset, FALSE, FALSE, FALSE),
-                   aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+                   aopGet (AOP (left), offset, FALSE, FALSE, NULL),
+                   aopGet (AOP (right), offset, FALSE, FALSE, NULL),
                    lbl->key + 100);
          emitcode ("", "!tlabeldef", lbl->key + 100);
        }
@@ -5222,7 +5910,7 @@ genCmp (operand * left, operand * right,
                    }
                  else
                    {
-                     MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE, FALSE, TRUE));
+                     MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE, FALSE, NULL));
 
                      freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
                      freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
@@ -5247,35 +5935,28 @@ genCmp (operand * left, operand * right,
          CLRC;
          while (size--)
            {
-             //emitcode (";", "genCmp #1: %d/%d/%d", size, sign, offset);
-             MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
-             //emitcode (";", "genCmp #2");
+             // emitcode (";", "genCmp #1: %d/%d/%d", size, sign, offset);
+             MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
+             // emitcode (";", "genCmp #2");
              if (sign && (size == 0))
                {
-                   //emitcode (";", "genCmp #3");
+                 // emitcode (";", "genCmp #3");
                  emitcode ("xrl", "a,#!constbyte",0x80);
                  if (AOP_TYPE (right) == AOP_LIT)
                    {
                      unsigned long lit = (unsigned long)
                      floatFromVal (AOP (right)->aopu.aop_lit);
-                     //emitcode (";", "genCmp #3.1");
+                     // emitcode (";", "genCmp #3.1");
                      emitcode ("subb", "a,#!constbyte",
                                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 (";", "genCmp #3.2");
+                     saveAccWarn = 0;  
+                     MOVB(aopGet (AOP (right), offset++, FALSE, FALSE, "b"));
+                     saveAccWarn = DEFAULT_ACC_WARNING;
                      emitcode ("xrl", "b,#!constbyte",0x80);
-                     if (AOP_NEEDSACC (right))
-                       {
-                         emitcode ("pop", "acc");
-                       }
                      emitcode ("subb", "a,b");
                    }
                }
@@ -5283,21 +5964,10 @@ genCmp (operand * left, operand * right,
                {
                  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 (";", "genCmp #4");
+                 saveAccWarn = 0;
+                 s = aopGet (AOP (right), offset++, FALSE, FALSE, "b");
+                 saveAccWarn = DEFAULT_ACC_WARNING;
 
                  emitcode ("subb", "a,%s", s);
                }
@@ -5404,6 +6074,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
      if the right is in a pointer register and left
      is not */
   if ((AOP_TYPE (left) == AOP_LIT) ||
+      (AOP_TYPE (left) == AOP_IMMD) ||
       (IS_AOP_PREG (right) && !IS_AOP_PREG (left)))
     {
       operand *t = right;
@@ -5420,8 +6091,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
        * Exclude the generic type byte from the comparison.
        */
       size--;
-      D (emitcode (";", "cjneshort: generic ptr special case.");
-       )
+      D (emitcode (";", "cjneshort: generic ptr special case."););
     }
 
 
@@ -5431,10 +6101,9 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
     {
       while (size--)
        {
-         char *l = aopGet (AOP (left), offset, FALSE, FALSE, TRUE);
-         MOVA (l);
+         MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
          emitcode ("cjne", "a,%s,!tlabel",
-                   aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+                   aopGet (AOP (right), offset, FALSE, FALSE, NULL),
                    lbl->key + 100);
          offset++;
        }
@@ -5444,18 +6113,20 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
      if the left is a pointer register & right is not */
   else if (AOP_TYPE (right) == AOP_REG ||
           AOP_TYPE (right) == AOP_DIR ||
+           AOP_TYPE (right) == AOP_LIT ||
+           AOP_TYPE (right) == AOP_IMMD ||
           (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));
+         MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
          if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) &&
              ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
            emitcode ("jnz", "!tlabel", lbl->key + 100);
          else
            emitcode ("cjne", "a,%s,!tlabel",
-                     aopGet (AOP (right), offset, FALSE, TRUE, FALSE),
+                     aopGet (AOP (right), offset, FALSE, TRUE, DP2_RESULT_REG),
                      lbl->key + 100);
          offset++;
        }
@@ -5465,10 +6136,8 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
       /* 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));
+         MOVB (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
+         MOVA (aopGet (AOP (right), offset, FALSE, FALSE, NULL));
          emitcode ("cjne", "a,b,!tlabel", lbl->key + 100);
          offset++;
        }
@@ -5915,9 +6584,9 @@ genFarFarLogicOp(iCode *ic, char *logicOp)
       _startLazyDPSEvaluation();
       for (size = compSize; (size--); offset++)
       {
-         MOVA (aopGet (AOP (IC_LEFT(ic)), offset, FALSE, FALSE, TRUE));
+         MOVA (aopGet (AOP (IC_LEFT(ic)), offset, FALSE, FALSE, NULL));
          emitcode ("mov", "%s, acc", DP2_RESULT_REG);
-         MOVA (aopGet (AOP (IC_RIGHT(ic)), offset, FALSE, FALSE, TRUE));
+         MOVA (aopGet (AOP (IC_RIGHT(ic)), offset, FALSE, FALSE, NULL));
          
          emitcode (logicOp, "a,%s", DP2_RESULT_REG);
          emitcode ("push", "acc");
@@ -5952,8 +6621,8 @@ genAnd (iCode * ic, iCode * ifx)
   operand *left, *right, *result;
   int size, offset = 0;
   unsigned long lit = 0L;
-  int bytelit = 0;
-  char buffer[10];
+  int bytelit;
+  char buff[10];
   bool pushResult;
 
   D (emitcode (";", "genAnd "););
@@ -6050,7 +6719,7 @@ genAnd (iCode * ic, iCode * ifx)
          else
            {
              // c = bit & val;
-             MOVA (aopGet (AOP (right), 0, FALSE, FALSE, TRUE));
+             MOVA (aopGet (AOP (right), 0, FALSE, FALSE, NULL));
              // c = lsb
              emitcode ("rrc", "a");
              emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
@@ -6077,7 +6746,7 @@ genAnd (iCode * ic, iCode * ifx)
       if (posbit)
        {
          posbit--;
-         MOVA (aopGet (AOP (left), posbit >> 3, FALSE, FALSE, TRUE));
+         MOVA (aopGet (AOP (left), posbit >> 3, FALSE, FALSE, NULL));
          // bit = left & 2^n
          if (size)
            emitcode ("mov", "c,acc.%d", posbit & 0x07);
@@ -6086,8 +6755,9 @@ genAnd (iCode * ic, iCode * ifx)
            {
              if (ifx)
                {
-                 sprintf (buffer, "acc.%d", posbit & 0x07);
-                 genIfxJump (ifx, buffer);
+                 SNPRINTF (buff, sizeof(buff), 
+                           "acc.%d", posbit & 0x07);
+                 genIfxJump (ifx, buff);
                }
              else 
                  {
@@ -6106,7 +6776,7 @@ genAnd (iCode * ic, iCode * ifx)
            {
              if ((bytelit = ((lit >> (offset * 8)) & 0x0FFL)) != 0x0L)
                {
-                 MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                 MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
                  // byte ==  2^n ?
                  if ((posbit = isLiteralBit (bytelit)) != 0)
                    emitcode ("jb", "acc.%d,!tlabel", (posbit - 1) & 0x07, tlbl->key + 100);
@@ -6114,7 +6784,7 @@ genAnd (iCode * ic, iCode * ifx)
                    {
                      if (bytelit != 0x0FFL)
                        emitcode ("anl", "a,%s",
-                         aopGet (AOP (right), offset, FALSE, TRUE, FALSE));
+                         aopGet (AOP (right), offset, FALSE, TRUE, DP2_RESULT_REG));
                      emitcode ("jnz", "!tlabel", tlbl->key + 100);
                    }
                }
@@ -6131,6 +6801,8 @@ genAnd (iCode * ic, iCode * ifx)
            {
              if (ifx)
                jmpTrueOrFalse (ifx, tlbl);
+              else
+               emitcode ("", "!tlabeldef", tlbl->key + 100);
              goto release;
            }
        }
@@ -6151,31 +6823,33 @@ genAnd (iCode * ic, iCode * ifx)
                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));
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, NULL));
+                 emitcode ("anl", "a,%s",
+                           aopGet (AOP (left), offset, FALSE, TRUE, DP2_RESULT_REG));
                  aopPut (AOP (result), "a", offset);
                }
              else
                emitcode ("anl", "%s,%s",
-                         aopGet (AOP (left), offset, FALSE, TRUE, FALSE),
-                         aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+                         aopGet (AOP (left), offset, FALSE, TRUE, NULL),
+                         aopGet (AOP (right), offset, FALSE, FALSE, NULL));
            }
          else
            {
              if (AOP_TYPE (left) == AOP_ACC)
-               emitcode ("anl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+               emitcode ("anl", "a,%s",
+                         aopGet (AOP (right), offset, FALSE, FALSE, DP2_RESULT_REG));
              else
                {
-                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, NULL));
                  if (IS_AOP_PREG (result))
                    {
-                     emitcode ("anl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                     emitcode ("anl", "a,%s",
+                               aopGet (AOP (left), offset, FALSE, TRUE, DP2_RESULT_REG));
                      aopPut (AOP (result), "a", offset);
-
                    }
                  else
                    emitcode ("anl", "%s,a",
-                          aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                          aopGet (AOP (left), offset, FALSE, TRUE, DP2_RESULT_REG));
                }
            }
        }
@@ -6196,16 +6870,16 @@ genAnd (iCode * ic, iCode * ifx)
            {
              if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
                emitcode ("anl", "a,%s",
-                         aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+                         aopGet (AOP (right), offset, FALSE, FALSE, DP2_RESULT_REG));
              } else {
                if (AOP_TYPE(left)==AOP_ACC) {
                  emitcode("mov", "b,a");
-                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, NULL));
                  emitcode("anl", "a,b");
                }else {
-                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, NULL));
                  emitcode ("anl", "a,%s",
-                           aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+                           aopGet (AOP (left), offset, FALSE, FALSE, DP2_RESULT_REG));
                }
              }
              emitcode ("jnz", "!tlabel", tlbl->key + 100);
@@ -6219,6 +6893,8 @@ genAnd (iCode * ic, iCode * ifx)
            }
          else if (ifx)
            jmpTrueOrFalse (ifx, tlbl);
+          else
+           emitcode ("", "!tlabeldef", tlbl->key + 100);
        }
       else
        {
@@ -6231,7 +6907,7 @@ genAnd (iCode * ic, iCode * ifx)
                  if ((bytelit = (int) ((lit >> (offset * 8)) & 0x0FFL)) == 0x0FF)
                    {
                      aopPut (AOP (result),
-                          aopGet (AOP (left), offset, FALSE, FALSE, FALSE),
+                          aopGet (AOP (left), offset, FALSE, FALSE, NULL),
                              offset);
                      continue;
                    }
@@ -6241,9 +6917,9 @@ genAnd (iCode * ic, iCode * ifx)
                      continue;
                    }
                  D (emitcode (";", "better literal AND."););
-                 MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                 MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
                  emitcode ("anl", "a, %s", aopGet (AOP (right), offset,
-                                                   FALSE, FALSE, FALSE));
+                                                   FALSE, FALSE, DP2_RESULT_REG));
 
                }
              else
@@ -6252,19 +6928,19 @@ genAnd (iCode * ic, iCode * ifx)
                  // and better if result is SFR
                  if (AOP_TYPE (left) == AOP_ACC)
                    {
-                     emitcode ("anl", "a,%s", aopGet (AOP (right), offset,
-                                                      FALSE, FALSE, FALSE));
+                     emitcode ("anl", "a,%s", 
+                               aopGet (AOP (right), offset, FALSE, FALSE, DP2_RESULT_REG));
                    }
                  else
                    {
-                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, NULL);
                      if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
                      {
                          emitcode("mov", "b,a");
                          rOp = "b";
                      }
                        
-                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
                      emitcode ("anl", "a,%s", rOp);
                    }                   
                }
@@ -6409,7 +7085,7 @@ genOr (iCode * ic, iCode * ifx)
        outBitC (result);
       // if(bit | ...)
       else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
-       genIfxJump (ifx, "c");
+          genIfxJump (ifx, "c");
       goto release;
     }
 
@@ -6466,15 +7142,16 @@ genOr (iCode * ic, iCode * ifx)
                {
                  if (IS_AOP_PREG (left))
                    {
-                     MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
-                     emitcode ("orl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                     MOVA (aopGet (AOP (right), offset, FALSE, FALSE, NULL));
+                     emitcode ("orl", "a,%s",
+                               aopGet (AOP (left), offset, FALSE, TRUE, DP2_RESULT_REG));
                      aopPut (AOP (result), "a", offset);
                    }
                  else
                    {
                      emitcode ("orl", "%s,%s",
-                           aopGet (AOP (left), offset, FALSE, TRUE, FALSE),
-                        aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+                               aopGet (AOP (left), offset, FALSE, TRUE, NULL),
+                               aopGet (AOP (right), offset, FALSE, FALSE, DP2_RESULT_REG));
                    }
                }
            }
@@ -6482,20 +7159,22 @@ genOr (iCode * ic, iCode * ifx)
            {
              if (AOP_TYPE (left) == AOP_ACC)
                {
-                 emitcode ("orl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+                 emitcode ("orl", "a,%s",
+                           aopGet (AOP (right), offset, FALSE, FALSE, DP2_RESULT_REG));
                }
              else
                {
-                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, NULL));
                  if (IS_AOP_PREG (left))
                    {
-                     emitcode ("orl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                     emitcode ("orl", "a,%s", 
+                               aopGet (AOP (left), offset, FALSE, TRUE, DP2_RESULT_REG));
                      aopPut (AOP (result), "a", offset);
                    }
                  else
                    {
                      emitcode ("orl", "%s,a",
-                          aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                          aopGet (AOP (left), offset, FALSE, TRUE, DP2_RESULT_REG));
                    }
                }
            }
@@ -6517,11 +7196,11 @@ genOr (iCode * ic, iCode * ifx)
            {
              if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
                emitcode ("orl", "a,%s",
-                         aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+                         aopGet (AOP (right), offset, FALSE, FALSE, DP2_RESULT_REG));
              } else {
-               MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+               MOVA (aopGet (AOP (right), offset, FALSE, FALSE, NULL));
                emitcode ("orl", "a,%s",
-                         aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+                         aopGet (AOP (left), offset, FALSE, FALSE, DP2_RESULT_REG));
              }
              emitcode ("jnz", "!tlabel", tlbl->key + 100);
              offset++;
@@ -6534,6 +7213,8 @@ genOr (iCode * ic, iCode * ifx)
            }
          else if (ifx)
            jmpTrueOrFalse (ifx, tlbl);
+          else
+           emitcode ("", "!tlabeldef", tlbl->key + 100);
        }
       else
        {
@@ -6547,14 +7228,15 @@ genOr (iCode * ic, iCode * ifx)
                  if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
                    {
                      aopPut (AOP (result),
-                          aopGet (AOP (left), offset, FALSE, FALSE, FALSE),
+                          aopGet (AOP (left), offset, FALSE, FALSE, NULL),
                              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));
+                 MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
+                 emitcode ("orl", "a, %s",
+                           aopGet (AOP (right), offset,
+                                   FALSE, FALSE, DP2_RESULT_REG));
 
                }
              else
@@ -6563,12 +7245,13 @@ genOr (iCode * ic, iCode * ifx)
                  // and better if result is SFR
                  if (AOP_TYPE (left) == AOP_ACC)
                    {
-                     emitcode ("orl", "a,%s", aopGet (AOP (right), offset,
-                                                      FALSE, FALSE, FALSE));
+                     emitcode ("orl", "a,%s",
+                               aopGet (AOP (right), offset,
+                                       FALSE, FALSE, DP2_RESULT_REG));
                    }
                  else
                    {
-                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, NULL);
                        
                      if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
                      {
@@ -6576,7 +7259,7 @@ genOr (iCode * ic, iCode * ifx)
                          rOp = "b";
                      }
                        
-                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
                      emitcode ("orl", "a,%s", rOp);
                    }
                }
@@ -6721,7 +7404,7 @@ genXor (iCode * ic, iCode * ifx)
              emitcode ("setb", "c");
              while (sizer)
                {
-                 MOVA (aopGet (AOP (right), sizer - 1, FALSE, FALSE, TRUE));
+                 MOVA (aopGet (AOP (right), sizer - 1, FALSE, FALSE, NULL));
                  if (sizer == 1)
                    // test the msb of the lsb
                    emitcode ("anl", "a,#!constbyte",0xfe);
@@ -6756,30 +7439,33 @@ genXor (iCode * ic, iCode * ifx)
                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));
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, NULL));
+                 emitcode ("xrl", "a,%s",
+                           aopGet (AOP (left), offset, FALSE, TRUE, DP2_RESULT_REG));
                  aopPut (AOP (result), "a", offset);
                }
              else
                emitcode ("xrl", "%s,%s",
-                         aopGet (AOP (left), offset, FALSE, TRUE, FALSE),
-                         aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+                         aopGet (AOP (left), offset, FALSE, TRUE, NULL),
+                         aopGet (AOP (right), offset, FALSE, FALSE, DP2_RESULT_REG));
            }
          else
            {
              if (AOP_TYPE (left) == AOP_ACC)
-               emitcode ("xrl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+               emitcode ("xrl", "a,%s",
+                         aopGet (AOP (right), offset, FALSE, FALSE, DP2_RESULT_REG));
              else
                {
-                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, NULL));
                  if (IS_AOP_PREG (left))
                    {
-                     emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                     emitcode ("xrl", "a,%s",
+                               aopGet (AOP (left), offset, FALSE, TRUE, DP2_RESULT_REG));
                      aopPut (AOP (result), "a", offset);
                    }
                  else
                    emitcode ("xrl", "%s,a",
-                          aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                          aopGet (AOP (left), offset, FALSE, TRUE, DP2_RESULT_REG));
                }
            }
        }
@@ -6802,22 +7488,22 @@ genXor (iCode * ic, iCode * ifx)
              if ((AOP_TYPE (right) == AOP_LIT) &&
                  (((lit >> (offset * 8)) & 0x0FFL) == 0x00L))
                {
-                 MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                 MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
                }
              else
                {
                  if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
                    emitcode ("xrl", "a,%s",
-                             aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+                             aopGet (AOP (right), offset, FALSE, FALSE, DP2_RESULT_REG));
                  } else {
-                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, NULL);
                      if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
                      {
                          emitcode("mov", "b,a");
                          rOp = "b";
                      }
                        
-                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
                      emitcode ("xrl", "a,%s", rOp);                  
                  }
                }
@@ -6844,14 +7530,14 @@ genXor (iCode * ic, iCode * ifx)
                if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
                  {
                    aopPut (AOP (result),
-                           aopGet (AOP (left), offset, FALSE, FALSE, FALSE),
+                           aopGet (AOP (left), offset, FALSE, FALSE, NULL),
                            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));
+               MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
+               emitcode ("xrl", "a, %s",
+                         aopGet (AOP (right), offset, FALSE, FALSE, DP2_RESULT_REG));
              }
            else
              {
@@ -6859,19 +7545,20 @@ genXor (iCode * ic, iCode * ifx)
                // and better if result is SFR
                if (AOP_TYPE (left) == AOP_ACC)
                  {
-                   emitcode ("xrl", "a,%s", aopGet (AOP (right), offset,
-                                                    FALSE, FALSE, FALSE));
+                   emitcode ("xrl", "a,%s",
+                             aopGet (AOP (right), offset,
+                                     FALSE, FALSE, DP2_RESULT_REG));
                  }
                else
                  {
-                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, NULL);
                      if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
                      {
                          emitcode("mov", "b,a");
                          rOp = "b";
                      }
                        
-                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
                      emitcode ("xrl", "a,%s", rOp);
                  }
              }
@@ -6895,13 +7582,13 @@ genInline (iCode * ic)
 {
   char *buffer, *bp, *bp1;
 
-  D (emitcode (";", "genInline ");
-    );
+  D (emitcode (";", "genInline "); );
 
   _G.inLine += (!options.asmpeep);
 
-  buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
-  strcpy (buffer, IC_INLINE (ic));
+  buffer = Safe_strdup(IC_INLINE(ic));
+  bp = buffer;
+  bp1 = buffer;
 
   /* emit each line as a code */
   while (*bp)
@@ -6939,17 +7626,15 @@ static void
 genRRC (iCode * ic)
 {
   operand *left, *result;
-  int size, offset = 0;
-  char *l;
+  int    size, offset;
 
-  D (emitcode (";", "genRRC ");
-    );
+  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);
+  aopOp (result, ic, FALSE, AOP_USESDPTR(left));
 
   /* move it to the result */
   size = AOP_SIZE (result);
@@ -6959,8 +7644,7 @@ genRRC (iCode * ic)
   _startLazyDPSEvaluation ();
   while (size--)
     {
-      l = aopGet (AOP (left), offset, FALSE, FALSE, TRUE);
-      MOVA (l);
+      MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
       emitcode ("rrc", "a");
       if (AOP_SIZE (result) > 1)
        aopPut (AOP (result), "a", offset--);
@@ -6971,8 +7655,7 @@ genRRC (iCode * ic)
      highest order byte of the result */
   if (AOP_SIZE (result) > 1)
     {
-      l = aopGet (AOP (result), AOP_SIZE (result) - 1, FALSE, FALSE, TRUE);
-      MOVA (l);
+      MOVA (aopGet (AOP (result), AOP_SIZE (result) - 1, FALSE, FALSE, NULL));
     }
   emitcode ("mov", "acc.7,c");
   aopPut (AOP (result), "a", AOP_SIZE (result) - 1);
@@ -6987,24 +7670,23 @@ static void
 genRLC (iCode * ic)
 {
   operand *left, *result;
-  int size, offset = 0;
+  int size, offset;
   char *l;
 
-  D (emitcode (";", "genRLC ");
-    );
+  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);
+  aopOp (result, ic, FALSE, AOP_USESDPTR(left));
 
   /* move it to the result */
   size = AOP_SIZE (result);
   offset = 0;
   if (size--)
     {
-      l = aopGet (AOP (left), offset, FALSE, FALSE, TRUE);
+      l = aopGet (AOP (left), offset, FALSE, FALSE, NULL);
       MOVA (l);
       emitcode ("add", "a,acc");
       if (AOP_SIZE (result) > 1)
@@ -7015,7 +7697,7 @@ genRLC (iCode * ic)
       _startLazyDPSEvaluation ();
       while (size--)
        {
-         l = aopGet (AOP (left), offset, FALSE, FALSE, TRUE);
+         l = aopGet (AOP (left), offset, FALSE, FALSE, NULL);
          MOVA (l);
          emitcode ("rlc", "a");
          if (AOP_SIZE (result) > 1)
@@ -7027,7 +7709,7 @@ genRLC (iCode * ic)
      highest order byte of the result */
   if (AOP_SIZE (result) > 1)
     {
-      l = aopGet (AOP (result), 0, FALSE, FALSE, TRUE);
+      l = aopGet (AOP (result), 0, FALSE, FALSE, NULL);
       MOVA (l);
     }
   emitcode ("mov", "acc.0,c");
@@ -7046,13 +7728,12 @@ genGetHbit (iCode * ic)
   left = IC_LEFT (ic);
   result = IC_RESULT (ic);
   aopOp (left, ic, FALSE, FALSE);
-  aopOp (result, ic, FALSE, AOP_TYPE (left) == AOP_DPTR);
+  aopOp (result, ic, FALSE, AOP_USESDPTR(left));
 
-  D (emitcode (";", "genGetHbit ");
-    );
+  D (emitcode (";", "genGetHbit "););
 
   /* get the highest order byte into a */
-  MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE, FALSE, TRUE));
+  MOVA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE, FALSE, NULL));
   if (AOP_TYPE (result) == AOP_CRY)
     {
       emitcode ("rlc", "a");
@@ -7070,6 +7751,65 @@ genGetHbit (iCode * ic)
   freeAsmop (result, NULL, ic, TRUE);
 }
 
+/*-----------------------------------------------------------------*/
+/* genSwap - generates code to swap nibbles or bytes               */
+/*-----------------------------------------------------------------*/
+static void
+genSwap (iCode * ic)
+{
+  operand *left, *result;
+
+  D(emitcode (";     genSwap",""));
+
+  left = IC_LEFT (ic);
+  result = IC_RESULT (ic);
+  aopOp (left, ic, FALSE, FALSE);
+  aopOp (result, ic, FALSE, AOP_USESDPTR(left));
+  
+  _startLazyDPSEvaluation ();
+  switch (AOP_SIZE (left))
+    {
+    case 1: /* swap nibbles in byte */
+      MOVA (aopGet (AOP (left), 0, FALSE, FALSE, NULL));
+      emitcode ("swap", "a");
+      aopPut (AOP (result), "a", 0);
+      break;
+    case 2: /* swap bytes in word */
+      if (AOP_TYPE(left) == AOP_REG && sameRegs(AOP(left), AOP(result)))
+       {
+         MOVA (aopGet (AOP (left), 0, FALSE, FALSE, NULL));
+         aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE, NULL), 0);
+         aopPut (AOP (result), "a", 1);
+       }
+      else if (operandsEqu (left, result))
+       {
+          char * reg = "a";
+         MOVA (aopGet (AOP (left), 0, FALSE, FALSE, NULL));
+         if (AOP_NEEDSACC (left) || AOP_NEEDSACC (result))
+           {
+             emitcode ("mov", "b,a");
+              reg = "b";
+              _G.bInUse=1;
+            }
+         aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE, NULL), 0);
+         aopPut (AOP (result), reg, 1);
+          _G.bInUse=0;
+       }
+      else
+       {
+         aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE, NULL), 0);
+         aopPut (AOP (result), aopGet (AOP (left), 0, FALSE, FALSE, NULL), 1);
+       }
+      break;
+    default:
+      wassertl(FALSE, "unsupported SWAP operand size");
+    }
+  _endLazyDPSEvaluation ();
+  
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
 /*-----------------------------------------------------------------*/
 /* AccRol - rotate left accumulator by known count                 */
 /*-----------------------------------------------------------------*/
@@ -7205,7 +7945,7 @@ shiftR1Left2Result (operand * left, int offl,
                    operand * result, int offr,
                    int shCount, int sign)
 {
-  MOVA (aopGet (AOP (left), offl, FALSE, FALSE, TRUE));
+  MOVA (aopGet (AOP (left), offl, FALSE, FALSE, NULL));
   /* shift right accumulator */
   if (sign)
     AccSRsh (shCount);
@@ -7223,7 +7963,7 @@ static void
 shiftL1Left2Result (operand * left, int offl,
                    operand * result, int offr, int shCount)
 {
-  MOVA(aopGet (AOP (left), offl, FALSE, FALSE, TRUE));
+  MOVA(aopGet (AOP (left), offl, FALSE, FALSE, NULL));
   /* shift left accumulator */
   AccLsh (shCount);
   aopPut (AOP (result), "a", offr);
@@ -7241,7 +7981,7 @@ movLeft2Result (operand * left, int offl,
   char *l;
   if (!sameRegs (AOP (left), AOP (result)) || (offl != offr))
   {
-      l = aopGet (AOP (left), offl, FALSE, FALSE, TRUE);
+      l = aopGet (AOP (left), offl, FALSE, FALSE, NULL);
 
       if (*l == '@' && (IS_AOP_PREG (result)))
       {
@@ -7605,22 +8345,22 @@ _loadLeftIntoAx(char    **lsb,
       if (AOP_TYPE(left) == AOP_DPTR2)
        {
            // Get MSB in A.
-                  MOVA(aopGet(AOP(left), offl + MSB16, FALSE, FALSE, TRUE));
+                  MOVA(aopGet(AOP(left), offl + MSB16, FALSE, FALSE, NULL));
                   // get LSB in DP2_RESULT_REG.
-                  leftByte = aopGet(AOP(left), offl, FALSE, FALSE, FALSE);
+                  leftByte = aopGet(AOP(left), offl, FALSE, FALSE, DP2_RESULT_REG);
                   assert(!strcmp(leftByte, DP2_RESULT_REG));
        }
        else
        {
            // get LSB into DP2_RESULT_REG
-                  leftByte = aopGet (AOP(left), offl, FALSE, FALSE, TRUE);
+                  leftByte = aopGet (AOP(left), offl, FALSE, FALSE, NULL);
            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);
+                  leftByte = aopGet(AOP(left), offl + MSB16, FALSE, FALSE, NULL);
                   assert(strcmp(leftByte, DP2_RESULT_REG));
                   MOVA(leftByte);
        }
@@ -7633,16 +8373,16 @@ _loadLeftIntoAx(char    **lsb,
        ((offl + MSB16) == offr))
       {
          /* don't crash result[offr] */
-         MOVA(aopGet(AOP(left), offl, FALSE, FALSE, TRUE));
+         MOVA(aopGet(AOP(left), offl, FALSE, FALSE, NULL));
          emitcode ("xch", "a,%s", 
-                   aopGet(AOP(left), offl + MSB16, FALSE, FALSE, FALSE));
+                   aopGet(AOP(left), offl + MSB16, FALSE, FALSE, DP2_RESULT_REG));
       }
       else
       {
          movLeft2Result (left, offl, result, offr, 0);
-         MOVA (aopGet (AOP (left), offl + MSB16, FALSE, FALSE, TRUE));
+         MOVA (aopGet (AOP (left), offl + MSB16, FALSE, FALSE, NULL));
       }
-      *lsb = aopGet(AOP (result), offr, FALSE, FALSE, FALSE);
+      *lsb = aopGet(AOP (result), offr, FALSE, FALSE, DP2_RESULT_REG);
       assert(strcmp(*lsb,"a"));      
   }
 }
@@ -7712,8 +8452,6 @@ shiftR2Left2Result (operand * left, int offl,
 }
 #endif
 
-#if 0
-//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* shiftLLeftOrResult - shift left one byte from left, or to result */
 /*-----------------------------------------------------------------*/
@@ -7721,15 +8459,15 @@ static void
 shiftLLeftOrResult (operand * left, int offl,
                    operand * result, int offr, int shCount)
 {
-  MOVA (aopGet (AOP (left), offl, FALSE, FALSE, TRUE));
+  MOVA (aopGet (AOP (left), offl, FALSE, FALSE, NULL));
   /* shift left accumulator */
   AccLsh (shCount);
   /* or with result */
-  emitcode ("orl", "a,%s", aopGet (AOP (result), offr, FALSE, FALSE, FALSE));
+  emitcode ("orl", "a,%s",
+           aopGet (AOP (result), offr, FALSE, FALSE, DP2_RESULT_REG));
   /* back to result */
   aopPut (AOP (result), "a", offr);
 }
-#endif
 
 #if 0
 //REMOVE ME!!!
@@ -7740,11 +8478,12 @@ static void
 shiftRLeftOrResult (operand * left, int offl,
                    operand * result, int offr, int shCount)
 {
-  MOVA (aopGet (AOP (left), offl, FALSE, FALSE, TRUE));
+  MOVA (aopGet (AOP (left), offl, FALSE, FALSE, NULL));
   /* shift right accumulator */
   AccRsh (shCount);
   /* or with result */
-  emitcode ("orl", "a,%s", aopGet (AOP (result), offr, FALSE, FALSE, FALSE));
+  emitcode ("orl", "a,%s",
+           aopGet (AOP (result), offr, FALSE, FALSE, DP2_RESULT_REG));
   /* back to result */
   aopPut (AOP (result), "a", offr);
 }
@@ -7833,13 +8572,13 @@ shiftLLong (operand * left, operand * result, int offr)
 
   if (size >= LSB + offr)
     {
-      l = aopGet (AOP (left), LSB, FALSE, FALSE, TRUE);
+      l = aopGet (AOP (left), LSB, FALSE, FALSE, NULL);
       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));
+                 aopGet (AOP (left), LSB + offr, FALSE, FALSE, DP2_RESULT_REG));
       else
        aopPut (AOP (result), "a", LSB + offr);
     }
@@ -7848,14 +8587,13 @@ shiftLLong (operand * left, operand * result, int offr)
     {
       if (!(sameRegs (AOP (result), AOP (left)) && size >= MSB16 + offr && offr != LSB))
        {
-         l = aopGet (AOP (left), MSB16, FALSE, FALSE, TRUE);
-         MOVA (l);
+         MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE, TRUE));
        }
       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));
+                 aopGet (AOP (left), MSB16 + offr, FALSE, FALSE, DP2_RESULT_REG));
       else
        aopPut (AOP (result), "a", MSB16 + offr);
     }
@@ -7864,14 +8602,13 @@ shiftLLong (operand * left, operand * result, int offr)
     {
       if (!(sameRegs (AOP (left), AOP (left)) && size >= MSB24 + offr && offr != LSB))
        {
-         l = aopGet (AOP (left), MSB24, FALSE, FALSE, TRUE);
-         MOVA (l);
+         MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE, NULL));
        }
       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));
+                 aopGet (AOP (left), MSB24 + offr, FALSE, FALSE, DP2_RESULT_REG));
       else
        aopPut (AOP (result), "a", MSB24 + offr);
     }
@@ -7880,8 +8617,7 @@ shiftLLong (operand * left, operand * result, int offr)
     {
       if (!(sameRegs (AOP (result), AOP (left)) && size >= MSB32 + offr && offr != LSB))
        {
-         l = aopGet (AOP (left), MSB32, FALSE, FALSE, TRUE);
-         MOVA (l);
+         MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE, NULL));
        }
       emitcode ("rlc", "a");
       aopPut (AOP (result), "a", MSB32 + offr);
@@ -8020,7 +8756,7 @@ genLeftShiftLiteral (operand * left,
   freeAsmop (right, NULL, ic, TRUE);
 
   aopOp(left, ic, FALSE, FALSE);
-  aopOp(result, ic, FALSE, (AOP_TYPE(left) == AOP_DPTR));
+  aopOp(result, ic, FALSE, AOP_USESDPTR(left));
 
 #if 0 // debug spew
   if (IS_SYMOP(left) && OP_SYMBOL(left)->aop)
@@ -8141,12 +8877,12 @@ genLeftShift (iCode * ic)
   }
   else
   {
-       emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, FALSE));
-       emitcode ("inc", "b");
+      MOVB(aopGet (AOP (right), 0, FALSE, FALSE, "b"));
+      emitcode ("inc", "b");
   }
   freeAsmop (right, NULL, ic, TRUE);
   aopOp (left, ic, FALSE, FALSE);
-  aopOp (result, ic, FALSE, AOP_TYPE (left) == AOP_DPTR);
+  aopOp (result, ic, FALSE, AOP_USESDPTR(left));
 
   /* now move the left to the result if they are not the
      same */
@@ -8159,7 +8895,7 @@ genLeftShift (iCode * ic)
       _startLazyDPSEvaluation ();
       while (size--)
        {
-         l = aopGet (AOP (left), offset, FALSE, TRUE, FALSE);
+         l = aopGet (AOP (left), offset, FALSE, TRUE, NULL);
          if (*l == '@' && (IS_AOP_PREG (result)))
            {
 
@@ -8183,8 +8919,7 @@ genLeftShift (iCode * ic)
     {
       symbol *tlbl1 = newiTempLabel (NULL);
 
-      l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
-      MOVA (l);
+      MOVA (aopGet (AOP (left), 0, FALSE, FALSE, NULL));
       emitcode ("sjmp", "!tlabel", tlbl1->key + 100);
       emitcode ("", "!tlabeldef", tlbl->key + 100);
       emitcode ("add", "a,acc");
@@ -8198,15 +8933,13 @@ genLeftShift (iCode * ic)
 
   emitcode ("sjmp", "!tlabel", tlbl1->key + 100);
   emitcode ("", "!tlabeldef", tlbl->key + 100);
-  l = aopGet (AOP (result), offset, FALSE, FALSE, TRUE);
-  MOVA (l);
+  MOVA (aopGet (AOP (result), offset, FALSE, FALSE, NULL));
   emitcode ("add", "a,acc");
   aopPut (AOP (result), "a", offset++);
   _startLazyDPSEvaluation ();
   while (--size)
     {
-      l = aopGet (AOP (result), offset, FALSE, FALSE, TRUE);
-      MOVA (l);
+      MOVA (aopGet (AOP (result), offset, FALSE, FALSE, NULL));
       emitcode ("rlc", "a");
       aopPut (AOP (result), "a", offset++);
     }
@@ -8269,8 +9002,6 @@ genrshTwo (operand * result, operand * left,
 }
 #endif
 
-#if 0
-//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* shiftRLong - shift right one long from left to result           */
 /* offl = LSB or MSB16                                             */
@@ -8286,14 +9017,15 @@ shiftRLong (operand * left, int offl,
     werror(E_INTERNAL_ERROR, __FILE__, __LINE__);
   }
 
-  MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE));
+  MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE, NULL));
   
   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));
+      emitcode ("xch", "a,%s",
+               aopGet(AOP(left), MSB32, FALSE, FALSE, DP2_RESULT_REG));
     } else {
       aopPut (AOP(result), zero, MSB32);
     }
@@ -8308,33 +9040,32 @@ shiftRLong (operand * left, int offl,
   emitcode ("rrc", "a");
 
   if (isSameRegs && offl==MSB16) {
-    emitcode ("xch", "a,%s",aopGet (AOP (left), MSB24, FALSE, FALSE));
+    emitcode ("xch",
+             "a,%s",aopGet (AOP (left), MSB24, FALSE, FALSE, DP2_RESULT_REG));
   } else {
     aopPut (AOP (result), "a", MSB32);
-    MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE));
+    MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE, NULL));
   }
 
   emitcode ("rrc", "a");
   if (isSameRegs && offl==1) {
-    emitcode ("xch", "a,%s",aopGet (AOP (left), MSB16, FALSE, FALSE));
+    emitcode ("xch", "a,%s",
+             aopGet (AOP (left), MSB16, FALSE, FALSE, DP2_RESULT_REG));
   } else {
     aopPut (AOP (result), "a", MSB24);
-    MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE));
+    MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE, NULL));
   }
   emitcode ("rrc", "a");
   aopPut (AOP (result), "a", MSB16 - offl);
 
   if (offl == LSB)
     {
-      MOVA (aopGet (AOP (left), LSB, FALSE, FALSE));
+      MOVA (aopGet (AOP (left), LSB, FALSE, FALSE, NULL));
       emitcode ("rrc", "a");
       aopPut (AOP (result), "a", LSB);
     }
 }
-#endif
 
-#if 0
-//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* genrshFour - shift four byte by a known amount != 0             */
 /*-----------------------------------------------------------------*/
@@ -8342,22 +9073,24 @@ static void
 genrshFour (operand * result, operand * left,
            int shCount, int sign)
 {
-  D (emitcode (";", "genrshFour");
-    );
+  D (emitcode (";", "genrshFour"););
 
   /* if shifting more that 3 bytes */
   if (shCount >= 24)
     {
       shCount -= 24;
+      _startLazyDPSEvaluation();
       if (shCount)
        shiftR1Left2Result (left, MSB32, result, LSB, shCount, sign);
       else
        movLeft2Result (left, MSB32, result, LSB, sign);
       addSign (result, MSB16, sign);
+      _endLazyDPSEvaluation();
     }
   else if (shCount >= 16)
     {
       shCount -= 16;
+      _startLazyDPSEvaluation();
       if (shCount)
        shiftR2Left2Result (left, MSB24, result, LSB, shCount, sign);
       else
@@ -8366,12 +9099,16 @@ genrshFour (operand * result, operand * left,
          movLeft2Result (left, MSB32, result, MSB16, sign);
        }
       addSign (result, MSB24, sign);
+      _endLazyDPSEvaluation();
     }
   else if (shCount >= 8)
     {
       shCount -= 8;
+      _startLazyDPSEvaluation();
       if (shCount == 1)
-       shiftRLong (left, MSB16, result, sign);
+       {
+           shiftRLong (left, MSB16, result, sign);
+       }
       else if (shCount == 0)
        {
          movLeft2Result (left, MSB16, result, LSB, 0);
@@ -8387,9 +9124,11 @@ genrshFour (operand * result, operand * left,
          shiftR1Left2Result (left, MSB32, result, MSB24, shCount, sign);
          addSign (result, MSB32, sign);
        }
+       _endLazyDPSEvaluation();
     }
   else
-    {                          /* 1 <= shCount <= 7 */
+    {  
+       /* 1 <= shCount <= 7 */
       if (shCount <= 2)
        {
          shiftRLong (left, LSB, result, sign);
@@ -8404,7 +9143,6 @@ genrshFour (operand * result, operand * left,
        }
     }
 }
-#endif
 
 #ifdef BETTER_LITERAL_SHIFT
 /*-----------------------------------------------------------------*/
@@ -8428,16 +9166,17 @@ genRightShiftLiteral (operand * left,
   if ((shCount != 0)
    && (shCount < (size * 8))
    && (size != 1)
-   && (size != 2))
+   && (size != 2)
+   && (size != 4))
   {
-      D(emitcode (";", "genRightShiftLiteral wimping out"););  
+      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);
+  aopOp (result, ic, FALSE, AOP_USESDPTR(left));
 
 #if VIEW_SIZE
   emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
@@ -8462,7 +9201,7 @@ genRightShiftLiteral (operand * left,
       if (sign)
       {
        /* get sign in acc.7 */
-       MOVA (aopGet (AOP (left), size - 1, FALSE, FALSE, TRUE));
+       MOVA (aopGet (AOP (left), size - 1, FALSE, FALSE, NULL));
       }
       addSign (result, LSB, sign);
     }
@@ -8477,7 +9216,7 @@ genRightShiftLiteral (operand * left,
        case 2:
          genrshTwo (result, left, shCount, sign);
          break;
-#if 0
+#if 1
        case 4:
          genrshFour (result, left, shCount, sign);
          break;
@@ -8485,11 +9224,11 @@ genRightShiftLiteral (operand * left,
        default:
          break;
        }
-
-      freeAsmop (left, NULL, ic, TRUE);
-      freeAsmop (result, NULL, ic, TRUE);
     }
-    return TRUE;
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+  
+  return TRUE;
 }
 #endif
 
@@ -8541,12 +9280,12 @@ genSignedRightShift (iCode * ic)
   }
   else
   {
-       emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, FALSE));
+       MOVB(aopGet (AOP (right), 0, FALSE, FALSE, "b"));
        emitcode ("inc", "b");
   }
   freeAsmop (right, NULL, ic, TRUE);
   aopOp (left, ic, FALSE, FALSE);
-  aopOp (result, ic, FALSE, AOP_TYPE (left) == AOP_DPTR);
+  aopOp (result, ic, FALSE, AOP_USESDPTR(left)); 
 
   /* now move the left to the result if they are not the
      same */
@@ -8559,7 +9298,7 @@ genSignedRightShift (iCode * ic)
       _startLazyDPSEvaluation ();
       while (size--)
        {
-         l = aopGet (AOP (left), offset, FALSE, TRUE, FALSE);
+         l = aopGet (AOP (left), offset, FALSE, TRUE, NULL);
          if (*l == '@' && IS_AOP_PREG (result))
            {
 
@@ -8579,14 +9318,13 @@ genSignedRightShift (iCode * ic)
 
   size = AOP_SIZE (result);
   offset = size - 1;
-  emitcode ("mov", "a,%s", aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+  MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
   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);
+      MOVA( aopGet (AOP (left), 0, FALSE, FALSE, NULL));
       emitcode ("sjmp", "!tlabel", tlbl1->key + 100);
       emitcode ("", "!tlabeldef", tlbl->key + 100);
       emitcode ("mov", "c,ov");
@@ -8604,8 +9342,7 @@ genSignedRightShift (iCode * ic)
   _startLazyDPSEvaluation ();
   while (size--)
     {
-      l = aopGet (AOP (result), offset, FALSE, FALSE, TRUE);
-      MOVA (l);
+      MOVA (aopGet (AOP (result), offset, FALSE, FALSE, NULL));
       emitcode ("rrc", "a");
       aopPut (AOP (result), "a", offset--);
     }
@@ -8626,7 +9363,7 @@ static void
 genRightShift (iCode * ic)
 {
   operand *right, *left, *result;
-  sym_link *retype;
+  sym_link *letype;
   int size, offset;
   char *l;
   symbol *tlbl, *tlbl1;
@@ -8635,9 +9372,9 @@ genRightShift (iCode * ic)
 
   /* if signed then we do it the hard way preserve the
      sign bit moving it inwards */
-  retype = getSpec (operandType (IC_RESULT (ic)));
+  letype = getSpec (operandType (IC_LEFT (ic)));
 
-  if (!SPEC_USIGN (retype))
+  if (!SPEC_USIGN (letype))
     {
       genSignedRightShift (ic);
       return;
@@ -8685,12 +9422,12 @@ genRightShift (iCode * ic)
   }
   else
   {
-       emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, FALSE));
-       emitcode ("inc", "b");
+      MOVB(aopGet (AOP (right), 0, FALSE, FALSE, "b"));
+      emitcode ("inc", "b");
   }
   freeAsmop (right, NULL, ic, TRUE);
   aopOp (left, ic, FALSE, FALSE);
-  aopOp (result, ic, FALSE, AOP_TYPE (left) == AOP_DPTR);
+  aopOp (result, ic, FALSE, AOP_USESDPTR(left));
 
   /* now move the left to the result if they are not the
      same */
@@ -8703,7 +9440,7 @@ genRightShift (iCode * ic)
       _startLazyDPSEvaluation ();
       while (size--)
        {
-         l = aopGet (AOP (left), offset, FALSE, TRUE, FALSE);
+         l = aopGet (AOP (left), offset, FALSE, TRUE, NULL);
          if (*l == '@' && IS_AOP_PREG (result))
            {
 
@@ -8725,8 +9462,7 @@ genRightShift (iCode * ic)
   /* if it is only one byte then */
   if (size == 1)
     {
-      l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
-      MOVA (l);
+      MOVA (aopGet (AOP (left), 0, FALSE, FALSE, NULL));
       emitcode ("sjmp", "!tlabel", tlbl1->key + 100);
       emitcode ("", "!tlabeldef", tlbl->key + 100);
       CLRC;
@@ -8744,8 +9480,7 @@ genRightShift (iCode * ic)
   _startLazyDPSEvaluation ();
   while (size--)
     {
-      l = aopGet (AOP (result), offset, FALSE, FALSE, TRUE);
-      MOVA (l);
+      MOVA (aopGet (AOP (result), offset, FALSE, FALSE, NULL));
       emitcode ("rrc", "a");
       aopPut (AOP (result), "a", offset--);
     }
@@ -8760,118 +9495,148 @@ release:
   freeAsmop (result, NULL, ic, TRUE);
 }
 
+
 /*-----------------------------------------------------------------*/
-/* genUnpackBits - generates code for unpacking bits               */
+/* emitPtrByteGet - emits code to get a byte into A through a      */
+/*                  pointer register (R0, R1, or DPTR). The        */
+/*                  original value of A can be preserved in B.     */
 /*-----------------------------------------------------------------*/
 static void
-genUnpackBits (operand * result, char *rname, int ptype)
+emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
 {
-  int shCnt;
-  int rlen = 0;
-  sym_link *etype;
-  int offset = 0;
-
-  D (emitcode (";", "genUnpackBits ");
-    );
-
-  etype = getSpec (operandType (result));
-
-  /* read the first byte  */
-  switch (ptype)
+  switch (p_type)
     {
-
-    case POINTER:
     case IPOINTER:
+    case POINTER:
+      if (preserveAinB)
+        emitcode ("mov", "b,a");
       emitcode ("mov", "a,@%s", rname);
       break;
 
     case PPOINTER:
+      if (preserveAinB)
+        emitcode ("mov", "b,a");
       emitcode ("movx", "a,@%s", rname);
       break;
-
+      
     case FPOINTER:
+      if (preserveAinB)
+        emitcode ("mov", "b,a");
       emitcode ("movx", "a,@dptr");
       break;
 
     case CPOINTER:
+      if (preserveAinB)
+        emitcode ("mov", "b,a");
       emitcode ("clr", "a");
       emitcode ("movc", "a,@a+dptr");
       break;
 
     case GPOINTER:
+      if (preserveAinB)
+        {
+          emitcode ("push", "b");
+          emitcode ("push", "acc");
+        }
       emitcode ("lcall", "__gptrget");
+      if (preserveAinB)
+        emitcode ("pop", "b");
       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))
+/*-----------------------------------------------------------------*/
+/* emitPtrByteSet - emits code to set a byte from src through a    */
+/*                  pointer register (R0, R1, or DPTR).            */
+/*-----------------------------------------------------------------*/
+static void
+emitPtrByteSet (char *rname, int p_type, char *src)
+{
+  switch (p_type)
     {
+    case IPOINTER:
+    case POINTER:
+      if (*src=='@')
+        {
+          MOVA (src);
+          emitcode ("mov", "@%s,a", rname);
+        }
+      else
+        emitcode ("mov", "@%s,%s", rname, src);
+      break;
 
-      /* shift right acc */
-      AccRsh (shCnt);
+    case PPOINTER:
+      MOVA (src);
+      emitcode ("movx", "@%s,a", rname);
+      break;
+      
+    case FPOINTER:
+      MOVA (src);
+      emitcode ("movx", "@dptr,a");
+      break;
 
-      emitcode ("anl", "a,#!constbyte",
-               ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
-      aopPut (AOP (result), "a", offset);
-      return;
+    case GPOINTER:
+      MOVA (src);
+      emitcode ("lcall", "__gptrput");
+      break;
     }
+}
 
-  /* 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;
+/*-----------------------------------------------------------------*/
+/* genUnpackBits - generates code for unpacking bits               */
+/*-----------------------------------------------------------------*/
+static void
+genUnpackBits (operand * result, char *rname, int ptype)
+{
+  int offset = 0;      /* result byte offset */
+  int rsize;           /* result size */
+  int rlen = 0;                /* remaining bitfield length */
+  sym_link *etype;     /* bitfield type information */
+  int blen;            /* bitfield length */
+  int bstr;            /* bitfield starting bit within byte */
 
-       case GPOINTER:
-         emitcode ("inc", "dptr");
-         emitcode ("lcall", "__gptrget");
-         break;
-       }
+  D(emitcode (";     genUnpackBits",""));
 
-      rlen -= 8;
-      /* if we are done */
-      if (rlen < 8)
-       break;
+  etype = getSpec (operandType (result));
+  rsize = getSize (operandType (result));
+  blen = SPEC_BLEN (etype);
+  bstr = SPEC_BSTR (etype);
 
+  /* If the bitfield length is less than a byte */
+  if (blen < 8)
+    {
+      emitPtrByteGet (rname, ptype, FALSE);
+      AccRsh (bstr);
+      emitcode ("anl", "a,#!constbyte", ((unsigned char) -1) >> (8 - blen));
       aopPut (AOP (result), "a", offset++);
+      goto finish;
+    }
 
+  /* Bit field did not fit in a byte. Copy all
+     but the partial byte at the end.  */
+  for (rlen=blen;rlen>=8;rlen-=8)
+    {
+      emitPtrByteGet (rname, ptype, FALSE);
+      aopPut (AOP (result), "a", offset++);
+      if (rlen>8)
+        emitcode ("inc", "%s", rname);
     }
 
+  /* Handle the partial byte at the end */
   if (rlen)
     {
-      emitcode ("anl", "a,#!constbyte", ((unsigned char) -1) >> (rlen));
-      aopPut (AOP (result), "a", offset);
+      emitPtrByteGet (rname, ptype, FALSE);
+      emitcode ("anl", "a,#!constbyte", ((unsigned char) -1) >> (8-rlen));
+      aopPut (AOP (result), "a", offset++);
     }
 
-  return;
+finish:
+  if (offset < rsize)
+    {
+      rsize -= offset;
+      while (rsize--)
+       aopPut (AOP (result), zero, offset++);
+    }
 }
 
 
@@ -8884,21 +9649,27 @@ genDataPointerGet (operand * left,
                   iCode * ic)
 {
   char *l;
-  char buffer[256];
+  char buff[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);
+  l = aopGet (AOP (left), 0, FALSE, TRUE, NULL);
   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++);
+       if (offset)
+       {
+           SNPRINTF (buff, sizeof(buff), 
+                     "(%s + %d)", l + 1, offset);
+       }
+       else
+       {
+           SNPRINTF (buff, sizeof(buff), 
+                     "%s", l + 1);
+       }
+      aopPut (AOP (result), buff, offset++);
     }
   _endLazyDPSEvaluation ();
 
@@ -8916,11 +9687,11 @@ genNearPointerGet (operand * left,
                   iCode *pi)
 {
   asmop *aop = NULL;
-  regs *preg = NULL;
+  regs *preg;
   char *rname;
   sym_link *rtype, *retype, *letype;
   sym_link *ltype = operandType (left);
-  char buffer[80];
+  char buff[80];
 
   rtype = operandType (result);
   retype = getSpec (rtype);
@@ -8929,12 +9700,12 @@ genNearPointerGet (operand * left,
   aopOp (left, ic, FALSE, FALSE);
 
   /* if left is rematerialisable and
-     result is not bit variable type and
+     result is not bitfield 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) &&
+      !IS_BITFIELD (retype) &&
+      !IS_BITFIELD (letype) &&
       DCL_TYPE (ltype) == POINTER)
     {
       genDataPointerGet (left, result, ic);
@@ -8950,17 +9721,17 @@ genNearPointerGet (operand * left,
       preg = getFreePtr (ic, &aop, FALSE);
       emitcode ("mov", "%s,%s",
                preg->name,
-               aopGet (AOP (left), 0, FALSE, TRUE, FALSE));
+               aopGet (AOP (left), 0, FALSE, TRUE, DP2_RESULT_REG));
       rname = preg->name;
     }
   else
-    rname = aopGet (AOP (left), 0, FALSE, FALSE, FALSE);
+    rname = aopGet (AOP (left), 0, FALSE, FALSE, DP2_RESULT_REG);
 
   freeAsmop (left, NULL, ic, TRUE);
   aopOp (result, ic, FALSE, FALSE);
 
   /* if bitfield then unpack the bits */
-  if (IS_BITVAR (retype) || IS_BITVAR (letype))
+  if (IS_BITFIELD (retype) || IS_BITFIELD (letype))
     genUnpackBits (result, rname, POINTER);
   else
     {
@@ -8978,12 +9749,14 @@ genNearPointerGet (operand * left,
            }
          else
            {
-             sprintf (buffer, "@%s", rname);
-             aopPut (AOP (result), buffer, offset);
+             SNPRINTF (buff, sizeof(buff), "@%s", rname);
+             aopPut (AOP (result), buff, offset);
            }
          offset++;
          if (size || pi)
-           emitcode ("inc", "%s", rname);
+           {
+               emitcode ("inc", "%s", rname);
+           }
        }
     }
 
@@ -9030,7 +9803,7 @@ genPagedPointerGet (operand * left,
                    iCode * pi)
 {
   asmop *aop = NULL;
-  regs *preg = NULL;
+  regs *preg;
   char *rname;
   sym_link *rtype, *retype, *letype;
 
@@ -9048,17 +9821,17 @@ genPagedPointerGet (operand * left,
       preg = getFreePtr (ic, &aop, FALSE);
       emitcode ("mov", "%s,%s",
                preg->name,
-               aopGet (AOP (left), 0, FALSE, TRUE, FALSE));
+               aopGet (AOP (left), 0, FALSE, TRUE, NULL));
       rname = preg->name;
     }
   else
-    rname = aopGet (AOP (left), 0, FALSE, FALSE, FALSE);
+    rname = aopGet (AOP (left), 0, FALSE, FALSE, NULL);
 
   freeAsmop (left, NULL, ic, TRUE);
   aopOp (result, ic, FALSE, FALSE);
 
   /* if bitfield then unpack the bits */
-  if (IS_BITVAR (retype) || IS_BITVAR (letype))
+  if (IS_BITFIELD (retype) || IS_BITFIELD (letype))
     genUnpackBits (result, rname, PPOINTER);
   else
     {
@@ -9120,8 +9893,7 @@ genFarPointerGet (operand * left,
     int size, offset, dopi=1;
   sym_link *retype = getSpec (operandType (result));
   sym_link *letype = getSpec (operandType (left));
-  D (emitcode (";", "genFarPointerGet");
-    );
+  D (emitcode (";", "genFarPointerGet"););
 
   aopOp (left, ic, FALSE, FALSE);
 
@@ -9132,7 +9904,7 @@ genFarPointerGet (operand * left,
       /* if this is remateriazable */
       if (AOP_TYPE (left) == AOP_IMMD)
        {
-         emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, FALSE));
+         emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, NULL));
        }
       else
        {
@@ -9140,20 +9912,19 @@ genFarPointerGet (operand * left,
          _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));
+             emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, NULL));
+             emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, NULL));
              if (options.model == MODEL_FLAT24)
-               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, NULL));
            }
          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));
+             D (emitcode (";", "genFarPointerGet -- indirection special case."););
+             emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, NULL));
+             emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, NULL));
              if (options.model == MODEL_FLAT24)
-               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, NULL));
              emitcode ("pop", "dph");
              emitcode ("pop", "dpl");
              dopi =0;
@@ -9165,7 +9936,7 @@ genFarPointerGet (operand * left,
   aopOp (result, ic, FALSE, (AOP_INDPTRn(left) ? FALSE : TRUE));
 
   /* if bit then unpack */
-  if (IS_BITVAR (retype) || IS_BITVAR (letype)) {
+  if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
       if (AOP_INDPTRn(left)) {
          genSetDPTR(AOP(left)->aopu.dptr);
       }
@@ -9208,15 +9979,18 @@ genFarPointerGet (operand * left,
     }
   if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) {
       if (!AOP_INDPTRn(left)) {
+         _startLazyDPSEvaluation ();
          aopPut ( AOP (left), "dpl", 0);
          aopPut ( AOP (left), "dph", 1);
          if (options.model == MODEL_FLAT24)
              aopPut ( AOP (left), "dpx", 2);
+         _endLazyDPSEvaluation ();
       }
     pi->generated = 1;
-  } else if ((OP_SYMBOL(left)->ruonly || AOP_INDPTRn(left)) && 
+  } else if ((AOP_IS_STR(left) || AOP_INDPTRn(left)) && 
             AOP_SIZE(result) > 1 &&
-            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+            IS_SYMOP(left) &&
+            (OP_SYMBOL(left)->liveTo > ic->seq || ic->depth)) {
       
       size = AOP_SIZE (result) - 1;
       if (AOP_INDPTRn(left)) {
@@ -9251,27 +10025,26 @@ genCodePointerGet (operand * left,
       /* if this is remateriazable */
       if (AOP_TYPE (left) == AOP_IMMD)
        {
-         emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, FALSE));
+         emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, NULL));
        }
       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));
+             emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, NULL));
+             emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, NULL));
              if (options.model == MODEL_FLAT24)
-               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, NULL));
            }
          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));
+             D (emitcode (";", "gencodePointerGet -- indirection special case."););
+             emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, NULL));
+             emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, NULL));
              if (options.model == MODEL_FLAT24)
-               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, NULL));
              emitcode ("pop", "dph");
              emitcode ("pop", "dpl");
              dopi=0;
@@ -9283,7 +10056,7 @@ genCodePointerGet (operand * left,
   aopOp (result, ic, FALSE, (AOP_INDPTRn(left) ? FALSE : TRUE));
 
   /* if bit then unpack */
-  if (IS_BITVAR (retype)) {
+  if (IS_BITFIELD (retype)) {
       if (AOP_INDPTRn(left)) {
          genSetDPTR(AOP(left)->aopu.dptr);
       }
@@ -9327,10 +10100,14 @@ genCodePointerGet (operand * left,
     }
   if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) {
       if (!AOP_INDPTRn(left)) {
+         _startLazyDPSEvaluation ();
+         
          aopPut ( AOP (left), "dpl", 0);
          aopPut ( AOP (left), "dph", 1);
          if (options.model == MODEL_FLAT24)
              aopPut ( AOP (left), "dpx", 2);
+
+         _endLazyDPSEvaluation ();
       }
       pi->generated = 1;
   } else if ((OP_SYMBOL(left)->ruonly || AOP_INDPTRn(left)) && 
@@ -9364,7 +10141,7 @@ genGenPointerGet (operand * left,
 
   D (emitcode (";", "genGenPointerGet "); );
 
-  aopOp (left, ic, FALSE, (OP_SYMBOL(left)->ruonly ? FALSE : TRUE));
+  aopOp (left, ic, FALSE, (AOP_IS_STR(left) ? FALSE : TRUE));
 
   /* if the operand is already in dptr
      then we do nothing else we move the value to dptr */
@@ -9373,78 +10150,87 @@ genGenPointerGet (operand * left,
       /* if this is remateriazable */
       if (AOP_TYPE (left) == AOP_IMMD)
        {
-         emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, FALSE));
+         emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, NULL));
          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));
+           {
+               MOVB(aopGet(AOP (left), AOP_SIZE(left)-1, FALSE, FALSE, NULL));
+           }
+           else
+           {
+               emitcode ("mov", "b,#%d", pointerCode (retype));
+           }
        }
       else
        {                       /* we need to get it byte by byte */
-         _startLazyDPSEvaluation ();
-#if 1  // I see no point at all to this code and will likely yank it soon.
-         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 
-#endif         
-         {
-           emitcode ("mov", "dpl,%s", aopGet (AOP(left),0,FALSE,FALSE,TRUE));
-           emitcode ("mov", "dph,%s", aopGet (AOP(left),1,FALSE,FALSE,TRUE));
+           _startLazyDPSEvaluation ();
+           emitcode ("mov", "dpl,%s", aopGet (AOP(left),0,FALSE,FALSE,NULL));
+           emitcode ("mov", "dph,%s", aopGet (AOP(left),1,FALSE,FALSE,NULL));
            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));
+               emitcode ("mov", "dpx,%s", aopGet (AOP(left),2,FALSE,FALSE,NULL));
+               emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,NULL));
            } else {
-             emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
+               emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,NULL));
            }
-         }
-         _endLazyDPSEvaluation ();
+           _endLazyDPSEvaluation ();
        }
     }
-  /* so dptr know contains the address */
+
+  /* so dptr-b now contains the address */
+  _G.bInUse++;
   aopOp (result, ic, FALSE, TRUE);
+  _G.bInUse--;
 
   /* if bit then unpack */
-  if (IS_BITVAR (retype) || IS_BITVAR (letype))
+  if (IS_BITFIELD (retype) || IS_BITFIELD (letype))
+  {
     genUnpackBits (result, "dptr", GPOINTER);
+  }
   else
     {
-      size = AOP_SIZE (result);
-      offset = 0;
+       size = AOP_SIZE (result);
+       offset = 0;
 
-      while (size--)
+       while (size--)
        {
-         emitcode ("lcall", "__gptrget");
-         aopPut (AOP (result), "a", offset++);
-         if (size || (pi && AOP_TYPE (left) != AOP_IMMD))
-           emitcode ("inc", "dptr");
+           if (size)
+           {
+               // Get two bytes at a time, results in _AP & A.
+               // dptr will be incremented ONCE by __gptrgetWord.
+               //
+               // Note: any change here must be coordinated
+               // with the implementation of __gptrgetWord
+               // in device/lib/_gptrget.c
+               emitcode ("lcall", "__gptrgetWord");
+               aopPut (AOP (result), DP2_RESULT_REG, offset++);
+               aopPut (AOP (result), "a", offset++);
+               size--;
+           }
+           else
+           {
+               // Only one byte to get.
+               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) {
+    _startLazyDPSEvaluation ();
+      
     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);      
+    
+    _endLazyDPSEvaluation ();
+      
     pi->generated = 1;
   } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
             (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
@@ -9489,7 +10275,7 @@ genPointerGet (iCode * ic, iCode *pi)
   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);
+         type = operandType (left);
          p_type = DCL_TYPE (type);
   }
   /* now that we have the pointer type we assign
@@ -9506,189 +10292,148 @@ genPointerGet (iCode * ic, iCode *pi)
       genPagedPointerGet (left, result, ic, pi);
       break;
 
-    case FPOINTER:
-      genFarPointerGet (left, result, ic, pi);
-      break;
-
-    case CPOINTER:
-      genCodePointerGet (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,#!constbyte", (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 FPOINTER:
+      genFarPointerGet (left, result, ic, pi);
+      break;
 
-       case GPOINTER:
-         MOVA (l);
-         emitcode ("lcall", "__gptrput");
-         break;
-       }
-      emitcode ("inc", "%s", rname);
+    case CPOINTER:
+      genCodePointerGet (left, result, ic, pi);
+      break;
+
+    case GPOINTER:
+      genGenPointerGet (left, result, ic, pi);
+      break;
     }
 
-  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;
+/*-----------------------------------------------------------------*/
+/* genPackBits - generates code for packed bit storage             */
+/*-----------------------------------------------------------------*/
+static void
+genPackBits (sym_link * etype,
+            operand * right,
+            char *rname, int p_type)
+{
+  int offset = 0;      /* source byte offset */
+  int rlen = 0;                /* remaining bitfield length */
+  int blen;            /* bitfield length */
+  int bstr;            /* bitfield starting bit within byte */
+  int litval;          /* source literal value (if AOP_LIT) */
+  unsigned char mask;  /* bitmask within current byte */
 
-       case FPOINTER:
-         emitcode ("mov", "b,a");
-         emitcode ("movx", "a,@dptr");
-         break;
+  D(emitcode (";     genPackBits",""));
 
-       case GPOINTER:
-         emitcode ("push", "b");
-         emitcode ("push", "acc");
-         emitcode ("lcall", "__gptrget");
-         emitcode ("pop", "b");
-         break;
-       }
+  blen = SPEC_BLEN (etype);
+  bstr = SPEC_BSTR (etype);
+
+  /* If the bitfield length is less than a byte */
+  if (blen < 8)
+    {
+      mask = ((unsigned char) (0xFF << (blen + bstr)) |
+             (unsigned char) (0xFF >> (8 - bstr)));
+
+      if (AOP_TYPE (right) == AOP_LIT)
+        {
+          /* Case with a bitfield length <8 and literal source
+          */
+          litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+          litval <<= bstr;
+          litval &= (~mask) & 0xff;
+          emitPtrByteGet (rname, p_type, FALSE);
+          if ((mask|litval)!=0xff)
+            emitcode ("anl","a,#!constbyte", mask);
+          if (litval)
+            emitcode ("orl","a,#!constbyte", litval);
+        }
+      else
+        {
+          if ((blen==1) && (p_type!=GPOINTER))
+            {
+              /* Case with a bitfield length == 1 and no generic pointer
+              */
+              if (AOP_TYPE (right) == AOP_CRY)
+                emitcode ("mov", "c,%s", AOP(right)->aopu.aop_dir);
+              else
+                {
+                  MOVA (aopGet (AOP (right), 0, FALSE, FALSE, NULL));
+                  emitcode ("rrc","a");
+                }
+              emitPtrByteGet (rname, p_type, FALSE);
+              emitcode ("mov","acc.%d,c",bstr);
+            }
+          else
+            {
+              /* Case with a bitfield length < 8 and arbitrary source
+              */
+              MOVA (aopGet (AOP (right), 0, FALSE, FALSE, NULL));
+              /* shift and mask source value */
+              AccLsh (bstr);
+              emitcode ("anl", "a,#!constbyte", (~mask) & 0xff);
+
+             /* transfer A to B and get next byte */
+              emitPtrByteGet (rname, p_type, TRUE);
+
+              emitcode ("anl", "a,#!constbyte", mask);
+              emitcode ("orl", "a,b");
+              if (p_type == GPOINTER)
+                emitcode ("pop", "b");
+           }
+        }
 
-      emitcode ("anl", "a,#!constbyte", ((unsigned char) -1 << rLen));
-      emitcode ("orl", "a,b");
+      emitPtrByteSet (rname, p_type, "a");
+      return;
     }
 
-  if (p_type == GPOINTER)
-    emitcode ("pop", "b");
+  /* Bit length is greater than 7 bits. In this case, copy  */
+  /* all except the partial byte at the end                 */
+  for (rlen=blen;rlen>=8;rlen-=8)
+    {
+      emitPtrByteSet (rname, p_type, 
+                      aopGet (AOP (right), offset++, FALSE, TRUE, NULL) );
+      if (rlen>8)
+        emitcode ("inc", "%s", rname);
+    }
 
-  switch (p_type)
+  /* If there was a partial byte at the end */
+  if (rlen)
     {
+      mask = (((unsigned char) -1 << rlen) & 0xff);
+      
+      if (AOP_TYPE (right) == AOP_LIT)
+        {
+          /* Case with partial byte and literal source
+          */
+          litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+          litval >>= (blen-rlen);
+          litval &= (~mask) & 0xff;
+          emitPtrByteGet (rname, p_type, FALSE);
+          if ((mask|litval)!=0xff)
+            emitcode ("anl","a,#!constbyte", mask);
+          if (litval)
+            emitcode ("orl","a,#!constbyte", litval);
+        }
+      else
+        {
+          /* Case with partial byte and arbitrary source
+          */
+          MOVA (aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
+          emitcode ("anl", "a,#!constbyte", (~mask) & 0xff);
+
+         /* transfer A to B and get next byte */
+          emitPtrByteGet (rname, p_type, TRUE);
+
+          emitcode ("anl", "a,#!constbyte", mask);
+          emitcode ("orl", "a,b");
+          if (p_type == GPOINTER)
+            emitcode ("pop", "b");
+        }
+      emitPtrByteSet (rname, p_type, "a");
+    }
 
-    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                 */
 /*-----------------------------------------------------------------*/
@@ -9698,20 +10443,25 @@ genDataPointerSet (operand * right,
                   iCode * ic)
 {
   int size, offset = 0;
-  char *l, buffer[256];
+  char *l, buff[256];
 
   aopOp (right, ic, FALSE, FALSE);
 
-  l = aopGet (AOP (result), 0, FALSE, TRUE, FALSE);
+  l = aopGet (AOP (result), 0, FALSE, TRUE, NULL);
   size = AOP_SIZE (right);
   while (size--)
     {
       if (offset)
-       sprintf (buffer, "(%s + %d)", l + 1, offset);
+       {
+           SNPRINTF (buff, sizeof(buff), "(%s + %d)", l + 1, offset);
+       }
       else
-       sprintf (buffer, "%s", l + 1);
-      emitcode ("mov", "%s,%s", buffer,
-               aopGet (AOP (right), offset++, FALSE, FALSE, FALSE));
+       {
+           SNPRINTF (buff, sizeof(buff), "%s", l + 1);
+       }
+       
+      emitcode ("mov", "%s,%s", buff,
+               aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
     }
 
   freeAsmop (right, NULL, ic, TRUE);
@@ -9728,7 +10478,6 @@ genNearPointerSet (operand * right,
                   iCode * pi)
 {
   asmop *aop = NULL;
-  regs *preg = NULL;
   char *rname, *l;
   sym_link *retype, *letype;
   sym_link *ptype = operandType (result);
@@ -9754,21 +10503,23 @@ genNearPointerSet (operand * right,
   if (!AOP_INPREG (AOP (result)))
     {
       /* otherwise get a free pointer register */
+      regs *preg;
+       
       aop = newAsmop (0);
       preg = getFreePtr (ic, &aop, FALSE);
       emitcode ("mov", "%s,%s",
                preg->name,
-               aopGet (AOP (result), 0, FALSE, TRUE, FALSE));
+               aopGet (AOP (result), 0, FALSE, TRUE, NULL));
       rname = preg->name;
     }
   else
-    rname = aopGet (AOP (result), 0, FALSE, FALSE, FALSE);
+    rname = aopGet (AOP (result), 0, FALSE, FALSE, NULL);
 
   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);
+  if (IS_BITFIELD (retype) || IS_BITFIELD (letype))
+    genPackBits ((IS_BITFIELD (retype) ? retype : letype), right, rname, POINTER);
   else
     {
       /* we have can just get the values */
@@ -9777,7 +10528,7 @@ genNearPointerSet (operand * right,
 
       while (size--)
        {
-         l = aopGet (AOP (right), offset, FALSE, TRUE, FALSE);
+         l = aopGet (AOP (right), offset, FALSE, TRUE, NULL);
          if (*l == '@')
            {
              MOVA (l);
@@ -9835,8 +10586,7 @@ genPagedPointerSet (operand * right,
                    iCode *pi)
 {
   asmop *aop = NULL;
-  regs *preg = NULL;
-  char *rname, *l;
+  char *rname;
   sym_link *retype, *letype;
 
   retype = getSpec (operandType (right));
@@ -9849,21 +10599,23 @@ genPagedPointerSet (operand * right,
   if (!AOP_INPREG (AOP (result)))
     {
       /* otherwise get a free pointer register */
+      regs *preg;
+       
       aop = newAsmop (0);
       preg = getFreePtr (ic, &aop, FALSE);
       emitcode ("mov", "%s,%s",
                preg->name,
-               aopGet (AOP (result), 0, FALSE, TRUE, FALSE));
+               aopGet (AOP (result), 0, FALSE, TRUE, NULL));
       rname = preg->name;
     }
   else
-    rname = aopGet (AOP (result), 0, FALSE, FALSE, FALSE);
+    rname = aopGet (AOP (result), 0, FALSE, FALSE, NULL);
 
   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);
+  if (IS_BITFIELD (retype) || IS_BITFIELD (letype))
+    genPackBits ((IS_BITFIELD (retype) ? retype : letype), right, rname, PPOINTER);
   else
     {
       /* we have can just get the values */
@@ -9872,9 +10624,8 @@ genPagedPointerSet (operand * right,
 
       while (size--)
        {
-         l = aopGet (AOP (right), offset, FALSE, TRUE, TRUE);
+         MOVA (aopGet (AOP (right), offset, FALSE, TRUE, NULL));
 
-         MOVA (l);
          emitcode ("movx", "@%s,a", rname);
 
          if (size || pi)
@@ -9937,27 +10688,28 @@ genFarPointerSet (operand * right,
     {
       /* if this is remateriazable */
       if (AOP_TYPE (result) == AOP_IMMD)
-       emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE, FALSE));
+       emitcode ("mov", "dptr,%s", 
+                 aopGet (AOP (result), 0, TRUE, FALSE, NULL));
       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));
+             emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, NULL));
+             emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, NULL));
              if (options.model == MODEL_FLAT24)
-               emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, NULL));
            }
          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));
+             D (emitcode (";", "genFarPointerSet -- indirection special case."););
+               
+             emitcode ("push", "%s", aopGet (AOP (result), 0, FALSE, TRUE, NULL));
+             emitcode ("push", "%s", aopGet (AOP (result), 1, FALSE, TRUE, NULL));
              if (options.model == MODEL_FLAT24)
-               emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, NULL));
              emitcode ("pop", "dph");
              emitcode ("pop", "dpl");
              dopi=0;
@@ -9969,11 +10721,11 @@ genFarPointerSet (operand * right,
   aopOp (right, ic, FALSE, (AOP_INDPTRn(result) ? FALSE : TRUE));
 
   /* if bit then unpack */
-  if (IS_BITVAR (retype) || IS_BITVAR (letype)) {
+  if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
       if (AOP_INDPTRn(result)) {
          genSetDPTR(AOP(result)->aopu.dptr);
       }
-      genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", FPOINTER);
+      genPackBits ((IS_BITFIELD (retype) ? retype : letype), right, "dptr", FPOINTER);
       if (AOP_INDPTRn(result)) {
          genSetDPTR(0);
       }
@@ -9982,8 +10734,7 @@ genFarPointerSet (operand * right,
       offset = 0;
       if (AOP_INDPTRn(result) && AOP_USESDPTR(right)) {
          while (size--) {
-             char *l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
-             MOVA (l);
+             MOVA (aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
              
              genSetDPTR(AOP(result)->aopu.dptr);
              emitcode ("movx", "@dptr,a");
@@ -9994,8 +10745,7 @@ genFarPointerSet (operand * right,
       } else {
          _startLazyDPSEvaluation ();
          while (size--) {
-             char *l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
-             MOVA (l);
+             MOVA (aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
              
              if (AOP_INDPTRn(result)) {
                  genSetDPTR(AOP(result)->aopu.dptr);
@@ -10014,10 +10764,14 @@ genFarPointerSet (operand * right,
   
   if (dopi && pi && AOP_TYPE (result) != AOP_IMMD) {
       if (!AOP_INDPTRn(result)) {
+         _startLazyDPSEvaluation ();
+         
          aopPut (AOP(result),"dpl",0);
          aopPut (AOP(result),"dph",1);
          if (options.model == MODEL_FLAT24)
              aopPut (AOP(result),"dpx",2);
+
+         _endLazyDPSEvaluation ();
       }
       pi->generated=1;
   } else if ((OP_SYMBOL(result)->ruonly || AOP_INDPTRn(result)) && 
@@ -10048,7 +10802,7 @@ genGenPointerSet (operand * right,
   sym_link *retype = getSpec (operandType (right));
   sym_link *letype = getSpec (operandType (result));
 
-  aopOp (result, ic, FALSE, OP_SYMBOL(result)->ruonly ? FALSE : TRUE);
+  aopOp (result, ic, FALSE, AOP_IS_STR(result) ? FALSE : TRUE);
 
   /* if the operand is already in dptr
      then we do nothing else we move the value to dptr */
@@ -10058,53 +10812,87 @@ genGenPointerSet (operand * right,
       /* if this is remateriazable */
       if (AOP_TYPE (result) == AOP_IMMD)
        {
-         emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE, FALSE));
+         emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE, NULL));
          if (AOP(result)->aopu.aop_immd.from_cast_remat) 
-                 emitcode ("mov", "b,%s",aopGet(AOP (result), AOP_SIZE(result)-1, FALSE, FALSE, FALSE));
+         {
+             MOVB(aopGet(AOP (result), AOP_SIZE(result)-1, FALSE, FALSE, NULL));
+         }
          else
-                 emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE, FALSE));
+         {
+             emitcode ("mov", 
+                       "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE, NULL));
+         }
        }
       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));
+         emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, NULL));
+         emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, NULL));
          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));
+           emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, NULL));
+           emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE, NULL));
          } else {
-           emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+           emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE, NULL));
          }
        }
       _endLazyDPSEvaluation ();
     }
-  /* so dptr know contains the address */
+  /* so dptr + b now contains the address */
+  _G.bInUse++;
   aopOp (right, ic, FALSE, TRUE);
+  _G.bInUse--;
+    
 
   /* if bit then unpack */
-  if (IS_BITVAR (retype) || IS_BITVAR (letype))
-    genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", GPOINTER);
+  if (IS_BITFIELD (retype) || IS_BITFIELD (letype))
+    {
+       genPackBits ((IS_BITFIELD (retype) ? retype : letype), right, "dptr", GPOINTER);
+    }
   else
     {
-      size = AOP_SIZE (right);
-      offset = 0;
+       size = AOP_SIZE (right);
+       offset = 0;
 
-      _startLazyDPSEvaluation ();
-      while (size--)
+       _startLazyDPSEvaluation ();
+       while (size--)
        {
-         char *l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
-         MOVA (l);
-
-         genSetDPTR (0);
-         _flushLazyDPS ();
+           if (size)
+           {
+               // Set two bytes at a time, passed in _AP & A.
+               // dptr will be incremented ONCE by __gptrputWord.
+               //
+               // Note: any change here must be coordinated
+               // with the implementation of __gptrputWord
+               // in device/lib/_gptrput.c
+               emitcode("mov", "_ap, %s", 
+                        aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
+               MOVA (aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
+               
+               genSetDPTR (0);
+               _flushLazyDPS ();
+               emitcode ("lcall", "__gptrputWord");
+               size--;
+           }
+           else
+           {
+               // Only one byte to put.
+               MOVA (aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
 
-         emitcode ("lcall", "__gptrput");
-         if (size || (pi && AOP_TYPE (result) != AOP_IMMD))
-           emitcode ("inc", "dptr");
+               genSetDPTR (0);
+               _flushLazyDPS ();               
+               emitcode ("lcall", "__gptrput");
+           }
+           
+           if (size || (pi && AOP_TYPE (result) != AOP_IMMD))
+           {
+               emitcode ("inc", "dptr");
+           }
        }
-      _endLazyDPSEvaluation ();
+       _endLazyDPSEvaluation ();
     }
 
   if (pi && AOP_TYPE (result) != AOP_IMMD) {
+      _startLazyDPSEvaluation ();
+      
       aopPut (AOP(result),"dpl",0);
       aopPut (AOP(result),"dph",1);
       if (options.model == MODEL_FLAT24) {
@@ -10113,6 +10901,8 @@ genGenPointerSet (operand * right,
       } else {
          aopPut (AOP(result),"b",2);
       }
+      _endLazyDPSEvaluation ();
+      
       pi->generated=1;
   } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 &&
             (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) {
@@ -10134,8 +10924,7 @@ genPointerSet (iCode * ic, iCode *pi)
   sym_link *type, *etype;
   int p_type;
 
-  D (emitcode (";", "genPointerSet ");
-    );
+  D (emitcode (";", "genPointerSet "););
 
   right = IC_RIGHT (ic);
   result = IC_RESULT (ic);
@@ -10158,7 +10947,7 @@ genPointerSet (iCode * ic, iCode *pi)
   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);
+         type = operandType (result);
          p_type = DCL_TYPE (type);
   }
 
@@ -10206,9 +10995,14 @@ genIfx (iCode * ic, iCode * popIc)
 
   /* get the value into acc */
   if (AOP_TYPE (cond) != AOP_CRY)
-    toBoolean (cond);
+    {
+       toBoolean (cond);
+    }
   else
-    isbit = 1;
+    {
+       isbit = 1;
+    }
+    
   /* the result is now in the accumulator */
   freeAsmop (cond, NULL, ic, TRUE);
 
@@ -10219,11 +11013,17 @@ genIfx (iCode * ic, iCode * popIc)
   /* if the condition is  a bit variable */
   if (isbit && IS_ITEMP (cond) &&
       SPIL_LOC (cond))
-    genIfxJump (ic, SPIL_LOC (cond)->rname);
+    {
+       genIfxJump (ic, SPIL_LOC (cond)->rname);
+    }
   else if (isbit && !IS_ITEMP (cond))
-    genIfxJump (ic, OP_SYMBOL (cond)->rname);
+    {
+       genIfxJump (ic, OP_SYMBOL (cond)->rname);
+    }
   else
-    genIfxJump (ic, "a");
+    {
+       genIfxJump (ic, "a");
+    }
 
   ic->generated = 1;
 }
@@ -10250,7 +11050,10 @@ genAddrOf (iCode * ic)
       /* if 10 bit stack */
       if (options.stack10bit) {
          char buff[10];
-         tsprintf(buff,"#!constbyte",(options.stack_loc >> 16) & 0xff);
+         int  offset;
+         
+         tsprintf(buff, sizeof(buff), 
+                  "#!constbyte",(options.stack_loc >> 16) & 0xff);
          /* if it has an offset then we need to compute it */
 /*       emitcode ("subb", "a,#!constbyte", */
 /*                 -((sym->stack < 0) ? */
@@ -10267,9 +11070,13 @@ genAddrOf (iCode * ic)
                                             ((char) sym->stack )) & 0xff);
              emitcode ("mov", "b,a");
              emitcode ("mov", "a,_bpx+1");
-             emitcode ("addc","a,#!constbyte", (((sym->stack < 0) ? 
-                                             ((short) (sym->stack - _G.nRegsSaved)) :
-                                             ((short) sym->stack )) >> 8) & 0xff);
+             
+             offset = (((sym->stack < 0) ? 
+                        ((short) (sym->stack - _G.nRegsSaved)) :
+                        ((short) sym->stack )) >> 8) & 0xff;
+         
+             emitcode ("addc","a,#!constbyte", offset);
+
              aopPut (AOP (IC_RESULT (ic)), "b", 0);
              aopPut (AOP (IC_RESULT (ic)), "a", 1);
              aopPut (AOP (IC_RESULT (ic)), buff, 2);
@@ -10316,21 +11123,25 @@ genAddrOf (iCode * ic)
       if (offset) {
          switch (offset) {
          case 1:
-             tsprintf(s,"!his",sym->rname);
+             tsprintf(s, sizeof(s), "#!his",sym->rname);
              break;
          case 2:
-             tsprintf(s,"!hihis",sym->rname);
+             tsprintf(s, sizeof(s), "#!hihis",sym->rname);
              break;
          case 3:
-             tsprintf(s,"!hihihis",sym->rname);
+             tsprintf(s, sizeof(s), "#!hihihis",sym->rname);
              break;
          default: /* should not need this (just in case) */
-             sprintf (s, "#(%s >> %d)",
+             SNPRINTF (s, sizeof(s), "#(%s >> %d)",
                       sym->rname,
                       offset * 8);
          }
-      } else
-         sprintf (s, "#%s", sym->rname);
+      } 
+      else
+      {
+         SNPRINTF (s, sizeof(s), "#%s", sym->rname);
+      }
+       
       aopPut (AOP (IC_RESULT (ic)), s, offset++);
     }
 
@@ -10339,6 +11150,7 @@ release:
 
 }
 
+#if 0 // obsolete, and buggy for != xdata
 /*-----------------------------------------------------------------*/
 /* genArrayInit - generates code for address of                       */
 /*-----------------------------------------------------------------*/
@@ -10360,7 +11172,7 @@ genArrayInit (iCode * ic)
     {
        // Load immediate value into DPTR.
        emitcode("mov", "dptr, %s",
-            aopGet(AOP(IC_LEFT(ic)), 0, TRUE, FALSE, TRUE));
+            aopGet(AOP(IC_LEFT(ic)), 0, TRUE, FALSE, NULL));
     }
     else if (AOP_TYPE(IC_LEFT(ic)) != AOP_DPTR)
     {
@@ -10370,10 +11182,10 @@ genArrayInit (iCode * ic)
       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));
+      emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, NULL));
+      emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, NULL));
       if (options.model == MODEL_FLAT24)
-       emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+       emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, NULL));
 #endif
     }
     
@@ -10447,6 +11259,7 @@ genArrayInit (iCode * ic)
     
     freeAsmop (IC_LEFT(ic), NULL, ic, TRUE);
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genFarFarAssign - assignment when both are in far space         */
@@ -10462,7 +11275,7 @@ genFarFarAssign (operand * result, operand * right, iCode * ic)
   {
       /* quick & easy case. */
       D(emitcode(";","genFarFarAssign (1 byte case)"););      
-      MOVA(aopGet(AOP(right), 0, FALSE, FALSE, TRUE));
+      MOVA(aopGet(AOP(right), 0, FALSE, FALSE, NULL));
       freeAsmop (right, NULL, ic, FALSE);
       /* now assign DPTR to result */
       _G.accInUse++;
@@ -10539,7 +11352,7 @@ no time to test now, so later well put in...kpb
       while (size--)
        {
          aopPut (AOP (result),
-                 aopGet (AOP (right), offset, FALSE, FALSE, FALSE), offset);
+                 aopGet (AOP (right), offset, FALSE, FALSE, NULL), offset);
          offset++;
        }
       _endLazyDPSEvaluation ();
@@ -10634,7 +11447,7 @@ genAssign (iCode * ic)
       while (size && ((unsigned int) (lit >> (offset * 8)) != 0))
        {
          aopPut (AOP (result),
-                 aopGet (AOP (right), offset, FALSE, FALSE, TRUE),
+                 aopGet (AOP (right), offset, FALSE, FALSE, NULL),
                  offset);
          offset++;
          size--;
@@ -10656,7 +11469,7 @@ genAssign (iCode * ic)
       while (size--)
        {
          aopPut (AOP (result),
-                 aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+                 aopGet (AOP (right), offset, FALSE, FALSE, NULL),
                  offset);
          offset++;
        }
@@ -10682,7 +11495,7 @@ genJumpTab (iCode * ic)
 
   aopOp (IC_JTCOND (ic), ic, FALSE, FALSE);
   /* get the condition into accumulator */
-  l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE, TRUE);
+  l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE, NULL);
   MOVA (l);
   /* multiply by four! */
   emitcode ("add", "a,acc");
@@ -10712,19 +11525,18 @@ genCast (iCode * ic)
   operand *right = IC_RIGHT (ic);
   int size, offset;
 
-  D (emitcode (";", "genCast ");
-    );
+  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);
+  aopOp (right, ic, FALSE, AOP_IS_STR (result));
+  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 (IS_BITVAR (OP_SYMBOL (result)->type)
+      && !IS_BITFIELD (OP_SYMBOL (result)->type) )
     {
       /* if the right size is a literal then
          we know what the value is */
@@ -10767,7 +11579,7 @@ genCast (iCode * ic)
       while (size--)
        {
          aopPut (AOP (result),
-                 aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+                 aopGet (AOP (right), offset, FALSE, FALSE, NULL),
                  offset);
          offset++;
        }
@@ -10838,7 +11650,7 @@ genCast (iCode * ic)
          while (size--)
            {
              aopPut (AOP (result),
-                     aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+                     aopGet (AOP (right), offset, FALSE, FALSE, NULL),
                      offset);
              offset++;
            }
@@ -10855,7 +11667,7 @@ genCast (iCode * ic)
                    exit(1);
                }
            
-               sprintf(gpValStr, "#0x%d", gpVal);
+               SNPRINTF(gpValStr, sizeof(gpValStr), "#0x%d", gpVal);
                aopPut (AOP (result), gpValStr, GPTRSIZE - 1);
            }
          goto release;
@@ -10868,7 +11680,7 @@ genCast (iCode * ic)
       while (size--)
        {
          aopPut (AOP (result),
-                 aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+                 aopGet (AOP (right), offset, FALSE, FALSE, NULL),
                  offset);
          offset++;
        }
@@ -10885,7 +11697,7 @@ genCast (iCode * ic)
   while (size--)
     {
       aopPut (AOP (result),
-             aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
+             aopGet (AOP (right), offset, FALSE, FALSE, NULL),
              offset);
       offset++;
     }
@@ -10897,7 +11709,7 @@ genCast (iCode * ic)
   /* 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)
+  if (!IS_SPEC (rtype) || SPEC_USIGN (rtype) || AOP_TYPE (right) == AOP_CRY)
     {
       while (size--)
        {
@@ -10907,9 +11719,8 @@ genCast (iCode * ic)
   else
     {
       /* we need to extend the sign :{ */
-      char *l = aopGet (AOP (right), AOP_SIZE (right) - 1,
-                       FALSE, FALSE, TRUE);
-      MOVA (l);
+      MOVA (aopGet (AOP (right), AOP_SIZE (right) - 1,
+                       FALSE, FALSE, NULL));
       emitcode ("rlc", "a");
       emitcode ("subb", "a,acc");
       while (size--)
@@ -10967,7 +11778,7 @@ genDjnz (iCode * ic, iCode * ifx)
        * the accumulator, we must explicitly write
        * it back after the decrement.
        */
-      char *rByte = aopGet(AOP(IC_RESULT(ic)), 0, FALSE, FALSE, TRUE);
+      char *rByte = aopGet(AOP(IC_RESULT(ic)), 0, FALSE, FALSE, NULL);
       
       if (strcmp(rByte, "a"))
       {
@@ -10987,13 +11798,13 @@ genDjnz (iCode * ic, iCode * ifx)
   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));
+               aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, NULL));
+      emitcode ("mov", "a,%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, NULL));
       emitcode ("jnz", "!tlabel", lbl->key + 100);
     }
   else
     {
-      emitcode ("djnz", "%s,!tlabel", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, TRUE, FALSE),
+      emitcode ("djnz", "%s,!tlabel", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, TRUE, NULL),
                lbl->key + 100);
     }
   emitcode ("sjmp", "!tlabel", lbl1->key + 100);
@@ -11012,53 +11823,55 @@ genDjnz (iCode * ic, iCode * ifx)
 static void
 genReceive (iCode * ic)
 {
-
     int size = getSize (operandType (IC_RESULT (ic)));
     int offset = 0;
     int rb1off ;
     
-    D (emitcode (";", "genReceive ");
-       );
+    D (emitcode (";", "genReceive "););
 
-  if (ic->argreg == 1) { /* first parameter */
-      if (isOperandInFarSpace (IC_RESULT (ic)) &&
-         (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
-          IS_TRUE_SYMOP (IC_RESULT (ic))))
-         {
-             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));
-         }
-  } else { /* second receive onwards */
-      /* this gets a little tricky since unused recevies will be
+    if (ic->argreg == 1) 
+    {
+       /* first parameter */
+       if (AOP_IS_STR(IC_RESULT(ic)))
+       {
+           /* Nothing to do: it's already in the proper place. */
+           return;
+       }
+       else
+       {
+           bool useDp2;
+           
+           useDp2 = isOperandInFarSpace (IC_RESULT (ic)) &&
+               (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
+                IS_TRUE_SYMOP (IC_RESULT (ic)));
+           
+           _G.accInUse++;
+           aopOp (IC_RESULT (ic), ic, FALSE, useDp2);
+           _G.accInUse--; 
+           
+           /* Sanity checking... */
+           if (AOP_USESDPTR(IC_RESULT(ic)))
+           {
+               werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                       "genReceive got unexpected DPTR.");
+           }
+           assignResultValue (IC_RESULT (ic));
+       }
+    } 
+    else 
+    { 
+       /* second receive onwards */
+       /* this gets a little tricky since unused recevies will be
         eliminated, we have saved the reg in the type field . and
         we use that to figure out which register to use */
-      aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
-      rb1off = ic->argreg;
-      while (size--) {
-         aopPut (AOP (IC_RESULT (ic)), rb1regs[rb1off++ -5], offset++);
-      }
-      
-  }
-  freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+       aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+       rb1off = ic->argreg;
+       while (size--) 
+       {
+           aopPut (AOP (IC_RESULT (ic)), rb1regs[rb1off++ -5], offset++);
+       }
+    }
+    freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -11091,10 +11904,10 @@ static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc)
     aopOp (from, ic->next, FALSE, FALSE);
 
     /* get from into DPTR1 */
-    emitcode ("mov", "dpl1,%s", aopGet (AOP (from), 0, FALSE, FALSE, TRUE));
-    emitcode ("mov", "dph1,%s", aopGet (AOP (from), 1, FALSE, FALSE, TRUE));
+    emitcode ("mov", "dpl1,%s", aopGet (AOP (from), 0, FALSE, FALSE, NULL));
+    emitcode ("mov", "dph1,%s", aopGet (AOP (from), 1, FALSE, FALSE, NULL));
     if (options.model == MODEL_FLAT24) {
-       emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, TRUE));
+       emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, NULL));
     }
 
     freeAsmop (from, NULL, ic, FALSE);
@@ -11105,22 +11918,22 @@ static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc)
     if (AOP_TYPE (to) != AOP_STR) {
        /* if already in DPTR then we need to push */
        if (AOP_TYPE(to) == AOP_DPTR) {
-           emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, TRUE));
-           emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, TRUE));
+           emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, NULL));
+           emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, NULL));
            if (options.model == MODEL_FLAT24)
-               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, NULL));
            emitcode ("pop", "dph");
            emitcode ("pop", "dpl");        
        } else {
            _startLazyDPSEvaluation ();
            /* if this is remateriazable */
            if (AOP_TYPE (to) == AOP_IMMD) {
-               emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, FALSE));
+               emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, NULL));
            } else {                    /* we need to get it byte by byte */
-               emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, TRUE));
-               emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, NULL));
+               emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, NULL));
                if (options.model == MODEL_FLAT24) {
-                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, NULL));
                }
            }
            _endLazyDPSEvaluation ();
@@ -11134,7 +11947,7 @@ static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc)
     /* now for the actual copy */
     if (AOP_TYPE(count) == AOP_LIT && 
        (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
-       emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE));
+       emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,NULL));
        if (fromc) {
            emitcode ("lcall","__bi_memcpyc2x_s");
        } else {
@@ -11145,8 +11958,8 @@ static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc)
        symbol *lbl1 = newiTempLabel(NULL);
        
        emitcode (";"," Auto increment but no djnz");
-       emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
-       emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
+       emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, NULL));
+       emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, NULL));
        freeAsmop (count, NULL, ic, FALSE);
        emitcode ("mov", "dps,#!constbyte",0x21);       /* Select DPTR2 & auto-toggle. */
        emitcode ("","!tlabeldef",lbl->key+100);
@@ -11206,10 +12019,10 @@ static void genMemcmpX2X( iCode *ic, int nparms, operand **parms, int fromc)
     aopOp (from, ic->next, FALSE, FALSE);
 
     /* get from into DPTR1 */
-    emitcode ("mov", "dpl1,%s", aopGet (AOP (from), 0, FALSE, FALSE, TRUE));
-    emitcode ("mov", "dph1,%s", aopGet (AOP (from), 1, FALSE, FALSE, TRUE));
+    emitcode ("mov", "dpl1,%s", aopGet (AOP (from), 0, FALSE, FALSE, NULL));
+    emitcode ("mov", "dph1,%s", aopGet (AOP (from), 1, FALSE, FALSE, NULL));
     if (options.model == MODEL_FLAT24) {
-       emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, TRUE));
+       emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, NULL));
     }
 
     freeAsmop (from, NULL, ic, FALSE);
@@ -11220,22 +12033,22 @@ static void genMemcmpX2X( iCode *ic, int nparms, operand **parms, int fromc)
     if (AOP_TYPE (to) != AOP_STR) {
        /* if already in DPTR then we need to push */
        if (AOP_TYPE(to) == AOP_DPTR) {
-           emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, TRUE));
-           emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, TRUE));
+           emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, NULL));
+           emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, NULL));
            if (options.model == MODEL_FLAT24)
-               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, NULL));
            emitcode ("pop", "dph");
            emitcode ("pop", "dpl");        
        } else {
            _startLazyDPSEvaluation ();
            /* if this is remateriazable */
            if (AOP_TYPE (to) == AOP_IMMD) {
-               emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, FALSE));
+               emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, NULL));
            } else {                    /* we need to get it byte by byte */
-               emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, TRUE));
-               emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, NULL));
+               emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, NULL));
                if (options.model == MODEL_FLAT24) {
-                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, NULL));
                }
            }
            _endLazyDPSEvaluation ();
@@ -11250,7 +12063,7 @@ static void genMemcmpX2X( iCode *ic, int nparms, operand **parms, int fromc)
     /* now for the actual compare */
     if (AOP_TYPE(count) == AOP_LIT && 
        (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
-       emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE));
+       emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,NULL));
        if (fromc)
            emitcode("lcall","__bi_memcmpc2x_s");
        else
@@ -11264,8 +12077,8 @@ static void genMemcmpX2X( iCode *ic, int nparms, operand **parms, int fromc)
 
        emitcode("push","ar0");         
        emitcode (";"," Auto increment but no djnz");
-       emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
-       emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
+       emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, NULL));
+       emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, NULL));
        freeAsmop (count, NULL, ic, FALSE);
        emitcode ("mov", "dps,#!constbyte",0x21);       /* Select DPTR2 & auto-toggle. */
        emitcode ("","!tlabeldef",lbl->key+100);
@@ -11337,10 +12150,10 @@ static void genInp( iCode *ic, int nparms, operand **parms)
     aopOp (from, ic->next, FALSE, FALSE);
 
     /* get from into DPTR1 */
-    emitcode ("mov", "dpl1,%s", aopGet (AOP (from), 0, FALSE, FALSE, TRUE));
-    emitcode ("mov", "dph1,%s", aopGet (AOP (from), 1, FALSE, FALSE, TRUE));
+    emitcode ("mov", "dpl1,%s", aopGet (AOP (from), 0, FALSE, FALSE, NULL));
+    emitcode ("mov", "dph1,%s", aopGet (AOP (from), 1, FALSE, FALSE, NULL));
     if (options.model == MODEL_FLAT24) {
-       emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, TRUE));
+       emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, NULL));
     }
 
     freeAsmop (from, NULL, ic, FALSE);
@@ -11351,22 +12164,22 @@ static void genInp( iCode *ic, int nparms, operand **parms)
     if (AOP_TYPE (to) != AOP_STR) {
        /* if already in DPTR then we need to push */
        if (AOP_TYPE(to) == AOP_DPTR) {
-           emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, TRUE));
-           emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, TRUE));
+           emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, NULL));
+           emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, NULL));
            if (options.model == MODEL_FLAT24)
-               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, NULL));
            emitcode ("pop", "dph");
            emitcode ("pop", "dpl");        
        } else {
            _startLazyDPSEvaluation ();
            /* if this is remateriazable */
            if (AOP_TYPE (to) == AOP_IMMD) {
-               emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, FALSE));
+               emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, NULL));
            } else {                    /* we need to get it byte by byte */
-               emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, TRUE));
-               emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, NULL));
+               emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, NULL));
                if (options.model == MODEL_FLAT24) {
-                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, NULL));
                }
            }
            _endLazyDPSEvaluation ();
@@ -11383,7 +12196,7 @@ static void genInp( iCode *ic, int nparms, operand **parms)
        (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
        emitcode (";","OH  JOY auto increment with djnz (very fast)");
        emitcode ("mov", "dps,#!constbyte",0x1);        /* Select DPTR2 */
-       emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE));
+       emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,NULL));
        freeAsmop (count, NULL, ic, FALSE);
        emitcode ("","!tlabeldef",lbl->key+100);
        emitcode ("movx", "a,@dptr");   /* read data from port */
@@ -11396,8 +12209,8 @@ static void genInp( iCode *ic, int nparms, operand **parms)
        symbol *lbl1 = newiTempLabel(NULL);
        
        emitcode (";"," Auto increment but no djnz");
-       emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
-       emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
+       emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, NULL));
+       emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, NULL));
        freeAsmop (count, NULL, ic, FALSE);
        emitcode ("mov", "dps,#!constbyte",0x1);        /* Select DPTR2 */
        emitcode ("","!tlabeldef",lbl->key+100);
@@ -11458,10 +12271,10 @@ static void genOutp( iCode *ic, int nparms, operand **parms)
     aopOp (from, ic->next, FALSE, FALSE);
 
     /* get from into DPTR1 */
-    emitcode ("mov", "dpl1,%s", aopGet (AOP (from), 0, FALSE, FALSE, TRUE));
-    emitcode ("mov", "dph1,%s", aopGet (AOP (from), 1, FALSE, FALSE, TRUE));
+    emitcode ("mov", "dpl1,%s", aopGet (AOP (from), 0, FALSE, FALSE, NULL));
+    emitcode ("mov", "dph1,%s", aopGet (AOP (from), 1, FALSE, FALSE, NULL));
     if (options.model == MODEL_FLAT24) {
-       emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, TRUE));
+       emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, NULL));
     }
 
     freeAsmop (from, NULL, ic, FALSE);
@@ -11472,22 +12285,22 @@ static void genOutp( iCode *ic, int nparms, operand **parms)
     if (AOP_TYPE (to) != AOP_STR) {
        /* if already in DPTR then we need to push */
        if (AOP_TYPE(to) == AOP_DPTR) {
-           emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, TRUE));
-           emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, TRUE));
+           emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, NULL));
+           emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, NULL));
            if (options.model == MODEL_FLAT24)
-               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, NULL));
            emitcode ("pop", "dph");
            emitcode ("pop", "dpl");        
        } else {
            _startLazyDPSEvaluation ();
            /* if this is remateriazable */
            if (AOP_TYPE (to) == AOP_IMMD) {
-               emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, FALSE));
+               emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, NULL));
            } else {                    /* we need to get it byte by byte */
-               emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, TRUE));
-               emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, NULL));
+               emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, NULL));
                if (options.model == MODEL_FLAT24) {
-                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, NULL));
                }
            }
            _endLazyDPSEvaluation ();
@@ -11504,7 +12317,7 @@ static void genOutp( iCode *ic, int nparms, operand **parms)
        (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
        emitcode (";","OH  JOY auto increment with djnz (very fast)");
        emitcode ("mov", "dps,#!constbyte",0x0);        /* Select DPTR */
-       emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE));
+       emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,NULL));
        emitcode ("","!tlabeldef",lbl->key+100);
        emitcode ("movx", "a,@dptr");   /* read data from port */
        emitcode ("inc","dps");         /* switch to DPTR2 */
@@ -11517,8 +12330,8 @@ static void genOutp( iCode *ic, int nparms, operand **parms)
        symbol *lbl1 = newiTempLabel(NULL);
        
        emitcode (";"," Auto increment but no djnz");
-       emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
-       emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
+       emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, NULL));
+       emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, NULL));
        freeAsmop (count, NULL, ic, FALSE);
        emitcode ("mov", "dps,#!constbyte",0x0);        /* Select DPTR */
        emitcode ("","!tlabeldef",lbl->key+100);
@@ -11560,9 +12373,9 @@ static void genSwapW(iCode *ic, int nparms, operand **parms)
     assert(getSize(operandType(src))==2);
 
     aopOp (src, ic, FALSE, FALSE);
-    emitcode ("mov","a,%s",aopGet(AOP(src),0,FALSE,FALSE,TRUE));
+    emitcode ("mov","a,%s",aopGet(AOP(src),0,FALSE,FALSE,NULL));
     _G.accInUse++;
-    emitcode ("mov","b,%s",aopGet(AOP(src),1,FALSE,FALSE,FALSE));
+    MOVB(aopGet(AOP(src),1,FALSE,FALSE,"b"));
     _G.accInUse--;
     freeAsmop (src, NULL, ic, FALSE);
     
@@ -11581,7 +12394,7 @@ static void genMemsetX(iCode *ic, int nparms, operand **parms)
     symbol *lbl;
     char *l;
     int i;
-    bitVect *rsave = NULL;
+    bitVect *rsave;
 
     /* we know it has to be 3 parameters */
     assert (nparms == 3);
@@ -11607,22 +12420,22 @@ static void genMemsetX(iCode *ic, int nparms, operand **parms)
     if (AOP_TYPE (to) != AOP_STR) {
        /* if already in DPTR then we need to push */
        if (AOP_TYPE(to) == AOP_DPTR) {
-           emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, TRUE));
-           emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, TRUE));
+           emitcode ("push", "%s", aopGet (AOP (to), 0, FALSE, TRUE, NULL));
+           emitcode ("push", "%s", aopGet (AOP (to), 1, FALSE, TRUE, NULL));
            if (options.model == MODEL_FLAT24)
-               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, NULL));
            emitcode ("pop", "dph");
            emitcode ("pop", "dpl");        
        } else {
            _startLazyDPSEvaluation ();
            /* if this is remateriazable */
            if (AOP_TYPE (to) == AOP_IMMD) {
-               emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, FALSE));
+               emitcode ("mov", "dptr,%s", aopGet (AOP (to), 0, TRUE, FALSE, NULL));
            } else {                    /* we need to get it byte by byte */
-               emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, TRUE));
-               emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, TRUE));
+               emitcode ("mov", "dpl,%s", aopGet (AOP (to), 0, FALSE, FALSE, NULL));
+               emitcode ("mov", "dph,%s", aopGet (AOP (to), 1, FALSE, FALSE, NULL));
                if (options.model == MODEL_FLAT24) {
-                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, NULL));
                }
            }
            _endLazyDPSEvaluation ();
@@ -11636,8 +12449,8 @@ static void genMemsetX(iCode *ic, int nparms, operand **parms)
     /* now for the actual copy */
     if (AOP_TYPE(count) == AOP_LIT && 
        (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
-       l = aopGet(AOP (val), 0, FALSE, FALSE, TRUE);
-       emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE));
+       l = aopGet(AOP (val), 0, FALSE, FALSE, NULL);
+       emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,NULL));
        MOVA(l);
        emitcode ("","!tlabeldef",lbl->key+100);
        emitcode ("movx", "@dptr,a");
@@ -11646,11 +12459,10 @@ static void genMemsetX(iCode *ic, int nparms, operand **parms)
     } else {
        symbol *lbl1 = newiTempLabel(NULL);
        
-       emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
-       emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
+       emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, NULL));
+       emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, NULL));
        emitcode ("","!tlabeldef",lbl->key+100);
-       l = aopGet(AOP (val), 0, FALSE, FALSE, TRUE);
-       MOVA(l);
+       MOVA (aopGet(AOP (val), 0, FALSE, FALSE, NULL));
        emitcode ("movx", "@dptr,a");
        emitcode ("inc", "dptr");
        emitcode ("mov","a,b");
@@ -11685,7 +12497,7 @@ static void genNatLibLoadPrimitive(iCode *ic, int nparms, operand **parms,int si
     
        pnum = parms[0]; 
        aopOp (pnum, ic, FALSE, FALSE);
-       emitcode ("mov","a,%s",aopGet(AOP(pnum),0,FALSE,FALSE,FALSE));
+       emitcode ("mov","a,%s",aopGet(AOP(pnum),0,FALSE,FALSE,DP2_RESULT_REG));
        freeAsmop (pnum, NULL, ic, FALSE);
        emitcode ("lcall","NatLib_LoadPrimitive");
        aopOp (result=IC_RESULT(ic), ic, FALSE, FALSE);
@@ -11695,7 +12507,8 @@ static void genNatLibLoadPrimitive(iCode *ic, int nparms, operand **parms,int si
                        emitcode ("push","a%s",javaRet[i]);
                }
                for (i=0; i < size ; i++ ) {
-                       emitcode ("pop","a%s",aopGet(AOP(result),i,FALSE,FALSE,FALSE));
+                       emitcode ("pop","a%s",
+                                 aopGet(AOP(result),i,FALSE,FALSE,DP2_RESULT_REG));
                }
        } else {
                for (i = 0 ; i < size ; i++ ) {
@@ -11723,7 +12536,7 @@ static void genNatLibLoadPointer(iCode *ic, int nparms, operand **parms)
     
        pnum = parms[0]; 
        aopOp (pnum, ic, FALSE, FALSE);
-       emitcode ("mov","a,%s",aopGet(AOP(pnum),0,FALSE,FALSE,FALSE));
+       emitcode ("mov","a,%s",aopGet(AOP(pnum),0,FALSE,FALSE,DP2_RESULT_REG));
        freeAsmop (pnum, NULL, ic, FALSE);
        emitcode ("lcall","NatLib_LoadPointer");
        aopOp (result=IC_RESULT(ic), ic, FALSE, FALSE);
@@ -11756,12 +12569,13 @@ static void genNatLibInstallStateBlock(iCode *ic, int nparms,
        aopOp (psb, ic, FALSE, FALSE);
        if (AOP_TYPE (psb) == AOP_IMMD) {
                emitcode ("mov","dps,#1");
-               emitcode ("mov", "dptr,%s", aopGet (AOP (psb), 0, TRUE, FALSE, FALSE));
+               emitcode ("mov", "dptr,%s",
+                         aopGet (AOP (psb), 0, TRUE, FALSE, DP2_RESULT_REG));
                emitcode ("mov","dps,#0");
        } else {
-               emitcode ("mov","dpl1,%s",aopGet(AOP(psb),0,FALSE,FALSE,FALSE));
-               emitcode ("mov","dph1,%s",aopGet(AOP(psb),1,FALSE,FALSE,FALSE));
-               emitcode ("mov","dpx1,%s",aopGet(AOP(psb),2,FALSE,FALSE,FALSE));
+               emitcode ("mov","dpl1,%s",aopGet(AOP(psb),0,FALSE,FALSE,DP2_RESULT_REG));
+               emitcode ("mov","dph1,%s",aopGet(AOP(psb),1,FALSE,FALSE,DP2_RESULT_REG));
+               emitcode ("mov","dpx1,%s",aopGet(AOP(psb),2,FALSE,FALSE,DP2_RESULT_REG));
        }
        freeAsmop (psb, NULL, ic, FALSE);
 
@@ -11771,13 +12585,13 @@ static void genNatLibInstallStateBlock(iCode *ic, int nparms,
        /* put handle into r3:r2 */
        aopOp (handle, ic, FALSE, FALSE);
        if (aopHasRegs(AOP(handle),R2_IDX,R3_IDX)) {
-               emitcode ("push","%s",aopGet(AOP(handle),0,FALSE,TRUE,FALSE));  
-               emitcode ("push","%s",aopGet(AOP(handle),1,FALSE,TRUE,FALSE));
+               emitcode ("push","%s",aopGet(AOP(handle),0,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode ("push","%s",aopGet(AOP(handle),1,FALSE,TRUE,DP2_RESULT_REG));
                emitcode ("pop","ar3");
                emitcode ("pop","ar2");
        } else {        
-               emitcode ("mov","r2,%s",aopGet(AOP(handle),0,FALSE,TRUE,FALSE));        
-               emitcode ("mov","r3,%s",aopGet(AOP(handle),1,FALSE,TRUE,FALSE));
+               emitcode ("mov","r2,%s",aopGet(AOP(handle),0,FALSE,TRUE,DP2_RESULT_REG));       
+               emitcode ("mov","r3,%s",aopGet(AOP(handle),1,FALSE,TRUE,DP2_RESULT_REG));
        }
        freeAsmop (psb, NULL, ic, FALSE);
 
@@ -11838,8 +12652,10 @@ static void genNatLibGetStateBlock(iCode *ic,int nparms,
        if (aopHasRegs(AOP(IC_RESULT(ic)),R2_IDX,R3_IDX)) {
                emitcode ("push","ar3");
                emitcode ("push","ar2");
-               emitcode ("pop","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,TRUE,FALSE));
-               emitcode ("pop","%s",aopGet(AOP(IC_RESULT(ic)),1,FALSE,TRUE,FALSE));
+               emitcode ("pop","%s",
+                         aopGet(AOP(IC_RESULT(ic)),0,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode ("pop","%s",
+                         aopGet(AOP(IC_RESULT(ic)),1,FALSE,TRUE,DP2_RESULT_REG));
        } else {
                aopPut(AOP(IC_RESULT(ic)),"r2",0);
                aopPut(AOP(IC_RESULT(ic)),"r3",1);
@@ -11870,19 +12686,19 @@ static void genMMMalloc (iCode *ic,int nparms, operand **parms,
 
        /* put the size in R4-R2 */
        if (aopHasRegs(AOP(bsize),R2_IDX, (size==3 ? R4_IDX: R3_IDX))) {
-               emitcode("push","%s",aopGet(AOP(bsize),0,FALSE,TRUE,FALSE));
-               emitcode("push","%s",aopGet(AOP(bsize),1,FALSE,TRUE,FALSE));
+               emitcode("push","%s",aopGet(AOP(bsize),0,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode("push","%s",aopGet(AOP(bsize),1,FALSE,TRUE,DP2_RESULT_REG));
                if (size==3) {
-                       emitcode("push","%s",aopGet(AOP(bsize),2,FALSE,TRUE,FALSE));
+                       emitcode("push","%s",aopGet(AOP(bsize),2,FALSE,TRUE,DP2_RESULT_REG));
                        emitcode("pop","ar4");
                }
                emitcode("pop","ar3");
                emitcode("pop","ar2");          
        } else {
-               emitcode ("mov","r2,%s",aopGet(AOP(bsize),0,FALSE,TRUE,FALSE));
-               emitcode ("mov","r3,%s",aopGet(AOP(bsize),1,FALSE,TRUE,FALSE));
+               emitcode ("mov","r2,%s",aopGet(AOP(bsize),0,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode ("mov","r3,%s",aopGet(AOP(bsize),1,FALSE,TRUE,DP2_RESULT_REG));
                if (size==3) {
-                       emitcode("mov","r4,%s",aopGet(AOP(bsize),2,FALSE,TRUE,FALSE));
+                       emitcode("mov","r4,%s",aopGet(AOP(bsize),2,FALSE,TRUE,DP2_RESULT_REG));
                }
        }
        freeAsmop (bsize, NULL, ic, FALSE);
@@ -11900,8 +12716,10 @@ static void genMMMalloc (iCode *ic,int nparms, operand **parms,
                if (aopHasRegs(AOP(IC_RESULT(ic)),R2_IDX,R3_IDX)) {
                        emitcode ("push","ar3");
                        emitcode ("push","ar2");
-                       emitcode ("pop","%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,TRUE,FALSE));
-                       emitcode ("pop","%s",aopGet(AOP(IC_RESULT(ic)),1,FALSE,TRUE,FALSE));
+                       emitcode ("pop","%s",
+                                 aopGet(AOP(IC_RESULT(ic)),0,FALSE,TRUE,DP2_RESULT_REG));
+                       emitcode ("pop","%s",
+                                 aopGet(AOP(IC_RESULT(ic)),1,FALSE,TRUE,DP2_RESULT_REG));
                } else {
                        aopPut(AOP(IC_RESULT(ic)),"r2",0);
                        aopPut(AOP(IC_RESULT(ic)),"r3",1);
@@ -11929,13 +12747,17 @@ static void genMMDeref (iCode *ic,int nparms, operand **parms)
 
        /* put the size in R4-R2 */
        if (aopHasRegs(AOP(handle),R2_IDX,R3_IDX)) {
-               emitcode("push","%s",aopGet(AOP(handle),0,FALSE,TRUE,FALSE));
-               emitcode("push","%s",aopGet(AOP(handle),1,FALSE,TRUE,FALSE));
+               emitcode("push","%s",
+                        aopGet(AOP(handle),0,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode("push","%s",
+                        aopGet(AOP(handle),1,FALSE,TRUE,DP2_RESULT_REG));
                emitcode("pop","ar3");
                emitcode("pop","ar2");          
        } else {
-               emitcode ("mov","r2,%s",aopGet(AOP(handle),0,FALSE,TRUE,FALSE));
-               emitcode ("mov","r3,%s",aopGet(AOP(handle),1,FALSE,TRUE,FALSE));
+               emitcode ("mov","r2,%s",
+                         aopGet(AOP(handle),0,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode ("mov","r3,%s",
+                         aopGet(AOP(handle),1,FALSE,TRUE,DP2_RESULT_REG));
        }
        freeAsmop (handle, NULL, ic, FALSE);
 
@@ -11947,9 +12769,14 @@ static void genMMDeref (iCode *ic,int nparms, operand **parms)
                if (rsym->liveFrom != rsym->liveTo) {                   
                        aopOp (IC_RESULT(ic),ic,FALSE,FALSE);
                        if (AOP_TYPE(IC_RESULT(ic)) != AOP_STR) {
+                           _startLazyDPSEvaluation ();
+                           
                                aopPut(AOP(IC_RESULT(ic)),"dpl",0);
                                aopPut(AOP(IC_RESULT(ic)),"dph",1);
                                aopPut(AOP(IC_RESULT(ic)),"dpx",2);
+
+                           _endLazyDPSEvaluation ();
+                           
                        }
                }
        }
@@ -11975,13 +12802,17 @@ static void genMMUnrestrictedPersist(iCode *ic,int nparms, operand **parms)
 
        /* put the size in R3-R2 */
        if (aopHasRegs(AOP(handle),R2_IDX,R3_IDX)) {
-               emitcode("push","%s",aopGet(AOP(handle),0,FALSE,TRUE,FALSE));
-               emitcode("push","%s",aopGet(AOP(handle),1,FALSE,TRUE,FALSE));
+               emitcode("push","%s",
+                        aopGet(AOP(handle),0,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode("push","%s",
+                        aopGet(AOP(handle),1,FALSE,TRUE,DP2_RESULT_REG));
                emitcode("pop","ar3");
                emitcode("pop","ar2");          
        } else {
-               emitcode ("mov","r2,%s",aopGet(AOP(handle),0,FALSE,TRUE,FALSE));
-               emitcode ("mov","r3,%s",aopGet(AOP(handle),1,FALSE,TRUE,FALSE));
+               emitcode ("mov","r2,%s",
+                         aopGet(AOP(handle),0,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode ("mov","r3,%s",
+                         aopGet(AOP(handle),1,FALSE,TRUE,DP2_RESULT_REG));
        }
        freeAsmop (handle, NULL, ic, FALSE);
 
@@ -12018,24 +12849,29 @@ static void genSystemExecJavaProcess(iCode *ic,int nparms, operand **parms)
        /* put the handle in R3-R2 */
        aopOp (handle,ic,FALSE,FALSE);
        if (aopHasRegs(AOP(handle),R2_IDX,R3_IDX)) {
-               emitcode("push","%s",aopGet(AOP(handle),0,FALSE,TRUE,FALSE));
-               emitcode("push","%s",aopGet(AOP(handle),1,FALSE,TRUE,FALSE));
+               emitcode("push","%s",
+                        aopGet(AOP(handle),0,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode("push","%s",
+                        aopGet(AOP(handle),1,FALSE,TRUE,DP2_RESULT_REG));
                emitcode("pop","ar3");
                emitcode("pop","ar2");          
        } else {
-               emitcode ("mov","r2,%s",aopGet(AOP(handle),0,FALSE,TRUE,FALSE));
-               emitcode ("mov","r3,%s",aopGet(AOP(handle),1,FALSE,TRUE,FALSE));
+               emitcode ("mov","r2,%s",
+                         aopGet(AOP(handle),0,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode ("mov","r3,%s",
+                         aopGet(AOP(handle),1,FALSE,TRUE,DP2_RESULT_REG));
        }
        freeAsmop (handle, NULL, ic, FALSE);
        
        /* put pointer in DPTR */
        aopOp (pp,ic,FALSE,FALSE);
        if (AOP_TYPE(pp) == AOP_IMMD) {
-               emitcode ("mov", "dptr,%s", aopGet (AOP (pp), 0, TRUE, FALSE, FALSE));          
+               emitcode ("mov", "dptr,%s",
+                         aopGet (AOP (pp), 0, TRUE, FALSE, NULL));
        } else if (AOP_TYPE(pp) != AOP_STR) { /* not already in dptr */
-               emitcode ("mov","dpl,%s",aopGet(AOP(pp),0,FALSE,FALSE,FALSE));
-               emitcode ("mov","dph,%s",aopGet(AOP(pp),1,FALSE,FALSE,FALSE));
-               emitcode ("mov","dpx,%s",aopGet(AOP(pp),2,FALSE,FALSE,FALSE));
+               emitcode ("mov","dpl,%s",aopGet(AOP(pp),0,FALSE,FALSE,NULL));
+               emitcode ("mov","dph,%s",aopGet(AOP(pp),1,FALSE,FALSE,NULL));
+               emitcode ("mov","dpx,%s",aopGet(AOP(pp),2,FALSE,FALSE,NULL));
        }
        freeAsmop (handle, NULL, ic, FALSE);
 
@@ -12074,12 +12910,16 @@ static void genSystemRTCRegisters(iCode *ic,int nparms, operand **parms,
        aopOp (pp,ic,FALSE,FALSE);
        if (AOP_TYPE (pp) == AOP_IMMD) {
                emitcode ("mov","dps,#1");
-               emitcode ("mov", "dptr,%s", aopGet (AOP (pp), 0, TRUE, FALSE, FALSE));
+               emitcode ("mov", "dptr,%s", 
+                         aopGet (AOP (pp), 0, TRUE, FALSE, NULL));
                emitcode ("mov","dps,#0");
        } else {
-               emitcode ("mov","dpl1,%s",aopGet(AOP(pp),0,FALSE,FALSE,FALSE));
-               emitcode ("mov","dph1,%s",aopGet(AOP(pp),1,FALSE,FALSE,FALSE));
-               emitcode ("mov","dpx1,%s",aopGet(AOP(pp),2,FALSE,FALSE,FALSE));
+               emitcode ("mov","dpl1,%s",
+                         aopGet(AOP(pp),0,FALSE,FALSE,DP2_RESULT_REG));
+               emitcode ("mov","dph1,%s",
+                         aopGet(AOP(pp),1,FALSE,FALSE,DP2_RESULT_REG));
+               emitcode ("mov","dpx1,%s",
+                         aopGet(AOP(pp),2,FALSE,FALSE,DP2_RESULT_REG));
        }
        freeAsmop (pp, NULL, ic, FALSE);
 
@@ -12106,26 +12946,35 @@ static void genSystemThreadSleep(iCode *ic,int nparms, operand **parms, char *na
        aopOp(to,ic,FALSE,FALSE);
        if (aopHasRegs(AOP(to),R2_IDX,R3_IDX) ||
            aopHasRegs(AOP(to),R0_IDX,R1_IDX) ) {
-               emitcode ("push","%s",aopGet(AOP(to),0,FALSE,TRUE,FALSE));
-               emitcode ("push","%s",aopGet(AOP(to),1,FALSE,TRUE,FALSE));
-               emitcode ("push","%s",aopGet(AOP(to),2,FALSE,TRUE,FALSE));
-               emitcode ("push","%s",aopGet(AOP(to),3,FALSE,TRUE,FALSE));
+               emitcode ("push","%s",
+                         aopGet(AOP(to),0,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode ("push","%s",
+                         aopGet(AOP(to),1,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode ("push","%s",
+                         aopGet(AOP(to),2,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode ("push","%s",
+                         aopGet(AOP(to),3,FALSE,TRUE,DP2_RESULT_REG));
                emitcode ("pop","ar3");
                emitcode ("pop","ar2");
                emitcode ("pop","ar1");
                emitcode ("pop","ar0");
        } else {
-               emitcode ("mov","r0,%s",aopGet(AOP(to),0,FALSE,TRUE,FALSE));
-               emitcode ("mov","r1,%s",aopGet(AOP(to),1,FALSE,TRUE,FALSE));
-               emitcode ("mov","r2,%s",aopGet(AOP(to),2,FALSE,TRUE,FALSE));
-               emitcode ("mov","r3,%s",aopGet(AOP(to),3,FALSE,TRUE,FALSE));
+               emitcode ("mov","r0,%s",
+                         aopGet(AOP(to),0,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode ("mov","r1,%s",
+                         aopGet(AOP(to),1,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode ("mov","r2,%s",
+                         aopGet(AOP(to),2,FALSE,TRUE,DP2_RESULT_REG));
+               emitcode ("mov","r3,%s",
+                         aopGet(AOP(to),3,FALSE,TRUE,DP2_RESULT_REG));
        }
        freeAsmop (to, NULL, ic, FALSE);
 
        /* suspend in acc */
        s = parms[1];
        aopOp(s,ic,FALSE,FALSE);
-       emitcode ("mov","a,%s",aopGet(AOP(s),0,FALSE,TRUE,FALSE));
+       emitcode ("mov","a,%s",
+                 aopGet(AOP(s),0,FALSE,TRUE,NULL));
        freeAsmop (s, NULL, ic, FALSE);
 
        /* make the call */
@@ -12152,12 +13001,14 @@ static void genSystemThreadResume(iCode *ic,int nparms, operand **parms)
        
        /* PID in R0 */
        aopOp(pid,ic,FALSE,FALSE);
-       emitcode ("mov","r0,%s",aopGet(AOP(pid),0,FALSE,TRUE,FALSE));
+       emitcode ("mov","r0,%s",
+                 aopGet(AOP(pid),0,FALSE,TRUE,DP2_RESULT_REG));
        freeAsmop (pid, NULL, ic, FALSE);
        
        /* tid into ACC */
        aopOp(tid,ic,FALSE,FALSE);
-       emitcode ("mov","a,%s",aopGet(AOP(tid),0,FALSE,TRUE,FALSE));
+       emitcode ("mov","a,%s",
+                 aopGet(AOP(tid),0,FALSE,TRUE,DP2_RESULT_REG));
        freeAsmop (tid, NULL, ic, FALSE);
        
        emitcode ("lcall","System_ThreadResume");
@@ -12191,7 +13042,8 @@ static void genSystemProcessResume(iCode *ic,int nparms, operand **parms)
        
        /* pid into ACC */
        aopOp(pid,ic,FALSE,FALSE);
-       emitcode ("mov","a,%s",aopGet(AOP(pid),0,FALSE,TRUE,FALSE));
+       emitcode ("mov","a,%s",
+                 aopGet(AOP(pid),0,FALSE,TRUE,DP2_RESULT_REG));
        freeAsmop (pid, NULL, ic, FALSE);
        
        emitcode ("lcall","System_ProcessResume");
@@ -12225,11 +13077,15 @@ static void genSystemPoll(iCode *ic,int nparms, operand **parms,char *name)
        fp = parms[0];
        aopOp (fp,ic,FALSE,FALSE);
        if (AOP_TYPE (fp) == AOP_IMMD) {
-               emitcode ("mov", "dptr,%s", aopGet (AOP (fp), 0, TRUE, FALSE, FALSE));
+               emitcode ("mov", "dptr,%s", 
+                         aopGet (AOP (fp), 0, TRUE, FALSE, DP2_RESULT_REG));
        } else if (AOP_TYPE(fp) != AOP_STR) { /* not already in dptr */
-               emitcode ("mov","dpl,%s",aopGet(AOP(fp),0,FALSE,FALSE,FALSE));
-               emitcode ("mov","dph,%s",aopGet(AOP(fp),1,FALSE,FALSE,FALSE));
-               emitcode ("mov","dpx,%s",aopGet(AOP(fp),2,FALSE,FALSE,FALSE));
+               emitcode ("mov","dpl,%s",
+                         aopGet(AOP(fp),0,FALSE,FALSE,DP2_RESULT_REG));
+               emitcode ("mov","dph,%s",
+                         aopGet(AOP(fp),1,FALSE,FALSE,DP2_RESULT_REG));
+               emitcode ("mov","dpx,%s",
+                         aopGet(AOP(fp),2,FALSE,FALSE,DP2_RESULT_REG));
        }
        freeAsmop (fp, NULL, ic, FALSE);
 
@@ -12266,6 +13122,127 @@ static void genSystemGetCurrentID(iCode *ic,int nparms, operand **parms,char *na
        }
 }
 
+/*-----------------------------------------------------------------*/
+/* genDummyRead - generate code for dummy read of volatiles        */
+/*-----------------------------------------------------------------*/
+static void
+genDummyRead (iCode * ic)
+{
+  operand *op;
+  int size, offset;
+
+  D(emitcode(";     genDummyRead",""));
+
+  op = IC_RIGHT (ic);
+  if (op && IS_SYMOP (op))
+    {
+      aopOp (op, ic, FALSE, FALSE);
+
+      /* if the result is a bit */
+      if (AOP_TYPE (op) == AOP_CRY)
+        emitcode ("mov", "c,%s", AOP (op)->aopu.aop_dir);
+      else
+       {
+         /* bit variables done */
+         /* general case */
+         size = AOP_SIZE (op);
+         offset = 0;
+         while (size--)
+         {
+           MOVA (aopGet (AOP (op), offset, FALSE, FALSE, FALSE));
+           offset++;
+         }
+       }
+
+      freeAsmop (op, NULL, ic, TRUE);
+    }
+
+  op = IC_LEFT (ic);
+  if (op && IS_SYMOP (op))
+    {
+      aopOp (op, ic, FALSE, FALSE);
+
+      /* if the result is a bit */
+      if (AOP_TYPE (op) == AOP_CRY)
+        emitcode ("mov", "c,%s", AOP (op)->aopu.aop_dir);
+      else
+       {
+         /* bit variables done */
+         /* general case */
+         size = AOP_SIZE (op);
+         offset = 0;
+         while (size--)
+         {
+           MOVA (aopGet (AOP (op), offset, FALSE, FALSE, FALSE));
+           offset++;
+         }
+       }
+
+      freeAsmop (op, NULL, ic, TRUE);
+    }
+    
+}
+
+/*-----------------------------------------------------------------*/
+/* genCritical - generate code for start of a critical sequence    */
+/*-----------------------------------------------------------------*/
+static void
+genCritical (iCode *ic)
+{
+  symbol *tlbl = newiTempLabel (NULL);
+
+  D(emitcode(";     genCritical",""));
+  
+  if (IC_RESULT (ic))
+    aopOp (IC_RESULT (ic), ic, TRUE, FALSE);
+
+  emitcode ("setb", "c");
+  emitcode ("jbc", "ea,%05d$", (tlbl->key + 100)); /* atomic test & clear */
+  emitcode ("clr", "c");
+  emitcode ("", "%05d$:", (tlbl->key + 100));
+
+  if (IC_RESULT (ic))
+    outBitC (IC_RESULT (ic)); /* save old ea in an operand */
+  else
+    emitcode ("push", "psw"); /* save old ea via c in psw on top of stack*/
+
+  if (IC_RESULT (ic))
+    freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genEndCritical - generate code for end of a critical sequence   */
+/*-----------------------------------------------------------------*/
+static void
+genEndCritical (iCode *ic)
+{
+  D(emitcode(";     genEndCritical",""));
+  
+  if (IC_RIGHT (ic))
+    {
+      aopOp (IC_RIGHT (ic), ic, FALSE, FALSE);
+      if (AOP_TYPE (IC_RIGHT (ic)) == AOP_CRY)
+        {
+         emitcode ("mov", "c,%s", IC_RIGHT (ic)->aop->aopu.aop_dir);
+          emitcode ("mov", "ea,c");
+        }
+      else
+        {
+          MOVA (aopGet (AOP (IC_RIGHT (ic)), 0, FALSE, FALSE, FALSE));
+          emitcode ("rrc", "a");
+          emitcode ("mov", "ea,c");
+        }
+      freeAsmop (IC_RIGHT (ic), NULL, ic, TRUE);
+    }
+  else
+    {
+      emitcode ("pop", "psw"); /* restore ea via c in psw on top of stack */
+      emitcode ("mov", "ea,c");
+    }
+}
+
+
+
 /*-----------------------------------------------------------------*/
 /* genBuiltIn - calls the appropriate function to  generating code */
 /* for a built in function                                        */
@@ -12400,13 +13377,13 @@ gen390Code (iCode * lic)
   }
 #if 1
   /* print the allocation information */
-  if (allocInfo)
+  if (allocInfo && currFunc)
     printAllocInfo (currFunc, codeOutFile);
 #endif
   /* if debug information required */
   if (options.debug && currFunc)
     {
-      cdbSymbol (currFunc, cdbFile, FALSE, TRUE);
+      debugFile->writeFunction(currFunc);
       _G.debugLine = 1;
       if (IS_STATIC (currFunc->etype))
        emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
@@ -12424,6 +13401,8 @@ gen390Code (iCode * lic)
   for (ic = lic; ic; ic = ic->next)
     {
 
+      _G.current_iCode = ic;
+      
       if (ic->lineno && cln != ic->lineno)
        {
          if (options.debug)
@@ -12434,10 +13413,15 @@ gen390Code (iCode * lic)
                        ic->level, ic->block);
              _G.debugLine = 0;
            }
-         emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
-                   printCLine(ic->filename, ic->lineno));
+         if (!options.noCcodeInAsm) {
+           emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
+                     printCLine(ic->filename, ic->lineno));
+         }
          cln = ic->lineno;
        }
+      if (options.iCodeInAsm) {
+       emitcode("", ";ic:%d: %s", ic->key, printILine(ic));
+      }
       /* if the result is marked as
          spilt and rematerializable or code for
          this has already been generated then
@@ -12630,9 +13614,27 @@ gen390Code (iCode * lic)
          else addSet (&_G.sendSet, ic);
          break;
 
+       case DUMMY_READ_VOLATILE:
+         genDummyRead (ic);
+         break;
+
+       case CRITICAL:
+         genCritical (ic);
+         break;
+
+       case ENDCRITICAL:
+         genEndCritical (ic);
+         break;
+       
+        case SWAP:
+         genSwap (ic);
+         break;
+          
+#if 0 // obsolete, and buggy for != xdata
        case ARRAYINIT:
            genArrayInit(ic);
            break;
+#endif
            
        default:
          ic = ic;