fixed bug #449107
[fw/sdcc] / src / ds390 / gen.c
index 9db62c56fb76c3b536565bb9939fa58f8d14976e..a400563ae157fe140e970452a66bdbac755bf17e 100644 (file)
@@ -62,8 +62,8 @@ char *aopLiteral (value * val, int offset);
    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
@@ -79,7 +79,7 @@ static char *fReturn16[] =
 static char **fReturn = fReturn24;
 static char *accUse[] =
 {"a", "b"};
-
+static char *javaRet[] = { "r0","r1","r2","r3"};
 static short rbank = -1;
 
 static struct
@@ -114,7 +114,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;
@@ -294,12 +294,12 @@ genSetDPTR (int n)
 
   if (!n)
     {
-      emitcode ("mov", "dps, #0x00");
+      emitcode ("mov", "dps,#0");
     }
   else
     {
       TR_DPTR("#1");
-      emitcode ("mov", "dps, #0x01");
+      emitcode ("mov", "dps,#1");
     }
 }
 
@@ -460,49 +460,68 @@ 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)) ;
       /* It's on the 10 bit stack, which is located in
        * far data space.
        */
-
-      if (_G.accInUse)
-       emitcode ("push", "acc");
-
-      if (_G.bInUse)
-       emitcode ("push", "b");
-
-      emitcode ("mov", "a,_bpx");
-      emitcode ("clr","c");
-      emitcode ("subb", "a,#!constbyte",
-               -((sym->stack < 0) ?
-                 ((short) (sym->stack - _G.nRegsSaved)) :
-                 ((short) sym->stack)) & 0xff);
-      emitcode ("mov","b,a");
-      emitcode ("mov","a,_bpx+1");
-      emitcode ("subb","a,#!constbyte",(-((sym->stack < 0) ?
-                                    ((short) (sym->stack - _G.nRegsSaved)) :
-                                    ((short) sym->stack)) >> 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");
-
-      sym->aop = aop = newAsmop ((short) (useDP2 ? AOP_DPTR2 : AOP_DPTR));
-      aop->size = getSize (sym->type);
-      return aop;
+       if (stack_val < 0 && stack_val > -3) { /* between -3 & -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");
+       }
+       sym->aop = aop = newAsmop ((short) (useDP2 ? AOP_DPTR2 : AOP_DPTR));
+       aop->size = getSize (sym->type);
+       return aop;
     }
 
   /* if in bit space */
@@ -607,6 +626,23 @@ aopForRemat (symbol * sym)
   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       */
 /*-----------------------------------------------------------------*/
@@ -1637,7 +1673,7 @@ genNot (iCode * ic)
   toBoolean (IC_LEFT (ic));
 
   tlbl = newiTempLabel (NULL);
-  emitcode ("cjne", "a,#0x01,!tlabel", tlbl->key + 100);
+  emitcode ("cjne", "a,#1,!tlabel", tlbl->key + 100);
   emitcode ("", "!tlabeldef", tlbl->key + 100);
   outBitC (IC_RESULT (ic));
 
@@ -1656,6 +1692,7 @@ genCpl (iCode * ic)
 {
   int offset = 0;
   int size;
+  symbol *tlbl;
 
   D (emitcode (";", "genCpl ");
     );
@@ -1665,17 +1702,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 ();
@@ -1806,16 +1847,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)
@@ -1841,42 +1911,44 @@ saveRegisters (iCode * lic)
          if (bitVectBitValue(ic->rMask,i))
              rsave = bitVectSetBit(rsave,i);
       }
+      rsave = bitVectCplAnd(rsave,ds390_rUmaskForOp (IC_RESULT(ic)));
   } else {
-      /* find the registers in use at this time
-        and push them away to safety */
-      rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
-                            ic->rUsed);
+    /* 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)));
 }
 
 /*-----------------------------------------------------------------*/
@@ -1885,7 +1957,6 @@ saveRegisters (iCode * lic)
 static void
 unsaveRegisters (iCode * ic)
 {
-  int i;
   bitVect *rsave;
 
   if (IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) {
@@ -1895,39 +1966,14 @@ unsaveRegisters (iCode * ic)
          if (bitVectBitValue(ic->rMask,i))
              rsave = bitVectSetBit(rsave,i);
       }
+      rsave = bitVectCplAnd(rsave,ds390_rUmaskForOp (IC_RESULT(ic)));
   } else {
-      /* find the registers in use at this time
-        and push them away to safety */
-      rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
-                            ic->rUsed);
+    /* 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)));
   }
-  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);
-      }
-
+  unsavermask(rsave);
 }
 
 
@@ -2303,43 +2349,6 @@ genCall (iCode * ic)
        {
          int size, offset = 0;
 
-#if 0
-         aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
-         size = AOP_SIZE (IC_LEFT (sic));
-
-         _startLazyDPSEvaluation ();
-         while (size--)
-           {
-             char *l = aopGet (AOP(IC_LEFT(sic)), offset,
-                               FALSE, FALSE, TRUE);
-               if ((AOP_TYPE(IC_LEFT(sic)) == AOP_DPTR) && size)
-               {
-                   emitcode("mov", "%s,%s", regs390[offset].name, l);
-               }
-               else if (strcmp (l, fReturn[offset]))
-               {
-                   emitcode ("mov", "%s,%s",
-                             fReturn[offset],
-                             l);
-               }
-             offset++;
-           }
-         _endLazyDPSEvaluation ();
-         if (AOP_TYPE(IC_LEFT(sic)) == AOP_DPTR)
-         {
-             size = AOP_SIZE (IC_LEFT (sic));
-             if (size)
-             {
-                size--;
-             }
-             while (size)
-             {
-                  size--;
-                  emitcode("mov", "%s,%s",
-                                   fReturn[size], regs390[size].name);
-             }
-         }
-#else
          // we know that dpl(hxb) is the result, so
          _startLazyDPSEvaluation ();
          size=getSize(operandType(IC_LEFT(sic)));
@@ -2362,7 +2371,6 @@ genCall (iCode * ic)
              offset++;
            }
          _endLazyDPSEvaluation ();
-#endif
          freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
        }
       _G.sendSet = NULL;
@@ -2428,16 +2436,23 @@ genCall (iCode * ic)
   /* adjust the stack for parameters if
      required */
   if (ic->parmBytes) {
+      int i;
       if (options.stack10bit) {
-         emitcode ("clr","c");
-         emitcode ("mov","a,sp");
-         emitcode ("subb","a,#!constbyte",ic->parmBytes & 0xff);
-         emitcode ("mov","sp,a");
-         emitcode ("mov","a,esp");
-         emitcode ("subb","a,#!constbyte",(ic->parmBytes >> 8) & 0xff);
-         emitcode ("mov","esp,a");       
+         if (ic->parmBytes <= 4) {
+             emitcode(";","stack adjustment for parms");
+             for (i=0; i < ic->parmBytes ; i++) {
+                 emitcode("pop","acc");
+             }
+         } else {
+             emitcode ("clr","c");
+             emitcode ("mov","a,sp");
+             emitcode ("subb","a,#!constbyte",ic->parmBytes & 0xff);
+             emitcode ("mov","sp,a");
+             emitcode ("mov","a,esp");
+             emitcode ("subb","a,#!constbyte",(ic->parmBytes >> 8) & 0xff);
+             emitcode ("mov","esp,a");   
+         }
       } else {
-         int i;
          if (ic->parmBytes > 3) {
              emitcode ("mov", "a,%s", spname);
              emitcode ("add", "a,#!constbyte", (-ic->parmBytes) & 0xff);
@@ -2679,11 +2694,11 @@ genFunction (iCode * ic)
        {
          if (regs390[i].print) {
              if (strcmp (regs390[i].base, "0") == 0)
-                 emitcode ("", "%s = !constbyte",
+                 emitcode ("", "%s !equ !constbyte",
                            regs390[i].dname,
                            8 * rbank + regs390[i].offset);
              else
-                 emitcode ("", "%s = %s + !constbyte",
+                 emitcode ("", "%s !equ %s + !constbyte",
                            regs390[i].dname,
                            regs390[i].base,
                            8 * rbank + regs390[i].offset);
@@ -2709,7 +2724,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. */
@@ -2877,7 +2892,8 @@ genFunction (iCode * ic)
       emitcode ("mov", "psw,#!constbyte", (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
     }
 
-  if (IFFUNC_ISREENT (sym->type) || options.stackAuto) {
+  if ( (IFFUNC_ISREENT (sym->type) || options.stackAuto) &&
+       (sym->stack || FUNC_HASSTACKPARM(sym->type))) {
       if (options.stack10bit) {
          emitcode ("push","_bpx");
          emitcode ("push","_bpx+1");
@@ -2952,7 +2968,9 @@ genEndFunction (iCode * ic)
       return;
   }
 
-  if (IFFUNC_ISREENT (sym->type) || options.stackAuto) {
+  if ((IFFUNC_ISREENT (sym->type) || options.stackAuto) &&
+       (sym->stack || FUNC_HASSTACKPARM(sym->type))) {
+
       if (options.stack10bit) {
          emitcode ("mov", "sp,_bpx", spname);
          emitcode ("mov", "esp,_bpx+1", spname);
@@ -2971,7 +2989,9 @@ genEndFunction (iCode * ic)
   }
 
 
-  if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) {
+  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");
@@ -3146,6 +3166,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                     */
 /*-----------------------------------------------------------------*/
@@ -3162,6 +3213,12 @@ 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, 
@@ -3288,6 +3345,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 &&
@@ -3320,7 +3384,7 @@ 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,!tlabel"
+       emitcode ("cjne", "%s,#0,!tlabel"
                  ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
                  ,tlbl->key + 100);
       else
@@ -3336,7 +3400,7 @@ genPlusIncr (iCode * ic)
        {
          if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
              IS_AOP_PREG (IC_RESULT (ic)))
-           emitcode ("cjne", "%s,#0x00,!tlabel"
+           emitcode ("cjne", "%s,#0,!tlabel"
                  ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
                      ,tlbl->key + 100);
          else
@@ -3350,7 +3414,7 @@ genPlusIncr (iCode * ic)
        {
          if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
              IS_AOP_PREG (IC_RESULT (ic)))
-           emitcode ("cjne", "%s,#0x00,!tlabel"
+           emitcode ("cjne", "%s,#0,!tlabel"
                  ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
                      ,tlbl->key + 100);
          else
@@ -3450,7 +3514,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));
     }
 }
@@ -3513,9 +3577,9 @@ adjustArithmeticResult (iCode * ic)
 #define AOP_OP_3_NOFATAL(ic, rc) \
     aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
     aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR) || \
-                                  (OP_SYMBOL(IC_RESULT(ic))->ruonly)); \
+                                  ((OP_SYMBOL(IC_RESULT(ic))->ruonly) && !isOperandEqual(IC_LEFT(ic),IC_RESULT(ic)))); \
     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \
-        (isOperandInFarSpace(IC_RESULT(ic)) || OP_SYMBOL(IC_RESULT(ic))->ruonly )) \
+        (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; \
@@ -3666,7 +3730,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 ();
@@ -3788,6 +3852,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 &&
@@ -3821,12 +3892,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,!tlabel"
-                 ,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 ("mov", "a,#!constbyte",0xff);
          emitcode ("cjne", "a,%s,!tlabel"
                    ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
                    ,tlbl->key + 100);
@@ -3837,8 +3908,8 @@ 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,!tlabel"
-                 ,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
            {
@@ -3853,8 +3924,8 @@ 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,!tlabel"
-                 ,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
            {
@@ -4293,7 +4364,7 @@ static void genMultTwoByte (operand *left, operand *right,
        lbl = newiTempLabel(NULL);
        emitcode("","!tlabeldef", lbl->key+100);
        emitcode("mov","a,mcnt1");
-       emitcode("anl","a,#0x80");
+       emitcode("anl","a,#!constbyte",0x80);
        emitcode("jnz","!tlabel",lbl->key+100);
        
        freeAsmop (left, NULL, ic, TRUE);
@@ -4623,7 +4694,7 @@ static void genDivTwoByte (operand *left, operand *right,
        lbl = newiTempLabel(NULL);
        emitcode("","!tlabeldef", lbl->key+100);
        emitcode("mov","a,mcnt1");
-       emitcode("anl","a,#0x80");
+       emitcode("anl","a,#!constbyte",0x80);
        emitcode("jnz","!tlabel",lbl->key+100);
        
        freeAsmop (left, NULL, ic, TRUE);
@@ -4877,7 +4948,7 @@ static void genModTwoByte (operand *left, operand *right,
        lbl = newiTempLabel(NULL);
        emitcode("","!tlabeldef", lbl->key+100);
        emitcode("mov","a,mcnt1");
-       emitcode("anl","a,#0x80");
+       emitcode("anl","a,#!constbyte",0x80);
        emitcode("jnz","!tlabel",lbl->key+100);
        
        freeAsmop (left, NULL, ic, TRUE);
@@ -5014,7 +5085,7 @@ 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,!tlabel",
@@ -5062,31 +5133,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 (";", "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");
@@ -5098,11 +5169,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");
@@ -5110,7 +5181,7 @@ genCmp (operand * left, operand * right,
                    }
                  else
                    {
-                     emitcode (";", "genCmp #4.2");
+                     //emitcode (";", "genCmp #4.2");
                      s = aopGet (AOP (right), offset++, FALSE, FALSE, FALSE);
                    }
 
@@ -5517,7 +5588,7 @@ ifxForOp (operand * op, iCode * ic)
 /* hasInc - operand is incremented before any other use            */
 /*-----------------------------------------------------------------*/
 static iCode *
-hasInc (operand *op, iCode *ic)
+hasInc (operand *op, iCode *ic, int osize)
 {
   sym_link *type = operandType(op);
   sym_link *retype = getSpec (type);
@@ -5528,7 +5599,9 @@ hasInc (operand *op, iCode *ic)
   if (!IS_SYMOP(op)) return NULL;
 
   if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
-  isize = getSize(type->next);
+  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) &&
@@ -5542,7 +5615,7 @@ hasInc (operand *op, iCode *ic)
          return NULL;
       }
       /* if GOTO or IFX */
-      if (lic->op == IFX || lic->op == GOTO) break;
+      if (lic->op == IFX || lic->op == GOTO || lic->op == LABEL) break;
       lic = lic->next;
   }
   return NULL;
@@ -6533,7 +6606,7 @@ 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 ("anl", "a,#!constbyte",0xfe);
                  emitcode ("jnz", "!tlabel", tlbl->key + 100);
                  sizer--;
                }
@@ -6870,7 +6943,7 @@ genGetHbit (iCode * ic)
   else
     {
       emitcode ("rl", "a");
-      emitcode ("anl", "a,#0x01");
+      emitcode ("anl", "a,#1");
       outAcc (result);
     }
 
@@ -7831,7 +7904,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));
@@ -10205,7 +10278,7 @@ 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. */
+      emitcode("mov", "dps,#!constbyte",0x21);         /* Select DPTR2 & auto-toggle. */
       emitcode ("mov", "dptr,#%s", rSym->rname); 
       /* DP2 = result, DP1 = right, DP1 is current. */
       while (size)
@@ -10218,13 +10291,13 @@ 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, #0x01");         /* Select DPTR2. */
+        emitcode("mov", "dps,#1");     /* Select DPTR2. */
         emitcode ("mov", "dptr,#%s", rSym->rname); 
         /* DP2 = result, DP1 = right, DP1 is current. */
         while (size)
@@ -10239,7 +10312,7 @@ no time to test now, so later well put in...kpb
             emitcode("inc", "dptr");
           emitcode("inc", "dps");
         }
-        emitcode("mov", "dps, #0");
+        emitcode("mov", "dps,#0");
         freeAsmop (right, NULL, ic, FALSE);
 #endif
   }
@@ -10782,10 +10855,22 @@ 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];
@@ -10836,8 +10921,8 @@ static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc)
     /* now for the actual copy */
     if (AOP_TYPE(count) == AOP_LIT && 
        (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
-       emitcode (";","OH! JOY auto increment with djnz (very fast)");
-       emitcode ("mov", "dps, #0x21");         /* Select DPTR2 & auto-toggle. */
+       emitcode (";","OH  JOY auto increment with djnz (very fast)");
+       emitcode ("mov", "dps,#!constbyte",0x21);       /* Select DPTR2 & auto-toggle. */
        emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE));
        emitcode ("","!tlabeldef",lbl->key+100);
        if (fromc) {
@@ -10853,9 +10938,9 @@ static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc)
        symbol *lbl1 = newiTempLabel(NULL);
        
        emitcode (";"," Auto increment but no djnz");
-       emitcode ("mov","ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
+       emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
        emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
-       emitcode ("mov", "dps, #0x21");         /* Select DPTR2 & auto-toggle. */
+       emitcode ("mov", "dps,#!constbyte",0x21);       /* Select DPTR2 & auto-toggle. */
        emitcode ("","!tlabeldef",lbl->key+100);
        if (fromc) {
            emitcode ("clr","a");
@@ -10866,19 +10951,20 @@ static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc)
        emitcode ("inc", "dptr");
        emitcode ("inc", "dptr");
        emitcode ("mov","a,b");
-       emitcode ("orl","a,ap");
+       emitcode ("orl","a,_ap");
        emitcode ("jz","!tlabel",lbl1->key+100);
-       emitcode ("mov","a,ap");
-       emitcode ("add","a,#0xFF");
-       emitcode ("mov","ap,a");
+       emitcode ("mov","a,_ap");
+       emitcode ("add","a,#!constbyte",0xFF);
+       emitcode ("mov","_ap,a");
        emitcode ("mov","a,b");
-       emitcode ("addc","a,#0xFF");
+       emitcode ("addc","a,#!constbyte",0xFF);
        emitcode ("mov","b,a");
        emitcode ("sjmp","!tlabel",lbl->key+100);
        emitcode ("","!tlabeldef",lbl1->key+100);
     }
-    emitcode ("mov", "dps, #0"); 
+    emitcode ("mov", "dps,#0"); 
     freeAsmop (count, NULL, ic, FALSE);
+    unsavermask(rsave);
 
 }
 
@@ -10890,12 +10976,25 @@ 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 */
@@ -10943,7 +11042,7 @@ static void genMemsetX(iCode *ic, int nparms, operand **parms)
     } else {
        symbol *lbl1 = newiTempLabel(NULL);
        
-       emitcode ("mov","ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
+       emitcode ("mov","_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);
@@ -10951,18 +11050,616 @@ static void genMemsetX(iCode *ic, int nparms, operand **parms)
        emitcode ("movx", "a,@dptr");
        emitcode ("inc", "dptr");
        emitcode ("mov","a,b");
-       emitcode ("orl","a,ap");
+       emitcode ("orl","a,_ap");
        emitcode ("jz","!tlabel",lbl1->key+100);
-       emitcode ("mov","a,ap");
-       emitcode ("add","a,#0xFF");
-       emitcode ("mov","ap,a");
+       emitcode ("mov","a,_ap");
+       emitcode ("add","a,#!constbyte",0xFF);
+       emitcode ("mov","_ap,a");
        emitcode ("mov","a,b");
-       emitcode ("addc","a,#0xFF");
+       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");
+       
+       {
+               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);
+                       }
+               }
+       }
+       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");
+
+       {
+               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);
+}
+
+/*-----------------------------------------------------------------*/
+/* genSystemRTCRegisters -                                         */
+/*-----------------------------------------------------------------*/
+static void genSystemRTCRegisters(iCode *ic,int nparms, operand **parms,
+                                 char *name)
+{
+       bitVect *rsave ;
+       operand *pp;
+
+       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);
+               }
+       }
 }
 
 /*-----------------------------------------------------------------*/
@@ -10971,27 +11668,97 @@ static void genMemsetX(iCode *ic, int nparms, operand **parms)
 /*-----------------------------------------------------------------*/
 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_memset_x")==0) {
-       genMemsetX(bi_iCode,nbi_parms,bi_parms);
-    } else {
-       werror(E_INTERNAL_ERROR,"unknown builtin function encountered\n");
-       return ;
-    }
-    return ;    
+       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_memset_x")==0) {
+               genMemsetX(bi_iCode,nbi_parms,bi_parms);
+       } 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 ;    
 }
 
 /*-----------------------------------------------------------------*/
@@ -11210,12 +11977,12 @@ gen390Code (iCode * lic)
          break;
 
        case GET_VALUE_AT_ADDRESS:
-         genPointerGet (ic,hasInc(IC_LEFT(ic),ic));
+         genPointerGet (ic,hasInc(IC_LEFT(ic),ic, getSize(operandType(IC_LEFT(ic)))));
          break;
 
        case '=':
          if (POINTER_SET (ic))
-           genPointerSet (ic,hasInc(IC_RESULT(ic),ic));
+           genPointerSet (ic,hasInc(IC_RESULT(ic),ic,getSize(operandType(IC_RIGHT(ic)))));
          else
            genAssign (ic);
          break;