X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCmem.c;h=2fb79e0b992642998610d07f1a6bd05da71ab147;hb=48cf52a951f5528d5833b3e496e404b733db336e;hp=e284d32dfa8c5aaded0c11b1258cd0c42f2c21e0;hpb=bd6b873b21bff3fdc161f53f25b5b884843ed9d9;p=fw%2Fsdcc diff --git a/src/SDCCmem.c b/src/SDCCmem.c index e284d32d..2fb79e0b 100644 --- a/src/SDCCmem.c +++ b/src/SDCCmem.c @@ -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); +}