cleanup; moved extern's from .c to .h files for double check
[fw/sdcc] / src / SDCCmem.c
index a134a4d9b9095898e79f55a602a01a214aa0f942..9a9cc20922de7d9225f4fb2711e293e2ea69e056 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  */
@@ -19,14 +19,12 @@ 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                   */
 
@@ -114,6 +112,18 @@ void initMem ()
        */
        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
@@ -429,7 +439,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);
                }                   
            }
@@ -448,11 +462,15 @@ void allocParms ( value  *val )
                   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 ));
-           
+               if (options.model == MODEL_SMALL) {
+                   SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = 
+                       ( options.model == MODEL_SMALL ? port->mem.default_local_map : 
+                         (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);
        }
     }
@@ -517,7 +535,6 @@ 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;
@@ -624,7 +641,7 @@ void allocLocal ( symbol *sym  )
     /* 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 : 
+    SPEC_OCLS(sym->etype) = ( options.model == MODEL_SMALL ? port->mem.default_local_map : 
                              (options.noOverlay ? port->mem.default_local_map
                               : overlay )) ;
     allocIntoSeg (sym); 
@@ -848,7 +865,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);
@@ -858,3 +875,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);
+}