/* 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 */
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 */
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 */
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 ;
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);
}
/*-----------------------------------------------------------------*/
void initMem ()
{
-
/* allocate all the segments */
/* xternal stack segment ;
SFRSPACE - NO
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
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
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
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
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
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
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
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
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
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
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
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);
+
}
/*-----------------------------------------------------------------*/
void allocIntoSeg (symbol *sym)
{
memmap *segment = SPEC_OCLS(sym->etype);
-
addSet (&segment->syms,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);
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 ;
allocIntoSeg (sym) ;
return ;
}
+
+ if ( SPEC_SCLS(sym->etype) == S_EEPROM ) {
+ SPEC_OCLS(sym->etype) = eeprom ;
+ allocIntoSeg (sym) ;
+ return ;
+ }
return ;
}
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;
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);
}
}
}
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 */
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);
}
{
/* 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;
/* 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 ;
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);
}
/* 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);
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);
+}