* sim/ucsim/cmd.src/cmdutil.cc: NUL device is detected as CG_FILE type
[fw/sdcc] / src / hc08 / gen.c
index 1c624bdb7d8daa2e65587944bd6403516433c4ea..8c93b380c85b1083471488e31910cd8b5eb77e86 100644 (file)
 
 -------------------------------------------------------------------------*/
 
-#define D(x)
-//#define D(x) x
+/* Use the D macro for basic (unobtrusive) debugging messages */
+//#define D(x)
+#define D(x) x
+/* Use the DD macro for detailed debugging messages */
+#define DD(x)
+//#define DD(x) x
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -47,6 +51,7 @@ char *aopLiteralLong (value * val, int offset, int size);
 extern int allocInfo;
 static int pushReg (regs *reg, bool freereg);
 static void pullReg (regs *reg);
+static void transferAopAop (asmop *srcaop, int srcofs, asmop *dstaop, int dstofs);
 
 static char *zero = "#0x00";
 static char *one = "#0x01";
@@ -78,7 +83,7 @@ static asmop *hc08_aop_pass[4];
 
 extern int hc08_ptrRegReq;
 extern int hc08_nRegs;
-extern FILE *codeOutFile;
+extern struct dbuf_s *codeOutBuf;
 //static void saveRBank (int, iCode *, bool);
 static bool operandsEqu (operand * op1, operand * op2);
 static void loadRegFromConst (regs *reg, char *c);
@@ -188,6 +193,7 @@ static void
 emitLabel (symbol *tlbl)
 {
   emitcode ("", "%05d$:", (tlbl->key +100));
+  lineCurr->isLabel = 1;
 }
 
 /*-----------------------------------------------------------------*/
@@ -227,7 +233,7 @@ transferRegReg (regs *sreg, regs *dreg, bool freesrc)
       return;
     }
 
-  D(emitcode ("", "; transferRegReg(%s,%s)",
+  DD(emitcode ("", "; transferRegReg(%s,%s)",
             sreg->name, dreg->name));
 
   srcidx = sreg->rIdx;
@@ -598,7 +604,7 @@ loadRegFromAop (regs *reg, asmop *aop, int loffset)
     printf(" reg missing operand link\n");
 #endif
 
-  D(emitcode ("", ";     loadRegFromAop (%s, %s, %d)",
+  DD(emitcode ("", ";     loadRegFromAop (%s, %s, %d)",
             reg->name, aopName (aop), loffset));
        
   /* If operand is volatile, we cannot optimize. */
@@ -613,7 +619,7 @@ loadRegFromAop (regs *reg, asmop *aop, int loffset)
       && (reg->aopofs == loffset))
     {
       hc08_useReg(reg);
-      D(emitcode ("","; already had correct value for %s", reg->name));
+      DD(emitcode ("","; already had correct value for %s", reg->name));
       return;
     }
 
@@ -623,7 +629,7 @@ loadRegFromAop (regs *reg, asmop *aop, int loffset)
       && operandsEqu(hc08_reg_h->aop->op,aop->op)
       && (hc08_reg_h->aopofs == loffset))
     {
-      D(emitcode ("","; found correct value for %s in h", reg->name));
+      DD(emitcode ("","; found correct value for %s in h", reg->name));
       transferRegReg (hc08_reg_h, reg, FALSE);
       hc08_useReg (reg);
       return;
@@ -634,7 +640,7 @@ loadRegFromAop (regs *reg, asmop *aop, int loffset)
       && operandsEqu(hc08_reg_x->aop->op,aop->op)
       && (hc08_reg_x->aopofs == loffset))
     {
-      D(emitcode ("","; found correct value for %s in x", reg->name));
+      DD(emitcode ("","; found correct value for %s in x", reg->name));
       transferRegReg (hc08_reg_x, reg, FALSE);
       hc08_useReg (reg);
       return;
@@ -644,7 +650,7 @@ loadRegFromAop (regs *reg, asmop *aop, int loffset)
       && operandsEqu(hc08_reg_a->aop->op,aop->op)
       && (hc08_reg_a->aopofs == loffset))
     {
-      D(emitcode ("","; found correct value for %s in a", reg->name));
+      DD(emitcode ("","; found correct value for %s in a", reg->name));
       transferRegReg (hc08_reg_a, reg, FALSE);
       hc08_useReg (reg);
       return;
@@ -768,25 +774,51 @@ forceload:
 /*--------------------------------------------------------------------------*/
 /* forceStackedAop - Reserve space on the stack for asmop aop; when         */
 /*                   freeAsmop is called with aop, the stacked data will    */
-/*                   be copied to the original aop location and             */
+/*                   be copied to the original aop location.                */
 /*--------------------------------------------------------------------------*/
 static asmop *
-forceStackedAop (asmop *aop)
+forceStackedAop (asmop *aop, bool copyOrig)
 {
+  regs *reg;
   int loffset;
   asmop *newaop = newAsmop (aop->type);
   memcpy (newaop, aop, sizeof(*newaop));
   
-  D(emitcode("", "; forcedStackAop %s", aopName(aop)));
+  DD(emitcode("", "; forcedStackAop %s", aopName(aop)));
+
+  if (copyOrig && hc08_reg_a->isFree)
+    reg = hc08_reg_a;
+  else if (copyOrig && hc08_reg_x->isFree)
+    reg = hc08_reg_x;
+  else
+    reg = NULL;
   for (loffset=0; loffset < newaop->size; loffset++)
     {
       asmop *aopsof = newAsmop (AOP_SOF);
       aopsof->size = 1;
-      aopsof->aopu.aop_stk = pushReg (hc08_reg_a, FALSE);
+      if (copyOrig && reg)
+        {
+          loadRegFromAop (reg, aop, loffset);
+          aopsof->aopu.aop_stk = pushReg (reg, FALSE);
+        }
+      else
+        {
+          aopsof->aopu.aop_stk = pushReg (hc08_reg_a, FALSE);
+        }
       aopsof->op = aop->op;
       newaop->stk_aop[loffset] = aopsof;
     }
   newaop->stacked = 1;
+
+  if (!reg && copyOrig)
+    {
+      for (loffset=0; loffset < newaop->size; loffset++)
+        {
+         transferAopAop (aop, loffset, newaop, loffset);
+       }
+    }
+
   return newaop;
 }
 
@@ -803,7 +835,7 @@ storeRegToAop (regs *reg, asmop *aop, int loffset)
   int otheridx;
   #endif
 
-  D(emitcode ("", ";     storeRegToAop (%s, %s, %d), stacked=%d, isaddr=%d",
+  DD(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
@@ -839,7 +871,10 @@ storeRegToAop (regs *reg, asmop *aop, int loffset)
 
   if (aop->type == AOP_DUMMY)
     return;
-    
+
+  if (aop->type == AOP_CRY) /* This can only happen if IFX was optimized */
+    return;                 /* away, so just toss the result */
+
   switch (regidx)
     {
       case A_IDX:
@@ -920,19 +955,19 @@ storeRegToAop (regs *reg, asmop *aop, int loffset)
                 && operandsEqu(otherreg->aop->op,aop->op)
                 && (otherreg->aopofs == loffset))
               {
-                D(emitcode("","; marking %s stale", otherreg->name));
+                DD(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;
-          D(emitcode("","; marking hx stale"));
+          DD(emitcode("","; marking hx stale"));
         }
       if ((!hc08_reg_x->aop || !hc08_reg_a->aop) && hc08_reg_xa->aop)
         {
           hc08_reg_xa->aop = NULL;
-          D(emitcode("","; marking xa stale"));
+          DD(emitcode("","; marking xa stale"));
         }
     
       reg->aop = aop;
@@ -1144,7 +1179,8 @@ transferAopAop (asmop *srcaop, int srcofs, asmop *dstaop, int dstofs)
   /* ignore transfers at the same byte, unless its volatile */
   if (srcaop->op && !isOperandVolatile (srcaop->op, FALSE)
       && dstaop->op && !isOperandVolatile (dstaop->op, FALSE)
-      && operandsEqu(srcaop->op, dstaop->op) && srcofs == dstofs)
+      && operandsEqu(srcaop->op, dstaop->op) && srcofs == dstofs
+      && dstaop->type == srcaop->type)
     return;
       
   if (srcaop->stacked && srcaop->stk_aop[srcofs])
@@ -1159,10 +1195,10 @@ transferAopAop (asmop *srcaop, int srcofs, asmop *dstaop, int dstofs)
       return;
     }
 
-//  D(emitcode ("", "; transferAopAop (%s, %d, %s, %d)",
+//  DD(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));
+//  DD(emitcode ("", "; srcaop->type = %d", srcaop->type));
+//  DD(emitcode ("", "; dstaop->type = %d", dstaop->type));
   
   if (dstofs >= dstaop->size)
     return;
@@ -1798,14 +1834,22 @@ aopOp (operand * op, iCode * ic, bool result)
       /* else spill location  */
       if (sym->usl.spillLoc)
         {
+          asmop *oldAsmOp = NULL;
+
           if (sym->usl.spillLoc->aop
               && sym->usl.spillLoc->aop->size != getSize (sym->type))
             {
              /* force a new aop if sizes differ */
+              oldAsmOp = sym->usl.spillLoc->aop;
              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->size != getSize (sym->type))
+            {
+              /* Don't reuse the new aop, go with the last one */
+              sym->usl.spillLoc->aop = oldAsmOp;
+            }
          aop->size = getSize (sym->type);
          aop->op = op;
          aop->isaddr = op->isaddr;
@@ -1857,7 +1901,7 @@ freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
       int stackAdjust;
       int loffset;
 
-      D(emitcode ("","; freeAsmop restoring stacked %s", aopName(aop)));
+      DD(emitcode ("","; freeAsmop restoring stacked %s", aopName(aop)));
       aop->stacked = 0;
       stackAdjust = 0;
       for (loffset=0; loffset<aop->size; loffset++)
@@ -1899,7 +1943,7 @@ aopDerefAop (asmop *aop)
   sym_link *type, *etype;
   int p_type;
   
-  D(emitcode ("", ";     aopDerefAop(%s)", aopName(aop)));
+  DD(emitcode ("", ";     aopDerefAop(%s)", aopName(aop)));
   if (aop->op)
     {
     
@@ -2144,7 +2188,7 @@ asmopToBool (asmop *aop, bool resultInA)
             emitcode ("tsta", "");
             emitcode ("bne", "%05d$", (tlbl->key + 100));
             emitcode ("tstx", "");
-            emitcode ("", "%05d$:", (tlbl->key + 100));
+            emitLabel (tlbl);
           }
         else
           {
@@ -2169,6 +2213,14 @@ asmopToBool (asmop *aop, bool resultInA)
             flagsonly = FALSE;
           }
         break;
+      case AOP_LIT:
+        /* Higher levels should optimize this case away but let's be safe */
+        if ((unsigned long) floatFromVal (aop->aopu.aop_lit))
+          loadRegFromConst (hc08_reg_a, one);
+        else
+          loadRegFromConst (hc08_reg_a, zero);
+        hc08_freeReg(hc08_reg_a);
+        break;
       default:
         if (size==1)
           {
@@ -2197,7 +2249,7 @@ asmopToBool (asmop *aop, bool resultInA)
                 emitcode ("tst", "%s", aopAdrStr (aop, 0, FALSE));
                 emitcode ("bne", "%05d$", (tlbl->key + 100));
                 emitcode ("tst", "%s", aopAdrStr (aop, 1, FALSE));
-                emitcode ("", "%05d$:", (tlbl->key + 100));
+                emitLabel (tlbl);
                 break;
               }
           }
@@ -2374,7 +2426,7 @@ genUminus (iCode * ic)
   else
     {
       if (IS_AOP_XA (AOP (IC_RESULT (ic))))
-        result = forceStackedAop (AOP (IC_RESULT (ic)));
+        result = forceStackedAop (AOP (IC_RESULT (ic)), FALSE);
       else
         result = AOP (IC_RESULT (ic));
        
@@ -2715,6 +2767,8 @@ genPcall (iCode * ic)
   emitBranch ("bsr", tlbl);
   emitBranch ("bra", rlbl);
   emitLabel (tlbl);
+  _G.stackPushes += 2; /* account for the bsr return address now on stack */
+  updateCFA();
 
   /* Push the function's address */
   aopOp (IC_LEFT (ic), ic, FALSE);
@@ -2733,6 +2787,8 @@ genPcall (iCode * ic)
   emitcode ("rts", "");
 
   emitLabel (rlbl);
+  _G.stackPushes -= 4; /* account for rts here & in called function */
+  updateCFA();
 
 
   /* if we need assign a result value */
@@ -2783,12 +2839,6 @@ resultRemat (iCode * ic)
   return 0;
 }
 
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
-#endif
-
 /*-----------------------------------------------------------------*/
 /* inExcludeList - return 1 if the string is in exclude Reg list   */
 /*-----------------------------------------------------------------*/
@@ -2830,6 +2880,7 @@ genFunction (iCode * ic)
   emitcode (";", "-----------------------------------------");
 
   emitcode ("", "%s:", sym->rname);
+  lineCurr->isLabel = 1;
   ftype = operandType (IC_LEFT (ic));
   
   _G.stackOfs = 0;
@@ -3110,7 +3161,7 @@ genLabel (iCode * ic)
          
   debugFile->writeLabel(IC_LABEL (ic), ic);
 
-  emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
+  emitLabel (IC_LABEL (ic));
 
 }
 
@@ -3184,7 +3235,7 @@ genPlusIncr (iCode * ic)
 
   icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
 
-  D(emitcode ("", "; IS_AOP_HX = %d", IS_AOP_HX (AOP (left))));
+  DD(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) )
@@ -3210,7 +3261,7 @@ genPlusIncr (iCode * ic)
       return TRUE;
     }
 
-  D(emitcode ("", "; icount = %d, sameRegs=%d", icount, 
+  DD(emitcode ("", "; icount = %d, sameRegs=%d", icount, 
             sameRegs (AOP (left), AOP (result))));
   
   if ((icount > 255) || (icount<0))
@@ -3295,9 +3346,9 @@ genPlus (iCode * ic)
   if (genPlusIncr (ic) == TRUE)
     goto release;
 
-  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))));
+  DD(emitcode("",";  left size = %d", getDataSize (IC_LEFT(ic))));
+  DD(emitcode("",";  right size = %d", getDataSize (IC_RIGHT(ic))));
+  DD(emitcode("",";  result size = %d", getDataSize (IC_RESULT(ic))));
   
   size = getDataSize (IC_RESULT (ic));
 
@@ -3528,7 +3579,7 @@ genMultOneByte (operand * left,
       || (lUnsigned && rUnsigned))
     {
       // just an unsigned 8*8=8/16 multiply
-      //D(emitcode (";","unsigned"));
+      //DD(emitcode (";","unsigned"));
 
       loadRegFromAop (hc08_reg_a, AOP (left), 0);
       loadRegFromAop (hc08_reg_x, AOP (right), 0);
@@ -4566,19 +4617,19 @@ genPointerGetSetOfs (iCode *ic)
   asmop *derefaop;
 
   /* Make sure we have a next iCode */
-  D(emitcode("","; checking lic"));
+  DD(emitcode("","; checking lic"));
   if (!lic)
     return FALSE;
 
   /* Make sure the result of the addition is an iCode */
-  D(emitcode("","; checking IS_ITEMP"));
+  DD(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);
-  D(emitcode("","; pset=%d, pget=%d",pset,pget));
+  DD(emitcode("","; pset=%d, pget=%d",pset,pget));
   if (!pset && !pget)
     return FALSE;
 
@@ -4586,25 +4637,25 @@ genPointerGetSetOfs (iCode *ic)
   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
     return FALSE;
     
-  D(emitcode("", "; checking pset operandsEqu"));
+  DD(emitcode("", "; checking pset operandsEqu"));
   if (pset & !operandsEqu (IC_RESULT (ic), IC_RESULT (lic)))
     return FALSE;
 
-  D(emitcode("", "; checking pget operandsEqu"));
+  DD(emitcode("", "; checking pget operandsEqu"));
   if (pget & !operandsEqu (IC_RESULT (ic), IC_LEFT (lic)))
     return FALSE;
 
-  D(emitcode("", "; checking IS_SYMOP"));
+  DD(emitcode("", "; checking IS_SYMOP"));
   if (!IS_SYMOP (IC_LEFT (ic)))
     return FALSE;
 
-  D(emitcode("", "; checking !IS_TRUE_SYMOP"));
+  DD(emitcode("", "; checking !IS_TRUE_SYMOP"));
   if (IS_TRUE_SYMOP (IC_LEFT (ic)))
     return FALSE;
 
   sym = OP_SYMBOL (IC_LEFT (ic));
   
-  D(emitcode("", "; checking remat"));
+  DD(emitcode("", "; checking remat"));
   if (!sym->remat)
     return FALSE;
     
@@ -4929,10 +4980,10 @@ genAnd (iCode * ic, iCode * ifx)
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
 
 #ifdef DEBUG_TYPE
-  D(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+  DD(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
            AOP_TYPE (result),
            AOP_TYPE (left), AOP_TYPE (right)));
-  D(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
+  DD(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
            AOP_SIZE (result),
            AOP_SIZE (left), AOP_SIZE (right)));
 #endif
@@ -5093,10 +5144,10 @@ genOr (iCode * ic, iCode * ifx)
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
 
 #ifdef DEBUG_TYPE
-  D(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+  DD(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
            AOP_TYPE (result),
            AOP_TYPE (left), AOP_TYPE (right)));
-  D(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
+  DD(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
            AOP_SIZE (result),
            AOP_SIZE (left), AOP_SIZE (right)));
 #endif
@@ -5252,10 +5303,10 @@ genXor (iCode * ic, iCode * ifx)
   aopOp ((result = IC_RESULT (ic)), ic, TRUE);
 
 #ifdef DEBUG_TYPE
-  D(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
+  DD(emitcode ("", "; Type res[%d] = l[%d]&r[%d]",
            AOP_TYPE (result),
            AOP_TYPE (left), AOP_TYPE (right)));
-  D(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
+  DD(emitcode ("", "; Size res[%d] = l[%d]&r[%d]",
            AOP_SIZE (result),
            AOP_SIZE (left), AOP_SIZE (right)));
 #endif
@@ -6289,7 +6340,7 @@ genlshTwo (operand * result, operand * left, int shCount)
 
 /*-----------------------------------------------------------------*/
 /* shiftLLong - shift left one long from left to result            */
-/* offl = LSB or MSB16                                             */
+/* offr = LSB or MSB16                                             */
 /*-----------------------------------------------------------------*/
 static void
 shiftLLong (operand * left, operand * result, int offr)
@@ -6306,10 +6357,10 @@ shiftLLong (operand * left, operand * result, int offr)
   loadRegFromAop (hc08_reg_xa, AOP (left), LSB);
   rmwWithReg ("lsl", hc08_reg_a);
   rmwWithReg ("rol", hc08_reg_x);
-  storeRegToAop (hc08_reg_xa, AOP (result), offr);
 
   if (offr==LSB)
     {
+      storeRegToAop (hc08_reg_xa, AOP (result), offr);
       loadRegFromAop (hc08_reg_xa, AOP (left), MSB24);
       rmwWithReg ("rol", hc08_reg_a);
       rmwWithReg ("rol", hc08_reg_x);
@@ -6317,7 +6368,9 @@ shiftLLong (operand * left, operand * result, int offr)
     }
   else if (offr==MSB16)
     {
+      storeRegToAop (hc08_reg_a, AOP (result), offr);
       loadRegFromAop (hc08_reg_a, AOP (left), MSB24);
+      storeRegToAop (hc08_reg_x, AOP (result), offr+1);
       rmwWithReg ("rol", hc08_reg_a);
       storeRegToAop (hc08_reg_a, AOP (result), offr+2);
       storeConstToAop (zero, AOP (result), 0);
@@ -6447,7 +6500,7 @@ genLeftShiftLiteral (operand * left,
   size = AOP_SIZE (result);
 
 #if VIEW_SIZE
-  D(emitcode ("; shift left ", "result %d, left %d", size,
+  DD(emitcode ("; shift left ", "result %d, left %d", size,
            AOP_SIZE (left)));
 #endif
 
@@ -6495,9 +6548,8 @@ genLeftShift (iCode * ic)
   operand *left, *right, *result;
   int size, offset;
   symbol *tlbl, *tlbl1;
-//  int i;
   char *shift;
-  regs *reg;
+  asmop *aopResult;
 
   D(emitcode (";     genLeftShift",""));
 
@@ -6516,38 +6568,41 @@ genLeftShift (iCode * ic)
     }
 
   /* shift count is unknown then we have to form
-     a loop get the loop count in A : Note: we take
+     a loop get the loop count in X : Note: we take
      only the lower order byte since shifting
      more that 32 bits make no sense anyway, ( the
      largest size of an object can be only 32 bits ) */
 
-  aopOp (left, ic, FALSE);
   aopOp (result, ic, FALSE);
+  aopOp (left, ic, FALSE);
+  aopResult = AOP (result);
+
+  if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result))
+      || isOperandVolatile (result, FALSE)) 
+    aopResult = forceStackedAop (AOP (result), sameRegs ( AOP (left), AOP (result)));
 
   /* now move the left to the result if they are not the
      same */
-  if (!sameRegs (AOP (left), AOP (result)))
+  if (!sameRegs (AOP (left), aopResult))
     {
-
       size = AOP_SIZE (result);
       offset = 0;
       while (size--)
        {
-         transferAopAop (AOP (left), offset, AOP (result), offset);
+         transferAopAop (AOP (left), offset, aopResult, offset);
          offset++;
        }
     }
   freeAsmop (left, NULL, ic, TRUE);
+  AOP (result) = aopResult;
   
   tlbl = newiTempLabel (NULL);
   size = AOP_SIZE (result);
   offset = 0;
   tlbl1 = newiTempLabel (NULL);
 
-  reg = hc08_reg_a;
-
-  loadRegFromAop (reg, AOP (right), 0);
-  freeAsmop (right, NULL, ic, TRUE);
+  loadRegFromAop (hc08_reg_x, AOP (right), 0);
+  emitcode ("tstx", "");
   emitBranch ("beq", tlbl1);
   emitLabel (tlbl);
   
@@ -6557,12 +6612,13 @@ genLeftShift (iCode * ic)
       rmwWithAop (shift, AOP (result), offset);  
       shift="rol";
     }
-  rmwWithReg ("dec", reg);
+  rmwWithReg ("dec", hc08_reg_x);
   emitBranch ("bne", tlbl);
   emitLabel (tlbl1);
-  hc08_freeReg (reg);
+  hc08_freeReg (hc08_reg_x);
   
   freeAsmop (result, NULL, ic, TRUE);
+  freeAsmop (right, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -6639,6 +6695,7 @@ shiftRLong (operand * left, int offl,
         rmwWithReg ("lsr", hc08_reg_x);
       rmwWithReg ("ror", hc08_reg_a);
       storeRegToAop (hc08_reg_xa, AOP (result), MSB24);
+      loadRegFromAop (hc08_reg_xa, AOP (left), LSB);
     }
   else if (offl==MSB16)
     {
@@ -6647,15 +6704,27 @@ shiftRLong (operand * left, int offl,
         rmwWithReg ("asr", hc08_reg_a);
       else
         rmwWithReg ("lsr", hc08_reg_a);
+      loadRegFromAop (hc08_reg_x, AOP (left), MSB24);
       storeRegToAop (hc08_reg_a, AOP (result), MSB24);
-      storeRegSignToUpperAop (hc08_reg_a, AOP (result), MSB32, sign);
+      loadRegFromAop (hc08_reg_a, AOP (left), MSB16);
     }
 
-  loadRegFromAop (hc08_reg_xa, AOP (left), offl);
   rmwWithReg ("ror", hc08_reg_x);
   rmwWithReg ("ror", hc08_reg_a);
   storeRegToAop (hc08_reg_xa, AOP (result), LSB);
 
+  if (offl==MSB16)
+    {
+      if (sign)
+        {
+          loadRegFromAop (hc08_reg_a, AOP (left), MSB24);
+          storeRegSignToUpperAop (hc08_reg_a, AOP (result), MSB32, sign);
+        }
+      else
+        {
+          storeConstToAop (zero, AOP (result), MSB32);
+        }
+    }
 
   pullOrFreeReg (hc08_reg_x, needpulx);
   pullOrFreeReg (hc08_reg_a, needpula);
@@ -6759,7 +6828,7 @@ genRightShiftLiteral (operand * left,
   aopOp (result, ic, FALSE);
 
 #if VIEW_SIZE
-  D(emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
+  DD(emitcode ("; shift right ", "result %d, left %d", AOP_SIZE (result),
            AOP_SIZE (left)));
 #endif
 
@@ -6814,10 +6883,10 @@ genRightShift (iCode * ic)
   operand *right, *left, *result;
   sym_link *retype;
   int size, offset;
-//  char *l;
   symbol *tlbl, *tlbl1;
   char *shift;
   bool sign;
+  asmop *aopResult;
   
   D(emitcode (";     genRightShift",""));
 
@@ -6853,19 +6922,28 @@ genRightShift (iCode * ic)
      more that 32 bits make no sense anyway, ( the
      largest size of an object can be only 32 bits ) */
 
-  aopOp (left, ic, FALSE);
   aopOp (result, ic, FALSE);
+  aopOp (left, ic, FALSE);
+  aopResult = AOP (result);
 
-  if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result)))
-    AOP (result) = forceStackedAop (AOP (result));
-  
-  size = AOP_SIZE (result); 
-  offset = size-1;
-  while (size--)
+  if (sameRegs(AOP (right), AOP (result)) || IS_AOP_XA (AOP (result))
+      || isOperandVolatile (result, FALSE)) 
+    aopResult = forceStackedAop (AOP (result), sameRegs ( AOP (left), AOP (result)));
+
+  /* now move the left to the result if they are not the
+     same */
+  if (!sameRegs (AOP (left), aopResult))
     {
-      transferAopAop (AOP (left), offset, AOP (result), offset);
-      offset--;
+      size = AOP_SIZE (result);
+      offset = 0;
+      while (size--)
+       {
+         transferAopAop (AOP (left), offset, aopResult, offset);
+         offset++;
+       }
     }
+  freeAsmop (left, NULL, ic, TRUE);
+  AOP (result) = aopResult;
   
   tlbl = newiTempLabel (NULL);
   size = AOP_SIZE (result);
@@ -6874,8 +6952,9 @@ genRightShift (iCode * ic)
 
   loadRegFromAop (hc08_reg_x, AOP (right), 0);
   emitcode ("tstx", "");
-  emitcode ("beq", "%05d$", tlbl1->key + 100);
-  emitcode ("", "%05d$:", tlbl->key + 100);
+  emitBranch ("beq", tlbl1);
+  emitLabel (tlbl);
+
   shift= sign ? "asr" : "lsr";
   for (offset=size-1;offset>=0;offset--)
     {
@@ -6883,11 +6962,11 @@ genRightShift (iCode * ic)
       shift="ror";
     }
   rmwWithReg ("dec", hc08_reg_x);
-  emitcode ("bne","%05d$", tlbl->key + 100);
-  emitcode ("", "%05d$:", tlbl1->key + 100);
+  emitBranch ("bne", tlbl);
+  emitLabel (tlbl1);
+  hc08_freeReg (hc08_reg_x);
   
   freeAsmop (result, NULL, ic, TRUE);
-  freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (right, NULL, ic, TRUE);
 }
 
@@ -7695,6 +7774,30 @@ genIfx (iCode * ic, iCode * popIc)
 
   aopOp (cond, ic, FALSE);
 
+  /* If the condition is a literal, we can just do an unconditional */
+  /* branch or no branch */
+  if (AOP_TYPE (cond) == AOP_LIT)
+    {
+      unsigned long lit = (unsigned long) floatFromVal (AOP (cond)->aopu.aop_lit);
+      freeAsmop (cond, NULL, ic, TRUE);
+
+      /* if there was something to be popped then do it */
+      if (popIc)
+        genIpop (popIc);
+      if (lit)
+        {
+          if (IC_TRUE (ic))
+            emitBranch ("jmp", IC_TRUE (ic));
+        }
+      else
+        {
+          if (IC_FALSE (ic))
+            emitBranch ("jmp", IC_FALSE (ic));
+        }
+      ic->generated = 1;
+      return;
+    }
+
   /* get the value into acc */
   if (AOP_TYPE (cond) != AOP_CRY)
     asmopToBool (AOP (cond), FALSE);
@@ -7737,11 +7840,21 @@ genAddrOf (iCode * ic)
      variable */
   if (sym->onStack)
     {
-      /* if it has an offset then we need to compute
-         it */
+      /* if it has an offset then we need to compute it */
+      offset = _G.stackOfs + _G.stackPushes + sym->stack;
       hc08_useReg (hc08_reg_hx);
       emitcode ("tsx", "");
-      emitcode ("aix", "#%d", _G.stackOfs + _G.stackPushes +sym->stack);
+      while (offset > 127)
+        {
+          emitcode ("aix", "#127");
+          offset -= 127;
+        }
+      while (offset < -128)
+        {
+          emitcode ("aix", "#-128");
+          offset += 128;
+        }
+      emitcode ("aix", "#%d", offset);
       storeRegToFullAop (hc08_reg_hx, AOP (IC_RESULT (ic)), FALSE);
       hc08_freeReg (hc08_reg_hx);
 
@@ -8227,7 +8340,7 @@ genhc08Code (iCode * lic)
 
   /* print the allocation information */
   if (allocInfo && currFunc)
-    printAllocInfo (currFunc, codeOutFile);
+    printAllocInfo (currFunc, codeOutBuf);
   /* if debug information required */
   if (options.debug && currFunc)
     {
@@ -8299,13 +8412,16 @@ genhc08Code (iCode * lic)
       if (options.iCodeInAsm) {
        char regsInUse[80];
        int i;
+        char *iLine;
 
        for (i=0; i<6; i++) {
          sprintf (&regsInUse[i],
                   "%c", ic->riu & (1<<i) ? i+'0' : '-'); 
        }
        regsInUse[i]=0;
+        iLine = printILine(ic);
        emitcode("", "; [%s] ic:%d: %s", regsInUse, ic->seq, printILine(ic));
+        dbuf_free(iLine);
       }
       /* if the result is marked as
          spilt and rematerializable or code for
@@ -8558,15 +8674,15 @@ genhc08Code (iCode * lic)
        }
 
       if (!hc08_reg_a->isFree)
-        D(emitcode("","; forgot to free a"));
+        DD(emitcode("","; forgot to free a"));
       if (!hc08_reg_x->isFree)
-        D(emitcode("","; forgot to free x"));
+        DD(emitcode("","; forgot to free x"));
       if (!hc08_reg_h->isFree)
-        D(emitcode("","; forgot to free h"));
+        DD(emitcode("","; forgot to free h"));
       if (!hc08_reg_hx->isFree)
-        D(emitcode("","; forgot to free hx"));
+        DD(emitcode("","; forgot to free hx"));
       if (!hc08_reg_xa->isFree)
-        D(emitcode("","; forgot to free xa"));
+        DD(emitcode("","; forgot to free xa"));
     }
 
   debugFile->writeFrameAddress (NULL, NULL, 0);  /* have no idea where frame is now */
@@ -8578,6 +8694,6 @@ genhc08Code (iCode * lic)
     peepHole (&lineHead);
 
   /* now do the actual printing */
-  printLine (lineHead, codeOutFile);
+  printLine (lineHead, codeOutBuf);
   return;
 }