fix combination of --xstack & ISRs using non-zero banks
authorkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 29 May 2001 23:21:18 +0000 (23:21 +0000)
committerkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 29 May 2001 23:21:18 +0000 (23:21 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@860 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/ds390/gen.c
src/mcs51/gen.c

index a02ac7f7b03754e3a26d124fcfc349fa3c112f75..79dfc23c6f3131fb5e90c81738d165d22b2f5e0b 100644 (file)
@@ -2046,32 +2046,36 @@ static void
 unsaveRBank (int bank, iCode * ic, bool popPsw)
 {
   int i;
-  asmop *aop;
+  asmop *aop = NULL;
   regs *r = NULL;
 
+  if (options.useXstack)
+  {
+      if (!ic)
+      {
+         /* Assume r0 is available for use. */
+         r = ds390_regWithIdx (R0_IDX);;          
+      }        
+      else
+      {
+         aop = newAsmop (0);
+         r = getFreePtr (ic, &aop, FALSE);
+      }
+      emitcode ("mov", "%s,_spx", r->name);      
+  }
+  
   if (popPsw)
     {
       if (options.useXstack)
-       {
-          if (!ic)
-          {
-              werror(E_INTERNAL_ERROR, __FILE__, __LINE__,
-                     "unexpected null IC in saveRBank");
-              return;
-          }    
-       
-         aop = newAsmop (0);
-         r = getFreePtr (ic, &aop, FALSE);
-
-
-         emitcode ("mov", "%s,_spx", r->name);
+      {
          emitcode ("movx", "a,@%s", r->name);
          emitcode ("mov", "psw,a");
          emitcode ("dec", "%s", r->name);
-
        }
       else
+      {
        emitcode ("pop", "psw");
+      }
     }
 
   for (i = (ds390_nRegs - 1); i >= 0; i--)
@@ -2091,11 +2095,13 @@ unsaveRBank (int bank, iCode * ic, bool popPsw)
 
   if (options.useXstack)
     {
-
       emitcode ("mov", "_spx,%s", r->name);
-      freeAsmop (NULL, aop, ic, TRUE);
-
     }
+    
+  if (aop)
+  {
+      freeAsmop (NULL, aop, ic, TRUE);  
+  }    
 }
 
 /*-----------------------------------------------------------------*/
@@ -2105,21 +2111,22 @@ static void
 saveRBank (int bank, iCode * ic, bool pushPsw)
 {
   int i;
-  asmop *aop;
+  asmop *aop = NULL;
   regs *r = NULL;
 
   if (options.useXstack)
     {
-      if (!ic)
-      {
-          werror(E_INTERNAL_ERROR, __FILE__, __LINE__,
-                 "unexpected null IC in saveRBank");
-          return;
-      }
-      aop = newAsmop (0);
-      r = getFreePtr (ic, &aop, FALSE);
-      emitcode ("mov", "%s,_spx", r->name);
+        if (!ic)
+        {
+                 /* Assume r0 is available for use. */
+                 r = ds390_regWithIdx (R0_IDX);;
+        }
+        else
+        {
+                 aop = newAsmop (0);
+                 r = getFreePtr (ic, &aop, FALSE);
+        }
+        emitcode ("mov", "%s,_spx", r->name);    
     }
 
   for (i = 0; i < ds390_nRegs; i++)
@@ -2144,8 +2151,6 @@ saveRBank (int bank, iCode * ic, bool pushPsw)
          emitcode ("movx", "@%s,a", r->name);
          emitcode ("inc", "%s", r->name);
          emitcode ("mov", "_spx,%s", r->name);
-         freeAsmop (NULL, aop, ic, TRUE);
-
        }
       else
       {
@@ -2154,6 +2159,11 @@ saveRBank (int bank, iCode * ic, bool pushPsw)
 
       emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff);
     }
+  
+  if (aop)
+  {
+       freeAsmop (NULL, aop, ic, TRUE);
+  }    
     
   if (ic)
   {  
@@ -2513,6 +2523,7 @@ genFunction (iCode * ic)
 {
   symbol *sym;
   sym_link *fetype;
+  bool   switchedPSW = FALSE;
 
   D (emitcode (";", "genFunction "););
 
@@ -2632,8 +2643,6 @@ genFunction (iCode * ic)
                iCode *i;
                int ix;
 
-               D(emitcode(";", "seeking function calls..."););
-               
                for (i = ic; i; i = i->next)
                {
                    if (i->op == ENDFUNCTION)
@@ -2657,8 +2666,6 @@ genFunction (iCode * ic)
                             }
                             else
                             {
-                                D(emitcode(";", "should save bank %d",
-                                            SPEC_BANK(detype));); 
                                 banksToSave |= (1 << SPEC_BANK(detype));
                             }
                             
@@ -2680,7 +2687,21 @@ genFunction (iCode * ic)
                        werror(W_FUNCPTR_IN_USING_ISR);   
                    }
                }
-               
+
+               if (banksToSave && options.useXstack)
+               {
+                   /* Since we aren't passing it an ic, 
+                    * saveRBank will assume r0 is available to abuse.
+                    *
+                    * So switch to our (trashable) bank now, so
+                    * the caller's R0 isn't trashed.
+                    */
+                   emitcode ("push", "psw");
+                   emitcode ("mov", "psw,#0x%02x", 
+                             (SPEC_BANK (sym->etype) << 3) & 0x00ff);
+                   switchedPSW = TRUE;
+               }
+               
                for (ix = 0; ix < MAX_REGISTER_BANKS; ix++)
                {
                     if (banksToSave & (1 << ix))
@@ -2718,7 +2739,8 @@ genFunction (iCode * ic)
     }
 
   /* set the register bank to the desired value */
-  if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
+  if ((SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
+   && !switchedPSW)
     {
       emitcode ("push", "psw");
       emitcode ("mov", "psw,#0x%02x", (SPEC_BANK (sym->etype) << 3) & 0x00ff);
@@ -2816,7 +2838,16 @@ genEndFunction (iCode * ic)
 
   /* restore the register bank  */
   if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
-    emitcode ("pop", "psw");
+  {
+    if (!SPEC_BANK (sym->etype) || !IS_ISR (sym->etype)
+     || !options.useXstack)
+    {
+        /* Special case of ISR using non-zero bank with useXstack
+         * is handled below.
+         */
+        emitcode ("pop", "psw");
+    }
+  }
 
   if (IS_ISR (sym->etype))
     {
@@ -2827,7 +2858,6 @@ genEndFunction (iCode * ic)
          registers :-) */
       if (!SPEC_BANK (sym->etype))
        {
-
          /* if this function does not call any other
             function then we can be economical and
             save only those registers that are used */
@@ -2861,11 +2891,11 @@ genEndFunction (iCode * ic)
            /* This ISR uses a non-zero bank.
             *
             * Restore any register banks saved by genFunction
-            * in reverse order/
+            * in reverse order.
             */
            unsigned savedBanks = SPEC_ISR_SAVED_BANKS(currFunc->etype);
            int ix;
-           
+         
            for (ix = MAX_REGISTER_BANKS - 1; ix >= 0; ix--)
            {
                if (savedBanks & (1 << ix))
@@ -2873,6 +2903,14 @@ genEndFunction (iCode * ic)
                    unsaveRBank(ix, NULL, FALSE);
                }
            }
+           
+           if (options.useXstack)
+           {
+               /* Restore bank AFTER calling unsaveRBank,
+                * since it can trash r0.
+                */
+               emitcode ("pop", "psw");
+           }
        }
 
       if (options.model == MODEL_FLAT24 && !inExcludeList ("dpx"))
index 31fecdab5a6b35fcf819d12bce8290ed3bd9da53..2d70a6af55b5b93cd6599ed7bfdd0ad03dd065b3 100644 (file)
@@ -1710,32 +1710,36 @@ static void
 unsaveRBank (int bank, iCode * ic, bool popPsw)
 {
   int i;
-  asmop *aop;
+  asmop *aop = NULL;
   regs *r = NULL;
 
+  if (options.useXstack)
+  {
+      if (!ic)
+      {
+         /* Assume r0 is available for use. */
+         r = mcs51_regWithIdx (R0_IDX);;          
+      }        
+      else
+      {
+         aop = newAsmop (0);
+         r = getFreePtr (ic, &aop, FALSE);
+      }
+      emitcode ("mov", "%s,_spx", r->name);      
+  }
+  
   if (popPsw)
     {
       if (options.useXstack)
-       {
-          if (!ic)
-          {
-              werror(E_INTERNAL_ERROR, __FILE__, __LINE__,
-                     "unexpected null IC in saveRBank");
-              return;
-          }    
-       
-         aop = newAsmop (0);
-         r = getFreePtr (ic, &aop, FALSE);
-
-
-         emitcode ("mov", "%s,_spx", r->name);
+      {
          emitcode ("movx", "a,@%s", r->name);
          emitcode ("mov", "psw,a");
          emitcode ("dec", "%s", r->name);
-
        }
       else
+      {
        emitcode ("pop", "psw");
+      }
     }
 
   for (i = (mcs51_nRegs - 1); i >= 0; i--)
@@ -1755,11 +1759,13 @@ unsaveRBank (int bank, iCode * ic, bool popPsw)
 
   if (options.useXstack)
     {
-
       emitcode ("mov", "_spx,%s", r->name);
-      freeAsmop (NULL, aop, ic, TRUE);
-
     }
+    
+  if (aop)
+  {
+      freeAsmop (NULL, aop, ic, TRUE);  
+  }    
 }
 
 /*-----------------------------------------------------------------*/
@@ -1769,21 +1775,22 @@ static void
 saveRBank (int bank, iCode * ic, bool pushPsw)
 {
   int i;
-  asmop *aop;
+  asmop *aop = NULL;
   regs *r = NULL;
 
   if (options.useXstack)
     {
       if (!ic)
       {
-          werror(E_INTERNAL_ERROR, __FILE__, __LINE__,
-                 "unexpected null IC in saveRBank");
-          return;
+         /* Assume r0 is available for use. */
+         r = mcs51_regWithIdx (R0_IDX);;
+      }
+      else
+      {
+         aop = newAsmop (0);
+         r = getFreePtr (ic, &aop, FALSE);
       }
-      aop = newAsmop (0);
-      r = getFreePtr (ic, &aop, FALSE);
       emitcode ("mov", "%s,_spx", r->name);
-
     }
 
   for (i = 0; i < mcs51_nRegs; i++)
@@ -1808,7 +1815,6 @@ saveRBank (int bank, iCode * ic, bool pushPsw)
          emitcode ("movx", "@%s,a", r->name);
          emitcode ("inc", "%s", r->name);
          emitcode ("mov", "_spx,%s", r->name);
-         freeAsmop (NULL, aop, ic, TRUE);
 
        }
       else
@@ -1819,10 +1825,15 @@ saveRBank (int bank, iCode * ic, bool pushPsw)
       emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff);
     }
 
+    if (aop)
+    {
+        freeAsmop (NULL, aop, ic, TRUE);
+    }
+
   if (ic)
   {  
       ic->bankSaved = 1;
-}
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -2109,6 +2120,7 @@ genFunction (iCode * ic)
 {
   symbol *sym;
   sym_link *fetype;
+  bool   switchedPSW = FALSE;
 
   _G.nRegsSaved = 0;
   /* create the function header */
@@ -2255,7 +2267,21 @@ genFunction (iCode * ic)
                        werror(W_FUNCPTR_IN_USING_ISR);   
                    }
                }
-               
+
+               if (banksToSave && options.useXstack)
+               {
+                   /* Since we aren't passing it an ic, 
+                    * saveRBank will assume r0 is available to abuse.
+                    *
+                    * So switch to our (trashable) bank now, so
+                    * the caller's R0 isn't trashed.
+                    */
+                   emitcode ("push", "psw");
+                   emitcode ("mov", "psw,#0x%02x", 
+                             (SPEC_BANK (sym->etype) << 3) & 0x00ff);
+                   switchedPSW = TRUE;
+               }
+               
                for (ix = 0; ix < MAX_REGISTER_BANKS; ix++)
                {
                     if (banksToSave & (1 << ix))
@@ -2293,7 +2319,8 @@ genFunction (iCode * ic)
     }
 
   /* set the register bank to the desired value */
-  if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
+  if ((SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
+   && !switchedPSW)
     {
       emitcode ("push", "psw");
       emitcode ("mov", "psw,#0x%02x", (SPEC_BANK (sym->etype) << 3) & 0x00ff);
@@ -2389,7 +2416,16 @@ genEndFunction (iCode * ic)
 
   /* restore the register bank  */
   if (SPEC_BANK (sym->etype) || IS_ISR (sym->etype))
-    emitcode ("pop", "psw");
+  {
+    if (!SPEC_BANK (sym->etype) || !IS_ISR (sym->etype)
+     || !options.useXstack)
+    {
+        /* Special case of ISR using non-zero bank with useXstack
+         * is handled below.
+         */
+        emitcode ("pop", "psw");
+    }
+  }
 
   if (IS_ISR (sym->etype))
     {
@@ -2400,7 +2436,6 @@ genEndFunction (iCode * ic)
          registers :-) */
       if (!SPEC_BANK (sym->etype))
        {
-
          /* if this function does not call any other
             function then we can be economical and
             save only those registers that are used */
@@ -2434,11 +2469,11 @@ genEndFunction (iCode * ic)
            /* This ISR uses a non-zero bank.
             *
             * Restore any register banks saved by genFunction
-            * in reverse order/
+            * in reverse order.
             */
            unsigned savedBanks = SPEC_ISR_SAVED_BANKS(currFunc->etype);
            int ix;
-           
+         
            for (ix = MAX_REGISTER_BANKS - 1; ix >= 0; ix--)
            {
                if (savedBanks & (1 << ix))
@@ -2446,6 +2481,14 @@ genEndFunction (iCode * ic)
                    unsaveRBank(ix, NULL, FALSE);
                }
            }
+           
+           if (options.useXstack)
+           {
+               /* Restore bank AFTER calling unsaveRBank,
+                * since it can trash r0.
+                */
+               emitcode ("pop", "psw");
+           }
        }
 
       if (!inExcludeList ("dph"))