* src/mcs51/gen.c, src/z80/gen.c, src/hc08/gen.c, src/ds390/gen.c,
[fw/sdcc] / src / ds390 / gen.c
index 8baf0d171d1e371cb79070ad235911edd7b79e72..0d90d01ed3e5200cc83458a8b18b060ec12ddf2e 100644 (file)
@@ -1668,6 +1668,52 @@ aopGet (operand * oper,
   return NULL;  // not reached, but makes compiler happy.
 }
 
+/*-----------------------------------------------------------------*/
+/* aopPutUsesAcc - indicates ahead of time whether aopPut() will   */
+/*                 clobber the accumulator                         */
+/*-----------------------------------------------------------------*/
+static bool
+aopPutUsesAcc (operand * oper, const char *s, int offset)
+{
+  asmop * aop = AOP (oper);
+
+  if (offset > (aop->size - 1))
+    return FALSE;
+
+  switch (aop->type)
+    {
+    case AOP_DUMMY:
+      return TRUE;
+    case AOP_DIR:
+      return FALSE;
+    case AOP_REG:
+      wassert(strcmp(aop->aopu.aop_reg[offset]->name, "a"));
+      return FALSE;
+    case AOP_DPTRn:
+      return FALSE;
+    case AOP_DPTR:
+    case AOP_DPTR2:
+      return TRUE;
+    case AOP_R0:
+    case AOP_R1:
+      return ((aop->paged) || (*s == '@'));
+    case AOP_STK:
+      return (*s == '@');
+    case AOP_CRY:
+      return (!aop->aopu.aop_dir || strcmp(s, aop->aopu.aop_dir));
+    case AOP_STR:
+      return FALSE;
+    case AOP_IMMD:
+      return FALSE;
+    case AOP_ACC:
+      return FALSE;
+    default:
+      /* Error case --- will have been caught already */
+      wassert(0);
+      return FALSE;
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* aopPut - puts a string for a aop and indicates if acc is in use */
 /*-----------------------------------------------------------------*/
@@ -1872,7 +1918,7 @@ aopPut (operand * result, const char *s, int offset)
     case AOP_CRY:
       // destination is carry for return-use-only
       d = (IS_OP_RUONLY (result)) ? "c" : aop->aopu.aop_dir;
-      
+
       // source is no literal and not in carry
       if ((s != zero) && (s != one) && strcmp (s, "c"))
         {
@@ -2850,7 +2896,7 @@ unsaveRBank (int bank, iCode * ic, bool popPsw)
       if (!ic)
         {
           /* Assume r0 is available for use. */
-          r = REG_WITH_INDEX (R0_IDX);;
+          r = REG_WITH_INDEX (R0_IDX);
         }
       else
         {
@@ -7783,7 +7829,7 @@ genOr (iCode * ic, iCode * ifx)
           // result = 1
           if (size)
             emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
-          else
+          else if(ifx)
             continueIfTrue (ifx);
           goto release;
         }
@@ -7801,7 +7847,7 @@ genOr (iCode * ic, iCode * ifx)
               emitLabel (tlbl);
             }
           else
-            {
+            { /* FIXME, thats pretty fishy, check for ifx!=0, testcase .. */
               genIfxJump (ifx, "a", ic->next);
               goto release;
             }
@@ -11937,6 +11983,7 @@ genAddrOf (iCode * ic)
 {
   symbol *sym = OP_SYMBOL (IC_LEFT (ic));
   int size, offset;
+  bool pushedA = FALSE;
 
   D (emitcode (";", "genAddrOf"));
 
@@ -11977,7 +12024,14 @@ genAddrOf (iCode * ic)
 
               emitcode ("addc","a,#!constbyte", offset);
 
+              if (aopPutUsesAcc (IC_RESULT (ic), "b", 0))
+                {
+                  emitcode ("push", "acc");
+                  pushedA = TRUE;
+                }
               aopPut (IC_RESULT (ic), "b", 0);
+              if (pushedA)
+                  emitcode ("pop", "acc");
               aopPut (IC_RESULT (ic), "a", 1);
               aopPut (IC_RESULT (ic), buff, 2);
           } else {
@@ -12056,7 +12110,6 @@ genAddrOf (iCode * ic)
 
 release:
   freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
-
 }
 
 #if 0 // obsolete, and buggy for != xdata