Use 'ao-dbg' instead of 's51' to communicate with TeleMetrum
[fw/sdcc] / src / SDCCmem.c
index b3c8381f50cfae85bac5f6e1ad5e92e08ee72b86..5bc6bb92c31ea1354df22ec3801954349b6dbacc 100644 (file)
 /*-----------------------------------------------------------------*/
-/* SDCCmem.c - 8051 memory management routines                    */
+/* SDCCmem.c - 8051 memory management routines                     */
 /*-----------------------------------------------------------------*/
 
 #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;    
-
-extern set *operKeyReset ;
-extern set *tmpfileSet ;
-extern symbol *interrupts[];
-int maxRegBank = 0;
-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 */
-                 )
+set *ovrSetSets = NULL;
+
+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 */
+)
 {
-       memmap *map ;
-
-       if (!(map = GC_malloc(sizeof(memmap)))) {
-               werror(E_OUT_OF_MEM,__FILE__,sizeof(memmap));
-               exit (1);
-       }
-
-       memset(map, ZERO, sizeof(memmap));
-       map->regsp  =  rspace   ;
-       map->fmap   =  farmap   ;
-       map->paged   =  paged    ;
-       map->direct  =  direct   ;
-       map->bitsp  =  bitaddr  ;
-       map->codesp =  codemap  ;
-       map->sloc   =  sloc ;
-       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 ;
-       return map;
+  memmap *map;
+
+  if (!(map = Safe_alloc (sizeof (memmap))))
+    {
+      werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap));
+      exit (1);
+    }
+
+  memset (map, ZERO, sizeof (memmap));
+  map->regsp = rspace;
+  map->fmap = farmap;
+  map->paged = paged;
+  map->direct = direct;
+  map->bitsp = bitaddr;
+  map->codesp = codemap;
+  map->sloc = sloc;
+  map->sname = name;
+  map->dbName = dbName;
+  map->ptrType = ptrType;
+  map->syms = NULL;
+
+  dbuf_init(&map->oBuf, 4096);
+
+  return map;
 }
 
 /*-----------------------------------------------------------------*/
-/* initMem - allocates and initializes all the segments           */
-/*-----------------------------------------------------------------*/
-void initMem ()
-{      
-       /* allocate all the segments */
-       /* xternal stack segment ;   
-                  SFRSPACE       -   NO
-                  FAR-SPACE      -   YES
-                  PAGED          -   YES
-                  DIRECT-ACCESS  -   NO
-                  BIT-ACCESS     -   NO
-                  CODE-ACESS     -   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 ;   
-                  SFRSPACE       -   NO
-                  FAR-SPACE      -   NO
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   NO
-                  BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO 
-                  DEBUG-NAME     -   'B'
-                  POINTER-TYPE   -   POINTER
-       */
-       istack    = allocMap (0, 0, 0, 0, 0, 0,options.stack_loc, ISTACK_NAME,'B',POINTER);
-
-       /* code  segment ;   
-                  SFRSPACE       -   NO
-                  FAR-SPACE      -   YES
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   NO
-                  BIT-ACCESS     -   NO
-                  CODE-ACESS     -   YES 
-                  DEBUG-NAME     -   'C'
-                  POINTER-TYPE   -   CPOINTER
-       */
-       code      = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME,'C',CPOINTER);
-
-       /* home  segment ;   
-                  SFRSPACE       -   NO
-                  FAR-SPACE      -   YES
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   NO
-                  BIT-ACCESS     -   NO
-                  CODE-ACESS     -   YES 
-                  DEBUG-NAME     -   'C'
-                  POINTER-TYPE   -   CPOINTER
-       */
-       home      = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME,'C',CPOINTER);
-
-       /* Static segment (code for variables );
-                  SFRSPACE       -   NO
-                  FAR-SPACE      -   YES
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   NO
-                  BIT-ACCESS     -   NO
-                  CODE-ACESS     -   YES 
-                  DEBUG-NAME     -   'D'
-                  POINTER-TYPE   -   CPOINTER
-       */
-       statsg    = allocMap (0, 1, 0, 0, 0, 1,0, STATIC_NAME,'D',CPOINTER);
-
-       /* Data segment - internal storage segment ;
-                  SFRSPACE       -   NO
-                  FAR-SPACE      -   NO
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   YES
-                  BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO 
-                  DEBUG-NAME     -   'E'
-                  POINTER-TYPE   -   POINTER
-       */      
-       data      = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME,'E',POINTER);
-
-       /* overlay segment - same as internal storage segment ;
-                  SFRSPACE       -   NO
-                  FAR-SPACE      -   NO
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   YES
-                  BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO 
-                  DEBUG-NAME     -   'E'
-                  POINTER-TYPE   -   POINTER
-       */
-       overlay   = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME,'E',POINTER);
-
-       /* Xternal Data segment - 
-                  SFRSPACE       -   NO
-                  FAR-SPACE      -   YES
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   NO
-                  BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO 
-                  DEBUG-NAME     -   'F'
-                  POINTER-TYPE   -   FPOINTER
-       */
-       xdata     = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME,'F',FPOINTER);
-
-       /* Inderectly addressed internal data segment
-                  SFRSPACE       -   NO
-                  FAR-SPACE      -   NO
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   NO
-                  BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO 
-                  DEBUG-NAME     -   'G'
-                  POINTER-TYPE   -   IPOINTER
-       */
-       idata     = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc,IDATA_NAME,'G',IPOINTER);
-
-       /* Static segment (code for variables );
-                  SFRSPACE       -   NO
-                  FAR-SPACE      -   NO
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   YES
-                  BIT-ACCESS     -   YES
-                  CODE-ACESS     -   NO 
-                  DEBUG-NAME     -   'H'
-                  POINTER-TYPE   -  _NONE_
-       */
-       bit       = allocMap (0, 0, 0, 1, 1, 0,0, BIT_NAME,'H',0);
-       
-       /* Special function register space :-
-                  SFRSPACE       -   YES
-                  FAR-SPACE      -   NO
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   YES
-                  BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO 
-                  DEBUG-NAME     -   'I'
-                  POINTER-TYPE   -   _NONE_
-       */
-       sfr        = allocMap (1,0, 0, 1, 0, 0,0, REG_NAME,'I',0);
-
-       /* Register space ;
-                  SFRSPACE       -   YES
-                  FAR-SPACE      -   NO
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   NO
-                  BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO 
-                  DEBUG-NAME     -   ' '
-                  POINTER-TYPE   -   _NONE_
-       */
-       reg        = allocMap (1,0, 0, 0, 0, 0, 0,REG_NAME,' ',0);
-
-       /* SFR bit space 
-                  SFRSPACE       -   YES
-                  FAR-SPACE      -   NO
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   YES
-                  BIT-ACCESS     -   YES
-                  CODE-ACESS     -   NO 
-                  DEBUG-NAME     -   'J'
-                  POINTER-TYPE   -   _NONE_
-       */
-       sfrbit     = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,'J',0);
-
-       /* EEPROM bit space 
-                  SFRSPACE       -   NO
-                  FAR-SPACE      -   YES
-                  PAGED          -   NO
-                  DIRECT-ACCESS  -   NO
-                  BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO 
-                  DEBUG-NAME     -   'K'
-                  POINTER-TYPE   -   EEPPOINTER
-       */
-       eeprom     = allocMap (0,1, 0, 0, 0, 0,0, REG_NAME,'K',EEPPOINTER);
-
-       /* the unknown map */
-       generic     = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,' ',GPOINTER);
-       
+/* initMem - allocates and initializes all the segments            */
+/*-----------------------------------------------------------------*/
+void
+initMem ()
+{
+  /* allocate all the segments */
+  /* xternal stack segment ;
+     SFRSPACE       -   NO
+     FAR-SPACE      -   YES
+     PAGED          -   YES
+     DIRECT-ACCESS  -   NO
+     BIT-ACCESS     -   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 ;
+     SFRSPACE       -   NO
+     FAR-SPACE      -   NO
+     PAGED          -   NO
+     DIRECT-ACCESS  -   NO
+     BIT-ACCESS     -   NO
+     CODE-ACCESS    -   NO
+     DEBUG-NAME     -   'B'
+     POINTER-TYPE   -   POINTER
+   */
+  if (ISTACK_NAME)
+    {
+      istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER);
+    }
+  else
+    {
+      istack = NULL;
+    }
+
+  /* code  segment ;
+     SFRSPACE       -   NO
+     FAR-SPACE      -   YES
+     PAGED          -   NO
+     DIRECT-ACCESS  -   NO
+     BIT-ACCESS     -   NO
+     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 ;
+     SFRSPACE       -   NO
+     FAR-SPACE      -   YES
+     PAGED          -   NO
+     DIRECT-ACCESS  -   NO
+     BIT-ACCESS     -   NO
+     CODE-ACCESS    -   YES
+     DEBUG-NAME     -   'C'
+     POINTER-TYPE   -   CPOINTER
+   */
+  home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, HOME_NAME, 'C', CPOINTER);
+
+  /* Static segment (code for variables );
+     SFRSPACE       -   NO
+     FAR-SPACE      -   YES
+     PAGED          -   NO
+     DIRECT-ACCESS  -   NO
+     BIT-ACCESS     -   NO
+     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-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-ACCESS    -   NO
+     DEBUG-NAME     -   'E'
+     POINTER-TYPE   -   POINTER
+   */
+  if (OVERLAY_NAME)
+    {
+      overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
+    }
+  else
+    {
+      overlay = NULL;
+    }
+
+  /* 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-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);
+
+  /* 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-ACCESS    -   NO
+     DEBUG-NAME     -   'G'
+     POINTER-TYPE   -   IPOINTER
+   */
+  if (IDATA_NAME)
+    {
+      idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER);
+    }
+  else
+    {
+      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
+     PAGED          -   NO
+     DIRECT-ACCESS  -   YES
+     BIT-ACCESS     -   YES
+     CODE-ACCESS    -   NO
+     DEBUG-NAME     -   'H'
+     POINTER-TYPE   -  _NONE_
+   */
+  bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0);
+
+  /* Special function register space :-
+     SFRSPACE       -   YES
+     FAR-SPACE      -   NO
+     PAGED          -   NO
+     DIRECT-ACCESS  -   YES
+     BIT-ACCESS     -   NO
+     CODE-ACCESS    -   NO
+     DEBUG-NAME     -   'I'
+     POINTER-TYPE   -   _NONE_
+   */
+  sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0);
+
+  /* Register space ;
+     SFRSPACE       -   YES
+     FAR-SPACE      -   NO
+     PAGED          -   NO
+     DIRECT-ACCESS  -   NO
+     BIT-ACCESS     -   NO
+     CODE-ACCESS    -   NO
+     DEBUG-NAME     -   ' '
+     POINTER-TYPE   -   _NONE_
+   */
+  reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
+
+  /* SFR bit space
+     SFRSPACE       -   YES
+     FAR-SPACE      -   NO
+     PAGED          -   NO
+     DIRECT-ACCESS  -   YES
+     BIT-ACCESS     -   YES
+     CODE-ACCESS    -   NO
+     DEBUG-NAME     -   'J'
+     POINTER-TYPE   -   _NONE_
+   */
+  sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
+
+  /* EEPROM space
+     SFRSPACE       -   NO
+     FAR-SPACE      -   YES
+     PAGED          -   NO
+     DIRECT-ACCESS  -   NO
+     BIT-ACCESS     -   NO
+     CODE-ACCESS    -   NO
+     DEBUG-NAME     -   'K'
+     POINTER-TYPE   -   EEPPOINTER
+   */
+  eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER);
+
+  /* the unknown map */
+  generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER);
+
 }
 
 /*-----------------------------------------------------------------*/
 /* allocIntoSeg - puts a symbol into a memory segment              */
 /*-----------------------------------------------------------------*/
-void allocIntoSeg (symbol *sym) 
+void
+allocIntoSeg (symbol * sym)
+{
+  memmap *segment = SPEC_OCLS (sym->etype);
+  addSet (&segment->syms, sym);
+  if (segment == pdata)
+    sym->iaccess = 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* deleteFromSeg - deletes a symbol from segment used when a var   */
+/*                 first declared as "extern" then no extern       */
+/*-----------------------------------------------------------------*/
+void deleteFromSeg(symbol *sym)
 {
-    memmap *segment = SPEC_OCLS(sym->etype);
-    addSet (&segment->syms,sym);
+    if (SPEC_OCLS(sym->etype)) {
+        memmap *segment = SPEC_OCLS (sym->etype);
+        deleteSetItem(&segment->syms,sym);
+    }
 }
 
 /*-----------------------------------------------------------------*/
-/* allocGlobal - aassigns the output segment to a global var      */
+/* allocDefault - assigns the output segment based on SCLASS       */
 /*-----------------------------------------------------------------*/
-void allocGlobal ( symbol *sym )
+bool
+allocDefault (symbol * sym)
 {
-    /* symbol name is internal name  */
-    sprintf (sym->rname,"%s%s", port->fun_prefix, sym->name);
-    
-    /* add it to the operandKey reset */
-    addSet(&operKeyReset,sym);
-        
-    /* if this is a literal e.g. enumerated type */
-    /* put it in the data segment & do nothing   */
-    if (IS_LITERAL(sym->etype)) {
-       SPEC_OCLS(sym->etype) = data ;
-       return ;
-    }
-       
-    /* if this is a function then assign code space    */
-    if (IS_FUNC(sym->type)) {
-       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 it is not compiler defined */
-       if (!sym->cdef)
-           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 ) {
-       SPEC_OCLS(sym->etype) = bit;
-       allocIntoSeg(sym);
-       return ;
-    }
-    
-    /* 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        */
-    if ( SPEC_SCLS(sym->etype) == S_FIXED  ||
-        SPEC_SCLS(sym->etype) == S_AUTO   ) {
-       /* set the output class */
-       SPEC_OCLS(sym->etype) = port->mem.default_globl_map ;
-       /* generate the symbol  */
-       allocIntoSeg  (sym) ;
-       return   ;
-    }
-    
-    /* if code change to constant */
-    if ( SPEC_SCLS(sym->etype) == S_CODE   ||
-        SPEC_SCLS(sym->etype) == S_CONSTANT )  {
-       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 ;
-    }
-    
-    return ;
+  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 */
+    SNPRINTF (sym->rname, sizeof(sym->rname),
+              "%s%s", port->fun_prefix, sym->name);
+
+  /* add it to the operandKey reset */
+  if (!isinSet (operKeyReset, sym)) {
+    addSet(&operKeyReset, sym);
+  }
+
+  /* if this is a literal e.g. enumerated type */
+  /* put it in the data segment & do nothing   */
+  if (IS_LITERAL (sym->etype))
+    {
+      SPEC_OCLS (sym->etype) = data;
+      return;
+    }
+
+  /* if this is a function then assign code space    */
+  if (IS_FUNC (sym->type))
+    {
+      SPEC_OCLS (sym->etype) = code;
+      /* if this is an interrupt service routine
+         then put it in the interrupt service array */
+      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);
+
+      return;
+    }
+
+  /* if this is a bit variable and no storage class */
+  if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
+      /*&& SPEC_SCLS (sym->etype) == S_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 it is fixed, then allocate depending on the  */
+  /* current memory model, same for automatics        */
+  if (SPEC_SCLS (sym->etype) == S_FIXED ||
+      (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;
+    }
+  }
+
+  allocDefault (sym);
+  return;
 }
 
 /*-----------------------------------------------------------------*/
-/* allocParms - parameters are always passed on stack             */
+/* allocParms - parameters are always passed on stack              */
 /*-----------------------------------------------------------------*/
-void allocParms ( value  *val )
+void
+allocParms (value * val)
 {
-    value    *lval ;   
-    int      pNum = 1;
-
-    for ( lval = val ; lval ; lval = lval->next, pNum++ ) {
-
-       /* check the declaration */
-       checkDecl (lval->sym);
-       
-       /* if this a register parm then allocate
-          it as a local variable by adding it
-          to the first block we see in the body */
-       if (IS_REGPARM(lval->etype)) 
-           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);
-       }
-       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 */
-               SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = 
-                   ( options.model  ? port->mem.default_local_map : 
-                     (options.noOverlay ? port->mem.default_local_map
-                      :overlay ));
-           
-           allocIntoSeg(lval->sym);
-       }
-    }
-    
-    return ;
+  value *lval;
+  int pNum = 1;
+
+  for (lval = val; lval; lval = lval->next, pNum++)
+    {
+      /* check the declaration */
+      checkDecl (lval->sym, 0);
+
+      /* if this a register parm then allocate
+         it as a local variable by adding it
+         to the first block we see in the body */
+      if (IS_REGPARM (lval->etype))
+        continue;
+
+      /* mark it as my parameter */
+      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;
+
+          /* 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  */
+          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               */
+/* deallocParms - parameters are always passed on stack                */
 /*-----------------------------------------------------------------*/
-void  deallocParms ( value *val )
+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);
-       }
-
-       /* 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);     
-           lval->sym->_isparm = 1;
-           addSet(&operKeyReset,lval->sym);
-       }
-
-    }
-    
-    return ;
+  value *lval;
+
+  for (lval = val; lval; lval = lval->next)
+    {
+      /* unmark is myparm */
+      lval->sym->ismyparm = 0;
+
+      /* delete it from the symbol table  */
+      deleteSym (SymbolTab, lval->sym, lval->sym->name);
+
+      if (!lval->sym->isref)
+        {
+          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];
+          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 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);
-    
-    sym->islocal = 1;
-    sym->localof = currFunc;
-
-    /* if this is a static variable */
-    if ( IS_STATIC (sym->etype)) {
-/*     SPEC_OCLS(sym->etype) = (options.model ? xdata : data ); */
-       SPEC_OCLS(sym->etype) = port->mem.default_local_map;
-       allocIntoSeg (sym);
-        sym->allocreq = 1;
-       return   ;
-    }
-    
-    /* if volatile then */
-    if (IS_VOLATILE(sym->etype))
-       sym->allocreq = 1;
-
-    /* this is automatic          */
-
-    /* if it to be placed on the stack */
-    if ( options.stackAuto || reentrant) {
-              
-       sym->onStack = 1;
-       if ( options.useXstack ) { 
-           /* PENDING: stack direction for xstack */
-           SPEC_OCLS(sym->etype) = xstack ;
-           SPEC_STAK(sym->etype) = sym->stack = (xstackPtr + 1);
-           xstackPtr += getSize (sym->type) ;
-       }
-       else {
-           SPEC_OCLS(sym->etype) = istack ;
-           if (port->stack.direction > 0) {
-               SPEC_STAK(sym->etype) = sym->stack = ( stackPtr + 1);
-               stackPtr += getSize (sym->type) ;
-           }
-           else {
-               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   ||
-         SPEC_SCLS(sym->etype) == S_CONSTANT) &&
-        !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 ;
-    }    
-
-        /* if this is a function then assign code space    */
-    if (IS_FUNC(sym->type)) {
-       SPEC_OCLS(sym->etype)  = code ;
-       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 ( SPEC_SCLS(sym->etype) == S_DATA  ) {
-       SPEC_OCLS(sym->etype) = (options.noOverlay ? data : overlay );
-       allocIntoSeg(sym)  ;
-       return ;
-    }
-
-    if ( SPEC_SCLS(sym->etype) == S_EEPROM  ) {
-       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 
-       overlay  analysis has been done */   
-    SPEC_OCLS(sym->etype) = ( options.model  ? port->mem.default_local_map : 
-                             (options.noOverlay ? port->mem.default_local_map
-                              : overlay )) ;
-    allocIntoSeg (sym); 
+/* allocLocal - allocate local variables                           */
+/*-----------------------------------------------------------------*/
+void
+allocLocal (symbol * sym)
+{
+  /* generate an unique name */
+  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;
+
+  /* if this is a static variable */
+  if (IS_STATIC (sym->etype))
+    {
+      allocGlobal (sym);
+      sym->allocreq = 1;
+      return;
+    }
+
+  /* if volatile then */
+  if (IS_VOLATILE (sym->etype))
+    sym->allocreq = 1;
+
+  /* this is automatic           */
+
+  /* if it's to be placed on the stack */
+  if (options.stackAuto || reentrant) {
+    sym->onStack = 1;
+    if (options.useXstack) {
+      /* PENDING: stack direction for xstack */
+      SPEC_OCLS (sym->etype) = xstack;
+      SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
+      xstackPtr += getSize (sym->type);
+    } else {
+      SPEC_OCLS (sym->etype) = istack;
+      if (port->stack.direction > 0) {
+        SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
+        stackPtr += getSize (sym->type);
+      } else {
+        stackPtr -= getSize (sym->type);
+        SPEC_STAK (sym->etype) = sym->stack = stackPtr;
+      }
+    }
+    allocIntoSeg (sym);
+    return;
+  }
+
+  /* else depending on the storage class specified */
+
+  /* if this is a function then assign code space    */
+  if (IS_FUNC (sym->type))
+    {
+      SPEC_OCLS (sym->etype) = code;
+      return;
+    }
+
+  /* if this is a bit variable and no storage class */
+  if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
+    {
+      SPEC_SCLS (sym->type) = S_BIT;
+      SPEC_OCLS (sym->type) = bit;
+      allocIntoSeg (sym);
+      return;
+    }
+
+  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 (allocDefault (sym))
+    {
+      return;
+    }
+
+  /* again note that we have put it into the overlay segment
+     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);
+  } else {
+      SPEC_OCLS (sym->etype) = port->mem.default_local_map;
+  }
+  allocIntoSeg (sym);
 }
 
 /*-----------------------------------------------------------------*/
 /* deallocLocal - deallocates the local variables                  */
 /*-----------------------------------------------------------------*/
-void  deallocLocal ( symbol *csym )
+void
+deallocLocal (symbol * csym)
 {
-    symbol *sym ;
-    
-    for ( sym = csym ; sym ; sym = sym->next) {
-       if (sym->_isparm)
-           continue ;
-
-       /* if it is on the stack */
-       if (sym->onStack) { 
-           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);
-       /* now delete it from the symbol table */
-       deleteSym (SymbolTab,sym,sym->name);    
+  symbol *sym;
+
+  for (sym = csym; sym; sym = sym->next)
+    {
+      if (sym->_isparm)
+        continue;
+
+      /* if it is on the stack */
+      if (sym->onStack)
+        {
+          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 ? currFunc->name : "(unknown)",
+                "local variable", sym->name);
+      /* now delete it from the symbol table */
+      deleteSym (SymbolTab, sym, sym->name);
     }
 }
 
 /*-----------------------------------------------------------------*/
 /* overlay2data - moves declarations from the overlay seg to data  */
 /*-----------------------------------------------------------------*/
-void overlay2data()
+void
+overlay2data ()
 {
-    symbol *sym;
+  symbol *sym;
 
-    for (sym = setFirstItem(overlay->syms); sym;
-        sym = setNextItem(overlay->syms)) {
+  for (sym = setFirstItem (overlay->syms); sym;
+       sym = setNextItem (overlay->syms))
+    {
 
-       SPEC_OCLS(sym->etype) = data;
-       allocIntoSeg(sym);
+      SPEC_OCLS (sym->etype) = data;
+      allocIntoSeg (sym);
     }
 
-    setToNull((void **) &overlay->syms);
-       
+  setToNull ((void *) &overlay->syms);
+
 }
 
 /*-----------------------------------------------------------------*/
 /* overlay2Set - will add all symbols from the overlay segment to  */
 /*               the set of sets containing the overlable symbols  */
 /*-----------------------------------------------------------------*/
-void overlay2Set ()
+void
+overlay2Set ()
 {
-    symbol *sym;
-    set *oset = NULL;
+  symbol *sym;
+  set *oset = NULL;
 
-    for (sym = setFirstItem(overlay->syms); sym;
-        sym = setNextItem(overlay->syms)) {
+  for (sym = setFirstItem (overlay->syms); sym;
+       sym = setNextItem (overlay->syms))
+    {
 
-       addSet(&oset,sym);
+      addSet (&oset, sym);
     }
-    
-    setToNull((void **) &overlay->syms);
-    addSet (&ovrSetSets,oset);
+
+  setToNull ((void *) &overlay->syms);
+  addSet (&ovrSetSets, oset);
 
 }
 
 /*-----------------------------------------------------------------*/
 /* allocVariables - creates decl & assign storage class for a v    */
 /*-----------------------------------------------------------------*/
-int allocVariables ( symbol *symChain )
+int
+allocVariables (symbol * symChain)
 {
-    symbol   *sym;
-    symbol   *csym;
-    int      stack = 0;    
-    int             saveLevel = 0 ;
-    
-    /* go thru the symbol chain   */
-    for ( sym = symChain ; sym ;  sym = sym->next   ) {
-       
-       /* 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);
-           continue ;  /* go to the next one         */
-       }
-       /* make sure it already exist */
-       csym = findSymWithLevel (SymbolTab, sym);
-       if (! csym || (csym && csym->level != sym->level) )
-           csym = sym;
-               
-       /* check the declaration */
-       checkDecl   (csym);
-               
-       /* if this is a function or a pointer to function */
-       /* then 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);
-       }
-       
-       /* if this is a extern variable then change the */
-       /* level to zero temporarily                                    */
-       if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type) ) {
-           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 ;
-       
-       /* generate the actual declaration  */
-       if ( csym->level  ) {
-           allocLocal  (csym);
-           if (csym->onStack)
-               stack += getSize(csym->type) ;              
-       }
-       else 
-           allocGlobal (csym);
-
-       /* restore the level */
-       if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type)) 
-           csym->level = saveLevel;            
-    }
-    
-    return stack ;
+  symbol *sym;
+  symbol *csym;
+  int stack = 0;
+  int saveLevel = 0;
+
+  /* go thru the symbol chain   */
+  for (sym = symChain; sym; sym = sym->next)
+    {
+
+      /* 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);
+
+          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;
+
+      /* check the declaration */
+      checkDecl (csym,0);
+
+      /* if this is a function or a pointer to a */
+      /* function then do args processing        */
+      if (funcInChain (csym->type))
+        {
+          processFuncArgs (csym);
+        }
+
+      /* if this is a extern variable then change the */
+      /* level to zero temporarily                    */
+      if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
+        {
+          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;
+
+      /* generate the actual declaration */
+      if (csym->level)
+        {
+          allocLocal (csym);
+          if (csym->onStack)
+            stack += getSize (csym->type);
+        }
+      else
+        allocGlobal (csym);
+
+      /* restore the level */
+      if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
+        csym->level = saveLevel;
+    }
+
+  return stack;
 }
 
 /*-----------------------------------------------------------------*/
 /* redoStackOffsets :- will reassign the values for stack offsets  */
 /*-----------------------------------------------------------------*/
-void redoStackOffsets ()
+void
+redoStackOffsets (void)
 {
-    symbol *sym;
-    int sPtr = 0;
-    int xsPtr=-1;
-
-    /* after register allocation is complete we know
-       which variables will need to be assigned space
-       on the stack. We will eliminate those variables
-       which do not have the allocReq flag thus reducing
-       the stack space */
-    for ( sym = setFirstItem(istack->syms); sym;
-         sym = setNextItem(istack->syms)) {
-       
-       int size = getSize(sym->type);
-       /* nothing to do with parameters so continue */
-       if ((sym->_isparm && !IS_REGPARM(sym->etype)))
-           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 allocation not required then subtract
-          size from overall stack size & continue */   
-       if (!sym->allocreq) {
-           currFunc->stack -= size;
-           SPEC_STAK(currFunc->etype) -= size;
-           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;
-       }
-    }
-
-    /* do the same for the external stack */
-    
-    for ( sym = setFirstItem(xstack->syms); sym;
-         sym = setNextItem(xstack->syms)) {
-       
-       int size  = getSize(sym->type);
-       /* nothing to do with parameters so continue */
-       if ((sym->_isparm && !IS_REGPARM(sym->etype)))
-           continue ;
-       
-       if (IS_AGGREGATE(sym->type)) {
-           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 ;
-       }
-
-       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 && !options.nodebug) {
-       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); 
+  symbol *sym;
+  int sPtr = 0;
+  int xsPtr = -1;
+
+  /* after register allocation is complete we know
+     which variables will need to be assigned space
+     on the stack. We will eliminate those variables
+     which do not have the allocReq flag thus reducing
+     the stack space */
+  for (sym = setFirstItem (istack->syms); sym;
+       sym = setNextItem (istack->syms))
+    {
+
+      int size = getSize (sym->type);
+      /* nothing to do with parameters so continue */
+      if ((sym->_isparm && !IS_REGPARM (sym->etype)))
+        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 allocation not required then subtract
+         size from overall stack size & continue */
+      if (!sym->allocreq)
+        {
+          currFunc->stack -= size;
+          SPEC_STAK (currFunc->etype) -= size;
+          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;
+        }
+    }
+
+  /* do the same for the external stack */
+
+  for (sym = setFirstItem (xstack->syms); sym;
+       sym = setNextItem (xstack->syms))
+    {
+
+      int size = getSize (sym->type);
+      /* nothing to do with parameters so continue */
+      if ((sym->_isparm && !IS_REGPARM (sym->etype)))
+        continue;
+
+      if (IS_AGGREGATE (sym->type))
+        {
+          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;
+        }
+
+      SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
+      xsPtr += size;
     }
+
 }
 
 /*-----------------------------------------------------------------*/
 /* 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;
+
+  if (!map)
+    return;
+  if (!map->syms)
+    return;
+
+  for (sym = setFirstItem (map->syms); sym;
+       sym = setNextItem (map->syms))
+    {
+
+      if (sym->level == 0)
+        continue;
+      if (sym->localof != func)
+        continue;
+
+      dbuf_printf (oBuf, ";%-25s Allocated ", sym->name);
+
+      /* if assigned to registers */
+      if (!sym->allocreq && sym->reqv)
+        {
+          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)
+        {
+          dbuf_printf (oBuf, "to stack - offset %d\n", sym->stack);
+          continue;
+        }
+
+      /* otherwise give rname */
+      dbuf_printf (oBuf, "with name '%s'\n", sym->rname);
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* canOverlayLocals - returns true if the local variables can overlayed */
+/*-----------------------------------------------------------------*/
+static bool
+canOverlayLocals (eBBlock ** ebbs, int count)
 {
-    symbol *sym;
-    
-    if (!map) return;
-    if (!map->syms) return;
-
-    for (sym = setFirstItem(map->syms); sym;
-        sym = setNextItem(map->syms)) {
-       
-       if (sym->level == 0) continue;
-       if (sym->localof != func) continue ;
-       fprintf(of,";%-25s Allocated to ",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 ;
-       }
-
-       /* if on stack */
-       if (sym->onStack) {
-           fprintf(of,"stack - offset %d\n",sym->stack);
-           continue;
-       }
-       
-       /* otherwise give rname */
-       fprintf(of,"in memory with name '%s'\n",sym->rname);
+  int i;
+  /* if staticAuto is in effect or the current function
+     being compiled is reentrant or the overlay segment
+     is empty or no overlay option is in effect then */
+  if (options.noOverlay ||
+      options.stackAuto ||
+      (currFunc &&
+       (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++)
+    {
+      iCode *ic;
+
+      for (ic = ebbs[i]->sch; ic; ic = ic->next)
+          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 */
+  return TRUE;
+}
+
+/*-----------------------------------------------------------------*/
+/* doOverlays - move the overlay segment to appropriate location   */
+/*-----------------------------------------------------------------*/
+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
+     calls any other functions if yes then we cannot
+     overlay */
+  if (canOverlayLocals (ebbs, count))
+    /* if we can then put the parameters &
+       local variables in the overlay set */
+    overlay2Set ();
+  else
+    /* otherwise put them into data where
+       they belong */
+    overlay2data ();
 }
 
 /*-----------------------------------------------------------------*/
 /* 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;
-
-    /* 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);
+  if (!func)
+        return;
+
+  /* must be called after register allocation is complete */
+  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");
 }