* device/lib/_modsint.c,
[fw/sdcc] / src / hc08 / gen.c
index 9f60de19fee3f42678e15669bdb3b8adaf1fbea3..97748e372cf15a0706d62893e6d7b790f3e18d22 100644 (file)
@@ -1352,7 +1352,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 +1377,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;
 }
@@ -1902,7 +1920,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 +2290,7 @@ genUminus (iCode * ic)
   sym_link *optype, *rtype;
   char *sub;
   bool needpula;
+  asmop *result;
 
   D(emitcode (";     genUminus",""));
 
@@ -2295,7 +2314,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 +2327,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 +2354,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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -3118,8 +3148,16 @@ genPlusIncr (iCode * ic)
       )
       && (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);
@@ -3152,7 +3190,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);
@@ -3269,8 +3310,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);
@@ -3402,7 +3451,9 @@ genMultOneByte (operand * left,
       //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");
@@ -3862,8 +3913,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);
            }
@@ -4486,6 +4536,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 +4581,7 @@ genAnd (iCode * ic, iCode * ifx)
           goto release;
         }
     }
-
+    
   offset = 0;
   while (size--)
     {
@@ -4561,14 +4640,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 +4683,6 @@ genOr (iCode * ic, iCode * ifx)
       goto release;
     }
     
-
-
   offset = 0;
   while (size--)
     {
@@ -4644,14 +4741,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 +4782,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 +5472,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 +5528,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 +5593,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);
 
@@ -6633,6 +6755,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 +7409,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);
+   }
 }
 
 /*-----------------------------------------------------------------*/