fixed bug #499071
[fw/sdcc] / src / SDCCmem.c
index 883072ff8bd3127f6b2da5a6c96f4f20e2b2b245..e4f60ba7ac33e110313389871433f9b51dd072eb 100644 (file)
@@ -5,14 +5,16 @@
 #include "common.h"
 
 /* memory segments */
-memmap *xstack = NULL;         /* xternal stack data         */
-memmap *istack = NULL;         /* internal stack             */
-memmap *code = NULL;           /* code segment               */
-memmap *data = NULL;           /* internal data upto 128     */
-memmap *xdata = NULL;          /* external data              */
-memmap *idata = NULL;          /* internal data upto 256     */
-memmap *bit = NULL;            /* bit addressable space      */
-memmap *statsg = NULL;         /* the constant data segment  */
+memmap *xstack = NULL;         /* xternal stack data          */
+memmap *istack = NULL;         /* internal stack              */
+memmap *code = NULL;           /* code segment                */
+memmap *data = NULL;           /* internal data upto 128      */
+memmap *xdata = NULL;          /* external data               */
+memmap *xidata = NULL;          /* the initialized xdata       */
+memmap *xinit = NULL;           /* the initializers for xidata */
+memmap *idata = NULL;          /* internal data upto 256      */
+memmap *bit = NULL;            /* bit addressable space       */
+memmap *statsg = NULL;         /* the constant data segment   */
 memmap *sfr = NULL;            /* register space              */
 memmap *reg = NULL;            /* register space              */
 memmap *sfrbit = NULL;         /* sfr bit space               */
@@ -175,6 +177,8 @@ initMem ()
      POINTER-TYPE   -   FPOINTER
    */
   xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
+  xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
+  xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
 
   /* Inderectly addressed internal data segment
      SFRSPACE       -   NO
@@ -264,7 +268,20 @@ allocIntoSeg (symbol * sym)
 }
 
 /*-----------------------------------------------------------------*/
-/* allocGlobal - aassigns the output segment to a global var       */
+/* deleteFromSeg - deletes a symbol from segment used when a var   */
+/*                firest declared as "extern" then no extern      */
+/*-----------------------------------------------------------------*/
+void deleteFromSeg(symbol *sym)
+{
+    if (SPEC_OCLS(sym->etype)) {
+       memmap *segment = SPEC_OCLS (sym->etype);       
+       deleteSetItem(&segment->syms,sym);
+    }
+}
+
+
+/*-----------------------------------------------------------------*/
+/* allocGlobal - assigns the output segment to a global var       */
 /*-----------------------------------------------------------------*/
 void 
 allocGlobal (symbol * sym)
@@ -364,16 +381,19 @@ allocGlobal (symbol * sym)
     }
 
   /* if it is fixed, then allocate depending on the  */
-  /* current memory model,same for automatics        */
+  /* current memory model, same for automatics        */
   if (SPEC_SCLS (sym->etype) == S_FIXED ||
-      SPEC_SCLS (sym->etype) == S_AUTO)
-    {
+      SPEC_SCLS (sym->etype) == S_AUTO) {
+    if (port->mem.default_globl_map != xdata) {
       /* set the output class */
       SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
       /* generate the symbol  */
       allocIntoSeg (sym);
       return;
+    } else {
+      SPEC_SCLS (sym->etype) = S_XDATA;
     }
+  }
 
   /* if code change to constant */
   if (SPEC_SCLS (sym->etype) == S_CODE) {
@@ -384,7 +404,13 @@ allocGlobal (symbol * sym)
 
   if (SPEC_SCLS (sym->etype) == S_XDATA)
     {
-      SPEC_OCLS (sym->etype) = xdata;
+      // should we move this to the initialized data segment?
+      if (port->genXINIT &&
+         sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
+       SPEC_OCLS(sym->etype)=xidata;
+      } else {
+       SPEC_OCLS (sym->etype) = xdata;
+      }
       allocIntoSeg (sym);
       return;
     }
@@ -520,14 +546,13 @@ deallocParms (value * val)
 
       /* unmark is myparm */
       lval->sym->ismyparm = 0;
-      /* if on stack then depending on which stack */
 
       /* delete it from the symbol table  */
       deleteSym (SymbolTab, lval->sym, lval->sym->name);
 
       if (!lval->sym->isref)
        {
-         lval->sym->allocreq = 1;
+         lval->sym->allocreq = 0;
          werror (W_NO_REFERENCE, currFunc->name,
                  "function argument", lval->sym->name);
        }
@@ -698,7 +723,7 @@ deallocLocal (symbol * csym)
 
   for (sym = csym; sym; sym = sym->next)
     {
-      if (sym->_isparm)
+      if (sym->_isparm) 
        continue;
 
       /* if it is on the stack */
@@ -799,8 +824,9 @@ allocVariables (symbol * symChain)
       /* then args  processing  */
       if (funcInChain (csym->type))
        {
-
-         processFuncArgs (csym, 1);
+#if 1 // jwk: TODO should have been done already in addDecl() (oclass????)
+         processFuncArgs (csym);
+#endif
          /* if register bank specified then update maxRegBank */
          if (maxRegBank < FUNC_REGBANK (csym->type))
            maxRegBank = FUNC_REGBANK (csym->type);
@@ -1008,6 +1034,9 @@ canOverlayLocals (eBBlock ** ebbs, int count)
 
     return FALSE;
 
+  /* if this is a forces overlay */
+  if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
+
   /* otherwise do thru the blocks and see if there
      any function calls if found then return false */
   for (i = 0; i < count; i++)
@@ -1015,8 +1044,13 @@ canOverlayLocals (eBBlock ** ebbs, int count)
       iCode *ic;
 
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
-       if (ic && (ic->op == CALL || ic->op == PCALL))
-         return FALSE;
+         if (ic) {
+             if (ic->op == CALL) {
+                 sym_link *ftype = operandType(IC_LEFT(ic));
+                 /* builtins only can use overlays */
+                 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE; 
+             } else if (ic->op == PCALL) return FALSE;
+         }
     }
 
   /* no function calls found return TRUE */