* src/SDCCpeeph.c (replaceRule): support empty replacement peephole
[fw/sdcc] / src / hc08 / gen.c
index 12a0982cf362782cbc708af03a466d44c7f08f21..1cf7271ceac429489c6ab9d5bd166d06c66a00da 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>
@@ -211,8 +211,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;
@@ -543,8 +543,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 +558,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 +568,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 +579,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 +589,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 +702,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 +728,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 +762,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 +845,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 +948,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 +1078,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 +1160,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 +1246,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));
    }
@@ -1352,7 +1362,7 @@ static asmop *
 aopForRemat (symbol * sym)
 {
   iCode *ic = sym->rematiCode;
-  asmop *aop = newAsmop (AOP_IMMD);
+  asmop *aop = NULL;
   int ptr_type=0;
   int val = 0;
 
@@ -1377,22 +1387,40 @@ aopForRemat (symbol * sym)
       ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
     }
 
-  if (val)
-    sprintf (buffer, "(%s %c 0x%04x)",
-            OP_SYMBOL (IC_LEFT (ic))->rname,
-            val >= 0 ? '+' : '-',
-            abs (val) & 0xffff);
-  else
-    strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
+  if (ic->op == ADDRESS_OF)
+    {
+      if (val)
+        sprintf (buffer, "(%s %c 0x%04x)",
+                OP_SYMBOL (IC_LEFT (ic))->rname,
+                val >= 0 ? '+' : '-',
+                abs (val) & 0xffff);
+      else
+        strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
 
-  aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1);
-  strcpy (aop->aopu.aop_immd.aop_immd1, buffer);
-  /* set immd2 field if required */
-  if (aop->aopu.aop_immd.from_cast_remat) {
+      aop = newAsmop (AOP_IMMD);
+      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);
-  }
+       }
+    }
+  else if (ic->op == '=')
+    {
+      val += (int) operandLitValue (IC_RIGHT (ic));
+      val &= 0xffff;
+      sprintf (buffer, "0x%04x", val);
+      aop = newAsmop (AOP_LIT);
+      aop->aopu.aop_lit = constVal (buffer);
+    }
+  else
+    werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+           "unexpected rematerialization");
+
+
 
   return aop;
 }
@@ -1671,27 +1699,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;
     }
 
@@ -1732,7 +1760,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++)
@@ -1774,7 +1802,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)
     {
     
@@ -1853,6 +1881,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);
@@ -1902,7 +1933,7 @@ aopAdrStr (asmop * aop, int loffset, bool bit16)
 
     case AOP_LIT:
       if (bit16)
-        return aopLiteralLong (aop->aopu.aop_lit, loffset, 2);
+        return aopLiteralLong (aop->aopu.aop_lit, /*loffset*/ 0, 2);
       else
         return aopLiteral (aop->aopu.aop_lit, loffset);
 
@@ -2272,6 +2303,7 @@ genUminus (iCode * ic)
   sym_link *optype, *rtype;
   char *sub;
   bool needpula;
+  asmop *result;
 
   D(emitcode (";     genUminus",""));
 
@@ -2295,7 +2327,10 @@ genUminus (iCode * ic)
 
   if (size == 1)
     {
-      needpula = pushRegIfUsed (hc08_reg_a);
+      if (!IS_AOP_A (AOP (IC_LEFT (ic))))
+        needpula = pushRegIfUsed (hc08_reg_a);
+      else
+        needpula = FALSE;
       loadRegFromAop (hc08_reg_a, AOP( IC_LEFT (ic)), 0);
       emitcode ("nega", "");
       hc08_freeReg (hc08_reg_a);
@@ -2305,18 +2340,26 @@ genUminus (iCode * ic)
     }
   else
     {
+      if (IS_AOP_XA (AOP (IC_RESULT (ic))))
+        result = forceStackedAop (AOP (IC_RESULT (ic)));
+      else
+        result = AOP (IC_RESULT (ic));
+       
       needpula = pushRegIfUsed (hc08_reg_a);
       sub="sub";
       while (size--)
         {
           loadRegFromConst (hc08_reg_a, zero);
           accopWithAop (sub, AOP( IC_LEFT (ic)), offset);
-          storeRegToAop (hc08_reg_a, AOP( IC_RESULT (ic)), offset++);
+          storeRegToAop (hc08_reg_a, result, offset++);
           sub = "sbc";
         }
-        storeRegSignToUpperAop (hc08_reg_a, AOP( IC_RESULT (ic)), offset, 
+        storeRegSignToUpperAop (hc08_reg_a, result, offset, 
                                 SPEC_USIGN (operandType (IC_LEFT (ic))));
       pullOrFreeReg (hc08_reg_a, needpula);
+      
+      if (IS_AOP_XA (AOP (IC_RESULT (ic))))
+        freeAsmop (NULL, result, ic, TRUE);
     }
 
 
@@ -2324,7 +2367,7 @@ genUminus (iCode * ic)
 release:
   /* release the aops */
   freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
-  freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+  freeAsmop (IC_LEFT (ic), NULL, ic, FALSE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -3111,15 +3154,23 @@ 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) )
       )
       && (icount>=-128) && (icount<=127) && (size==2))
     {
-      needpulx = pushRegIfUsed (hc08_reg_x);
-      needpulh = pushRegIfUsed (hc08_reg_h);
+      if (!IS_AOP_HX (AOP (left)))
+        {
+          needpulx = pushRegIfUsed (hc08_reg_x);
+          needpulh = pushRegIfUsed (hc08_reg_h);
+        }
+      else
+        {
+          needpulx = FALSE;
+          needpulh = FALSE;
+        }
       loadRegFromAop (hc08_reg_hx, AOP(left), 0);
       emitcode ("aix","#%d", icount);
       hc08_dirtyReg (hc08_reg_hx, FALSE);
@@ -3129,8 +3180,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;
@@ -3152,7 +3203,10 @@ genPlusIncr (iCode * ic)
     }
   else
     {
-      needpula = pushRegIfUsed (hc08_reg_a);
+      if (!IS_AOP_A (AOP (result)) && !IS_AOP_XA (AOP (result)))
+        needpula = pushRegIfUsed (hc08_reg_a);
+      else
+        needpula = FALSE;
       loadRegFromAop (hc08_reg_a, AOP (result), 0);
       accopWithAop ("add", AOP (IC_RIGHT (ic)), 0);
       hc08_useReg (hc08_reg_a);
@@ -3211,9 +3265,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));
 
@@ -3269,8 +3323,16 @@ genMinusDec (iCode * ic)
   if ((AOP_TYPE (left) == AOP_DIR) && (AOP_TYPE (result) == AOP_DIR)
       && (icount>=-127) && (icount<=128) && (size==2))
     {
-      needpulx = pushRegIfUsed (hc08_reg_x);
-      needpulh = pushRegIfUsed (hc08_reg_h);
+      if (!IS_AOP_HX (AOP (left)))
+        {
+          needpulx = pushRegIfUsed (hc08_reg_x);
+          needpulh = pushRegIfUsed (hc08_reg_h);
+        }
+      else
+        {
+          needpulx = FALSE;
+          needpulh = FALSE;
+        }
       loadRegFromAop (hc08_reg_hx, AOP(left), 0);
       emitcode ("aix","#%d", -icount);
       hc08_dirtyReg (hc08_reg_hx, FALSE);
@@ -3378,7 +3440,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;
@@ -3399,13 +3461,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);
@@ -3420,7 +3484,7 @@ genMultOneByte (operand * left,
   // we have to do a signed multiply
 
 
-  //emitcode (";", "signed");
+  //D(emitcode (";", "signed"));
   adjustStack (-1);
   emitcode ("clr", "1,s");
 
@@ -3862,8 +3926,7 @@ genCmp (operand * left, operand * right,
            }
          else
            {
-              needpula = pushRegIfUsed (hc08_reg_a);
-             loadRegFromAop (hc08_reg_a, AOP (left), AOP_SIZE (left) -1);
+             loadRegFromAop (hc08_reg_a, AOP (left), AOP_SIZE (left) -1);
              emitcode ("rola", "");
              hc08_useReg (hc08_reg_a);
            }
@@ -4138,44 +4201,45 @@ 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");
+  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",""));
@@ -4185,9 +4249,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;
@@ -4221,8 +4303,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;
@@ -4462,12 +4562,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 */
@@ -4486,6 +4586,35 @@ genAnd (iCode * ic, iCode * ifx)
       left = tmp;
     }
 
+
+  if (AOP_TYPE (result) == AOP_CRY)
+    {
+      symbol *tlbl;
+      wassertl (ifx, "AOP_CPY result without ifx");
+      
+      tlbl = newiTempLabel (NULL);
+      size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
+      offset = 0;
+      while (size--)
+        {
+          loadRegFromAop (hc08_reg_a, AOP (left), offset);
+          if ((AOP_TYPE (right) == AOP_LIT)
+              && (((lit >> (offset*8)) & 0xff) == 0xff))
+            emitcode ("tsta","");
+          else
+            accopWithAop ("and", AOP (right), offset);
+          hc08_freeReg( hc08_reg_a);      
+          if (size)
+            emitBranch ("bne", tlbl);
+          else
+            {
+              emitLabel (tlbl);
+              genIfxJump (ifx, "a");
+            }
+          offset++;
+        }
+    }
+  
   size = AOP_SIZE (result);
 
   if (AOP_TYPE (right) == AOP_LIT)
@@ -4502,7 +4631,7 @@ genAnd (iCode * ic, iCode * ifx)
           goto release;
         }
     }
-
+    
   offset = 0;
   while (size--)
     {
@@ -4537,12 +4666,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 */
@@ -4561,14 +4690,34 @@ genOr (iCode * ic, iCode * ifx)
       left = tmp;
     }
 
-  /* if right is bit then exchange them */
-  if (AOP_TYPE (right) == AOP_CRY &&
-      AOP_TYPE (left) != AOP_CRY)
+  if (AOP_TYPE (result) == AOP_CRY)
     {
-      operand *tmp = right;
-      right = left;
-      left = tmp;
+      symbol *tlbl;
+      wassertl (ifx, "AOP_CPY result without ifx");
+      
+      tlbl = newiTempLabel (NULL);
+      size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
+      offset = 0;
+      while (size--)
+        {
+          loadRegFromAop (hc08_reg_a, AOP (left), offset);
+          if ((AOP_TYPE (right) == AOP_LIT)
+              && (((lit >> (offset*8)) & 0xff) == 0))
+            emitcode ("tsta","");
+          else
+            accopWithAop ("ora", AOP (right), offset);
+          hc08_freeReg( hc08_reg_a);      
+          if (size)
+            emitBranch ("bne", tlbl);
+          else
+            {
+              emitLabel (tlbl);
+              genIfxJump (ifx, "a");
+            }
+          offset++;
+        }
     }
+  
   if (AOP_TYPE (right) == AOP_LIT)
     lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
 
@@ -4584,8 +4733,6 @@ genOr (iCode * ic, iCode * ifx)
       goto release;
     }
     
-
-
   offset = 0;
   while (size--)
     {
@@ -4619,12 +4766,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 ||
@@ -4644,14 +4791,34 @@ genXor (iCode * ic, iCode * ifx)
       left = tmp;
     }
 
-  /* if right is bit then exchange them */
-  if (AOP_TYPE (right) == AOP_CRY &&
-      AOP_TYPE (left) != AOP_CRY)
+  if (AOP_TYPE (result) == AOP_CRY)
     {
-      operand *tmp = right;
-      right = left;
-      left = tmp;
+      symbol *tlbl;
+      wassertl (ifx, "AOP_CPY result without ifx");
+      
+      tlbl = newiTempLabel (NULL);
+      size = (AOP_SIZE (left) >= AOP_SIZE (right)) ? AOP_SIZE (left) : AOP_SIZE (right);
+      offset = 0;
+      while (size--)
+        {
+          loadRegFromAop (hc08_reg_a, AOP (left), offset);
+          if ((AOP_TYPE (right) == AOP_LIT)
+              && (((lit >> (offset*8)) & 0xff) == 0))
+            emitcode ("tsta","");
+          else
+            accopWithAop ("eor", AOP (right), offset);
+          hc08_freeReg( hc08_reg_a);      
+          if (size)
+            emitBranch ("bne", tlbl);
+          else
+            {
+              emitLabel (tlbl);
+              genIfxJump (ifx, "a");
+            }
+          offset++;
+        }
     }
+    
   if (AOP_TYPE (right) == AOP_LIT)
     lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
 
@@ -4665,7 +4832,6 @@ genXor (iCode * ic, iCode * ifx)
       hc08_freeReg( hc08_reg_a);      
     }
 
-
 //release:
   freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
   freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
@@ -5356,7 +5522,7 @@ XAccRsh (int shCount, bool sign)
       **   rola       1  1        bcde fgh0  0000 000a   0
       **   lslx       1  1        cdef gh00  0000 000a   b
       **   rola       1  1        cdef gh00  0000 00ab   0
-      **   clrx       1  1        0000 0000  0000 000a   0
+      **   clrx       1  1        0000 0000  0000 00ab   0
       ** total: 6 cycles, 6 bytes
       */
       loadRegFromConst (hc08_reg_x, zero);
@@ -5412,12 +5578,12 @@ XAccRsh (int shCount, bool sign)
       ;
     }
 
-  /* lslx/rola is only 2 cycles and bytes, so an unrolled loop is often  */
+  /* lsrx/rora is only 2 cycles and bytes, so an unrolled loop is often  */
   /* the fastest and shortest.                                           */
   for (i=0;i<shCount;i++)
     {
-      rmwWithReg ("lsl", hc08_reg_x);
-      rmwWithReg ("rol", hc08_reg_a);
+      rmwWithReg ("lsr", hc08_reg_x);
+      rmwWithReg ("ror", hc08_reg_a);
     }
 
 }
@@ -5477,8 +5643,14 @@ shiftL2Left2Result (operand * left, int offl,
   bool needpula = FALSE;
   bool needpulx = FALSE;
 
-  needpula = pushRegIfUsed (hc08_reg_a);
-  needpulx = pushRegIfUsed (hc08_reg_x);
+  if (!IS_AOP_XA (AOP (left)) && !IS_AOP_A (AOP (left)))
+    needpula = pushRegIfUsed (hc08_reg_a);
+  else
+    needpula = FALSE;
+  if (!IS_AOP_XA (AOP (left)))
+    needpulx = pushRegIfUsed (hc08_reg_x);
+  else
+    needpulx = FALSE;
 
   loadRegFromAop (hc08_reg_xa, AOP (left), offl);
 
@@ -5780,8 +5952,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)
@@ -6090,8 +6262,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);
@@ -6491,7 +6663,7 @@ genPointerGet (iCode * ic, iCode *pi)
     }
 
   /* special case when cast remat */
-  if (p_type == GPOINTER && OP_SYMBOL(left)->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);
@@ -6633,6 +6805,7 @@ genPackBits (sym_link * etype,
       emitcode ("and", "#0x%02x", mask);
       emitcode ("ora", "1,s");
       emitcode ("sta", ",x");
+      pullReg (hc08_reg_a);
     }
 
   hc08_freeReg (hc08_reg_a);
@@ -7286,28 +7459,47 @@ genReceive (iCode * ic)
 static void
 genDummyRead (iCode * ic)
 {
-  operand *right;
+  operand *op;
   int size, offset;
 
   D(emitcode(";     genDummyRead",""));
 
-  right = IC_RIGHT (ic);
+  op = IC_RIGHT (ic);
+  if (op && IS_SYMOP (op))
+    {
 
-  aopOp (right, ic, FALSE);
+      aopOp (op, ic, FALSE);
 
-  /* bit variables done */
-  /* general case */
-  size = AOP_SIZE (right);
-  offset = 0;
+      size = AOP_SIZE (op);
+      offset = 0;
 
-  while (size--)
+      while (size--)
+        {
+          loadRegFromAop (hc08_reg_a, AOP (op), offset);
+          hc08_freeReg (hc08_reg_a);
+          offset++;
+        }
+
+      freeAsmop (op, NULL, ic, TRUE);
+   }
+  op = IC_LEFT (ic);
+  if (op && IS_SYMOP (op))
     {
-      loadRegFromAop (hc08_reg_a, AOP (right), offset);
-      hc08_freeReg (hc08_reg_a);
-      offset++;
-    }
 
-  freeAsmop (right, NULL, ic, TRUE);
+      aopOp (op, ic, FALSE);
+
+      size = AOP_SIZE (op);
+      offset = 0;
+
+      while (size--)
+        {
+          loadRegFromAop (hc08_reg_a, AOP (op), offset);
+          hc08_freeReg (hc08_reg_a);
+          offset++;
+        }
+
+      freeAsmop (op, NULL, ic, TRUE);
+   }
 }
 
 /*-----------------------------------------------------------------*/
@@ -7691,15 +7883,15 @@ 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"));
     }