Previous fix was BADDD . this should do it
[fw/sdcc] / src / mcs51 / gen.c
index 78725f19686023b03b2396b8423ef8041c9ed76c..6ea17c482f7864b701db871d101b18b5d35e52b4 100644 (file)
@@ -28,6 +28,9 @@
       Made everything static
 -------------------------------------------------------------------------*/
 
+//#define D(x)
+#define D(x) x
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #ifdef HAVE_SYS_ISA_DEFS_H
 #include <sys/isa_defs.h>
 #else
+#ifdef HAVE_MACHINE_ENDIAN_H
+#include <machine/endian.h>
+#else
 #ifdef HAVE_ENDIAN_H
 #include <endian.h>
 #else
-#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__)
+#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
 #endif
 #endif
 #endif
+#endif
 
 #include "common.h"
 #include "SDCCpeeph.h"
@@ -162,9 +169,9 @@ getFreePtr (iCode * ic, asmop ** aopp, bool result)
 
   /* first check if r0 & r1 are used by this
      instruction, in which case we are in trouble */
-  if ((r0iu = bitVectBitValue (ic->rUsed, R0_IDX)) &&
-      (r1iu = bitVectBitValue (ic->rUsed, R1_IDX)))
-    {
+  r0iu = bitVectBitValue (ic->rUsed, R0_IDX);
+  r1iu = bitVectBitValue (ic->rUsed, R1_IDX);
+  if (r0iu && r1iu) {
       goto endOfWorld;
     }
 
@@ -236,7 +243,7 @@ endOfWorld:
   /* other wise this is true end of the world */
   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
          "getFreePtr should never reach here");
-  exit (0);
+  exit (1);
 }
 
 /*-----------------------------------------------------------------*/
@@ -270,7 +277,12 @@ static asmop *
 aopForSym (iCode * ic, symbol * sym, bool result)
 {
   asmop *aop;
-  memmap *space = SPEC_OCLS (sym->etype);
+  memmap *space;
+
+  wassertl (ic != NULL, "Got a null iCode");
+  wassertl (sym != NULL, "Got a null symbol");
+
+  space = SPEC_OCLS (sym->etype);
 
   /* if already has one */
   if (sym->aop)
@@ -338,8 +350,8 @@ aopForSym (iCode * ic, symbol * sym, bool result)
   if (IS_FUNC (sym->type))
     {
       sym->aop = aop = newAsmop (AOP_IMMD);
-      aop->aopu.aop_immd = Safe_calloc (1, strlen (sym->rname) + 1);
-      strcpy (aop->aopu.aop_immd, sym->rname);
+      aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (sym->rname) + 1);
+      strcpy (aop->aopu.aop_immd.aop_immd1, sym->rname);
       aop->size = FPTRSIZE;
       return aop;
     }
@@ -365,6 +377,7 @@ aopForRemat (symbol * sym)
 {
   iCode *ic = sym->rematiCode;
   asmop *aop = newAsmop (AOP_IMMD);
+  int ptr_type=0;
   int val = 0;
 
   for (;;)
@@ -373,8 +386,17 @@ aopForRemat (symbol * sym)
        val += (int) operandLitValue (IC_RIGHT (ic));
       else if (ic->op == '-')
        val -= (int) operandLitValue (IC_RIGHT (ic));
-      else
-       break;
+      else if (IS_CAST_ICODE(ic)) {
+             sym_link *from_type = operandType(IC_RIGHT(ic));
+             aop->aopu.aop_immd.from_cast_remat = 1;
+             ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
+             ptr_type = DCL_TYPE(from_type);
+             if (ptr_type == IPOINTER) {
+               // bug #481053
+               ptr_type = POINTER;
+             }
+             continue ;
+      } else break;
 
       ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
     }
@@ -387,8 +409,15 @@ aopForRemat (symbol * sym)
   else
     strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
 
-  aop->aopu.aop_immd = Safe_calloc (1, strlen (buffer) + 1);
-  strcpy (aop->aopu.aop_immd, buffer);
+  aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1);
+  strcpy (aop->aopu.aop_immd.aop_immd1, buffer);
+  /* set immd2 field if required */
+  if (aop->aopu.aop_immd.from_cast_remat) {
+         sprintf(buffer,"#0x%02x",ptr_type);
+         aop->aopu.aop_immd.aop_immd2 = Safe_calloc (1, strlen (buffer) + 1);
+         strcpy (aop->aopu.aop_immd.aop_immd2, buffer);
+  }
+
   return aop;
 }
 
@@ -525,7 +554,7 @@ aopOp (operand * op, iCode * ic, bool result)
     }
 
   /* if already has a asmop then continue */
-  if (op->aop)
+  if (op->aop )
     return;
 
   /* if the underlying symbol has a aop */
@@ -552,7 +581,6 @@ aopOp (operand * op, iCode * ic, bool result)
 
   sym = OP_SYMBOL (op);
 
-
   /* if the type is a conditional */
   if (sym->regType == REG_CND)
     {
@@ -589,6 +617,7 @@ aopOp (operand * op, iCode * ic, bool result)
       if (sym->ruonly)
        {
          unsigned i;
+
          aop = op->aop = sym->aop = newAsmop (AOP_STR);
          aop->size = getSize (sym->type);
          for (i = 0; i < fReturnSizeMCS51; i++)
@@ -597,6 +626,10 @@ aopOp (operand * op, iCode * ic, bool result)
        }
 
       /* else spill location  */
+      if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
+         /* force a new aop if sizes differ */
+         sym->usl.spillLoc->aop = NULL;
+      }
       sym->aop = op->aop = aop =
        aopForSym (ic, sym->usl.spillLoc, result);
       aop->size = getSize (sym->type);
@@ -790,15 +823,17 @@ aopGet (asmop * aop, int offset, bool bit16, bool dname)
 
 
     case AOP_IMMD:
-      if (bit16)
-       sprintf (s, "#%s", aop->aopu.aop_immd);
+      if (aop->aopu.aop_immd.from_cast_remat && (offset == (aop->size-1))) {
+             sprintf(s,"%s",aop->aopu.aop_immd.aop_immd2);
+      } else if (bit16)
+       sprintf (s, "#%s", aop->aopu.aop_immd.aop_immd1);
       else if (offset)
        sprintf (s, "#(%s >> %d)",
-                aop->aopu.aop_immd,
+                aop->aopu.aop_immd.aop_immd1,
                 offset * 8);
       else
        sprintf (s, "#%s",
-                aop->aopu.aop_immd);
+                aop->aopu.aop_immd.aop_immd1);
       rs = Safe_calloc (1, strlen (s) + 1);
       strcpy (rs, s);
       return rs;
@@ -846,7 +881,7 @@ aopGet (asmop * aop, int offset, bool bit16, bool dname)
 
   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
          "aopget got unsupported aop->type");
-  exit (0);
+  exit (1);
 }
 /*-----------------------------------------------------------------*/
 /* aopPut - puts a string for a aop                                */
@@ -860,7 +895,7 @@ aopPut (asmop * aop, char *s, int offset)
     {
       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
              "aopPut got offset > aop->size");
-      exit (0);
+      exit (1);
     }
 
   /* will assign value to value */
@@ -905,7 +940,7 @@ aopPut (asmop * aop, char *s, int offset)
        {
          werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
                  "aopPut writting to code space");
-         exit (0);
+         exit (1);
        }
 
       while (offset > aop->coff)
@@ -976,7 +1011,12 @@ aopPut (asmop * aop, char *s, int offset)
       if (strcmp (s, "a") == 0)
        emitcode ("push", "acc");
       else
-       emitcode ("push", "%s", s);
+       if (*s=='@') {
+         MOVA(s);
+         emitcode ("push", "acc");
+       } else {
+         emitcode ("push", s);
+       }
 
       break;
 
@@ -1003,7 +1043,7 @@ aopPut (asmop * aop, char *s, int offset)
                }
              {
                symbol *lbl = newiTempLabel (NULL);
-               emitcode ("clr", "c; oops");
+               emitcode ("clr", "c");
                emitcode ("jz", "%05d$", lbl->key + 100);
                emitcode ("cpl", "c");
                emitcode ("", "%05d$:", lbl->key + 100);
@@ -1031,7 +1071,7 @@ aopPut (asmop * aop, char *s, int offset)
     default:
       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
              "aopPut got unsupported aop->type");
-      exit (0);
+      exit (1);
     }
 
 }
@@ -1114,6 +1154,8 @@ genNotFloat (operand * op, operand * res)
   char *l;
   symbol *tlbl;
 
+  D(emitcode (";", "genNotFloat"));
+
   /* we will put 127 in the first byte of
      the result */
   aopPut (AOP (res), "#127", 0);
@@ -1242,6 +1284,8 @@ genNot (iCode * ic)
   symbol *tlbl;
   sym_link *optype = operandType (IC_LEFT (ic));
 
+  D(emitcode (";", "genNot"));
+
   /* assign asmOps to operand & result */
   aopOp (IC_LEFT (ic), ic, FALSE);
   aopOp (IC_RESULT (ic), ic, TRUE);
@@ -1286,6 +1330,8 @@ genCpl (iCode * ic)
   int size;
 
 
+  D(emitcode (";", "genCpl"));
+
   /* assign asmOps to operand & result */
   aopOp (IC_LEFT (ic), ic, FALSE);
   aopOp (IC_RESULT (ic), ic, TRUE);
@@ -1326,6 +1372,9 @@ genUminusFloat (operand * op, operand * result)
 {
   int size, offset = 0;
   char *l;
+
+  D(emitcode (";", "genUminusFloat"));
+
   /* for this we just need to flip the
      first it then copy the rest in place */
   size = AOP_SIZE (op) - 1;
@@ -1355,6 +1404,8 @@ genUminus (iCode * ic)
   sym_link *optype, *rtype;
 
 
+  D(emitcode (";", "genUminus"));
+
   /* assign asmops */
   aopOp (IC_LEFT (ic), ic, FALSE);
   aopOp (IC_RESULT (ic), ic, TRUE);
@@ -1430,7 +1481,6 @@ saveRegisters (iCode * lic)
   int i;
   iCode *ic;
   bitVect *rsave;
-  sym_link *detype;
 
   /* look for call */
   for (ic = lic; ic; ic = ic->next)
@@ -1445,14 +1495,14 @@ saveRegisters (iCode * lic)
 
   /* if the registers have been saved already or don't need to be then
      do nothing */
-  if (ic->regsSaved || (OP_SYMBOL (IC_LEFT (ic))->calleeSave) ||
-      SPEC_NAKED(OP_SYM_ETYPE(IC_LEFT (ic))))
+  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);
+  /* safe the registers in use at this time but skip the
+     ones for the result */
+  rsave = bitVectCplAnd (bitVectCopy (ic->rMask), 
+                        mcs51_rUmaskForOp (IC_RESULT(ic)));
 
   ic->regsSaved = 1;
   if (options.useXstack)
@@ -1482,10 +1532,8 @@ saveRegisters (iCode * lic)
        if (bitVectBitValue (rsave, i))
          emitcode ("push", "%s", mcs51_regWithIdx (i)->dname);
       }
-
-  detype = getSpec (operandType (IC_LEFT (ic)));
-
 }
+
 /*-----------------------------------------------------------------*/
 /* unsaveRegisters - pop the pushed registers                      */
 /*-----------------------------------------------------------------*/
@@ -1494,10 +1542,11 @@ 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);
+
+  /* restore the registers in use at this time but skip the
+     ones for the result */
+  rsave = bitVectCplAnd (bitVectCopy (ic->rMask), 
+                        mcs51_rUmaskForOp (IC_RESULT(ic)));
 
   if (options.useXstack)
     {
@@ -1577,6 +1626,8 @@ genXpush (iCode * ic)
   regs *r;
   int size, offset = 0;
 
+  D(emitcode (";", "genXpush"));
+
   aopOp (IC_LEFT (ic), ic, FALSE);
   r = getFreePtr (ic, &aop, FALSE);
 
@@ -1611,6 +1662,8 @@ genIpush (iCode * ic)
   int size, offset = 0;
   char *l;
 
+  D(emitcode (";", "genIpush"));
+
   /* if this is not a parm push : ie. it is spill push
      and spill push is always done on the local stack */
   if (!ic->parmPush)
@@ -1681,6 +1734,7 @@ genIpop (iCode * ic)
 {
   int size, offset;
 
+  D(emitcode (";", "genIpop"));
 
   /* if the temp was not pushed then */
   if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
@@ -1835,10 +1889,12 @@ saveRBank (int bank, iCode * ic, bool pushPsw)
 static void
 genCall (iCode * ic)
 {
-  sym_link *detype;
+  sym_link *dtype;
   bool restoreBank = FALSE;
   bool swapBanks = FALSE;
 
+  D(emitcode(";", "genCall"));
+
   /* if send set is not empty the assign */
   if (_G.sendSet)
     {
@@ -1868,17 +1924,17 @@ genCall (iCode * ic)
   /* if we are calling a not _naked function that is not using
      the same register bank then we need to save the
      destination registers on the stack */
-  detype = getSpec (operandType (IC_LEFT (ic)));
-  if (detype && !SPEC_NAKED(detype) &&
-      (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
-      IS_ISR (currFunc->etype))
+  dtype = operandType (IC_LEFT (ic));
+  if (dtype && !IFFUNC_ISNAKED(dtype) &&
+      (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) &&
+      IFFUNC_ISISR (currFunc->type))
   {
       if (!ic->bankSaved) 
       {
            /* This is unexpected; the bank should have been saved in
             * genFunction.
             */
-          saveRBank (SPEC_BANK (detype), ic, FALSE);
+          saveRBank (FUNC_REGBANK (dtype), ic, FALSE);
           restoreBank = TRUE;
       }
       swapBanks = TRUE;  
@@ -1891,7 +1947,7 @@ genCall (iCode * ic)
   if (swapBanks)
   {
         emitcode ("mov", "psw,#0x%02x", 
-           ((SPEC_BANK(detype)) << 3) & 0xff);
+           ((FUNC_REGBANK(dtype)) << 3) & 0xff);
   }
 
   /* make the call */
@@ -1902,12 +1958,13 @@ genCall (iCode * ic)
   if (swapBanks)
   {
        emitcode ("mov", "psw,#0x%02x", 
-          ((SPEC_BANK(currFunc->etype)) << 3) & 0xff);
+          ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff);
   }
 
   /* if we need assign a result value */
   if ((IS_ITEMP (IC_RESULT (ic)) &&
        (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
+       OP_SYMBOL (IC_RESULT (ic))->accuse || 
        OP_SYMBOL (IC_RESULT (ic))->spildir)) ||
       IS_TRUE_SYMOP (IC_RESULT (ic)))
     {
@@ -1938,12 +1995,12 @@ genCall (iCode * ic)
     }
 
   /* if we hade saved some registers then unsave them */
-  if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave))
+  if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
     unsaveRegisters (ic);
 
   /* if register bank was saved then pop them */
   if (restoreBank)
-    unsaveRBank (SPEC_BANK (detype), ic, FALSE);
+    unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1952,9 +2009,11 @@ genCall (iCode * ic)
 static void
 genPcall (iCode * ic)
 {
-  sym_link *detype;
+  sym_link *dtype;
   symbol *rlbl = newiTempLabel (NULL);
+  bool restoreBank=FALSE;
 
+  D(emitcode(";", "genPCall"));
 
   /* if caller saves & we have not saved then */
   if (!ic->regsSaved)
@@ -1963,12 +2022,13 @@ genPcall (iCode * ic)
   /* if we are calling a function that is not using
      the same register bank then we need to save the
      destination registers on the stack */
-  detype = getSpec (operandType (IC_LEFT (ic)));
-  if (detype &&
-      IS_ISR (currFunc->etype) &&
-      (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)))
-    saveRBank (SPEC_BANK (detype), ic, TRUE);
-
+  dtype = operandType (IC_LEFT (ic));
+  if (dtype && !FUNC_ISNAKED(dtype) &&
+      IFFUNC_ISISR (currFunc->type) &&
+      (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype))) {
+    saveRBank (FUNC_REGBANK (dtype), ic, TRUE);
+    restoreBank=TRUE;
+  }
 
   /* push the return address on to the stack */
   emitcode ("mov", "a,#%05d$", (rlbl->key + 100));
@@ -2047,16 +2107,13 @@ genPcall (iCode * ic)
     }
 
   /* if register bank was saved then unsave them */
-  if (detype &&
-      (SPEC_BANK (currFunc->etype) !=
-       SPEC_BANK (detype)))
-    unsaveRBank (SPEC_BANK (detype), ic, TRUE);
+  if (restoreBank)
+    unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE);
 
   /* if we hade saved some registers then
      unsave them */
-  if (ic->regsSaved)
+  if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
     unsaveRegisters (ic);
-
 }
 
 /*-----------------------------------------------------------------*/
@@ -2112,7 +2169,7 @@ static void
 genFunction (iCode * ic)
 {
   symbol *sym;
-  sym_link *fetype;
+  sym_link *ftype;
   bool   switchedPSW = FALSE;
 
   _G.nRegsSaved = 0;
@@ -2122,25 +2179,25 @@ genFunction (iCode * ic)
   emitcode (";", "-----------------------------------------");
 
   emitcode ("", "%s:", sym->rname);
-  fetype = getSpec (operandType (IC_LEFT (ic)));
+  ftype = operandType (IC_LEFT (ic));
 
-  if (SPEC_NAKED(fetype))
+  if (IFFUNC_ISNAKED(ftype))
   {
       emitcode(";", "naked function: no prologue.");
       return;
   }
 
   /* if critical function then turn interrupts off */
-  if (SPEC_CRTCL (fetype))
+  if (IFFUNC_ISCRITICAL (ftype))
     emitcode ("clr", "ea");
 
   /* here we need to generate the equates for the
      register bank if required */
-  if (SPEC_BANK (fetype) != rbank)
+  if (FUNC_REGBANK (ftype) != rbank)
     {
       int i;
 
-      rbank = SPEC_BANK (fetype);
+      rbank = FUNC_REGBANK (ftype);
       for (i = 0; i < mcs51_nRegs; i++)
        {
          if (strcmp (regs8051[i].base, "0") == 0)
@@ -2157,7 +2214,7 @@ genFunction (iCode * ic)
 
   /* if this is an interrupt service routine then
      save acc, b, dpl, dph  */
-  if (IS_ISR (sym->etype))
+  if (IFFUNC_ISISR (sym->type))
     {
 
       if (!inExcludeList ("acc"))
@@ -2171,13 +2228,13 @@ genFunction (iCode * ic)
       /* if this isr has no bank i.e. is going to
          run with bank 0 , then we need to save more
          registers :-) */
-      if (!SPEC_BANK (sym->etype))
+      if (!FUNC_REGBANK (sym->type))
        {
 
          /* if this function does not call any other
             function then we can be economical and
             save only those registers that are used */
-         if (!sym->hasFcall)
+         if (!IFFUNC_HASFCALL(sym->type))
            {
              int i;
 
@@ -2214,7 +2271,7 @@ genFunction (iCode * ic)
             */
            unsigned long banksToSave = 0;
            
-           if (sym->hasFcall)
+           if (IFFUNC_HASFCALL(sym->type))
            {
 
 #define MAX_REGISTER_BANKS 4
@@ -2232,20 +2289,20 @@ genFunction (iCode * ic)
                    
                    if (i->op == CALL)
                    {
-                       sym_link *detype;
+                       sym_link *dtype;
                        
-                       detype = getSpec(operandType (IC_LEFT(i)));
-                       if (detype 
-                        && SPEC_BANK(detype) != SPEC_BANK(sym->etype))
+                       dtype = operandType (IC_LEFT(i));
+                       if (dtype
+                        && FUNC_REGBANK(dtype) != FUNC_REGBANK(sym->type))
                        {
                             /* Mark this bank for saving. */
-                            if (SPEC_BANK(detype) >= MAX_REGISTER_BANKS)
+                            if (FUNC_REGBANK(dtype) >= MAX_REGISTER_BANKS)
                             {
-                                werror(E_NO_SUCH_BANK, SPEC_BANK(detype));
+                                werror(E_NO_SUCH_BANK, FUNC_REGBANK(dtype));
                             }
                             else
                             {
-                                banksToSave |= (1 << SPEC_BANK(detype));
+                                banksToSave |= (1 << FUNC_REGBANK(dtype));
                             }
                             
                             /* And note that we don't need to do it in 
@@ -2277,7 +2334,7 @@ genFunction (iCode * ic)
                     */
                    emitcode ("push", "psw");
                    emitcode ("mov", "psw,#0x%02x", 
-                             (SPEC_BANK (sym->etype) << 3) & 0x00ff);
+                             (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
                    switchedPSW = TRUE;
                }
                
@@ -2289,6 +2346,7 @@ genFunction (iCode * ic)
                     }
                }
            }
+           // jwk: this needs a closer look
            SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave;
        }
     }
@@ -2296,7 +2354,7 @@ genFunction (iCode * ic)
     {
       /* if callee-save to be used for this function
          then save the registers being used in this function */
-      if (sym->calleeSave)
+      if (IFFUNC_CALLEESAVES(sym->type))
        {
          int i;
 
@@ -2318,14 +2376,14 @@ genFunction (iCode * ic)
     }
 
   /* set the register bank to the desired value */
-  if ((SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
+  if ((FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type))
    && !switchedPSW)
     {
       emitcode ("push", "psw");
-      emitcode ("mov", "psw,#0x%02x", (SPEC_BANK (sym->etype) << 3) & 0x00ff);
+      emitcode ("mov", "psw,#0x%02x", (FUNC_REGBANK (sym->type) << 3) & 0x00ff);
     }
 
-  if (IS_RENT (sym->etype) || options.stackAuto)
+  if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
     {
 
       if (options.useXstack)
@@ -2382,13 +2440,13 @@ genEndFunction (iCode * ic)
 {
   symbol *sym = OP_SYMBOL (IC_LEFT (ic));
 
-  if (SPEC_NAKED(sym->etype))
+  if (IFFUNC_ISNAKED(sym->type))
   {
       emitcode(";", "naked function: no epilogue.");
       return;
   }
 
-  if (IS_RENT (sym->etype) || options.stackAuto)
+  if (IFFUNC_ISREENT (sym->type) || options.stackAuto)
     {
       emitcode ("mov", "%s,_bp", spname);
     }
@@ -2404,7 +2462,7 @@ genEndFunction (iCode * ic)
     }
 
 
-  if ((IS_RENT (sym->etype) || options.stackAuto))
+  if ((IFFUNC_ISREENT (sym->type) || options.stackAuto))
     {
       if (options.useXstack)
        {
@@ -2420,9 +2478,9 @@ genEndFunction (iCode * ic)
     }
 
   /* restore the register bank  */
-  if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
+  if (FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type))
   {
-    if (!SPEC_BANK (sym->etype) || !IS_ISR (sym->etype)
+    if (!FUNC_REGBANK (sym->type) || !IFFUNC_ISISR (sym->type)
      || !options.useXstack)
     {
         /* Special case of ISR using non-zero bank with useXstack
@@ -2432,19 +2490,19 @@ genEndFunction (iCode * ic)
     }
   }
 
-  if (IS_ISR (sym->etype))
+  if (IFFUNC_ISISR (sym->type))
     {
 
       /* now we need to restore the registers */
       /* if this isr has no bank i.e. is going to
          run with bank 0 , then we need to save more
          registers :-) */
-      if (!SPEC_BANK (sym->etype))
+      if (!FUNC_REGBANK (sym->type))
        {
          /* if this function does not call any other
             function then we can be economical and
             save only those registers that are used */
-         if (!sym->hasFcall)
+         if (!IFFUNC_HASFCALL(sym->type))
            {
              int i;
 
@@ -2476,6 +2534,7 @@ genEndFunction (iCode * ic)
             * Restore any register banks saved by genFunction
             * in reverse order.
             */
+         // jwk: this needs a closer look
            unsigned savedBanks = SPEC_ISR_SAVED_BANKS(currFunc->etype);
            int ix;
          
@@ -2505,7 +2564,7 @@ genEndFunction (iCode * ic)
       if (!inExcludeList ("acc"))
        emitcode ("pop", "acc");
 
-      if (SPEC_CRTCL (sym->etype))
+      if (IFFUNC_ISCRITICAL (sym->type))
        emitcode ("setb", "ea");
 
       /* if debug then send end of function */
@@ -2527,10 +2586,10 @@ genEndFunction (iCode * ic)
     }
   else
     {
-      if (SPEC_CRTCL (sym->etype))
+      if (IFFUNC_ISCRITICAL (sym->type))
        emitcode ("setb", "ea");
 
-      if (sym->calleeSave)
+      if (IFFUNC_CALLEESAVES(sym->type))
        {
          int i;
 
@@ -2575,6 +2634,8 @@ genRet (iCode * ic)
 {
   int size, offset = 0, pushed = 0;
 
+  D(emitcode (";", "genRet"));
+
   /* if we have no return value then
      just generate the "ret" */
   if (!IC_LEFT (ic))
@@ -2696,6 +2757,8 @@ genPlusIncr (iCode * ic)
   if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
     return FALSE;
 
+  D(emitcode (";", "genPlusIncr"));
+
   /* if increment 16 bits in register */
   if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
       (size > 1) &&
@@ -2831,6 +2894,8 @@ outBitAcc (operand * result)
 static void
 genPlusBits (iCode * ic)
 {
+  D(emitcode (";", "genPlusBits"));
+
   if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
     {
       symbol *lbl = newiTempLabel (NULL);
@@ -2934,6 +2999,8 @@ genPlus (iCode * ic)
 
   /* special cases :- */
 
+  D(emitcode (";", "genPlus"));
+
   aopOp (IC_LEFT (ic), ic, FALSE);
   aopOp (IC_RIGHT (ic), ic, FALSE);
   aopOp (IC_RESULT (ic), ic, TRUE);
@@ -3044,6 +3111,8 @@ genMinusDec (iCode * ic)
   if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
     return FALSE;
 
+  D(emitcode (";", "genMinusDec"));
+
   /* if decrement 16 bits in register */
   if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
       (size > 1) &&
@@ -3171,6 +3240,9 @@ static void
 genMinusBits (iCode * ic)
 {
   symbol *lbl = newiTempLabel (NULL);
+
+  D(emitcode (";", "genMinusBits"));
+
   if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
     {
       emitcode ("mov", "c,%s", AOP (IC_LEFT (ic))->aopu.aop_dir);
@@ -3200,6 +3272,8 @@ genMinus (iCode * ic)
   int size, offset = 0;
   unsigned long lit = 0L;
 
+  D(emitcode (";", "genMinus"));
+
   aopOp (IC_LEFT (ic), ic, FALSE);
   aopOp (IC_RIGHT (ic), ic, FALSE);
   aopOp (IC_RESULT (ic), ic, TRUE);
@@ -3240,12 +3314,17 @@ genMinus (iCode * ic)
       else
        {
          /* first add without previous c */
-         if (!offset)
-           emitcode ("add", "a,#0x%02x",
-                     (unsigned int) (lit & 0x0FFL));
-         else
+         if (!offset) {
+           if (!size && lit==-1) {
+             emitcode ("dec", "a");
+           } else {
+             emitcode ("add", "a,#0x%02x", 
+                       (unsigned int) (lit & 0x0FFL));
+           }
+         } else {
            emitcode ("addc", "a,#0x%02x",
                      (unsigned int) ((lit >> (offset * 8)) & 0x0FFL));
+         }
        }
       aopPut (AOP (IC_RESULT (ic)), "a", offset++);
     }
@@ -3267,6 +3346,8 @@ genMultbits (operand * left,
             operand * right,
             operand * result)
 {
+  D(emitcode (";", "genMultbits"));
+
   emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
   emitcode ("anl", "c,%s", AOP (right)->aopu.aop_dir);
   outBitC (result);
@@ -3285,6 +3366,8 @@ genMultOneByte (operand * left,
   symbol *lbl;
   int size=AOP_SIZE(result);
 
+  D(emitcode (";", "genMultOneByte"));
+
   if (size<1 || size>2) {
     // this should never happen
       fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", 
@@ -3387,6 +3470,8 @@ genMult (iCode * ic)
   operand *right = IC_RIGHT (ic);
   operand *result = IC_RESULT (ic);
 
+  D(emitcode (";", "genMult"));
+
   /* assign the amsops */
   aopOp (left, ic, FALSE);
   aopOp (right, ic, FALSE);
@@ -3402,15 +3487,21 @@ genMult (iCode * ic)
     }
 
   /* if both are of size == 1 */
-  if (AOP_SIZE (left) == 1 &&
-      AOP_SIZE (right) == 1)
+#if 0 // one of them can be a sloc shared with the result
+    if (AOP_SIZE (left) == 1 && AOP_SIZE (right) == 1)
+#else
+  if (getSize(operandType(left)) == 1 && 
+      getSize(operandType(right)) == 1)
+#endif
     {
       genMultOneByte (left, right, result);
       goto release;
     }
 
   /* should have been converted to function call */
-  assert (1);
+    fprintf (stderr, "left: %d right: %d\n", getSize(OP_SYMBOL(left)->type),
+            getSize(OP_SYMBOL(right)->type));
+  assert (0);
 
 release:
   freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
@@ -3429,6 +3520,8 @@ genDivbits (operand * left,
 
   char *l;
 
+  D(emitcode (";", "genDivbits"));
+
   /* the result must be bit */
   emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
   l = aopGet (AOP (left), 0, FALSE, FALSE);
@@ -3453,6 +3546,8 @@ genDivOneByte (operand * left,
   symbol *lbl;
   int size, offset;
 
+  D(emitcode (";", "genDivOneByte"));
+
   size = AOP_SIZE (result) - 1;
   offset = 1;
   /* signed or unsigned */
@@ -3536,6 +3631,8 @@ genDiv (iCode * ic)
   operand *right = IC_RIGHT (ic);
   operand *result = IC_RESULT (ic);
 
+  D(emitcode (";", "genDiv"));
+
   /* assign the amsops */
   aopOp (left, ic, FALSE);
   aopOp (right, ic, FALSE);
@@ -3559,7 +3656,7 @@ genDiv (iCode * ic)
     }
 
   /* should have been converted to function call */
-  assert (1);
+  assert (0);
 release:
   freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
   freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
@@ -3577,6 +3674,8 @@ genModbits (operand * left,
 
   char *l;
 
+  D(emitcode (";", "genModbits"));
+
   /* the result must be bit */
   emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
   l = aopGet (AOP (left), 0, FALSE, FALSE);
@@ -3601,6 +3700,8 @@ genModOneByte (operand * left,
   char *l;
   symbol *lbl;
 
+  D(emitcode (";", "genModOneByte"));
+
   /* signed or unsigned */
   if (SPEC_USIGN (opetype))
     {
@@ -3674,6 +3775,8 @@ genMod (iCode * ic)
   operand *right = IC_RIGHT (ic);
   operand *result = IC_RESULT (ic);
 
+  D(emitcode (";", "genMod"));
+
   /* assign the amsops */
   aopOp (left, ic, FALSE);
   aopOp (right, ic, FALSE);
@@ -3697,7 +3800,7 @@ genMod (iCode * ic)
     }
 
   /* should have been converted to function call */
-  assert (1);
+  assert (0);
 
 release:
   freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
@@ -3715,6 +3818,8 @@ genIfxJump (iCode * ic, char *jval)
   symbol *tlbl = newiTempLabel (NULL);
   char *inst;
 
+  D(emitcode (";", "genIfxJump"));
+
   /* if true label then we jump if condition
      supplied is true */
   if (IC_TRUE (ic))
@@ -3751,6 +3856,8 @@ genCmp (operand * left, operand * right,
   int size, offset = 0;
   unsigned long lit = 0L;
 
+  D(emitcode (";", "genCmp"));
+
   /* if left & right are bit variables */
   if (AOP_TYPE (left) == AOP_CRY &&
       AOP_TYPE (right) == AOP_CRY)
@@ -3859,6 +3966,8 @@ genCmpGt (iCode * ic, iCode * ifx)
   sym_link *letype, *retype;
   int sign;
 
+  D(emitcode (";", "genCmpGt"));
+
   left = IC_LEFT (ic);
   right = IC_RIGHT (ic);
   result = IC_RESULT (ic);
@@ -3886,6 +3995,8 @@ genCmpLt (iCode * ic, iCode * ifx)
   sym_link *letype, *retype;
   int sign;
 
+  D(emitcode (";", "genCmpLt"));
+
   left = IC_LEFT (ic);
   right = IC_RIGHT (ic);
   result = IC_RESULT (ic);
@@ -4001,6 +4112,8 @@ genCmpEq (iCode * ic, iCode * ifx)
 {
   operand *left, *right, *result;
 
+  D(emitcode (";", "genCmpEq"));
+
   aopOp ((left = IC_LEFT (ic)), ic, FALSE);
   aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
@@ -4191,6 +4304,9 @@ hasInc (operand *op, iCode *ic)
   iCode *lic = ic->next;
   int isize ;
   
+  /* this could from a cast, e.g.: "(char xdata *) 0x7654;" */
+  if (!IS_SYMOP(op)) return NULL;
+
   if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
   isize = getSize(type->next);
   while (lic) {
@@ -4202,9 +4318,11 @@ hasInc (operand *op, iCode *ic)
       return lic;
     }
     /* if the operand used or deffed */
-    if (bitVectBitValue(ic->uses,op->key) || (unsigned) ic->defKey == op->key) {
+    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;
@@ -4219,6 +4337,8 @@ genAndOp (iCode * ic)
   operand *left, *right, *result;
   symbol *tlbl;
 
+  D(emitcode (";", "genAndOp"));
+
   /* note here that && operations that are in an
      if statement are taken away by backPatchLabels
      only those used in arthmetic operations remain */
@@ -4259,6 +4379,8 @@ genOrOp (iCode * ic)
   operand *left, *right, *result;
   symbol *tlbl;
 
+  D(emitcode (";", "genOrOp"));
+
   /* note here that || operations that are in an
      if statement are taken away by backPatchLabels
      only those used in arthmetic operations remain */
@@ -4368,6 +4490,8 @@ genAnd (iCode * ic, iCode * ifx)
   int bytelit = 0;
   char buffer[10];
 
+  D(emitcode (";", "genAnd"));
+
   aopOp ((left = IC_LEFT (ic)), ic, FALSE);
   aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
@@ -4670,6 +4794,8 @@ genOr (iCode * ic, iCode * ifx)
   int size, offset = 0;
   unsigned long lit = 0L;
 
+  D(emitcode (";", "genOr"));
+
   aopOp ((left = IC_LEFT (ic)), ic, FALSE);
   aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
@@ -4937,6 +5063,8 @@ genXor (iCode * ic, iCode * ifx)
   int size, offset = 0;
   unsigned long lit = 0L;
 
+  D(emitcode (";", "genXor"));
+
   aopOp ((left = IC_LEFT (ic)), ic, FALSE);
   aopOp ((right = IC_RIGHT (ic)), ic, FALSE);
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
@@ -5193,6 +5321,8 @@ genInline (iCode * ic)
 {
   char *buffer, *bp, *bp1;
 
+  D(emitcode (";", "genInline"));
+
   _G.inLine += (!options.asmpeep);
 
   buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
@@ -5237,6 +5367,8 @@ genRRC (iCode * ic)
   int size, offset = 0;
   char *l;
 
+  D(emitcode (";", "genRRC"));
+
   /* rotate right with carry */
   left = IC_LEFT (ic);
   result = IC_RESULT (ic);
@@ -5246,6 +5378,12 @@ genRRC (iCode * ic)
   /* move it to the result */
   size = AOP_SIZE (result);
   offset = size - 1;
+  if (size == 1) { /* special case for 1 byte */
+      l = aopGet (AOP (left), offset, FALSE, FALSE);
+      MOVA (l);
+      emitcode ("rr", "a");
+      goto release;
+  }
   CLRC;
   while (size--)
     {
@@ -5263,6 +5401,7 @@ genRRC (iCode * ic)
       MOVA (l);
     }
   emitcode ("mov", "acc.7,c");
+ release:
   aopPut (AOP (result), "a", AOP_SIZE (result) - 1);
   freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
@@ -5278,6 +5417,8 @@ genRLC (iCode * ic)
   int size, offset = 0;
   char *l;
 
+  D(emitcode (";", "genRLC"));
+
   /* rotate right with carry */
   left = IC_LEFT (ic);
   result = IC_RESULT (ic);
@@ -5291,6 +5432,10 @@ genRLC (iCode * ic)
     {
       l = aopGet (AOP (left), offset, FALSE, FALSE);
       MOVA (l);
+      if (size == 0) { /* special case for 1 byte */
+             emitcode("rl","a");
+             goto release;
+      }
       emitcode ("add", "a,acc");
       if (AOP_SIZE (result) > 1)
        aopPut (AOP (result), "a", offset++);
@@ -5311,6 +5456,7 @@ genRLC (iCode * ic)
       MOVA (l);
     }
   emitcode ("mov", "acc.0,c");
+ release:
   aopPut (AOP (result), "a", 0);
   freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
@@ -5323,6 +5469,9 @@ static void
 genGetHbit (iCode * ic)
 {
   operand *left, *result;
+
+  D(emitcode (";", "genGetHbit"));
+
   left = IC_LEFT (ic);
   result = IC_RESULT (ic);
   aopOp (left, ic, FALSE);
@@ -5927,6 +6076,8 @@ shiftRLeftOrResult (operand * left, int offl,
 static void
 genlshOne (operand * result, operand * left, int shCount)
 {
+  D(emitcode (";", "genlshOne"));
+
   shiftL1Left2Result (left, LSB, result, LSB, shCount);
 }
 
@@ -5938,6 +6089,8 @@ genlshTwo (operand * result, operand * left, int shCount)
 {
   int size;
 
+  D(emitcode (";", "genlshTwo"));
+
   size = getDataSize (result);
 
   /* if shCount >= 8 */
@@ -6042,6 +6195,8 @@ genlshFour (operand * result, operand * left, int shCount)
 {
   int size;
 
+  D(emitcode (";", "genlshFour"));
+
   size = AOP_SIZE (result);
 
   /* if shifting more that 3 bytes */
@@ -6139,6 +6294,8 @@ genLeftShiftLiteral (operand * left,
   int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
   int size;
 
+  D(emitcode (";", "genLeftShiftLiteral"));
+
   freeAsmop (right, NULL, ic, TRUE);
 
   aopOp (left, ic, FALSE);
@@ -6198,6 +6355,8 @@ genLeftShift (iCode * ic)
   char *l;
   symbol *tlbl, *tlbl1;
 
+  D(emitcode (";", "genLeftShift"));
+
   right = IC_RIGHT (ic);
   left = IC_LEFT (ic);
   result = IC_RESULT (ic);
@@ -6299,6 +6458,8 @@ static void
 genrshOne (operand * result, operand * left,
           int shCount, int sign)
 {
+  D(emitcode (";", "genrshOne"));
+
   shiftR1Left2Result (left, LSB, result, LSB, shCount, sign);
 }
 
@@ -6309,6 +6470,8 @@ static void
 genrshTwo (operand * result, operand * left,
           int shCount, int sign)
 {
+  D(emitcode (";", "genrshTwo"));
+
   /* if shCount >= 8 */
   if (shCount >= 8)
     {
@@ -6394,6 +6557,8 @@ static void
 genrshFour (operand * result, operand * left,
            int shCount, int sign)
 {
+  D(emitcode (";", "genrshFour"));
+
   /* if shifting more that 3 bytes */
   if (shCount >= 24)
     {
@@ -6467,6 +6632,8 @@ genRightShiftLiteral (operand * left,
   int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
   int size;
 
+  D(emitcode (";", "genRightShiftLiteral"));
+
   freeAsmop (right, NULL, ic, TRUE);
 
   aopOp (left, ic, FALSE);
@@ -6530,6 +6697,8 @@ genSignedRightShift (iCode * ic)
   char *l;
   symbol *tlbl, *tlbl1;
 
+  D(emitcode (";", "genSignedRightShift"));
+
   /* we do it the hard way put the shift count in b
      and loop thru preserving the sign */
 
@@ -6636,6 +6805,8 @@ genRightShift (iCode * ic)
   char *l;
   symbol *tlbl, *tlbl1;
 
+  D(emitcode (";", "genRightShift"));
+
   /* if signed then we do it the hard way preserve the
      sign bit moving it inwards */
   retype = getSpec (operandType (IC_RESULT (ic)));
@@ -6755,6 +6926,8 @@ genUnpackBits (operand * result, char *rname, int ptype)
   int offset = 0;
   int rsize;
 
+  D(emitcode (";", "genUnpackBits"));
+
   etype = getSpec (operandType (result));
   rsize = getSize (operandType (result));
   /* read the first byte  */
@@ -6776,7 +6949,7 @@ genUnpackBits (operand * result, char *rname, int ptype)
 
     case CPOINTER:
       emitcode ("clr", "a");
-      emitcode ("movc", "a,%s", "@a+dptr");
+      emitcode ("movc", "a,@a+dptr");
       break;
 
     case GPOINTER:
@@ -6829,7 +7002,7 @@ genUnpackBits (operand * result, char *rname, int ptype)
        case CPOINTER:
          emitcode ("clr", "a");
          emitcode ("inc", "dptr");
-         emitcode ("movc", "a", "@a+dptr");
+         emitcode ("movc", "a,@a+dptr");
          break;
 
        case GPOINTER:
@@ -6876,6 +7049,9 @@ genDataPointerGet (operand * left,
   char *l;
   char buffer[256];
   int size, offset = 0;
+
+  D(emitcode (";", "genDataPointerGet"));
+
   aopOp (result, ic, TRUE);
 
   /* get the string representation of the name */
@@ -6910,6 +7086,8 @@ genNearPointerGet (operand * left,
   sym_link *ltype = operandType (left);
   char buffer[80];
 
+  D(emitcode (";", "genNearPointerGet"));
+
   rtype = operandType (result);
   retype = getSpec (rtype);
 
@@ -6941,8 +7119,9 @@ genNearPointerGet (operand * left,
     }
   else
     rname = aopGet (AOP (left), 0, FALSE, FALSE);
-
-  aopOp (result, ic, FALSE);
+  
+  //aopOp (result, ic, FALSE);
+  aopOp (result, ic, result?TRUE:FALSE);
 
   /* if bitfield then unpack the bits */
   if (IS_BITVAR (retype))
@@ -7019,6 +7198,8 @@ genPagedPointerGet (operand * left,
   char *rname;
   sym_link *rtype, *retype;
 
+  D(emitcode (";", "genPagedPointerGet"));
+
   rtype = operandType (result);
   retype = getSpec (rtype);
 
@@ -7105,6 +7286,8 @@ genFarPointerGet (operand * left,
   int size, offset;
   sym_link *retype = getSpec (operandType (result));
 
+  D(emitcode (";", "genFarPointerGet"));
+
   aopOp (left, ic, FALSE);
 
   /* if the operand is already in dptr
@@ -7159,6 +7342,8 @@ genCodePointerGet (operand * left,
   int size, offset;
   sym_link *retype = getSpec (operandType (result));
 
+  D(emitcode (";", "genCodePointerGet"));
+
   aopOp (left, ic, FALSE);
 
   /* if the operand is already in dptr
@@ -7214,6 +7399,8 @@ genGenPointerGet (operand * left,
   int size, offset;
   sym_link *retype = getSpec (operandType (result));
 
+  D(emitcode (";", "genGenPointerGet"));
+
   aopOp (left, ic, FALSE);
 
   /* if the operand is already in dptr
@@ -7224,7 +7411,10 @@ genGenPointerGet (operand * left,
       if (AOP_TYPE (left) == AOP_IMMD)
        {
          emitcode ("mov", "dptr,%s", aopGet (AOP (left), 0, TRUE, FALSE));
-         emitcode ("mov", "b,#%d", pointerCode (retype));
+         if (AOP(left)->aopu.aop_immd.from_cast_remat) 
+                 emitcode ("mov", "b,%s",aopGet(AOP (left), AOP_SIZE(left)-1, FALSE, FALSE));
+         else
+                 emitcode ("mov", "b,#%d", pointerCode (retype));
        }
       else
        {                       /* we need to get it byte by byte */
@@ -7256,6 +7446,7 @@ genGenPointerGet (operand * left,
   if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) {
     aopPut ( AOP (left), "dpl", 0);
     aopPut ( AOP (left), "dph", 1);
+    aopPut ( AOP (left), "b", 2);
     pi->generated = 1;
   }
   freeAsmop (left, NULL, ic, TRUE);
@@ -7272,6 +7463,8 @@ genPointerGet (iCode * ic, iCode *pi)
   sym_link *type, *etype;
   int p_type;
 
+  D(emitcode (";", "genPointerGet"));
+
   left = IC_LEFT (ic);
   result = IC_RESULT (ic);
 
@@ -7288,6 +7481,13 @@ genPointerGet (iCode * ic, iCode *pi)
       p_type = PTR_TYPE (SPEC_OCLS (etype));
     }
 
+  /* special case when cast remat */
+  if (p_type == GPOINTER && OP_SYMBOL(left)->remat &&
+      IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) {
+         left = IC_RIGHT(OP_SYMBOL(left)->rematiCode);
+         type =   type = operandType (left);
+         p_type = DCL_TYPE (type);
+  }
   /* now that we have the pointer type we assign
      the pointer values */
   switch (p_type)
@@ -7331,6 +7531,8 @@ genPackBits (sym_link * etype,
   int blen, bstr;
   char *l;
 
+  D(emitcode (";", "genPackBits"));
+
   blen = SPEC_BLEN (etype);
   bstr = SPEC_BSTR (etype);
 
@@ -7496,6 +7698,8 @@ genDataPointerSet (operand * right,
   int size, offset = 0;
   char *l, buffer[256];
 
+  D(emitcode (";", "genDataPointerSet"));
+
   aopOp (right, ic, FALSE);
 
   l = aopGet (AOP (result), 0, FALSE, TRUE);
@@ -7529,6 +7733,8 @@ genNearPointerSet (operand * right,
   sym_link *retype, *letype;
   sym_link *ptype = operandType (result);
 
+  D(emitcode (";", "genNearPointerSet"));
+
   retype = getSpec (operandType (right));
   letype = getSpec (ptype);
   aopOp (result, ic, FALSE);
@@ -7543,24 +7749,47 @@ genNearPointerSet (operand * right,
       genDataPointerSet (right, result, ic);
       return;
     }
-
+  
   /* if the value is already in a pointer register
      then don't need anything more */
   if (!AOP_INPREG (AOP (result)))
     {
-      /* otherwise get a free pointer register */
-      aop = newAsmop (0);
-      preg = getFreePtr (ic, &aop, FALSE);
-      emitcode ("mov", "%s,%s",
-               preg->name,
-               aopGet (AOP (result), 0, FALSE, TRUE));
-      rname = preg->name;
+       if (
+           //AOP_TYPE (result) == AOP_STK
+           IS_AOP_PREG(result)
+           )
+       {
+           // Aha, it is a pointer, just in disguise.
+           rname = aopGet (AOP (result), 0, FALSE, FALSE);
+           if (*rname != '@')
+           {
+               fprintf(stderr, "probable internal error: unexpected rname @ %s:%d\n",
+                       __FILE__, __LINE__);
+           }
+           else
+           {
+               // Expected case.
+               rname++;  // skip the '@'.
+           }
+       }
+       else
+       {
+           /* otherwise get a free pointer register */
+           aop = newAsmop (0);
+           preg = getFreePtr (ic, &aop, FALSE);
+           emitcode ("mov", "%s,%s",
+                     preg->name,
+                     aopGet (AOP (result), 0, FALSE, TRUE));
+           rname = preg->name;
+       }
+    }
+    else
+    {
+       rname = aopGet (AOP (result), 0, FALSE, FALSE);
     }
-  else
-    rname = aopGet (AOP (result), 0, FALSE, FALSE);
 
   aopOp (right, ic, FALSE);
-
+    
   /* if bitfield then unpack the bits */
   if (IS_BITVAR (retype) || IS_BITVAR (letype))
     genPackBits ((IS_BITVAR (retype) ? retype : letype), right, rname, POINTER);
@@ -7631,6 +7860,8 @@ genPagedPointerSet (operand * right,
   char *rname, *l;
   sym_link *retype, *letype;
 
+  D(emitcode (";", "genPagedPointerSet"));
+
   retype = getSpec (operandType (right));
   letype = getSpec (operandType (result));
 
@@ -7718,6 +7949,9 @@ genFarPointerSet (operand * right,
   int size, offset;
   sym_link *retype = getSpec (operandType (right));
   sym_link *letype = getSpec (operandType (result));
+
+  D(emitcode (";", "genFarPointerSet"));
+
   aopOp (result, ic, FALSE);
 
   /* if the operand is already in dptr
@@ -7773,6 +8007,8 @@ genGenPointerSet (operand * right,
   sym_link *retype = getSpec (operandType (right));
   sym_link *letype = getSpec (operandType (result));
 
+  D(emitcode (";", "genGenPointerSet"));
+
   aopOp (result, ic, FALSE);
 
   /* if the operand is already in dptr
@@ -7783,7 +8019,10 @@ genGenPointerSet (operand * right,
       if (AOP_TYPE (result) == AOP_IMMD)
        {
          emitcode ("mov", "dptr,%s", aopGet (AOP (result), 0, TRUE, FALSE));
-         emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE));
+         if (AOP(result)->aopu.aop_immd.from_cast_remat) 
+                 emitcode ("mov", "b,%s",aopGet(AOP (result), AOP_SIZE(result)-1, FALSE, FALSE));
+         else 
+                 emitcode ("mov", "b,%s + 1", aopGet (AOP (result), 0, TRUE, FALSE));
        }
       else
        {                       /* we need to get it byte by byte */
@@ -7816,6 +8055,7 @@ genGenPointerSet (operand * right,
   if (pi && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD) {
     aopPut (AOP(result),"dpl",0);
     aopPut (AOP(result),"dph",1);
+    aopPut (AOP(result),"b",2);
     pi->generated=1;
   }
   freeAsmop (result, NULL, ic, TRUE);
@@ -7832,6 +8072,8 @@ genPointerSet (iCode * ic, iCode *pi)
   sym_link *type, *etype;
   int p_type;
 
+  D(emitcode (";", "genPointerSet"));
+
   right = IC_RIGHT (ic);
   result = IC_RESULT (ic);
 
@@ -7850,6 +8092,13 @@ genPointerSet (iCode * ic, iCode *pi)
       p_type = PTR_TYPE (SPEC_OCLS (etype));
     }
 
+  /* special case when cast remat */
+  if (p_type == GPOINTER && OP_SYMBOL(result)->remat &&
+      IS_CAST_ICODE(OP_SYMBOL(result)->rematiCode)) {
+         result = IC_RIGHT(OP_SYMBOL(result)->rematiCode);
+         type =   type = operandType (result);
+         p_type = DCL_TYPE (type);
+  }
   /* now that we have the pointer type we assign
      the pointer values */
   switch (p_type)
@@ -7884,6 +8133,8 @@ genIfx (iCode * ic, iCode * popIc)
   operand *cond = IC_COND (ic);
   int isbit = 0;
 
+  D(emitcode (";", "genIfx"));
+
   aopOp (cond, ic, FALSE);
 
   /* get the value into acc */
@@ -7919,6 +8170,8 @@ genAddrOf (iCode * ic)
   symbol *sym = OP_SYMBOL (IC_LEFT (ic));
   int size, offset;
 
+  D(emitcode (";", "genAddrOf"));
+
   aopOp (IC_RESULT (ic), ic, FALSE);
 
   /* if the operand is on the stack then we
@@ -7931,7 +8184,9 @@ genAddrOf (iCode * ic)
       if (sym->stack)
        {
          emitcode ("mov", "a,_bp");
-         emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+         emitcode ("add", "a,#0x%02x", ((sym->stack < 0) ?
+                                        ((char) (sym->stack - _G.nRegsSaved)) :
+                                        ((char) sym->stack)) & 0xff);
          aopPut (AOP (IC_RESULT (ic)), "a", 0);
        }
       else
@@ -7981,6 +8236,9 @@ genFarFarAssign (operand * result, operand * right, iCode * ic)
   int size = AOP_SIZE (right);
   int offset = 0;
   char *l;
+
+  D(emitcode (";", "genFarFarAssign"));
+
   /* first push the right side on to the stack */
   while (size--)
     {
@@ -8012,6 +8270,8 @@ genAssign (iCode * ic)
   int size, offset;
   unsigned long lit = 0L;
 
+  D(emitcode(";","genAssign"));
+
   result = IC_RESULT (ic);
   right = IC_RIGHT (ic);
 
@@ -8114,6 +8374,8 @@ genJumpTab (iCode * ic)
   symbol *jtab;
   char *l;
 
+  D(emitcode (";", "genJumpTab"));
+
   aopOp (IC_JTCOND (ic), ic, FALSE);
   /* get the condition into accumulator */
   l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE);
@@ -8146,6 +8408,8 @@ genCast (iCode * ic)
   operand *right = IC_RIGHT (ic);
   int size, offset;
 
+  D(emitcode(";", "genCast"));
+
   /* if they are equivalent then do nothing */
   if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
     return;
@@ -8154,7 +8418,8 @@ genCast (iCode * ic)
   aopOp (result, ic, FALSE);
 
   /* if the result is a bit */
-  if (AOP_TYPE (result) == AOP_CRY)
+  // if (AOP_TYPE (result) == AOP_CRY /* works only for true symbols */
+  if (IS_BITVAR(OP_SYMBOL(result)->type))
     {
       /* if the right size is a literal then
          we know what the value is */
@@ -8334,6 +8599,8 @@ genDjnz (iCode * ic, iCode * ifx)
   if (!ifx)
     return 0;
 
+  D(emitcode (";", "genDjnz"));
+
   /* if the if condition has a false label
      then we cannot save */
   if (IC_FALSE (ifx))
@@ -8410,6 +8677,8 @@ genDjnz (iCode * ic, iCode * ifx)
 static void
 genReceive (iCode * ic)
 {
+  D(emitcode (";", "genReceive"));
+
   if (isOperandInFarSpace (IC_RESULT (ic)) &&
       (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
        IS_TRUE_SYMOP (IC_RESULT (ic))))
@@ -8444,6 +8713,66 @@ genReceive (iCode * ic)
   freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
 }
 
+/*-----------------------------------------------------------------*/
+/* gen51AggregateAssign - copy complete array's or structures            */
+/*-----------------------------------------------------------------*/
+void gen51AggregateAssign(iCode *ic) {
+  operand *left=IC_LEFT(ic);
+  operand *right=IC_RIGHT(ic);
+  char *fromName=OP_SYMBOL(right)->rname;
+  char *toName=OP_SYMBOL(left)->rname;
+  int fromSize=getSize(OP_SYMBOL(right)->type);
+  int toSize=getSize(OP_SYMBOL(left)->type);
+  int count=toSize;
+
+  D(emitcode (";", "gen51AggregateAssign"));
+
+  if (SPEC_OCLS(OP_SYMBOL(left)->etype)!=xdata ||
+      SPEC_OCLS(OP_SYMBOL(right)->etype)!=code) {
+    // well, this code isn't used yet from anywhere else as for initialising
+    fprintf (stderr, "*** error: %s:%d can only assign aggregates from cseg to xseg for now\n", ic->filename, ic->lineno);
+    exit (457);
+  }
+
+  if (fromSize!=toSize) {
+    fprintf (stderr, "*** error: %s:%d aggregates have different size\n",
+            ic->filename, ic->lineno);
+    exit (821);
+  }
+
+#if 1
+  // use the generic memcpy() for now
+  emitcode (";", "initialize %s", OP_SYMBOL(IC_LEFT(ic))->name);
+  emitcode ("mov", "dptr,#_memcpy_PARM_2");
+  emitcode ("mov", "a,#%s", fromName);
+  emitcode ("movx", "@dptr,a");
+  emitcode ("inc", "dptr");
+  emitcode ("mov", "a,#(%s>>8)", fromName);
+  emitcode ("movx", "@dptr,a");
+  emitcode ("inc", "dptr");
+  emitcode ("mov", "a,#%02x;   only from cseg for now", 2);
+  emitcode ("movx", "@dptr,a");
+  emitcode ("mov", "dptr,#_memcpy_PARM_3");
+  emitcode ("mov", "a,#(%d>>0);        number of bytes", count);
+  emitcode ("movx", "@dptr,a");
+  emitcode ("inc", "dptr");
+  emitcode ("mov", "a,#(%d>>8)", count);
+  emitcode ("movx", "@dptr,a");
+  emitcode ("mov", "dptr,#%s", toName);
+  emitcode ("mov", "b,#%02x;   only to xseg for now", 1);
+  emitcode ("lcall", "_memcpy");
+#else
+  // more efficient, but will require the native_memcpy_cs2xs
+  emitcode ("mov", "r0,#%s", fromName);
+  emitcode ("mov", "r1,#(%s>>8)", fromName);
+  emitcode ("mov", "r2,#%s", toName);
+  emitcode ("mov", "r3,#(%s>>8)", toName);
+  emitcode ("mov", "r4,#%d", count);
+  emitcode ("mov", "r5,#(%d>>8)", count);
+  emitcode ("lcall", "_native_memcpy_cs2xs");
+#endif
+}
+
 /*-----------------------------------------------------------------*/
 /* gen51Code - generate code for 8051 based controllers            */
 /*-----------------------------------------------------------------*/
@@ -8684,6 +9013,10 @@ gen51Code (iCode * lic)
          addSet (&_G.sendSet, ic);
          break;
 
+       case ARRAYINIT:
+         gen51AggregateAssign(ic);
+         break;
+
        default:
          ic = ic;
        }