reverting to 1.127
[fw/sdcc] / src / ds390 / gen.c
index bd67167cdbf02412650137b18e16fae2edc94a3a..3e23ce3e0e50e83a6933c620399434afa8034613 100644 (file)
@@ -460,27 +460,29 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
       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", "a,_bpx");
+      emitcode ("clr","c");
+      emitcode ("subb", "a,#0x%02x",
+               -((sym->stack < 0) ?
+                 ((short) (sym->stack - _G.nRegsSaved)) :
+                 ((short) sym->stack)) & 0xff);
+      emitcode ("mov","b,a");
+      emitcode ("mov","a,#0x%02x",(-((sym->stack < 0) ?
+                                    ((short) (sym->stack - _G.nRegsSaved)) :
+                                    ((short) sym->stack)) >> 8) & 0xff);
+      emitcode ("subb","a,_bpx+1");
+      if (useDP2) {
          if (options.model == MODEL_FLAT24)
-           emitcode ("mov", "dpx1,#0x40");
+             emitcode ("mov", "dpx1,#0x40");
          TR_DPTR("#2");
-         emitcode ("mov", "dph1,#0x00");
-         emitcode ("mov", "dpl1, a");
-       }
-      else
-       {
+         emitcode ("mov", "dph1,a");
+         emitcode ("mov", "dpl1,b");
+      } else {
          if (options.model == MODEL_FLAT24)
-           emitcode ("mov", "dpx,#0x40");
-         emitcode ("mov", "dph,#0x00");
-         emitcode ("mov", "dpl, a");
-       }
+             emitcode ("mov", "dpx,#0x40");
+         emitcode ("mov", "dph,a");
+         emitcode ("mov", "dpl,b");
+      }
 
       if (_G.accInUse)
        emitcode ("pop", "acc");
@@ -562,6 +564,10 @@ aopForRemat (symbol * sym)
              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;
       
@@ -797,7 +803,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");
+             fprintf (stderr, "*** Internal error: AOP_STR with DPTR in use! for operand %s\n",sym->name);
            }
 
          aop = op->aop = sym->aop = newAsmop (AOP_STR);
@@ -1794,15 +1800,23 @@ saveRegisters (iCode * lic)
 
   /* if the registers have been saved already then
      do nothing */
-  if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type) ||
-      IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic))))
-    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);
+      }
+  } else {
+      /* find the registers in use at this time
+        and push them away to safety */
+      rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                            ic->rUsed);
+  }
   ic->regsSaved = 1;
   if (options.useXstack)
     {
@@ -1843,11 +1857,20 @@ 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 (IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) {
+      int i =0;
+      rsave = newBitVect(ic->rMask->size);
+      for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
+         if (bitVectBitValue(ic->rMask,i))
+             rsave = bitVectSetBit(rsave,i);
+      }
+  } else {
+      /* find the registers in use at this time
+        and push them away to safety */
+      rsave = bitVectCplAnd (bitVectCopy (ic->rMask),
+                            ic->rUsed);
+  }
   if (options.useXstack)
     {
       emitcode ("mov", "r0,%s", spname);
@@ -2250,6 +2273,7 @@ genCall (iCode * ic)
        {
          int size, offset = 0;
 
+#if 0
          aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
          size = AOP_SIZE (IC_LEFT (sic));
 
@@ -2285,6 +2309,29 @@ genCall (iCode * ic)
                                    fReturn[size], regs390[size].name);
              }
          }
+#else
+         // we know that dpl(hxb) is the result, so
+         _startLazyDPSEvaluation ();
+         size=getSize(operandType(IC_LEFT(sic)));
+         if (size>1) {
+           aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
+         } else {
+           aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
+         }
+         while (size--)
+           {
+             char *l = aopGet (AOP (IC_LEFT (sic)), offset,
+                               FALSE, FALSE, TRUE);
+             if (strcmp (l, fReturn[offset]))
+               {
+                 emitcode ("mov", "%s,%s",
+                           fReturn[offset],
+                           l);
+               }
+             offset++;
+           }
+         _endLazyDPSEvaluation ();
+#endif
          freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
        }
       _G.sendSet = NULL;
@@ -2310,6 +2357,7 @@ genCall (iCode * ic)
   /* 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)))
     {
@@ -2348,22 +2396,29 @@ genCall (iCode * ic)
 
   /* adjust the stack for parameters if
      required */
-  if (ic->parmBytes)
-    {
-      int i;
-      if (ic->parmBytes > 3)
-       {
-         emitcode ("mov", "a,%s", spname);
-         emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
-         emitcode ("mov", "%s,a", spname);
-       }
-      else
-       for (i = 0; i < ic->parmBytes; i++)
-         emitcode ("dec", "%s", spname);
-    }
+  if (ic->parmBytes) {
+      if (options.stack10bit) {
+         emitcode ("clr","c");
+         emitcode ("mov","a,sp");
+         emitcode ("subb","a,#0x%02x",ic->parmBytes & 0xff);
+         emitcode ("mov","sp,a");
+         emitcode ("mov","a,#0x%02x",(ic->parmBytes >> 8) & 0xff);
+         emitcode ("subb","a,esp");
+         emitcode ("mov","esp,a");       
+      } else {
+         int i;
+         if (ic->parmBytes > 3) {
+             emitcode ("mov", "a,%s", spname);
+             emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff);
+             emitcode ("mov", "%s,a", spname);
+         } else
+             for (i = 0; i < ic->parmBytes; i++)
+                 emitcode ("dec", "%s", spname);
+      }
+  }
 
   /* if we hade saved some registers then unsave them */
-  if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
+  if (ic->regsSaved)
     unsaveRegisters (ic);
 
   /* if register bank was saved then pop them */
@@ -2429,9 +2484,14 @@ genPcall (iCode * ic)
        {
          int size, offset = 0;
 
-         aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
-         size = AOP_SIZE (IC_LEFT (sic));
+         // we know that dpl(hxb) is the result, so
          _startLazyDPSEvaluation ();
+         size=getSize(operandType(IC_LEFT(sic)));
+         if (size>1) {
+           aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
+         } else {
+           aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
+         }
          while (size--)
            {
              char *l = aopGet (AOP (IC_LEFT (sic)), offset,
@@ -2493,7 +2553,7 @@ genPcall (iCode * ic)
   
   /* if we hade saved some registers then
      unsave them */
-  if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
+  if (ic->regsSaved)
     unsaveRegisters (ic);
 
 }
@@ -2584,15 +2644,17 @@ genFunction (iCode * ic)
       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 = 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);
+         }
        }
     }
 
@@ -2782,44 +2844,54 @@ genFunction (iCode * ic)
       emitcode ("mov", "psw,#0x%02x", (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
     }
 
-  if (IFFUNC_ISREENT (sym->type) || 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);
-    }
+  if (IFFUNC_ISREENT (sym->type) || options.stackAuto) {
+      if (options.stack10bit) {
+         emitcode ("push","_bpx");
+         emitcode ("push","_bpx+1");
+         emitcode ("mov","_bpx,%s",spname);
+         emitcode ("mov","_bpx+1,esp");
+         emitcode ("anl","_bpx+1,#3");
+      } else {
+         if (options.useXstack) {
+             emitcode ("mov", "r0,%s", spname);
+             emitcode ("mov", "a,_bp");
+             emitcode ("movx", "@r0,a");
+             emitcode ("inc", "%s", spname);
+         } else {
+             /* set up the stack */
+             emitcode ("push", "_bp"); /* save the callers stack  */
+         }
+         emitcode ("mov", "_bp,%s", spname);
+      }
+  }
 
   /* adjust the stack for the function */
-  if (sym->stack)
-    {
-
+  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);
+         emitcode ("mov","a,sp");
+         emitcode ("add","a,#0x%02x", ((short) sym->stack & 0xff));
+         emitcode ("mov","sp,a");
+         emitcode ("mov","a,esp");
+         emitcode ("addc","a,0x%02x", (((short) sym->stack) >> 8) & 0xff);
+         emitcode ("mov","esp,a");
+      } else {
+         if (i > 256)
+             werror (W_STACK_OVERFLOW, sym->name);
+         
+         if (i > 3 && sym->recvSize < 4) {
+             
+             emitcode ("mov", "a,sp");
+             emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+             emitcode ("mov", "sp,a");
+             
+         } else
+             while (i--)
+                 emitcode ("inc", "sp");
+      }
+  }
 
   if (sym->xstack)
     {
@@ -2847,36 +2919,40 @@ genEndFunction (iCode * ic)
       return;
   }
 
-  if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
-    {
-      emitcode ("mov", "%s,_bp", spname);
-    }
+  if (IFFUNC_ISREENT (sym->type) || options.stackAuto) {
+      if (options.stack10bit) {
+         emitcode ("mov", "sp,_bpx", spname);
+         emitcode ("mov", "esp,_bpx+1", spname);
+      } else {
+         emitcode ("mov", "%s,_bp", spname);
+      }
+  }
 
   /* if use external stack but some variables were
      added to the local stack then decrement the
      local stack */
-  if (options.useXstack && sym->stack)
-    {
+  if (options.useXstack && sym->stack) {
       emitcode ("mov", "a,sp");
       emitcode ("add", "a,#0x%02x", ((char) -sym->stack) & 0xff);
       emitcode ("mov", "sp,a");
-    }
+  }
 
 
-  if ((IFFUNC_ISREENT (sym->type) || options.stackAuto))
-    {
-      if (options.useXstack)
-       {
+  if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) {
+      if (options.useXstack) {
          emitcode ("mov", "r0,%s", spname);
          emitcode ("movx", "a,@r0");
          emitcode ("mov", "_bp,a");
          emitcode ("dec", "%s", spname);
-       }
-      else
-       {
-         emitcode ("pop", "_bp");
-       }
-    }
+      } else {
+         if (options.stack10bit) {
+             emitcode ("pop", "_bpx+1");
+             emitcode ("pop", "_bpx");
+         } else {
+             emitcode ("pop", "_bp");
+         }
+      }
+  }
 
   /* restore the register bank  */
   if (FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type))
@@ -3055,7 +3131,8 @@ genRet (iCode * ic)
 
   /* 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 ();
@@ -3402,9 +3479,10 @@ adjustArithmeticResult (iCode * ic)
 // 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)); \
     if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \
-        isOperandInFarSpace(IC_RESULT(ic))) \
+        (isOperandInFarSpace(IC_RESULT(ic)) || OP_SYMBOL(IC_RESULT(ic))->ruonly )) \
     { \
        /* No can do; DPTR & DPTR2 in use, and we need another. */ \
        rc = TRUE; \
@@ -3478,7 +3556,34 @@ genPlus (iCode * ic)
   D (emitcode (";", "genPlus "););
 
   /* special cases :- */
-
+  if (isOperandEqual(IC_LEFT(ic),IC_RESULT(ic)) &&
+      isOperandLiteral(IC_RIGHT(ic)) && OP_SYMBOL(IC_RESULT(ic))->ruonly) {
+      aopOp (IC_RIGHT (ic), ic, TRUE, FALSE);
+      size = floatFromVal (AOP (IC_RIGHT(ic))->aopu.aop_lit);
+      if (size <= 9) {
+         while (size--) emitcode ("inc","dptr");
+      } else {
+         emitcode ("mov","a,dpl");
+         emitcode ("add","a,#0x%02x",size & 0xff);
+         emitcode ("mov","dpl,a");
+         emitcode ("mov","a,dph");
+         emitcode ("addc","a,#0x%02x",(size >> 8) & 0xff);
+         emitcode ("mov","dph,a");
+         emitcode ("mov","a,dpx");
+         emitcode ("addc","a,#0x%02x",(size >> 16) & 0xff);
+         emitcode ("mov","dpx,a");
+      }
+      freeAsmop (IC_RIGHT (ic), NULL, ic, FALSE);
+      return ;
+  }
+  if ( IS_SYMOP(IC_LEFT(ic)) && 
+       OP_SYMBOL(IC_LEFT(ic))->remat &&
+       isOperandInFarSpace(IC_RIGHT(ic))) {
+      operand *op = IC_RIGHT(ic);
+      IC_RIGHT(ic) = IC_LEFT(ic);
+      IC_LEFT(ic) = op;
+  }
+               
   AOP_OP_3_NOFATAL (ic, pushResult);
   if (pushResult)
     {
@@ -5390,18 +5495,20 @@ hasInc (operand *op, iCode *ic)
   if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
   isize = getSize(type->next);
   while (lic) {
-    /* if operand of the form op = op + <sizeof *op> */
-    if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
-       isOperandEqual(IC_RESULT(lic),op) && 
-       isOperandLiteral(IC_RIGHT(lic)) &&
-       operandLitValue(IC_RIGHT(lic)) == isize) {
-      return lic;
-    }
-    /* if the operand used or deffed */
-    if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
-      return NULL;
-    }
-    lic = lic->next;
+      /* if operand of the form op = op + <sizeof *op> */
+      if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
+         isOperandEqual(IC_RESULT(lic),op) && 
+         isOperandLiteral(IC_RIGHT(lic)) &&
+         operandLitValue(IC_RIGHT(lic)) == isize) {
+         return lic;
+      }
+      /* if the operand used or deffed */
+      if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
+         return NULL;
+      }
+      /* if GOTO or IFX */
+      if (lic->op == IFX || lic->op == GOTO) break;
+      lic = lic->next;
   }
   return NULL;
 }
@@ -6461,6 +6568,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--)
@@ -6476,9 +6584,15 @@ genXor (iCode * ic, iCode * ifx)
                    emitcode ("xrl", "a,%s",
                              aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
                  } else {
-                   MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
-                   emitcode ("xrl", "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 ("xrl", "a,%s", rOp);                  
                  }
                }
              emitcode ("jnz", "%05d$", tlbl->key + 100);
@@ -6494,6 +6608,7 @@ genXor (iCode * ic, iCode * ifx)
            jmpTrueOrFalse (ifx, tlbl);
        }
       else
+       {
        for (; (size--); offset++)
          {
            // normal case
@@ -6507,8 +6622,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));
@@ -6537,6 +6651,8 @@ genXor (iCode * ic, iCode * ifx)
              }
            aopPut (AOP (result), "a", offset);
          }
+       }
+       
     }
 
 release:
@@ -8775,7 +8891,7 @@ static void
 genFarPointerGet (operand * left,
                  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");
@@ -8814,12 +8930,12 @@ genFarPointerGet (operand * left,
                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);
 
   /* if bit then unpack */
@@ -8838,21 +8954,27 @@ genFarPointerGet (operand * left,
          _flushLazyDPS ();
 
          emitcode ("movx", "a,@dptr");
-         if (size || pi)
+         if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
            emitcode ("inc", "dptr");
 
          aopPut (AOP (result), "a", offset++);
        }
       _endLazyDPSEvaluation ();
     }
-  if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) {
+  if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) {
     aopPut ( AOP (left), "dpl", 0);
     aopPut ( AOP (left), "dph", 1);
     if (options.model == MODEL_FLAT24)
            aopPut ( AOP (left), "dpx", 2);
     pi->generated = 1;
+  } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
+            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (result) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
   }
 
+  freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
 }
 
@@ -8863,7 +8985,7 @@ static void
 emitcodePointerGet (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);
@@ -8898,6 +9020,7 @@ emitcodePointerGet (operand * left,
                emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE, TRUE));
              emitcode ("pop", "dph");
              emitcode ("pop", "dpl");
+             dopi=0;
            }
          _endLazyDPSEvaluation ();
        }
@@ -8921,20 +9044,25 @@ emitcodePointerGet (operand * left,
 
          emitcode ("clr", "a");
          emitcode ("movc", "a,@a+dptr");
-         if (size || pi)
+         if (size || (dopi && pi && AOP_TYPE (left) != AOP_IMMD))
            emitcode ("inc", "dptr");
          aopPut (AOP (result), "a", offset++);
        }
       _endLazyDPSEvaluation ();
     }
-  if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) {
-    aopPut ( AOP (left), "dpl", 0);
-    aopPut ( AOP (left), "dph", 1);
-    if (options.model == MODEL_FLAT24)
-           aopPut ( AOP (left), "dpx", 2);
-    pi->generated = 1;
+  if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) {
+      aopPut ( AOP (left), "dpl", 0);
+      aopPut ( AOP (left), "dph", 1);
+      if (options.model == MODEL_FLAT24)
+         aopPut ( AOP (left), "dpx", 2);
+      pi->generated = 1;
+  } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
+            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (result) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
   }
-
+  
   freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
 }
@@ -8952,7 +9080,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 */
@@ -9017,20 +9145,26 @@ genGenPointerGet (operand * left,
        {
          emitcode ("lcall", "__gptrget");
          aopPut (AOP (result), "a", offset++);
-         if (size || pi)
+         if (size || (pi && AOP_TYPE (left) != AOP_IMMD))
            emitcode ("inc", "dptr");
        }
     }
 
-  if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) {
+  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);       
+       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);
 }
@@ -9503,7 +9637,7 @@ static void
 genFarPointerSet (operand * right,
                  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));
 
@@ -9538,6 +9672,7 @@ genFarPointerSet (operand * right,
                emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE, TRUE));
              emitcode ("pop", "dph");
              emitcode ("pop", "dpl");
+             dopi=0;
            }
          _endLazyDPSEvaluation ();
        }
@@ -9563,18 +9698,23 @@ genFarPointerSet (operand * right,
          _flushLazyDPS ();
 
          emitcode ("movx", "@dptr,a");
-         if (size || pi)
+         if (size || (dopi && pi && AOP_TYPE (result) != AOP_IMMD))
            emitcode ("inc", "dptr");
        }
       _endLazyDPSEvaluation ();
     }
 
-  if (pi && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD) {
-    aopPut (AOP(result),"dpl",0);
-    aopPut (AOP(result),"dph",1);
-    if (options.model == MODEL_FLAT24)
-       aopPut (AOP(result),"dpx",2);
-    pi->generated=1;
+  if (dopi && pi && AOP_TYPE (result) != AOP_IMMD) {
+      aopPut (AOP(result),"dpl",0);
+      aopPut (AOP(result),"dph",1);
+      if (options.model == MODEL_FLAT24)
+         aopPut (AOP(result),"dpx",2);
+      pi->generated=1;
+  } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 &&
+            (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) {
+      
+      size = AOP_SIZE (right) - 1;
+      while (size--) emitcode ("lcall","__decdptr");
   }
   freeAsmop (result, NULL, ic, TRUE);
   freeAsmop (right, NULL, ic, TRUE);
@@ -9591,7 +9731,7 @@ genGenPointerSet (operand * right,
   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 */
@@ -9641,22 +9781,27 @@ genGenPointerSet (operand * right,
          _flushLazyDPS ();
 
          emitcode ("lcall", "__gptrput");
-         if (size || pi)
+         if (size || (pi && AOP_TYPE (result) != AOP_IMMD))
            emitcode ("inc", "dptr");
        }
       _endLazyDPSEvaluation ();
     }
 
-  if (pi && AOP_TYPE (result) != AOP_STR && 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;
+  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);
@@ -9779,47 +9924,64 @@ 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) {
+         /* if it has an offset then we need to compute it */
+      emitcode ("subb", "a,#0x%02x",
+               -((sym->stack < 0) ?
+                 ((short) (sym->stack - _G.nRegsSaved)) :
+                 ((short) sym->stack)) & 0xff);
+      emitcode ("mov","b,a");
+      emitcode ("mov","a,#0x%02x",(-((sym->stack < 0) ?
+                                    ((short) (sym->stack - _G.nRegsSaved)) :
+                                    ((short) sym->stack)) >> 8) & 0xff);
+         if (sym->stack) {
+             emitcode ("mov", "a,_bpx");
+             emitcode ("add", "a,#0x%02x", ((sym->stack < 0) ? 
+                                            ((char) (sym->stack - _G.nRegsSaved)) :
+                                            ((char) sym->stack )) & 0xff);
+             emitcode ("mov", "b,a");
+             emitcode ("mov", "a,_bpx+1");
+             emitcode ("addc","a,#0x%02x", (((sym->stack < 0) ? 
+                                             ((short) (sym->stack - _G.nRegsSaved)) :
+                                             ((short) sym->stack )) >> 8) & 0xff);
+             aopPut (AOP (IC_RESULT (ic)), "b", 0);
+             aopPut (AOP (IC_RESULT (ic)), "a", 1);
+             aopPut (AOP (IC_RESULT (ic)), "#0x40", 2);
+         } else {
+             /* we can just move _bp */
+             aopPut (AOP (IC_RESULT (ic)), "_bpx", 0);
+             aopPut (AOP (IC_RESULT (ic)), "_bpx+1", 1);
+             aopPut (AOP (IC_RESULT (ic)), "#0x40", 2);
+         }       
+      } else {
+         /* if it has an offset then we need to compute it */
+         if (sym->stack) {
+             emitcode ("mov", "a,_bp");
+             emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+             aopPut (AOP (IC_RESULT (ic)), "a", 0);
+         } else {
+             /* we can just move _bp */
+             aopPut (AOP (IC_RESULT (ic)), "_bp", 0);
+         }
+         /* fill the result with zero */
+         size = AOP_SIZE (IC_RESULT (ic)) - 1;
+         
+         
+         if (options.stack10bit && size < (FPTRSIZE - 1)) {
+             fprintf (stderr,
+                      "*** warning: pointer to stack var truncated.\n");
+         }
 
-      offset = 1;
-      while (size--)
-       {
-         /* 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));