Buffer overflow hunt: removing strcpy, strcat, sprintf
[fw/sdcc] / src / ds390 / gen.c
index b3fdbe68ad70a360980ed6a3dfea3601b20c8879..1cf40126b348e97bf7c6490a1f18184af97ec885 100644 (file)
@@ -4,6 +4,7 @@
   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
+  DS390 adaptation by Kevin Vigor <kevin@vigor.nu>
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
@@ -29,7 +30,7 @@
 #include <string.h>
 #include <ctype.h>
 
-#include <common.h>
+#include "common.h"
 #include "ralloc.h"
 #include "gen.h"
 #include "SDCCglobl.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)
+#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);
+extern int allocInfo;
 
 /* this is the down and dirty file with all kinds of
    kludgy & hacky stuff. This is what it is all about
    CODE GENERATION for a specific MCU . some of the
    routines may be reusable, will have to see */
 
-static char *zero = "#0x00";
-static char *one = "#0x01";
+static char *zero = "#0";
+static char *one = "#1";
 static char *spname;
 
 #define D(x) x
 
+#define TR_DPTR(s) if (options.model != MODEL_FLAT24) { emitcode(";", " Use_DPTR1 %s ", s); }
+#define TR_AP(s) if (options.model != MODEL_FLAT24) { emitcode(";", " Use_AP %s ", s); }
+
 unsigned fReturnSizeDS390 = 5; /* shared with ralloc.c */
-static char *fReturn[] =
+static char *fReturn24[] =
 {"dpl", "dph", "dpx", "b", "a"};
+static char *fReturn16[] =
+{"dpl", "dph", "b", "a"};
+static char **fReturn = fReturn24;
 static char *accUse[] =
 {"a", "b"};
-
+static char *dptrn[2][3];
+static char *javaRet[] = { "r0","r1","r2","r3"};
 static short rbank = -1;
 
 static struct
@@ -76,13 +89,20 @@ static struct
     short r0Pushed;
     short r1Pushed;
     short accInUse;
+    short bInUse;
     short inLine;
     short debugLine;
     short nRegsSaved;
+    short dptrInUse;
+    short dptr1InUse;
     set *sendSet;
   }
 _G;
 
+static char *rb1regs[] = {
+    "b1_0","b1_1","b1_2","b1_3","b1_4","b1_5","b1_6","b1_7"
+};
+
 static void saveRBank (int, iCode *, bool);
 
 #define RESULTONSTACK(x) \
@@ -102,7 +122,7 @@ static void saveRBank (int, iCode *, bool);
 
 // A scratch register which will be used to hold
 // result bytes from operands in far space via DPTR2.
-#define DP2_RESULT_REG "ap"
+#define DP2_RESULT_REG "_ap"
 
 static lineNode *lineHead = NULL;
 static lineNode *lineCurr = NULL;
@@ -118,6 +138,20 @@ static unsigned char SRMask[] =
 #define MSB16   1
 #define MSB24   2
 #define MSB32   3
+#define PROTECT_SP     {if (options.protect_sp_update) {                       \
+                               symbol *lbl = newiTempLabel(NULL);              \
+                               emitcode ("setb","F1");                         \
+                               emitcode ("jbc","EA,!tlabel",lbl->key+100);     \
+                               emitcode ("clr","F1");                          \
+                               emitcode ("","!tlabeldef",lbl->key+100);        \
+                       }}
+#define UNPROTECT_SP   { if (options.protect_sp_update) {                      \
+                               symbol *lbl = newiTempLabel(NULL);              \
+                               emitcode ("jnb","F1,!tlabel",lbl->key+100);     \
+                               emitcode ("setb","EA");                         \
+                               emitcode ("","!tlabeldef",lbl->key+100);        \
+                       }}
+
 
 /*-----------------------------------------------------------------*/
 /* emitcode - writes the code into a file : for now it is simple    */
@@ -125,33 +159,47 @@ static unsigned char SRMask[] =
 static void
 emitcode (char *inst, char *fmt,...)
 {
-  va_list ap;
-  char lb[MAX_INLINEASM];
-  char *lbp = lb;
-
-  va_start (ap, fmt);
-
-  if (inst && *inst)
+    va_list ap;
+    char lb[INITIAL_INLINEASM];
+    char *lbp = lb;
+    
+    va_start (ap, fmt);
+    
+    if (inst && *inst)
     {
-      if (fmt && *fmt)
-       sprintf (lb, "%s\t", inst);
-      else
-       sprintf (lb, "%s", inst);
-      vsprintf (lb + (strlen (lb)), fmt, ap);
+       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
-    vsprintf (lb, fmt, ap);
+    else
+    {
+       tvsprintf (lb, sizeof(lb), fmt, ap);
+    }
+    
 
-  while (isspace (*lbp))
-    lbp++;
+    while (isspace (*lbp))
+    {
+       lbp++;
+    }
 
-  if (lbp && *lbp)
-    lineCurr = (lineCurr ?
-               connectLine (lineCurr, newLineNode (lb)) :
-               (lineHead = newLineNode (lb)));
-  lineCurr->isInline = _G.inLine;
-  lineCurr->isDebug = _G.debugLine;
-  va_end (ap);
+    if (lbp && *lbp)
+    {
+       lineCurr = (lineCurr ?
+                   connectLine (lineCurr, newLineNode (lb)) :
+                   (lineHead = newLineNode (lb)));
+    }
+    
+    lineCurr->isInline = _G.inLine;
+    lineCurr->isDebug = _G.debugLine;
+    va_end (ap);
 }
 
 /*-----------------------------------------------------------------*/
@@ -168,9 +216,9 @@ getFreePtr (iCode * ic, asmop ** aopp, bool result)
 
   /* first check if r0 & r1 are used by this
      instruction, in which case we are in trouble */
-  if ((r0iu = bitVectBitValue (ic->rUsed, R0_IDX)) &&
-      (r1iu = bitVectBitValue (ic->rUsed, R1_IDX)))
-    {
+  r0iu = bitVectBitValue (ic->rUsed, R0_IDX);
+  r1iu = bitVectBitValue (ic->rUsed, R1_IDX);
+  if (r0iu && r1iu) {
       goto endOfWorld;
     }
 
@@ -282,11 +330,12 @@ genSetDPTR (int n)
 
   if (!n)
     {
-      emitcode ("mov", "dps, #0x00");
+      emitcode ("mov", "dps,#0");
     }
   else
     {
-      emitcode ("mov", "dps, #0x01");
+      TR_DPTR("#1");
+      emitcode ("mov", "dps,#1");
     }
 }
 
@@ -417,14 +466,20 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
              if (_G.accInUse)
                emitcode ("push", "acc");
 
+             if (_G.bInUse)
+               emitcode ("push", "b");
+
              emitcode ("mov", "a,_bp");
-             emitcode ("add", "a,#0x%02x",
+             emitcode ("add", "a,#!constbyte",
                        ((sym->stack < 0) ?
                         ((char) (sym->stack - _G.nRegsSaved)) :
                         ((char) sym->stack)) & 0xff);
              emitcode ("mov", "%s,a",
                        aop->aopu.aop_ptr->name);
 
+             if (_G.bInUse)
+               emitcode ("pop", "b");
+
              if (_G.accInUse)
                emitcode ("pop", "acc");
            }
@@ -441,38 +496,77 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
 
   if (sym->onStack && options.stack10bit)
     {
+       short stack_val = -((sym->stack < 0) ?
+                           ((short) (sym->stack - _G.nRegsSaved)) :
+                           ((short) sym->stack)) ;
+       if (useDP2 && _G.dptr1InUse) {
+           emitcode ("push","dpl1");
+           emitcode ("push","dph1");
+           emitcode ("push","dpx1");
+       } else if (_G.dptrInUse ) {
+           emitcode ("push","dpl");
+           emitcode ("push","dph");
+           emitcode ("push","dpx");
+       }
       /* It's on the 10 bit stack, which is located in
        * far data space.
-       */
-
-      if (_G.accInUse)
-       emitcode ("push", "acc");
-
-      emitcode ("mov", "a,_bp");
-      emitcode ("add", "a,#0x%02x",
-               ((sym->stack < 0) ?
-                ((char) (sym->stack - _G.nRegsSaved)) :
-                ((char) sym->stack)) & 0xff);
-
-      if (useDP2)
-       {
-         emitcode ("mov", "dpx1,#0x40");
-         emitcode ("mov", "dph1,#0x00");
-         emitcode ("mov", "dpl1, a");
-       }
-      else
-       {
-         emitcode ("mov", "dpx,#0x40");
-         emitcode ("mov", "dph,#0x00");
-         emitcode ("mov", "dpl, a");
+       */          
+       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", "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", "dph,_bpx+1");
+               emitcode ("mov", "dpl,_bpx");
+           }
+           stack_val = -stack_val;
+           while (stack_val--) {
+               emitcode ("inc","dptr");
+           }
+           if (useDP2) {
+               emitcode("mov","dps,#0");
+           }
+       }  else {
+           if (_G.accInUse)
+               emitcode ("push", "acc");
+           
+           if (_G.bInUse)
+               emitcode ("push", "b");
+       
+           emitcode ("mov", "a,_bpx");
+           emitcode ("clr","c");
+           emitcode ("subb", "a,#!constbyte", stack_val & 0xff);
+           emitcode ("mov","b,a");
+           emitcode ("mov","a,_bpx+1");
+           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", "dph1,a");
+               emitcode ("mov", "dpl1,b");
+           } else {
+               if (options.model == MODEL_FLAT24)
+                   emitcode ("mov", "dpx,#!constbyte", (options.stack_loc >> 16) & 0xff);
+               emitcode ("mov", "dph,a");
+               emitcode ("mov", "dpl,b");
+           }
+           
+           if (_G.bInUse)
+               emitcode ("pop", "b");
+           
+           if (_G.accInUse)
+               emitcode ("pop", "acc");
        }
-
-      if (_G.accInUse)
-       emitcode ("pop", "acc");
-
-      sym->aop = aop = newAsmop ((short) (useDP2 ? AOP_DPTR2 : AOP_DPTR));
-      aop->size = getSize (sym->type);
-      return aop;
+       sym->aop = aop = newAsmop ((short) (useDP2 ? AOP_DPTR2 : AOP_DPTR));
+       aop->size = getSize (sym->type);
+       return aop;
     }
 
   /* if in bit space */
@@ -496,12 +590,12 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
   if (IS_FUNC (sym->type))
     {
       sym->aop = aop = newAsmop (AOP_IMMD);
-      aop->aopu.aop_immd = Safe_calloc (1, strlen (sym->rname) + 1);
-      strcpy (aop->aopu.aop_immd, sym->rname);
+      aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (sym->rname) + 1);
+      strcpy (aop->aopu.aop_immd.aop_immd1, sym->rname);
       aop->size = FPTRSIZE;
       return aop;
     }
-
+  
   /* only remaining is far space */
   /* in which case DPTR gets the address */
   sym->aop = aop = newAsmop ((short) (useDP2 ? AOP_DPTR2 : AOP_DPTR));
@@ -533,7 +627,7 @@ aopForRemat (symbol * sym)
 {
   iCode *ic = sym->rematiCode;
   asmop *aop = newAsmop (AOP_IMMD);
-
+  int ptr_type =0;
   int val = 0;
 
   for (;;)
@@ -542,9 +636,18 @@ aopForRemat (symbol * sym)
        val += (int) operandLitValue (IC_RIGHT (ic));
       else if (ic->op == '-')
        val -= (int) operandLitValue (IC_RIGHT (ic));
-      else
-       break;
-
+      else if (IS_CAST_ICODE(ic)) {
+             sym_link *from_type = operandType(IC_RIGHT(ic));
+             aop->aopu.aop_immd.from_cast_remat = 1;
+             ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+             ptr_type = DCL_TYPE(from_type);
+             if (ptr_type == IPOINTER) {
+               // bug #481053
+               ptr_type = POINTER;
+             }
+             continue ;
+      } else break;
+      
       ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
     }
 
@@ -553,14 +656,42 @@ aopForRemat (symbol * sym)
             OP_SYMBOL (IC_LEFT (ic))->rname,
             val >= 0 ? '+' : '-',
             abs (val) & 0xffff);
-  else
-    strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
+  else {
+      if (IS_ASSIGN_ICODE(ic) && isOperandLiteral(IC_RIGHT(ic)))
+         sprintf(buffer,"0x%x",(int) operandLitValue (IC_RIGHT (ic)));
+      else
+         strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
+  }
+
+  aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1);
+  strcpy (aop->aopu.aop_immd.aop_immd1, buffer);
+  /* set immd2 field if required */
+  if (aop->aopu.aop_immd.from_cast_remat) 
+  {
+      tsprintf(buffer, sizeof(buffer), "#!constbyte",ptr_type);
+      aop->aopu.aop_immd.aop_immd2 = Safe_strdup(buffer);  
+  }
 
-  aop->aopu.aop_immd = Safe_calloc (1, strlen (buffer) + 1);
-  strcpy (aop->aopu.aop_immd, buffer);
   return aop;
 }
 
+/*-----------------------------------------------------------------*/
+/* aopHasRegs - returns true if aop has regs between from-to       */
+/*-----------------------------------------------------------------*/
+static int aopHasRegs(asmop *aop, int from, int to)
+{
+    int size =0;
+
+    if (aop->type != AOP_REG) return 0; /* if not assigned to regs */
+
+    for (; size < aop->size ; size++) {
+       int reg;
+       for (reg = from ; reg <= to ; reg++)
+           if (aop->aopu.aop_reg[size] == ds390_regWithIdx(reg)) return 1;
+    }
+    return 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* regsInCommon - two operands have some registers in common       */
 /*-----------------------------------------------------------------*/
@@ -770,7 +901,7 @@ aopOp (operand * op, iCode * ic, bool result, bool useDP2)
              /* a AOP_STR uses DPTR, but DPTR is already in use;
               * we're just hosed.
               */
-             fprintf (stderr, "*** Internal error: AOP_STR with DPTR in use!\n");
+               werror(E_INTERNAL_ERROR,__FILE__,__LINE__,"AOP_STR with DPTR in use!");
            }
 
          aop = op->aop = sym->aop = newAsmop (AOP_STR);
@@ -779,8 +910,18 @@ aopOp (operand * op, iCode * ic, bool result, bool useDP2)
            aop->aopu.aop_str[i] = fReturn[i];
          return;
        }
-
+      
+      if (sym->dptr) { /* has been allocated to a DPTRn */
+         aop = op->aop = sym->aop = newAsmop (AOP_DPTRn);
+         aop->size = getSize (sym->type);
+         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);
       aop->size = getSize (sym->type);
@@ -864,7 +1005,7 @@ freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
        if (stk)
          {
            emitcode ("mov", "a,_bp");
-           emitcode ("add", "a,#0x%02x", ((char) stk) & 0xff);
+           emitcode ("add", "a,#!constbyte", ((char) stk) & 0xff);
            emitcode ("mov", "%s,a", aop->aopu.aop_ptr->name);
          }
        else
@@ -894,8 +1035,21 @@ freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
            _G.r1Pushed--;
          }
       }
+    case AOP_DPTR2:
+       if (_G.dptr1InUse) {
+           emitcode ("pop","dpx1");
+           emitcode ("pop","dph1");
+           emitcode ("pop","dpl1");
+       }
+       break;
+    case AOP_DPTR:
+       if (_G.dptrInUse) {
+           emitcode ("pop","dpx");
+           emitcode ("pop","dph");
+           emitcode ("pop","dpl");
+       }
+       break;
     }
-
 dealloc:
   /* all other cases just dealloc */
   if (op)
@@ -926,8 +1080,8 @@ aopGet (asmop * aop,
        bool dname,
        bool canClobberACC)
 {
-  char *s = buffer;
-  char *rs;
+  //char *s = buffer;
+  //char *rs;
 
   /* offset is greater than
      size then zero */
@@ -960,10 +1114,12 @@ 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);
+       return dptrn[aop->aopu.dptr][offset];
 
     case AOP_DPTR:
     case AOP_DPTR2:
@@ -973,7 +1129,8 @@ aopGet (asmop * aop,
          genSetDPTR (1);
          if (!canClobberACC)
            {
-             emitcode ("xch", "a, %s", DP2_RESULT_REG);
+                   TR_AP("#1");
+                   emitcode ("xch", "a, %s", DP2_RESULT_REG);
            }
        }
 
@@ -1007,6 +1164,7 @@ aopGet (asmop * aop,
          genSetDPTR (0);
          if (!canClobberACC)
            {
+       TR_AP("#2");
              emitcode ("xch", "a, %s", DP2_RESULT_REG);
              return DP2_RESULT_REG;
            }
@@ -1014,29 +1172,60 @@ aopGet (asmop * aop,
       return (dname ? "acc" : "a");
 
     case AOP_IMMD:
-      if (bit16)
-       sprintf (s, "#%s", aop->aopu.aop_immd);
-      else if (offset)
-       sprintf (s, "#(%s >> %d)",
-                aop->aopu.aop_immd,
-                offset * 8);
+      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(buffer, sizeof(buffer),
+                      "#!his",aop->aopu.aop_immd.aop_immd1);
+             break;
+         case 2:
+             tsprintf(buffer, sizeof(buffer), 
+                      "#!hihis",aop->aopu.aop_immd.aop_immd1);
+             break;
+         case 3:
+             tsprintf(buffer, sizeof(buffer),
+                      "#!hihihis",aop->aopu.aop_immd.aop_immd1);
+             break;
+         default: /* should not need this (just in case) */
+             SNPRINTF (buffer, sizeof(buffer), 
+                       "#(%s >> %d)",
+                      aop->aopu.aop_immd.aop_immd1,
+                      offset * 8);
+         }
+      }
       else
-       sprintf (s, "#%s",
-                aop->aopu.aop_immd);
-      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)
@@ -1124,6 +1313,10 @@ aopPut (asmop * aop, char *s, int offset)
        }
       break;
 
+    case AOP_DPTRn:
+       emitcode ("mov","%s,%s",dptrn[aop->aopu.dptr][offset],s);
+       break;
+
     case AOP_DPTR:
     case AOP_DPTR2:
 
@@ -1213,7 +1406,12 @@ aopPut (asmop * aop, char *s, int offset)
       if (strcmp (s, "a") == 0)
        emitcode ("push", "acc");
       else
-       emitcode ("push", "%s", s);
+       if (*s=='@') {
+         MOVA(s);
+         emitcode ("push", "acc");
+       } else {
+         emitcode ("push", s);
+       }
 
       break;
 
@@ -1239,11 +1437,8 @@ aopPut (asmop * aop, char *s, int offset)
                  MOVA (s);
                }
              {
-               symbol *lbl = newiTempLabel (NULL);
-               emitcode ("clr", "c");
-               emitcode ("jz", "%05d$", lbl->key + 100);
-               emitcode ("cpl", "c");
-               emitcode ("", "%05d$:", lbl->key + 100);
+               /* set C, if a >= 1 */
+               emitcode ("add", "a,#!constbyte",0xff);
                emitcode ("mov", "%s,c", aop->aopu.aop_dir);
              }
            }
@@ -1326,6 +1521,8 @@ reAdjustPreg (asmop * aop)
 #define AOP_INPREG(x) (x && (x->type == AOP_REG &&                        \
                       (x->aopu.aop_reg[0] == ds390_regWithIdx(R0_IDX) || \
                       x->aopu.aop_reg[0] == ds390_regWithIdx(R1_IDX) )))
+#define AOP_INDPTRn(x) (AOP_TYPE(x) == AOP_DPTRn)
+#define AOP_USESDPTR(x) (AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_STR)
 
 /* Workaround for DS80C390 bug: div ab may return bogus results
  * if A is accessed in instruction immediately before the div.
@@ -1387,9 +1584,9 @@ genNotFloat (operand * op, operand * res)
 
   tlbl = newiTempLabel (NULL);
   aopPut (res->aop, one, 1);
-  emitcode ("jz", "%05d$", (tlbl->key + 100));
+  emitcode ("jz", "!tlabel", (tlbl->key + 100));
   aopPut (res->aop, zero, 1);
-  emitcode ("", "%05d$:", (tlbl->key + 100));
+  emitcode ("", "!tlabeldef", (tlbl->key + 100));
 
   size = res->aop->size - 2;
   offset = 2;
@@ -1565,8 +1762,8 @@ genNot (iCode * ic)
   toBoolean (IC_LEFT (ic));
 
   tlbl = newiTempLabel (NULL);
-  emitcode ("cjne", "a,#0x01,%05d$", tlbl->key + 100);
-  emitcode ("", "%05d$:", tlbl->key + 100);
+  emitcode ("cjne", "a,#1,!tlabel", tlbl->key + 100);
+  emitcode ("", "!tlabeldef", tlbl->key + 100);
   outBitC (IC_RESULT (ic));
 
 release:
@@ -1584,6 +1781,7 @@ genCpl (iCode * ic)
 {
   int offset = 0;
   int size;
+  symbol *tlbl;
 
   D (emitcode (";", "genCpl ");
     );
@@ -1593,17 +1791,21 @@ genCpl (iCode * ic)
   aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
   aopOp (IC_RESULT (ic), ic, TRUE, AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR);
 
-  /* if both are in bit space then
-     a special case */
-  if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY &&
-      AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
-    {
-
+  /* special case if in bit space */
+  if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY) {
+    if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY) {
       emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
       emitcode ("cpl", "c");
       emitcode ("mov", "%s,c", IC_RESULT (ic)->aop->aopu.aop_dir);
       goto release;
     }
+    tlbl=newiTempLabel(NULL);
+    emitcode ("cjne", "%s,#0x01,%05d$", 
+             aopGet(AOP(IC_LEFT(ic)), 0, FALSE,FALSE,TRUE), tlbl->key+100);
+    emitcode ("", "%05d$:", tlbl->key+100);
+    outBitC (IC_RESULT(ic));
+    goto release;
+  }
 
   size = AOP_SIZE (IC_RESULT (ic));
   _startLazyDPSEvaluation ();
@@ -1734,16 +1936,45 @@ release:
   freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
 }
 
+/*-----------------------------------------------------------------*/
+/* savermask - saves registers in the mask                         */
+/*-----------------------------------------------------------------*/
+static void savermask(bitVect *rs_mask)
+{
+    int i;
+    if (options.useXstack) {
+       if (bitVectBitValue (rs_mask, R0_IDX))
+           emitcode ("mov", "b,r0");
+       emitcode ("mov", "r0,%s", spname);
+       for (i = 0; i < ds390_nRegs; i++) {
+           if (bitVectBitValue (rs_mask, i)) {
+               if (i == R0_IDX)
+                   emitcode ("mov", "a,b");
+               else
+                   emitcode ("mov", "a,%s", ds390_regWithIdx (i)->name);
+               emitcode ("movx", "@r0,a");
+               emitcode ("inc", "r0");
+           }
+       }
+       emitcode ("mov", "%s,r0", spname);
+       if (bitVectBitValue (rs_mask, R0_IDX))
+           emitcode ("mov", "r0,b");
+    } else {
+       for (i = 0; i < ds390_nRegs; i++) {
+           if (bitVectBitValue (rs_mask, i))
+               emitcode ("push", "%s", ds390_regWithIdx (i)->dname);
+       }
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* saveRegisters - will look for a call and save the registers     */
 /*-----------------------------------------------------------------*/
 static void
 saveRegisters (iCode * lic)
 {
-  int i;
   iCode *ic;
   bitVect *rsave;
-  sym_link *detype;
 
   /* look for call */
   for (ic = lic; ic; ic = ic->next)
@@ -1758,94 +1989,80 @@ saveRegisters (iCode * lic)
 
   /* if the registers have been saved already then
      do nothing */
-  if (ic->regsSaved || (OP_SYMBOL (IC_LEFT (ic))->calleeSave))
-    return;
-
-  /* find the registers in use at this time
-     and push them away to safety */
-  rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
-                        ic->rUsed);
-
+  if (ic->regsSaved || IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic)))) return ;
+
+  /* special case if DPTR alive across a function call then must save it 
+     even though callee saves */
+  if (IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) {
+      int i =0;
+      rsave = newBitVect(ic->rMask->size);
+      for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+         if (bitVectBitValue(ic->rMask,i))
+             rsave = bitVectSetBit(rsave,i);
+      }
+      rsave = bitVectCplAnd(rsave,ds390_rUmaskForOp (IC_RESULT(ic)));
+  } else {
+    /* safe the registers in use at this time but skip the
+       ones for the result */
+    rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                          ds390_rUmaskForOp (IC_RESULT(ic)));
+  }
   ic->regsSaved = 1;
-  if (options.useXstack)
-    {
-      if (bitVectBitValue (rsave, R0_IDX))
-       emitcode ("mov", "b,r0");
-      emitcode ("mov", "r0,%s", spname);
-      for (i = 0; i < ds390_nRegs; i++)
-       {
-         if (bitVectBitValue (rsave, i))
-           {
-             if (i == R0_IDX)
-               emitcode ("mov", "a,b");
-             else
-               emitcode ("mov", "a,%s", ds390_regWithIdx (i)->name);
-             emitcode ("movx", "@r0,a");
-             emitcode ("inc", "r0");
-           }
+  savermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* usavermask - restore registers with mask                        */
+/*-----------------------------------------------------------------*/
+static void unsavermask(bitVect *rs_mask)
+{
+    int i;
+    if (options.useXstack) {
+       emitcode ("mov", "r0,%s", spname);
+       for (i = ds390_nRegs; i >= 0; i--) {
+           if (bitVectBitValue (rs_mask, i)) {
+               emitcode ("dec", "r0");
+               emitcode ("movx", "a,@r0");
+               if (i == R0_IDX)
+                   emitcode ("mov", "b,a");
+               else
+                   emitcode ("mov", "%s,a", ds390_regWithIdx (i)->name);
+           }       
+       }
+       emitcode ("mov", "%s,r0", spname);
+       if (bitVectBitValue (rs_mask, R0_IDX))
+           emitcode ("mov", "r0,b");
+    } else {
+       for (i = ds390_nRegs; i >= 0; i--) {
+           if (bitVectBitValue (rs_mask, i))
+               emitcode ("pop", "%s", ds390_regWithIdx (i)->dname);
        }
-      emitcode ("mov", "%s,r0", spname);
-      if (bitVectBitValue (rsave, R0_IDX))
-       emitcode ("mov", "r0,b");
     }
-  else
-    for (i = 0; i < ds390_nRegs; i++)
-      {
-       if (bitVectBitValue (rsave, i))
-         emitcode ("push", "%s", ds390_regWithIdx (i)->dname);
-      }
-
-  detype = getSpec (operandType (IC_LEFT (ic)));
-
-#if 0 // why should we do this here??? jwk20011105
-  if (detype &&
-      (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
-      IS_ISR (currFunc->etype) &&
-      !ic->bankSaved)
-    saveRBank (SPEC_BANK (detype), ic, TRUE);
-#endif
-
 }
+
 /*-----------------------------------------------------------------*/
 /* unsaveRegisters - pop the pushed registers                      */
 /*-----------------------------------------------------------------*/
 static void
 unsaveRegisters (iCode * ic)
 {
-  int i;
   bitVect *rsave;
-  /* find the registers in use at this time
-     and push them away to safety */
-  rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
-                        ic->rUsed);
-
-  if (options.useXstack)
-    {
-      emitcode ("mov", "r0,%s", spname);
-      for (i = ds390_nRegs; i >= 0; i--)
-       {
-         if (bitVectBitValue (rsave, i))
-           {
-             emitcode ("dec", "r0");
-             emitcode ("movx", "a,@r0");
-             if (i == R0_IDX)
-               emitcode ("mov", "b,a");
-             else
-               emitcode ("mov", "%s,a", ds390_regWithIdx (i)->name);
-           }
 
-       }
-      emitcode ("mov", "%s,r0", spname);
-      if (bitVectBitValue (rsave, R0_IDX))
-       emitcode ("mov", "r0,b");
-    }
-  else
-    for (i = ds390_nRegs; i >= 0; i--)
-      {
-       if (bitVectBitValue (rsave, i))
-         emitcode ("pop", "%s", ds390_regWithIdx (i)->dname);
+  if (IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) {
+      int i =0;
+      rsave = newBitVect(ic->rMask->size);
+      for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+         if (bitVectBitValue(ic->rMask,i))
+             rsave = bitVectSetBit(rsave,i);
       }
-
+      rsave = bitVectCplAnd(rsave,ds390_rUmaskForOp (IC_RESULT(ic)));
+  } else {
+    /* restore the registers in use at this time but skip the
+       ones for the result */
+    rsave = bitVectCplAnd (bitVectCopy (ic->rMask), 
+                          ds390_rUmaskForOp (IC_RESULT(ic)));
+  }
+  unsavermask(rsave);
 }
 
 
@@ -1950,7 +2167,7 @@ genIpush (iCode * ic)
     {
 
       /* and the item is spilt then do nothing */
-      if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
+      if (OP_SYMBOL (IC_LEFT (ic))->isspilt || OP_SYMBOL(IC_LEFT(ic))->dptr)
        return;
 
       aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
@@ -2022,7 +2239,7 @@ genIpop (iCode * ic)
 
 
   /* if the temp was not pushed then */
-  if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
+  if (OP_SYMBOL (IC_LEFT (ic))->isspilt || OP_SYMBOL (IC_LEFT (ic))->dptr)
     return;
 
   aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
@@ -2046,28 +2263,39 @@ static void
 unsaveRBank (int bank, iCode * ic, bool popPsw)
 {
   int i;
-  asmop *aop;
+  asmop *aop = NULL;
   regs *r = NULL;
 
+  if (options.useXstack)
+  {
+      if (!ic)
+      {
+         /* Assume r0 is available for use. */
+         r = ds390_regWithIdx (R0_IDX);;          
+      }        
+      else
+      {
+         aop = newAsmop (0);
+         r = getFreePtr (ic, &aop, FALSE);
+      }
+      emitcode ("mov", "%s,_spx", r->name);      
+  }
+  
   if (popPsw)
     {
       if (options.useXstack)
-       {
-         aop = newAsmop (0);
-         r = getFreePtr (ic, &aop, FALSE);
-
-
-         emitcode ("mov", "%s,_spx", r->name);
+      {
          emitcode ("movx", "a,@%s", r->name);
          emitcode ("mov", "psw,a");
          emitcode ("dec", "%s", r->name);
-
        }
       else
+      {
        emitcode ("pop", "psw");
+      }
     }
 
-  for (i = (ds390_nRegs - 1); i >= 0; i--)
+  for (i = 7; i >= 0; i--) /* only R7-R0 needs to be popped */
     {
       if (options.useXstack)
        {
@@ -2084,11 +2312,13 @@ unsaveRBank (int bank, iCode * ic, bool popPsw)
 
   if (options.useXstack)
     {
-
       emitcode ("mov", "_spx,%s", r->name);
-      freeAsmop (NULL, aop, ic, TRUE);
-
     }
+    
+  if (aop)
+  {
+      freeAsmop (NULL, aop, ic, TRUE);  
+  }    
 }
 
 /*-----------------------------------------------------------------*/
@@ -2098,19 +2328,25 @@ static void
 saveRBank (int bank, iCode * ic, bool pushPsw)
 {
   int i;
-  asmop *aop;
+  asmop *aop = NULL;
   regs *r = NULL;
 
   if (options.useXstack)
     {
-
-      aop = newAsmop (0);
-      r = getFreePtr (ic, &aop, FALSE);
-      emitcode ("mov", "%s,_spx", r->name);
-
+        if (!ic)
+        {
+                 /* Assume r0 is available for use. */
+                 r = ds390_regWithIdx (R0_IDX);;
+        }
+        else
+        {
+                 aop = newAsmop (0);
+                 r = getFreePtr (ic, &aop, FALSE);
+        }
+        emitcode ("mov", "%s,_spx", r->name);    
     }
 
-  for (i = 0; i < ds390_nRegs; i++)
+  for (i = 0; i < 8 ; i++) /* only R0-R7 needs saving */
     {
       if (options.useXstack)
        {
@@ -2132,16 +2368,74 @@ saveRBank (int bank, iCode * ic, bool pushPsw)
          emitcode ("movx", "@%s,a", r->name);
          emitcode ("inc", "%s", r->name);
          emitcode ("mov", "_spx,%s", r->name);
-         freeAsmop (NULL, aop, ic, TRUE);
-
        }
       else
+      {
        emitcode ("push", "psw");
+      }
 
-      emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff);
+      emitcode ("mov", "psw,#!constbyte", (bank << 3) & 0x00ff);
     }
-  ic->bankSaved = 1;
+  
+  if (aop)
+  {
+       freeAsmop (NULL, aop, ic, TRUE);
+  }    
+    
+  if (ic)
+  {  
+      ic->bankSaved = 1;
+  }
+}
+
+/*-----------------------------------------------------------------*/
+/* genSend - gen code for SEND                                    */
+/*-----------------------------------------------------------------*/
+static void genSend(set *sendSet)
+{
+    iCode *sic;
+    int sendCount = 0 ;
+    static int rb1_count = 0;
 
+    for (sic = setFirstItem (sendSet); sic;
+        sic = setNextItem (sendSet)) {     
+       int size, offset = 0;
+       
+       size=getSize(operandType(IC_LEFT(sic)));
+       D (emitcode (";", "genSend argreg = %d, size = %d ",sic->argreg,size));
+       if (sendCount == 0) { /* first parameter */
+           // we know that dpl(hxb) is the result, so
+           rb1_count = 0 ;
+           _startLazyDPSEvaluation ();
+           if (size>1) {
+               aopOp (IC_LEFT (sic), sic, FALSE, 
+                      (IS_SYMOP(IC_LEFT(sic)) && OP_SYMBOL(IC_LEFT(sic))->ruonly ? FALSE : TRUE));
+           } else {
+               aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
+           }
+           while (size--) {
+               char *l = aopGet (AOP (IC_LEFT (sic)), offset,
+                                 FALSE, FALSE, TRUE);
+               if (strcmp (l, fReturn[offset])) {
+                   emitcode ("mov", "%s,%s",
+                             fReturn[offset],
+                             l);
+               }
+               offset++;
+           }
+           _endLazyDPSEvaluation ();
+           freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+           rb1_count =0;
+       } else { /* if more parameter in registers */
+           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));
+           }
+           freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
+       }
+       sendCount++;
+    }
 }
 
 /*-----------------------------------------------------------------*/
@@ -2150,57 +2444,55 @@ saveRBank (int bank, iCode * ic, bool pushPsw)
 static void
 genCall (iCode * ic)
 {
-  sym_link *detype;
-
-  D (emitcode (";", "genCall ");
-    );
-
-  /* if send set is not empty the assign */
-  if (_G.sendSet)
-    {
-      iCode *sic;
-
-      for (sic = setFirstItem (_G.sendSet); sic;
-          sic = setNextItem (_G.sendSet))
-       {
-         int size, offset = 0;
+  sym_link *dtype;
+  bool restoreBank = FALSE;
+  bool swapBanks = FALSE;
 
-         aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
-         size = AOP_SIZE (IC_LEFT (sic));
-
-         _startLazyDPSEvaluation ();
-         while (size--)
-           {
-             char *l = aopGet (AOP (IC_LEFT (sic)), offset,
-                               FALSE, FALSE, TRUE);
-             if (strcmp (l, fReturn[offset])) {
-               genSetDPTR(0);
-               _flushLazyDPS();
-               emitcode ("mov", "%s,%s",
-                         fReturn[offset],
-                         l);
-             }
-             offset++;
-           }
-         _endLazyDPSEvaluation ();
-         freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
-       }
-      _G.sendSet = NULL;
-    }
+  D (emitcode (";", "genCall "););
 
-  /* if we are calling a function that is not using
+  /* if we are calling a not _naked function that is not using
      the same register bank then we need to save the
      destination registers on the stack */
-  detype = getSpec (operandType (IC_LEFT (ic)));
-  if (detype &&
-      (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
-      IS_ISR (currFunc->etype) &&
-      !ic->bankSaved) {
-    saveRBank (SPEC_BANK (detype), ic, TRUE);
-  } else /* no need to save if we just saved the whole bank */ {
+  dtype = operandType (IC_LEFT (ic));
+  if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) &&
+      (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) &&
+      IFFUNC_ISISR (currFunc->type))
+  {
+      if (!ic->bankSaved) 
+      {
+           /* This is unexpected; the bank should have been saved in
+            * genFunction.
+            */
+          saveRBank (FUNC_REGBANK (dtype), ic, FALSE);
+          restoreBank = TRUE;
+      }
+      swapBanks = TRUE;
+  }
+  
     /* if caller saves & we have not saved then */
     if (!ic->regsSaved)
       saveRegisters (ic);
+  
+  /* if send set is not empty the assign */
+  /* We've saved all the registers we care about;
+  * therefore, we may clobber any register not used
+  * in the calling convention (i.e. anything not in
+  * fReturn.
+  */
+  if (_G.sendSet)
+    {
+       if (IFFUNC_ISREENT(dtype)) { /* need to reverse the send set */
+           genSend(reverseSet(_G.sendSet));
+       } else {
+           genSend(_G.sendSet);
+       }
+      _G.sendSet = NULL;
+    }  
+    
+  if (swapBanks)
+  {
+        emitcode ("mov", "psw,#!constbyte", 
+           ((FUNC_REGBANK(dtype)) << 3) & 0xff);
   }
 
   /* make the call */
@@ -2208,9 +2500,16 @@ genCall (iCode * ic)
                            OP_SYMBOL (IC_LEFT (ic))->rname :
                            OP_SYMBOL (IC_LEFT (ic))->name));
 
-  /* if we need assign a result value */
-  if ((IS_ITEMP (IC_RESULT (ic)) &&
+  if (swapBanks)
+  {
+       emitcode ("mov", "psw,#!constbyte", 
+          ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff);
+  }
+
+  /* if we need assign a result value */
+  if ((IS_ITEMP (IC_RESULT (ic)) &&
        (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
+       OP_SYMBOL (IC_RESULT (ic))->accuse ||
        OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
       IS_TRUE_SYMOP (IC_RESULT (ic)))
     {
@@ -2249,30 +2548,44 @@ genCall (iCode * ic)
 
   /* adjust the stack for parameters if
      required */
-  if (ic->parmBytes)
-    {
+  if (ic->parmBytes) {
       int i;
-      if (ic->parmBytes > 3)
-       {
-         emitcode ("mov", "a,%s", spname);
-         emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
-         emitcode ("mov", "%s,a", spname);
-       }
-      else
-       for (i = 0; i < ic->parmBytes; i++)
-         emitcode ("dec", "%s", spname);
-
-    }
-
-  /* if register bank was saved then pop them */
-  if (ic->bankSaved)
-    unsaveRBank (SPEC_BANK (detype), ic, TRUE);
+      if (options.stack10bit) {
+         if (ic->parmBytes <= 10) {
+             emitcode(";","stack adjustment for parms");
+             for (i=0; i < ic->parmBytes ; i++) {
+                 emitcode("pop","acc");
+             }
+         } else {            
+             PROTECT_SP;
+             emitcode ("clr","c");
+             emitcode ("mov","a,sp");
+             emitcode ("subb","a,#!constbyte",ic->parmBytes & 0xff);
+             emitcode ("mov","sp,a");
+             emitcode ("mov","a,esp");
+             emitcode ("anl","a,#3");
+             emitcode ("subb","a,#!constbyte",(ic->parmBytes >> 8) & 0xff);
+             emitcode ("mov","esp,a");   
+             UNPROTECT_SP;
+         }
+      } else {
+         if (ic->parmBytes > 3) {
+             emitcode ("mov", "a,%s", spname);
+             emitcode ("add", "a,#!constbyte", (-ic->parmBytes) & 0xff);
+             emitcode ("mov", "%s,a", spname);
+         } else
+             for (i = 0; i < ic->parmBytes; i++)
+                 emitcode ("dec", "%s", spname);
+      }
+  }
 
   /* if we hade saved some registers then unsave them */
-  if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave))
+  if (ic->regsSaved)
     unsaveRegisters (ic);
 
-
+  /* if register bank was saved then pop them */
+  if (restoreBank)
+    unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2281,8 +2594,9 @@ genCall (iCode * ic)
 static void
 genPcall (iCode * ic)
 {
-  sym_link *detype;
+  sym_link *dtype;
   symbol *rlbl = newiTempLabel (NULL);
+  bool restoreBank=FALSE;
 
   D (emitcode (";", "genPcall ");
     );
@@ -2295,22 +2609,23 @@ genPcall (iCode * ic)
   /* if we are calling a function that is not using
      the same register bank then we need to save the
      destination registers on the stack */
-  detype = getSpec (operandType (IC_LEFT (ic)));
-  if (detype &&
-      IS_ISR (currFunc->etype) &&
-      (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)))
-    saveRBank (SPEC_BANK (detype), ic, TRUE);
-
+  dtype = operandType (IC_LEFT (ic));
+  if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) &&
+      IFFUNC_ISISR (currFunc->type) &&
+      (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype))) {
+    saveRBank (FUNC_REGBANK (dtype), ic, TRUE);
+    restoreBank=TRUE;
+  }
 
   /* push the return address on to the stack */
-  emitcode ("mov", "a,#%05d$", (rlbl->key + 100));
+  emitcode ("mov", "a,#!tlabel", (rlbl->key + 100));
   emitcode ("push", "acc");
-  emitcode ("mov", "a,#(%05d$ >> 8)", (rlbl->key + 100));
+  emitcode ("mov", "a,#!hil", (rlbl->key + 100));
   emitcode ("push", "acc");
 
   if (options.model == MODEL_FLAT24)
     {
-      emitcode ("mov", "a,#(%05d$ >> 16)", (rlbl->key + 100));
+      emitcode ("mov", "a,#!hihil", (rlbl->key + 100));
       emitcode ("push", "acc");
     }
 
@@ -2324,36 +2639,12 @@ genPcall (iCode * ic)
   /* if send set is not empty the assign */
   if (_G.sendSet)
     {
-      iCode *sic;
-
-      for (sic = setFirstItem (_G.sendSet); sic;
-          sic = setNextItem (_G.sendSet))
-       {
-         int size, offset = 0;
-
-         aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
-         size = AOP_SIZE (IC_LEFT (sic));
-         _startLazyDPSEvaluation ();
-         while (size--)
-           {
-             char *l = aopGet (AOP (IC_LEFT (sic)), offset,
-                               FALSE, FALSE, TRUE);
-             if (strcmp (l, fReturn[offset]))
-               {
-                 emitcode ("mov", "%s,%s",
-                           fReturn[offset],
-                           l);
-               }
-             offset++;
-           }
-         _endLazyDPSEvaluation ();
-         freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
-       }
-      _G.sendSet = NULL;
+       genSend(reverseSet(_G.sendSet));
+       _G.sendSet = NULL;
     }
 
   emitcode ("ret", "");
-  emitcode ("", "%05d$:", (rlbl->key + 100));
+  emitcode ("", "!tlabeldef", (rlbl->key + 100));
 
 
   /* if we need assign a result value */
@@ -2377,24 +2668,40 @@ genPcall (iCode * ic)
   if (ic->parmBytes)
     {
       int i;
-      if (ic->parmBytes > 3)
-       {
-         emitcode ("mov", "a,%s", spname);
-         emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
-         emitcode ("mov", "%s,a", spname);
-       }
-      else
-       for (i = 0; i < ic->parmBytes; i++)
-         emitcode ("dec", "%s", spname);
-
+      if (options.stack10bit) {
+         if (ic->parmBytes <= 10) {
+             emitcode(";","stack adjustment for parms");
+             for (i=0; i < ic->parmBytes ; i++) {
+                 emitcode("pop","acc");
+             }
+         } else {            
+             PROTECT_SP;
+             emitcode ("clr","c");
+             emitcode ("mov","a,sp");
+             emitcode ("subb","a,#!constbyte",ic->parmBytes & 0xff);
+             emitcode ("mov","sp,a");
+             emitcode ("mov","a,esp");
+             emitcode ("anl","a,#3");
+             emitcode ("subb","a,#!constbyte",(ic->parmBytes >> 8) & 0xff);
+             emitcode ("mov","esp,a");   
+             UNPROTECT_SP;
+         }
+      } else {
+         if (ic->parmBytes > 3) {
+             emitcode ("mov", "a,%s", spname);
+             emitcode ("add", "a,#!constbyte", (-ic->parmBytes) & 0xff);
+             emitcode ("mov", "%s,a", spname);
+         }
+         else
+             for (i = 0; i < ic->parmBytes; i++)
+                 emitcode ("dec", "%s", spname);
+         
+      }
     }
-
   /* if register bank was saved then unsave them */
-  if (detype &&
-      (SPEC_BANK (currFunc->etype) !=
-       SPEC_BANK (detype)))
-    unsaveRBank (SPEC_BANK (detype), ic, TRUE);
-
+  if (restoreBank)
+    unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE);
+  
   /* if we hade saved some registers then
      unsave them */
   if (ic->regsSaved)
@@ -2455,10 +2762,10 @@ static void
 genFunction (iCode * ic)
 {
   symbol *sym;
-  sym_link *fetype;
+  sym_link *ftype;
+  bool   switchedPSW = FALSE;
 
-  D (emitcode (";", "genFunction ");
-    );
+  D (emitcode (";", "genFunction "););
 
   _G.nRegsSaved = 0;
   /* create the function header */
@@ -2467,38 +2774,47 @@ genFunction (iCode * ic)
   emitcode (";", "-----------------------------------------");
 
   emitcode ("", "%s:", sym->rname);
-  fetype = getSpec (operandType (IC_LEFT (ic)));
+  ftype = operandType (IC_LEFT (ic));
 
+  if (IFFUNC_ISNAKED(ftype))
+  {
+      emitcode(";", "naked function: no prologue.");
+      return;
+  }
+  
+  if (options.stack_probe) 
+      emitcode ("lcall","__stack_probe");
   /* if critical function then turn interrupts off */
-  if (SPEC_CRTCL (fetype))
+  if (IFFUNC_ISCRITICAL (ftype))
     emitcode ("clr", "ea");
 
   /* here we need to generate the equates for the
      register bank if required */
-  if (SPEC_BANK (fetype) != rbank)
+  if (FUNC_REGBANK (ftype) != rbank)
     {
       int i;
 
-      rbank = SPEC_BANK (fetype);
+      rbank = FUNC_REGBANK (ftype);
       for (i = 0; i < ds390_nRegs; i++)
        {
-         if (strcmp (regs390[i].base, "0") == 0)
-           emitcode ("", "%s = 0x%02x",
-                     regs390[i].dname,
-                     8 * rbank + regs390[i].offset);
-         else
-           emitcode ("", "%s = %s + 0x%02x",
-                     regs390[i].dname,
-                     regs390[i].base,
-                     8 * rbank + regs390[i].offset);
+         if (regs390[i].print) {
+             if (strcmp (regs390[i].base, "0") == 0)
+                 emitcode ("", "%s !equ !constbyte",
+                           regs390[i].dname,
+                           8 * rbank + regs390[i].offset);
+             else
+                 emitcode ("", "%s !equ %s + !constbyte",
+                           regs390[i].dname,
+                           regs390[i].base,
+                           8 * rbank + regs390[i].offset);
+         }
        }
     }
 
   /* if this is an interrupt service routine then
      save acc, b, dpl, dph  */
-  if (IS_ISR (sym->etype))
-    {
-
+  if (IFFUNC_ISISR (sym->type))
+      { /* is ISR */
       if (!inExcludeList ("acc"))
        emitcode ("push", "acc");
       if (!inExcludeList ("b"))
@@ -2512,7 +2828,7 @@ genFunction (iCode * ic)
          emitcode ("push", "dpx");
          /* Make sure we're using standard DPTR */
          emitcode ("push", "dps");
-         emitcode ("mov", "dps, #0x00");
+         emitcode ("mov", "dps,#0");
          if (options.stack10bit)
            {
              /* This ISR could conceivably use DPTR2. Better save it. */
@@ -2525,15 +2841,15 @@ genFunction (iCode * ic)
       /* if this isr has no bank i.e. is going to
          run with bank 0 , then we need to save more
          registers :-) */
-      if (!SPEC_BANK (sym->etype))
+      if (!FUNC_REGBANK (sym->type))
        {
+           int i;
 
          /* if this function does not call any other
             function then we can be economical and
             save only those registers that are used */
-         if (!sym->hasFcall)
+         if (!IFFUNC_HASFCALL(sym->type))
            {
-             int i;
 
              /* if any registers used */
              if (sym->regsUsed)
@@ -2554,14 +2870,109 @@ genFunction (iCode * ic)
                 determines register usage so we will have to push the
                 entire bank */
              saveRBank (0, ic, FALSE);
+             if (options.parms_in_bank1) {
+                 for (i=0; i < 8 ; i++ ) {
+                     emitcode ("push","%s",rb1regs[i]);
+                 }
+             }
+           }
+       }
+       else
+       {
+           /* This ISR uses a non-zero bank.
+            *
+            * We assume that the bank is available for our
+            * exclusive use.
+            *
+            * However, if this ISR calls a function which uses some
+            * other bank, we must save that bank entirely.
+            */
+           unsigned long banksToSave = 0;
+           
+           if (IFFUNC_HASFCALL(sym->type))
+           {
+
+#define MAX_REGISTER_BANKS 4
+
+               iCode *i;
+               int ix;
+
+               for (i = ic; i; i = i->next)
+               {
+                   if (i->op == ENDFUNCTION)
+                   {
+                       /* we got to the end OK. */
+                       break;
+                   }
+                   
+                   if (i->op == CALL)
+                   {
+                       sym_link *dtype;
+                       
+                       dtype = operandType (IC_LEFT(i));
+                       if (dtype 
+                        && FUNC_REGBANK(dtype) != FUNC_REGBANK(sym->type))
+                       {
+                            /* Mark this bank for saving. */
+                            if (FUNC_REGBANK(dtype) >= MAX_REGISTER_BANKS)
+                            {
+                                werror(E_NO_SUCH_BANK, FUNC_REGBANK(dtype));
+                            }
+                            else
+                            {
+                                banksToSave |= (1 << FUNC_REGBANK(dtype));
+                            }
+                            
+                            /* And note that we don't need to do it in 
+                             * genCall.
+                             */
+                            i->bankSaved = 1;
+                       }
+                   }
+                   if (i->op == PCALL)
+                   {
+                       /* This is a mess; we have no idea what
+                        * register bank the called function might
+                        * use.
+                        *
+                        * The only thing I can think of to do is
+                        * throw a warning and hope.
+                        */
+                       werror(W_FUNCPTR_IN_USING_ISR);   
+                   }
+               }
+
+               if (banksToSave && options.useXstack)
+               {
+                   /* Since we aren't passing it an ic, 
+                    * saveRBank will assume r0 is available to abuse.
+                    *
+                    * So switch to our (trashable) bank now, so
+                    * the caller's R0 isn't trashed.
+                    */
+                   emitcode ("push", "psw");
+                   emitcode ("mov", "psw,#!constbyte", 
+                             (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
+                   switchedPSW = TRUE;
+               }
+               
+               for (ix = 0; ix < MAX_REGISTER_BANKS; ix++)
+               {
+                    if (banksToSave & (1 << ix))
+                    {
+                        saveRBank(ix, NULL, FALSE);
+                    }
+               }
            }
+           // jwk: this needs a closer look
+           SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave;
        }
     }
   else
     {
       /* if callee-save to be used for this function
          then save the registers being used in this function */
-      if (sym->calleeSave)
+      if (IFFUNC_CALLEESAVES(sym->type))
        {
          int i;
 
@@ -2583,56 +2994,75 @@ genFunction (iCode * ic)
     }
 
   /* set the register bank to the desired value */
-  if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
+  if ((FUNC_REGBANK (sym->type) || FUNC_ISISR (sym->type))
+   && !switchedPSW)
     {
       emitcode ("push", "psw");
-      emitcode ("mov", "psw,#0x%02x", (SPEC_BANK (sym->etype) << 3) & 0x00ff);
-    }
-
-  if (IS_RENT (sym->etype) || options.stackAuto)
-    {
-
-      if (options.useXstack)
-       {
-         emitcode ("mov", "r0,%s", spname);
-         emitcode ("mov", "a,_bp");
-         emitcode ("movx", "@r0,a");
-         emitcode ("inc", "%s", spname);
-       }
-      else
-       {
-         /* set up the stack */
-         emitcode ("push", "_bp");     /* save the callers stack  */
-       }
-      emitcode ("mov", "_bp,%s", spname);
-    }
+      emitcode ("mov", "psw,#!constbyte", (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
+    }
+
+  if ( (IFFUNC_ISREENT (sym->type) || options.stackAuto) &&
+       (sym->stack || FUNC_HASSTACKPARM(sym->type))) {
+      if (options.stack10bit) {
+         emitcode ("push","_bpx");
+         emitcode ("push","_bpx+1");
+         emitcode ("mov","_bpx,%s",spname);
+         emitcode ("mov","_bpx+1,esp");
+         emitcode ("anl","_bpx+1,#3");
+      } else {
+         if (options.useXstack) {
+             emitcode ("mov", "r0,%s", spname);
+             emitcode ("mov", "a,_bp");
+             emitcode ("movx", "@r0,a");
+             emitcode ("inc", "%s", spname);
+         } else {
+             /* set up the stack */
+             emitcode ("push", "_bp"); /* save the callers stack  */
+         }
+         emitcode ("mov", "_bp,%s", spname);
+      }
+  }
 
   /* adjust the stack for the function */
-  if (sym->stack)
-    {
-
+  if (sym->stack) {
       int i = sym->stack;
-      if (i > 256)
-       werror (W_STACK_OVERFLOW, sym->name);
-
-      if (i > 3 && sym->recvSize < 4)
-       {
-
-         emitcode ("mov", "a,sp");
-         emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
-         emitcode ("mov", "sp,a");
-
-       }
-      else
-       while (i--)
-         emitcode ("inc", "sp");
-    }
+      if (options.stack10bit) {
+         if ( i > 1024) werror (W_STACK_OVERFLOW, sym->name);    
+         assert (sym->recvSize <= 4);
+         if (sym->stack <= 8) {
+             while (i--) emitcode ("push","acc");
+         } else {
+             PROTECT_SP;
+             emitcode ("mov","a,sp");
+             emitcode ("add","a,#!constbyte", ((short) sym->stack & 0xff));
+             emitcode ("mov","sp,a");
+             emitcode ("mov","a,esp");
+             emitcode ("anl","a,#3");
+             emitcode ("addc","a,#!constbyte", (((short) sym->stack) >> 8) & 0xff);
+             emitcode ("mov","esp,a");
+             UNPROTECT_SP;
+         }
+      } else {
+         if (i > 256)
+             werror (W_STACK_OVERFLOW, sym->name);
+         
+         if (i > 3 && sym->recvSize < 4) {
+             
+             emitcode ("mov", "a,sp");
+             emitcode ("add", "a,#!constbyte", ((char) sym->stack & 0xff));
+             emitcode ("mov", "sp,a");
+             
+         } else
+             while (i--)
+                 emitcode ("inc", "sp");
+      }
+  }
 
   if (sym->xstack)
     {
 
       emitcode ("mov", "a,_spx");
-      emitcode ("add", "a,#0x%02x", ((char) sym->xstack & 0xff));
+      emitcode ("add", "a,#!constbyte", ((char) sym->xstack & 0xff));
       emitcode ("mov", "_spx,a");
     }
 
@@ -2646,60 +3076,83 @@ genEndFunction (iCode * ic)
 {
   symbol *sym = OP_SYMBOL (IC_LEFT (ic));
 
-  D (emitcode (";", "genEndFunction ");
-    );
+  D (emitcode (";", "genEndFunction "););
 
-  if (IS_RENT (sym->etype) || options.stackAuto)
-    {
-      emitcode ("mov", "%s,_bp", spname);
-    }
+  if (IFFUNC_ISNAKED(sym->type))
+  {
+      emitcode(";", "naked function: no epilogue.");
+      return;
+  }
+
+  if ((IFFUNC_ISREENT (sym->type) || options.stackAuto) &&
+       (sym->stack || FUNC_HASSTACKPARM(sym->type))) {
+
+      if (options.stack10bit) {
+         PROTECT_SP;     
+         emitcode ("mov", "sp,_bpx", spname);
+         emitcode ("mov", "esp,_bpx+1", spname);
+         UNPROTECT_SP;
+      } else {
+         emitcode ("mov", "%s,_bp", spname);
+      }
+  }
 
   /* if use external stack but some variables were
      added to the local stack then decrement the
      local stack */
-  if (options.useXstack && sym->stack)
-    {
+  if (options.useXstack && sym->stack) {
       emitcode ("mov", "a,sp");
-      emitcode ("add", "a,#0x%02x", ((char) -sym->stack) & 0xff);
+      emitcode ("add", "a,#!constbyte", ((char) -sym->stack) & 0xff);
       emitcode ("mov", "sp,a");
-    }
+  }
 
 
-  if ((IS_RENT (sym->etype) || options.stackAuto))
-    {
-      if (options.useXstack)
-       {
+  if ((IFFUNC_ISREENT (sym->type) || options.stackAuto) &&
+       (sym->stack || FUNC_HASSTACKPARM(sym->type))) {
+
+      if (options.useXstack) {
          emitcode ("mov", "r0,%s", spname);
          emitcode ("movx", "a,@r0");
          emitcode ("mov", "_bp,a");
          emitcode ("dec", "%s", spname);
-       }
-      else
-       {
-         emitcode ("pop", "_bp");
-       }
-    }
+      } else {
+         if (options.stack10bit) {
+             emitcode ("pop", "_bpx+1");
+             emitcode ("pop", "_bpx");
+         } else {
+             emitcode ("pop", "_bp");
+         }
+      }
+  }
 
   /* restore the register bank  */
-  if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
-    emitcode ("pop", "psw");
-
-  if (IS_ISR (sym->etype))
+  if (FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type))
+  {
+    if (!FUNC_REGBANK (sym->type) || !IFFUNC_ISISR (sym->type)
+     || !options.useXstack)
     {
+        /* Special case of ISR using non-zero bank with useXstack
+         * is handled below.
+         */
+        emitcode ("pop", "psw");
+    }
+  } 
+
+  if (IFFUNC_ISISR (sym->type))
+      { /* is ISR */  
 
       /* now we need to restore the registers */
       /* if this isr has no bank i.e. is going to
          run with bank 0 , then we need to save more
          registers :-) */
-      if (!SPEC_BANK (sym->etype))
+      if (!FUNC_REGBANK (sym->type))
        {
-
+           int i;
          /* if this function does not call any other
             function then we can be economical and
             save only those registers that are used */
-         if (!sym->hasFcall)
+         if (!IFFUNC_HASFCALL(sym->type))
            {
-             int i;
 
              /* if any registers used */
              if (sym->regsUsed)
@@ -2719,9 +3172,41 @@ genEndFunction (iCode * ic)
              /* this function has  a function call cannot
                 determines register usage so we will have to pop the
                 entire bank */
+             if (options.parms_in_bank1) {
+                 for (i = 7 ; i >= 0 ; i-- ) {
+                     emitcode ("pop","%s",rb1regs[i]);
+                 }
+             }
              unsaveRBank (0, ic, FALSE);
            }
        }
+       else
+       {
+           /* This ISR uses a non-zero bank.
+            *
+            * Restore any register banks saved by genFunction
+            * in reverse order.
+            */
+         // jwk: this needs a closer look
+           unsigned savedBanks = SPEC_ISR_SAVED_BANKS(currFunc->etype);
+           int ix;
+         
+           for (ix = MAX_REGISTER_BANKS - 1; ix >= 0; ix--)
+           {
+               if (savedBanks & (1 << ix))
+               {
+                   unsaveRBank(ix, NULL, FALSE);
+               }
+           }
+           
+           if (options.useXstack)
+           {
+               /* Restore bank AFTER calling unsaveRBank,
+                * since it can trash r0.
+                */
+               emitcode ("pop", "psw");
+           }
+       }
 
       if (options.model == MODEL_FLAT24 && !inExcludeList ("dpx"))
        {
@@ -2744,13 +3229,11 @@ genEndFunction (iCode * ic)
       if (!inExcludeList ("acc"))
        emitcode ("pop", "acc");
 
-      if (SPEC_CRTCL (sym->etype))
+      if (IFFUNC_ISCRITICAL (sym->type))
        emitcode ("setb", "ea");
 
       /* if debug then send end of function */
-/*  if (options.debug && currFunc) { */
-      if (currFunc)
-       {
+      if (options.debug && currFunc) {
          _G.debugLine = 1;
          emitcode ("", "C$%s$%d$%d$%d ==.",
                    FileBaseName (ic->filename), currFunc->lastLine,
@@ -2766,10 +3249,10 @@ genEndFunction (iCode * ic)
     }
   else
     {
-      if (SPEC_CRTCL (sym->etype))
+      if (IFFUNC_ISCRITICAL (sym->type))
        emitcode ("setb", "ea");
 
-      if (sym->calleeSave)
+      if (IFFUNC_CALLEESAVES(sym->type))
        {
          int i;
 
@@ -2788,7 +3271,7 @@ genEndFunction (iCode * ic)
        }
 
       /* if debug then send end of function */
-      if (currFunc)
+      if (options.debug && currFunc)
        {
          _G.debugLine = 1;
          emitcode ("", "C$%s$%d$%d$%d ==.",
@@ -2806,6 +3289,37 @@ genEndFunction (iCode * ic)
 
 }
 
+/*-----------------------------------------------------------------*/
+/* genJavaNativeRet - generate code for return JavaNative          */
+/*-----------------------------------------------------------------*/
+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));
+    size = AOP_SIZE (IC_LEFT (ic));
+
+    assert (size <= 4);
+
+    /* it is assigned to GPR0-R3 then push them */
+    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));     
+       }
+       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));
+    }
+    for (i = size ; i < 4 ; i++ )
+           emitcode ("mov","%s,#0",javaRet[i]);
+    return;
+}
+
 /*-----------------------------------------------------------------*/
 /* genRet - generate code for return statement                     */
 /*-----------------------------------------------------------------*/
@@ -2822,9 +3336,16 @@ genRet (iCode * ic)
   if (!IC_LEFT (ic))
     goto jumpret;
 
+  /* if this is a JavaNative function then return 
+     value in different register */
+  if (IFFUNC_ISJAVANATIVE(currFunc->type)) {
+      genJavaNativeRet(ic);
+      goto jumpret;
+  }
   /* we have something to return then
      move the return value into place */
-  aopOp (IC_LEFT (ic), ic, FALSE, TRUE);
+  aopOp (IC_LEFT (ic), ic, FALSE, 
+        (IS_SYMOP(IC_LEFT(ic)) && OP_SYMBOL(IC_LEFT(ic))->ruonly ? FALSE :TRUE));
   size = AOP_SIZE (IC_LEFT (ic));
 
   _startLazyDPSEvaluation ();
@@ -2870,7 +3391,7 @@ jumpret:
   if (!(ic->next && ic->next->op == LABEL &&
        IC_LABEL (ic->next) == returnLabel))
 
-    emitcode ("ljmp", "%05d$", (returnLabel->key + 100));
+    emitcode ("ljmp", "!tlabel", (returnLabel->key + 100));
 
 }
 
@@ -2887,7 +3408,7 @@ genLabel (iCode * ic)
   D (emitcode (";", "genLabel ");
     );
 
-  emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
+  emitcode ("", "!tlabeldef", (IC_LABEL (ic)->key + 100));
 }
 
 /*-----------------------------------------------------------------*/
@@ -2898,7 +3419,7 @@ genGoto (iCode * ic)
 {
   D (emitcode (";", "genGoto ");
     );
-  emitcode ("ljmp", "%05d$", (IC_LABEL (ic)->key + 100));
+  emitcode ("ljmp", "!tlabel", (IC_LABEL (ic)->key + 100));
 }
 
 /*-----------------------------------------------------------------*/
@@ -2917,6 +3438,13 @@ findLabelBackwards (iCode * ic, int key)
       ic = ic->prev;
       count++;
 
+      /* If we have any pushes or pops, we cannot predict the distance.
+        I don't like this at all, this should be dealt with in the 
+        back-end */
+      if (ic->op == IPUSH || ic->op == IPOP) {
+       return 0;
+      }
+
       if (ic->op == LABEL && IC_LABEL (ic)->key == key)
        {
          /* printf("findLabelBackwards = %d\n", count); */
@@ -2947,6 +3475,13 @@ genPlusIncr (iCode * ic)
   if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
     return FALSE;
 
+  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));
+      }
+      return TRUE;
+  }
   /* if increment 16 bits in register */
   if (
        AOP_TYPE (IC_LEFT (ic)) == AOP_REG &&
@@ -2979,13 +3514,13 @@ genPlusIncr (iCode * ic)
       emitcode ("inc", "%s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE));
       if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
          IS_AOP_PREG (IC_RESULT (ic)))
-       emitcode ("cjne", "%s,#0x00,%05d$"
+       emitcode ("cjne", "%s,#0,!tlabel"
                  ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
                  ,tlbl->key + 100);
       else
        {
          emitcode ("clr", "a");
-         emitcode ("cjne", "a,%s,%05d$"
+         emitcode ("cjne", "a,%s,!tlabel"
                    ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
                    ,tlbl->key + 100);
        }
@@ -2995,11 +3530,11 @@ genPlusIncr (iCode * ic)
        {
          if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
              IS_AOP_PREG (IC_RESULT (ic)))
-           emitcode ("cjne", "%s,#0x00,%05d$"
+           emitcode ("cjne", "%s,#0,!tlabel"
                  ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
                      ,tlbl->key + 100);
          else
-           emitcode ("cjne", "a,%s,%05d$"
+           emitcode ("cjne", "a,%s,!tlabel"
                  ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
                      ,tlbl->key + 100);
 
@@ -3009,12 +3544,12 @@ genPlusIncr (iCode * ic)
        {
          if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
              IS_AOP_PREG (IC_RESULT (ic)))
-           emitcode ("cjne", "%s,#0x00,%05d$"
+           emitcode ("cjne", "%s,#0,!tlabel"
                  ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
                      ,tlbl->key + 100);
          else
            {
-             emitcode ("cjne", "a,%s,%05d$"
+             emitcode ("cjne", "a,%s,!tlabel"
                  ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
                        ,tlbl->key + 100);
            }
@@ -3023,11 +3558,37 @@ genPlusIncr (iCode * ic)
 
       if (emitTlbl)
        {
-         emitcode ("", "%05d$:", tlbl->key + 100);
+         emitcode ("", "!tlabeldef", tlbl->key + 100);
        }
       return TRUE;
     }
 
+  if (AOP_TYPE(IC_RESULT(ic))==AOP_STR && IS_ITEMP(IC_RESULT(ic)) &&
+      !AOP_USESDPTR(IC_LEFT(ic)) && icount <= 5 && size <= 3 && 
+      options.model == MODEL_FLAT24 ) {
+
+      switch (size) {
+      case 3:
+         emitcode ("mov","dpx,%s",aopGet(AOP (IC_LEFT (ic)), 2, FALSE, FALSE, FALSE));
+      case 2:
+         emitcode ("mov","dph,%s",aopGet(AOP (IC_LEFT (ic)), 1, FALSE, FALSE, FALSE));
+      case 1:
+         emitcode ("mov","dpl,%s",aopGet(AOP (IC_LEFT (ic)), 0, FALSE, FALSE, FALSE));
+         break;
+      }
+      while (icount--) emitcode ("inc","dptr");      
+      return TRUE;
+  }
+
+  if (AOP_INDPTRn(IC_LEFT(ic)) && AOP_INDPTRn(IC_RESULT(ic)) &&
+      AOP(IC_LEFT(ic))->aopu.dptr == AOP(IC_RESULT(ic))->aopu.dptr &&
+      icount <= 5 ) {
+      emitcode ("mov","dps,#!constbyte",AOP(IC_LEFT(ic))->aopu.dptr);
+      while (icount--) emitcode ("inc","dptr");
+      emitcode ("mov","dps,#0");
+      return TRUE;
+  }
+
   /* if the sizes are greater than 1 then we cannot */
   if (AOP_SIZE (IC_RESULT (ic)) > 1 ||
       AOP_SIZE (IC_LEFT (ic)) > 1)
@@ -3045,7 +3606,7 @@ genPlusIncr (iCode * ic)
       if (icount > 3)
        {
          MOVA (aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE, TRUE));
-         emitcode ("add", "a,#0x%02x", ((char) icount) & 0xff);
+         emitcode ("add", "a,#!constbyte", ((char) icount) & 0xff);
          aopPut (AOP (IC_RESULT (ic)), "a", 0);
        }
       else
@@ -3079,9 +3640,9 @@ outBitAcc (operand * result)
     }
   else
     {
-      emitcode ("jz", "%05d$", tlbl->key + 100);
+      emitcode ("jz", "!tlabel", tlbl->key + 100);
       emitcode ("mov", "a,%s", one);
-      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("", "!tlabeldef", tlbl->key + 100);
       outAcc (result);
     }
 }
@@ -3098,9 +3659,9 @@ genPlusBits (iCode * ic)
     {
       symbol *lbl = newiTempLabel (NULL);
       emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
-      emitcode ("jnb", "%s,%05d$", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100));
+      emitcode ("jnb", "%s,!tlabel", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100));
       emitcode ("cpl", "c");
-      emitcode ("", "%05d$:", (lbl->key + 100));
+      emitcode ("", "!tlabeldef", (lbl->key + 100));
       outBitC (IC_RESULT (ic));
     }
   else
@@ -3109,7 +3670,7 @@ genPlusBits (iCode * ic)
       emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
       emitcode ("rlc", "a");
       emitcode ("mov", "c,%s", AOP (IC_RIGHT (ic))->aopu.aop_dir);
-      emitcode ("addc", "a,#0x00");
+      emitcode ("addc", "a,#0");
       outAcc (IC_RESULT (ic));
     }
 }
@@ -3147,30 +3708,17 @@ adjustArithmeticResult (iCode * ic)
     }
 }
 
-// Macro to aopOp all three operands of an ic. Will fatal if this cannot be done
-// (because all three operands are in far space).
-#define AOP_OP_3(ic) \
-    aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
-    aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
-    aopOp (IC_RESULT(ic),ic,TRUE, (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) || \
-              (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
-    if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \
-        AOP_TYPE(IC_RESULT(ic)) == AOP_DPTR2) \
-    { \
-        /* werror(E_INTERNAL_ERROR,__FILE__,__LINE__, */ \
-        fprintf(stderr,                                  \
-               "Ack: three operands in far space! (%s:%d %s:%d)\n", __FILE__, __LINE__, ic->filename, ic->lineno);   \
-    }
-
+#ifdef KEVIN_SCREWED_UP
 // 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)); \
+    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))) \
+        (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; \
@@ -3194,6 +3742,88 @@ adjustArithmeticResult (iCode * ic)
     aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
     aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR));
 
+#else // Kevin didn't screw up...
+
+#define AOP_IS_STR(x) (IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
+
+// 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;
+    
+    // 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");
+//      );
+    
+    aopOp (IC_RIGHT(ic),ic,FALSE, AOP_IS_STR(IC_LEFT(ic)) || AOP_IS_STR(IC_RESULT(ic)));
+    
+    // Now, the left opcode. This can use DPTR if the right didn't AND the result is not
+    // AOP_STR (however, if the result is the same operand as the left, then DPTR may be used).
+    aopOp (IC_LEFT(ic),ic,FALSE, AOP_USESDPTR(IC_RIGHT(ic)) ||
+                                  (AOP_IS_STR(IC_RESULT(ic)) && !isOperandEqual(IC_LEFT(ic),IC_RESULT(ic))));
+    
+    // We've op'd the left. So, if left & result are the same operand, we know aopOp
+    // will succeed, and we can just do it & bail.
+    if (isOperandEqual(IC_LEFT(ic),IC_RESULT(ic)))
+    {
+//     D(emitcode(";", "aopOp3: left & result equal"););
+       aopOp(IC_RESULT(ic),ic,TRUE, FALSE);
+       return TRUE;
+    }
+    
+    // Note which dptrs are currently in use.
+    dp1InUse = (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR) || (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) ||
+               AOP_IS_STR(IC_RIGHT(ic)) || AOP_IS_STR(IC_LEFT(ic));
+    dp2InUse = (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR2) || (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2);
+    
+    // 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;
+    }
+    
+    // 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 (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 &&
+       AOP_TYPE(IC_RESULT(ic)) == AOP_DPTR2)
+    {
+       fprintf(stderr,
+               "Ack: got unexpected DP2! (%s:%d %s:%d)\n",
+               __FILE__, __LINE__, ic->filename, ic->lineno);  
+    }
+       
+    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) \
+           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, AOP_IS_STR(IC_LEFT(ic))); \
+    aopOp (IC_LEFT(ic),ic,FALSE, AOP_USESDPTR(IC_RIGHT(ic)));
+
+#endif
+
 // convienience macro.
 #define AOP_SET_LOCALS(ic) \
     left = IC_LEFT(ic); \
@@ -3244,7 +3874,34 @@ genPlus (iCode * ic)
   D (emitcode (";", "genPlus "););
 
   /* special cases :- */
-
+  if ( IS_SYMOP(IC_LEFT(ic)) && OP_SYMBOL(IC_LEFT(ic))->ruonly &&
+      isOperandLiteral(IC_RIGHT(ic)) && OP_SYMBOL(IC_RESULT(ic))->ruonly) {
+      aopOp (IC_RIGHT (ic), ic, TRUE, FALSE);
+      size = floatFromVal (AOP (IC_RIGHT(ic))->aopu.aop_lit);
+      if (size <= 9) {
+         while (size--) emitcode ("inc","dptr");
+      } else {
+         emitcode ("mov","a,dpl");
+         emitcode ("add","a,#!constbyte",size & 0xff);
+         emitcode ("mov","dpl,a");
+         emitcode ("mov","a,dph");
+         emitcode ("addc","a,#!constbyte",(size >> 8) & 0xff);
+         emitcode ("mov","dph,a");
+         emitcode ("mov","a,dpx");
+         emitcode ("addc","a,#!constbyte",(size >> 16) & 0xff);
+         emitcode ("mov","dpx,a");
+      }
+      freeAsmop (IC_RIGHT (ic), NULL, ic, FALSE);
+      return ;
+  }
+  if ( IS_SYMOP(IC_LEFT(ic)) && 
+       OP_SYMBOL(IC_LEFT(ic))->remat &&
+       isOperandInFarSpace(IC_RIGHT(ic))) {
+      operand *op = IC_RIGHT(ic);
+      IC_RIGHT(ic) = IC_LEFT(ic);
+      IC_LEFT(ic) = op;
+  }
+               
   AOP_OP_3_NOFATAL (ic, pushResult);
   if (pushResult)
     {
@@ -3294,7 +3951,7 @@ genPlus (iCode * ic)
              while (size--)
                {
                  MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, TRUE));
-                 emitcode ("addc", "a,#00");
+                 emitcode ("addc", "a,#0");
                  aopPut (AOP (IC_RESULT (ic)), "a", offset++);
                }
              _endLazyDPSEvaluation ();
@@ -3316,7 +3973,7 @@ genPlus (iCode * ic)
   _startLazyDPSEvaluation ();
   while (size--)
     {
-      if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC)
+      if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC && !AOP_NEEDSACC(IC_RIGHT(ic)))
        {
          MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, TRUE));
          if (offset == 0)
@@ -3328,13 +3985,35 @@ genPlus (iCode * ic)
        }
       else
        {
+         if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC && (offset == 0))
+         {
+             /* right is going to use ACC or we would have taken the
+              * above branch.
+              */
+             assert(AOP_NEEDSACC(IC_RIGHT(ic)));
+       TR_AP("#3");
+             D(emitcode(";", "+ AOP_ACC special case."););
+             emitcode("xch", "a, %s", DP2_RESULT_REG);
+         }
          MOVA (aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, TRUE));
          if (offset == 0)
-           emitcode ("add", "a,%s",
-                 aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, FALSE));
+         {
+           if (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC)
+           {
+         TR_AP("#4");
+               emitcode("add", "a, %s", DP2_RESULT_REG); 
+           }
+           else
+           {
+               emitcode ("add", "a,%s",
+                       aopGet (AOP(IC_LEFT(ic)), offset, FALSE, FALSE, FALSE));
+           }
+          }
          else
+         {
            emitcode ("addc", "a,%s",
                  aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, FALSE));
+         }
        }
       if (!pushResult)
        {
@@ -3394,6 +4073,13 @@ genMinusDec (iCode * ic)
   if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
     return FALSE;
 
+  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));
+      }
+      return TRUE;
+  }
   /* if decrement 16 bits in register */
   if (AOP_TYPE (IC_LEFT (ic)) == AOP_REG &&
       AOP_TYPE (IC_RESULT (ic)) == AOP_REG &&
@@ -3427,13 +4113,13 @@ genMinusDec (iCode * ic)
       if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
          AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
          IS_AOP_PREG (IC_RESULT (ic)))
-       emitcode ("cjne", "%s,#0xff,%05d$"
-                 ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
+       emitcode ("cjne", "%s,#!constbyte,!tlabel"
+                 ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE), 0xff
                  ,tlbl->key + 100);
       else
        {
-         emitcode ("mov", "a,#0xff");
-         emitcode ("cjne", "a,%s,%05d$"
+         emitcode ("mov", "a,#!constbyte",0xff);
+         emitcode ("cjne", "a,%s,!tlabel"
                    ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
                    ,tlbl->key + 100);
        }
@@ -3443,12 +4129,12 @@ genMinusDec (iCode * ic)
          if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
              AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
              IS_AOP_PREG (IC_RESULT (ic)))
-           emitcode ("cjne", "%s,#0xff,%05d$"
-                 ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
+           emitcode ("cjne", "%s,#!constbyte,!tlabel"
+                     ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE),0xff
                      ,tlbl->key + 100);
          else
            {
-             emitcode ("cjne", "a,%s,%05d$"
+             emitcode ("cjne", "a,%s,!tlabel"
                  ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
                        ,tlbl->key + 100);
            }
@@ -3459,12 +4145,12 @@ genMinusDec (iCode * ic)
          if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
              AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
              IS_AOP_PREG (IC_RESULT (ic)))
-           emitcode ("cjne", "%s,#0xff,%05d$"
-                 ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
+           emitcode ("cjne", "%s,#!constbyte,!tlabel"
+                     ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE),0xff
                      ,tlbl->key + 100);
          else
            {
-             emitcode ("cjne", "a,%s,%05d$"
+             emitcode ("cjne", "a,%s,!tlabel"
                  ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
                        ,tlbl->key + 100);
            }
@@ -3472,7 +4158,7 @@ genMinusDec (iCode * ic)
        }
       if (emitTlbl)
        {
-         emitcode ("", "%05d$:", tlbl->key + 100);
+         emitcode ("", "!tlabeldef", tlbl->key + 100);
        }
       return TRUE;
     }
@@ -3547,18 +4233,18 @@ genMinusBits (iCode * ic)
   if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
     {
       emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
-      emitcode ("jnb", "%s,%05d$", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100));
+      emitcode ("jnb", "%s,!tlabel", AOP (IC_RIGHT (ic))->aopu.aop_dir, (lbl->key + 100));
       emitcode ("cpl", "c");
-      emitcode ("", "%05d$:", (lbl->key + 100));
+      emitcode ("", "!tlabeldef", (lbl->key + 100));
       outBitC (IC_RESULT (ic));
     }
   else
     {
       emitcode ("mov", "c,%s", AOP (IC_RIGHT (ic))->aopu.aop_dir);
       emitcode ("subb", "a,acc");
-      emitcode ("jnb", "%s,%05d$", AOP (IC_LEFT (ic))->aopu.aop_dir, (lbl->key + 100));
+      emitcode ("jnb", "%s,!tlabel", AOP (IC_LEFT (ic))->aopu.aop_dir, (lbl->key + 100));
       emitcode ("inc", "a");
-      emitcode ("", "%05d$:", (lbl->key + 100));
+      emitcode ("", "!tlabeldef", (lbl->key + 100));
       aopPut (AOP (IC_RESULT (ic)), "a", 0);
       addSign (IC_RESULT (ic), MSB16, SPEC_USIGN (getSpec (operandType (IC_RESULT (ic)))));
     }
@@ -3578,9 +4264,11 @@ genMinus (iCode * ic)
   D (emitcode (";", "genMinus "););
 
   aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
-  aopOp (IC_RIGHT (ic), ic, FALSE, TRUE);
+  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))
+      ((AOP_TYPE (IC_RIGHT (ic)) == AOP_DPTR2)
+       || OP_SYMBOL(IC_RESULT(ic))->ruonly))
     {
       pushResult = TRUE;
     }
@@ -3619,35 +4307,42 @@ genMinus (iCode * ic)
 
   /* if literal, add a,#-lit, else normal subb */
   _startLazyDPSEvaluation ();
-  while (size--)
-    {
+  while (size--) {
       MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, TRUE));
-      if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
-       emitcode ("subb", "a,%s",
-                 aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, FALSE));
-      else
-       {
+      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 ("subb","a,b");
+         } else {
+             emitcode ("subb", "a,%s",
+                       aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, FALSE));
+         }
+      } else {
          /* first add without previous c */
-         if (!offset)
-           emitcode ("add", "a,#0x%02x",
-                     (unsigned int) (lit & 0x0FFL));
-         else
-           emitcode ("addc", "a,#0x%02x",
-                     (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
-       }
-
-      if (pushResult)
-       {
+         if (!offset) {
+             if (!size && lit==-1) {
+                 emitcode ("dec", "a");
+             } else {
+                 emitcode ("add", "a,#!constbyte",
+                           (unsigned int) (lit & 0x0FFL));
+             }
+         } else {
+             emitcode ("addc", "a,#!constbyte",
+                       (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
+         }
+      }
+      
+      if (pushResult) {
          emitcode ("push", "acc");
-       }
-      else
-       {
+      } else {
          aopPut (AOP (IC_RESULT (ic)), "a", offset);
-       }
+      }
       offset++;
-    }
+  }
   _endLazyDPSEvaluation ();
-
+  
   if (pushResult)
     {
       aopOp (IC_RESULT (ic), ic, TRUE, FALSE);
@@ -3681,10 +4376,12 @@ release:
 static void
 genMultbits (operand * left,
             operand * right,
-            operand * result)
+            operand * result,
+            iCode   * ic)
 {
   emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
   emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
+  aopOp(result, ic, TRUE, FALSE);
   outBitC (result);
 }
 
@@ -3695,19 +4392,12 @@ genMultbits (operand * left,
 static void
 genMultOneByte (operand * left,
                operand * right,
-               operand * result)
+               operand * result,
+               iCode   * ic)
 {
   sym_link *opetype = operandType (result);
   symbol *lbl;
-  int size=AOP_SIZE(result);
 
-  emitcode (";",__FUNCTION__);
-  if (size<1 || size>2) {
-    // this should never happen
-      fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", 
-              AOP_SIZE(result), __FUNCTION__, lineno);
-      exit (1);
-  }
 
   /* (if two literals: the value is computed before) */
   /* if one literal, literal on the right */
@@ -3728,8 +4418,22 @@ genMultOneByte (operand * left,
     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);
-    if (size==2) {
+    _G.accInUse--; _G.bInUse--;
+    if (AOP_SIZE(result)==2) 
+    {
       aopPut (AOP (result), "b", 1);
     }
     return;
@@ -3739,44 +4443,56 @@ genMultOneByte (operand * left,
 
   emitcode (";", "signed");
   emitcode ("clr", "F0"); // reset sign flag
-  emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE, TRUE));
   MOVA (aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
 
   lbl=newiTempLabel(NULL);
-  emitcode ("jnb", "acc.7,%05d$",  lbl->key+100);
+  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");
 
-  emitcode ("", "%05d$:", lbl->key+100);
-  emitcode ("xch", "a,b");
+  emitcode ("", "!tlabeldef", lbl->key+100);
 
   /* if literal */
   if (AOP_TYPE(right)==AOP_LIT) {
+    signed char val=floatFromVal (AOP (right)->aopu.aop_lit);
     /* AND literal negative */
-    if ((int) floatFromVal (AOP (right)->aopu.aop_lit) < 0) {
-      // two's complement for literal<0
-      emitcode ("xrl", "PSW,#0x20"); // xrl sign flag
-      emitcode ("cpl", "a");
-      emitcode ("inc", "a");
+    if ((int) val < 0) {
+      emitcode ("cpl", "F0"); // complement sign flag
+      emitcode ("mov", "b,#!constbyte", -val);
+    } else {
+      emitcode ("mov", "b,#!constbyte", val);
     }
   } else {
     lbl=newiTempLabel(NULL);
-    emitcode ("jnb", "acc.7,%05d$", lbl->key+100);
+    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 ("xrl", "PSW,#0x20"); // xrl sign flag
+    emitcode ("cpl", "F0"); // complement sign flag
     emitcode ("cpl", "a");
     emitcode ("inc", "a");
-    emitcode ("", "%05d$:", lbl->key+100);
+    emitcode ("", "!tlabeldef", lbl->key+100);
   }
   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);
+  }    
+    
   lbl=newiTempLabel(NULL);
-  emitcode ("jnb", "F0,%05d$", lbl->key+100);
+  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 (size==1) {
+  if (AOP_SIZE(result)==1) {
     emitcode ("inc", "a");
   } else {
     emitcode ("add", "a,#1");
@@ -3786,13 +4502,174 @@ genMultOneByte (operand * left,
     emitcode ("xch", "a,b");
   }
 
-  emitcode ("", "%05d$:", lbl->key+100);
+  emitcode ("", "!tlabeldef", lbl->key+100);
   aopPut (AOP (result), "a", 0);
-  if (size==2) {
+  _G.accInUse--;_G.bInUse--;
+  if (AOP_SIZE(result)==2) {
     aopPut (AOP (result), "b", 1);
   }
 }
 
+/*-----------------------------------------------------------------*/
+/* genMultTwoByte - use the DS390 MAC unit to do 16*16 multiply    */
+/*-----------------------------------------------------------------*/
+static void genMultTwoByte (operand *left, operand *right, 
+                           operand *result, iCode *ic)
+{
+       sym_link *retype = getSpec(operandType(right));
+       sym_link *letype = getSpec(operandType(left));
+       int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype);
+       symbol *lbl;
+
+       if (AOP_TYPE (left) == AOP_LIT) {
+               operand *t = right;
+               right = left;
+               left = t;
+       }
+       /* save EA bit in F1 */
+       lbl = newiTempLabel(NULL);
+       emitcode ("setb","F1");
+       emitcode ("jbc","EA,!tlabel",lbl->key+100);
+       emitcode ("clr","F1");
+       emitcode("","!tlabeldef",lbl->key+100);
+
+       /* load up MB with right */
+       if (!umult) {
+               emitcode("clr","F0");
+               if (AOP_TYPE(right) == AOP_LIT) {
+                       int val=floatFromVal (AOP (right)->aopu.aop_lit);
+                       if (val < 0) {
+                               emitcode("setb","F0");
+                               val = -val;
+                       }
+                       emitcode ("mov","mb,#!constbyte",val & 0xff);
+                       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 ("jnb","acc.7,!tlabel",lbl->key+100);          
+                       emitcode ("xch", "a,b");
+                       emitcode ("cpl","a");
+                       emitcode ("add", "a,#1");
+                       emitcode ("xch", "a,b");
+                       emitcode ("cpl", "a"); // msb
+                       emitcode ("addc", "a,#0");
+                       emitcode ("setb","F0");
+                       emitcode ("","!tlabeldef",lbl->key+100);
+                       emitcode ("mov","mb,b");
+                       emitcode ("mov","mb,a");
+               }
+       } else {
+               emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+       }
+       /* load up MA with left */
+       if (!umult) {
+               lbl = newiTempLabel(NULL);
+               emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+               emitcode ("jnb","acc.7,!tlabel",lbl->key+100);
+               emitcode ("xch", "a,b");
+               emitcode ("cpl","a");
+               emitcode ("add", "a,#1");
+               emitcode ("xch", "a,b");
+               emitcode ("cpl", "a"); // msb
+               emitcode ("addc","a,#0");
+               emitcode ("jbc","F0,!tlabel",lbl->key+100);
+               emitcode ("setb","F0");
+               emitcode ("","!tlabeldef",lbl->key+100);
+               emitcode ("mov","ma,b");
+               emitcode ("mov","ma,a");
+       } else {
+               emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+       }
+       /* wait for multiplication to finish */
+       lbl = newiTempLabel(NULL);
+       emitcode("","!tlabeldef", lbl->key+100);
+       emitcode("mov","a,mcnt1");
+       emitcode("anl","a,#!constbyte",0x80);
+       emitcode("jnz","!tlabel",lbl->key+100);
+       
+       freeAsmop (left, NULL, ic, TRUE);
+       freeAsmop (right, NULL, ic,TRUE);
+       aopOp(result, ic, TRUE, FALSE);
+
+       /* if unsigned then simple */   
+       if (umult) {
+               emitcode ("mov","a,ma");
+               if (AOP_SIZE(result) >= 4) aopPut(AOP(result),"a",3);
+               emitcode ("mov","a,ma");
+               if (AOP_SIZE(result) >= 3) aopPut(AOP(result),"a",2);
+               aopPut(AOP(result),"ma",1);
+               aopPut(AOP(result),"ma",0);
+       } else {
+               emitcode("push","ma");
+               emitcode("push","ma");
+               emitcode("push","ma");
+               MOVA("ma");
+               /* negate result if needed */
+               lbl = newiTempLabel(NULL);      
+               emitcode("jnb","F0,!tlabel",lbl->key+100);
+               emitcode("cpl","a");
+               emitcode("add","a,#1");
+               emitcode("","!tlabeldef", lbl->key+100);
+               if (AOP_TYPE(result) == AOP_ACC)
+               {
+                   D(emitcode(";", "ACC special case."););
+                   /* We know result is the only live aop, and 
+                    * it's obviously not a DPTR2, so AP is available.
+                    */
+                   emitcode("mov", "%s,acc", DP2_RESULT_REG);
+               }
+               else
+               {
+                   aopPut(AOP(result),"a",0);
+               }
+           
+               emitcode("pop","acc");
+               lbl = newiTempLabel(NULL);      
+               emitcode("jnb","F0,!tlabel",lbl->key+100);
+               emitcode("cpl","a");
+               emitcode("addc","a,#0");
+               emitcode("","!tlabeldef", lbl->key+100);
+               aopPut(AOP(result),"a",1);
+               emitcode("pop","acc");
+               if (AOP_SIZE(result) >= 3) {
+                       lbl = newiTempLabel(NULL);      
+                       emitcode("jnb","F0,!tlabel",lbl->key+100);
+                       emitcode("cpl","a");
+                       emitcode("addc","a,#0");                        
+                       emitcode("","!tlabeldef", lbl->key+100);
+                       aopPut(AOP(result),"a",2);
+               }
+               emitcode("pop","acc");
+               if (AOP_SIZE(result) >= 4) {
+                       lbl = newiTempLabel(NULL);      
+                       emitcode("jnb","F0,!tlabel",lbl->key+100);
+                       emitcode("cpl","a");
+                       emitcode("addc","a,#0");                        
+                       emitcode("","!tlabeldef", lbl->key+100);
+                       aopPut(AOP(result),"a",3);
+               }
+               if (AOP_TYPE(result) == AOP_ACC)
+               {
+                   /* We stashed the result away above. */
+                   emitcode("mov", "acc,%s", DP2_RESULT_REG);
+               }           
+               
+       }
+       freeAsmop (result, NULL, ic, TRUE);
+
+       /* restore EA bit in F1 */
+       lbl = newiTempLabel(NULL);
+       emitcode ("jnb","F1,!tlabel",lbl->key+100);
+       emitcode ("setb","EA");
+       emitcode("","!tlabeldef",lbl->key+100);
+       return ;
+}
+
 /*-----------------------------------------------------------------*/
 /* genMult - generates code for multiplication                     */
 /*-----------------------------------------------------------------*/
@@ -3806,14 +4683,14 @@ genMult (iCode * ic)
   D (emitcode (";", "genMult "););
 
   /* assign the amsops */
-  AOP_OP_3 (ic);
+  AOP_OP_2 (ic);
 
   /* special cases first */
   /* both are bits */
   if (AOP_TYPE (left) == AOP_CRY &&
       AOP_TYPE (right) == AOP_CRY)
     {
-      genMultbits (left, right, result);
+      genMultbits (left, right, result, ic);
       goto release;
     }
 
@@ -3821,12 +4698,17 @@ genMult (iCode * ic)
   if (AOP_SIZE (left) == 1 &&
       AOP_SIZE (right) == 1)
     {
-      genMultOneByte (left, right, result);
+      genMultOneByte (left, right, result, ic);
       goto release;
     }
 
+  if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) {
+         /* use the ds390 ARITHMETIC accel UNIT */
+         genMultTwoByte (left, right, result, ic);
+         return ;
+  }
   /* should have been converted to function call */
-  assert (1);
+  assert (0);
 
 release:
   freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
@@ -3840,7 +4722,8 @@ release:
 static void
 genDivbits (operand * left,
            operand * right,
-           operand * result)
+           operand * result,
+           iCode   * ic)
 {
 
   char *l;
@@ -3849,6 +4732,8 @@ genDivbits (operand * left,
   LOAD_AB_FOR_DIV (left, right, l);
   emitcode ("div", "ab");
   emitcode ("rrc", "a");
+  aopOp(result, ic, TRUE, FALSE);
+    
   aopPut (AOP (result), "c", 0);
 }
 
@@ -3858,24 +4743,33 @@ genDivbits (operand * left,
 static void
 genDivOneByte (operand * left,
               operand * right,
-              operand * result)
+              operand * result,
+              iCode   * ic)
 {
   sym_link *opetype = operandType (result);
   char *l;
   symbol *lbl;
   int size, offset;
 
-  size = AOP_SIZE (result) - 1;
   offset = 1;
   /* signed or unsigned */
   if (SPEC_USIGN (opetype))
     {
-      /* unsigned is easy */
-      LOAD_AB_FOR_DIV (left, right, l);
-      emitcode ("div", "ab");
-      aopPut (AOP (result), "a", 0);
-      while (size--)
-       aopPut (AOP (result), zero, offset++);
+       /* unsigned is easy */
+       LOAD_AB_FOR_DIV (left, right, l);
+       emitcode ("div", "ab");
+
+       _G.accInUse++;
+       aopOp(result, ic, TRUE, FALSE);
+       aopPut (AOP (result), "a", 0);
+       _G.accInUse--;
+
+       size = AOP_SIZE (result) - 1;
+       
+       while (size--)
+       {
+           aopPut (AOP (result), zero, offset++);
+       }
       return;
     }
 
@@ -3891,10 +4785,10 @@ genDivOneByte (operand * left,
   l = aopGet (AOP (right), 0, FALSE, FALSE, TRUE);
   MOVA (l);
   lbl = newiTempLabel (NULL);
-  emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
+  emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100));
   emitcode ("cpl", "a");
   emitcode ("inc", "a");
-  emitcode ("", "%05d$:", (lbl->key + 100));
+  emitcode ("", "!tlabeldef", (lbl->key + 100));
   emitcode ("mov", "b,a");
 
   /* sign adjust left side */
@@ -3902,10 +4796,10 @@ genDivOneByte (operand * left,
   MOVA (l);
 
   lbl = newiTempLabel (NULL);
-  emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
+  emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100));
   emitcode ("cpl", "a");
   emitcode ("inc", "a");
-  emitcode ("", "%05d$:", (lbl->key + 100));
+  emitcode ("", "!tlabeldef", (lbl->key + 100));
 
   /* now the division */
   emitcode ("nop", "; workaround for DS80C390 div bug.");
@@ -3917,24 +4811,150 @@ genDivOneByte (operand * left,
   emitcode ("pop", "acc");
   /* if there was an over flow we don't
      adjust the sign of the result */
-  emitcode ("jb", "ov,%05d$", (lbl->key + 100));
-  emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
+  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 ("", "%05d$:", (lbl->key + 100));
+  emitcode ("", "!tlabeldef", (lbl->key + 100));
 
   /* now we are done */
-  aopPut (AOP (result), "b", 0);
-  if (size > 0)
+  _G.accInUse++;     _G.bInUse++;
+    aopOp(result, ic, TRUE, FALSE);
+    
+    aopPut (AOP (result), "b", 0);
+    
+    size = AOP_SIZE (result) - 1;
+    
+    if (size > 0)
     {
       emitcode ("mov", "c,b.7");
       emitcode ("subb", "a,acc");
     }
-  while (size--)
-    aopPut (AOP (result), "a", offset++);
-
+    while (size--)
+    {
+       aopPut (AOP (result), "a", offset++);
+    }
+    _G.accInUse--;     _G.bInUse--;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genDivTwoByte - use the DS390 MAC unit to do 16/16 divide       */
+/*-----------------------------------------------------------------*/
+static void genDivTwoByte (operand *left, operand *right, 
+                           operand *result, iCode *ic)
+{
+       sym_link *retype = getSpec(operandType(right));
+       sym_link *letype = getSpec(operandType(left));
+       int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype);
+       symbol *lbl;
+
+       /* save EA bit in F1 */
+       lbl = newiTempLabel(NULL);
+       emitcode ("setb","F1");
+       emitcode ("jbc","EA,!tlabel",lbl->key+100);
+       emitcode ("clr","F1");
+       emitcode("","!tlabeldef",lbl->key+100);
+
+       /* load up MA with left */
+       if (!umult) {
+               emitcode("clr","F0");
+               lbl = newiTempLabel(NULL);
+               emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+               emitcode ("jnb","acc.7,!tlabel",lbl->key+100);
+               emitcode ("xch", "a,b");
+               emitcode ("cpl","a");
+               emitcode ("add", "a,#1");
+               emitcode ("xch", "a,b");
+               emitcode ("cpl", "a"); // msb
+               emitcode ("addc","a,#0");
+               emitcode ("setb","F0");
+               emitcode ("","!tlabeldef",lbl->key+100);
+               emitcode ("mov","ma,b");
+               emitcode ("mov","ma,a");
+       } else {
+               emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+       }
+
+       /* load up MB with right */
+       if (!umult) {
+               if (AOP_TYPE(right) == AOP_LIT) {
+                       int val=floatFromVal (AOP (right)->aopu.aop_lit);
+                       if (val < 0) {
+                               lbl = newiTempLabel(NULL);
+                               emitcode ("jbc","F0,!tlabel",lbl->key+100);
+                               emitcode("setb","F0");
+                               emitcode ("","!tlabeldef",lbl->key+100);
+                               val = -val;
+                       } 
+                       emitcode ("mov","mb,#!constbyte",val & 0xff);               
+                       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 ("jnb","acc.7,!tlabel",lbl->key+100);          
+                       emitcode ("xch", "a,b");
+                       emitcode ("cpl","a");
+                       emitcode ("add", "a,#1");
+                       emitcode ("xch", "a,b");
+                       emitcode ("cpl", "a"); // msb
+                       emitcode ("addc", "a,#0");
+                       emitcode ("jbc","F0,!tlabel",lbl->key+100);
+                       emitcode ("setb","F0");
+                       emitcode ("","!tlabeldef",lbl->key+100);
+                       emitcode ("mov","mb,b");
+                       emitcode ("mov","mb,a");
+               }
+       } else {
+               emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+       }
+
+       /* wait for multiplication to finish */
+       lbl = newiTempLabel(NULL);
+       emitcode("","!tlabeldef", lbl->key+100);
+       emitcode("mov","a,mcnt1");
+       emitcode("anl","a,#!constbyte",0x80);
+       emitcode("jnz","!tlabel",lbl->key+100);
+       
+       freeAsmop (left, NULL, ic, TRUE);
+       freeAsmop (right, NULL, ic,TRUE);
+       aopOp(result, ic, TRUE, FALSE);
+
+       /* if unsigned then simple */   
+       if (umult) {
+               aopPut(AOP(result),"ma",1);
+               aopPut(AOP(result),"ma",0);
+       } else {
+               emitcode("push","ma");
+               MOVA("ma");
+               /* negate result if needed */
+               lbl = newiTempLabel(NULL);      
+               emitcode("jnb","F0,!tlabel",lbl->key+100);
+               emitcode("cpl","a");
+               emitcode("add","a,#1");
+               emitcode("","!tlabeldef", lbl->key+100);
+               aopPut(AOP(result),"a",0);
+               emitcode("pop","acc");
+               lbl = newiTempLabel(NULL);      
+               emitcode("jnb","F0,!tlabel",lbl->key+100);
+               emitcode("cpl","a");
+               emitcode("addc","a,#0");
+               emitcode("","!tlabeldef", lbl->key+100);
+               aopPut(AOP(result),"a",1);
+       }
+       freeAsmop (result, NULL, ic, TRUE);
+       /* restore EA bit in F1 */
+       lbl = newiTempLabel(NULL);
+       emitcode ("jnb","F1,!tlabel",lbl->key+100);
+       emitcode ("setb","EA");
+       emitcode("","!tlabeldef",lbl->key+100);
+       return ;
 }
 
 /*-----------------------------------------------------------------*/
@@ -3947,18 +4967,17 @@ genDiv (iCode * ic)
   operand *right = IC_RIGHT (ic);
   operand *result = IC_RESULT (ic);
 
-  D (emitcode (";", "genDiv ");
-    );
+  D (emitcode (";", "genDiv "););
 
   /* assign the amsops */
-  AOP_OP_3 (ic);
+  AOP_OP_2 (ic);
 
   /* special cases first */
   /* both are bits */
   if (AOP_TYPE (left) == AOP_CRY &&
       AOP_TYPE (right) == AOP_CRY)
     {
-      genDivbits (left, right, result);
+      genDivbits (left, right, result, ic);
       goto release;
     }
 
@@ -3966,12 +4985,17 @@ genDiv (iCode * ic)
   if (AOP_SIZE (left) == 1 &&
       AOP_SIZE (right) == 1)
     {
-      genDivOneByte (left, right, result);
+      genDivOneByte (left, right, result, ic);
       goto release;
     }
 
+  if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) {
+         /* use the ds390 ARITHMETIC accel UNIT */
+         genDivTwoByte (left, right, result, ic);
+         return ;
+  }
   /* should have been converted to function call */
-  assert (1);
+  assert (0);
 release:
   freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
   freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
@@ -3984,7 +5008,8 @@ release:
 static void
 genModbits (operand * left,
            operand * right,
-           operand * result)
+           operand * result,
+           iCode   * ic)
 {
 
   char *l;
@@ -3994,6 +5019,7 @@ genModbits (operand * left,
   emitcode ("div", "ab");
   emitcode ("mov", "a,b");
   emitcode ("rrc", "a");
+  aopOp(result, ic, TRUE, FALSE);
   aopPut (AOP (result), "c", 0);
 }
 
@@ -4003,7 +5029,8 @@ genModbits (operand * left,
 static void
 genModOneByte (operand * left,
               operand * right,
-              operand * result)
+              operand * result,
+              iCode   * ic)
 {
   sym_link *opetype = operandType (result);
   char *l;
@@ -4015,6 +5042,7 @@ genModOneByte (operand * left,
       /* unsigned is easy */
       LOAD_AB_FOR_DIV (left, right, l);
       emitcode ("div", "ab");
+      aopOp(result, ic, TRUE, FALSE);  
       aopPut (AOP (result), "b", 0);
       return;
     }
@@ -4033,10 +5061,10 @@ genModOneByte (operand * left,
   MOVA (l);
 
   lbl = newiTempLabel (NULL);
-  emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
+  emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100));
   emitcode ("cpl", "a");
   emitcode ("inc", "a");
-  emitcode ("", "%05d$:", (lbl->key + 100));
+  emitcode ("", "!tlabeldef", (lbl->key + 100));
   emitcode ("mov", "b,a");
 
   /* sign adjust left side */
@@ -4044,10 +5072,10 @@ genModOneByte (operand * left,
   MOVA (l);
 
   lbl = newiTempLabel (NULL);
-  emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
+  emitcode ("jnb", "acc.7,!tlabel", (lbl->key + 100));
   emitcode ("cpl", "a");
   emitcode ("inc", "a");
-  emitcode ("", "%05d$:", (lbl->key + 100));
+  emitcode ("", "!tlabeldef", (lbl->key + 100));
 
   /* now the multiplication */
   emitcode ("nop", "; workaround for DS80C390 div bug.");
@@ -4058,17 +5086,110 @@ genModOneByte (operand * left,
   emitcode ("pop", "acc");
   /* if there was an over flow we don't
      adjust the sign of the result */
-  emitcode ("jb", "ov,%05d$", (lbl->key + 100));
-  emitcode ("jnb", "acc.7,%05d$", (lbl->key + 100));
+  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 ("", "%05d$:", (lbl->key + 100));
-
+  emitcode ("", "!tlabeldef", (lbl->key + 100));
+  
+  _G.bInUse++;
   /* now we are done */
+  aopOp(result, ic, TRUE, FALSE);    
   aopPut (AOP (result), "b", 0);
+  _G.bInUse--;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genModTwoByte - use the DS390 MAC unit to do 16%16 modulus      */
+/*-----------------------------------------------------------------*/
+static void genModTwoByte (operand *left, operand *right, 
+                           operand *result, iCode *ic)
+{
+       sym_link *retype = getSpec(operandType(right));
+       sym_link *letype = getSpec(operandType(left));
+       int umult = SPEC_USIGN(retype) | SPEC_USIGN(letype);
+       symbol *lbl;
+
+       /* load up MA with left */
+       /* save EA bit in F1 */
+       lbl = newiTempLabel(NULL);
+       emitcode ("setb","F1");
+       emitcode ("jbc","EA,!tlabel",lbl->key+100);
+       emitcode ("clr","F1");
+       emitcode("","!tlabeldef",lbl->key+100);
+
+       if (!umult) {
+               lbl = newiTempLabel(NULL);
+               emitcode ("mov","b,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","a,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+               emitcode ("jnb","acc.7,!tlabel",lbl->key+100);
+               emitcode ("xch", "a,b");
+               emitcode ("cpl","a");
+               emitcode ("add", "a,#1");
+               emitcode ("xch", "a,b");
+               emitcode ("cpl", "a"); // msb
+               emitcode ("addc","a,#0");
+               emitcode ("","!tlabeldef",lbl->key+100);
+               emitcode ("mov","ma,b");
+               emitcode ("mov","ma,a");
+       } else {
+               emitcode ("mov","ma,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","ma,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+       }
+
+       /* load up MB with right */
+       if (!umult) {
+               if (AOP_TYPE(right) == AOP_LIT) {
+                       int val=floatFromVal (AOP (right)->aopu.aop_lit);
+                       if (val < 0) {
+                               val = -val;
+                       } 
+                       emitcode ("mov","mb,#!constbyte",val & 0xff);
+                       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 ("jnb","acc.7,!tlabel",lbl->key+100);          
+                       emitcode ("xch", "a,b");
+                       emitcode ("cpl","a");
+                       emitcode ("add", "a,#1");
+                       emitcode ("xch", "a,b");
+                       emitcode ("cpl", "a"); // msb
+                       emitcode ("addc", "a,#0");
+                       emitcode ("","!tlabeldef",lbl->key+100);
+                       emitcode ("mov","mb,b");
+                       emitcode ("mov","mb,a");
+               }
+       } else {
+               emitcode ("mov","mb,%s",aopGet(AOP(right),0,FALSE,FALSE,TRUE));
+               emitcode ("mov","mb,%s",aopGet(AOP(right),1,FALSE,FALSE,TRUE));
+       }
+
+       /* wait for multiplication to finish */
+       lbl = newiTempLabel(NULL);
+       emitcode("","!tlabeldef", lbl->key+100);
+       emitcode("mov","a,mcnt1");
+       emitcode("anl","a,#!constbyte",0x80);
+       emitcode("jnz","!tlabel",lbl->key+100);
+       
+       freeAsmop (left, NULL, ic, TRUE);
+       freeAsmop (right, NULL, ic,TRUE);
+       aopOp(result, ic, TRUE, FALSE);
+
+       aopPut(AOP(result),"mb",1);
+       aopPut(AOP(result),"mb",0);
+       freeAsmop (result, NULL, ic, TRUE);
 
+       /* restore EA bit in F1 */
+       lbl = newiTempLabel(NULL);
+       emitcode ("jnb","F1,!tlabel",lbl->key+100);
+       emitcode ("setb","EA");
+       emitcode("","!tlabeldef",lbl->key+100);
+       return ;
 }
 
 /*-----------------------------------------------------------------*/
@@ -4081,18 +5202,17 @@ genMod (iCode * ic)
   operand *right = IC_RIGHT (ic);
   operand *result = IC_RESULT (ic);
 
-  D (emitcode (";", "genMod ");
-    );
+  D (emitcode (";", "genMod "); );
 
   /* assign the amsops */
-  AOP_OP_3 (ic);
+  AOP_OP_2 (ic);
 
   /* special cases first */
   /* both are bits */
   if (AOP_TYPE (left) == AOP_CRY &&
       AOP_TYPE (right) == AOP_CRY)
     {
-      genModbits (left, right, result);
+      genModbits (left, right, result, ic);
       goto release;
     }
 
@@ -4100,12 +5220,18 @@ genMod (iCode * ic)
   if (AOP_SIZE (left) == 1 &&
       AOP_SIZE (right) == 1)
     {
-      genModOneByte (left, right, result);
+      genModOneByte (left, right, result, ic);
       goto release;
     }
 
+  if (AOP_SIZE (left) == 2 && AOP_SIZE(right) == 2) {
+         /* use the ds390 ARITHMETIC accel UNIT */
+         genModTwoByte (left, right, result, ic);
+         return ;
+  }
+
   /* should have been converted to function call */
-  assert (1);
+  assert (0);
 
 release:
   freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
@@ -4142,11 +5268,11 @@ genIfxJump (iCode * ic, char *jval)
               (strcmp (jval, "c") == 0 ? "jc" : "jb")));
     }
   if (strcmp (inst, "jb") == 0 || strcmp (inst, "jnb") == 0)
-    emitcode (inst, "%s,%05d$", jval, (tlbl->key + 100));
+    emitcode (inst, "%s,!tlabel", jval, (tlbl->key + 100));
   else
-    emitcode (inst, "%05d$", tlbl->key + 100);
-  emitcode ("ljmp", "%05d$", jlbl->key + 100);
-  emitcode ("", "%05d$:", tlbl->key + 100);
+    emitcode (inst, "!tlabel", tlbl->key + 100);
+  emitcode ("ljmp", "!tlabel", jlbl->key + 100);
+  emitcode ("", "!tlabeldef", tlbl->key + 100);
 
   /* mark the icode as generated */
   ic->generated = 1;
@@ -4184,14 +5310,14 @@ genCmp (operand * left, operand * 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 (right) == AOP_LIT && AOP_TYPE (left) != AOP_DIR && AOP_TYPE (left) != AOP_STR))
        {
          symbol *lbl = newiTempLabel (NULL);
-         emitcode ("cjne", "%s,%s,%05d$",
+         emitcode ("cjne", "%s,%s,!tlabel",
                    aopGet (AOP (left), offset, FALSE, FALSE, FALSE),
                    aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
                    lbl->key + 100);
-         emitcode ("", "%05d$:", lbl->key + 100);
+         emitcode ("", "!tlabeldef", lbl->key + 100);
        }
       else
        {
@@ -4232,31 +5358,31 @@ genCmp (operand * left, operand * right,
          CLRC;
          while (size--)
            {
-             emitcode (";", "genCmp #1: %d/%d/%d", size, sign, offset);
+             //emitcode (";", "genCmp #1: %d/%d/%d", size, sign, offset);
              MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
-             emitcode (";", "genCmp #2");
+             //emitcode (";", "genCmp #2");
              if (sign && (size == 0))
                {
-                 emitcode (";", "genCmp #3");
-                 emitcode ("xrl", "a,#0x80");
+                   //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 ("subb", "a,#0x%02x",
+                     //emitcode (";", "genCmp #3.1");
+                     emitcode ("subb", "a,#!constbyte",
                                0x80 ^ (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
                    }
                  else
                    {
-                     emitcode (";", "genCmp #3.2");
+                     //emitcode (";", "genCmp #3.2");
                      if (AOP_NEEDSACC (right))
                        {
                          emitcode ("push", "acc");
                        }
                      emitcode ("mov", "b,%s", aopGet (AOP (right), offset++,
                                                       FALSE, FALSE, FALSE));
-                     emitcode ("xrl", "b,#0x80");
+                     emitcode ("xrl", "b,#!constbyte",0x80);
                      if (AOP_NEEDSACC (right))
                        {
                          emitcode ("pop", "acc");
@@ -4268,11 +5394,11 @@ genCmp (operand * left, operand * right,
                {
                  const char *s;
 
-                 emitcode (";", "genCmp #4");
+                 //emitcode (";", "genCmp #4");
                  if (AOP_NEEDSACC (right))
                    {
                      /* Yuck!! */
-                     emitcode (";", "genCmp #4.1");
+                     //emitcode (";", "genCmp #4.1");
                      emitcode ("xch", "a, b");
                      MOVA (aopGet (AOP (right), offset++, FALSE, FALSE, TRUE));
                      emitcode ("xch", "a, b");
@@ -4280,7 +5406,7 @@ genCmp (operand * left, operand * right,
                    }
                  else
                    {
-                     emitcode (";", "genCmp #4.2");
+                     //emitcode (";", "genCmp #4.2");
                      s = aopGet (AOP (right), offset++, FALSE, FALSE, FALSE);
                    }
 
@@ -4418,7 +5544,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
        {
          char *l = aopGet (AOP (left), offset, FALSE, FALSE, TRUE);
          MOVA (l);
-         emitcode ("cjne", "a,%s,%05d$",
+         emitcode ("cjne", "a,%s,!tlabel",
                    aopGet (AOP (right), offset, FALSE, FALSE, FALSE),
                    lbl->key + 100);
          offset++;
@@ -4437,9 +5563,9 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
          MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
          if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) &&
              ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
-           emitcode ("jnz", "%05d$", lbl->key + 100);
+           emitcode ("jnz", "!tlabel", lbl->key + 100);
          else
-           emitcode ("cjne", "a,%s,%05d$",
+           emitcode ("cjne", "a,%s,!tlabel",
                      aopGet (AOP (right), offset, FALSE, TRUE, FALSE),
                      lbl->key + 100);
          offset++;
@@ -4454,7 +5580,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
          if (strcmp (l, "b"))
            emitcode ("mov", "b,%s", l);
          MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
-         emitcode ("cjne", "a,b,%05d$", lbl->key + 100);
+         emitcode ("cjne", "a,b,!tlabel", lbl->key + 100);
          offset++;
        }
     }
@@ -4474,10 +5600,10 @@ gencjne (operand * left, operand * right, symbol * lbl)
   gencjneshort (left, right, lbl);
 
   emitcode ("mov", "a,%s", one);
-  emitcode ("sjmp", "%05d$", tlbl->key + 100);
-  emitcode ("", "%05d$:", lbl->key + 100);
+  emitcode ("sjmp", "!tlabel", tlbl->key + 100);
+  emitcode ("", "!tlabeldef", lbl->key + 100);
   emitcode ("clr", "a");
-  emitcode ("", "%05d$:", tlbl->key + 100);
+  emitcode ("", "!tlabeldef", tlbl->key + 100);
 }
 
 /*-----------------------------------------------------------------*/
@@ -4536,24 +5662,24 @@ genCmpEq (iCode * ic, iCode * ifx)
            {
              symbol *lbl = newiTempLabel (NULL);
              emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
-             emitcode ("jb", "%s,%05d$", AOP (right)->aopu.aop_dir, (lbl->key + 100));
+             emitcode ("jb", "%s,!tlabel", AOP (right)->aopu.aop_dir, (lbl->key + 100));
              emitcode ("cpl", "c");
-             emitcode ("", "%05d$:", (lbl->key + 100));
+             emitcode ("", "!tlabeldef", (lbl->key + 100));
            }
          /* if true label then we jump if condition
             supplied is true */
          tlbl = newiTempLabel (NULL);
          if (IC_TRUE (ifx))
            {
-             emitcode ("jnc", "%05d$", tlbl->key + 100);
-             emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
+             emitcode ("jnc", "!tlabel", tlbl->key + 100);
+             emitcode ("ljmp", "!tlabel", IC_TRUE (ifx)->key + 100);
            }
          else
            {
-             emitcode ("jc", "%05d$", tlbl->key + 100);
-             emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
+             emitcode ("jc", "!tlabel", tlbl->key + 100);
+             emitcode ("ljmp", "!tlabel", IC_FALSE (ifx)->key + 100);
            }
-         emitcode ("", "%05d$:", tlbl->key + 100);
+         emitcode ("", "!tlabeldef", tlbl->key + 100);
        }
       else
        {
@@ -4561,16 +5687,16 @@ genCmpEq (iCode * ic, iCode * ifx)
          gencjneshort (left, right, tlbl);
          if (IC_TRUE (ifx))
            {
-             emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
-             emitcode ("", "%05d$:", tlbl->key + 100);
+             emitcode ("ljmp", "!tlabel", IC_TRUE (ifx)->key + 100);
+             emitcode ("", "!tlabeldef", tlbl->key + 100);
            }
          else
            {
              symbol *lbl = newiTempLabel (NULL);
-             emitcode ("sjmp", "%05d$", lbl->key + 100);
-             emitcode ("", "%05d$:", tlbl->key + 100);
-             emitcode ("ljmp", "%05d$", IC_FALSE (ifx)->key + 100);
-             emitcode ("", "%05d$:", lbl->key + 100);
+             emitcode ("sjmp", "!tlabel", lbl->key + 100);
+             emitcode ("", "!tlabeldef", tlbl->key + 100);
+             emitcode ("ljmp", "!tlabel", IC_FALSE (ifx)->key + 100);
+             emitcode ("", "!tlabeldef", lbl->key + 100);
            }
        }
       /* mark the icode as generated */
@@ -4607,9 +5733,9 @@ genCmpEq (iCode * ic, iCode * ifx)
        {
          symbol *lbl = newiTempLabel (NULL);
          emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
-         emitcode ("jb", "%s,%05d$", AOP (right)->aopu.aop_dir, (lbl->key + 100));
+         emitcode ("jb", "%s,!tlabel", AOP (right)->aopu.aop_dir, (lbl->key + 100));
          emitcode ("cpl", "c");
-         emitcode ("", "%05d$:", (lbl->key + 100));
+         emitcode ("", "!tlabeldef", (lbl->key + 100));
        }
 
       freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
@@ -4683,6 +5809,43 @@ ifxForOp (operand * op, iCode * ic)
 
   return NULL;
 }
+/*-----------------------------------------------------------------*/
+/* hasInc - operand is incremented before any other use            */
+/*-----------------------------------------------------------------*/
+static iCode *
+hasInc (operand *op, iCode *ic, int osize)
+{
+  sym_link *type = operandType(op);
+  sym_link *retype = getSpec (type);
+  iCode *lic = ic->next;
+  int isize ;
+  
+  /* this could from a cast, e.g.: "(char xdata *) 0x7654;" */
+  if (!IS_SYMOP(op)) return NULL;
+
+  if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
+  if (IS_AGGREGATE(type->next)) return NULL;
+  if (osize != (isize = getSize(type->next))) return NULL;
+
+  while (lic) {
+      /* if operand of the form op = op + <sizeof *op> */
+      if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
+         isOperandEqual(IC_RESULT(lic),op) && 
+         isOperandLiteral(IC_RIGHT(lic)) &&
+         operandLitValue(IC_RIGHT(lic)) == isize) {
+         return lic;
+      }
+      /* if the operand used or deffed */
+      if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
+         return NULL;
+      }
+      /* if GOTO or IFX */
+      if (lic->op == IFX || lic->op == GOTO || lic->op == LABEL) break;
+      lic = lic->next;
+  }
+  return NULL;
+}
+
 /*-----------------------------------------------------------------*/
 /* genAndOp - for && operation                                     */
 /*-----------------------------------------------------------------*/
@@ -4716,9 +5879,9 @@ genAndOp (iCode * ic)
     {
       tlbl = newiTempLabel (NULL);
       toBoolean (left);
-      emitcode ("jz", "%05d$", tlbl->key + 100);
+      emitcode ("jz", "!tlabel", tlbl->key + 100);
       toBoolean (right);
-      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("", "!tlabeldef", tlbl->key + 100);
       freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
       freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
   
@@ -4763,9 +5926,9 @@ genOrOp (iCode * ic)
     {
       tlbl = newiTempLabel (NULL);
       toBoolean (left);
-      emitcode ("jnz", "%05d$", tlbl->key + 100);
+      emitcode ("jnz", "!tlabel", tlbl->key + 100);
       toBoolean (right);
-      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("", "!tlabeldef", tlbl->key + 100);
       freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
       freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
   
@@ -4806,7 +5969,7 @@ static void
 continueIfTrue (iCode * ic)
 {
   if (IC_TRUE (ic))
-    emitcode ("ljmp", "%05d$", IC_TRUE (ic)->key + 100);
+    emitcode ("ljmp", "!tlabel", IC_TRUE (ic)->key + 100);
   ic->generated = 1;
 }
 
@@ -4817,7 +5980,7 @@ static void
 jumpIfTrue (iCode * ic)
 {
   if (!IC_TRUE (ic))
-    emitcode ("ljmp", "%05d$", IC_FALSE (ic)->key + 100);
+    emitcode ("ljmp", "!tlabel", IC_FALSE (ic)->key + 100);
   ic->generated = 1;
 }
 
@@ -4831,15 +5994,15 @@ jmpTrueOrFalse (iCode * ic, symbol * tlbl)
   if (IC_TRUE (ic))
     {
       symbol *nlbl = newiTempLabel (NULL);
-      emitcode ("sjmp", "%05d$", nlbl->key + 100);
-      emitcode ("", "%05d$:", tlbl->key + 100);
-      emitcode ("ljmp", "%05d$", IC_TRUE (ic)->key + 100);
-      emitcode ("", "%05d$:", nlbl->key + 100);
+      emitcode ("sjmp", "!tlabel", nlbl->key + 100);
+      emitcode ("", "!tlabeldef", tlbl->key + 100);
+      emitcode ("ljmp", "!tlabel", IC_TRUE (ic)->key + 100);
+      emitcode ("", "!tlabeldef", nlbl->key + 100);
     }
   else
     {
-      emitcode ("ljmp", "%05d$", IC_FALSE (ic)->key + 100);
-      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("ljmp", "!tlabel", IC_FALSE (ic)->key + 100);
+      emitcode ("", "!tlabeldef", tlbl->key + 100);
     }
   ic->generated = 1;
 }
@@ -4855,6 +6018,7 @@ genFarFarLogicOp(iCode *ic, char *logicOp)
       int size, resultSize, compSize;
       int offset = 0;
       
+      TR_AP("#5");
       D(emitcode(";", "%s special case for 3 far operands.", logicOp););
       compSize = AOP_SIZE(IC_LEFT(ic)) < AOP_SIZE(IC_RIGHT(ic)) ? 
                  AOP_SIZE(IC_LEFT(ic)) : AOP_SIZE(IC_RIGHT(ic));
@@ -4924,8 +6088,11 @@ genAnd (iCode * ic, iCode * ifx)
 #endif
 
   /* if left is a literal & right is not then exchange them */
-  if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
-      AOP_NEEDSACC (left))
+  if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT)
+#ifdef LOGIC_OPS_BROKEN      
+    ||  AOP_NEEDSACC (left)
+#endif
+    )
     {
       operand *tmp = right;
       right = left;
@@ -5033,6 +6200,10 @@ genAnd (iCode * ic, iCode * ifx)
                  sprintf (buffer, "acc.%d", posbit & 0x07);
                  genIfxJump (ifx, buffer);
                }
+             else 
+                 {
+                     emitcode ("anl","a,#!constbyte",1 << (posbit & 0x07));
+                 }
              goto release;
            }
        }
@@ -5049,13 +6220,13 @@ genAnd (iCode * ic, iCode * ifx)
                  MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
                  // byte ==  2^n ?
                  if ((posbit = isLiteralBit (bytelit)) != 0)
-                   emitcode ("jb", "acc.%d,%05d$", (posbit - 1) & 0x07, tlbl->key + 100);
+                   emitcode ("jb", "acc.%d,!tlabel", (posbit - 1) & 0x07, tlbl->key + 100);
                  else
                    {
                      if (bytelit != 0x0FFL)
                        emitcode ("anl", "a,%s",
                          aopGet (AOP (right), offset, FALSE, TRUE, FALSE));
-                     emitcode ("jnz", "%05d$", tlbl->key + 100);
+                     emitcode ("jnz", "!tlabel", tlbl->key + 100);
                    }
                }
              offset++;
@@ -5064,7 +6235,7 @@ genAnd (iCode * ic, iCode * ifx)
          if (size)
            {
              emitcode ("clr", "c");
-             emitcode ("", "%05d$:", tlbl->key + 100);
+             emitcode ("", "!tlabeldef", tlbl->key + 100);
            }
          // if(left & literal)
          else
@@ -5134,16 +6305,27 @@ genAnd (iCode * ic, iCode * ifx)
            emitcode ("setb", "c");
          while (sizer--)
            {
-             MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
-             emitcode ("anl", "a,%s",
-                       aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
-             emitcode ("jnz", "%05d$", tlbl->key + 100);
+             if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+               emitcode ("anl", "a,%s",
+                         aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+             } else {
+               if (AOP_TYPE(left)==AOP_ACC) {
+                 emitcode("mov", "b,a");
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 emitcode("anl", "a,b");
+               }else {
+                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+                 emitcode ("anl", "a,%s",
+                           aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+               }
+             }
+             emitcode ("jnz", "!tlabel", tlbl->key + 100);
              offset++;
            }
          if (size)
            {
              CLRC;
-             emitcode ("", "%05d$:", tlbl->key + 100);
+             emitcode ("", "!tlabeldef", tlbl->key + 100);
              outBitC (result);
            }
          else if (ifx)
@@ -5169,8 +6351,7 @@ genAnd (iCode * ic, iCode * ifx)
                      aopPut (AOP (result), zero, offset);
                      continue;
                    }
-                 D (emitcode (";", "better literal AND.");
-                   );
+                 D (emitcode (";", "better literal AND."););
                  MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
                  emitcode ("anl", "a, %s", aopGet (AOP (right), offset,
                                                    FALSE, FALSE, FALSE));
@@ -5187,10 +6368,16 @@ genAnd (iCode * ic, iCode * ifx)
                    }
                  else
                    {
-                     MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
-                     emitcode ("anl", "a,%s",
-                         aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
-                   }
+                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+                     if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
+                     {
+                         emitcode("mov", "b,a");
+                         rOp = "b";
+                     }
+                       
+                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                     emitcode ("anl", "a,%s", rOp);
+                   }                   
                }
              aopPut (AOP (result), "a", offset);
            }
@@ -5237,8 +6424,11 @@ genOr (iCode * ic, iCode * ifx)
 #endif
 
   /* if left is a literal & right is not then exchange them */
-  if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
-      AOP_NEEDSACC (left))
+  if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT)
+#ifdef LOGIC_OPS_BROKEN
+   || AOP_NEEDSACC (left) // I think this is a net loss now.
+#endif      
+      )
     {
       operand *tmp = right;
       right = left;
@@ -5308,10 +6498,10 @@ genOr (iCode * ic, iCode * ifx)
              symbol *tlbl = newiTempLabel (NULL);
              if (!((AOP_TYPE (result) == AOP_CRY) && ifx))
                emitcode ("setb", "c");
-             emitcode ("jb", "%s,%05d$",
+             emitcode ("jb", "%s,!tlabel",
                        AOP (left)->aopu.aop_dir, tlbl->key + 100);
              toBoolean (right);
-             emitcode ("jnz", "%05d$", tlbl->key + 100);
+             emitcode ("jnz", "!tlabel", tlbl->key + 100);
              if ((AOP_TYPE (result) == AOP_CRY) && ifx)
                {
                  jmpTrueOrFalse (ifx, tlbl);
@@ -5320,7 +6510,7 @@ genOr (iCode * ic, iCode * ifx)
              else
                {
                  CLRC;
-                 emitcode ("", "%05d$:", tlbl->key + 100);
+                 emitcode ("", "!tlabeldef", tlbl->key + 100);
                }
            }
        }
@@ -5358,9 +6548,9 @@ genOr (iCode * ic, iCode * ifx)
          if (size)
            {
              symbol *tlbl = newiTempLabel (NULL);
-             emitcode ("jnz", "%05d$", tlbl->key + 100);
+             emitcode ("jnz", "!tlabel", tlbl->key + 100);
              CLRC;
-             emitcode ("", "%05d$:", tlbl->key + 100);
+             emitcode ("", "!tlabeldef", tlbl->key + 100);
            }
          else
            {
@@ -5436,16 +6626,21 @@ genOr (iCode * ic, iCode * ifx)
            emitcode ("setb", "c");
          while (sizer--)
            {
-             MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
-             emitcode ("orl", "a,%s",
-                       aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
-             emitcode ("jnz", "%05d$", tlbl->key + 100);
+             if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+               emitcode ("orl", "a,%s",
+                         aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+             } else {
+               MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+               emitcode ("orl", "a,%s",
+                         aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+             }
+             emitcode ("jnz", "!tlabel", tlbl->key + 100);
              offset++;
            }
          if (size)
            {
              CLRC;
-             emitcode ("", "%05d$:", tlbl->key + 100);
+             emitcode ("", "!tlabeldef", tlbl->key + 100);
              outBitC (result);
            }
          else if (ifx)
@@ -5453,6 +6648,7 @@ genOr (iCode * ic, iCode * ifx)
        }
       else
        {
+           _startLazyDPSEvaluation();
          for (; (size--); offset++)
            {
              // normal case
@@ -5466,8 +6662,7 @@ genOr (iCode * ic, iCode * ifx)
                              offset);
                      continue;
                    }
-                 D (emitcode (";", "better literal OR.");
-                   );
+                 D (emitcode (";", "better literal OR."););
                  MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
                  emitcode ("orl", "a, %s", aopGet (AOP (right), offset,
                                                    FALSE, FALSE, FALSE));
@@ -5484,13 +6679,21 @@ genOr (iCode * ic, iCode * ifx)
                    }
                  else
                    {
-                     MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
-                     emitcode ("orl", "a,%s",
-                         aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+                       
+                     if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
+                     {
+                         emitcode("mov", "b,a");
+                         rOp = "b";
+                     }
+                       
+                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                     emitcode ("orl", "a,%s", rOp);
                    }
                }
              aopPut (AOP (result), "a", offset);
            }
+           _endLazyDPSEvaluation();
        }
     }
 
@@ -5533,8 +6736,11 @@ genXor (iCode * ic, iCode * ifx)
 
   /* if left is a literal & right is not ||
      if left needs acc & right does not */
-  if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) ||
-      (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right)))
+  if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) 
+#ifdef LOGIC_OPS_BROKEN      
+      || (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right))
+#endif
+     )
     {
       operand *tmp = right;
       right = left;
@@ -5629,16 +6835,16 @@ genXor (iCode * ic, iCode * ifx)
                  MOVA (aopGet (AOP (right), sizer - 1, FALSE, FALSE, TRUE));
                  if (sizer == 1)
                    // test the msb of the lsb
-                   emitcode ("anl", "a,#0xfe");
-                 emitcode ("jnz", "%05d$", tlbl->key + 100);
+                   emitcode ("anl", "a,#!constbyte",0xfe);
+                 emitcode ("jnz", "!tlabel", tlbl->key + 100);
                  sizer--;
                }
              // val = (0,1)
              emitcode ("rrc", "a");
            }
-         emitcode ("jnb", "%s,%05d$", AOP (left)->aopu.aop_dir, (tlbl->key + 100));
+         emitcode ("jnb", "%s,!tlabel", AOP (left)->aopu.aop_dir, (tlbl->key + 100));
          emitcode ("cpl", "c");
-         emitcode ("", "%05d$:", (tlbl->key + 100));
+         emitcode ("", "!tlabeldef", (tlbl->key + 100));
        }
       // bit = c
       // val = c
@@ -5699,6 +6905,7 @@ genXor (iCode * ic, iCode * ifx)
          // if(!size && ifx), conditional oper: if(left ^ right)
          symbol *tlbl = newiTempLabel (NULL);
          int sizer = max (AOP_SIZE (left), AOP_SIZE (right));
+                 
          if (size)
            emitcode ("setb", "c");
          while (sizer--)
@@ -5710,23 +6917,35 @@ genXor (iCode * ic, iCode * ifx)
                }
              else
                {
-                 MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
-                 emitcode ("xrl", "a,%s",
-                         aopGet (AOP (left), offset, FALSE, FALSE, FALSE));
+                 if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+                   emitcode ("xrl", "a,%s",
+                             aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+                 } else {
+                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+                     if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
+                     {
+                         emitcode("mov", "b,a");
+                         rOp = "b";
+                     }
+                       
+                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                     emitcode ("xrl", "a,%s", rOp);                  
+                 }
                }
-             emitcode ("jnz", "%05d$", tlbl->key + 100);
+             emitcode ("jnz", "!tlabel", tlbl->key + 100);
              offset++;
            }
          if (size)
            {
              CLRC;
-             emitcode ("", "%05d$:", tlbl->key + 100);
+             emitcode ("", "!tlabeldef", tlbl->key + 100);
              outBitC (result);
            }
          else if (ifx)
            jmpTrueOrFalse (ifx, tlbl);
        }
       else
+       {
        for (; (size--); offset++)
          {
            // normal case
@@ -5740,8 +6959,7 @@ genXor (iCode * ic, iCode * ifx)
                            offset);
                    continue;
                  }
-               D (emitcode (";", "better literal XOR.");
-                 );
+               D (emitcode (";", "better literal XOR."););
                MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
                emitcode ("xrl", "a, %s", aopGet (AOP (right), offset,
                                                  FALSE, FALSE, FALSE));
@@ -5757,13 +6975,21 @@ genXor (iCode * ic, iCode * ifx)
                  }
                else
                  {
-                   MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
-                   emitcode ("xrl", "a,%s",
-                          aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+                     char *rOp = aopGet (AOP (right), offset, FALSE, FALSE, TRUE);
+                     if (!strcmp(rOp, "a") || !strcmp(rOp, "acc"))
+                     {
+                         emitcode("mov", "b,a");
+                         rOp = "b";
+                     }
+                       
+                     MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+                     emitcode ("xrl", "a,%s", rOp);
                  }
              }
            aopPut (AOP (result), "a", offset);
          }
+       }
+       
     }
 
 release:
@@ -5778,14 +7004,14 @@ release:
 static void
 genInline (iCode * ic)
 {
-  char buffer[MAX_INLINEASM];
-  char *bp = buffer;
-  char *bp1 = buffer;
+  char *buffer, *bp, *bp1;
 
   D (emitcode (";", "genInline ");
     );
 
   _G.inLine += (!options.asmpeep);
+
+  buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
   strcpy (buffer, IC_INLINE (ic));
 
   /* emit each line as a code */
@@ -5946,7 +7172,7 @@ genGetHbit (iCode * ic)
   else
     {
       emitcode ("rl", "a");
-      emitcode ("anl", "a,#0x01");
+      emitcode ("anl", "a,#1");
       outAcc (result);
     }
 
@@ -6015,7 +7241,7 @@ AccLsh (int shCount)
          /* rotate left accumulator */
          AccRol (shCount);
          /* and kill the lower order bits */
-         emitcode ("anl", "a,#0x%02x", SLMask[shCount]);
+         emitcode ("anl", "a,#!constbyte", SLMask[shCount]);
        }
     }
 }
@@ -6038,7 +7264,7 @@ AccRsh (int shCount)
          /* rotate right accumulator */
          AccRol (8 - shCount);
          /* and kill the higher order bits */
-         emitcode ("anl", "a,#0x%02x", SRMask[shCount]);
+         emitcode ("anl", "a,#!constbyte", SRMask[shCount]);
        }
     }
 }
@@ -6071,11 +7297,11 @@ AccSRsh (int shCount)
          /* rotate right accumulator */
          AccRol (8 - shCount);
          /* and kill the higher order bits */
-         emitcode ("anl", "a,#0x%02x", SRMask[shCount]);
-         emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
-         emitcode ("orl", "a,#0x%02x",
+         emitcode ("anl", "a,#!constbyte", SRMask[shCount]);
+         emitcode ("jnb", "acc.%d,!tlabel", 7 - shCount, tlbl->key + 100);
+         emitcode ("orl", "a,#!constbyte",
                    (unsigned char) ~SRMask[shCount]);
-         emitcode ("", "%05d$:", tlbl->key + 100);
+         emitcode ("", "!tlabeldef", tlbl->key + 100);
        }
     }
 }
@@ -6220,7 +7446,7 @@ AccAXLsh (char *x, int shCount)
 
       AccRol (shCount);                // BBBAAAAA:CCCCCDDD
 
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                SLMask[shCount]);       // BBB00000:CCCCCDDD
 
       emitcode ("xch", "a,%s", x);     // CCCCCDDD:BBB00000
@@ -6233,7 +7459,7 @@ AccAXLsh (char *x, int shCount)
 
       emitcode ("xch", "a,%s", x);     // DDDCCCCC:(BBB^DDD)CCCCC
 
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                SLMask[shCount]);       // DDD00000:(BBB^DDD)CCCCC
 
       emitcode ("xch", "a,%s", x);     // (BBB^DDD)CCCCC:DDD00000
@@ -6242,7 +7468,7 @@ AccAXLsh (char *x, int shCount)
 
       break;
     case 6:                    // AAAAAABB:CCCCCCDD
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                SRMask[shCount]);       // 000000BB:CCCCCCDD
       emitcode ("mov", "c,acc.0");     // c = B
       emitcode ("xch", "a,%s", x);     // CCCCCCDD:000000BB
@@ -6264,7 +7490,7 @@ AccAXLsh (char *x, int shCount)
       break;
     case 7:                    // a:x <<= 7
 
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                SRMask[shCount]);       // 0000000B:CCCCCCCD
 
       emitcode ("mov", "c,acc.0");     // c = B
@@ -6315,14 +7541,14 @@ AccAXRsh (char *x, int shCount)
 
       AccRol (8 - shCount);    // DDDCCCCC:BBBAAAAA
 
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                SRMask[shCount]);       // 000CCCCC:BBBAAAAA
 
       emitcode ("xrl", "a,%s", x);     // BBB(CCCCC^AAAAA):BBBAAAAA
 
       emitcode ("xch", "a,%s", x);     // BBBAAAAA:BBB(CCCCC^AAAAA)
 
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                SRMask[shCount]);       // 000AAAAA:BBB(CCCCC^AAAAA)
 
       emitcode ("xch", "a,%s", x);     // BBB(CCCCC^AAAAA):000AAAAA
@@ -6341,7 +7567,7 @@ AccAXRsh (char *x, int shCount)
 
       emitcode ("xch", "a,%s", x);     // DDDDDDAA:BBBBBBCC
 
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                SRMask[shCount]);       // 000000AA:BBBBBBCC
 
       break;
@@ -6353,7 +7579,7 @@ AccAXRsh (char *x, int shCount)
 
       emitcode ("xch", "a,%s", x);     // DDDDDDDA:BBBBBBCC
 
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                SRMask[shCount]);       // 0000000A:BBBBBBBC
 
       break;
@@ -6364,7 +7590,6 @@ AccAXRsh (char *x, int shCount)
 #endif
 
 #ifdef BETTER_LITERAL_SHIFT
-//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* AccAXRshS - right shift signed a:x known count (0..7)           */
 /*-----------------------------------------------------------------*/
@@ -6400,14 +7625,14 @@ AccAXRshS (char *x, int shCount)
 
       AccRol (8 - shCount);    // DDDCCCCC:BBBAAAAA
 
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                SRMask[shCount]);       // 000CCCCC:BBBAAAAA
 
       emitcode ("xrl", "a,%s", x);     // BBB(CCCCC^AAAAA):BBBAAAAA
 
       emitcode ("xch", "a,%s", x);     // BBBAAAAA:BBB(CCCCC^AAAAA)
 
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                SRMask[shCount]);       // 000AAAAA:BBB(CCCCC^AAAAA)
 
       emitcode ("xch", "a,%s", x);     // BBB(CCCCC^AAAAA):000AAAAA
@@ -6416,11 +7641,11 @@ AccAXRshS (char *x, int shCount)
 
       emitcode ("xch", "a,%s", x);     // 000SAAAA:BBBCCCCC
 
-      emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
-      emitcode ("orl", "a,#0x%02x",
+      emitcode ("jnb", "acc.%d,!tlabel", 7 - shCount, tlbl->key + 100);
+      emitcode ("orl", "a,#!constbyte",
                (unsigned char) ~SRMask[shCount]);      // 111AAAAA:BBBCCCCC
 
-      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("", "!tlabeldef", tlbl->key + 100);
       break;                   // SSSSAAAA:BBBCCCCC
 
     case 6:                    // AABBBBBB:CCDDDDDD
@@ -6433,14 +7658,14 @@ AccAXRshS (char *x, int shCount)
 
       emitcode ("xch", "a,%s", x);     // DDDDDDAA:BBBBBBCC
 
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                SRMask[shCount]);       // 000000AA:BBBBBBCC
 
-      emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
-      emitcode ("orl", "a,#0x%02x",
+      emitcode ("jnb", "acc.%d,!tlabel", 7 - shCount, tlbl->key + 100);
+      emitcode ("orl", "a,#!constbyte",
                (unsigned char) ~SRMask[shCount]);      // 111111AA:BBBBBBCC
 
-      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("", "!tlabeldef", tlbl->key + 100);
       break;
     case 7:                    // ABBBBBBB:CDDDDDDD
 
@@ -6451,14 +7676,14 @@ AccAXRshS (char *x, int shCount)
 
       emitcode ("xch", "a,%s", x);     // DDDDDDDA:BBBBBBCC
 
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                SRMask[shCount]);       // 0000000A:BBBBBBBC
 
-      emitcode ("jnb", "acc.%d,%05d$", 7 - shCount, tlbl->key + 100);
-      emitcode ("orl", "a,#0x%02x",
+      emitcode ("jnb", "acc.%d,!tlabel", 7 - shCount, tlbl->key + 100);
+      emitcode ("orl", "a,#!constbyte",
                (unsigned char) ~SRMask[shCount]);      // 1111111A:BBBBBBBC
 
-      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("", "!tlabeldef", tlbl->key + 100);
       break;
     default:
       break;
@@ -6488,7 +7713,7 @@ _loadLeftIntoAx(char      **lsb,
        char *leftByte;
        
        _startLazyDPSEvaluation();
-       if (AOP_TYPE(left) == AOP_DPTR2)
+      if (AOP_TYPE(left) == AOP_DPTR2)
        {
            // Get MSB in A.
                   MOVA(aopGet(AOP(left), offl + MSB16, FALSE, FALSE, TRUE));
@@ -6502,6 +7727,7 @@ _loadLeftIntoAx(char      **lsb,
                   leftByte = aopGet (AOP(left), offl, FALSE, FALSE, TRUE);
            if (strcmp(leftByte, DP2_RESULT_REG))
            {
+               TR_AP("#7");
                emitcode("mov","%s,%s", DP2_RESULT_REG, leftByte);
                   }
                   // And MSB in A.
@@ -6586,11 +7812,11 @@ shiftR2Left2Result (operand * left, int offl,
   /* a:x >> shCount (x = lsb(result)) */
   if (sign)
   {
-    AccAXRshS(aopGet(AOP(result), offr, FALSE, FALSE, FALSE), shCount);
+     AccAXRshS(lsb, shCount);
   }
   else
   {
-    AccAXRsh(aopGet(AOP(result), offr, FALSE, FALSE, FALSE), shCount);
+    AccAXRsh(lsb, shCount);
   }
   
   _storeAxResults(lsb, result, offr);
@@ -6907,7 +8133,7 @@ genLeftShiftLiteral (operand * left,
   aopOp(left, ic, FALSE, FALSE);
   aopOp(result, ic, FALSE, (AOP_TYPE(left) == AOP_DPTR));
 
-#if 1 // debug spew
+#if 0 // debug spew
   if (IS_SYMOP(left) && OP_SYMBOL(left)->aop)
   {
        emitcode(";", "left (%s) is %d", OP_SYMBOL(left)->rname, AOP_TYPE(left));
@@ -7021,7 +8247,7 @@ genLeftShift (iCode * ic)
        * but since I'm too lazy to fix that today, at least we can make
        * some small improvement.
        */
-       emitcode("mov", "b,#0x%02x",
+       emitcode("mov", "b,#!constbyte",
                        ((int) floatFromVal (AOP (right)->aopu.aop_lit)) + 1);
   }
   else
@@ -7070,19 +8296,19 @@ genLeftShift (iCode * ic)
 
       l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
       MOVA (l);
-      emitcode ("sjmp", "%05d$", tlbl1->key + 100);
-      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("sjmp", "!tlabel", tlbl1->key + 100);
+      emitcode ("", "!tlabeldef", tlbl->key + 100);
       emitcode ("add", "a,acc");
-      emitcode ("", "%05d$:", tlbl1->key + 100);
-      emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+      emitcode ("", "!tlabeldef", tlbl1->key + 100);
+      emitcode ("djnz", "b,!tlabel", tlbl->key + 100);
       aopPut (AOP (result), "a", 0);
       goto release;
     }
 
   reAdjustPreg (AOP (result));
 
-  emitcode ("sjmp", "%05d$", tlbl1->key + 100);
-  emitcode ("", "%05d$:", tlbl->key + 100);
+  emitcode ("sjmp", "!tlabel", tlbl1->key + 100);
+  emitcode ("", "!tlabeldef", tlbl->key + 100);
   l = aopGet (AOP (result), offset, FALSE, FALSE, TRUE);
   MOVA (l);
   emitcode ("add", "a,acc");
@@ -7098,8 +8324,8 @@ genLeftShift (iCode * ic)
   _endLazyDPSEvaluation ();
   reAdjustPreg (AOP (result));
 
-  emitcode ("", "%05d$:", tlbl1->key + 100);
-  emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+  emitcode ("", "!tlabeldef", tlbl1->key + 100);
+  emitcode ("djnz", "b,!tlabel", tlbl->key + 100);
 release:
   freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
@@ -7164,28 +8390,54 @@ static void
 shiftRLong (operand * left, int offl,
            operand * result, int sign)
 {
-  if (!sign)
+  int isSameRegs=sameRegs(AOP(left),AOP(result));
+
+  if (isSameRegs && offl>1) {
+    // we are in big trouble, but this shouldn't happen
+    werror(E_INTERNAL_ERROR, __FILE__, __LINE__);
+  }
+
+  MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE));
+  
+  if (offl==MSB16) {
+    // shift is > 8
+    if (sign) {
+      emitcode ("rlc", "a");
+      emitcode ("subb", "a,acc");
+      emitcode ("xch", "a,%s", aopGet(AOP(left), MSB32, FALSE, FALSE));
+    } else {
+      aopPut (AOP(result), zero, MSB32);
+    }
+  }
+
+  if (!sign) {
     emitcode ("clr", "c");
-  MOVA (aopGet (AOP (left), MSB32, FALSE, FALSE, TRUE));
-  if (sign)
+  } else {
     emitcode ("mov", "c,acc.7");
-  emitcode ("rrc", "a");
-  aopPut (AOP (result), "a", MSB32 - offl);
-  if (offl == MSB16)
-    /* add sign of "a" */
-    addSign (result, MSB32, sign);
+  }
 
-  MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE, TRUE));
   emitcode ("rrc", "a");
-  aopPut (AOP (result), "a", MSB24 - offl);
 
-  MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE, TRUE));
+  if (isSameRegs && offl==MSB16) {
+    emitcode ("xch", "a,%s",aopGet (AOP (left), MSB24, FALSE, FALSE));
+  } else {
+    aopPut (AOP (result), "a", MSB32);
+    MOVA (aopGet (AOP (left), MSB24, FALSE, FALSE));
+  }
+
+  emitcode ("rrc", "a");
+  if (isSameRegs && offl==1) {
+    emitcode ("xch", "a,%s",aopGet (AOP (left), MSB16, FALSE, FALSE));
+  } else {
+    aopPut (AOP (result), "a", MSB24);
+    MOVA (aopGet (AOP (left), MSB16, FALSE, FALSE));
+  }
   emitcode ("rrc", "a");
   aopPut (AOP (result), "a", MSB16 - offl);
 
   if (offl == LSB)
     {
-      MOVA (aopGet (AOP (left), LSB, FALSE, FALSE, TRUE));
+      MOVA (aopGet (AOP (left), LSB, FALSE, FALSE));
       emitcode ("rrc", "a");
       aopPut (AOP (result), "a", LSB);
     }
@@ -7344,11 +8596,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
 
@@ -7395,7 +8647,7 @@ genSignedRightShift (iCode * ic)
        * but since I'm too lazy to fix that today, at least we can make
        * some small improvement.
        */
-       emitcode("mov", "b,#0x%02x",
+       emitcode("mov", "b,#!constbyte",
                        ((int) floatFromVal (AOP (right)->aopu.aop_lit)) + 1);
   }
   else
@@ -7446,19 +8698,19 @@ genSignedRightShift (iCode * ic)
     {
       l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
       MOVA (l);
-      emitcode ("sjmp", "%05d$", tlbl1->key + 100);
-      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("sjmp", "!tlabel", tlbl1->key + 100);
+      emitcode ("", "!tlabeldef", tlbl->key + 100);
       emitcode ("mov", "c,ov");
       emitcode ("rrc", "a");
-      emitcode ("", "%05d$:", tlbl1->key + 100);
-      emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+      emitcode ("", "!tlabeldef", tlbl1->key + 100);
+      emitcode ("djnz", "b,!tlabel", tlbl->key + 100);
       aopPut (AOP (result), "a", 0);
       goto release;
     }
 
   reAdjustPreg (AOP (result));
-  emitcode ("sjmp", "%05d$", tlbl1->key + 100);
-  emitcode ("", "%05d$:", tlbl->key + 100);
+  emitcode ("sjmp", "!tlabel", tlbl1->key + 100);
+  emitcode ("", "!tlabeldef", tlbl->key + 100);
   emitcode ("mov", "c,ov");
   _startLazyDPSEvaluation ();
   while (size--)
@@ -7470,8 +8722,8 @@ genSignedRightShift (iCode * ic)
     }
   _endLazyDPSEvaluation ();
   reAdjustPreg (AOP (result));
-  emitcode ("", "%05d$:", tlbl1->key + 100);
-  emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+  emitcode ("", "!tlabeldef", tlbl1->key + 100);
+  emitcode ("djnz", "b,!tlabel", tlbl->key + 100);
 
 release:
   freeAsmop (left, NULL, ic, TRUE);
@@ -7539,7 +8791,7 @@ genRightShift (iCode * ic)
        * but since I'm too lazy to fix that today, at least we can make
        * some small improvement.
        */
-       emitcode("mov", "b,#0x%02x",
+       emitcode("mov", "b,#!constbyte",
                        ((int) floatFromVal (AOP (right)->aopu.aop_lit)) + 1);
   }
   else
@@ -7586,19 +8838,19 @@ genRightShift (iCode * ic)
     {
       l = aopGet (AOP (left), 0, FALSE, FALSE, TRUE);
       MOVA (l);
-      emitcode ("sjmp", "%05d$", tlbl1->key + 100);
-      emitcode ("", "%05d$:", tlbl->key + 100);
+      emitcode ("sjmp", "!tlabel", tlbl1->key + 100);
+      emitcode ("", "!tlabeldef", tlbl->key + 100);
       CLRC;
       emitcode ("rrc", "a");
-      emitcode ("", "%05d$:", tlbl1->key + 100);
-      emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+      emitcode ("", "!tlabeldef", tlbl1->key + 100);
+      emitcode ("djnz", "b,!tlabel", tlbl->key + 100);
       aopPut (AOP (result), "a", 0);
       goto release;
     }
 
   reAdjustPreg (AOP (result));
-  emitcode ("sjmp", "%05d$", tlbl1->key + 100);
-  emitcode ("", "%05d$:", tlbl->key + 100);
+  emitcode ("sjmp", "!tlabel", tlbl1->key + 100);
+  emitcode ("", "!tlabeldef", tlbl->key + 100);
   CLRC;
   _startLazyDPSEvaluation ();
   while (size--)
@@ -7611,8 +8863,8 @@ genRightShift (iCode * ic)
   _endLazyDPSEvaluation ();
   reAdjustPreg (AOP (result));
 
-  emitcode ("", "%05d$:", tlbl1->key + 100);
-  emitcode ("djnz", "b,%05d$", tlbl->key + 100);
+  emitcode ("", "!tlabeldef", tlbl1->key + 100);
+  emitcode ("djnz", "b,!tlabel", tlbl->key + 100);
 
 release:
   freeAsmop (left, NULL, ic, TRUE);
@@ -7654,7 +8906,7 @@ genUnpackBits (operand * result, char *rname, int ptype)
 
     case CPOINTER:
       emitcode ("clr", "a");
-      emitcode ("movc", "a", "@a+dptr");
+      emitcode ("movc", "a,@a+dptr");
       break;
 
     case GPOINTER:
@@ -7672,7 +8924,7 @@ genUnpackBits (operand * result, char *rname, int ptype)
       /* shift right acc */
       AccRsh (shCnt);
 
-      emitcode ("anl", "a,#0x%02x",
+      emitcode ("anl", "a,#!constbyte",
                ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
       aopPut (AOP (result), "a", offset);
       return;
@@ -7706,7 +8958,7 @@ genUnpackBits (operand * result, char *rname, int ptype)
        case CPOINTER:
          emitcode ("clr", "a");
          emitcode ("inc", "dptr");
-         emitcode ("movc", "a", "@a+dptr");
+         emitcode ("movc", "a,@a+dptr");
          break;
 
        case GPOINTER:
@@ -7726,7 +8978,7 @@ genUnpackBits (operand * result, char *rname, int ptype)
 
   if (rlen)
     {
-      emitcode ("anl", "a,#0x%02x", ((unsigned char) -1) >> (rlen));
+      emitcode ("anl", "a,#!constbyte", ((unsigned char) -1) >> (rlen));
       aopPut (AOP (result), "a", offset);
     }
 
@@ -7771,7 +9023,8 @@ genDataPointerGet (operand * left,
 static void
 genNearPointerGet (operand * left,
                   operand * result,
-                  iCode * ic)
+                  iCode * ic,
+                  iCode *pi)
 {
   asmop *aop = NULL;
   regs *preg = NULL;
@@ -7840,7 +9093,7 @@ genNearPointerGet (operand * left,
              aopPut (AOP (result), buffer, offset);
            }
          offset++;
-         if (size)
+         if (size || pi)
            emitcode ("inc", "%s", rname);
        }
     }
@@ -7849,6 +9102,9 @@ genNearPointerGet (operand * left,
   if (aop)
     {
       /* we had to allocate for this iCode */
+      if (pi) { /* post increment present */
+       aopPut(AOP ( left ),rname,0);
+      }
       freeAsmop (NULL, aop, ic, TRUE);
     }
   else
@@ -7861,7 +9117,8 @@ genNearPointerGet (operand * left,
       if (AOP_SIZE (result) > 1 &&
          !OP_SYMBOL (left)->remat &&
          (OP_SYMBOL (left)->liveTo > ic->seq ||
-          ic->depth))
+          ic->depth) &&
+         !pi)
        {
          int size = AOP_SIZE (result) - 1;
          while (size--)
@@ -7871,7 +9128,7 @@ genNearPointerGet (operand * left,
 
   /* done */
   freeAsmop (result, NULL, ic, TRUE);
-
+  if (pi) pi->generated = 1;
 }
 
 /*-----------------------------------------------------------------*/
@@ -7880,7 +9137,8 @@ genNearPointerGet (operand * left,
 static void
 genPagedPointerGet (operand * left,
                    operand * result,
-                   iCode * ic)
+                   iCode * ic,
+                   iCode * pi)
 {
   asmop *aop = NULL;
   regs *preg = NULL;
@@ -7927,7 +9185,7 @@ genPagedPointerGet (operand * left,
 
          offset++;
 
-         if (size)
+         if (size || pi)
            emitcode ("inc", "%s", rname);
        }
     }
@@ -7936,6 +9194,7 @@ genPagedPointerGet (operand * left,
   if (aop)
     {
       /* we had to allocate for this iCode */
+      if (pi) aopPut ( AOP (left), rname, 0);
       freeAsmop (NULL, aop, ic, TRUE);
     }
   else
@@ -7948,7 +9207,8 @@ genPagedPointerGet (operand * left,
       if (AOP_SIZE (result) > 1 &&
          !OP_SYMBOL (left)->remat &&
          (OP_SYMBOL (left)->liveTo > ic->seq ||
-          ic->depth))
+          ic->depth) &&
+         !pi)
        {
          int size = AOP_SIZE (result) - 1;
          while (size--)
@@ -7958,8 +9218,7 @@ genPagedPointerGet (operand * left,
 
   /* done */
   freeAsmop (result, NULL, ic, TRUE);
-
-
+  if (pi) pi->generated = 1;
 }
 
 /*-----------------------------------------------------------------*/
@@ -7967,9 +9226,9 @@ genPagedPointerGet (operand * left,
 /*-----------------------------------------------------------------*/
 static void
 genFarPointerGet (operand * left,
-                 operand * result, iCode * ic)
+                 operand * result, iCode * ic, iCode *pi)
 {
-  int size, offset;
+    int size, offset, dopi=1;
   sym_link *retype = getSpec (operandType (result));
   sym_link *letype = getSpec (operandType (left));
   D (emitcode (";", "genFarPointerGet");
@@ -7979,7 +9238,7 @@ genFarPointerGet (operand * left,
 
   /* if the operand is already in dptr
      then we do nothing else we move the value to dptr */
-  if (AOP_TYPE (left) != AOP_STR)
+  if (AOP_TYPE (left) != AOP_STR && !AOP_INDPTRn(left) )
     {
       /* if this is remateriazable */
       if (AOP_TYPE (left) == AOP_IMMD)
@@ -7994,7 +9253,8 @@ genFarPointerGet (operand * left,
            {
              emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
              emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE));
-             emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
            }
          else
            {
@@ -8003,59 +9263,101 @@ genFarPointerGet (operand * left,
                );
              emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, TRUE));
              emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, TRUE));
-             emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
              emitcode ("pop", "dph");
              emitcode ("pop", "dpl");
+             dopi =0;
            }
          _endLazyDPSEvaluation ();
        }
     }
   /* so dptr know contains the address */
-  freeAsmop (left, NULL, ic, TRUE);
-  aopOp (result, ic, FALSE, TRUE);
+  aopOp (result, ic, FALSE, (AOP_INDPTRn(left) ? FALSE : TRUE));
 
   /* if bit then unpack */
-  if (IS_BITVAR (retype) || IS_BITVAR (letype))
-    genUnpackBits (result, "dptr", FPOINTER);
-  else
+  if (IS_BITVAR (retype) || IS_BITVAR (letype)) {
+      if (AOP_INDPTRn(left)) {
+         genSetDPTR(AOP(left)->aopu.dptr);
+      }
+      genUnpackBits (result, "dptr", FPOINTER);
+      if (AOP_INDPTRn(left)) {
+         genSetDPTR(0);
+      }
+  } else
     {
       size = AOP_SIZE (result);
       offset = 0;
 
-      _startLazyDPSEvaluation ();
-      while (size--)
-       {
-
-         genSetDPTR (0);
-         _flushLazyDPS ();
-
-         emitcode ("movx", "a,@dptr");
-         if (size)
-           emitcode ("inc", "dptr");
-
-         aopPut (AOP (result), "a", offset++);
-       }
-      _endLazyDPSEvaluation ();
+      if (AOP_INDPTRn(left) && AOP_USESDPTR(result)) {
+         while (size--) {
+             genSetDPTR(AOP(left)->aopu.dptr);
+             emitcode ("movx", "a,@dptr");
+             if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
+                 emitcode ("inc", "dptr");
+             genSetDPTR (0);
+             aopPut (AOP (result), "a", offset++);
+         }
+      } else {
+         _startLazyDPSEvaluation ();
+         while (size--) {
+             if (AOP_INDPTRn(left)) {
+                 genSetDPTR(AOP(left)->aopu.dptr);
+             } else {
+                 genSetDPTR (0);
+             }
+             _flushLazyDPS ();
+             
+             emitcode ("movx", "a,@dptr");
+             if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
+                 emitcode ("inc", "dptr");
+             
+             aopPut (AOP (result), "a", offset++);
+         }
+         _endLazyDPSEvaluation ();
+      }
     }
+  if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) {
+      if (!AOP_INDPTRn(left)) {
+         aopPut ( AOP (left), "dpl", 0);
+         aopPut ( AOP (left), "dph", 1);
+         if (options.model == MODEL_FLAT24)
+             aopPut ( AOP (left), "dpx", 2);
+      }
+    pi->generated = 1;
+  } else if ((OP_SYMBOL(left)->ruonly || AOP_INDPTRn(left)) && 
+            AOP_SIZE(result) > 1 &&
+            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (result) - 1;
+      if (AOP_INDPTRn(left)) {
+         genSetDPTR(AOP(left)->aopu.dptr);
+      }
+      while (size--) emitcode ("lcall","__decdptr");
+      if (AOP_INDPTRn(left)) {
+         genSetDPTR(0);
+      }
+  }
 
+  freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
-/* emitcodePointerGet - gget value from code space                  */
+/* genCodePointerGet - get value from code space                  */
 /*-----------------------------------------------------------------*/
 static void
-emitcodePointerGet (operand * left,
-                   operand * result, iCode * ic)
+genCodePointerGet (operand * left,
+                   operand * result, iCode * ic, iCode *pi)
 {
-  int size, offset;
+  int size, offset, dopi=1;
   sym_link *retype = getSpec (operandType (result));
 
   aopOp (left, ic, FALSE, FALSE);
 
   /* if the operand is already in dptr
      then we do nothing else we move the value to dptr */
-  if (AOP_TYPE (left) != AOP_STR)
+  if (AOP_TYPE (left) != AOP_STR && !AOP_INDPTRn(left))
     {
       /* if this is remateriazable */
       if (AOP_TYPE (left) == AOP_IMMD)
@@ -8069,7 +9371,8 @@ emitcodePointerGet (operand * left,
            {
              emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
              emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE));
-             emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
            }
          else
            {
@@ -8078,40 +9381,84 @@ emitcodePointerGet (operand * left,
                );
              emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, TRUE));
              emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, TRUE));
-             emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
              emitcode ("pop", "dph");
              emitcode ("pop", "dpl");
+             dopi=0;
            }
          _endLazyDPSEvaluation ();
        }
     }
   /* so dptr know contains the address */
-  freeAsmop (left, NULL, ic, TRUE);
-  aopOp (result, ic, FALSE, TRUE);
+  aopOp (result, ic, FALSE, (AOP_INDPTRn(left) ? FALSE : TRUE));
 
   /* if bit then unpack */
-  if (IS_BITVAR (retype))
-    genUnpackBits (result, "dptr", CPOINTER);
-  else
+  if (IS_BITVAR (retype)) {
+      if (AOP_INDPTRn(left)) {
+         genSetDPTR(AOP(left)->aopu.dptr);
+      }
+      genUnpackBits (result, "dptr", CPOINTER);
+      if (AOP_INDPTRn(left)) {
+         genSetDPTR(0);
+      }
+  } else
     {
       size = AOP_SIZE (result);
       offset = 0;
-
-      _startLazyDPSEvaluation ();
-      while (size--)
-       {
-         genSetDPTR (0);
-         _flushLazyDPS ();
-
-         emitcode ("clr", "a");
-         emitcode ("movc", "a,@a+dptr");
-         if (size)
-           emitcode ("inc", "dptr");
-         aopPut (AOP (result), "a", offset++);
-       }
-      _endLazyDPSEvaluation ();
+      if (AOP_INDPTRn(left) && AOP_USESDPTR(result)) {
+         while (size--) {
+             genSetDPTR(AOP(left)->aopu.dptr);
+             emitcode ("clr", "a");
+             emitcode ("movc", "a,@a+dptr");
+             if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
+                 emitcode ("inc", "dptr");
+             genSetDPTR (0);
+             aopPut (AOP (result), "a", offset++);
+         }
+      } else {
+         _startLazyDPSEvaluation ();
+         while (size--)
+             {
+                 if (AOP_INDPTRn(left)) {
+                     genSetDPTR(AOP(left)->aopu.dptr);
+                 } else {
+                     genSetDPTR (0);
+                 }
+                 _flushLazyDPS ();
+                 
+                 emitcode ("clr", "a");
+                 emitcode ("movc", "a,@a+dptr");
+                 if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
+                     emitcode ("inc", "dptr");
+                 aopPut (AOP (result), "a", offset++);
+             }
+         _endLazyDPSEvaluation ();
+      }
     }
-
+  if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) {
+      if (!AOP_INDPTRn(left)) {
+         aopPut ( AOP (left), "dpl", 0);
+         aopPut ( AOP (left), "dph", 1);
+         if (options.model == MODEL_FLAT24)
+             aopPut ( AOP (left), "dpx", 2);
+      }
+      pi->generated = 1;
+  } else if ((OP_SYMBOL(left)->ruonly || AOP_INDPTRn(left)) && 
+            AOP_SIZE(result) > 1 &&
+            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (result) - 1;
+      if (AOP_INDPTRn(left)) {
+         genSetDPTR(AOP(left)->aopu.dptr);
+      }
+      while (size--) emitcode ("lcall","__decdptr");
+      if (AOP_INDPTRn(left)) {
+         genSetDPTR(0);
+      }
+  }
+  
+  freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
 }
 
@@ -8120,7 +9467,7 @@ emitcodePointerGet (operand * left,
 /*-----------------------------------------------------------------*/
 static void
 genGenPointerGet (operand * left,
-                 operand * result, iCode * ic)
+                 operand * result, iCode * ic, iCode * pi)
 {
   int size, offset;
   sym_link *retype = getSpec (operandType (result));
@@ -8128,7 +9475,7 @@ genGenPointerGet (operand * left,
 
   D (emitcode (";", "genGenPointerGet "); );
 
-  aopOp (left, ic, FALSE, TRUE);
+  aopOp (left, ic, FALSE, (OP_SYMBOL(left)->ruonly ? FALSE : TRUE));
 
   /* if the operand is already in dptr
      then we do nothing else we move the value to dptr */
@@ -8138,11 +9485,16 @@ genGenPointerGet (operand * left,
       if (AOP_TYPE (left) == AOP_IMMD)
        {
          emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE, FALSE));
-         emitcode ("mov", "b,#%d", pointerCode (retype));
+         if (AOP(left)->aopu.aop_immd.from_cast_remat) 
+                 emitcode ("mov", "b,%s",aopGet(AOP (left), AOP_SIZE(left)-1, FALSE, FALSE, FALSE));
+         else
+                 emitcode ("mov", "b,#%d", pointerCode (retype));
        }
       else
        {                       /* we need to get it byte by byte */
          _startLazyDPSEvaluation ();
+#if 0  // I see no point at all to this code.
+       // So I yanked it. Kill at some future date if no bugs rear their heads.
          if (AOP(left)->type==AOP_DPTR2) {
            char *l;
            l=aopGet(AOP(left),0,FALSE,FALSE,TRUE);
@@ -8153,41 +9505,92 @@ genGenPointerGet (operand * left,
            genSetDPTR(0);
            _flushLazyDPS();
            emitcode ("mov", "dph,%s", l);
-           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 {
+           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));
-           emitcode ("mov", "dpx,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
-           emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+           if (options.model == MODEL_FLAT24) {
+             emitcode ("mov", "dpx,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
+             emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
+           } else {
+             emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
+           }
          }
          _endLazyDPSEvaluation ();
        }
     }
-  /* so dptr know contains the address */
-  freeAsmop (left, NULL, ic, TRUE);
+
+  /* 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))
+  {
     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)
-           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) {
+    aopPut ( AOP (left), "dpl", 0);
+    aopPut ( AOP (left), "dph", 1);
+    if (options.model == MODEL_FLAT24) {
+       aopPut ( AOP (left), "dpx", 2);
+       aopPut ( AOP (left), "b", 3);   
+    } else  aopPut ( AOP (left), "b", 2);      
+    pi->generated = 1;
+  } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
+            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (result) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
+  }
+
+  freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
 }
 
@@ -8195,7 +9598,7 @@ genGenPointerGet (operand * left,
 /* genPointerGet - generate code for pointer get                   */
 /*-----------------------------------------------------------------*/
 static void
-genPointerGet (iCode * ic)
+genPointerGet (iCode * ic, iCode *pi)
 {
   operand *left, *result;
   sym_link *type, *etype;
@@ -8219,7 +9622,13 @@ genPointerGet (iCode * ic)
       /* we have to go by the storage class */
       p_type = PTR_TYPE (SPEC_OCLS (etype));
     }
-
+  /* special case when cast remat */
+  if (p_type == GPOINTER && OP_SYMBOL(left)->remat &&
+      IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) {
+         left = IC_RIGHT(OP_SYMBOL(left)->rematiCode);
+         type = operandType (left);
+         p_type = DCL_TYPE (type);
+  }
   /* now that we have the pointer type we assign
      the pointer values */
   switch (p_type)
@@ -8227,23 +9636,23 @@ genPointerGet (iCode * ic)
 
     case POINTER:
     case IPOINTER:
-      genNearPointerGet (left, result, ic);
+      genNearPointerGet (left, result, ic, pi);
       break;
 
     case PPOINTER:
-      genPagedPointerGet (left, result, ic);
+      genPagedPointerGet (left, result, ic, pi);
       break;
 
     case FPOINTER:
-      genFarPointerGet (left, result, ic);
+      genFarPointerGet (left, result, ic, pi);
       break;
 
     case CPOINTER:
-      emitcodePointerGet (left, result, ic);
+      genCodePointerGet (left, result, ic, pi);
       break;
 
     case GPOINTER:
-      genGenPointerGet (left, result, ic);
+      genGenPointerGet (left, result, ic, pi);
       break;
     }
 
@@ -8302,7 +9711,7 @@ genPackBits (sym_link * etype,
              break;
            }
 
-         emitcode ("anl", "a,#0x%02x", (unsigned char)
+         emitcode ("anl", "a,#!constbyte", (unsigned char)
                    ((unsigned char) (0xFF << (blen + bstr)) |
                     (unsigned char) (0xFF >> (8 - bstr))));
          emitcode ("orl", "a,b");
@@ -8394,7 +9803,7 @@ genPackBits (sym_link * etype,
          break;
        }
 
-      emitcode ("anl", "a,#0x%02x", ((unsigned char) -1 << rLen));
+      emitcode ("anl", "a,#!constbyte", ((unsigned char) -1 << rLen));
       emitcode ("orl", "a,b");
     }
 
@@ -8452,7 +9861,8 @@ genDataPointerSet (operand * right,
 static void
 genNearPointerSet (operand * right,
                   operand * result,
-                  iCode * ic)
+                  iCode * ic,
+                  iCode * pi)
 {
   asmop *aop = NULL;
   regs *preg = NULL;
@@ -8491,7 +9901,6 @@ genNearPointerSet (operand * right,
   else
     rname = aopGet (AOP (result), 0, FALSE, FALSE, FALSE);
 
-  freeAsmop (result, NULL, ic, TRUE);
   aopOp (right, ic, FALSE, FALSE);
 
   /* if bitfield then unpack the bits */
@@ -8513,7 +9922,7 @@ genNearPointerSet (operand * right,
            }
          else
            emitcode ("mov", "@%s,%s", rname, l);
-         if (size)
+         if (size || pi)
            emitcode ("inc", "%s", rname);
          offset++;
        }
@@ -8523,6 +9932,7 @@ genNearPointerSet (operand * right,
   if (aop)
     {
       /* we had to allocate for this iCode */
+      if (pi) aopPut (AOP (result),rname,0);
       freeAsmop (NULL, aop, ic, TRUE);
     }
   else
@@ -8535,7 +9945,8 @@ genNearPointerSet (operand * right,
       if (AOP_SIZE (right) > 1 &&
          !OP_SYMBOL (result)->remat &&
          (OP_SYMBOL (result)->liveTo > ic->seq ||
-          ic->depth))
+          ic->depth) &&
+         !pi)
        {
          int size = AOP_SIZE (right) - 1;
          while (size--)
@@ -8544,6 +9955,8 @@ genNearPointerSet (operand * right,
     }
 
   /* done */
+  if (pi) pi->generated = 1;
+  freeAsmop (result, NULL, ic, TRUE);
   freeAsmop (right, NULL, ic, TRUE);
 
 
@@ -8555,7 +9968,8 @@ genNearPointerSet (operand * right,
 static void
 genPagedPointerSet (operand * right,
                    operand * result,
-                   iCode * ic)
+                   iCode * ic,
+                   iCode *pi)
 {
   asmop *aop = NULL;
   regs *preg = NULL;
@@ -8582,7 +9996,6 @@ genPagedPointerSet (operand * right,
   else
     rname = aopGet (AOP (result), 0, FALSE, FALSE, FALSE);
 
-  freeAsmop (result, NULL, ic, TRUE);
   aopOp (right, ic, FALSE, FALSE);
 
   /* if bitfield then unpack the bits */
@@ -8601,7 +10014,7 @@ genPagedPointerSet (operand * right,
          MOVA (l);
          emitcode ("movx", "@%s,a", rname);
 
-         if (size)
+         if (size || pi)
            emitcode ("inc", "%s", rname);
 
          offset++;
@@ -8611,6 +10024,7 @@ genPagedPointerSet (operand * right,
   /* now some housekeeping stuff */
   if (aop)
     {
+      if (pi) aopPut (AOP (result),rname,0);
       /* we had to allocate for this iCode */
       freeAsmop (NULL, aop, ic, TRUE);
     }
@@ -8624,7 +10038,8 @@ genPagedPointerSet (operand * right,
       if (AOP_SIZE (right) > 1 &&
          !OP_SYMBOL (result)->remat &&
          (OP_SYMBOL (result)->liveTo > ic->seq ||
-          ic->depth))
+          ic->depth) &&
+         !pi)
        {
          int size = AOP_SIZE (right) - 1;
          while (size--)
@@ -8633,6 +10048,8 @@ genPagedPointerSet (operand * right,
     }
 
   /* done */
+  if (pi) pi->generated = 1;
+  freeAsmop (result, NULL, ic, TRUE);
   freeAsmop (right, NULL, ic, TRUE);
 
 
@@ -8643,9 +10060,9 @@ genPagedPointerSet (operand * right,
 /*-----------------------------------------------------------------*/
 static void
 genFarPointerSet (operand * right,
-                 operand * result, iCode * ic)
+                 operand * result, iCode * ic, iCode *pi)
 {
-  int size, offset;
+  int size, offset, dopi=1;
   sym_link *retype = getSpec (operandType (right));
   sym_link *letype = getSpec (operandType (result));
 
@@ -8653,7 +10070,7 @@ genFarPointerSet (operand * right,
 
   /* if the operand is already in dptr
      then we do nothing else we move the value to dptr */
-  if (AOP_TYPE (result) != AOP_STR)
+  if (AOP_TYPE (result) != AOP_STR && !AOP_INDPTRn(result))
     {
       /* if this is remateriazable */
       if (AOP_TYPE (result) == AOP_IMMD)
@@ -8666,7 +10083,8 @@ genFarPointerSet (operand * right,
            {
              emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, TRUE));
              emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, TRUE));
-             emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
            }
          else
            {
@@ -8675,41 +10093,84 @@ genFarPointerSet (operand * right,
                );
              emitcode ("push", "%s", aopGet (AOP (result), 0, FALSE, TRUE, TRUE));
              emitcode ("push", "%s", aopGet (AOP (result), 1, FALSE, TRUE, TRUE));
-             emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+             if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
              emitcode ("pop", "dph");
              emitcode ("pop", "dpl");
+             dopi=0;
            }
          _endLazyDPSEvaluation ();
        }
     }
   /* so dptr know contains the address */
-  freeAsmop (result, NULL, ic, TRUE);
-  aopOp (right, ic, FALSE, TRUE);
+  aopOp (right, ic, FALSE, (AOP_INDPTRn(result) ? FALSE : TRUE));
 
   /* if bit then unpack */
-  if (IS_BITVAR (retype) || IS_BITVAR (letype))
-    genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", FPOINTER);
-  else
-    {
+  if (IS_BITVAR (retype) || IS_BITVAR (letype)) {
+      if (AOP_INDPTRn(result)) {
+         genSetDPTR(AOP(result)->aopu.dptr);
+      }
+      genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", FPOINTER);
+      if (AOP_INDPTRn(result)) {
+         genSetDPTR(0);
+      }
+  } else {
       size = AOP_SIZE (right);
       offset = 0;
-
-      _startLazyDPSEvaluation ();
-      while (size--)
-       {
-         char *l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
-         MOVA (l);
-
-         genSetDPTR (0);
-         _flushLazyDPS ();
-
-         emitcode ("movx", "@dptr,a");
-         if (size)
-           emitcode ("inc", "dptr");
-       }
-      _endLazyDPSEvaluation ();
-    }
-
+      if (AOP_INDPTRn(result) && AOP_USESDPTR(right)) {
+         while (size--) {
+             char *l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
+             MOVA (l);
+             
+             genSetDPTR(AOP(result)->aopu.dptr);
+             emitcode ("movx", "@dptr,a");
+             if (size || (dopi && pi && AOP_TYPE (result) != AOP_IMMD))
+                 emitcode ("inc", "dptr");
+             genSetDPTR (0);
+         }
+      } else {
+         _startLazyDPSEvaluation ();
+         while (size--) {
+             char *l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
+             MOVA (l);
+             
+             if (AOP_INDPTRn(result)) {
+                 genSetDPTR(AOP(result)->aopu.dptr);
+             } else {
+                 genSetDPTR (0);
+             }
+             _flushLazyDPS ();
+             
+             emitcode ("movx", "@dptr,a");
+             if (size || (dopi && pi && AOP_TYPE (result) != AOP_IMMD))
+                 emitcode ("inc", "dptr");
+         }
+         _endLazyDPSEvaluation ();
+      }
+  }
+  
+  if (dopi && pi && AOP_TYPE (result) != AOP_IMMD) {
+      if (!AOP_INDPTRn(result)) {
+         aopPut (AOP(result),"dpl",0);
+         aopPut (AOP(result),"dph",1);
+         if (options.model == MODEL_FLAT24)
+             aopPut (AOP(result),"dpx",2);
+      }
+      pi->generated=1;
+  } else if ((OP_SYMBOL(result)->ruonly || AOP_INDPTRn(result)) && 
+            AOP_SIZE(right) > 1 &&
+            (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (right) - 1;
+      if (AOP_INDPTRn(result)) {
+         genSetDPTR(AOP(result)->aopu.dptr);
+      } 
+      while (size--) emitcode ("lcall","__decdptr");
+      if (AOP_INDPTRn(result)) {
+         genSetDPTR(0);
+      }
+  }
+  freeAsmop (result, NULL, ic, TRUE);
   freeAsmop (right, NULL, ic, TRUE);
 }
 
@@ -8718,13 +10179,13 @@ genFarPointerSet (operand * right,
 /*-----------------------------------------------------------------*/
 static void
 genGenPointerSet (operand * right,
-                 operand * result, iCode * ic)
+                 operand * result, iCode * ic, iCode *pi)
 {
   int size, offset;
   sym_link *retype = getSpec (operandType (right));
   sym_link *letype = getSpec (operandType (result));
 
-  aopOp (result, ic, FALSE, TRUE);
+  aopOp (result, ic, FALSE, OP_SYMBOL(result)->ruonly ? FALSE : TRUE);
 
   /* if the operand is already in dptr
      then we do nothing else we move the value to dptr */
@@ -8735,19 +10196,25 @@ genGenPointerSet (operand * right,
       if (AOP_TYPE (result) == AOP_IMMD)
        {
          emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE, FALSE));
-         emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE, FALSE));
+         if (AOP(result)->aopu.aop_immd.from_cast_remat) 
+                 emitcode ("mov", "b,%s",aopGet(AOP (result), AOP_SIZE(result)-1, FALSE, FALSE, FALSE));
+         else
+                 emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE, FALSE));
        }
       else
        {                       /* we need to get it byte by byte */
          emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE, TRUE));
          emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE, TRUE));
-         emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
-         emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE, TRUE));
+         if (options.model == MODEL_FLAT24) {
+           emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+           emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE, TRUE));
+         } else {
+           emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
+         }
        }
       _endLazyDPSEvaluation ();
     }
   /* so dptr know contains the address */
-  freeAsmop (result, NULL, ic, TRUE);
   aopOp (right, ic, FALSE, TRUE);
 
   /* if bit then unpack */
@@ -8768,12 +10235,29 @@ genGenPointerSet (operand * right,
          _flushLazyDPS ();
 
          emitcode ("lcall", "__gptrput");
-         if (size)
+         if (size || (pi && AOP_TYPE (result) != AOP_IMMD))
            emitcode ("inc", "dptr");
        }
       _endLazyDPSEvaluation ();
     }
 
+  if (pi && AOP_TYPE (result) != AOP_IMMD) {
+      aopPut (AOP(result),"dpl",0);
+      aopPut (AOP(result),"dph",1);
+      if (options.model == MODEL_FLAT24) {
+         aopPut (AOP(result),"dpx",2);
+         aopPut (AOP(result),"b",3);
+      } else {
+         aopPut (AOP(result),"b",2);
+      }
+      pi->generated=1;
+  } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 &&
+            (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (right) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
+  }
+  freeAsmop (result, NULL, ic, TRUE);
   freeAsmop (right, NULL, ic, TRUE);
 }
 
@@ -8781,7 +10265,7 @@ genGenPointerSet (operand * right,
 /* genPointerSet - stores the value into a pointer location        */
 /*-----------------------------------------------------------------*/
 static void
-genPointerSet (iCode * ic)
+genPointerSet (iCode * ic, iCode *pi)
 {
   operand *right, *result;
   sym_link *type, *etype;
@@ -8807,6 +10291,13 @@ genPointerSet (iCode * ic)
       /* we have to go by the storage class */
       p_type = PTR_TYPE (SPEC_OCLS (etype));
     }
+  /* special case when cast remat */
+  if (p_type == GPOINTER && OP_SYMBOL(result)->remat &&
+      IS_CAST_ICODE(OP_SYMBOL(result)->rematiCode)) {
+         result = IC_RIGHT(OP_SYMBOL(result)->rematiCode);
+         type = operandType (result);
+         p_type = DCL_TYPE (type);
+  }
 
   /* now that we have the pointer type we assign
      the pointer values */
@@ -8815,20 +10306,24 @@ genPointerSet (iCode * ic)
 
     case POINTER:
     case IPOINTER:
-      genNearPointerSet (right, result, ic);
+      genNearPointerSet (right, result, ic, pi);
       break;
 
     case PPOINTER:
-      genPagedPointerSet (right, result, ic);
+      genPagedPointerSet (right, result, ic, pi);
       break;
 
     case FPOINTER:
-      genFarPointerSet (right, result, ic);
+      genFarPointerSet (right, result, ic, pi);
       break;
 
     case GPOINTER:
-      genGenPointerSet (right, result, ic);
+      genGenPointerSet (right, result, ic, pi);
       break;
+
+    default:
+      werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
+             "genPointerSet: illegal pointer type");
     }
 
 }
@@ -8887,47 +10382,67 @@ genAddrOf (iCode * ic)
   /* if the operand is on the stack then we
      need to get the stack offset of this
      variable */
-  if (sym->onStack)
-    {
-      /* if it has an offset then we need to compute
-         it */
-      if (sym->stack)
-       {
-         emitcode ("mov", "a,_bp");
-         emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
-         aopPut (AOP (IC_RESULT (ic)), "a", 0);
-       }
-      else
-       {
-         /* we can just move _bp */
-         aopPut (AOP (IC_RESULT (ic)), "_bp", 0);
-       }
-      /* fill the result with zero */
-      size = AOP_SIZE (IC_RESULT (ic)) - 1;
-
-
-      if (options.stack10bit && size < (FPTRSIZE - 1))
-       {
-         fprintf (stderr,
-                  "*** warning: pointer to stack var truncated.\n");
-       }
+  if (sym->onStack) {
+      
+      /* if 10 bit stack */
+      if (options.stack10bit) {
+         char buff[10];
+         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) ? */
+/*                   ((short) (sym->stack - _G.nRegsSaved)) : */
+/*                   ((short) sym->stack)) & 0xff); */
+/*       emitcode ("mov","b,a"); */
+/*       emitcode ("mov","a,#!constbyte",(-((sym->stack < 0) ? */
+/*                                      ((short) (sym->stack - _G.nRegsSaved)) : */
+/*                                      ((short) sym->stack)) >> 8) & 0xff); */
+         if (sym->stack) {
+             emitcode ("mov", "a,_bpx");
+             emitcode ("add", "a,#!constbyte", ((sym->stack < 0) ? 
+                                            ((char) (sym->stack - _G.nRegsSaved)) :
+                                            ((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);
+             aopPut (AOP (IC_RESULT (ic)), "b", 0);
+             aopPut (AOP (IC_RESULT (ic)), "a", 1);
+             aopPut (AOP (IC_RESULT (ic)), buff, 2);
+         } else {
+             /* we can just move _bp */
+             aopPut (AOP (IC_RESULT (ic)), "_bpx", 0);
+             aopPut (AOP (IC_RESULT (ic)), "_bpx+1", 1);
+             aopPut (AOP (IC_RESULT (ic)), buff, 2);
+         }       
+      } else {
+         /* if it has an offset then we need to compute it */
+         if (sym->stack) {
+             emitcode ("mov", "a,_bp");
+             emitcode ("add", "a,#!constbyte", ((char) sym->stack & 0xff));
+             aopPut (AOP (IC_RESULT (ic)), "a", 0);
+         } else {
+             /* we can just move _bp */
+             aopPut (AOP (IC_RESULT (ic)), "_bp", 0);
+         }
+         /* fill the result with zero */
+         size = AOP_SIZE (IC_RESULT (ic)) - 1;
+         
+         
+         if (options.stack10bit && size < (FPTRSIZE - 1)) {
+             fprintf (stderr,
+                      "*** warning: pointer to stack var truncated.\n");
+         }
 
-      offset = 1;
-      while (size--)
-       {
-         /* Yuck! */
-         if (options.stack10bit && offset == 2)
-           {
-             aopPut (AOP (IC_RESULT (ic)), "#0x40", offset++);
-           }
-         else
-           {
+         offset = 1;
+         while (size--) {
              aopPut (AOP (IC_RESULT (ic)), zero, offset++);
-           }
-       }
-
+         }      
+      }
       goto release;
-    }
+  }
 
   /* object not on stack then we need the name */
   size = AOP_SIZE (IC_RESULT (ic));
@@ -8936,12 +10451,24 @@ genAddrOf (iCode * ic)
   while (size--)
     {
       char s[SDCC_NAME_MAX];
-      if (offset)
-       sprintf (s, "#(%s >> %d)",
-                sym->rname,
-                offset * 8);
-      else
-       sprintf (s, "#%s", sym->rname);
+      if (offset) {
+         switch (offset) {
+         case 1:
+             tsprintf(s, sizeof(s), "!his",sym->rname);
+             break;
+         case 2:
+             tsprintf(s, sizeof(s), "!hihis",sym->rname);
+             break;
+         case 3:
+             tsprintf(s, sizeof(s), "!hihihis",sym->rname);
+             break;
+         default: /* should not need this (just in case) */
+             SNPRINTF (s, sizeof(s), "#(%s >> %d)",
+                      sym->rname,
+                      offset * 8);
+         }
+      } else
+         sprintf (s, "#%s", sym->rname);
       aopPut (AOP (IC_RESULT (ic)), s, offset++);
     }
 
@@ -8950,6 +10477,115 @@ release:
 
 }
 
+/*-----------------------------------------------------------------*/
+/* genArrayInit - generates code for address of                       */
+/*-----------------------------------------------------------------*/
+static void
+genArrayInit (iCode * ic)
+{
+    literalList *iLoop;
+    int         ix, count;
+    int         elementSize = 0, eIndex;
+    unsigned    val, lastVal;
+    sym_link    *type;
+    operand     *left=IC_LEFT(ic);
+    
+    D (emitcode (";", "genArrayInit "););
+
+    aopOp (IC_LEFT(ic), ic, FALSE, FALSE);
+    
+    if (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD)
+    {
+       // Load immediate value into DPTR.
+       emitcode("mov", "dptr, %s",
+            aopGet(AOP(IC_LEFT(ic)), 0, TRUE, FALSE, TRUE));
+    }
+    else if (AOP_TYPE(IC_LEFT(ic)) != AOP_DPTR)
+    {
+#if 0
+      werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+             "Unexpected operand to genArrayInit.\n");
+      exit(1);
+#else
+      // a regression because of SDCCcse.c:1.52
+      emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE, TRUE));
+      emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE, TRUE));
+      if (options.model == MODEL_FLAT24)
+       emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
+#endif
+    }
+    
+    type = operandType(IC_LEFT(ic));
+    
+    if (type && type->next)
+    {
+       elementSize = getSize(type->next);
+    }
+    else
+    {
+       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                               "can't determine element size in genArrayInit.\n");
+       exit(1);
+    }
+    
+    iLoop = IC_ARRAYILIST(ic);
+    lastVal = 0xffff;
+    
+    while (iLoop)
+    {
+       bool firstpass = TRUE;
+       
+       emitcode(";", "store %d x 0x%x to DPTR (element size %d)", 
+                iLoop->count, (int)iLoop->literalValue, elementSize);
+       
+       ix = iLoop->count;
+       
+       while (ix)
+       {
+           symbol *tlbl = NULL;
+           
+           count = ix > 256 ? 256 : ix;
+           
+           if (count > 1)
+           {
+               tlbl = newiTempLabel (NULL);
+               if (firstpass || (count & 0xff))
+               {
+                   emitcode("mov", "b, #!constbyte", count & 0xff);
+               }
+               
+               emitcode ("", "!tlabeldef", tlbl->key + 100);
+           }
+           
+           firstpass = FALSE;
+               
+           for (eIndex = 0; eIndex < elementSize; eIndex++)
+           {
+               val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff;
+               if (val != lastVal)
+               {
+                   emitcode("mov", "a, #!constbyte", val);
+                   lastVal = val;
+               }
+               
+               emitcode("movx", "@dptr, a");
+               emitcode("inc", "dptr");
+           }
+           
+           if (count > 1)
+           {
+               emitcode("djnz", "b, !tlabel", tlbl->key + 100);
+           }
+           
+           ix -= count;
+       }
+       
+       iLoop = iLoop->next;
+    }
+    
+    freeAsmop (IC_LEFT(ic), NULL, ic, TRUE);
+}
+
 /*-----------------------------------------------------------------*/
 /* genFarFarAssign - assignment when both are in far space         */
 /*-----------------------------------------------------------------*/
@@ -8992,8 +10628,8 @@ genFarFarAssign (operand * result, operand * right, iCode * ic)
   {
       /* We can use the '390 auto-toggle feature to good effect here. */
       
-      D(emitcode(";","genFarFarAssign ('390 auto-toggle fun)"););
-      emitcode("mov", "dps, #0x21");   /* Select DPTR2 & auto-toggle. */
+      D(emitcode(";","genFarFarAssign (390 auto-toggle fun)"););
+      emitcode("mov", "dps,#!constbyte",0x21);         /* Select DPTR2 & auto-toggle. */
       emitcode ("mov", "dptr,#%s", rSym->rname); 
       /* DP2 = result, DP1 = right, DP1 is current. */
       while (size)
@@ -9006,8 +10642,30 @@ genFarFarAssign (operand * result, operand * right, iCode * ic)
                emitcode("inc", "dptr");
           }
       }
-      emitcode("mov", "dps, #0");
+      emitcode("mov", "dps,#0");
       freeAsmop (right, NULL, ic, FALSE);
+#if 0
+some alternative code for processors without auto-toggle
+no time to test now, so later well put in...kpb
+        D(emitcode(";","genFarFarAssign (dual-dptr fun)"););
+        emitcode("mov", "dps,#1");     /* Select DPTR2. */
+        emitcode ("mov", "dptr,#%s", rSym->rname); 
+        /* DP2 = result, DP1 = right, DP1 is current. */
+        while (size)
+        {
+          --size;
+          emitcode("movx", "a,@dptr");
+          if (size)
+            emitcode("inc", "dptr");
+          emitcode("inc", "dps");
+          emitcode("movx", "@dptr,a");
+          if (size)
+            emitcode("inc", "dptr");
+          emitcode("inc", "dps");
+        }
+        emitcode("mov", "dps,#0");
+        freeAsmop (right, NULL, ic, FALSE);
+#endif
   }
   else
   {
@@ -9071,9 +10729,8 @@ genAssign (iCode * ic)
     goto release;
 
   /* if the result is a bit */
-  if (AOP_TYPE (result) == AOP_CRY)
+  if (AOP_TYPE (result) == AOP_CRY) /* works only for true symbols */
     {
-
       /* if the right size is a literal then
          we know what the value is */
       if (AOP_TYPE (right) == AOP_LIT)
@@ -9171,13 +10828,13 @@ genJumpTab (iCode * ic)
   freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE);
 
   jtab = newiTempLabel (NULL);
-  emitcode ("mov", "dptr,#%05d$", jtab->key + 100);
+  emitcode ("mov", "dptr,#!tlabel", jtab->key + 100);
   emitcode ("jmp", "@a+dptr");
-  emitcode ("", "%05d$:", jtab->key + 100);
+  emitcode ("", "!tlabeldef", jtab->key + 100);
   /* now generate the jump labels */
   for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab;
        jtab = setNextItem (IC_JTLABELS (ic)))
-    emitcode ("ljmp", "%05d$", jtab->key + 100);
+    emitcode ("ljmp", "!tlabel", jtab->key + 100);
 
 }
 
@@ -9204,7 +10861,8 @@ genCast (iCode * ic)
   aopOp (result, ic, FALSE, AOP_TYPE (right) == AOP_DPTR);
 
   /* if the result is a bit */
-  if (AOP_TYPE (result) == AOP_CRY)
+  // if (AOP_TYPE (result) == AOP_CRY) /* works only for true symbols */
+  if (IS_BITVAR(OP_SYMBOL(result)->type))
     {
       /* if the right size is a literal then
          we know what the value is */
@@ -9266,8 +10924,6 @@ genCast (iCode * ic)
       /* pointer to generic pointer */
       if (IS_GENPTR (ctype))
        {
-         char *l = zero;
-
          if (IS_PTR (type))
            {
              p_type = DCL_TYPE (type);
@@ -9327,29 +10983,19 @@ genCast (iCode * ic)
          _endLazyDPSEvaluation ();
 
          /* the last byte depending on type */
-         switch (p_type)
            {
-           case IPOINTER:
-           case POINTER:
-             l = zero;
-             break;
-           case FPOINTER:
-             l = one;
-             break;
-           case CPOINTER:
-             l = "#0x02";
-             break;
-           case PPOINTER:
-             l = "#0x03";
-             break;
-
-           default:
-             /* this should never happen */
-             werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
-                     "got unknown pointer type");
-             exit (1);
+               int gpVal = pointerTypeToGPByte(p_type, NULL, NULL);
+               char gpValStr[10];
+           
+               if (gpVal == -1)
+               {
+                   // pointerTypeToGPByte will have bitched.
+                   exit(1);
+               }
+           
+               sprintf(gpValStr, "#0x%d", gpVal);
+               aopPut (AOP (result), gpValStr, GPTRSIZE - 1);
            }
-         aopPut (AOP (result), l, GPTRSIZE - 1);
          goto release;
        }
 
@@ -9474,24 +11120,24 @@ genDjnz (iCode * ic, iCode * ifx)
       }
       emitcode ("dec", "%s", rByte);
       aopPut(AOP(IC_RESULT(ic)), rByte, 0);
-      emitcode ("jnz", "%05d$", lbl->key + 100);
+      emitcode ("jnz", "!tlabel", lbl->key + 100);
   }
   else if (IS_AOP_PREG (IC_RESULT (ic)))
     {
       emitcode ("dec", "%s",
                aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, FALSE));
       emitcode ("mov", "a,%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, FALSE));
-      emitcode ("jnz", "%05d$", lbl->key + 100);
+      emitcode ("jnz", "!tlabel", lbl->key + 100);
     }
   else
     {
-      emitcode ("djnz", "%s,%05d$", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, TRUE, FALSE),
+      emitcode ("djnz", "%s,!tlabel", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, TRUE, FALSE),
                lbl->key + 100);
     }
-  emitcode ("sjmp", "%05d$", lbl1->key + 100);
-  emitcode ("", "%05d$:", lbl->key + 100);
-  emitcode ("ljmp", "%05d$", IC_TRUE (ifx)->key + 100);
-  emitcode ("", "%05d$:", lbl1->key + 100);
+  emitcode ("sjmp", "!tlabel", lbl1->key + 100);
+  emitcode ("", "!tlabeldef", lbl->key + 100);
+  emitcode ("ljmp", "!tlabel", IC_TRUE (ifx)->key + 100);
+  emitcode ("", "!tlabeldef", lbl1->key + 100);
 
   freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
   ifx->generated = 1;
@@ -9505,40 +11151,1367 @@ static void
 genReceive (iCode * ic)
 {
 
-  D (emitcode (";", "genReceive ");
-    );
+    int size = getSize (operandType (IC_RESULT (ic)));
+    int offset = 0;
+    int rb1off ;
+    
+    D (emitcode (";", "genReceive ");
+       );
 
-  if (isOperandInFarSpace (IC_RESULT (ic)) &&
-      (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
-       IS_TRUE_SYMOP (IC_RESULT (ic))))
-    {
-      int size = getSize (operandType (IC_RESULT (ic)));
-      int offset = fReturnSizeDS390 - size;
-      while (size--)
+  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
+        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);
+}
+
+/*-----------------------------------------------------------------*/
+/* genMemcpyX2X - gen code for memcpy xdata to xdata               */
+/*-----------------------------------------------------------------*/
+static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc)
+{
+    operand *from , *to , *count;
+    symbol *lbl;
+    bitVect *rsave;
+    int i;
+
+    /* we know it has to be 3 parameters */
+    assert (nparms == 3);
+    
+    rsave = newBitVect(16);
+    /* save DPTR if it needs to be saved */
+    for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+           if (bitVectBitValue(ic->rMask,i))
+                   rsave = bitVectSetBit(rsave,i);
+    }
+    rsave = bitVectIntersect(rsave,bitVectCplAnd (bitVectCopy (ic->rMask),
+                                                 ds390_rUmaskForOp (IC_RESULT(ic))));
+    savermask(rsave);
+    
+    to = parms[0];
+    from = parms[1];
+    count = parms[2];
+
+    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));
+    if (options.model == MODEL_FLAT24) {
+       emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, TRUE));
+    }
+
+    freeAsmop (from, NULL, ic, FALSE);
+    aopOp (to, ic, FALSE, FALSE);
+    /* get "to" into DPTR */
+    /* if the operand is already in dptr
+       then we do nothing else we move the value to dptr */
+    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));
+           if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+           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));
+           } 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));
+               if (options.model == MODEL_FLAT24) {
+                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+               }
+           }
+           _endLazyDPSEvaluation ();
+       }
+    }
+    freeAsmop (to, NULL, ic, FALSE);
+    _G.dptrInUse = _G.dptr1InUse = 1;
+    aopOp (count, ic->next->next, FALSE,FALSE);
+    lbl =newiTempLabel(NULL);
+
+    /* 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));
+       if (fromc) {
+           emitcode ("lcall","__bi_memcpyc2x_s");
+       } else {
+           emitcode ("lcall","__bi_memcpyx2x_s");
+       }
+       freeAsmop (count, NULL, ic, FALSE);
+    } else {
+       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));
+       freeAsmop (count, NULL, ic, FALSE);
+       emitcode ("mov", "dps,#!constbyte",0x21);       /* Select DPTR2 & auto-toggle. */
+       emitcode ("","!tlabeldef",lbl->key+100);
+       if (fromc) {
+           emitcode ("clr","a");
+           emitcode ("movc", "a,@a+dptr");
+       } else 
+           emitcode ("movx", "a,@dptr");
+       emitcode ("movx", "@dptr,a");
+       emitcode ("inc", "dptr");
+       emitcode ("inc", "dptr");
+       emitcode ("mov","a,b");
+       emitcode ("orl","a,_ap");
+       emitcode ("jz","!tlabel",lbl1->key+100);
+       emitcode ("mov","a,_ap");
+       emitcode ("add","a,#!constbyte",0xFF);
+       emitcode ("mov","_ap,a");
+       emitcode ("mov","a,b");
+       emitcode ("addc","a,#!constbyte",0xFF);
+       emitcode ("mov","b,a");
+       emitcode ("sjmp","!tlabel",lbl->key+100);
+       emitcode ("","!tlabeldef",lbl1->key+100);
+    }
+    emitcode ("mov", "dps,#0"); 
+    _G.dptrInUse = _G.dptr1InUse = 0;
+    unsavermask(rsave);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genMemcmpX2X - gen code for memcmp xdata to xdata               */
+/*-----------------------------------------------------------------*/
+static void genMemcmpX2X( iCode *ic, int nparms, operand **parms, int fromc)
+{
+    operand *from , *to , *count;
+    symbol *lbl,*lbl2;
+    bitVect *rsave;
+    int i;
+
+    /* we know it has to be 3 parameters */
+    assert (nparms == 3);
+    
+    rsave = newBitVect(16);
+    /* save DPTR if it needs to be saved */
+    for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+           if (bitVectBitValue(ic->rMask,i))
+                   rsave = bitVectSetBit(rsave,i);
+    }
+    rsave = bitVectIntersect(rsave,bitVectCplAnd (bitVectCopy (ic->rMask),
+                                                 ds390_rUmaskForOp (IC_RESULT(ic))));
+    savermask(rsave);
+    
+    to = parms[0];
+    from = parms[1];
+    count = parms[2];
+
+    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));
+    if (options.model == MODEL_FLAT24) {
+       emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, TRUE));
+    }
+
+    freeAsmop (from, NULL, ic, FALSE);
+    aopOp (to, ic, FALSE, FALSE);
+    /* get "to" into DPTR */
+    /* if the operand is already in dptr
+       then we do nothing else we move the value to dptr */
+    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));
+           if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+           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));
+           } 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));
+               if (options.model == MODEL_FLAT24) {
+                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+               }
+           }
+           _endLazyDPSEvaluation ();
+       }
+    }
+    freeAsmop (to, NULL, ic, FALSE);
+    _G.dptrInUse = _G.dptr1InUse = 1;
+    aopOp (count, ic->next->next, FALSE,FALSE);
+    lbl =newiTempLabel(NULL);
+    lbl2 =newiTempLabel(NULL);
+
+    /* 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));
+       if (fromc)
+           emitcode("lcall","__bi_memcmpc2x_s");
+       else
+           emitcode("lcall","__bi_memcmpx2x_s");
+       freeAsmop (count, NULL, ic, FALSE);
+       aopOp (IC_RESULT(ic), ic, FALSE,FALSE);
+       aopPut(AOP(IC_RESULT(ic)),"a",0);
+       freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+    } else {
+       symbol *lbl1 = newiTempLabel(NULL);
+
+       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));
+       freeAsmop (count, NULL, ic, FALSE);
+       emitcode ("mov", "dps,#!constbyte",0x21);       /* Select DPTR2 & auto-toggle. */
+       emitcode ("","!tlabeldef",lbl->key+100);
+       if (fromc) {
+           emitcode ("clr","a");
+           emitcode ("movc", "a,@a+dptr");
+       } else 
+           emitcode ("movx", "a,@dptr");
+       emitcode ("mov","r0,a");
+       emitcode ("movx", "a,@dptr");
+       emitcode ("clr","c");
+       emitcode ("subb","a,r0");
+       emitcode ("jnz","!tlabel",lbl2->key+100);
+       emitcode ("inc", "dptr");
+       emitcode ("inc", "dptr");
+       emitcode ("mov","a,b");
+       emitcode ("orl","a,_ap");
+       emitcode ("jz","!tlabel",lbl1->key+100);
+       emitcode ("mov","a,_ap");
+       emitcode ("add","a,#!constbyte",0xFF);
+       emitcode ("mov","_ap,a");
+       emitcode ("mov","a,b");
+       emitcode ("addc","a,#!constbyte",0xFF);
+       emitcode ("mov","b,a");
+       emitcode ("sjmp","!tlabel",lbl->key+100);
+       emitcode ("","!tlabeldef",lbl1->key+100);
+       emitcode ("clr","a");
+       emitcode ("","!tlabeldef",lbl2->key+100);
+       aopOp (IC_RESULT(ic), ic, FALSE,FALSE);
+       aopPut(AOP(IC_RESULT(ic)),"a",0);
+       freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+       emitcode("pop","ar0");
+       emitcode ("mov", "dps,#0");      
+    }
+    _G.dptrInUse = _G.dptr1InUse = 0;
+    unsavermask(rsave);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genInp - gen code for __builtin_inp read data from a mem mapped */
+/* port, first parameter output area second parameter pointer to   */
+/* port third parameter count                                      */
+/*-----------------------------------------------------------------*/
+static void genInp( iCode *ic, int nparms, operand **parms)
+{
+    operand *from , *to , *count;
+    symbol *lbl;
+    bitVect *rsave;
+    int i;
+
+    /* we know it has to be 3 parameters */
+    assert (nparms == 3);
+    
+    rsave = newBitVect(16);
+    /* save DPTR if it needs to be saved */
+    for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+           if (bitVectBitValue(ic->rMask,i))
+                   rsave = bitVectSetBit(rsave,i);
+    }
+    rsave = bitVectIntersect(rsave,bitVectCplAnd (bitVectCopy (ic->rMask),
+                                                 ds390_rUmaskForOp (IC_RESULT(ic))));
+    savermask(rsave);
+    
+    to = parms[0];
+    from = parms[1];
+    count = parms[2];
+
+    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));
+    if (options.model == MODEL_FLAT24) {
+       emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, TRUE));
+    }
+
+    freeAsmop (from, NULL, ic, FALSE);
+    aopOp (to, ic, FALSE, FALSE);
+    /* get "to" into DPTR */
+    /* if the operand is already in dptr
+       then we do nothing else we move the value to dptr */
+    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));
+           if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+           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));
+           } 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));
+               if (options.model == MODEL_FLAT24) {
+                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+               }
+           }
+           _endLazyDPSEvaluation ();
+       }
+    }
+    freeAsmop (to, NULL, ic, FALSE);
+
+    _G.dptrInUse = _G.dptr1InUse = 1;
+    aopOp (count, ic->next->next, FALSE,FALSE);
+    lbl =newiTempLabel(NULL);
+
+    /* now for the actual copy */
+    if (AOP_TYPE(count) == AOP_LIT && 
+       (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));
+       freeAsmop (count, NULL, ic, FALSE);
+       emitcode ("","!tlabeldef",lbl->key+100);
+       emitcode ("movx", "a,@dptr");   /* read data from port */
+       emitcode ("dec","dps");         /* switch to DPTR */
+       emitcode ("movx", "@dptr,a");   /* save into location */
+       emitcode ("inc", "dptr");       /* point to next area */
+       emitcode ("inc","dps");         /* switch to DPTR2 */
+       emitcode ("djnz","b,!tlabel",lbl->key+100);
+    } else {
+       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));
+       freeAsmop (count, NULL, ic, FALSE);
+       emitcode ("mov", "dps,#!constbyte",0x1);        /* Select DPTR2 */
+       emitcode ("","!tlabeldef",lbl->key+100);
+       emitcode ("movx", "a,@dptr");
+       emitcode ("dec","dps");         /* switch to DPTR */
+       emitcode ("movx", "@dptr,a");
+       emitcode ("inc", "dptr");
+       emitcode ("inc","dps");         /* switch to DPTR2 */
+/*     emitcode ("djnz","b,!tlabel",lbl->key+100); */
+/*     emitcode ("djnz","_ap,!tlabel",lbl->key+100); */
+       emitcode ("mov","a,b");
+       emitcode ("orl","a,_ap");
+       emitcode ("jz","!tlabel",lbl1->key+100);
+       emitcode ("mov","a,_ap");
+       emitcode ("add","a,#!constbyte",0xFF);
+       emitcode ("mov","_ap,a");
+       emitcode ("mov","a,b");
+       emitcode ("addc","a,#!constbyte",0xFF);
+       emitcode ("mov","b,a");
+       emitcode ("sjmp","!tlabel",lbl->key+100);
+       emitcode ("","!tlabeldef",lbl1->key+100);
+    }
+    emitcode ("mov", "dps,#0"); 
+    _G.dptrInUse = _G.dptr1InUse = 0;
+    unsavermask(rsave);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genOutp - gen code for __builtin_inp write data to a mem mapped */
+/* port, first parameter output area second parameter pointer to   */
+/* port third parameter count                                      */
+/*-----------------------------------------------------------------*/
+static void genOutp( iCode *ic, int nparms, operand **parms)
+{
+    operand *from , *to , *count;
+    symbol *lbl;
+    bitVect *rsave;
+    int i;
+
+    /* we know it has to be 3 parameters */
+    assert (nparms == 3);
+    
+    rsave = newBitVect(16);
+    /* save DPTR if it needs to be saved */
+    for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+           if (bitVectBitValue(ic->rMask,i))
+                   rsave = bitVectSetBit(rsave,i);
+    }
+    rsave = bitVectIntersect(rsave,bitVectCplAnd (bitVectCopy (ic->rMask),
+                                                 ds390_rUmaskForOp (IC_RESULT(ic))));
+    savermask(rsave);
+    
+    to = parms[0];
+    from = parms[1];
+    count = parms[2];
+
+    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));
+    if (options.model == MODEL_FLAT24) {
+       emitcode ("mov", "dpx1,%s", aopGet (AOP (from), 2, FALSE, FALSE, TRUE));
+    }
+
+    freeAsmop (from, NULL, ic, FALSE);
+    aopOp (to, ic, FALSE, FALSE);
+    /* get "to" into DPTR */
+    /* if the operand is already in dptr
+       then we do nothing else we move the value to dptr */
+    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));
+           if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+           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));
+           } 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));
+               if (options.model == MODEL_FLAT24) {
+                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+               }
+           }
+           _endLazyDPSEvaluation ();
+       }
+    }
+    freeAsmop (to, NULL, ic, FALSE);
+
+    _G.dptrInUse = _G.dptr1InUse = 1;
+    aopOp (count, ic->next->next, FALSE,FALSE);
+    lbl =newiTempLabel(NULL);
+
+    /* now for the actual copy */
+    if (AOP_TYPE(count) == AOP_LIT && 
+       (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 ("","!tlabeldef",lbl->key+100);
+       emitcode ("movx", "a,@dptr");   /* read data from port */
+       emitcode ("inc","dps");         /* switch to DPTR2 */
+       emitcode ("movx", "@dptr,a");   /* save into location */
+       emitcode ("inc", "dptr");       /* point to next area */
+       emitcode ("dec","dps");         /* switch to DPTR */
+       emitcode ("djnz","b,!tlabel",lbl->key+100);
+       freeAsmop (count, NULL, ic, FALSE);
+    } else {
+       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));
+       freeAsmop (count, NULL, ic, FALSE);
+       emitcode ("mov", "dps,#!constbyte",0x0);        /* Select DPTR */
+       emitcode ("","!tlabeldef",lbl->key+100);
+       emitcode ("movx", "a,@dptr");
+       emitcode ("inc", "dptr");
+       emitcode ("inc","dps");         /* switch to DPTR2 */
+       emitcode ("movx", "@dptr,a");
+       emitcode ("dec","dps");         /* switch to DPTR */
+       emitcode ("mov","a,b");
+       emitcode ("orl","a,_ap");
+       emitcode ("jz","!tlabel",lbl1->key+100);
+       emitcode ("mov","a,_ap");
+       emitcode ("add","a,#!constbyte",0xFF);
+       emitcode ("mov","_ap,a");
+       emitcode ("mov","a,b");
+       emitcode ("addc","a,#!constbyte",0xFF);
+       emitcode ("mov","b,a");
+       emitcode ("sjmp","!tlabel",lbl->key+100);
+       emitcode ("","!tlabeldef",lbl1->key+100);
+    }
+    emitcode ("mov", "dps,#0"); 
+    _G.dptrInUse = _G.dptr1InUse = 0;
+    unsavermask(rsave);
+
+}
+
+/*-----------------------------------------------------------------*/
+/* genSwapW - swap lower & high order bytes                        */
+/*-----------------------------------------------------------------*/
+static void genSwapW(iCode *ic, int nparms, operand **parms)
+{
+    operand *dest;
+    operand *src;
+    assert (nparms==1);
+
+    src = parms[0];
+    dest=IC_RESULT(ic);
+
+    assert(getSize(operandType(src))==2);
+
+    aopOp (src, ic, FALSE, FALSE);
+    emitcode ("mov","a,%s",aopGet(AOP(src),0,FALSE,FALSE,TRUE));
+    _G.accInUse++;
+    emitcode ("mov","b,%s",aopGet(AOP(src),1,FALSE,FALSE,FALSE));
+    _G.accInUse--;
+    freeAsmop (src, NULL, ic, FALSE);
+    
+    aopOp (dest,ic, FALSE, FALSE);
+    aopPut(AOP(dest),"b",0);
+    aopPut(AOP(dest),"a",1);
+    freeAsmop (dest, NULL, ic, FALSE);    
+}
+
+/*-----------------------------------------------------------------*/
+/* genMemsetX - gencode for memSetX data                           */
+/*-----------------------------------------------------------------*/
+static void genMemsetX(iCode *ic, int nparms, operand **parms)
+{
+    operand *to , *val , *count;
+    symbol *lbl;
+    char *l;
+    int i;
+    bitVect *rsave = NULL;
+
+    /* we know it has to be 3 parameters */
+    assert (nparms == 3);
+    
+    to = parms[0];
+    val = parms[1];
+    count = parms[2];
+        
+    /* save DPTR if it needs to be saved */
+    rsave = newBitVect(16);
+    for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+           if (bitVectBitValue(ic->rMask,i))
+                   rsave = bitVectSetBit(rsave,i);
+    }
+    rsave = bitVectIntersect(rsave,bitVectCplAnd (bitVectCopy (ic->rMask),
+                                                 ds390_rUmaskForOp (IC_RESULT(ic))));
+    savermask(rsave);
+
+    aopOp (to, ic, FALSE, FALSE);
+    /* get "to" into DPTR */
+    /* if the operand is already in dptr
+       then we do nothing else we move the value to dptr */
+    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));
+           if (options.model == MODEL_FLAT24)
+               emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+           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));
+           } 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));
+               if (options.model == MODEL_FLAT24) {
+                   emitcode ("mov", "dpx,%s", aopGet (AOP (to), 2, FALSE, FALSE, TRUE));
+               }
+           }
+           _endLazyDPSEvaluation ();
+       }
+    }
+    freeAsmop (to, NULL, ic, FALSE);
+
+    aopOp (val, ic->next->next, FALSE,FALSE);
+    aopOp (count, ic->next->next, FALSE,FALSE);    
+    lbl =newiTempLabel(NULL);
+    /* 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));
+       MOVA(l);
+       emitcode ("","!tlabeldef",lbl->key+100);
+       emitcode ("movx", "@dptr,a");
+       emitcode ("inc", "dptr");
+       emitcode ("djnz","b,!tlabel",lbl->key+100);
+    } 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 ("","!tlabeldef",lbl->key+100);
+       l = aopGet(AOP (val), 0, FALSE, FALSE, TRUE);
+       MOVA(l);
+       emitcode ("movx", "@dptr,a");
+       emitcode ("inc", "dptr");
+       emitcode ("mov","a,b");
+       emitcode ("orl","a,_ap");
+       emitcode ("jz","!tlabel",lbl1->key+100);
+       emitcode ("mov","a,_ap");
+       emitcode ("add","a,#!constbyte",0xFF);
+       emitcode ("mov","_ap,a");
+       emitcode ("mov","a,b");
+       emitcode ("addc","a,#!constbyte",0xFF);
+       emitcode ("mov","b,a");
+       emitcode ("sjmp","!tlabel",lbl->key+100);
+       emitcode ("","!tlabeldef",lbl1->key+100);
+    }
+    freeAsmop (count, NULL, ic, FALSE);
+    unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genNatLibLoadPrimitive - calls TINI api function to load primitive */
+/*-----------------------------------------------------------------*/
+static void genNatLibLoadPrimitive(iCode *ic, int nparms, operand **parms,int size)
+{
+       bitVect *rsave ;
+       operand *pnum, *result;
+       int i;
+    
+       assert (nparms==1);
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));
+    
+       pnum = parms[0]; 
+       aopOp (pnum, ic, FALSE, FALSE);
+       emitcode ("mov","a,%s",aopGet(AOP(pnum),0,FALSE,FALSE,FALSE));
+       freeAsmop (pnum, NULL, ic, FALSE);
+       emitcode ("lcall","NatLib_LoadPrimitive");
+       aopOp (result=IC_RESULT(ic), ic, FALSE, FALSE);
+       if (aopHasRegs(AOP(result),R0_IDX,R1_IDX) || 
+           aopHasRegs(AOP(result),R2_IDX,R3_IDX) ) {
+               for (i = (size-1) ; i >= 0 ; i-- ) {
+                       emitcode ("push","a%s",javaRet[i]);
+               }
+               for (i=0; i < size ; i++ ) {
+                       emitcode ("pop","a%s",aopGet(AOP(result),i,FALSE,FALSE,FALSE));
+               }
+       } else {
+               for (i = 0 ; i < size ; i++ ) {
+                       aopPut(AOP(result),javaRet[i],i);
+               }
+       }    
+       freeAsmop (result, NULL, ic, FALSE);
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genNatLibLoadPointer - calls TINI api function to load pointer  */
+/*-----------------------------------------------------------------*/
+static void genNatLibLoadPointer(iCode *ic, int nparms, operand **parms)
+{
+       bitVect *rsave ;
+       operand *pnum, *result;
+       int size = 3;
+       int i;
+    
+       assert (nparms==1);
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));
+    
+       pnum = parms[0]; 
+       aopOp (pnum, ic, FALSE, FALSE);
+       emitcode ("mov","a,%s",aopGet(AOP(pnum),0,FALSE,FALSE,FALSE));
+       freeAsmop (pnum, NULL, ic, FALSE);
+       emitcode ("lcall","NatLib_LoadPointer");
+       aopOp (result=IC_RESULT(ic), ic, FALSE, FALSE);
+       if (AOP_TYPE(result)!=AOP_STR) {
+               for (i = 0 ; i < size ; i++ ) {
+                       aopPut(AOP(result),fReturn[i],i);
+               }
+       }    
+       freeAsmop (result, NULL, ic, FALSE);
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genNatLibInstallStateBlock -                                   */
+/*-----------------------------------------------------------------*/
+static void genNatLibInstallStateBlock(iCode *ic, int nparms, 
+                                      operand **parms, const char *name)
+{
+       bitVect *rsave ;
+       operand *psb, *handle;
+       assert (nparms==2);
+
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));
+       psb = parms[0];
+       handle = parms[1];
+
+       /* put pointer to state block into DPTR1 */
+       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","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));
+       }
+       freeAsmop (psb, NULL, ic, FALSE);
+
+       /* put libraryID into DPTR */
+       emitcode ("mov","dptr,#LibraryID");
+
+       /* 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 ("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));
+       }
+       freeAsmop (psb, NULL, ic, FALSE);
+
+       /* make the call */
+       emitcode ("lcall","NatLib_Install%sStateBlock",name);
+
+       /* put return value into place*/
+       _G.accInUse++;
+       aopOp (IC_RESULT(ic), ic, FALSE, FALSE);
+       _G.accInUse--;
+       aopPut(AOP(IC_RESULT(ic)),"a",0);
+       freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genNatLibRemoveStateBlock -                                     */
+/*-----------------------------------------------------------------*/
+static void genNatLibRemoveStateBlock(iCode *ic,int nparms,const char *name)
+{
+       bitVect *rsave ;
+
+       assert(nparms==0);
+
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));
+
+       /* put libraryID into DPTR */
+       emitcode ("mov","dptr,#LibraryID");
+       /* make the call */
+       emitcode ("lcall","NatLib_Remove%sStateBlock",name);
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genNatLibGetStateBlock -                                        */
+/*-----------------------------------------------------------------*/
+static void genNatLibGetStateBlock(iCode *ic,int nparms,
+                                  operand **parms,const char *name)
+{
+       bitVect *rsave ;
+       symbol *lbl = newiTempLabel(NULL);
+       
+       assert(nparms==0);
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));
+
+       /* put libraryID into DPTR */
+       emitcode ("mov","dptr,#LibraryID");
+       /* make the call */
+       emitcode ("lcall","NatLib_Remove%sStateBlock",name);
+       emitcode ("jnz","!tlabel",lbl->key+100);
+
+       /* put return value into place */
+       aopOp(IC_RESULT(ic),ic,FALSE,FALSE);
+       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));
+       } else {
+               aopPut(AOP(IC_RESULT(ic)),"r2",0);
+               aopPut(AOP(IC_RESULT(ic)),"r3",1);
+       }
+       freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+       emitcode ("","!tlabeldef",lbl->key+100);
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genMMMalloc -                                                   */
+/*-----------------------------------------------------------------*/
+static void genMMMalloc (iCode *ic,int nparms, operand **parms,
+                        int size, const char *name)
+{
+       bitVect *rsave ;
+       operand *bsize;
+       symbol *rsym;
+       symbol *lbl = newiTempLabel(NULL);
+
+       assert (nparms == 1);
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));   
+       
+       bsize=parms[0];
+       aopOp (bsize,ic,FALSE,FALSE);
+
+       /* 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));
+               if (size==3) {
+                       emitcode("push","%s",aopGet(AOP(bsize),2,FALSE,TRUE,FALSE));
+                       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));
+               if (size==3) {
+                       emitcode("mov","r4,%s",aopGet(AOP(bsize),2,FALSE,TRUE,FALSE));
+               }
+       }
+       freeAsmop (bsize, NULL, ic, FALSE);
+
+       /* make the call */
+       emitcode ("lcall","MM_%s",name);
+       emitcode ("jz","!tlabel",lbl->key+100);
+       emitcode ("mov","r2,#!constbyte",0xff);
+       emitcode ("mov","r3,#!constbyte",0xff);
+       emitcode ("","!tlabeldef",lbl->key+100);
+       /* we don't care about the pointer : we just save the handle */
+       rsym = OP_SYMBOL(IC_RESULT(ic));
+       if (rsym->liveFrom != rsym->liveTo) {
+               aopOp(IC_RESULT(ic),ic,FALSE,FALSE);
+               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));
+               } else {
+                       aopPut(AOP(IC_RESULT(ic)),"r2",0);
+                       aopPut(AOP(IC_RESULT(ic)),"r3",1);
+               }
+               freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+       }
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genMMDeref -                                                    */
+/*-----------------------------------------------------------------*/
+static void genMMDeref (iCode *ic,int nparms, operand **parms)
+{
+       bitVect *rsave ;
+       operand *handle;
+
+       assert (nparms == 1);
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));   
+       
+       handle=parms[0];
+       aopOp (handle,ic,FALSE,FALSE);
+
+       /* 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("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));
+       }
+       freeAsmop (handle, NULL, ic, FALSE);
+
+       /* make the call */
+       emitcode ("lcall","MM_Deref");
+       
        {
-         emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeDS390 - offset - 1], "a") ?
-                           fReturn[fReturnSizeDS390 - offset - 1] : "acc"));
-         offset++;
+               symbol *rsym = OP_SYMBOL(IC_RESULT(ic));
+               if (rsym->liveFrom != rsym->liveTo) {                   
+                       aopOp (IC_RESULT(ic),ic,FALSE,FALSE);
+                       if (AOP_TYPE(IC_RESULT(ic)) != AOP_STR) {
+                               aopPut(AOP(IC_RESULT(ic)),"dpl",0);
+                               aopPut(AOP(IC_RESULT(ic)),"dph",1);
+                               aopPut(AOP(IC_RESULT(ic)),"dpx",2);
+                       }
+               }
        }
-      aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
-      size = AOP_SIZE (IC_RESULT (ic));
-      offset = 0;
-      while (size--)
+       freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genMMUnrestrictedPersist -                                      */
+/*-----------------------------------------------------------------*/
+static void genMMUnrestrictedPersist(iCode *ic,int nparms, operand **parms)
+{
+       bitVect *rsave ;
+       operand *handle;
+
+       assert (nparms == 1);
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));   
+       
+       handle=parms[0];
+       aopOp (handle,ic,FALSE,FALSE);
+
+       /* 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("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));
+       }
+       freeAsmop (handle, NULL, ic, FALSE);
+
+       /* make the call */
+       emitcode ("lcall","MM_UnrestrictedPersist");
+
        {
-         emitcode ("pop", "acc");
-         aopPut (AOP (IC_RESULT (ic)), "a", offset++);
+               symbol *rsym = OP_SYMBOL(IC_RESULT(ic));
+               if (rsym->liveFrom != rsym->liveTo) {   
+                       aopOp (IC_RESULT(ic),ic,FALSE,FALSE);
+                       aopPut(AOP(IC_RESULT(ic)),"a",0);
+                       freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+               }
+       }
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genSystemExecJavaProcess -                                      */
+/*-----------------------------------------------------------------*/
+static void genSystemExecJavaProcess(iCode *ic,int nparms, operand **parms)
+{
+       bitVect *rsave ;
+       operand *handle, *pp;
+
+       assert (nparms==2);
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));   
+       
+       pp = parms[0];
+       handle = parms[1];
+       
+       /* 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("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));
+       }
+       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));          
+       } 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));
+       }
+       freeAsmop (handle, NULL, ic, FALSE);
+
+       /* make the call */
+       emitcode ("lcall","System_ExecJavaProcess");
+       
+       /* put result in place */
+       {
+               symbol *rsym = OP_SYMBOL(IC_RESULT(ic));
+               if (rsym->liveFrom != rsym->liveTo) {   
+                       aopOp (IC_RESULT(ic),ic,FALSE,FALSE);
+                       aopPut(AOP(IC_RESULT(ic)),"a",0);
+                       freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+               }
        }
+       
+       unsavermask(rsave);
+}
 
-    }
-  else
-    {
-      _G.accInUse++;
-      aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
-      _G.accInUse--;
-      assignResultValue (IC_RESULT (ic));
-    }
+/*-----------------------------------------------------------------*/
+/* genSystemRTCRegisters -                                         */
+/*-----------------------------------------------------------------*/
+static void genSystemRTCRegisters(iCode *ic,int nparms, operand **parms,
+                                 char *name)
+{
+       bitVect *rsave ;
+       operand *pp;
 
-  freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+       assert (nparms==1);
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));   
+       
+       pp=parms[0];
+       /* put pointer in DPTR */
+       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","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));
+       }
+       freeAsmop (pp, NULL, ic, FALSE);
+
+       /* make the call */
+       emitcode ("lcall","System_%sRTCRegisters",name);
+
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genSystemThreadSleep -                                          */
+/*-----------------------------------------------------------------*/
+static void genSystemThreadSleep(iCode *ic,int nparms, operand **parms, char *name)
+{
+       bitVect *rsave ;
+       operand *to, *s;
+
+       assert (nparms==1);
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));   
+
+       to = parms[0];
+       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 ("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));
+       }
+       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));
+       freeAsmop (s, NULL, ic, FALSE);
+
+       /* make the call */
+       emitcode ("lcall","System_%s",name);
+
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genSystemThreadResume -                                         */
+/*-----------------------------------------------------------------*/
+static void genSystemThreadResume(iCode *ic,int nparms, operand **parms)
+{
+       bitVect *rsave ;
+       operand *tid,*pid;
+
+       assert (nparms==2);
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));
+       
+       tid = parms[0];
+       pid = parms[1];
+       
+       /* PID in R0 */
+       aopOp(pid,ic,FALSE,FALSE);
+       emitcode ("mov","r0,%s",aopGet(AOP(pid),0,FALSE,TRUE,FALSE));
+       freeAsmop (pid, NULL, ic, FALSE);
+       
+       /* tid into ACC */
+       aopOp(tid,ic,FALSE,FALSE);
+       emitcode ("mov","a,%s",aopGet(AOP(tid),0,FALSE,TRUE,FALSE));
+       freeAsmop (tid, NULL, ic, FALSE);
+       
+       emitcode ("lcall","System_ThreadResume");
+
+       /* put result into place */
+       {
+               symbol *rsym = OP_SYMBOL(IC_RESULT(ic));
+               if (rsym->liveFrom != rsym->liveTo) {   
+                       aopOp (IC_RESULT(ic),ic,FALSE,FALSE);
+                       aopPut(AOP(IC_RESULT(ic)),"a",0);
+                       freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+               }
+       }
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genSystemProcessResume -                                        */
+/*-----------------------------------------------------------------*/
+static void genSystemProcessResume(iCode *ic,int nparms, operand **parms)
+{
+       bitVect *rsave ;
+       operand *pid;
+
+       assert (nparms==1);
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));
+       
+       pid = parms[0];
+       
+       /* pid into ACC */
+       aopOp(pid,ic,FALSE,FALSE);
+       emitcode ("mov","a,%s",aopGet(AOP(pid),0,FALSE,TRUE,FALSE));
+       freeAsmop (pid, NULL, ic, FALSE);
+       
+       emitcode ("lcall","System_ProcessResume");
+
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genSystem -                                                     */
+/*-----------------------------------------------------------------*/
+static void genSystem (iCode *ic,int nparms,char *name)
+{
+       assert(nparms == 0);
+
+       emitcode ("lcall","System_%s",name);
+}
+
+/*-----------------------------------------------------------------*/
+/* genSystemPoll -                                                  */
+/*-----------------------------------------------------------------*/
+static void genSystemPoll(iCode *ic,int nparms, operand **parms,char *name)
+{
+       bitVect *rsave ;
+       operand *fp;
+
+       assert (nparms==1);
+       /* save registers that need to be saved */
+       savermask(rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                                        ds390_rUmaskForOp (IC_RESULT(ic))));
+
+       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));
+       } 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));
+       }
+       freeAsmop (fp, NULL, ic, FALSE);
+
+       emitcode ("lcall","System_%sPoll",name);
+
+       /* put result into place */
+       {
+               symbol *rsym = OP_SYMBOL(IC_RESULT(ic));
+               if (rsym->liveFrom != rsym->liveTo) {   
+                       aopOp (IC_RESULT(ic),ic,FALSE,FALSE);
+                       aopPut(AOP(IC_RESULT(ic)),"a",0);
+                       freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+               }
+       }
+       unsavermask(rsave);
+}
+
+/*-----------------------------------------------------------------*/
+/* genSystemGetCurrentID -                                         */
+/*-----------------------------------------------------------------*/
+static void genSystemGetCurrentID(iCode *ic,int nparms, operand **parms,char *name)
+{
+       assert (nparms==0);
+
+       emitcode ("lcall","System_GetCurrent%sId",name);
+       /* put result into place */
+       {
+               symbol *rsym = OP_SYMBOL(IC_RESULT(ic));
+               if (rsym->liveFrom != rsym->liveTo) {   
+                       aopOp (IC_RESULT(ic),ic,FALSE,FALSE);
+                       aopPut(AOP(IC_RESULT(ic)),"a",0);
+                       freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+               }
+       }
+}
+
+/*-----------------------------------------------------------------*/
+/* genBuiltIn - calls the appropriate function to  generating code */
+/* for a built in function                                        */
+/*-----------------------------------------------------------------*/
+static void genBuiltIn (iCode *ic)
+{
+       operand *bi_parms[MAX_BUILTIN_ARGS];
+       int nbi_parms;
+       iCode *bi_iCode;
+       symbol *bif;
+
+       /* get all the arguments for a built in function */
+       bi_iCode = getBuiltinParms(ic,&nbi_parms,bi_parms);
+
+       /* which function is it */
+       bif = OP_SYMBOL(IC_LEFT(bi_iCode));
+       if (strcmp(bif->name,"__builtin_memcpy_x2x")==0) {
+               genMemcpyX2X(bi_iCode,nbi_parms,bi_parms,0);
+       } else if (strcmp(bif->name,"__builtin_memcpy_c2x")==0) {
+               genMemcpyX2X(bi_iCode,nbi_parms,bi_parms,1);
+       } else  if (strcmp(bif->name,"__builtin_memcmp_x2x")==0) {
+               genMemcmpX2X(bi_iCode,nbi_parms,bi_parms,0);
+       } else if (strcmp(bif->name,"__builtin_memcmp_c2x")==0) {
+               genMemcmpX2X(bi_iCode,nbi_parms,bi_parms,1);
+       } else if (strcmp(bif->name,"__builtin_memset_x")==0) {
+               genMemsetX(bi_iCode,nbi_parms,bi_parms);
+       } else if (strcmp(bif->name,"__builtin_inp")==0) {
+               genInp(bi_iCode,nbi_parms,bi_parms);
+       } else if (strcmp(bif->name,"__builtin_outp")==0) {
+               genOutp(bi_iCode,nbi_parms,bi_parms);
+       } else if (strcmp(bif->name,"__builtin_swapw")==0) {
+               genSwapW(bi_iCode,nbi_parms,bi_parms);
+               /* JavaNative builtIns */               
+       } else if (strcmp(bif->name,"NatLib_LoadByte")==0) {
+               genNatLibLoadPrimitive(bi_iCode,nbi_parms,bi_parms,1);
+       } else if (strcmp(bif->name,"NatLib_LoadShort")==0) {
+               genNatLibLoadPrimitive(bi_iCode,nbi_parms,bi_parms,2);
+       } else if (strcmp(bif->name,"NatLib_LoadInt")==0) {
+               genNatLibLoadPrimitive(bi_iCode,nbi_parms,bi_parms,4);
+       } else if (strcmp(bif->name,"NatLib_LoadPointer")==0) {
+               genNatLibLoadPointer(bi_iCode,nbi_parms,bi_parms);
+       } else if (strcmp(bif->name,"NatLib_InstallImmutableStateBlock")==0) {
+               genNatLibInstallStateBlock(bi_iCode,nbi_parms,bi_parms,"Immutable");
+       } else if (strcmp(bif->name,"NatLib_InstallEphemeralStateBlock")==0) {
+               genNatLibInstallStateBlock(bi_iCode,nbi_parms,bi_parms,"Ephemeral");
+       } else if (strcmp(bif->name,"NatLib_RemoveImmutableStateBlock")==0) {
+               genNatLibRemoveStateBlock(bi_iCode,nbi_parms,"Immutable");
+       } else if (strcmp(bif->name,"NatLib_RemoveEphemeralStateBlock")==0) {
+               genNatLibRemoveStateBlock(bi_iCode,nbi_parms,"Ephemeral");
+       } else if (strcmp(bif->name,"NatLib_GetImmutableStateBlock")==0) {
+               genNatLibGetStateBlock(bi_iCode,nbi_parms,bi_parms,"Immutable");
+       } else if (strcmp(bif->name,"NatLib_GetEphemeralStateBlock")==0) {
+               genNatLibGetStateBlock(bi_iCode,nbi_parms,bi_parms,"Ephemeral");
+       } else if (strcmp(bif->name,"MM_XMalloc")==0) {
+               genMMMalloc(bi_iCode,nbi_parms,bi_parms,3,"XMalloc");
+       } else if (strcmp(bif->name,"MM_Malloc")==0) {
+               genMMMalloc(bi_iCode,nbi_parms,bi_parms,2,"Malloc");
+       } else if (strcmp(bif->name,"MM_ApplicationMalloc")==0) {
+               genMMMalloc(bi_iCode,nbi_parms,bi_parms,2,"ApplicationMalloc");
+       } else if (strcmp(bif->name,"MM_Free")==0) {
+               genMMMalloc(bi_iCode,nbi_parms,bi_parms,2,"Free");
+       } else if (strcmp(bif->name,"MM_Deref")==0) {
+               genMMDeref(bi_iCode,nbi_parms,bi_parms);
+       } else if (strcmp(bif->name,"MM_UnrestrictedPersist")==0) {
+               genMMUnrestrictedPersist(bi_iCode,nbi_parms,bi_parms);
+       } else if (strcmp(bif->name,"System_ExecJavaProcess")==0) {
+               genSystemExecJavaProcess(bi_iCode,nbi_parms,bi_parms);
+       } else if (strcmp(bif->name,"System_GetRTCRegisters")==0) {
+               genSystemRTCRegisters(bi_iCode,nbi_parms,bi_parms,"Get");
+       } else if (strcmp(bif->name,"System_SetRTCRegisters")==0) {
+               genSystemRTCRegisters(bi_iCode,nbi_parms,bi_parms,"Set");
+       } else if (strcmp(bif->name,"System_ThreadSleep")==0) {
+               genSystemThreadSleep(bi_iCode,nbi_parms,bi_parms,"ThreadSleep");
+       } else if (strcmp(bif->name,"System_ThreadSleep_ExitCriticalSection")==0) {
+               genSystemThreadSleep(bi_iCode,nbi_parms,bi_parms,"ThreadSleep_ExitCriticalSection");
+       } else if (strcmp(bif->name,"System_ProcessSleep")==0) {
+               genSystemThreadSleep(bi_iCode,nbi_parms,bi_parms,"ProcessSleep");
+       } else if (strcmp(bif->name,"System_ProcessSleep_ExitCriticalSection")==0) {
+               genSystemThreadSleep(bi_iCode,nbi_parms,bi_parms,"ProcessSleep_ExitCriticalSection");
+       } else if (strcmp(bif->name,"System_ThreadResume")==0) {
+               genSystemThreadResume(bi_iCode,nbi_parms,bi_parms);
+       } else if (strcmp(bif->name,"System_SaveThread")==0) {
+               genSystemThreadResume(bi_iCode,nbi_parms,bi_parms);
+       } else if (strcmp(bif->name,"System_ThreadResume")==0) {
+               genSystemThreadResume(bi_iCode,nbi_parms,bi_parms);
+       } else if (strcmp(bif->name,"System_ProcessResume")==0) {
+               genSystemProcessResume(bi_iCode,nbi_parms,bi_parms);
+       } else if (strcmp(bif->name,"System_SaveJavaThreadState")==0) {
+               genSystem(bi_iCode,nbi_parms,"SaveJavaThreadState");
+       } else if (strcmp(bif->name,"System_RestoreJavaThreadState")==0) {
+               genSystem(bi_iCode,nbi_parms,"RestoreJavaThreadState");
+       } else if (strcmp(bif->name,"System_ProcessYield")==0) {
+               genSystem(bi_iCode,nbi_parms,"ProcessYield");
+       } else if (strcmp(bif->name,"System_ProcessSuspend")==0) {
+               genSystem(bi_iCode,nbi_parms,"ProcessSuspend");
+       } else if (strcmp(bif->name,"System_RegisterPoll")==0) {
+               genSystemPoll(bi_iCode,nbi_parms,bi_parms,"Register");
+       } else if (strcmp(bif->name,"System_RemovePoll")==0) {
+               genSystemPoll(bi_iCode,nbi_parms,bi_parms,"Remove");
+       } else if (strcmp(bif->name,"System_GetCurrentThreadId")==0) {
+               genSystemGetCurrentID(bi_iCode,nbi_parms,bi_parms,"Thread");
+       } else if (strcmp(bif->name,"System_GetCurrentProcessId")==0) {
+               genSystemGetCurrentID(bi_iCode,nbi_parms,bi_parms,"Process");
+       } else {
+               werror(E_INTERNAL_ERROR,__FILE__,__LINE__,"unknown builtin function encountered\n");
+               return ;
+       }
+       return ;    
 }
 
 /*-----------------------------------------------------------------*/
@@ -9551,9 +12524,19 @@ gen390Code (iCode * lic)
   int cln = 0;
 
   lineHead = lineCurr = NULL;
-
-#if 0
-  //REMOVE ME!!!
+  dptrn[1][0] = "dpl1";
+  dptrn[1][1] = "dph1";
+  dptrn[1][2] = "dpx1";
+  
+  if (options.model == MODEL_FLAT24) {
+    fReturnSizeDS390 = 5;
+    fReturn = fReturn24;
+  } else {
+    fReturnSizeDS390 = 4;
+    fReturn = fReturn16;
+    options.stack10bit=0;
+  }
+#if 1
   /* print the allocation information */
   if (allocInfo)
     printAllocInfo (currFunc, codeOutFile);
@@ -9579,7 +12562,7 @@ gen390Code (iCode * lic)
   for (ic = lic; ic; ic = ic->next)
     {
 
-      if (cln != ic->lineno)
+      if (ic->lineno && cln != ic->lineno)
        {
          if (options.debug)
            {
@@ -9589,9 +12572,15 @@ gen390Code (iCode * lic)
                        ic->level, ic->block);
              _G.debugLine = 0;
            }
-         emitcode (";", "%s %d", 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
@@ -9749,12 +12738,12 @@ gen390Code (iCode * lic)
          break;
 
        case GET_VALUE_AT_ADDRESS:
-         genPointerGet (ic);
+         genPointerGet (ic,hasInc(IC_LEFT(ic),ic, getSize(operandType(IC_RESULT(ic)))));
          break;
 
        case '=':
          if (POINTER_SET (ic))
-           genPointerSet (ic);
+           genPointerSet (ic,hasInc(IC_RESULT(ic),ic,getSize(operandType(IC_RIGHT(ic)))));
          else
            genAssign (ic);
          break;
@@ -9780,9 +12769,14 @@ gen390Code (iCode * lic)
          break;
 
        case SEND:
-         addSet (&_G.sendSet, ic);
+         if (ic->builtinSEND) genBuiltIn(ic);
+         else addSet (&_G.sendSet, ic);
          break;
 
+       case ARRAYINIT:
+           genArrayInit(ic);
+           break;
+           
        default:
          ic = ic;
        }