* sim/ucsim/cmd.src/cmdutil.cc: NUL device is detected as CG_FILE type
[fw/sdcc] / src / SDCCmem.c
index ddf5ce66bb7e202d10356bfb47f01cf28402a2ac..a128b8b674991f130e2b4eeb2191ce88b35a80a2 100644 (file)
@@ -3,6 +3,7 @@
 /*-----------------------------------------------------------------*/
 
 #include "common.h"
+#include "dbuf_string.h"
 
 /* memory segments */
 memmap *xstack = NULL;          /* xternal stack data          */
@@ -16,6 +17,10 @@ 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 *c_abs = NULL;           /* constant absolute data      */
+memmap *x_abs = NULL;           /* absolute xdata/pdata        */
+memmap *i_abs = NULL;           /* absolute idata upto 256     */
+memmap *d_abs = NULL;           /* absolute data upto 128      */
 memmap *sfr = NULL;             /* register space              */
 memmap *reg = NULL;             /* register space              */
 memmap *sfrbit = NULL;          /* sfr bit space               */
@@ -66,13 +71,10 @@ allocMap (char rspace,          /* sfr space            */
   map->sname = name;
   map->dbName = dbName;
   map->ptrType = ptrType;
-  if (!(map->oFile = tempfile ()))
-    {
-      werror (E_TMPFILE_FAILED);
-      exit (1);
-    }
-  addSetHead (&tmpfileSet, map->oFile);
   map->syms = NULL;
+
+  dbuf_init(&map->oBuf, 4096);
+
   return map;
 }
 
@@ -134,7 +136,7 @@ initMem ()
      DEBUG-NAME     -   'C'
      POINTER-TYPE   -   CPOINTER
    */
-  home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
+  home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, HOME_NAME, 'C', CPOINTER);
 
   /* Static segment (code for variables );
      SFRSPACE       -   NO
@@ -148,6 +150,18 @@ initMem ()
    */
   statsg = allocMap (0, 1, 0, 0, 0, 1, 0, STATIC_NAME, 'D', CPOINTER);
 
+  /* Constant Absolute Data segment (for variables );
+     SFRSPACE       -   NO
+     FAR-SPACE      -   YES
+     PAGED          -   NO
+     DIRECT-ACCESS  -   NO
+     BIT-ACCESS     -   NO
+     CODE-ACCESS    -   YES
+     DEBUG-NAME     -   'D'
+     POINTER-TYPE   -   CPOINTER
+   */
+  c_abs = allocMap (0, 1, 0, 0, 0, 1, 0, CABS_NAME, 'D', CPOINTER);
+
   /* Data segment - internal storage segment ;
      SFRSPACE       -   NO
      FAR-SPACE      -   NO
@@ -160,6 +174,22 @@ initMem ()
    */
   data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
 
+  /* Absolute internal storage segment ;
+     SFRSPACE       -   NO
+     FAR-SPACE      -   NO
+     PAGED          -   NO
+     DIRECT-ACCESS  -   YES
+     BIT-ACCESS     -   NO
+     CODE-ACCESS    -   NO
+     DEBUG-NAME     -   'E'
+     POINTER-TYPE   -   POINTER
+   */
+  if (IABS_NAME) {
+    d_abs = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, IABS_NAME, 'E', POINTER);
+  } else {
+    d_abs = NULL;
+  }
+
   /* overlay segment - same as internal storage segment ;
      SFRSPACE       -   NO
      FAR-SPACE      -   NO
@@ -223,6 +253,22 @@ initMem ()
     idata=NULL;
   }
 
+  /* Indirectly addressed absolute internal segment
+     SFRSPACE       -   NO
+     FAR-SPACE      -   NO
+     PAGED          -   NO
+     DIRECT-ACCESS  -   NO
+     BIT-ACCESS     -   NO
+     CODE-ACCESS    -   NO
+     DEBUG-NAME     -   'E'
+     POINTER-TYPE   -   IPOINTER
+   */
+  if (IABS_NAME) {
+    i_abs = allocMap (0, 0, 0, 0, 0, 0, options.data_loc, IABS_NAME, 'E', IPOINTER);
+  } else {
+    i_abs = NULL;
+  }
+
   /* Bit space ;
      SFRSPACE       -   NO
      FAR-SPACE      -   NO
@@ -296,6 +342,8 @@ allocIntoSeg (symbol * sym)
 {
   memmap *segment = SPEC_OCLS (sym->etype);
   addSet (&segment->syms, sym);
+  if (segment == pdata)
+    sym->iaccess = 1;
 }
 
 /*-----------------------------------------------------------------*/
@@ -328,22 +376,36 @@ allocDefault (symbol * sym)
       if (sym->_isparm)
         return FALSE;
       /* if code change to constant */
-      SPEC_OCLS (sym->etype) = statsg;
+      if (sym->ival && (sym->level==0) && SPEC_ABSA (sym->etype)) {
+        SPEC_OCLS(sym->etype) = c_abs;
+      } else {
+        SPEC_OCLS (sym->etype) = statsg;
+      }
       break;
     case S_XDATA:
       // should we move this to the initialized data segment?
       if (port->genXINIT &&
-          sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
+          sym->ival && (sym->level==0) && !SPEC_ABSA (sym->etype)) {
         SPEC_OCLS(sym->etype) = xidata;
       } else {
         SPEC_OCLS (sym->etype) = xdata;
       }
       break;
     case S_DATA:
-      SPEC_OCLS (sym->etype) = data;
+      /* absolute initialized global */
+      if (sym->ival && (sym->level==0) && SPEC_ABSA (sym->etype)) {
+        SPEC_OCLS(sym->etype) = d_abs;
+      } else {
+        SPEC_OCLS (sym->etype) = data;
+      }
       break;
     case S_IDATA:
-      SPEC_OCLS (sym->etype) = idata;
+      /* absolute initialized global */
+      if (sym->ival && (sym->level==0) && SPEC_ABSA (sym->etype)) {
+        SPEC_OCLS(sym->etype) = i_abs;
+      } else {
+        SPEC_OCLS (sym->etype) = idata;
+      }
       sym->iaccess = 1;
       break;
     case S_PDATA:
@@ -416,10 +478,10 @@ allocGlobal (symbol * sym)
     }
 
   /* if this is a bit variable and no storage class */
-  if (SPEC_NOUN (sym->etype) == V_BIT
-      /*&& SPEC_SCLS (sym->etype) == S_BIT*/)
+  if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
+      /*&& SPEC_SCLS (sym->etype) == S_BIT*/
     {
-      SPEC_OCLS (sym->etype) = bit;
+      SPEC_OCLS (sym->type) = bit;
       allocIntoSeg (sym);
       return;
     }
@@ -460,7 +522,6 @@ allocParms (value * val)
 
   for (lval = val; lval; lval = lval->next, pNum++)
     {
-
       /* check the declaration */
       checkDecl (lval->sym, 0);
 
@@ -474,11 +535,9 @@ allocParms (value * val)
       lval->sym->ismyparm = 1;
       lval->sym->localof = currFunc;
 
-
       /* if automatic variables r 2b stacked */
       if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
         {
-
           if (lval->sym)
             lval->sym->onStack = 1;
 
@@ -531,25 +590,31 @@ allocParms (value * val)
               continue;
             }
 
-            /* otherwise depending on the memory model
-               note here that we put it into the overlay segment
-               first, we will remove it from the overlay segment
-               after the overlay determination has been done */
-            if (options.model == MODEL_SMALL)
-              {
-                SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
-                  (options.noOverlay ? port->mem.default_local_map
-                   : overlay);
-              }
-            else
-              {
-                SPEC_SCLS (lval->etype) = S_XDATA;
-                SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
-              }
+          /* otherwise depending on the memory model */
+          SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
+              port->mem.default_local_map;
+          if (options.model == MODEL_SMALL)
+            {
+              /* note here that we put it into the overlay segment
+                 first, we will remove it from the overlay segment
+                 after the overlay determination has been done */
+              if (!options.noOverlay)
+                {
+                  SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
+                    overlay;
+                }
+            }
+          else if (options.model == MODEL_MEDIUM)
+            {
+              SPEC_SCLS (lval->etype) = S_PDATA;
+            }
+          else
+            {
+              SPEC_SCLS (lval->etype) = S_XDATA;
+            }
           allocIntoSeg (lval->sym);
         }
     }
-
   return;
 }
 
@@ -563,7 +628,6 @@ deallocParms (value * val)
 
   for (lval = val; lval; lval = lval->next)
     {
-
       /* unmark is myparm */
       lval->sym->ismyparm = 0;
 
@@ -591,13 +655,12 @@ deallocParms (value * val)
           addSym (SymbolTab, lval->sym, lval->sym->name,
                   lval->sym->level, lval->sym->block, 1);
           lval->sym->_isparm = 1;
-          if (!isinSet (operKeyReset, lval->sym)) {
-            addSet(&operKeyReset, lval->sym);
-          }
+          if (!isinSet (operKeyReset, lval->sym))
+            {
+              addSet(&operKeyReset, lval->sym);
+            }
         }
-
     }
-
   return;
 }
 
@@ -607,7 +670,6 @@ deallocParms (value * val)
 void
 allocLocal (symbol * sym)
 {
-
   /* generate an unique name */
   SNPRINTF (sym->rname, sizeof(sym->rname),
             "%s%s_%s_%d_%d",
@@ -663,15 +725,15 @@ allocLocal (symbol * sym)
     }
 
   /* if this is a bit variable and no storage class */
-  if (SPEC_NOUN (sym->etype) == V_BIT)
+  if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
     {
-      SPEC_SCLS (sym->etype) = S_BIT;
-      SPEC_OCLS (sym->etype) = bit;
+      SPEC_SCLS (sym->type) = S_BIT;
+      SPEC_OCLS (sym->type) = bit;
       allocIntoSeg (sym);
       return;
     }
 
-  if (SPEC_SCLS (sym->etype) == S_DATA)
+  if ((SPEC_SCLS (sym->etype) == S_DATA) || (SPEC_SCLS (sym->etype) == S_REGISTER))
     {
       SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
       allocIntoSeg (sym);
@@ -688,8 +750,7 @@ allocLocal (symbol * sym)
      overlay  analysis has been done */
   if (options.model == MODEL_SMALL) {
       SPEC_OCLS (sym->etype) =
-        (options.noOverlay ? port->mem.default_local_map
-         : overlay);
+        (options.noOverlay ? port->mem.default_local_map : overlay);
   } else {
       SPEC_OCLS (sym->etype) = port->mem.default_local_map;
   }
@@ -946,7 +1007,7 @@ redoStackOffsets (void)
 /* printAllocInfoSeg- print the allocation for a given section     */
 /*-----------------------------------------------------------------*/
 static void
-printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
+printAllocInfoSeg (memmap * map, symbol * func, struct dbuf_s *oBuf)
 {
   symbol *sym;
 
@@ -964,7 +1025,7 @@ printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
       if (sym->localof != func)
         continue;
 
-      fprintf (of, ";%-25s Allocated ", sym->name);
+      dbuf_printf (oBuf, ";%-25s Allocated ", sym->name);
 
       /* if assigned to registers */
       if (!sym->allocreq && sym->reqv)
@@ -974,10 +1035,10 @@ printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
           sym = OP_SYMBOL (sym->reqv);
           if (!sym->isspilt || sym->remat)
             {
-              fprintf (of, "to registers ");
+              dbuf_append_str (oBuf, "to registers ");
               for (i = 0; i < 4 && sym->regs[i]; i++)
-                fprintf (of, "%s ", port->getRegName (sym->regs[i]));
-              fprintf (of, "\n");
+                dbuf_printf (oBuf, "%s ", port->getRegName (sym->regs[i]));
+              dbuf_append_char (oBuf, '\n');
               continue;
             }
           else
@@ -989,12 +1050,12 @@ printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
       /* if on stack */
       if (sym->onStack)
         {
-          fprintf (of, "to stack - offset %d\n", sym->stack);
+          dbuf_printf (oBuf, "to stack - offset %d\n", sym->stack);
           continue;
         }
 
       /* otherwise give rname */
-      fprintf (of, "with name '%s'\n", sym->rname);
+      dbuf_printf (oBuf, "with name '%s'\n", sym->rname);
     }
 }
 
@@ -1069,27 +1130,24 @@ doOverlays (eBBlock ** ebbs, int count)
 /* printAllocInfo - prints allocation information for a function   */
 /*-----------------------------------------------------------------*/
 void
-printAllocInfo (symbol * func, FILE * of)
+printAllocInfo (symbol * func, struct dbuf_s * oBuf)
 {
   if (!func)
         return;
 
-  if (!of)
-    of = stdout;
-
   /* must be called after register allocation is complete */
-  fprintf (of, ";------------------------------------------------------------\n");
-  fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
-  fprintf (of, ";------------------------------------------------------------\n");
-
-  printAllocInfoSeg (xstack, func, of);
-  printAllocInfoSeg (istack, func, of);
-  printAllocInfoSeg (code, func, of);
-  printAllocInfoSeg (data, func, of);
-  printAllocInfoSeg (xdata, func, of);
-  printAllocInfoSeg (idata, func, of);
-  printAllocInfoSeg (sfr, func, of);
-  printAllocInfoSeg (sfrbit, func, of);
+  dbuf_append_str (oBuf, ";------------------------------------------------------------\n");
+  dbuf_printf (oBuf, ";Allocation info for local variables in function '%s'\n", func->name);
+  dbuf_append_str (oBuf, ";------------------------------------------------------------\n");
+
+  printAllocInfoSeg (xstack, func, oBuf);
+  printAllocInfoSeg (istack, func, oBuf);
+  printAllocInfoSeg (code, func, oBuf);
+  printAllocInfoSeg (data, func, oBuf);
+  printAllocInfoSeg (xdata, func, oBuf);
+  printAllocInfoSeg (idata, func, oBuf);
+  printAllocInfoSeg (sfr, func, oBuf);
+  printAllocInfoSeg (sfrbit, func, oBuf);
 
   {
     set *ovrset;
@@ -1100,10 +1158,10 @@ printAllocInfo (symbol * func, FILE * of)
          ovrset = setNextItem (ovrSetSets))
       {
         overlay->syms = ovrset;
-        printAllocInfoSeg (overlay, func, of);
+        printAllocInfoSeg (overlay, func, oBuf);
       }
     overlay->syms = tempOverlaySyms;
   }
 
-  fprintf (of, ";------------------------------------------------------------\n");
+  dbuf_append_str (oBuf, ";------------------------------------------------------------\n");
 }