Use 'ao-dbg' instead of 's51' to communicate with TeleMetrum
[fw/sdcc] / src / SDCCmem.c
index 4692be48e609842c9020b1e5f950311272e2c707..5bc6bb92c31ea1354df22ec3801954349b6dbacc 100644 (file)
@@ -3,50 +3,57 @@
 /*-----------------------------------------------------------------*/
 
 #include "common.h"
+#include "dbuf_string.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 *sfr = NULL;            /* register space              */
-memmap *reg = NULL;            /* register space              */
-memmap *sfrbit = NULL;         /* sfr bit space               */
-memmap *generic = NULL;                /* is a generic pointer        */
-memmap *overlay = NULL;                /* overlay segment             */
-memmap *eeprom = NULL;         /* eeprom location             */
-memmap *home = NULL;           /* Unswitchable code bank      */
+memmap *xstack = NULL;          /* xternal stack data          */
+memmap *istack = NULL;          /* internal stack              */
+memmap *code = NULL;            /* code segment                */
+memmap *data = NULL;            /* internal data upto 128      */
+memmap *pdata = NULL;           /* paged external data         */
+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 *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               */
+memmap *generic = NULL;         /* is a generic pointer        */
+memmap *overlay = NULL;         /* overlay segment             */
+memmap *eeprom = NULL;          /* eeprom location             */
+memmap *home = NULL;            /* Unswitchable code bank      */
 
 /* this is a set of sets each set containing
    symbols in a single overlay */
 set *ovrSetSets = NULL;
 
-int maxRegBank = 0;
-int fatalError = 0;            /* fatal error flag                   */
+int fatalError = 0;             /* fatal error flag                   */
 
 /*-----------------------------------------------------------------*/
 /* allocMap - allocates a memory map                               */
 /*-----------------------------------------------------------------*/
 memmap *
-allocMap (char rspace,         /* sfr space            */
-         char farmap,          /* far or near segment  */
-         char paged,           /* can this segment be paged  */
-         char direct,          /* directly addressable */
-         char bitaddr,         /* bit addressable space */
-         char codemap,         /* this is code space   */
-         unsigned sloc,        /* starting location    */
-         const char *name,     /* 2 character name     */
-         char dbName,          /* debug name                 */
-         int ptrType           /* pointer type for this space */
+allocMap (char rspace,          /* sfr space            */
+          char farmap,          /* far or near segment  */
+          char paged,           /* can this segment be paged  */
+          char direct,          /* directly addressable */
+          char bitaddr,         /* bit addressable space */
+          char codemap,         /* this is code space   */
+          unsigned sloc,        /* starting location    */
+          const char *name,     /* 2 character name     */
+          char dbName,          /* debug name                 */
+          int ptrType           /* pointer type for this space */
 )
 {
   memmap *map;
 
-  if (!(map = calloc (sizeof (memmap), 1)))
+  if (!(map = Safe_alloc (sizeof (memmap))))
     {
       werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap));
       exit (1);
@@ -63,70 +70,74 @@ 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;
 }
 
 /*-----------------------------------------------------------------*/
 /* initMem - allocates and initializes all the segments            */
 /*-----------------------------------------------------------------*/
-void 
+void
 initMem ()
 {
   /* allocate all the segments */
-  /* xternal stack segment ;   
+  /* xternal stack segment ;
      SFRSPACE       -   NO
      FAR-SPACE      -   YES
      PAGED          -   YES
      DIRECT-ACCESS  -   NO
      BIT-ACCESS     -   NO
-     CODE-ACESS     -   NO 
+     CODE-ACCESS    -   NO
      DEBUG-NAME     -   'A'
      POINTER-TYPE   -   FPOINTER
    */
   xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER);
 
-  /* internal stack segment ;   
+  /* internal stack segment ;
      SFRSPACE       -   NO
      FAR-SPACE      -   NO
      PAGED          -   NO
      DIRECT-ACCESS  -   NO
      BIT-ACCESS     -   NO
-     CODE-ACESS     -   NO 
+     CODE-ACCESS    -   NO
      DEBUG-NAME     -   'B'
      POINTER-TYPE   -   POINTER
    */
-  istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER);
+  if (ISTACK_NAME)
+    {
+      istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER);
+    }
+  else
+    {
+      istack = NULL;
+    }
 
-  /* code  segment ;   
+  /* code  segment ;
      SFRSPACE       -   NO
      FAR-SPACE      -   YES
      PAGED          -   NO
      DIRECT-ACCESS  -   NO
      BIT-ACCESS     -   NO
-     CODE-ACESS     -   YES 
+     CODE-ACCESS    -   YES
      DEBUG-NAME     -   'C'
      POINTER-TYPE   -   CPOINTER
    */
   code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
 
-  /* home  segment ;   
+  /* home  segment ;
      SFRSPACE       -   NO
      FAR-SPACE      -   YES
      PAGED          -   NO
      DIRECT-ACCESS  -   NO
      BIT-ACCESS     -   NO
-     CODE-ACESS     -   YES 
+     CODE-ACCESS    -   YES
      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
@@ -134,67 +145,171 @@ initMem ()
      PAGED          -   NO
      DIRECT-ACCESS  -   NO
      BIT-ACCESS     -   NO
-     CODE-ACESS     -   YES 
+     CODE-ACCESS    -   YES
      DEBUG-NAME     -   'D'
      POINTER-TYPE   -   CPOINTER
    */
   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
      PAGED          -   NO
      DIRECT-ACCESS  -   YES
      BIT-ACCESS     -   NO
-     CODE-ACESS     -   NO 
+     CODE-ACCESS    -   NO
      DEBUG-NAME     -   'E'
      POINTER-TYPE   -   POINTER
    */
   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
      PAGED          -   NO
      DIRECT-ACCESS  -   YES
      BIT-ACCESS     -   NO
-     CODE-ACESS     -   NO 
+     CODE-ACCESS    -   NO
      DEBUG-NAME     -   'E'
      POINTER-TYPE   -   POINTER
    */
-  overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
+  if (OVERLAY_NAME)
+    {
+      overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
+    }
+  else
+    {
+      overlay = NULL;
+    }
 
-  /* Xternal Data segment - 
+  /* Xternal paged segment ;   
+     SFRSPACE       -   NO
+     FAR-SPACE      -   NO
+     PAGED          -   YES
+     DIRECT-ACCESS  -   NO
+     BIT-ACCESS     -   NO
+     CODE-ACCESS    -   NO 
+     DEBUG-NAME     -   'P'
+     POINTER-TYPE   -   PPOINTER
+   */
+  if (PDATA_NAME)
+    {
+      pdata = allocMap (0, 0, 1, 0, 0, 0, options.xstack_loc, PDATA_NAME, 'P', PPOINTER);
+    }
+  else
+    {
+      pdata = NULL;
+    }
+
+  /* Xternal Data segment -
      SFRSPACE       -   NO
      FAR-SPACE      -   YES
      PAGED          -   NO
      DIRECT-ACCESS  -   NO
      BIT-ACCESS     -   NO
-     CODE-ACESS     -   NO 
+     CODE-ACCESS    -   NO
      DEBUG-NAME     -   'F'
      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
+  /* Absolute external storage segment ;
+     SFRSPACE       -   NO
+     FAR-SPACE      -   YES
+     PAGED          -   NO
+     DIRECT-ACCESS  -   NO
+     BIT-ACCESS     -   NO
+     CODE-ACCESS    -   NO
+     DEBUG-NAME     -   'F'
+     POINTER-TYPE   -   FPOINTER
+   */
+  if (XABS_NAME)
+    {
+      x_abs = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XABS_NAME, 'F', FPOINTER);
+    }
+  else
+    {
+      x_abs = NULL;
+    }
+
+  /* Indirectly addressed internal data segment
      SFRSPACE       -   NO
      FAR-SPACE      -   NO
      PAGED          -   NO
      DIRECT-ACCESS  -   NO
      BIT-ACCESS     -   NO
-     CODE-ACESS     -   NO 
+     CODE-ACCESS    -   NO
      DEBUG-NAME     -   'G'
      POINTER-TYPE   -   IPOINTER
    */
-  idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER);
+  if (IDATA_NAME)
+    {
+      idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER);
+    }
+  else
+    {
+      idata = NULL;
+    }
 
-  /* Static segment (code for variables );
+  /* 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
      PAGED          -   NO
      DIRECT-ACCESS  -   YES
      BIT-ACCESS     -   YES
-     CODE-ACESS     -   NO 
+     CODE-ACCESS    -   NO
      DEBUG-NAME     -   'H'
      POINTER-TYPE   -  _NONE_
    */
@@ -206,7 +321,7 @@ initMem ()
      PAGED          -   NO
      DIRECT-ACCESS  -   YES
      BIT-ACCESS     -   NO
-     CODE-ACESS     -   NO 
+     CODE-ACCESS    -   NO
      DEBUG-NAME     -   'I'
      POINTER-TYPE   -   _NONE_
    */
@@ -218,31 +333,31 @@ initMem ()
      PAGED          -   NO
      DIRECT-ACCESS  -   NO
      BIT-ACCESS     -   NO
-     CODE-ACESS     -   NO 
+     CODE-ACCESS    -   NO
      DEBUG-NAME     -   ' '
      POINTER-TYPE   -   _NONE_
    */
   reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
 
-  /* SFR bit space 
+  /* SFR bit space
      SFRSPACE       -   YES
      FAR-SPACE      -   NO
      PAGED          -   NO
      DIRECT-ACCESS  -   YES
      BIT-ACCESS     -   YES
-     CODE-ACESS     -   NO 
+     CODE-ACCESS    -   NO
      DEBUG-NAME     -   'J'
      POINTER-TYPE   -   _NONE_
    */
   sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
 
-  /* EEPROM bit space 
+  /* EEPROM space
      SFRSPACE       -   NO
      FAR-SPACE      -   YES
      PAGED          -   NO
      DIRECT-ACCESS  -   NO
      BIT-ACCESS     -   NO
-     CODE-ACESS     -   NO 
+     CODE-ACCESS    -   NO
      DEBUG-NAME     -   'K'
      POINTER-TYPE   -   EEPPOINTER
    */
@@ -256,26 +371,126 @@ initMem ()
 /*-----------------------------------------------------------------*/
 /* allocIntoSeg - puts a symbol into a memory segment              */
 /*-----------------------------------------------------------------*/
-void 
+void
 allocIntoSeg (symbol * sym)
 {
   memmap *segment = SPEC_OCLS (sym->etype);
   addSet (&segment->syms, sym);
+  if (segment == pdata)
+    sym->iaccess = 1;
 }
 
 /*-----------------------------------------------------------------*/
-/* allocGlobal - aassigns the output segment to a global var       */
+/* deleteFromSeg - deletes a symbol from segment used when a var   */
+/*                 first 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);
+    }
+}
+
 /*-----------------------------------------------------------------*/
-void 
+/* allocDefault - assigns the output segment based on SCLASS       */
+/*-----------------------------------------------------------------*/
+bool
+allocDefault (symbol * sym)
+{
+  switch (SPEC_SCLS (sym->etype))
+    {
+    case S_SFR:
+      SPEC_OCLS (sym->etype) = sfr;
+      break;
+    case S_SBIT:
+      SPEC_OCLS (sym->etype) = sfrbit;
+      break;
+    case S_CODE:
+      if (sym->_isparm)
+        return FALSE;
+      /* if code change to constant */
+      if (sym->ival && SPEC_ABSA (sym->etype))
+        {
+          SPEC_OCLS(sym->etype) = c_abs;
+        }
+      else
+        {
+          SPEC_OCLS (sym->etype) = statsg;
+        }
+      break;
+    case S_XDATA:
+      /* absolute initialized global */
+      if (sym->ival && SPEC_ABSA (sym->etype))
+        {
+          SPEC_OCLS(sym->etype) = x_abs;
+        }
+      /* or should we move this to the initialized data segment? */
+      else if (port->genXINIT && sym->ival && (sym->level==0))
+        {
+          SPEC_OCLS(sym->etype) = xidata;
+        }
+      else
+        {
+          SPEC_OCLS (sym->etype) = xdata;
+        }
+      break;
+    case S_DATA:
+      /* absolute initialized global */
+      if (sym->ival && SPEC_ABSA (sym->etype))
+        {
+          SPEC_OCLS(sym->etype) = d_abs;
+        }
+      else
+        {
+          SPEC_OCLS (sym->etype) = data;
+        }
+      break;
+    case S_IDATA:
+      /* absolute initialized global */
+      if (sym->ival && SPEC_ABSA (sym->etype))
+        {
+          SPEC_OCLS(sym->etype) = i_abs;
+        }
+      else
+        {
+          SPEC_OCLS (sym->etype) = idata;
+        }
+      sym->iaccess = 1;
+      break;
+    case S_PDATA:
+      SPEC_OCLS (sym->etype) = pdata;
+      sym->iaccess = 1;
+      break;
+    case S_BIT:
+      SPEC_OCLS (sym->etype) = bit;
+      break;
+    case S_EEPROM:
+      SPEC_OCLS (sym->etype) = eeprom;
+      break;
+    default:
+      return FALSE;
+    }
+  allocIntoSeg (sym);
+  return TRUE;
+}
+
+/*-----------------------------------------------------------------*/
+/* allocGlobal - assigns the output segment to a global var       */
+/*-----------------------------------------------------------------*/
+void
 allocGlobal (symbol * sym)
 {
 
   /* symbol name is internal name  */
-  if (!sym->level)             /* local statics can come here */
-    sprintf (sym->rname, "%s%s", port->fun_prefix, sym->name);
+  if (!sym->level)              /* local statics can come here */
+    SNPRINTF (sym->rname, sizeof(sym->rname),
+              "%s%s", port->fun_prefix, sym->name);
 
   /* add it to the operandKey reset */
-  addSet (&operKeyReset, sym);
+  if (!isinSet (operKeyReset, sym)) {
+    addSet(&operKeyReset, sym);
+  }
 
   /* if this is a literal e.g. enumerated type */
   /* put it in the data segment & do nothing   */
@@ -291,126 +506,65 @@ allocGlobal (symbol * sym)
       SPEC_OCLS (sym->etype) = code;
       /* if this is an interrupt service routine
          then put it in the interrupt service array */
-      if (IS_ISR (sym->etype))
-       {
-
-         if (interrupts[SPEC_INTN (sym->etype)])
-           werror (E_INT_DEFINED,
-                   SPEC_INTN (sym->etype),
-                   interrupts[SPEC_INTN (sym->etype)]->name);
-         else
-           interrupts[SPEC_INTN (sym->etype)] = sym;
-
-         /* automagically extend the maximum interrupts */
-         if (SPEC_INTN (sym->etype) >= maxInterrupts)
-           maxInterrupts = SPEC_INTN (sym->etype) + 1;
-       }
+      if (FUNC_ISISR (sym->type) && !options.noiv
+          && (FUNC_INTNO (sym->type) != INTNO_UNSPEC))
+            {
+          if (interrupts[FUNC_INTNO (sym->type)])
+            werror (E_INT_DEFINED,
+                    FUNC_INTNO (sym->type),
+                    interrupts[FUNC_INTNO (sym->type)]->name);
+          else
+            interrupts[FUNC_INTNO (sym->type)] = sym;
+
+          /* automagically extend the maximum interrupts */
+          if (FUNC_INTNO (sym->type) >= maxInterrupts)
+            maxInterrupts = FUNC_INTNO (sym->type) + 1;
+            }
       /* if it is not compiler defined */
       if (!sym->cdef)
-       allocIntoSeg (sym);
+        allocIntoSeg (sym);
 
       return;
     }
 
-  /* if this is a  SFR or SBIT */
-  if (SPEC_SCLS (sym->etype) == S_SFR ||
-      SPEC_SCLS (sym->etype) == S_SBIT)
-    {
-
-      /* if both absolute address & initial  */
-      /* value specified then error        */
-      if (IS_ABSOLUTE (sym->etype) && sym->ival)
-       {
-         werror (E_SFR_INIT, sym->name);
-         sym->ival = NULL;
-       }
-
-      SPEC_OCLS (sym->etype) =
-       (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
-
-      allocIntoSeg (sym);
-      return;
-    }
-
   /* if this is a bit variable and no storage class */
-  if (SPEC_NOUN (sym->etype) == V_BIT
-      && SPEC_SCLS (sym->etype) == S_BIT)
-    {
-      SPEC_OCLS (sym->etype) = bit;
-      allocIntoSeg (sym);
-      return;
-    }
-
-  /* if bit storage class */
-  if (SPEC_SCLS (sym->etype) == S_SBIT)
+  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;
     }
 
+  if(!TARGET_IS_PIC16 || (TARGET_IS_PIC16 && sym->level))
   /* register storage class ignored changed to FIXED */
   if (SPEC_SCLS (sym->etype) == S_REGISTER)
     SPEC_SCLS (sym->etype) = S_FIXED;
 
-  /* if data specified then  */
-  if (SPEC_SCLS (sym->etype) == S_DATA)
-    {
-      /* set the output class */
-      SPEC_OCLS (sym->etype) = data;
-      /* generate the symbol  */
-      allocIntoSeg (sym);
-      return;
-    }
-
   /* 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)
-    {
+      (TARGET_IS_PIC16 && (SPEC_SCLS (sym->etype) == S_REGISTER) && (sym->level==0)) ||
+      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) {
-    SPEC_OCLS (sym->etype) = statsg;
-    allocIntoSeg (sym);
-    return;
   }
 
-  if (SPEC_SCLS (sym->etype) == S_XDATA)
-    {
-      SPEC_OCLS (sym->etype) = xdata;
-      allocIntoSeg (sym);
-      return;
-    }
-
-  if (SPEC_SCLS (sym->etype) == S_IDATA)
-    {
-      SPEC_OCLS (sym->etype) = idata;
-      sym->iaccess = 1;
-      allocIntoSeg (sym);
-      return;
-    }
-
-  if (SPEC_SCLS (sym->etype) == S_EEPROM)
-    {
-      SPEC_OCLS (sym->etype) = eeprom;
-      allocIntoSeg (sym);
-      return;
-    }
-
+  allocDefault (sym);
   return;
 }
 
 /*-----------------------------------------------------------------*/
 /* allocParms - parameters are always passed on stack              */
 /*-----------------------------------------------------------------*/
-void 
+void
 allocParms (value * val)
 {
   value *lval;
@@ -418,7 +572,6 @@ allocParms (value * val)
 
   for (lval = val; lval; lval = lval->next, pNum++)
     {
-
       /* check the declaration */
       checkDecl (lval->sym, 0);
 
@@ -426,143 +579,160 @@ allocParms (value * val)
          it as a local variable by adding it
          to the first block we see in the body */
       if (IS_REGPARM (lval->etype))
-       continue;
+        continue;
 
       /* mark it as my parameter */
       lval->sym->ismyparm = 1;
       lval->sym->localof = currFunc;
 
-
       /* if automatic variables r 2b stacked */
-      if (options.stackAuto || IS_RENT (currFunc->etype))
-       {
-
-         if (lval->sym)
-           lval->sym->onStack = 1;
-
-         /* choose which stack 2 use   */
-         /*  use xternal stack */
-         if (options.useXstack)
-           {
-             /* PENDING: stack direction support */
-             SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
-             SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
-               xstackPtr - getSize (lval->type);
-             xstackPtr -= getSize (lval->type);
-           }
-         else
-           {                   /* use internal stack   */
-             SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
-             if (port->stack.direction > 0)
-               {
-                 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
-                   stackPtr - (SPEC_BANK (currFunc->etype) ? port->stack.bank_overhead : 0) -
-                   getSize (lval->type) -
-                   (IS_ISR (currFunc->etype) ? port->stack.isr_overhead : 0);
-                 stackPtr -= getSize (lval->type);
-               }
-             else
-               {
-                 /* This looks like the wrong order but it turns out OK... */
-                 /* PENDING: isr, bank overhead, ... */
-                 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
-                   stackPtr +
-                   (IS_BANKEDCALL (currFunc->etype) ? port->stack.banked_overhead : 0) +
-                   (IS_ISR (currFunc->etype) ? port->stack.isr_overhead : 0) +
-                   0;
-                 stackPtr += getSize (lval->type);
-               }
-           }
-         allocIntoSeg (lval->sym);
-       }
+      if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
+        {
+          if (lval->sym)
+            lval->sym->onStack = 1;
+
+          /* choose which stack 2 use   */
+          /*  use xternal stack */
+          if (options.useXstack)
+            {
+              /* PENDING: stack direction support */
+              SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
+              SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
+                xstackPtr - getSize (lval->type);
+              xstackPtr -= getSize (lval->type);
+            }
+          else
+            {                   /* use internal stack   */
+              SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
+              if (port->stack.direction > 0)
+                {
+                  SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
+                    stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
+                    getSize (lval->type) -
+                    (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
+                  stackPtr -= getSize (lval->type);
+                }
+              else
+                {
+                  /* This looks like the wrong order but it turns out OK... */
+                  /* PENDING: isr, bank overhead, ... */
+                  SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
+                    stackPtr +
+                    ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
+                    (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
+                    0;
+                  stackPtr += getSize (lval->type);
+                }
+            }
+          allocIntoSeg (lval->sym);
+        }
       else
-       { /* allocate them in the automatic space */
-         /* generate a unique name  */
-         sprintf (lval->sym->rname, "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
-         strcpy (lval->name, lval->sym->rname);
-         
-         /* if declared in external storage */
-         if (SPEC_SCLS (lval->etype) == S_XDATA)
-           SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
-         else
-           /* other wise 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;
-             }
-         allocIntoSeg (lval->sym);
-       }
+        { /* allocate them in the automatic space */
+          /* generate a unique name  */
+          SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname),
+                    "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
+          strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
+
+          /* if declared in specific storage */
+          if (allocDefault (lval->sym))
+            {
+              SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype);
+              continue;
+            }
+
+          /* 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;
 }
 
 /*-----------------------------------------------------------------*/
 /* deallocParms - parameters are always passed on stack                */
 /*-----------------------------------------------------------------*/
-void 
+void
 deallocParms (value * val)
 {
   value *lval;
 
   for (lval = val; lval; lval = lval->next)
     {
-
       /* 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;
-         werror (W_NO_REFERENCE, currFunc->name,
-                 "function argument", lval->sym->name);
-       }
+        {
+          lval->sym->allocreq = 0;
+            werror (W_NO_REFERENCE,
+                    currFunc ? currFunc->name : "(unknown)",
+                    "function argument", lval->sym->name);
+        }
 
       /* move the rname if any to the name for both val & sym */
       /* and leave a copy of it in the symbol table           */
       if (lval->sym->rname[0])
-       {
-         char buffer[SDCC_NAME_MAX];
-         strcpy (buffer, lval->sym->rname);
-         lval->sym = copySymbol (lval->sym);
-         strcpy (lval->sym->rname, buffer);
-         strcpy (lval->name, strcpy (lval->sym->name, lval->sym->rname));
-         addSym (SymbolTab, lval->sym, lval->sym->name,
-                 lval->sym->level, lval->sym->block, 1);
-         lval->sym->_isparm = 1;
-         addSet (&operKeyReset, lval->sym);
-       }
-
+        {
+          char buffer[SDCC_NAME_MAX];
+          symbol * argsym = lval->sym;
+
+          strncpyz (buffer, lval->sym->rname, sizeof(buffer));
+          lval->sym = copySymbol (lval->sym);
+          strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname));
+
+          strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name));
+          /* need to keep the original name for inlining to work */
+          /*strncpyz (lval->name, buffer, sizeof(lval->name)); */
+
+          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);
+            }
+
+          /* restore the original symbol */
+          lval->sym = argsym;
+        }
     }
-
   return;
 }
 
 /*-----------------------------------------------------------------*/
 /* allocLocal - allocate local variables                           */
 /*-----------------------------------------------------------------*/
-void 
+void
 allocLocal (symbol * sym)
 {
-
   /* generate an unique name */
-  sprintf (sym->rname, "%s%s_%s_%d_%d",
-          port->fun_prefix,
-          currFunc->name, sym->name, sym->level, sym->block);
+  SNPRINTF (sym->rname, sizeof(sym->rname),
+            "%s%s_%s_%d_%d",
+            port->fun_prefix,
+            currFunc->name, sym->name, sym->level, sym->block);
 
   sym->islocal = 1;
   sym->localof = currFunc;
@@ -581,7 +751,7 @@ allocLocal (symbol * sym)
 
   /* this is automatic           */
 
-  /* if it to be placed on the stack */
+  /* if it's to be placed on the stack */
   if (options.stackAuto || reentrant) {
     sym->onStack = 1;
     if (options.useXstack) {
@@ -592,38 +762,18 @@ allocLocal (symbol * sym)
     } else {
       SPEC_OCLS (sym->etype) = istack;
       if (port->stack.direction > 0) {
-       SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
-       stackPtr += getSize (sym->type);
+        SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
+        stackPtr += getSize (sym->type);
       } else {
-       stackPtr -= getSize (sym->type);
-       SPEC_STAK (sym->etype) = sym->stack = stackPtr;
+        stackPtr -= getSize (sym->type);
+        SPEC_STAK (sym->etype) = sym->stack = stackPtr;
       }
     }
     allocIntoSeg (sym);
     return;
   }
-  
-  /* else depending on the storage class specified */
-  if (SPEC_SCLS (sym->etype) == S_XDATA)
-    {
-      SPEC_OCLS (sym->etype) = xdata;
-      allocIntoSeg (sym);
-      return;
-    }
 
-  if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
-    SPEC_OCLS (sym->etype) = statsg;
-    allocIntoSeg (sym);
-    return;
-  }
-  
-  if (SPEC_SCLS (sym->etype) == S_IDATA)
-    {
-      SPEC_OCLS (sym->etype) = idata;
-      sym->iaccess = 1;
-      allocIntoSeg (sym);
-      return;
-    }
+  /* else depending on the storage class specified */
 
   /* if this is a function then assign code space    */
   if (IS_FUNC (sym->type))
@@ -632,58 +782,35 @@ allocLocal (symbol * sym)
       return;
     }
 
-  /* if this is a  SFR or SBIT */
-  if (SPEC_SCLS (sym->etype) == S_SFR ||
-      SPEC_SCLS (sym->etype) == S_SBIT)
-    {
-
-      /* if both absolute address & initial  */
-      /* value specified then error        */
-      if (IS_ABSOLUTE (sym->etype) && sym->ival)
-       {
-         werror (E_SFR_INIT, sym->name);
-         sym->ival = NULL;
-       }
-
-      SPEC_OCLS (sym->etype) =
-       (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
-
-      allocIntoSeg (sym);
-      return;
-    }
-
   /* 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_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);
       return;
     }
 
-  if (SPEC_SCLS (sym->etype) == S_EEPROM)
+  if (allocDefault (sym))
     {
-      SPEC_OCLS (sym->etype) = eeprom;
-      allocIntoSeg (sym);
       return;
     }
 
   /* again note that we have put it into the overlay segment
-     will remove and put into the 'data' segment if required after 
+     will remove and put into the 'data' segment if required after
      overlay  analysis has been done */
   if (options.model == MODEL_SMALL) {
-    SPEC_OCLS (sym->etype) = 
-      (options.noOverlay ? port->mem.default_local_map
-       : overlay);
+      SPEC_OCLS (sym->etype) =
+        (options.noOverlay ? port->mem.default_local_map : overlay);
   } else {
-    SPEC_OCLS (sym->etype) = port->mem.default_local_map;
+      SPEC_OCLS (sym->etype) = port->mem.default_local_map;
   }
   allocIntoSeg (sym);
 }
@@ -691,7 +818,7 @@ allocLocal (symbol * sym)
 /*-----------------------------------------------------------------*/
 /* deallocLocal - deallocates the local variables                  */
 /*-----------------------------------------------------------------*/
-void 
+void
 deallocLocal (symbol * csym)
 {
   symbol *sym;
@@ -699,20 +826,21 @@ deallocLocal (symbol * csym)
   for (sym = csym; sym; sym = sym->next)
     {
       if (sym->_isparm)
-       continue;
+        continue;
 
       /* if it is on the stack */
       if (sym->onStack)
-       {
-         if (options.useXstack)
-           xstackPtr -= getSize (sym->type);
-         else
-           stackPtr -= getSize (sym->type);
-       }
+        {
+          if (options.useXstack)
+            xstackPtr -= getSize (sym->type);
+          else
+            stackPtr -= getSize (sym->type);
+        }
       /* if not used give a warning */
       if (!sym->isref && !IS_STATIC (sym->etype))
-       werror (W_NO_REFERENCE, currFunc->name,
-               "local variable", sym->name);
+        werror (W_NO_REFERENCE,
+                currFunc ? currFunc->name : "(unknown)",
+                "local variable", sym->name);
       /* now delete it from the symbol table */
       deleteSym (SymbolTab, sym, sym->name);
     }
@@ -721,7 +849,7 @@ deallocLocal (symbol * csym)
 /*-----------------------------------------------------------------*/
 /* overlay2data - moves declarations from the overlay seg to data  */
 /*-----------------------------------------------------------------*/
-void 
+void
 overlay2data ()
 {
   symbol *sym;
@@ -734,7 +862,7 @@ overlay2data ()
       allocIntoSeg (sym);
     }
 
-  setToNull ((void **) &overlay->syms);
+  setToNull ((void *) &overlay->syms);
 
 }
 
@@ -742,7 +870,7 @@ overlay2data ()
 /* overlay2Set - will add all symbols from the overlay segment to  */
 /*               the set of sets containing the overlable symbols  */
 /*-----------------------------------------------------------------*/
-void 
+void
 overlay2Set ()
 {
   symbol *sym;
@@ -755,7 +883,7 @@ overlay2Set ()
       addSet (&oset, sym);
     }
 
-  setToNull ((void **) &overlay->syms);
+  setToNull ((void *) &overlay->syms);
   addSet (&ovrSetSets, oset);
 
 }
@@ -763,7 +891,7 @@ overlay2Set ()
 /*-----------------------------------------------------------------*/
 /* allocVariables - creates decl & assign storage class for a v    */
 /*-----------------------------------------------------------------*/
-int 
+int
 allocVariables (symbol * symChain)
 {
   symbol *sym;
@@ -778,60 +906,57 @@ allocVariables (symbol * symChain)
       /* if this is a typedef then add it */
       /* to the typedef table             */
       if (IS_TYPEDEF (sym->etype))
-       {
-         /* check if the typedef already exists    */
-         csym = findSym (TypedefTab, NULL, sym->name);
-         if (csym && csym->level == sym->level)
-           werror (E_DUPLICATE_TYPEDEF, sym->name);
-
-         addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
-         continue;             /* go to the next one         */
-       }
-      /* make sure it already exist */
+        {
+          /* check if the typedef already exists    */
+          csym = findSym (TypedefTab, NULL, sym->name);
+          if (csym && csym->level == sym->level)
+            werror (E_DUPLICATE_TYPEDEF, sym->name);
+
+          SPEC_EXTR (sym->etype) = 0;
+          addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
+          continue;             /* go to the next one */
+        }
+      /* make sure it already exists */
       csym = findSymWithLevel (SymbolTab, sym);
       if (!csym || (csym && csym->level != sym->level))
-       csym = sym;
+        csym = sym;
 
       /* check the declaration */
       checkDecl (csym,0);
 
-      /* if this is a function or a pointer to function */
-      /* then args  processing  */
+      /* if this is a function or a pointer to a */
+      /* function then do args processing        */
       if (funcInChain (csym->type))
-       {
-
-         processFuncArgs (csym, 1);
-         /* if register bank specified then update maxRegBank */
-         if (maxRegBank < SPEC_BANK (csym->etype))
-           maxRegBank = SPEC_BANK (csym->etype);
-       }
+        {
+          processFuncArgs (csym);
+        }
 
       /* if this is a extern variable then change the */
-      /* level to zero temporarily                                    */
+      /* level to zero temporarily                    */
       if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
-       {
-         saveLevel = csym->level;
-         csym->level = 0;
-       }
+        {
+          saveLevel = csym->level;
+          csym->level = 0;
+        }
 
       /* if this is a literal then it is an enumerated */
       /* type so need not allocate it space for it     */
       if (IS_LITERAL (sym->etype))
-       continue;
+        continue;
 
-      /* generate the actual declaration  */
+      /* generate the actual declaration */
       if (csym->level)
-       {
-         allocLocal (csym);
-         if (csym->onStack)
-           stack += getSize (csym->type);
-       }
+        {
+          allocLocal (csym);
+          if (csym->onStack)
+            stack += getSize (csym->type);
+        }
       else
-       allocGlobal (csym);
+        allocGlobal (csym);
 
       /* restore the level */
       if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
-       csym->level = saveLevel;
+        csym->level = saveLevel;
     }
 
   return stack;
@@ -840,7 +965,7 @@ allocVariables (symbol * symChain)
 /*-----------------------------------------------------------------*/
 /* redoStackOffsets :- will reassign the values for stack offsets  */
 /*-----------------------------------------------------------------*/
-void 
+void
 redoStackOffsets (void)
 {
   symbol *sym;
@@ -859,42 +984,42 @@ redoStackOffsets (void)
       int size = getSize (sym->type);
       /* nothing to do with parameters so continue */
       if ((sym->_isparm && !IS_REGPARM (sym->etype)))
-       continue;
+        continue;
 
       if (IS_AGGREGATE (sym->type))
-       {
-         if (port->stack.direction > 0)
-           {
-             SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
-             sPtr += size;
-           }
-         else
-           {
-             sPtr -= size;
-             SPEC_STAK (sym->etype) = sym->stack = sPtr;
-           }
-         continue;
-       }
+        {
+          if (port->stack.direction > 0)
+            {
+              SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
+              sPtr += size;
+            }
+          else
+            {
+              sPtr -= size;
+              SPEC_STAK (sym->etype) = sym->stack = sPtr;
+            }
+          continue;
+        }
 
       /* if allocation not required then subtract
          size from overall stack size & continue */
       if (!sym->allocreq)
-       {
-         currFunc->stack -= size;
-         SPEC_STAK (currFunc->etype) -= size;
-         continue;
-       }
+        {
+          currFunc->stack -= size;
+          SPEC_STAK (currFunc->etype) -= size;
+          continue;
+        }
 
       if (port->stack.direction > 0)
-       {
-         SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
-         sPtr += size;
-       }
+        {
+          SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
+          sPtr += size;
+        }
       else
-       {
-         sPtr -= size;
-         SPEC_STAK (sym->etype) = sym->stack = sPtr;
-       }
+        {
+          sPtr -= size;
+          SPEC_STAK (sym->etype) = sym->stack = sPtr;
+        }
     }
 
   /* do the same for the external stack */
@@ -906,47 +1031,35 @@ redoStackOffsets (void)
       int size = getSize (sym->type);
       /* nothing to do with parameters so continue */
       if ((sym->_isparm && !IS_REGPARM (sym->etype)))
-       continue;
+        continue;
 
       if (IS_AGGREGATE (sym->type))
-       {
-         SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
-         xsPtr += size;
-         continue;
-       }
+        {
+          SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
+          xsPtr += size;
+          continue;
+        }
 
       /* if allocation not required then subtract
          size from overall stack size & continue */
       if (!sym->allocreq)
-       {
-         currFunc->xstack -= size;
-         SPEC_STAK (currFunc->etype) -= size;
-         continue;
-       }
+        {
+          currFunc->xstack -= size;
+          SPEC_STAK (currFunc->etype) -= size;
+          continue;
+        }
 
       SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
       xsPtr += size;
     }
 
-  /* if the debug option is set then output the
-     symbols to the map file */
-  if (options.debug)
-    {
-      for (sym = setFirstItem (istack->syms); sym;
-          sym = setNextItem (istack->syms))
-       cdbSymbol (sym, cdbFile, FALSE, FALSE);
-
-      for (sym = setFirstItem (xstack->syms); sym;
-          sym = setNextItem (xstack->syms))
-       cdbSymbol (sym, cdbFile, FALSE, FALSE);
-    }
 }
 
 /*-----------------------------------------------------------------*/
 /* printAllocInfoSeg- print the allocation for a given section     */
 /*-----------------------------------------------------------------*/
-static void 
-printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
+static void
+printAllocInfoSeg (memmap * map, symbol * func, struct dbuf_s *oBuf)
 {
   symbol *sym;
 
@@ -960,39 +1073,48 @@ printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
     {
 
       if (sym->level == 0)
-       continue;
+        continue;
       if (sym->localof != func)
-       continue;
-      fprintf (of, ";%-25s Allocated to ", sym->name);
+        continue;
+
+      dbuf_printf (oBuf, ";%-25s Allocated ", sym->name);
 
       /* if assigned to registers */
       if (!sym->allocreq && sym->reqv)
-       {
-         int i;
-         sym = OP_SYMBOL (sym->reqv);
-         fprintf (of, "registers ");
-         for (i = 0; i < 4 && sym->regs[i]; i++)
-           fprintf (of, "%s ", port->getRegName (sym->regs[i]));
-         fprintf (of, "\n");
-         continue;
-       }
+        {
+          int i;
+
+          sym = OP_SYMBOL (sym->reqv);
+          if (!sym->isspilt || sym->remat)
+            {
+              dbuf_append_str (oBuf, "to registers ");
+              for (i = 0; i < 4 && sym->regs[i]; i++)
+                dbuf_printf (oBuf, "%s ", port->getRegName (sym->regs[i]));
+              dbuf_append_char (oBuf, '\n');
+              continue;
+            }
+          else
+            {
+              sym = sym->usl.spillLoc;
+            }
+        }
 
       /* if on stack */
       if (sym->onStack)
-       {
-         fprintf (of, "stack - offset %d\n", sym->stack);
-         continue;
-       }
+        {
+          dbuf_printf (oBuf, "to stack - offset %d\n", sym->stack);
+          continue;
+        }
 
       /* otherwise give rname */
-      fprintf (of, "in memory with name '%s'\n", sym->rname);
+      dbuf_printf (oBuf, "with name '%s'\n", sym->rname);
     }
 }
 
 /*-----------------------------------------------------------------*/
 /* canOverlayLocals - returns true if the local variables can overlayed */
 /*-----------------------------------------------------------------*/
-static bool 
+static bool
 canOverlayLocals (eBBlock ** ebbs, int count)
 {
   int i;
@@ -1002,12 +1124,15 @@ canOverlayLocals (eBBlock ** ebbs, int count)
   if (options.noOverlay ||
       options.stackAuto ||
       (currFunc &&
-       (IS_RENT (currFunc->etype) ||
-       IS_ISR (currFunc->etype))) ||
+       (IFFUNC_ISREENT (currFunc->type) ||
+        FUNC_ISISR (currFunc->type))) ||
       elementsInSet (overlay->syms) == 0)
 
     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 +1140,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 */
@@ -1026,9 +1156,13 @@ canOverlayLocals (eBBlock ** ebbs, int count)
 /*-----------------------------------------------------------------*/
 /* doOverlays - move the overlay segment to appropriate location   */
 /*-----------------------------------------------------------------*/
-void 
+void
 doOverlays (eBBlock ** ebbs, int count)
 {
+  if (!overlay) {
+    return;
+  }
+
   /* check if the parameters and local variables
      of this function can be put in the overlay segment
      This check is essentially to see if the function
@@ -1047,23 +1181,39 @@ doOverlays (eBBlock ** ebbs, int count)
 /*-----------------------------------------------------------------*/
 /* printAllocInfo - prints allocation information for a function   */
 /*-----------------------------------------------------------------*/
-void 
-printAllocInfo (symbol * func, FILE * of)
+void
+printAllocInfo (symbol * func, struct dbuf_s * oBuf)
 {
-  if (!of)
-    of = stdout;
+  if (!func)
+        return;
 
   /* 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;
+    set *tempOverlaySyms = overlay->syms;
+
+    /* search the set of overlay sets for local variables/parameters */
+    for (ovrset = setFirstItem (ovrSetSets); ovrset;
+         ovrset = setNextItem (ovrSetSets))
+      {
+        overlay->syms = ovrset;
+        printAllocInfoSeg (overlay, func, oBuf);
+      }
+    overlay->syms = tempOverlaySyms;
+  }
+
+  dbuf_append_str (oBuf, ";------------------------------------------------------------\n");
 }