fixed a small bug with large effects
[fw/sdcc] / src / ds390 / gen.c
index dc63df816aa7b6227086aff646a9a121b09172b4..cc326219e363b05f5ad891890ef089a207585335 100644 (file)
@@ -48,7 +48,7 @@
 #endif
 #endif
 
-// #define BETTER_LITERAL_SHIFT
+#define BETTER_LITERAL_SHIFT
 
 char *aopLiteral (value * val, int offset);
 
@@ -83,7 +83,7 @@ static struct
   }
 _G;
 
-static void saverbank (int, iCode *, bool);
+static void saveRBank (int, iCode *, bool);
 
 #define RESULTONSTACK(x) \
                          (IC_RESULT(x) && IC_RESULT(x)->aop && \
@@ -126,7 +126,7 @@ static void
 emitcode (char *inst, char *fmt,...)
 {
   va_list ap;
-  char lb[MAX_INLINEASM];
+  char lb[INITIAL_INLINEASM];
   char *lbp = lb;
 
   va_start (ap, fmt);
@@ -456,11 +456,9 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
 
       if (useDP2)
        {
-         /* genSetDPTR(1); */
          emitcode ("mov", "dpx1,#0x40");
          emitcode ("mov", "dph1,#0x00");
          emitcode ("mov", "dpl1, a");
-         /* genSetDPTR(0); */
        }
       else
        {
@@ -1794,16 +1792,18 @@ saveRegisters (iCode * lic)
     for (i = 0; i < ds390_nRegs; i++)
       {
        if (bitVectBitValue (rsave, i))
-         emitcode ("push", "%s ;jwk saveRegisters", ds390_regWithIdx (i)->dname);
+         emitcode ("push", "%s", ds390_regWithIdx (i)->dname);
       }
 
   detype = getSpec (operandType (IC_LEFT (ic)));
+
+#if 0 // why should we do this here??? jwk20011105
   if (detype &&
       (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
       IS_ISR (currFunc->etype) &&
       !ic->bankSaved)
-
-    saverbank (SPEC_BANK (detype), ic, TRUE);
+    saveRBank (SPEC_BANK (detype), ic, TRUE);
+#endif
 
 }
 /*-----------------------------------------------------------------*/
@@ -1843,7 +1843,7 @@ unsaveRegisters (iCode * ic)
     for (i = ds390_nRegs; i >= 0; i--)
       {
        if (bitVectBitValue (rsave, i))
-         emitcode ("pop", "%s ;jwk unsaveRegisters", ds390_regWithIdx (i)->dname);
+         emitcode ("pop", "%s", ds390_regWithIdx (i)->dname);
       }
 
 }
@@ -1965,7 +1965,7 @@ genIpush (iCode * ic)
              MOVA (l);
              l = "acc";
            }
-         emitcode ("push", "%s ;jwk genIpush: !parm", l);
+         emitcode ("push", "%s", l);
        }
       _endLazyDPSEvaluation ();
       return;
@@ -2002,7 +2002,7 @@ genIpush (iCode * ic)
          emitcode ("push", "acc");
        }
       else
-       emitcode ("push", "%s ;jwk genIpush", l);
+       emitcode ("push", "%s", l);
     }
   _endLazyDPSEvaluation ();
 
@@ -2031,7 +2031,7 @@ genIpop (iCode * ic)
   _startLazyDPSEvaluation ();
   while (size--)
     {
-      emitcode ("pop", "%s ;jwk genIpop", aopGet (AOP (IC_LEFT (ic)), offset--,
+      emitcode ("pop", "%s", aopGet (AOP (IC_LEFT (ic)), offset--,
                                     FALSE, TRUE, TRUE));
     }
   _endLazyDPSEvaluation ();
@@ -2040,10 +2040,10 @@ genIpop (iCode * ic)
 }
 
 /*-----------------------------------------------------------------*/
-/* unsaverbank - restores the resgister bank from stack            */
+/* unsaveRBank - restores the resgister bank from stack            */
 /*-----------------------------------------------------------------*/
 static void
-unsaverbank (int bank, iCode * ic, bool popPsw)
+unsaveRBank (int bank, iCode * ic, bool popPsw)
 {
   int i;
   asmop *aop;
@@ -2092,10 +2092,10 @@ unsaverbank (int bank, iCode * ic, bool popPsw)
 }
 
 /*-----------------------------------------------------------------*/
-/* saverbank - saves an entire register bank on the stack          */
+/* saveRBank - saves an entire register bank on the stack          */
 /*-----------------------------------------------------------------*/
 static void
-saverbank (int bank, iCode * ic, bool pushPsw)
+saveRBank (int bank, iCode * ic, bool pushPsw)
 {
   int i;
   asmop *aop;
@@ -2155,21 +2155,6 @@ genCall (iCode * ic)
   D (emitcode (";", "genCall ");
     );
 
-  /* if caller saves & we have not saved then */
-  if (!ic->regsSaved)
-    saveRegisters (ic);
-
-  /* if we are calling a function that is not using
-     the same register bank then we need to save the
-     destination registers on the stack */
-  detype = getSpec (operandType (IC_LEFT (ic)));
-  if (detype &&
-      (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
-      IS_ISR (currFunc->etype) &&
-      !ic->bankSaved)
-
-    saverbank (SPEC_BANK (detype), ic, TRUE);
-
   /* if send set is not empty the assign */
   if (_G.sendSet)
     {
@@ -2191,7 +2176,7 @@ genCall (iCode * ic)
              if (strcmp (l, fReturn[offset])) {
                genSetDPTR(0);
                _flushLazyDPS();
-               emitcode ("mov", "%s,%s ;jwk lazy genCall",
+               emitcode ("mov", "%s,%s",
                          fReturn[offset],
                          l);
              }
@@ -2202,6 +2187,22 @@ genCall (iCode * ic)
        }
       _G.sendSet = NULL;
     }
+
+  /* if we are calling a function that is not using
+     the same register bank then we need to save the
+     destination registers on the stack */
+  detype = getSpec (operandType (IC_LEFT (ic)));
+  if (detype &&
+      (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)) &&
+      IS_ISR (currFunc->etype) &&
+      !ic->bankSaved) {
+    saveRBank (SPEC_BANK (detype), ic, TRUE);
+  } else /* no need to save if we just saved the whole bank */ {
+    /* if caller saves & we have not saved then */
+    if (!ic->regsSaved)
+      saveRegisters (ic);
+  }
+
   /* make the call */
   emitcode ("lcall", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
                            OP_SYMBOL (IC_LEFT (ic))->rname :
@@ -2219,8 +2220,6 @@ genCall (iCode * ic)
          int size = getSize (operandType (IC_RESULT (ic)));
 
          /* Special case for 1 or 2 byte return in far space. */
-         emitcode (";", "Kevin function call abuse #1");
-
          MOVA (fReturn[0]);
          if (size > 1)
            {
@@ -2267,7 +2266,7 @@ genCall (iCode * ic)
 
   /* if register bank was saved then pop them */
   if (ic->bankSaved)
-    unsaverbank (SPEC_BANK (detype), ic, TRUE);
+    unsaveRBank (SPEC_BANK (detype), ic, TRUE);
 
   /* if we hade saved some registers then unsave them */
   if (ic->regsSaved && !(OP_SYMBOL (IC_LEFT (ic))->calleeSave))
@@ -2300,7 +2299,7 @@ genPcall (iCode * ic)
   if (detype &&
       IS_ISR (currFunc->etype) &&
       (SPEC_BANK (currFunc->etype) != SPEC_BANK (detype)))
-    saverbank (SPEC_BANK (detype), ic, TRUE);
+    saveRBank (SPEC_BANK (detype), ic, TRUE);
 
 
   /* push the return address on to the stack */
@@ -2394,7 +2393,7 @@ genPcall (iCode * ic)
   if (detype &&
       (SPEC_BANK (currFunc->etype) !=
        SPEC_BANK (detype)))
-    unsaverbank (SPEC_BANK (detype), ic, TRUE);
+    unsaveRBank (SPEC_BANK (detype), ic, TRUE);
 
   /* if we hade saved some registers then
      unsave them */
@@ -2552,9 +2551,9 @@ genFunction (iCode * ic)
          else
            {
              /* this function has  a function call cannot
-                determines register usage so we will have the
+                determines register usage so we will have to push the
                 entire bank */
-             saverbank (0, ic, FALSE);
+             saveRBank (0, ic, FALSE);
            }
        }
     }
@@ -2718,9 +2717,9 @@ genEndFunction (iCode * ic)
          else
            {
              /* this function has  a function call cannot
-                determines register usage so we will have the
+                determines register usage so we will have to pop the
                 entire bank */
-             unsaverbank (0, ic, FALSE);
+             unsaveRBank (0, ic, FALSE);
            }
        }
 
@@ -2841,8 +2840,11 @@ genRet (iCode * ic)
        }
       else
        {
+         /* Since A is the last element of fReturn,
+          * is is OK to clobber it in the aopGet.
+          */
          l = aopGet (AOP (IC_LEFT (ic)), offset,
-                     FALSE, FALSE, FALSE);
+                     FALSE, FALSE, TRUE);
          if (strcmp (fReturn[offset], l))
            emitcode ("mov", "%s,%s", fReturn[offset++], l);
        }
@@ -3699,11 +3701,10 @@ genMultOneByte (operand * left,
   symbol *lbl;
   int size=AOP_SIZE(result);
 
-  emitcode (";",__FUNCTION__);
   if (size<1 || size>2) {
     // this should never happen
       fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", 
-              AOP_SIZE(result), __FUNCTION__, lineno);
+              AOP_SIZE(result), __FILE__, lineno);
       exit (1);
   }
 
@@ -5776,14 +5777,14 @@ release:
 static void
 genInline (iCode * ic)
 {
-  char buffer[MAX_INLINEASM];
-  char *bp = buffer;
-  char *bp1 = buffer;
+  char *buffer, *bp, *bp1;
 
   D (emitcode (";", "genInline ");
     );
 
   _G.inLine += (!options.asmpeep);
+
+  buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
   strcpy (buffer, IC_INLINE (ic));
 
   /* emit each line as a code */
@@ -6485,7 +6486,6 @@ _loadLeftIntoAx(char      **lsb,
   {
        char *leftByte;
        
-       D(emitcode(";", "watch me do the hambone!"););
        _startLazyDPSEvaluation();
        if (AOP_TYPE(left) == AOP_DPTR2)
        {
@@ -6665,22 +6665,25 @@ genlshTwo (operand * result, operand * left, int shCount)
       shCount -= 8;
 
       _startLazyDPSEvaluation();
-      aopPut (AOP (result), zero, LSB);
+
       if (size > 1)
        {
          if (shCount)
          {
            _endLazyDPSEvaluation();
            shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+           aopPut (AOP (result), zero, LSB);       
          }
          else
          {
            movLeft2Result (left, LSB, result, MSB16, 0);
+           aopPut (AOP (result), zero, LSB);
            _endLazyDPSEvaluation();
          }
        }
        else
        {
+         aopPut (AOP (result), zero, LSB);
          _endLazyDPSEvaluation();
        }
   }
@@ -8144,15 +8147,15 @@ genGenPointerGet (operand * left,
            l=aopGet(AOP(left),0,FALSE,FALSE,TRUE);
            genSetDPTR(0);
            _flushLazyDPS();
-           emitcode ("mov", "dpl,%s ;jwk lazy genGenPointerGet", l);
+           emitcode ("mov", "dpl,%s", l);
            l=aopGet(AOP(left),1,FALSE,FALSE,TRUE);
            genSetDPTR(0);
            _flushLazyDPS();
-           emitcode ("mov", "dph,%s ;jwk lazy genGenPointerGet", l);
+           emitcode ("mov", "dph,%s", l);
            l=aopGet(AOP(left),2,FALSE,FALSE,TRUE);
            genSetDPTR(0);
            _flushLazyDPS();
-           emitcode ("mov", "dpx,%s ;jwk lazy genGenPointerGet", l);
+           emitcode ("mov", "dpx,%s", l);
            emitcode ("mov", "b,%s", aopGet (AOP(left),3,FALSE,FALSE,TRUE));
          } else {
            emitcode ("mov", "dpl,%s", aopGet (AOP(left),0,FALSE,FALSE,TRUE));
@@ -8954,19 +8957,64 @@ genFarFarAssign (operand * result, operand * right, iCode * ic)
 {
   int size = AOP_SIZE (right);
   int offset = 0;
-  char *l;
-
-  if (size > 1)
-    {
-      /* This is a net loss for size == 1, but a big gain
-       * otherwise.
-       */
-      D (emitcode (";", "genFarFarAssign (improved)");
-       );
+  symbol *rSym = NULL;
 
+  if (size == 1)
+  {
+      /* quick & easy case. */
+      D(emitcode(";","genFarFarAssign (1 byte case)"););      
+      MOVA(aopGet(AOP(right), 0, FALSE, FALSE, TRUE));
+      freeAsmop (right, NULL, ic, FALSE);
+      /* now assign DPTR to result */
+      _G.accInUse++;
+      aopOp(result, ic, FALSE, FALSE);
+      _G.accInUse--;
+      aopPut(AOP(result), "a", 0);
+      freeAsmop(result, NULL, ic, FALSE);
+      return;
+  }
+  
+  /* See if we've got an underlying symbol to abuse. */
+  if (IS_SYMOP(result) && OP_SYMBOL(result))
+  {
+      if (IS_TRUE_SYMOP(result))
+      {
+         rSym = OP_SYMBOL(result);
+      }
+      else if (IS_ITEMP(result) && OP_SYMBOL(result)->isspilt && OP_SYMBOL(result)->usl.spillLoc)
+      {
+         rSym = OP_SYMBOL(result)->usl.spillLoc;
+      }
+  }
+            
+  if (size > 1 && rSym && rSym->rname && !rSym->onStack)
+  {
+      /* We can use the '390 auto-toggle feature to good effect here. */
+      
+      D(emitcode(";","genFarFarAssign ('390 auto-toggle fun)"););
+      emitcode("mov", "dps, #0x21");   /* Select DPTR2 & auto-toggle. */
+      emitcode ("mov", "dptr,#%s", rSym->rname); 
+      /* DP2 = result, DP1 = right, DP1 is current. */
+      while (size)
+      {
+          emitcode("movx", "a,@dptr");
+          emitcode("movx", "@dptr,a");
+          if (--size)
+          {
+               emitcode("inc", "dptr");
+               emitcode("inc", "dptr");
+          }
+      }
+      emitcode("mov", "dps, #0");
+      freeAsmop (right, NULL, ic, FALSE);
+  }
+  else
+  {
+      D (emitcode (";", "genFarFarAssign"););
       aopOp (result, ic, TRUE, TRUE);
 
       _startLazyDPSEvaluation ();
+      
       while (size--)
        {
          aopPut (AOP (result),
@@ -8976,33 +9024,7 @@ genFarFarAssign (operand * result, operand * right, iCode * ic)
       _endLazyDPSEvaluation ();
       freeAsmop (result, NULL, ic, FALSE);
       freeAsmop (right, NULL, ic, FALSE);
-    }
-  else
-    {
-      D (emitcode (";", "genFarFarAssign ");
-       );
-
-      /* first push the right side on to the stack */
-      _startLazyDPSEvaluation ();
-      while (size--)
-       {
-         l = aopGet (AOP (right), offset++, FALSE, FALSE, TRUE);
-         MOVA (l);
-         emitcode ("push", "acc");
-       }
-
-      freeAsmop (right, NULL, ic, FALSE);
-      /* now assign DPTR to result */
-      aopOp (result, ic, FALSE, FALSE);
-      size = AOP_SIZE (result);
-      while (size--)
-       {
-         emitcode ("pop", "acc");
-         aopPut (AOP (result), "a", --offset);
-       }
-      freeAsmop (result, NULL, ic, FALSE);
-      _endLazyDPSEvaluation ();
-    }
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -9088,8 +9110,6 @@ genAssign (iCode * ic)
       (AOP_TYPE (right) == AOP_LIT) &&
       !IS_FLOAT (operandType (right)))
     {
-      D (emitcode (";", "Kevin's better literal load code");
-       );
       _startLazyDPSEvaluation ();
       while (size && ((unsigned int) (lit >> (offset * 8)) != 0))
        {