Improved parameter passing code generation
authorkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 24 May 2001 03:38:51 +0000 (03:38 +0000)
committerkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 24 May 2001 03:38:51 +0000 (03:38 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@846 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/ds390/gen.c

index cc326219e363b05f5ad891890ef089a207585335..006cc10e235dc98a1fc4a54b0ff4e3cf0d613d96 100644 (file)
@@ -2152,10 +2152,29 @@ genCall (iCode * ic)
 {
   sym_link *detype;
 
-  D (emitcode (";", "genCall ");
-    );
+  D (emitcode (";", "genCall "););
 
+  /* 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);
+  }
+  
   /* if send set is not empty the assign */
+  /* We've saved all the registers we care about;
+  * therefore, we may clobber any register not used
+  * in the calling convention (i.e. anything not in
+  * fReturn.
+  */
   if (_G.sendSet)
     {
       iCode *sic;
@@ -2165,43 +2184,45 @@ genCall (iCode * ic)
        {
          int size, offset = 0;
 
-         aopOp (IC_LEFT (sic), sic, FALSE, TRUE);
+         aopOp (IC_LEFT (sic), sic, FALSE, FALSE);
          size = AOP_SIZE (IC_LEFT (sic));
 
          _startLazyDPSEvaluation ();
          while (size--)
            {
-             char *l = aopGet (AOP (IC_LEFT (sic)), offset,
+             char *l = aopGet (AOP(IC_LEFT(sic)), offset,
                                FALSE, FALSE, TRUE);
-             if (strcmp (l, fReturn[offset])) {
-               genSetDPTR(0);
-               _flushLazyDPS();
-               emitcode ("mov", "%s,%s",
-                         fReturn[offset],
-                         l);
-             }
+               if ((AOP_TYPE(IC_LEFT(sic)) == AOP_DPTR) && size)
+               {
+                   emitcode("mov", "%s,%s", regs390[offset].name, l);
+               }
+               else if (strcmp (l, fReturn[offset]))
+               {
+                   emitcode ("mov", "%s,%s",
+                             fReturn[offset],
+                             l);
+               }
              offset++;
            }
          _endLazyDPSEvaluation ();
+         if (AOP_TYPE(IC_LEFT(sic)) == AOP_DPTR)
+         {
+             size = AOP_SIZE (IC_LEFT (sic));
+             if (size)
+             {
+                size--;
+             }
+             while (size)
+             {
+                  size--;
+                  emitcode("mov", "%s,%s",
+                                   fReturn[size], regs390[size].name);
+             }
+         }
          freeAsmop (IC_LEFT (sic), NULL, sic, TRUE);
        }
       _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] ?