options.model specific fixes
[fw/sdcc] / src / SDCCmem.c
index e284d32dfa8c5aaded0c11b1258cd0c42f2c21e0..2fb79e0b992642998610d07f1a6bd05da71ab147 100644 (file)
@@ -6,10 +6,10 @@
 
 /* memory segments */
 memmap  *xstack= NULL ;         /* xternal stack data         */
-memmap  *istack= NULL;  /* internal stack                 */
-memmap  *code  = NULL;  /* code segment                   */
+memmap  *istack= NULL;  /* internal stack             */
+memmap  *code  = NULL;  /* code segment               */
 memmap  *data  = NULL;  /* internal data upto 128     */
-memmap  *xdata = NULL;  /* external data                          */
+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  */
@@ -18,6 +18,8 @@ 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 */
@@ -30,7 +32,7 @@ int maxRegBank = 0;
 int fatalError = 0                      ;/* fatal error flag                   */
 
 /*-----------------------------------------------------------------*/
-/* allocMap - allocates a memory map                                                      */
+/* allocMap - allocates a memory map                              */
 /*-----------------------------------------------------------------*/
 memmap *allocMap (char rspace,     /* sfr space            */
                   char farmap,     /* far or near segment  */
@@ -40,7 +42,8 @@ memmap *allocMap (char rspace,     /* sfr space            */
                  char codemap,    /* this is code space   */
                  unsigned sloc,   /* starting location    */
                  const char *name,      /* 2 character name     */
-                 char dbName     
+                 char dbName    , /* debug name                 */
+                 int  ptrType     /* pointer type for this space */
                  )
 {
        memmap *map ;
@@ -60,7 +63,8 @@ memmap *allocMap (char rspace,     /* sfr space            */
        map->sloc   =  sloc ;
        map->sname = name ;
        map->dbName = dbName ;
-       if (!(map->oFile = tmpfile())) {
+       map->ptrType= ptrType;
+       if (!(map->oFile = tempfile())) {
                werror(E_TMPFILE_FAILED);
                exit (1);
        } 
@@ -74,7 +78,6 @@ memmap *allocMap (char rspace,     /* sfr space            */
 /*-----------------------------------------------------------------*/
 void initMem ()
 {      
-       
        /* allocate all the segments */
        /* xternal stack segment ;   
                   SFRSPACE       -   NO
@@ -82,8 +85,11 @@ void initMem ()
                   PAGED          -   YES
                   DIRECT-ACCESS  -   NO
                   BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO */
-       xstack    = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME,'A');
+                  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
@@ -91,8 +97,11 @@ void initMem ()
                   PAGED          -   NO
                   DIRECT-ACCESS  -   NO
                   BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO */
-       istack    = allocMap (0, 0, 0, 0, 0, 0,options.stack_loc, ISTACK_NAME,'B');
+                  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
@@ -100,8 +109,23 @@ void initMem ()
                   PAGED          -   NO
                   DIRECT-ACCESS  -   NO
                   BIT-ACCESS     -   NO
-                  CODE-ACESS     -   YES */
-       code      = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME,'C');
+                  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
@@ -109,8 +133,11 @@ void initMem ()
                   PAGED          -   NO
                   DIRECT-ACCESS  -   NO
                   BIT-ACCESS     -   NO
-                  CODE-ACESS     -   YES */
-       statsg    = allocMap (0, 1, 0, 0, 0, 1,0, STATIC_NAME,'D');
+                  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
@@ -118,8 +145,11 @@ void initMem ()
                   PAGED          -   NO
                   DIRECT-ACCESS  -   YES
                   BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO */     
-       data      = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME,'E');
+                  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
@@ -127,8 +157,11 @@ void initMem ()
                   PAGED          -   NO
                   DIRECT-ACCESS  -   YES
                   BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO */     
-       overlay   = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME,'E');
+                  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
@@ -136,8 +169,11 @@ void initMem ()
                   PAGED          -   NO
                   DIRECT-ACCESS  -   NO
                   BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO */
-       xdata     = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME,'F' );
+                  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
@@ -145,8 +181,11 @@ void initMem ()
                   PAGED          -   NO
                   DIRECT-ACCESS  -   NO
                   BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO */
-       idata     = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc,IDATA_NAME,'G' );
+                  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
@@ -154,8 +193,11 @@ void initMem ()
                   PAGED          -   NO
                   DIRECT-ACCESS  -   YES
                   BIT-ACCESS     -   YES
-                  CODE-ACESS     -   NO */
-       bit       = allocMap (0, 0, 0, 1, 1, 0,0, BIT_NAME,'H');
+                  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
@@ -163,8 +205,11 @@ void initMem ()
                   PAGED          -   NO
                   DIRECT-ACCESS  -   YES
                   BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO */
-       sfr        = allocMap (1,0, 0, 1, 0, 0,0, REG_NAME,'I');
+                  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
@@ -172,8 +217,11 @@ void initMem ()
                   PAGED          -   NO
                   DIRECT-ACCESS  -   NO
                   BIT-ACCESS     -   NO
-                  CODE-ACESS     -   NO */
-       reg        = allocMap (1,0, 0, 0, 0, 0, 0,REG_NAME,' ');
+                  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
@@ -181,12 +229,27 @@ void initMem ()
                   PAGED          -   NO
                   DIRECT-ACCESS  -   YES
                   BIT-ACCESS     -   YES
-                  CODE-ACESS     -   NO */
-       sfrbit     = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,'J' );
+                  CODE-ACESS     -   NO 
+                  DEBUG-NAME     -   'J'
+                  POINTER-TYPE   -   _NONE_
+       */
+       sfrbit     = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,'J',0);
 
-       /* the unknown map */
-       generic     = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,' ' );
+       /* 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);
+       
 }
 
 /*-----------------------------------------------------------------*/
@@ -195,7 +258,6 @@ void initMem ()
 void allocIntoSeg (symbol *sym) 
 {
     memmap *segment = SPEC_OCLS(sym->etype);
-
     addSet (&segment->syms,sym);
 }
 
@@ -205,7 +267,7 @@ void allocIntoSeg (symbol *sym)
 void allocGlobal ( symbol *sym )
 {
     /* symbol name is internal name  */
-    sprintf (sym->rname,"_%s",sym->name);
+    sprintf (sym->rname,"%s%s", port->fun_prefix, sym->name);
     
     /* add it to the operandKey reset */
     addSet(&operKeyReset,sym);
@@ -293,7 +355,7 @@ void allocGlobal ( symbol *sym )
     if ( SPEC_SCLS(sym->etype) == S_FIXED  ||
         SPEC_SCLS(sym->etype) == S_AUTO   ) {
        /* set the output class */
-       SPEC_OCLS(sym->etype) = ( options.model  ? xdata : data ) ;
+       SPEC_OCLS(sym->etype) = port->mem.default_globl_map ;
        /* generate the symbol  */
        allocIntoSeg  (sym) ;
        return   ;
@@ -319,6 +381,12 @@ void allocGlobal ( symbol *sym )
        allocIntoSeg (sym)  ;
        return ;
     }
+
+    if ( SPEC_SCLS(sym->etype) == S_EEPROM  )    {
+       SPEC_OCLS(sym->etype) = eeprom ;
+       allocIntoSeg (sym)  ;
+       return ;
+    }
     
     return ;
 }
@@ -333,21 +401,15 @@ void allocParms ( value  *val )
 
     for ( lval = val ; lval ; lval = lval->next, pNum++ ) {
 
-       /* if this is a literal e.g. enumerated type */
-       if (IS_LITERAL(lval->etype)) {
-           SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = 
-               ( options.model  ? xdata : data );
-           continue;
-       }
+       /* 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 ;
 
-       /* check the declaration */
-       checkDecl (lval->sym);
-       
        /* mark it as my parameter */
        lval->sym->ismyparm = 1;
        lval->sym->localof = currFunc;
@@ -380,7 +442,11 @@ void allocParms ( value  *val )
                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;
+                   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);
                }                   
            }
@@ -388,7 +454,7 @@ void allocParms ( value  *val )
        }
        else   {        /* allocate them in the automatic space */
            /* generate a unique name  */
-           sprintf (lval->sym->rname,"_%s_PARM_%d",currFunc->name,pNum);
+           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 */
@@ -400,7 +466,9 @@ void allocParms ( value  *val )
                   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  ? xdata : (options.noOverlay ? data :overlay ));
+                   ( options.model == MODEL_SMALL ? port->mem.default_local_map : 
+                     (options.noOverlay ? port->mem.default_local_map
+                      :overlay ));
            
            allocIntoSeg(lval->sym);
        }
@@ -457,7 +525,8 @@ void allocLocal ( symbol *sym  )
 {   
     
     /* generate an unique name */
-    sprintf(sym->rname,"_%s_%s_%d_%d",
+    sprintf(sym->rname,"%s%s_%s_%d_%d",
+           port->fun_prefix,
            currFunc->name,sym->name,sym->level,sym->block);
     
     sym->islocal = 1;
@@ -465,7 +534,7 @@ void allocLocal ( symbol *sym  )
 
     /* 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   ;
@@ -556,11 +625,24 @@ void allocLocal ( symbol *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  ? xdata : 
-                             (options.noOverlay ? data : overlay )) ;
+    SPEC_OCLS(sym->etype) = ( options.model == MODEL_SMALL ? port->mem.default_local_map : 
+                             (options.noOverlay ? port->mem.default_local_map
+                              : overlay )) ;
     allocIntoSeg (sym); 
 }
 
@@ -782,7 +864,7 @@ void redoStackOffsets ()
 
     /* if the debug option is set then output the
        symbols to the map file */
-    if (options.debug) {
+    if (options.debug && !options.nodebug) {
        for (sym = setFirstItem(istack->syms); sym;
             sym = setNextItem(istack->syms))
            cdbSymbol(sym,cdbFile,FALSE,FALSE);
@@ -792,3 +874,116 @@ void redoStackOffsets ()
            cdbSymbol(sym,cdbFile,FALSE,FALSE); 
     }
 }
+
+/*-----------------------------------------------------------------*/
+/* printAllocInfoSeg- print the allocation for a given section     */
+/*-----------------------------------------------------------------*/
+static void printAllocInfoSeg ( memmap *map, symbol *func, FILE *of)
+{
+    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);
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* canOverlayLocals - returns true if the local variables can overlayed */
+/*-----------------------------------------------------------------*/
+static bool canOverlayLocals (eBBlock **ebbs, int count)
+{
+    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 &&
+        (IS_RENT(currFunc->etype) ||
+         IS_ISR(currFunc->etype))) ||
+       elementsInSet(overlay->syms) == 0)
+       
+       return FALSE;
+
+    /* 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 && ( ic->op == CALL || 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)
+{
+    /* 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)
+{
+    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);
+}