Don't include mcs51-stack-auto in target all
[fw/sdcc] / src / mcs51 / gen.c
index d91f0d4c205b7719bfe38176ed57b333aca7cd70..63106da72587e28be1544659cc329384a2a34b7a 100644 (file)
@@ -1890,7 +1890,7 @@ static void
 genCall (iCode * ic)
 {
   sym_link *dtype;
-  bool restoreBank = FALSE;
+//  bool restoreBank = FALSE;
   bool swapBanks = FALSE;
 
   D(emitcode(";", "genCall"));
@@ -1927,16 +1927,17 @@ genCall (iCode * ic)
   dtype = operandType (IC_LEFT (ic));
   if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) &&
       (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) &&
-      IFFUNC_ISISR (currFunc->type))
+       !IFFUNC_ISISR (dtype))
   {
-      if (!ic->bankSaved) 
-      {
-           /* This is unexpected; the bank should have been saved in
-            * genFunction.
-            */
-          saveRBank (FUNC_REGBANK (dtype), ic, FALSE);
-          restoreBank = TRUE;
-      }
+//      if (!ic->bankSaved) 
+//      {
+//           /* This is unexpected; the bank should have been saved in
+//            * genFunction.
+//            */
+//        saveRBank (FUNC_REGBANK (dtype), ic, FALSE);
+//        restoreBank = TRUE;
+//      }
+      // need caution message to user here
       swapBanks = TRUE;  
   } 
     
@@ -1998,20 +1999,21 @@ genCall (iCode * ic)
   if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
     unsaveRegisters (ic);
 
-  /* if register bank was saved then pop them */
-  if (restoreBank)
-    unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE);
+//  /* if register bank was saved then pop them */
+//  if (restoreBank)
+//    unsaveRBank (FUNC_REGBANK (dtype), ic, FALSE);
 }
 
 /*-----------------------------------------------------------------*/
-/* genPcall - generates a call by pointer statement                */
+/* -10l - generates a call by pointer statement                */
 /*-----------------------------------------------------------------*/
 static void
 genPcall (iCode * ic)
 {
   sym_link *dtype;
   symbol *rlbl = newiTempLabel (NULL);
-  bool restoreBank=FALSE;
+//  bool restoreBank=FALSE;
+  bool swapBanks = FALSE;
 
   D(emitcode(";", "genPCall"));
 
@@ -2019,15 +2021,18 @@ genPcall (iCode * ic)
   if (!ic->regsSaved)
     saveRegisters (ic);
 
-  /* if we are calling a function that is not using
+  /* if we are calling a not _naked function that is not using
      the same register bank then we need to save the
      destination registers on the stack */
-  dtype = operandType (IC_LEFT (ic));
-  if (currFunc && dtype && !FUNC_ISNAKED(dtype) &&
-      IFFUNC_ISISR (currFunc->type) &&
-      (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype))) {
-    saveRBank (FUNC_REGBANK (dtype), ic, TRUE);
-    restoreBank=TRUE;
+  dtype = operandType (IC_LEFT (ic))->next;
+  if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) &&
+      (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) &&
+      !IFFUNC_ISISR (dtype))
+  {
+//    saveRBank (FUNC_REGBANK (dtype), ic, TRUE);
+//    restoreBank=TRUE;
+      swapBanks = TRUE;
+      // need caution message to user here
   }
 
   /* push the return address on to the stack */
@@ -2069,10 +2074,23 @@ genPcall (iCode * ic)
       _G.sendSet = NULL;
     }
 
+  if (swapBanks)
+  {
+        emitcode ("mov", "psw,#0x%02x", 
+           ((FUNC_REGBANK(dtype)) << 3) & 0xff);
+  }
+
+  /* make the call */
   emitcode ("ret", "");
   emitcode ("", "%05d$:", (rlbl->key + 100));
 
 
+  if (swapBanks)
+  {
+       emitcode ("mov", "psw,#0x%02x", 
+          ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff);
+  }
+
   /* if we need assign a result value */
   if ((IS_ITEMP (IC_RESULT (ic)) &&
        (OP_SYMBOL (IC_RESULT (ic))->nRegs ||
@@ -2106,9 +2124,9 @@ genPcall (iCode * ic)
 
     }
 
-  /* if register bank was saved then unsave them */
-  if (restoreBank)
-    unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE);
+//  /* if register bank was saved then unsave them */
+//  if (restoreBank)
+//    unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE);
 
   /* if we hade saved some registers then
      unsave them */
@@ -2171,6 +2189,7 @@ genFunction (iCode * ic)
   symbol *sym;
   sym_link *ftype;
   bool   switchedPSW = FALSE;
+  int calleesaves_saved_register = -1;
 
   _G.nRegsSaved = 0;
   /* create the function header */
@@ -2367,6 +2386,9 @@ genFunction (iCode * ic)
                  if (bitVectBitValue (sym->regsUsed, i) ||
                      (mcs51_ptrRegReq && (i == R0_IDX || i == R1_IDX)))
                    {
+                     /* remember one saved register for later usage */
+                     if (calleesaves_saved_register < 0)
+                       calleesaves_saved_register = i;
                      emitcode ("push", "%s", mcs51_regWithIdx (i)->dname);
                      _G.nRegsSaved++;
                    }
@@ -2376,7 +2398,7 @@ genFunction (iCode * ic)
     }
 
   /* set the register bank to the desired value */
-  if ((FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type))
+  if (( /* FUNC_REGBANK (sym->type) || */ IFFUNC_ISISR (sym->type))
    && !switchedPSW)
     {
       emitcode ("push", "psw");
@@ -2418,16 +2440,32 @@ genFunction (iCode * ic)
 
        }
       else if (i > 5)
-       {
-
-         /* ISRs will be handled by the code above, because they
-            can't have parameters. Therefore it's save to use r0 */
-         emitcode ("mov", "r0,a");
-         emitcode ("mov", "a,sp");
-         emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
-         emitcode ("mov", "sp,a");
-         emitcode ("mov", "a,r0");
-
+        {
+         if (IFFUNC_CALLEESAVES(sym->type))
+           {
+             /* if it's a callee-saves function we need a saved register */
+             if (calleesaves_saved_register >= 0)
+               {
+                 emitcode ("mov", "%s,a", mcs51_regWithIdx (calleesaves_saved_register)->dname);
+                 emitcode ("mov", "a,sp");
+                 emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+                 emitcode ("mov", "sp,a");
+                 emitcode ("mov", "a,%s", mcs51_regWithIdx (calleesaves_saved_register)->dname);
+               }
+             else
+               /* do it the hard way */
+               while (i--)
+                 emitcode ("inc", "sp");
+           }
+         else
+           {
+             /* not callee-saves, we can clobber ar0 */
+             emitcode ("mov", "ar0,a");
+             emitcode ("mov", "a,sp");
+             emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff));
+             emitcode ("mov", "sp,a");
+             emitcode ("mov", "a,ar0");
+           }
        }
       else
        while (i--)
@@ -2490,9 +2528,9 @@ genEndFunction (iCode * ic)
     }
 
   /* restore the register bank  */
-  if (FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type))
+  if ( /* FUNC_REGBANK (sym->type) || */ IFFUNC_ISISR (sym->type))
   {
-    if (!FUNC_REGBANK (sym->type) || !IFFUNC_ISISR (sym->type)
+    if (/* !FUNC_REGBANK (sym->type) || */ !IFFUNC_ISISR (sym->type)
      || !options.useXstack)
     {
         /* Special case of ISR using non-zero bank with useXstack
@@ -4308,7 +4346,7 @@ ifxForOp (operand * op, iCode * ic)
 /* hasInc - operand is incremented before any other use            */
 /*-----------------------------------------------------------------*/
 static iCode *
-hasInc (operand *op, iCode *ic)
+hasInc (operand *op, iCode *ic,int osize)
 {
   sym_link *type = operandType(op);
   sym_link *retype = getSpec (type);
@@ -4319,7 +4357,7 @@ hasInc (operand *op, iCode *ic)
   if (!IS_SYMOP(op)) return NULL;
 
   if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL;
-  isize = getSize(type->next);
+  if (osize != (isize = getSize(type->next))) return NULL;
   while (lic) {
     /* if operand of the form op = op + <sizeof *op> */
     if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
@@ -4333,7 +4371,7 @@ hasInc (operand *op, iCode *ic)
       return NULL;
     }
     /* if GOTO or IFX */
-    if (lic->op == IFX || lic->op == GOTO) break;
+    if (lic->op == IFX || lic->op == GOTO || lic->op == LABEL) break;
     lic = lic->next;
   }
   return NULL;
@@ -8724,66 +8762,6 @@ genReceive (iCode * ic)
   freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
 }
 
-/*-----------------------------------------------------------------*/
-/* gen51AggregateAssign - copy complete array's or structures            */
-/*-----------------------------------------------------------------*/
-void gen51AggregateAssign(iCode *ic) {
-  operand *left=IC_LEFT(ic);
-  operand *right=IC_RIGHT(ic);
-  char *fromName=OP_SYMBOL(right)->rname;
-  char *toName=OP_SYMBOL(left)->rname;
-  int fromSize=getSize(OP_SYMBOL(right)->type);
-  int toSize=getSize(OP_SYMBOL(left)->type);
-  int count=toSize;
-
-  D(emitcode (";", "gen51AggregateAssign"));
-
-  if (SPEC_OCLS(OP_SYMBOL(left)->etype)!=xdata ||
-      SPEC_OCLS(OP_SYMBOL(right)->etype)!=code) {
-    // well, this code isn't used yet from anywhere else as for initialising
-    fprintf (stderr, "*** error: %s:%d can only assign aggregates from cseg to xseg for now\n", ic->filename, ic->lineno);
-    exit (457);
-  }
-
-  if (fromSize!=toSize) {
-    fprintf (stderr, "*** error: %s:%d aggregates have different size\n",
-            ic->filename, ic->lineno);
-    exit (821);
-  }
-
-#if 1
-  // use the generic memcpy() for now
-  emitcode (";", "initialize %s", OP_SYMBOL(IC_LEFT(ic))->name);
-  emitcode ("mov", "dptr,#_memcpy_PARM_2");
-  emitcode ("mov", "a,#%s", fromName);
-  emitcode ("movx", "@dptr,a");
-  emitcode ("inc", "dptr");
-  emitcode ("mov", "a,#(%s>>8)", fromName);
-  emitcode ("movx", "@dptr,a");
-  emitcode ("inc", "dptr");
-  emitcode ("mov", "a,#%02x;   only from cseg for now", 2);
-  emitcode ("movx", "@dptr,a");
-  emitcode ("mov", "dptr,#_memcpy_PARM_3");
-  emitcode ("mov", "a,#(%d>>0);        number of bytes", count);
-  emitcode ("movx", "@dptr,a");
-  emitcode ("inc", "dptr");
-  emitcode ("mov", "a,#(%d>>8)", count);
-  emitcode ("movx", "@dptr,a");
-  emitcode ("mov", "dptr,#%s", toName);
-  emitcode ("mov", "b,#%02x;   only to xseg for now", 1);
-  emitcode ("lcall", "_memcpy");
-#else
-  // more efficient, but will require the native_memcpy_cs2xs
-  emitcode ("mov", "r0,#%s", fromName);
-  emitcode ("mov", "r1,#(%s>>8)", fromName);
-  emitcode ("mov", "r2,#%s", toName);
-  emitcode ("mov", "r3,#(%s>>8)", toName);
-  emitcode ("mov", "r4,#%d", count);
-  emitcode ("mov", "r5,#(%d>>8)", count);
-  emitcode ("lcall", "_native_memcpy_cs2xs");
-#endif
-}
-
 /*-----------------------------------------------------------------*/
 /* gen51Code - generate code for 8051 based controllers            */
 /*-----------------------------------------------------------------*/
@@ -8989,12 +8967,12 @@ gen51Code (iCode * lic)
          break;
 
        case GET_VALUE_AT_ADDRESS:
-         genPointerGet (ic, hasInc(IC_LEFT(ic),ic));
+         genPointerGet (ic, hasInc(IC_LEFT(ic),ic,getSize(operandType(IC_LEFT(ic)))));
          break;
 
        case '=':
          if (POINTER_SET (ic))
-           genPointerSet (ic, hasInc (IC_RESULT(ic),ic));
+           genPointerSet (ic, hasInc (IC_RESULT(ic),ic,getSize(operandType(IC_RIGHT(ic)))));
          else
            genAssign (ic);
          break;
@@ -9023,10 +9001,6 @@ gen51Code (iCode * lic)
          addSet (&_G.sendSet, ic);
          break;
 
-       case ARRAYINIT:
-         gen51AggregateAssign(ic);
-         break;
-
        default:
          ic = ic;
        }