* src/hc08/gen.c (genPointerSet, genFarPointerSet): moved code from
[fw/sdcc] / src / hc08 / gen.c
index e9b718cbdf8b937b4c271de126d2016e29beba1c..273a685f0e2a8f247244c9a5d1dc1a7f93cbbda3 100644 (file)
@@ -27,8 +27,8 @@
 
 -------------------------------------------------------------------------*/
 
-//#define D(x)
-#define D(x) x
+#define D(x)
+//#define D(x) x
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -45,6 +45,8 @@
 char *aopLiteral (value * val, int offset);
 char *aopLiteralLong (value * val, int offset, int size);
 extern int allocInfo;
+static int pushReg (regs *reg, bool freereg);
+static void pullReg (regs *reg);
 
 static char *zero = "#0x00";
 static char *one = "#0x01";
@@ -68,6 +70,7 @@ static struct
     int stackPushes;
     short regsinuse;
     set *sendSet;
+    iCode *current_iCode;
   }
 _G;
 
@@ -168,6 +171,7 @@ emitcode (char *inst, char *fmt,...)
                (lineHead = newLineNode (lb)));
   lineCurr->isInline = _G.inLine;
   lineCurr->isDebug = _G.debugLine;
+  lineCurr->ic = _G.current_iCode;
 
   //printf("%s\n", lb);
   va_end (ap);
@@ -185,6 +189,17 @@ emitLabel (symbol *tlbl)
   emitcode ("", "%05d$:", (tlbl->key +100));
 }
 
+/*-----------------------------------------------------------------*/
+/* hc08_emitDebuggerSymbol - associate the current code location   */
+/*   with a debugger symbol                                        */
+/*-----------------------------------------------------------------*/
+void
+hc08_emitDebuggerSymbol (char * debugSym)
+{
+  _G.debugLine = 1;
+  emitcode ("", "%s ==.", debugSym);
+  _G.debugLine = 0;
+}
 
 
 /*--------------------------------------------------------------------------*/
@@ -211,8 +226,8 @@ transferRegReg (regs *sreg, regs *dreg, bool freesrc)
       return;
     }
 
-  emitcode ("", "; transferRegReg(%s,%s)",
-            sreg->name, dreg->name);  
+  D(emitcode ("", "; transferRegReg(%s,%s)",
+            sreg->name, dreg->name));
 
   srcidx = sreg->rIdx;
   dstidx = dreg->rIdx;
@@ -226,8 +241,8 @@ transferRegReg (regs *sreg, regs *dreg, bool freesrc)
         switch (srcidx)
           {
             case H_IDX: /* H to A */
-              emitcode ("pshh", "");
-              emitcode ("pula", "");
+             pushReg (hc08_reg_h, FALSE);
+             pullReg (hc08_reg_a);
               break;
             case X_IDX: /* X to A */
               emitcode ("txa", "");
@@ -240,12 +255,12 @@ transferRegReg (regs *sreg, regs *dreg, bool freesrc)
         switch (srcidx)
           {
             case A_IDX: /* A to H */
-              emitcode ("psha", "");
-              emitcode ("pulh", "");
+             pushReg (hc08_reg_a, FALSE);
+             pullReg (hc08_reg_h);
               break;
             case X_IDX: /* X to H */
-              emitcode ("pshx", "");
-              emitcode ("pulh", "");
+             pushReg (hc08_reg_x, FALSE);
+             pullReg (hc08_reg_h);
               break;
             default:
               error=1;
@@ -258,8 +273,8 @@ transferRegReg (regs *sreg, regs *dreg, bool freesrc)
               emitcode ("tax", "");
               break;
             case H_IDX: /* H to X */
-              emitcode ("pshh", "");
-              emitcode ("pulx", "");
+             pushReg (hc08_reg_h, FALSE);
+             pullReg (hc08_reg_x);
               break;
             default:
               error=1;
@@ -269,8 +284,8 @@ transferRegReg (regs *sreg, regs *dreg, bool freesrc)
         switch (srcidx)
           {
             case XA_IDX: /* XA to HX */
-              emitcode ("pshx", "");
-              emitcode ("pulh", "");
+             pushReg (hc08_reg_x, FALSE);
+             pullReg (hc08_reg_h);
               emitcode ("tax", "");
               break;
             default:
@@ -282,8 +297,8 @@ transferRegReg (regs *sreg, regs *dreg, bool freesrc)
           {
             case HX_IDX: /* HX to XA */
               emitcode ("txa", "");
-              emitcode ("pshh", "");
-              emitcode ("pulx", "");
+             pushReg (hc08_reg_h, FALSE);
+             pullReg (hc08_reg_x);
               break;
             default:
               error=1;
@@ -304,6 +319,21 @@ transferRegReg (regs *sreg, regs *dreg, bool freesrc)
   hc08_useReg(dreg);
 }
 
+/*--------------------------------------------------------------------------*/
+/* updateCFA - update the debugger information to reflect the current       */
+/*             connonical frame address relative to the stack pointer       */
+/*--------------------------------------------------------------------------*/
+static void
+updateCFA(void)
+{
+  /* there is no frame unless there is a function */
+  if (!currFunc)
+    return;
+  
+  debugFile->writeFrameAddress (NULL, hc08_reg_sp,
+                               1 + _G.stackOfs + _G.stackPushes);
+}
+
 /*--------------------------------------------------------------------------*/
 /* pushReg - Push register reg onto the stack. If freereg is true, reg is   */
 /*           marked free and available for reuse.                           */
@@ -318,24 +348,33 @@ pushReg (regs *reg, bool freereg)
       case A_IDX:
         emitcode ("psha", "");
         _G.stackPushes++;
+       updateCFA();
         break;
       case X_IDX:
         emitcode ("pshx", "");
         _G.stackPushes++;
+       updateCFA();
         break;
       case H_IDX:
         emitcode ("pshh", "");
         _G.stackPushes++;
+       updateCFA();
         break;
       case HX_IDX:
         emitcode ("pshx", "");
+        _G.stackPushes++;
+       updateCFA();
         emitcode ("pshh", "");
-        _G.stackPushes += 2;
+        _G.stackPushes++;
+       updateCFA();
         break;
       case XA_IDX:
         emitcode ("psha", "");
+       updateCFA();
+        _G.stackPushes++;
         emitcode ("pshx", "");
-        _G.stackPushes += 2;
+       updateCFA();
+        _G.stackPushes++;
         break;
       default:
         break;
@@ -358,24 +397,33 @@ pullReg (regs *reg)
       case A_IDX:
         emitcode ("pula", "");
         _G.stackPushes--;
+       updateCFA();
         break;
       case X_IDX:
         emitcode ("pulx", "");
         _G.stackPushes--;
+       updateCFA();
         break;
       case H_IDX:
         emitcode ("pulh", "");
         _G.stackPushes--;
+       updateCFA();
         break;
       case HX_IDX:
         emitcode ("pulx", "");
+        _G.stackPushes--;
+       updateCFA();
         emitcode ("pulh", "");
-        _G.stackPushes -= 2;
+        _G.stackPushes--;
+       updateCFA();
         break;
       case XA_IDX:
         emitcode ("pula", "");
+        _G.stackPushes--;
+       updateCFA();
         emitcode ("pulx", "");
-        _G.stackPushes -= 2;
+        _G.stackPushes--;
+       updateCFA();
         break;
       default:
         break;
@@ -394,6 +442,7 @@ pullNull (int n)
     {
       emitcode("ais","#%d",n);
       _G.stackPushes -= n;
+      updateCFA();
     }
 }
 
@@ -432,23 +481,28 @@ pullOrFreeReg (regs *reg, bool needpull)
 static void
 adjustStack (int n)
 {
-  _G.stackPushes -= n;
   while (n)
     {
       if (n>127)
         {
           emitcode ("ais","#127");
           n -= 127;
+         _G.stackPushes -= 127;
+         updateCFA();
         }
       else if (n<-128)
         {
           emitcode ("ais","#-128");
           n += 128;
+         _G.stackPushes += 128;
+         updateCFA();
         }
       else
         {
           emitcode ("ais", "#%d", n);
+         _G.stackPushes -= n;
           n = 0;
+         updateCFA();
         }
     }    
 }
@@ -543,8 +597,8 @@ loadRegFromAop (regs *reg, asmop *aop, int loffset)
     printf(" reg missing operand link\n");
 #endif
 
-  emitcode ("", ";     loadRegFromAop (%s, %s, %d)",
-            reg->name, aopName (aop), loffset);
+  D(emitcode ("", ";     loadRegFromAop (%s, %s, %d)",
+            reg->name, aopName (aop), loffset));
        
   /* If operand is volatile, we cannot optimize. */
   if (!aop->op || isOperandVolatile (aop->op, FALSE))
@@ -558,7 +612,7 @@ loadRegFromAop (regs *reg, asmop *aop, int loffset)
       && (reg->aopofs == loffset))
     {
       hc08_useReg(reg);
-      emitcode ("","; already had correct value for %s", reg->name);
+      D(emitcode ("","; already had correct value for %s", reg->name));
       return;
     }
 
@@ -568,7 +622,7 @@ loadRegFromAop (regs *reg, asmop *aop, int loffset)
       && operandsEqu(hc08_reg_h->aop->op,aop->op)
       && (hc08_reg_h->aopofs == loffset))
     {
-      emitcode ("","; found correct value for %s in h", reg->name);
+      D(emitcode ("","; found correct value for %s in h", reg->name));
       transferRegReg (hc08_reg_h, reg, FALSE);
       hc08_useReg (reg);
       return;
@@ -579,7 +633,7 @@ loadRegFromAop (regs *reg, asmop *aop, int loffset)
       && operandsEqu(hc08_reg_x->aop->op,aop->op)
       && (hc08_reg_x->aopofs == loffset))
     {
-      emitcode ("","; found correct value for %s in x", reg->name);
+      D(emitcode ("","; found correct value for %s in x", reg->name));
       transferRegReg (hc08_reg_x, reg, FALSE);
       hc08_useReg (reg);
       return;
@@ -589,7 +643,7 @@ loadRegFromAop (regs *reg, asmop *aop, int loffset)
       && operandsEqu(hc08_reg_a->aop->op,aop->op)
       && (hc08_reg_a->aopofs == loffset))
     {
-      emitcode ("","; found correct value for %s in a", reg->name);
+      D(emitcode ("","; found correct value for %s in a", reg->name));
       transferRegReg (hc08_reg_a, reg, FALSE);
       hc08_useReg (reg);
       return;
@@ -702,7 +756,7 @@ forceStackedAop (asmop *aop)
   asmop *newaop = newAsmop (aop->type);
   memcpy (newaop, aop, sizeof(*newaop));
   
-  emitcode("", "; forcedStackAop %s", aopName(aop));
+  D(emitcode("", "; forcedStackAop %s", aopName(aop)));
   for (loffset=0; loffset < newaop->size; loffset++)
     {
       asmop *aopsof = newAsmop (AOP_SOF);
@@ -728,8 +782,8 @@ storeRegToAop (regs *reg, asmop *aop, int loffset)
   int otheridx;
   #endif
 
-  emitcode ("", ";     storeRegToAop (%s, %s, %d), stacked=%d, isaddr=%d",
-            reg->name, aopName (aop), loffset, aop->stacked, aop->isaddr);
+  D(emitcode ("", ";     storeRegToAop (%s, %s, %d), stacked=%d, isaddr=%d",
+            reg->name, aopName (aop), loffset, aop->stacked, aop->isaddr));
 
   if ((reg->rIdx == HX_IDX) && aop->stacked
       && (aop->stk_aop[loffset] || aop->stk_aop[loffset+1]))
@@ -762,7 +816,10 @@ storeRegToAop (regs *reg, asmop *aop, int loffset)
       return;
     }
 
-    switch (regidx)
+  if (aop->type == AOP_DUMMY)
+    return;
+    
+  switch (regidx)
     {
       case A_IDX:
         if ((aop->type == AOP_REG) && (loffset < aop->size))
@@ -842,19 +899,19 @@ storeRegToAop (regs *reg, asmop *aop, int loffset)
                 && operandsEqu(otherreg->aop->op,aop->op)
                 && (otherreg->aopofs == loffset))
               {
-                emitcode("","; marking %s stale", otherreg->name);
+                D(emitcode("","; marking %s stale", otherreg->name));
                 otherreg->aop=NULL;
               }
           }
       if ((!hc08_reg_x->aop || !hc08_reg_h->aop) && hc08_reg_hx->aop)
         {
           hc08_reg_hx->aop = NULL;
-          emitcode("","; marking hx stale");
+          D(emitcode("","; marking hx stale"));
         }
       if ((!hc08_reg_x->aop || !hc08_reg_a->aop) && hc08_reg_xa->aop)
         {
           hc08_reg_xa->aop = NULL;
-          emitcode("","; marking xa stale");
+          D(emitcode("","; marking xa stale"));
         }
     
       reg->aop = aop;
@@ -945,6 +1002,8 @@ storeConstToAop (char *c, asmop *aop, int loffset)
           break;
         loadRegFromConst (aop->aopu.aop_reg[loffset], c);
         break;
+      case AOP_DUMMY:
+        break;
       default:
         if (hc08_reg_a->isFree)
           {
@@ -1073,10 +1132,10 @@ transferAopAop (asmop *srcaop, int srcofs, asmop *dstaop, int dstofs)
       return;
     }
 
-//  emitcode ("", "; transferAopAop (%s, %d, %s, %d)",
-//            aopName (srcaop), srcofs, aopName (dstaop), dstofs);  
-//  emitcode ("", "; srcaop->type = %d", srcaop->type);
-//  emitcode ("", "; dstaop->type = %d", dstaop->type);
+//  D(emitcode ("", "; transferAopAop (%s, %d, %s, %d)",
+//            aopName (srcaop), srcofs, aopName (dstaop), dstofs));
+//  D(emitcode ("", "; srcaop->type = %d", srcaop->type));
+//  D(emitcode ("", "; dstaop->type = %d", dstaop->type));
   
   if (dstofs >= dstaop->size)
     return;
@@ -1155,7 +1214,10 @@ accopWithAop (char *accop, asmop *aop, int loffset)
       accopWithAop (accop, aop->stk_aop[loffset], 0);
       return;
     }
-    
+
+  if (aop->type == AOP_DUMMY)
+    return;
+
   if (aop->type == AOP_REG)
     {
       pushReg (aop->aopu.aop_reg[loffset], FALSE);
@@ -1238,6 +1300,8 @@ rmwWithAop (char *rmwop, asmop *aop, int loffset)
        storeRegToAop (hc08_reg_a, aop, loffset);
         pullOrFreeReg (hc08_reg_a, needpula);
         break;
+      case AOP_DUMMY:
+        break;
       default:
         emitcode (rmwop, "%s", aopAdrStr (aop, loffset, FALSE));
    }
@@ -1478,10 +1542,10 @@ operandsEqu (operand * op1, operand * op2)
   if (sym1 == sym2)
     return TRUE;
 
-  if (strcmp (sym1->rname, sym2->rname) == 0)
+  if (sym1->rname[0] && sym2->rname[0]
+      && strcmp (sym1->rname, sym2->rname) == 0)
     return TRUE;
 
-
   /* if left is a tmp & right is not */
   if (IS_ITEMP (op1) &&
       !IS_ITEMP (op2) &&
@@ -1689,27 +1753,27 @@ aopOp (operand * op, iCode * ic, bool result)
        }
 #endif
       /* else spill location  */
-//      printf("checking spill loc\n");
-//      if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
-      if (sym->usl.spillLoc && sym->usl.spillLoc->aop
-          && sym->usl.spillLoc->aop->size != getSize (sym->type))
+      if (sym->usl.spillLoc)
         {
-         /* force a new aop if sizes differ */
-         sym->usl.spillLoc->aop = NULL;
-         //printf ("forcing new aop\n");
-        }
-      sym->aop = op->aop = aop =
-       aopForSym (ic, sym->usl.spillLoc, result);
+          if (sym->usl.spillLoc->aop
+              && sym->usl.spillLoc->aop->size != getSize (sym->type))
+            {
+             /* force a new aop if sizes differ */
+             sym->usl.spillLoc->aop = NULL;
+             //printf ("forcing new aop\n");
+            }
+         sym->aop = op->aop = aop = aopForSym (ic, sym->usl.spillLoc, result);
+         aop->size = getSize (sym->type);
+         aop->op = op;
+         aop->isaddr = op->isaddr;
+         //printf ("spill symbol %s\n", OP_SYMBOL (op)->name);
+         //printf (" with size = %d\n", aop->size);
+         return;
+       }
+      
+      /* else must be a dummy iTemp */
+      sym->aop = op->aop = aop = newAsmop (AOP_DUMMY);
       aop->size = getSize (sym->type);
-      aop->op = op;
-      aop->isaddr = op->isaddr;
-      //printf ("spill symbol %s\n", OP_SYMBOL (op)->name);
-      //printf (" with size = %d\n", aop->size);
-      /* if (aop->isaddr & IS_ITEMP (op))
-        {
-          aop->psize=aop->size;
-          aop->size = getSize( operandType (op)->next);
-        } */
       return;
     }
 
@@ -1750,7 +1814,7 @@ freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
       int stackAdjust;
       int loffset;
 
-      emitcode ("","; freeAsmop restoring stacked %s", aopName(aop));
+      D(emitcode ("","; freeAsmop restoring stacked %s", aopName(aop)));
       aop->stacked = 0;
       stackAdjust = 0;
       for (loffset=0; loffset<aop->size; loffset++)
@@ -1792,7 +1856,7 @@ aopDerefAop (asmop *aop)
   sym_link *type, *etype;
   int p_type;
   
-  emitcode ("", ";     aopDerefAop(%s)", aopName(aop));
+  D(emitcode ("", ";     aopDerefAop(%s)", aopName(aop)));
   if (aop->op)
     {
     
@@ -1871,6 +1935,9 @@ aopAdrStr (asmop * aop, int loffset, bool bit16)
   switch (aop->type)
     {
 
+    case AOP_DUMMY:
+      return zero;
+      
     case AOP_IMMD:
       if (aop->aopu.aop_immd.from_cast_remat && (loffset == (aop->size-1))) {
              sprintf(s,"%s",aop->aopu.aop_immd.aop_immd2);
@@ -2783,6 +2850,10 @@ genFunction (iCode * ic)
 
   emitcode ("", "%s:", sym->rname);
   ftype = operandType (IC_LEFT (ic));
+  
+  _G.stackOfs = 0;
+  _G.stackPushes = 0;
+  debugFile->writeFrameAddress (NULL, hc08_reg_sp, 0);
 
   if (IFFUNC_ISNAKED(ftype))
   {
@@ -2798,7 +2869,7 @@ genFunction (iCode * ic)
     {
 
       if (!inExcludeList ("h"))
-       emitcode ("pshh", "");
+        pushReg (hc08_reg_h, FALSE);
     }
   else
     {
@@ -2880,6 +2951,8 @@ genEndFunction (iCode * ic)
   if (IFFUNC_ISNAKED(sym->type))
   {
       emitcode(";", "naked function: no epilogue.");
+      if (options.debug && currFunc)
+        debugFile->writeEndFunction (currFunc, ic, 0);
       return;
   }
 
@@ -2921,21 +2994,13 @@ genEndFunction (iCode * ic)
     {
 
       if (!inExcludeList ("h"))
-       emitcode ("pulh", "");
+        pullReg (hc08_reg_h);
 
 
       /* if debug then send end of function */
       if (options.debug && currFunc)
        {
-         _G.debugLine = 1;
-         emitcode ("", "C$%s$%d$%d$%d ==.",
-                   FileBaseName (ic->filename), currFunc->lastLine,
-                   ic->level, ic->block);
-         if (IS_STATIC (currFunc->etype))
-           emitcode ("", "XF%s$%s$0$0 ==.", moduleName, currFunc->name);
-         else
-           emitcode ("", "XG$%s$0$0 ==.", currFunc->name);
-         _G.debugLine = 0;
+         debugFile->writeEndFunction (currFunc, ic, 1);
        }
 
       emitcode ("rti", "");
@@ -2954,7 +3019,7 @@ genEndFunction (iCode * ic)
                {
                  if (bitVectBitValue (sym->regsUsed, i) ||
                      (hc08_ptrRegReq && (i == HX_IDX || i == HX_IDX)))
-                   emitcode ("pop", "%s", hc08_regWithIdx (i)->dname);
+                   emitcode ("pop", "%s", hc08_regWithIdx (i)->name);
                }
            }
 
@@ -2963,15 +3028,7 @@ genEndFunction (iCode * ic)
       /* if debug then send end of function */
       if (options.debug && currFunc)
        {
-         _G.debugLine = 1;
-         emitcode ("", "C$%s$%d$%d$%d ==.",
-                   FileBaseName (ic->filename), currFunc->lastLine,
-                   ic->level, ic->block);
-         if (IS_STATIC (currFunc->etype))
-           emitcode ("", "XF%s$%s$0$0 ==.", moduleName, currFunc->name);
-         else
-           emitcode ("", "XG$%s$0$0 ==.", currFunc->name);
-         _G.debugLine = 0;
+         debugFile->writeEndFunction (currFunc, ic, 1);
        }
 
       emitcode ("rts", "");
@@ -3066,6 +3123,8 @@ genLabel (iCode * ic)
   /* special case never generate */
   if (IC_LABEL (ic) == entryLabel)
     return;
+         
+  debugFile->writeLabel(IC_LABEL (ic), ic);
 
   emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
 
@@ -3141,7 +3200,7 @@ genPlusIncr (iCode * ic)
 
   icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
 
-  emitcode ("", "; IS_AOP_HX = %d", IS_AOP_HX (AOP (left)));
+  D(emitcode ("", "; IS_AOP_HX = %d", IS_AOP_HX (AOP (left))));
   
   if ((IS_AOP_HX (AOP (left)) ||
        ( (AOP_TYPE (left) == AOP_DIR) && (AOP_TYPE (result) == AOP_DIR) )
@@ -3167,8 +3226,8 @@ genPlusIncr (iCode * ic)
       return TRUE;
     }
 
-  emitcode ("", "; icount = %d, sameRegs=%d", icount, 
-            sameRegs (AOP (left), AOP (result)));
+  D(emitcode ("", "; icount = %d, sameRegs=%d", icount, 
+            sameRegs (AOP (left), AOP (result))));
   
   if ((icount > 255) || (icount<0))
     return FALSE;
@@ -3252,9 +3311,9 @@ genPlus (iCode * ic)
   if (genPlusIncr (ic) == TRUE)
     goto release;
 
-  emitcode("",";  left size = %d", getDataSize (IC_LEFT(ic)));
-  emitcode("",";  right size = %d", getDataSize (IC_RIGHT(ic)));
-  emitcode("",";  result size = %d", getDataSize (IC_RESULT(ic)));
+  D(emitcode("",";  left size = %d", getDataSize (IC_LEFT(ic))));
+  D(emitcode("",";  right size = %d", getDataSize (IC_RIGHT(ic))));
+  D(emitcode("",";  result size = %d", getDataSize (IC_RESULT(ic))));
   
   size = getDataSize (IC_RESULT (ic));
 
@@ -3427,7 +3486,7 @@ genMultOneByte (operand * left,
                operand * right,
                operand * result)
 {
-  sym_link *opetype = operandType (result);
+  /* sym_link *opetype = operandType (result); */
   symbol *tlbl1, *tlbl2, *tlbl3, *tlbl4;
   int size=AOP_SIZE(result);
   bool negLiteral = FALSE;
@@ -3448,15 +3507,15 @@ genMultOneByte (operand * left,
       operand *t = right;
       right = left;
       left = t;
-      //emitcode (";", "swapped left and right");
+      //D(emitcode (";", "swapped left and right"));
     }
 
-  if (SPEC_USIGN(opetype)
+  if (size == 1
       || (SPEC_USIGN(operandType(left)) &&
          SPEC_USIGN(operandType(right))))
     {
       // just an unsigned 8*8=8/16 multiply
-      //emitcode (";","unsigned");
+      //D(emitcode (";","unsigned"));
 
       loadRegFromAop (hc08_reg_a, AOP (left), 0);
       loadRegFromAop (hc08_reg_x, AOP (right), 0);
@@ -3471,7 +3530,7 @@ genMultOneByte (operand * left,
   // we have to do a signed multiply
 
 
-  //emitcode (";", "signed");
+  //D(emitcode (";", "signed"));
   adjustStack (-1);
   emitcode ("clr", "1,s");
 
@@ -4188,44 +4247,49 @@ genPointerGetSetOfs (iCode *ic)
   asmop *derefaop;
 
   /* Make sure we have a next iCode */
-  emitcode("","; checking lic");
+  D(emitcode("","; checking lic"));
   if (!lic)
     return FALSE;
 
   /* Make sure the result of the addition is an iCode */
-  emitcode("","; checking IS_ITEMP");
+  D(emitcode("","; checking IS_ITEMP"));
   if (!IS_ITEMP (IC_RESULT (ic)))
     return FALSE;
 
   /* Make sure the next iCode is a pointer set or get */
   pset = POINTER_SET(lic);
   pget = POINTER_GET(lic);
-  emitcode("","; pset=%d, pget=%d",pset,pget);
+  D(emitcode("","; pset=%d, pget=%d",pset,pget));
   if (!pset && !pget)
     return FALSE;
 
-  emitcode("", "; checking pset operandsEqu");
+  /* Make sure this is the only use of the pointer */
+  if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
+    return FALSE;
+    
+  D(emitcode("", "; checking pset operandsEqu"));
   if (pset & !operandsEqu (IC_RESULT (ic), IC_RESULT (lic)))
     return FALSE;
 
-  emitcode("", "; checking pget operandsEqu");
+  D(emitcode("", "; checking pget operandsEqu"));
   if (pget & !operandsEqu (IC_RESULT (ic), IC_LEFT (lic)))
     return FALSE;
 
-  emitcode("", "; checking IS_SYMOP");
+  D(emitcode("", "; checking IS_SYMOP"));
   if (!IS_SYMOP (IC_LEFT (ic)))
     return FALSE;
 
-  emitcode("", "; checking !IS_TRUE_SYMOP");
+  D(emitcode("", "; checking !IS_TRUE_SYMOP"));
   if (IS_TRUE_SYMOP (IC_LEFT (ic)))
     return FALSE;
 
   sym = OP_SYMBOL (IC_LEFT (ic));
   
-  emitcode("", "; checking remat");
+  D(emitcode("", "; checking remat"));
   if (!sym->remat)
     return FALSE;
     
+  
   if (pget)
     {
       D(emitcode (";     genPointerGetOfs",""));
@@ -4235,9 +4299,27 @@ genPointerGetSetOfs (iCode *ic)
       
       aopOp (IC_RIGHT(ic), ic, FALSE);
       aopOp (IC_RESULT(lic), lic, FALSE);
-      
 
-      loadRegFromAop (hc08_reg_hx, AOP (IC_RIGHT (ic)), 0);
+      if (AOP_SIZE (IC_RIGHT (ic)) == 1)
+        {
+          if (SPEC_USIGN (getSpec (operandType (IC_RIGHT (ic)))))
+            {
+              loadRegFromAop (hc08_reg_x, AOP (IC_RIGHT (ic)), 0);
+              loadRegFromConst (hc08_reg_h, zero);
+            }
+          else
+            {
+              loadRegFromAop (hc08_reg_a, AOP (IC_RIGHT (ic)), 0);
+              transferRegReg (hc08_reg_a, hc08_reg_x, FALSE);
+              emitcode ("rola","");
+              emitcode ("clra","");
+              emitcode ("sbc", "#0");
+              hc08_useReg (hc08_reg_a);
+              transferRegReg (hc08_reg_a, hc08_reg_h, FALSE);
+           }
+        }
+      else
+        loadRegFromAop (hc08_reg_hx, AOP (IC_RIGHT (ic)), 0);
       size = AOP_SIZE (IC_RESULT(lic));
       derefaop->size = size;
       offset=0;
@@ -4271,8 +4353,26 @@ genPointerGetSetOfs (iCode *ic)
       aopOp (IC_RIGHT(ic), ic, FALSE);
       aopOp (IC_RIGHT(lic), lic, FALSE);
       
-
-      loadRegFromAop (hc08_reg_hx, AOP (IC_RIGHT (ic)), 0);
+      if (AOP_SIZE (IC_RIGHT (ic)) == 1)
+        {
+          if (SPEC_USIGN (getSpec (operandType (IC_RIGHT (ic)))))
+            {
+              loadRegFromAop (hc08_reg_x, AOP (IC_RIGHT (ic)), 0);
+              loadRegFromConst (hc08_reg_h, zero);
+            }
+          else
+            {
+              loadRegFromAop (hc08_reg_a, AOP (IC_RIGHT (ic)), 0);
+              transferRegReg (hc08_reg_a, hc08_reg_x, FALSE);
+              emitcode ("rola","");
+              emitcode ("clra","");
+              emitcode ("sbc", "#0");
+              hc08_useReg (hc08_reg_a);
+              transferRegReg (hc08_reg_a, hc08_reg_h, FALSE);
+           }
+        }
+      else
+        loadRegFromAop (hc08_reg_hx, AOP (IC_RIGHT (ic)), 0);
       size = AOP_SIZE (IC_RIGHT(lic));
       derefaop->size = size;
       offset=0;
@@ -4512,12 +4612,12 @@ genAnd (iCode * ic, iCode * ifx)
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
 
 #ifdef DEBUG_TYPE
-  emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+  D(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
            AOP_TYPE (result),
-           AOP_TYPE (left), AOP_TYPE (right));
-  emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
+           AOP_TYPE (left), AOP_TYPE (right)));
+  D(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
            AOP_SIZE (result),
-           AOP_SIZE (left), AOP_SIZE (right));
+           AOP_SIZE (left), AOP_SIZE (right)));
 #endif
 
   /* if left is a literal & right is not then exchange them */
@@ -4616,12 +4716,12 @@ genOr (iCode * ic, iCode * ifx)
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
 
 #ifdef DEBUG_TYPE
-  emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+  D(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
            AOP_TYPE (result),
-           AOP_TYPE (left), AOP_TYPE (right));
-  emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
+           AOP_TYPE (left), AOP_TYPE (right)));
+  D(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
            AOP_SIZE (result),
-           AOP_SIZE (left), AOP_SIZE (right));
+           AOP_SIZE (left), AOP_SIZE (right)));
 #endif
 
   /* if left is a literal & right is not then exchange them */
@@ -4716,12 +4816,12 @@ genXor (iCode * ic, iCode * ifx)
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
 
 #ifdef DEBUG_TYPE
-  emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+  D(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
            AOP_TYPE (result),
-           AOP_TYPE (left), AOP_TYPE (right));
-  emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
+           AOP_TYPE (left), AOP_TYPE (right)));
+  D(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
            AOP_SIZE (result),
-           AOP_SIZE (left), AOP_SIZE (right));
+           AOP_SIZE (left), AOP_SIZE (right)));
 #endif
 
   /* if left is a literal & right is not ||
@@ -5902,8 +6002,8 @@ genLeftShiftLiteral (operand * left,
   size = AOP_SIZE (result);
 
 #if VIEW_SIZE
-  emitcode ("; shift left ", "result %d, left %d", size,
-           AOP_SIZE (left));
+  D(emitcode ("; shift left ", "result %d, left %d", size,
+           AOP_SIZE (left)));
 #endif
 
   if (shCount == 0)
@@ -6212,8 +6312,8 @@ genRightShiftLiteral (operand * left,
   aopOp (result, ic, FALSE);
 
 #if VIEW_SIZE
-  emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
-           AOP_SIZE (left));
+  D(emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
+           AOP_SIZE (left)));
 #endif
 
   size = getDataSize (left);
@@ -6344,11 +6444,12 @@ genRightShift (iCode * ic)
   freeAsmop (right, NULL, ic, TRUE);
 }
 
+
 /*-----------------------------------------------------------------*/
 /* genUnpackBits - generates code for unpacking bits               */
 /*-----------------------------------------------------------------*/
 static void
-genUnpackBits (operand * result)
+genUnpackBits (operand * result, iCode *ifx)
 {
   int offset = 0;      /* result byte offset */
   int rsize;           /* result size */
@@ -6369,9 +6470,17 @@ genUnpackBits (operand * result)
     {
       emitcode ("lda", ",x");
       hc08_dirtyReg (hc08_reg_a, FALSE);
-      AccRsh (bstr, FALSE);
-      emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8 - blen));
-      storeRegToAop (hc08_reg_a, AOP (result), offset++);
+      if (!ifx)
+        {
+          AccRsh (bstr, FALSE);
+          emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8 - blen));
+          storeRegToAop (hc08_reg_a, AOP (result), offset++);
+        }
+      else
+        {
+          emitcode ("and", "#0x%02x",
+                    (((unsigned char) -1) >> (8 - blen)) << bstr);
+        }
       goto finish;
     }
 
@@ -6381,7 +6490,9 @@ genUnpackBits (operand * result)
     {
       emitcode ("lda", ",x");
       hc08_dirtyReg (hc08_reg_a, FALSE);
-      storeRegToAop (hc08_reg_a, AOP (result), offset++);
+      if (!ifx)
+        storeRegToAop (hc08_reg_a, AOP (result), offset);
+      offset++;
       if (rlen>8)
         emitcode ("aix", "#1");
     }
@@ -6401,21 +6512,33 @@ finish:
       while (rsize--)
         storeConstToAop (zero, AOP (result), offset++);
     }
+  
+  if (ifx && !ifx->generated)
+    {
+      genIfxJump (ifx, "a");
+    }
 }
 
 
 /*-----------------------------------------------------------------*/
-/* genDataPointerGet - generates code when ptr offset is known     */
+/* genUnpackBitsImmed - generates code for unpacking bits          */
 /*-----------------------------------------------------------------*/
 static void
-genDataPointerGet (operand * left,
-                  operand * result,
-                  iCode * ic)
+genUnpackBitsImmed (operand * left,
+                    operand * result,
+                    iCode *ic,
+                    iCode *ifx)
 {
-  int size, offset = 0;
+  int size;
+  int offset = 0;      /* result byte offset */
+  int rsize;           /* result size */
+  int rlen = 0;                /* remaining bitfield length */
+  sym_link *etype;     /* bitfield type information */
+  int blen;            /* bitfield length */
+  int bstr;            /* bitfield starting bit within byte */
   asmop *derefaop;
   
-  D(emitcode (";     genDataPointerGet",""));
+  D(emitcode (";     genUnpackBitsImmed",""));
 
   aopOp (result, ic, TRUE);
   size = AOP_SIZE (result);
@@ -6424,116 +6547,187 @@ genDataPointerGet (operand * left,
   freeAsmop (left, NULL, ic, TRUE);
   derefaop->size = size;
   
-  while (size--)
+  etype = getSpec (operandType (result));
+  rsize = getSize (operandType (result));
+  blen = SPEC_BLEN (etype);
+  bstr = SPEC_BSTR (etype);
+
+  /* if the bitfield is a single bit in the direct page */
+  if (blen == 1 && derefaop->type == AOP_DIR)
+    {
+      if (!ifx && bstr)
+        {
+          symbol *tlbl = newiTempLabel (NULL);
+          
+          loadRegFromConst (hc08_reg_a, zero);
+          emitcode ("brclr", "#%d,%s,%05d$",
+                    bstr, aopAdrStr (derefaop, 0, FALSE),
+                    (tlbl->key + 100));
+          rmwWithReg ("inc", hc08_reg_a);
+          emitLabel (tlbl);
+          storeRegToAop (hc08_reg_a, AOP (result), offset);
+          hc08_freeReg (hc08_reg_a);
+          offset++;
+          goto finish;
+        }
+      else if (ifx)
+        {
+          symbol *tlbl = newiTempLabel (NULL);
+          symbol *jlbl;
+          char * inst;
+          
+          if (IC_TRUE (ifx))
+            {
+              jlbl = IC_TRUE (ifx);
+              inst = "brclr";
+            }
+          else
+            {
+              jlbl = IC_FALSE (ifx);
+              inst = "brset";
+            }
+          emitcode (inst, "#%d,%s,%05d$",
+                    bstr, aopAdrStr (derefaop, 0, FALSE),
+                    (tlbl->key + 100));
+          emitBranch ("jmp", jlbl);
+          emitLabel (tlbl);
+          ifx->generated = 1;
+          offset++;
+          goto finish;
+        }
+    }
+
+  /* If the bitfield length is less than a byte */
+  if (blen < 8)
     {
-      transferAopAop(derefaop, offset, AOP (result), offset);
+      loadRegFromAop (hc08_reg_a, derefaop, 0);
+      if (!ifx)
+        {
+          AccRsh (bstr, FALSE);
+          emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8 - blen));
+          hc08_dirtyReg (hc08_reg_a, FALSE);
+          storeRegToAop (hc08_reg_a, AOP (result), offset);
+        }
+      else
+        {
+          emitcode ("and", "#0x%02x",
+                    (((unsigned char) -1) >> (8 - blen)) << bstr);
+          hc08_dirtyReg (hc08_reg_a, FALSE);
+        }
+      offset++;
+      goto finish;
+    }
+
+  /* Bit field did not fit in a byte. Copy all
+     but the partial byte at the end.  */
+  for (rlen=blen;rlen>=8;rlen-=8)
+    {
+      loadRegFromAop (hc08_reg_a, derefaop, size-offset);
+      if (!ifx)
+        storeRegToAop (hc08_reg_a, AOP (result), offset);
+      else
+        emitcode ("tsta", "");
       offset++;
     }
 
+  /* Handle the partial byte at the end */
+  if (rlen)
+    {
+      loadRegFromAop (hc08_reg_a, derefaop, size-offset);
+      emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8-rlen));
+      storeRegToAop (hc08_reg_a, AOP (result), offset++);
+    }
+
+finish:
+  if (offset < rsize)
+    {
+      rsize -= offset;
+      while (rsize--)
+        storeConstToAop (zero, AOP (result), offset++);
+    }
+  
   freeAsmop (NULL, derefaop, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
+  
+  if (ifx && !ifx->generated)
+    {
+      genIfxJump (ifx, "a");
+    }
 }
 
-#if 0
+
 /*-----------------------------------------------------------------*/
-/* genNearPointerGet - emitcode for near pointer fetch             */
+/* genDataPointerGet - generates code when ptr offset is known     */
 /*-----------------------------------------------------------------*/
 static void
-genNearPointerGet (operand * left,
+genDataPointerGet (operand * left,
                   operand * result,
                   iCode * ic,
-                  iCode * pi)
+                   iCode * ifx)
 {
-  int size, offset;
-  sym_link *retype = getSpec (operandType (result));
-
-  D(emitcode (";     genNearPointerGet",""));
-
-  aopOp (left, ic, FALSE);
-
-  /* if left is rematerialisable and
-     result is not bit variable type and
-     the left is pointer to data space i.e
-     lower 128 bytes of space */
-  if ((AOP_TYPE (left) == AOP_IMMD)
-      || (AOP_TYPE (left) == AOP_LIT) 
-      /* !IS_BITVAR (retype) */
-      /* && DCL_TYPE (ltype) == POINTER */ )
-    {
-      genDataPointerGet (left, result, ic);
-      return;
-    }
-
-  /* if the operand is already in hx
-     then we do nothing else we move the value to hx */
-  if (AOP_TYPE (left) != AOP_STR)
-    {
-      /* if this is remateriazable */
-      loadRegFromAop (hc08_reg_x, AOP (left), 0);
-      loadRegFromConst (hc08_reg_h, zero);
-    }
+  int size, offset = 0;
+  asmop *derefaop;
+  
+  D(emitcode (";     genDataPointerGet",""));
 
-  /* so hx now contains the address */
-  aopOp (result, ic, FALSE);
+  aopOp (result, ic, TRUE);
+  size = AOP_SIZE (result);
 
-  /* if bit then unpack */
-  if (IS_BITVAR (retype))
-    genUnpackBits (result);
-  else
+  derefaop = aopDerefAop (AOP (left));
+  freeAsmop (left, NULL, ic, TRUE);
+  derefaop->size = size;
+  
+  while (size--)
     {
-      size = AOP_SIZE (result);
-      offset = size-1;
-
-      while (size--)
-       {
-         accopWithMisc ("lda", ",x");
-         if (size || pi)
-            {
-              rmwWithReg ("inc", hc08_reg_x);
-            }
-          storeRegToAop (hc08_reg_a, AOP (result), offset--);
-          hc08_freeReg (hc08_reg_a);
-       }
+      if (!ifx)
+        transferAopAop (derefaop, offset, AOP (result), offset);
+      else
+        loadRegFromAop (hc08_reg_a, derefaop, offset);
+      offset++;
     }
 
-  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (NULL, derefaop, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
   
-  if (pi /* && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR */) {
-    aopOp (IC_RESULT (pi), pi, FALSE);
-    storeRegToAop (hc08_reg_x, AOP (IC_RESULT (pi)), 0);
-    freeAsmop (IC_RESULT (pi), NULL, pi, TRUE);
-    pi->generated = 1;
-  }
-
-  hc08_freeReg (hc08_reg_hx);
+  if (ifx && !ifx->generated)
+    {
+      genIfxJump (ifx, "a");
+    }
 }
-#endif
+
 
 /*-----------------------------------------------------------------*/
-/* genFarPointerGet - get value from far space                     */
+/* genPointerGet - generate code for pointer get                   */
 /*-----------------------------------------------------------------*/
 static void
-genFarPointerGet (operand * left,
-                 operand * result, iCode * ic, iCode * pi)
+genPointerGet (iCode * ic, iCode *pi, iCode *ifx)
 {
+  operand *left = IC_LEFT (ic);
+  operand *result = IC_RESULT (ic);
   int size, offset;
   sym_link *retype = getSpec (operandType (result));
 
-  D(emitcode (";     genFarPointerGet",""));
+  D(emitcode (";     genPointerGet",""));
 
+  if (getSize (operandType (result))>1)
+    ifx = NULL;
+  
   aopOp (left, ic, FALSE);
 
   /* if left is rematerialisable and
-     result is not bit variable type and
-     the left is pointer to data space i.e
-     lower 128 bytes of space */
-  if (AOP_TYPE (left) == AOP_IMMD &&
-      !IS_BITVAR (retype)
-      /* && DCL_TYPE (ltype) == POINTER */ )
-    {
-      genDataPointerGet (left, result, ic);
-      return;
+     result is not bit variable type */
+  if (AOP_TYPE (left) == AOP_IMMD || AOP_TYPE (left) == AOP_LIT)
+    {
+      if (!IS_BITVAR (retype))
+        {
+          genDataPointerGet (left, result, ic, ifx);
+          return;
+        }
+      else
+        {
+          genUnpackBitsImmed (left, result, ic, ifx);
+          return;
+        }
     }
 
   /* if the operand is already in hx
@@ -6549,7 +6743,7 @@ genFarPointerGet (operand * left,
 
   /* if bit then unpack */
   if (IS_BITVAR (retype))
-    genUnpackBits (result);
+    genUnpackBits (result, ifx);
   else
     {
       size = AOP_SIZE (result);
@@ -6563,7 +6757,9 @@ genFarPointerGet (operand * left,
              emitcode ("aix", "#1");
              hc08_dirtyReg (hc08_reg_hx, FALSE);
             }
-          storeRegToAop (hc08_reg_a, AOP (result), offset--);
+          if (!ifx)
+            storeRegToAop (hc08_reg_a, AOP (result), offset);
+          offset--;
           hc08_freeReg (hc08_reg_a);
        }
     }
@@ -6571,81 +6767,28 @@ genFarPointerGet (operand * left,
   freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
   
-  if (pi /* && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR */) {
+  if (pi) {
     aopOp (IC_RESULT (pi), pi, FALSE);
     storeRegToAop (hc08_reg_hx, AOP (IC_RESULT (pi)), 0);
     freeAsmop (IC_RESULT (pi), NULL, pi, TRUE);
     pi->generated = 1;
   }
+  
+  if (ifx && !ifx->generated)
+    {
+      genIfxJump (ifx, "a");
+    }
 
   hc08_freeReg (hc08_reg_hx);
   
 }
 
-
-
 /*-----------------------------------------------------------------*/
-/* genPointerGet - generate code for pointer get                   */
+/* genPackBits - generates code for packed bit storage             */
 /*-----------------------------------------------------------------*/
 static void
-genPointerGet (iCode * ic, iCode *pi)
-{
-  operand *left, *result;
-  sym_link *type, *etype;
-  int p_type;
-
-  D(emitcode (";     genPointerGet",""));
-
-  left = IC_LEFT (ic);
-  result = IC_RESULT (ic);
-
-  /* depending on the type of pointer we need to
-     move it to the correct pointer register */
-  type = operandType (left);
-  etype = getSpec (type);
-  /* if left is of type of pointer then it is simple */
-  if (IS_PTR (type) && !IS_FUNC (type->next))
-    p_type = DCL_TYPE (type);
-  else
-    {
-      /* we have to go by the storage class */
-      p_type = PTR_TYPE (SPEC_OCLS (etype));
-    }
-
-  /* special case when cast remat */
-  if (p_type == GPOINTER && IS_SYMOP(left) && OP_SYMBOL(left)->remat &&
-      IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) {
-         left = IC_RIGHT(OP_SYMBOL(left)->rematiCode);
-         type = operandType (left);
-         p_type = DCL_TYPE (type);
-  }
-  /* now that we have the pointer type we assign
-     the pointer values */
-  switch (p_type)
-    {
-
-    case POINTER:
-    case IPOINTER:
-#if 0
-      genNearPointerGet (left, result, ic, pi);
-      break;
-#endif
-    case GPOINTER:
-    case CPOINTER:
-    case FPOINTER:
-      genFarPointerGet (left, result, ic, pi);
-      break;
-
-    }
-
-}
-
-/*-----------------------------------------------------------------*/
-/* genPackBits - generates code for packed bit storage             */
-/*-----------------------------------------------------------------*/
-static void
-genPackBits (sym_link * etype,
-            operand * right)
+genPackBits (sym_link * etype,
+            operand * right)
 {
   int offset = 0;      /* source byte offset */
   int rlen = 0;                /* remaining bitfield length */
@@ -6653,12 +6796,13 @@ genPackBits (sym_link * etype,
   int bstr;            /* bitfield starting bit within byte */
   int litval;          /* source literal value (if AOP_LIT) */
   unsigned char mask;  /* bitmask within current byte */
+  int xoffset = 0;
 
   D(emitcode (";     genPackBits",""));
 
   blen = SPEC_BLEN (etype);
   bstr = SPEC_BSTR (etype);
-  
+
   /* If the bitfield length is less than a byte */
   if (blen < 8)
     {
@@ -6711,6 +6855,7 @@ genPackBits (sym_link * etype,
       if (AOP (right)->type == AOP_DIR)
         {
           emitcode ("mov", "%s,x+", aopAdrStr(AOP (right), offset, FALSE));
+         xoffset++;
         }
       else
         {
@@ -6732,13 +6877,13 @@ genPackBits (sym_link * etype,
           litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
           litval >>= (blen-rlen);
           litval &= (~mask) & 0xff;
-          emitcode ("lda", "%d,x", offset);
+          emitcode ("lda", "%d,x", offset - xoffset);
           hc08_dirtyReg (hc08_reg_a, FALSE);
           if ((mask|litval)!=0xff)
             emitcode ("and","#0x%02x", mask);
           if (litval)
             emitcode ("ora","#0x%02x", litval);
-          emitcode ("sta", "%d,x", offset);
+          emitcode ("sta", "%d,x", offset - xoffset);
           hc08_dirtyReg (hc08_reg_a, FALSE);
           hc08_freeReg (hc08_reg_a);
           return;
@@ -6746,15 +6891,15 @@ genPackBits (sym_link * etype,
       
       /* Case with partial byte and arbitrary source
       */
-      loadRegFromAop (hc08_reg_a, AOP (right), offset++);
+      loadRegFromAop (hc08_reg_a, AOP (right), offset);
       emitcode ("and", "#0x%02x", (~mask) & 0xff);
       hc08_dirtyReg (hc08_reg_a, FALSE);
       pushReg (hc08_reg_a, TRUE);
 
-      emitcode ("lda", ",x");
+      emitcode ("lda", "%d,x", offset - xoffset);
       emitcode ("and", "#0x%02x", mask);
       emitcode ("ora", "1,s");
-      emitcode ("sta", ",x");
+      emitcode ("sta", "%d,x", offset - xoffset);
       pullReg (hc08_reg_a);
     }
 
@@ -6762,17 +6907,24 @@ genPackBits (sym_link * etype,
 }
 
 /*-----------------------------------------------------------------*/
-/* genDataPointerSet - remat pointer to data space                 */
+/* genPackBits - generates code for packed bit storage             */
 /*-----------------------------------------------------------------*/
 static void
-genDataPointerSet (operand * right,
-                  operand * result,
-                  iCode * ic)
+genPackBitsImmed (operand *result, sym_link * etype, operand * right, iCode * ic)
 {
-  int size, offset = 0;
   asmop *derefaop;
+  int size;
+  int offset = 0;      /* source byte offset */
+  int rlen = 0;                /* remaining bitfield length */
+  int blen;            /* bitfield length */
+  int bstr;            /* bitfield starting bit within byte */
+  int litval;          /* source literal value (if AOP_LIT) */
+  unsigned char mask;  /* bitmask within current byte */
 
-  D(emitcode (";     genDataPointerSet",""));
+  D(emitcode (";     genPackBitsImmed",""));
+
+  blen = SPEC_BLEN (etype);
+  bstr = SPEC_BSTR (etype);
 
   aopOp (right, ic, FALSE);
   size = AOP_SIZE (right);
@@ -6780,115 +6932,197 @@ genDataPointerSet (operand * right,
   derefaop = aopDerefAop (AOP (result));
   freeAsmop (result, NULL, ic, TRUE);
   derefaop->size = size;
-  
-  while (size--)
+
+  /* if the bitfield is a single bit in the direct page */
+  if (blen == 1 && derefaop->type == AOP_DIR)
     {
-      transferAopAop (AOP (right), offset, derefaop, offset);
+      if (AOP_TYPE (right) == AOP_LIT)
+        {
+          litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+      
+          emitcode ((litval & 1) ? "bset" : "bclr", 
+                    "#%d,%s", bstr, aopAdrStr (derefaop, 0, FALSE));
+        }
+      else
+        {
+          symbol *tlbl1 = newiTempLabel (NULL);
+          symbol *tlbl2 = newiTempLabel (NULL);
+          
+          loadRegFromAop (hc08_reg_a, AOP (right), 0);
+          emitcode ("bit", "#1");
+          emitBranch ("bne", tlbl1);
+          emitcode ("bclr", "#%d,%s", bstr, aopAdrStr (derefaop, 0, FALSE));
+          emitBranch ("bra", tlbl2);
+          emitLabel (tlbl1);
+          emitcode ("bset", "#%d,%s", bstr, aopAdrStr (derefaop, 0, FALSE));
+          emitLabel (tlbl2);
+          hc08_freeReg (hc08_reg_a);
+        }
+      goto release;
+    }
+    
+  /* If the bitfield length is less than a byte */
+  if (blen < 8)
+    {
+      mask = ((unsigned char) (0xFF << (blen + bstr)) |
+             (unsigned char) (0xFF >> (8 - bstr)));
+
+      if (AOP_TYPE (right) == AOP_LIT)
+        {
+          /* Case with a bitfield length <8 and literal source
+          */
+          litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+          litval <<= bstr;
+          litval &= (~mask) & 0xff;
+
+          loadRegFromAop (hc08_reg_a, derefaop, 0);
+          if ((mask|litval)!=0xff)
+            emitcode ("and","#0x%02x", mask);
+          if (litval)
+            emitcode ("ora","#0x%02x", litval);
+          hc08_dirtyReg (hc08_reg_a, FALSE);
+          storeRegToAop (hc08_reg_a, derefaop, 0);
+          
+          hc08_freeReg (hc08_reg_a);
+          goto release;
+        }
+          
+      /* Case with a bitfield length < 8 and arbitrary source
+      */
+      loadRegFromAop (hc08_reg_a, AOP (right), 0);
+      /* shift and mask source value */
+      AccLsh (bstr);
+      emitcode ("and", "#0x%02x", (~mask) & 0xff);
+      hc08_dirtyReg (hc08_reg_a, FALSE);
+      pushReg (hc08_reg_a, TRUE);
+
+      loadRegFromAop (hc08_reg_a, derefaop, 0);
+      emitcode ("and", "#0x%02x", mask);
+      emitcode ("ora", "1,s");
+      storeRegToAop (hc08_reg_a, derefaop, 0);
+      pullReg (hc08_reg_a);
+     
+      hc08_freeReg (hc08_reg_a);
+      goto release;
+    }
+
+  /* Bit length is greater than 7 bits. In this case, copy  */
+  /* all except the partial byte at the end                 */
+  for (rlen=blen;rlen>=8;rlen-=8)
+    {
+      transferAopAop (AOP (right), offset, derefaop, size-offset);
       offset++;
     }
 
+  /* If there was a partial byte at the end */
+  if (rlen)
+    {
+      mask = (((unsigned char) -1 << rlen) & 0xff);
+      
+      if (AOP_TYPE (right) == AOP_LIT)
+        {
+          /* Case with partial byte and literal source
+          */
+          litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+          litval >>= (blen-rlen);
+          litval &= (~mask) & 0xff;
+          loadRegFromAop (hc08_reg_a, derefaop, size-offset);
+          if ((mask|litval)!=0xff)
+            emitcode ("and","#0x%02x", mask);
+          if (litval)
+            emitcode ("ora","#0x%02x", litval);
+          hc08_dirtyReg (hc08_reg_a, FALSE);
+          storeRegToAop (hc08_reg_a, derefaop, size-offset);
+          hc08_dirtyReg (hc08_reg_a, FALSE);
+          hc08_freeReg (hc08_reg_a);
+          goto release;
+        }
+      
+      /* Case with partial byte and arbitrary source
+      */
+      loadRegFromAop (hc08_reg_a, AOP (right), offset);
+      emitcode ("and", "#0x%02x", (~mask) & 0xff);
+      hc08_dirtyReg (hc08_reg_a, FALSE);
+      pushReg (hc08_reg_a, TRUE);
+
+      loadRegFromAop (hc08_reg_a, derefaop, size-offset);
+      emitcode ("and", "#0x%02x", mask);
+      emitcode ("ora", "1,s");
+      storeRegToAop (hc08_reg_a, derefaop, size-offset);
+      pullReg (hc08_reg_a);
+    }
+
+  hc08_freeReg (hc08_reg_a);
+
+release:  
   freeAsmop (right, NULL, ic, TRUE);
   freeAsmop (NULL, derefaop, ic, TRUE);
 }
 
-#if 0
 /*-----------------------------------------------------------------*/
-/* genNearPointerSet - emitcode for near pointer put                */
+/* genDataPointerSet - remat pointer to data space                 */
 /*-----------------------------------------------------------------*/
 static void
-genNearPointerSet (operand * right,
+genDataPointerSet (operand * right,
                   operand * result,
-                  iCode * ic,
-                  iCode * pi)
+                  iCode * ic)
 {
-  int size, offset;
-  sym_link *retype = getSpec (operandType (right));
-  sym_link *letype = getSpec (operandType (result));
-
-  D(emitcode (";     genNearPointerSet",""));
-
-  aopOp (result, ic, FALSE);
+  int size, offset = 0;
+  asmop *derefaop;
 
-  /* if the result is rematerializable &
-     in data space & not a bit variable */
-  if (AOP_TYPE (result) == AOP_IMMD &&
-      /* DCL_TYPE (ptype) == POINTER && */
-      !IS_BITVAR (retype) &&
-      !IS_BITVAR (letype))
-    {
-      genDataPointerSet (right, result, ic);
-      return;
-    }
+  D(emitcode (";     genDataPointerSet",""));
 
-  /* if the operand is already in hx
-     then we do nothing else we move the value to hx */
-  if (AOP_TYPE (result) != AOP_STR)
-    {
-      loadRegFromAop (hc08_reg_x, AOP (result), 0);
-      loadRegFromConst (hc08_reg_h, zero);
-    }
-  /* so hx now contains the address */
   aopOp (right, ic, FALSE);
+  size = AOP_SIZE (right);
 
-  /* if bit then unpack */
-  if (IS_BITVAR (retype) || IS_BITVAR (letype))
-    genPackBits ((IS_BITVAR (retype) ? retype : letype), right);
-  else
+  derefaop = aopDerefAop (AOP (result));
+  freeAsmop (result, NULL, ic, TRUE);
+  derefaop->size = size;
+  
+  while (size--)
     {
-      size = AOP_SIZE (right);
-      offset = size-1;
-
-      while (size--)
-       {
-          loadRegFromAop (hc08_reg_a, AOP (right), offset--);
-         accopWithMisc ("sta", ",x");
-         if (size || pi)
-           {
-             rmwWithReg ("inc", hc08_reg_x);
-           }
-          hc08_freeReg (hc08_reg_a);
-       }
+      transferAopAop (AOP (right), offset, derefaop, offset);
+      offset++;
     }
 
-  freeAsmop (result, NULL, ic, TRUE);
   freeAsmop (right, NULL, ic, TRUE);
-
-  if (pi /* && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD */) {
-    aopOp (IC_RESULT (pi), pi, FALSE);
-    storeRegToAop (hc08_reg_x, AOP (IC_RESULT (pi)), 0);
-    freeAsmop (IC_RESULT (pi), NULL, pi, TRUE);
-    pi->generated=1;
-  }
-
-  hc08_freeReg (hc08_reg_hx);
-  
+  freeAsmop (NULL, derefaop, ic, TRUE);
 }
-#endif
+
 
 /*-----------------------------------------------------------------*/
-/* genFarPointerSet - set value from far space                     */
+/* genPointerSet - stores the value into a pointer location        */
 /*-----------------------------------------------------------------*/
 static void
-genFarPointerSet (operand * right,
-                 operand * result, iCode * ic, iCode * pi)
+genPointerSet (iCode * ic, iCode *pi)
 {
+  operand *right = IC_RIGHT (ic);
+  operand *result = IC_RESULT (ic);
+  sym_link *type, *etype;
   int size, offset;
   sym_link *retype = getSpec (operandType (right));
   sym_link *letype = getSpec (operandType (result));
 
-  D(emitcode (";     genFarPointerSet",""));
+  D(emitcode (";     genPointerSet",""));
 
+  type = operandType (result);
+  etype = getSpec (type);
+  
   aopOp (result, ic, FALSE);
 
-  /* if the result is rematerializable &
-     in data space & not a bit variable */
-  if (AOP_TYPE (result) == AOP_IMMD &&
-      /* DCL_TYPE (ptype) == POINTER && */
-      !IS_BITVAR (retype) &&
-      !IS_BITVAR (letype))
+  /* if the result is rematerializable */
+  if (AOP_TYPE (result) == AOP_IMMD || AOP_TYPE (result) == AOP_LIT)
     {
-      genDataPointerSet (right, result, ic);
-      return;
+      if (!IS_BITVAR (retype) && !IS_BITVAR (letype))
+        {
+          genDataPointerSet (right, result, ic);
+          return;
+        }
+      else
+        {
+          genPackBitsImmed (result, (IS_BITVAR (retype) ? retype : letype), right, ic);
+          return;
+        }
     }
 
   /* if the operand is already in hx
@@ -6923,7 +7157,7 @@ genFarPointerSet (operand * right,
   freeAsmop (result, NULL, ic, TRUE);
   freeAsmop (right, NULL, ic, TRUE);
 
-  if (pi /* && AOP_TYPE (result) != AOP_STR && AOP_TYPE (result) != AOP_IMMD  */) {
+  if (pi) {
     aopOp (IC_RESULT (pi), pi, FALSE);
     storeRegToAop (hc08_reg_hx, AOP (IC_RESULT (pi)), 0);
     freeAsmop (IC_RESULT (pi), NULL, pi, TRUE);
@@ -6931,69 +7165,6 @@ genFarPointerSet (operand * right,
   }
 
   hc08_freeReg (hc08_reg_hx);
-  
-
-}
-
-
-/*-----------------------------------------------------------------*/
-/* genPointerSet - stores the value into a pointer location        */
-/*-----------------------------------------------------------------*/
-static void
-genPointerSet (iCode * ic, iCode *pi)
-{
-  operand *right, *result;
-  sym_link *type, *etype;
-  int p_type;
-
-  D(emitcode (";     genPointerSet",""));
-
-  right = IC_RIGHT (ic);
-  result = IC_RESULT (ic);
-
-  /* depending on the type of pointer we need to
-     move it to the correct pointer register */
-  type = operandType (result);
-  etype = getSpec (type);
-  /* if left is of type of pointer then it is simple */
-  if (IS_PTR (type) && !IS_FUNC (type->next))
-    {
-      p_type = DCL_TYPE (type);
-    }
-  else
-    {
-      /* we have to go by the storage class */
-      p_type = PTR_TYPE (SPEC_OCLS (etype));
-    }
-
-  /* special case when cast remat */
-  if (p_type == GPOINTER && OP_SYMBOL(result)->remat &&
-      IS_CAST_ICODE(OP_SYMBOL(result)->rematiCode)) {
-         result = IC_RIGHT(OP_SYMBOL(result)->rematiCode);
-         type = operandType (result);
-         p_type = DCL_TYPE (type);
-  }
-  /* now that we have the pointer type we assign
-     the pointer values */
-  switch (p_type)
-    {
-
-    case POINTER:
-    case IPOINTER:
-#if 0
-      genNearPointerSet (right, result, ic, pi);
-      break;
-#endif
-
-    case GPOINTER:
-    case FPOINTER:
-      genFarPointerSet (right, result, ic, pi);
-      break;
-
-    default:
-      werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
-             "genPointerSet: illegal pointer type");
-    }
 
 }
 
@@ -7160,6 +7331,7 @@ genJumpTab (iCode * ic)
   emitcode ("add","1,s");
   transferRegReg (hc08_reg_a, hc08_reg_x, TRUE);
   loadRegFromConst (hc08_reg_h, zero);
+  pullReg (hc08_reg_a);
 
   jtab = newiTempLabel (NULL);
   emitcode ("jmp", "%05d$,x", jtab->key + 100);
@@ -7501,6 +7673,7 @@ genEndCritical (iCode *ic)
 }
 
 
+
 /*-----------------------------------------------------------------*/
 /* genhc08Code - generate code for HC08 based controllers          */
 /*-----------------------------------------------------------------*/
@@ -7509,6 +7682,8 @@ genhc08Code (iCode * lic)
 {
   iCode *ic;
   int cln = 0;
+  int clevel = 0;
+  int cblock = 0;
 
   lineHead = lineCurr = NULL;
 
@@ -7518,19 +7693,23 @@ genhc08Code (iCode * lic)
   /* if debug information required */
   if (options.debug && currFunc)
     {
-      debugFile->writeFunction(currFunc);
+      debugFile->writeFunction (currFunc, lic);
+      #if 0
       _G.debugLine = 1;
       if (IS_STATIC (currFunc->etype))
        emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
       else
        emitcode ("", "G$%s$0$0 ==.", currFunc->name);
       _G.debugLine = 0;
+      #endif
     }
   /* stack pointer name */
   if (options.useXstack)
     spname = "_spx";
   else
     spname = "sp";
+  
+  debugFile->writeFrameAddress (NULL, NULL, 0);  /* have no idea where frame is now */
 
   hc08_aop_pass[0] = newAsmop (AOP_REG);
   hc08_aop_pass[0]->size=1;
@@ -7547,16 +7726,31 @@ genhc08Code (iCode * lic)
 
   for (ic = lic; ic; ic = ic->next)
     {
-
+      
+      _G.current_iCode = ic;
+      
+      if (ic->level != clevel || ic->block != cblock)
+       {
+         if (options.debug)
+           {
+             debugFile->writeScope(ic);
+           }
+         clevel = ic->level;
+         cblock = ic->block;
+       }
+       
       if (ic->lineno && cln != ic->lineno)
        {
          if (options.debug)
            {
+             debugFile->writeCLine(ic);
+             #if 0
              _G.debugLine = 1;
              emitcode ("", "C$%s$%d$%d$%d ==.",
                        FileBaseName (ic->filename), ic->lineno,
                        ic->level, ic->block);
              _G.debugLine = 0;
+             #endif
            }
          if (!options.noCcodeInAsm) {
            emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno, 
@@ -7778,7 +7972,10 @@ genhc08Code (iCode * lic)
          break;
 
        case GET_VALUE_AT_ADDRESS:
-         genPointerGet (ic, hasInc(IC_LEFT(ic),ic,getSize(operandType(IC_RESULT(ic)))));
+         genPointerGet (ic,
+                         hasInc (IC_LEFT (ic), ic,
+                                 getSize (operandType (IC_RESULT (ic)))),
+                         ifxForOp (IC_RESULT (ic), ic) );
          break;
 
        case '=':
@@ -7833,17 +8030,19 @@ genhc08Code (iCode * lic)
        }
 
       if (!hc08_reg_a->isFree)
-        emitcode("","; forgot to free a");
+        D(emitcode("","; forgot to free a"));
       if (!hc08_reg_x->isFree)
-        emitcode("","; forgot to free x");
+        D(emitcode("","; forgot to free x"));
       if (!hc08_reg_h->isFree)
-        emitcode("","; forgot to free h");
+        D(emitcode("","; forgot to free h"));
       if (!hc08_reg_hx->isFree)
-        emitcode("","; forgot to free hx");
+        D(emitcode("","; forgot to free hx"));
       if (!hc08_reg_xa->isFree)
-        emitcode("","; forgot to free xa");
+        D(emitcode("","; forgot to free xa"));
     }
 
+  debugFile->writeFrameAddress (NULL, NULL, 0);  /* have no idea where frame is now */
+    
 
   /* now we are ready to call the
      peep hole optimizer */