X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCmem.c;h=5bc6bb92c31ea1354df22ec3801954349b6dbacc;hb=HEAD;hp=e4f60ba7ac33e110313389871433f9b51dd072eb;hpb=d0654a8f79791ae227ac282b273640c476802e60;p=fw%2Fsdcc diff --git a/src/SDCCmem.c b/src/SDCCmem.c index e4f60ba7..5bc6bb92 100644 --- a/src/SDCCmem.c +++ b/src/SDCCmem.c @@ -3,47 +3,52 @@ /*-----------------------------------------------------------------*/ #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 *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 *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 *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; -int maxRegBank = 0; -int fatalError = 0; /* fatal error flag */ +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 */ +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; @@ -65,70 +70,74 @@ allocMap (char rspace, /* sfr space */ 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; + + dbuf_init(&map->oBuf, 4096); + return map; } /*-----------------------------------------------------------------*/ /* initMem - allocates and initializes all the segments */ /*-----------------------------------------------------------------*/ -void +void initMem () { /* allocate all the segments */ - /* xternal stack segment ; + /* xternal stack segment ; SFRSPACE - NO FAR-SPACE - YES PAGED - YES DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - 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 ; + /* internal stack segment ; SFRSPACE - NO FAR-SPACE - NO PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACCESS - NO DEBUG-NAME - 'B' POINTER-TYPE - POINTER */ - istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER); + if (ISTACK_NAME) + { + istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER); + } + else + { + istack = NULL; + } - /* code segment ; + /* code segment ; SFRSPACE - NO FAR-SPACE - YES PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - YES + 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 ; + /* home segment ; SFRSPACE - NO FAR-SPACE - YES PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - YES + CODE-ACCESS - YES DEBUG-NAME - 'C' POINTER-TYPE - CPOINTER */ - home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER); + home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, HOME_NAME, 'C', CPOINTER); /* Static segment (code for variables ); SFRSPACE - NO @@ -136,43 +145,100 @@ initMem () PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - YES + 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-ACESS - 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-ACESS - NO + CODE-ACCESS - NO DEBUG-NAME - 'E' POINTER-TYPE - POINTER */ - overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', 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 - + /* Xternal Data segment - SFRSPACE - NO FAR-SPACE - YES PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACCESS - NO DEBUG-NAME - 'F' POINTER-TYPE - FPOINTER */ @@ -180,25 +246,70 @@ initMem () 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); - /* Inderectly addressed internal data segment + /* 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-ACESS - NO + CODE-ACCESS - NO DEBUG-NAME - 'G' POINTER-TYPE - IPOINTER */ - idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER); + if (IDATA_NAME) + { + idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER); + } + else + { + idata = NULL; + } - /* Static segment (code for variables ); + /* 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-ACESS - NO + CODE-ACCESS - NO DEBUG-NAME - 'H' POINTER-TYPE - _NONE_ */ @@ -210,7 +321,7 @@ initMem () PAGED - NO DIRECT-ACCESS - YES BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACCESS - NO DEBUG-NAME - 'I' POINTER-TYPE - _NONE_ */ @@ -222,31 +333,31 @@ initMem () PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACCESS - NO DEBUG-NAME - ' ' POINTER-TYPE - _NONE_ */ reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0); - /* SFR bit space + /* SFR bit space SFRSPACE - YES FAR-SPACE - NO PAGED - NO DIRECT-ACCESS - YES BIT-ACCESS - YES - CODE-ACESS - NO + CODE-ACCESS - NO DEBUG-NAME - 'J' POINTER-TYPE - _NONE_ */ sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0); - /* EEPROM bit space + /* EEPROM space SFRSPACE - NO FAR-SPACE - YES PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACCESS - NO DEBUG-NAME - 'K' POINTER-TYPE - EEPPOINTER */ @@ -260,39 +371,126 @@ initMem () /*-----------------------------------------------------------------*/ /* allocIntoSeg - puts a symbol into a memory segment */ /*-----------------------------------------------------------------*/ -void +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 */ -/* firest declared as "extern" then no extern */ +/* first declared as "extern" then no extern */ /*-----------------------------------------------------------------*/ void deleteFromSeg(symbol *sym) { if (SPEC_OCLS(sym->etype)) { - memmap *segment = SPEC_OCLS (sym->etype); - deleteSetItem(&segment->syms,sym); + memmap *segment = SPEC_OCLS (sym->etype); + deleteSetItem(&segment->syms,sym); } } +/*-----------------------------------------------------------------*/ +/* allocDefault - assigns the output segment based on SCLASS */ +/*-----------------------------------------------------------------*/ +bool +allocDefault (symbol * sym) +{ + 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 +void allocGlobal (symbol * sym) { /* symbol name is internal name */ - if (!sym->level) /* local statics can come here */ - sprintf (sym->rname, "%s%s", port->fun_prefix, sym->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 */ - addSet (&operKeyReset, sym); + if (!isinSet (operKeyReset, sym)) { + addSet(&operKeyReset, sym); + } /* if this is a literal e.g. enumerated type */ /* put it in the data segment & do nothing */ @@ -308,81 +506,45 @@ allocGlobal (symbol * sym) 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)) - { - - 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 (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 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); - 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) + if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT) + /*&& SPEC_SCLS (sym->etype) == S_BIT*/ { - SPEC_OCLS (sym->etype) = 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 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 || + (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 */ @@ -395,48 +557,14 @@ allocGlobal (symbol * sym) } } - /* if code change to constant */ - if (SPEC_SCLS (sym->etype) == S_CODE) { - SPEC_OCLS (sym->etype) = statsg; - allocIntoSeg (sym); - return; - } - - if (SPEC_SCLS (sym->etype) == S_XDATA) - { - // should we move this to the initialized data segment? - if (port->genXINIT && - sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) { - SPEC_OCLS(sym->etype)=xidata; - } else { - 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; - } - + allocDefault (sym); return; } /*-----------------------------------------------------------------*/ /* allocParms - parameters are always passed on stack */ /*-----------------------------------------------------------------*/ -void +void allocParms (value * val) { value *lval; @@ -444,7 +572,6 @@ allocParms (value * val) for (lval = val; lval; lval = lval->next, pNum++) { - /* check the declaration */ checkDecl (lval->sym, 0); @@ -452,98 +579,105 @@ allocParms (value * val) it as a local variable by adding it to the first block we see in the body */ if (IS_REGPARM (lval->etype)) - continue; + 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); - } + { + 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 */ - 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 */ - if (options.model == MODEL_SMALL) - { - SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = - (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); - } + { /* 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 */ /*-----------------------------------------------------------------*/ -void +void deallocParms (value * val) { value *lval; for (lval = val; lval; lval = lval->next) { - /* unmark is myparm */ lval->sym->ismyparm = 0; @@ -551,43 +685,54 @@ deallocParms (value * val) deleteSym (SymbolTab, lval->sym, lval->sym->name); if (!lval->sym->isref) - { - lval->sym->allocreq = 0; - werror (W_NO_REFERENCE, currFunc->name, - "function argument", lval->sym->name); - } + { + 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]; - 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, 1); - lval->sym->_isparm = 1; - addSet (&operKeyReset, lval->sym); - } - + { + 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 +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); + 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; @@ -606,7 +751,7 @@ allocLocal (symbol * sym) /* this is automatic */ - /* if it to be placed on the stack */ + /* if it's to be placed on the stack */ if (options.stackAuto || reentrant) { sym->onStack = 1; if (options.useXstack) { @@ -617,38 +762,18 @@ allocLocal (symbol * sym) } else { SPEC_OCLS (sym->etype) = istack; if (port->stack.direction > 0) { - SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1); - stackPtr += getSize (sym->type); + SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1); + stackPtr += getSize (sym->type); } else { - stackPtr -= getSize (sym->type); - SPEC_STAK (sym->etype) = sym->stack = stackPtr; + 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 && !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; - } + /* else depending on the storage class specified */ /* if this is a function then assign code space */ if (IS_FUNC (sym->type)) @@ -657,58 +782,35 @@ allocLocal (symbol * 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)) + if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT) { - SPEC_OCLS (sym->etype) = bit; + SPEC_SCLS (sym->type) = S_BIT; + SPEC_OCLS (sym->type) = bit; allocIntoSeg (sym); return; } - if (SPEC_SCLS (sym->etype) == S_DATA) + 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 (SPEC_SCLS (sym->etype) == S_EEPROM) + if (allocDefault (sym)) { - 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 + 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); + SPEC_OCLS (sym->etype) = + (options.noOverlay ? port->mem.default_local_map : overlay); } else { - SPEC_OCLS (sym->etype) = port->mem.default_local_map; + SPEC_OCLS (sym->etype) = port->mem.default_local_map; } allocIntoSeg (sym); } @@ -716,28 +818,29 @@ allocLocal (symbol * sym) /*-----------------------------------------------------------------*/ /* deallocLocal - deallocates the local variables */ /*-----------------------------------------------------------------*/ -void +void deallocLocal (symbol * csym) { symbol *sym; for (sym = csym; sym; sym = sym->next) { - if (sym->_isparm) - continue; + 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 (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); + werror (W_NO_REFERENCE, + currFunc ? currFunc->name : "(unknown)", + "local variable", sym->name); /* now delete it from the symbol table */ deleteSym (SymbolTab, sym, sym->name); } @@ -746,7 +849,7 @@ deallocLocal (symbol * csym) /*-----------------------------------------------------------------*/ /* overlay2data - moves declarations from the overlay seg to data */ /*-----------------------------------------------------------------*/ -void +void overlay2data () { symbol *sym; @@ -759,7 +862,7 @@ overlay2data () allocIntoSeg (sym); } - setToNull ((void **) &overlay->syms); + setToNull ((void *) &overlay->syms); } @@ -767,7 +870,7 @@ overlay2data () /* overlay2Set - will add all symbols from the overlay segment to */ /* the set of sets containing the overlable symbols */ /*-----------------------------------------------------------------*/ -void +void overlay2Set () { symbol *sym; @@ -780,7 +883,7 @@ overlay2Set () addSet (&oset, sym); } - setToNull ((void **) &overlay->syms); + setToNull ((void *) &overlay->syms); addSet (&ovrSetSets, oset); } @@ -788,7 +891,7 @@ overlay2Set () /*-----------------------------------------------------------------*/ /* allocVariables - creates decl & assign storage class for a v */ /*-----------------------------------------------------------------*/ -int +int allocVariables (symbol * symChain) { symbol *sym; @@ -803,61 +906,57 @@ allocVariables (symbol * symChain) /* 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, 0); - continue; /* go to the next one */ - } - /* make sure it already exist */ + { + /* 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; + csym = sym; /* check the declaration */ checkDecl (csym,0); - /* if this is a function or a pointer to function */ - /* then args processing */ + /* if this is a function or a pointer to a */ + /* function then do args processing */ if (funcInChain (csym->type)) - { -#if 1 // jwk: TODO should have been done already in addDecl() (oclass????) - processFuncArgs (csym); -#endif - /* if register bank specified then update maxRegBank */ - if (maxRegBank < FUNC_REGBANK (csym->type)) - maxRegBank = FUNC_REGBANK (csym->type); - } + { + processFuncArgs (csym); + } /* if this is a extern variable then change the */ - /* level to zero temporarily */ + /* level to zero temporarily */ if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type)) - { - saveLevel = csym->level; - csym->level = 0; - } + { + 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; + continue; - /* generate the actual declaration */ + /* generate the actual declaration */ if (csym->level) - { - allocLocal (csym); - if (csym->onStack) - stack += getSize (csym->type); - } + { + allocLocal (csym); + if (csym->onStack) + stack += getSize (csym->type); + } else - allocGlobal (csym); + allocGlobal (csym); /* restore the level */ if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type)) - csym->level = saveLevel; + csym->level = saveLevel; } return stack; @@ -866,7 +965,7 @@ allocVariables (symbol * symChain) /*-----------------------------------------------------------------*/ /* redoStackOffsets :- will reassign the values for stack offsets */ /*-----------------------------------------------------------------*/ -void +void redoStackOffsets (void) { symbol *sym; @@ -885,42 +984,42 @@ redoStackOffsets (void) int size = getSize (sym->type); /* nothing to do with parameters so continue */ if ((sym->_isparm && !IS_REGPARM (sym->etype))) - continue; + 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 (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; - } + { + currFunc->stack -= size; + SPEC_STAK (currFunc->etype) -= size; + continue; + } if (port->stack.direction > 0) - { - SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1); - sPtr += size; - } + { + SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1); + sPtr += size; + } else - { - sPtr -= size; - SPEC_STAK (sym->etype) = sym->stack = sPtr; - } + { + sPtr -= size; + SPEC_STAK (sym->etype) = sym->stack = sPtr; + } } /* do the same for the external stack */ @@ -932,47 +1031,35 @@ redoStackOffsets (void) int size = getSize (sym->type); /* nothing to do with parameters so continue */ if ((sym->_isparm && !IS_REGPARM (sym->etype))) - continue; + continue; if (IS_AGGREGATE (sym->type)) - { - SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1); - xsPtr += size; - continue; - } + { + 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; - } + { + 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) - { - 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); - } } /*-----------------------------------------------------------------*/ /* 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; @@ -986,39 +1073,48 @@ printAllocInfoSeg (memmap * map, symbol * func, FILE * of) { if (sym->level == 0) - continue; + continue; if (sym->localof != func) - continue; - fprintf (of, ";%-25s Allocated to ", sym->name); + continue; + + dbuf_printf (oBuf, ";%-25s Allocated ", 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; - } + { + 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) - { - fprintf (of, "stack - offset %d\n", sym->stack); - continue; - } + { + dbuf_printf (oBuf, "to stack - offset %d\n", sym->stack); + continue; + } /* otherwise give rname */ - fprintf (of, "in memory with name '%s'\n", sym->rname); + dbuf_printf (oBuf, "with name '%s'\n", sym->rname); } } /*-----------------------------------------------------------------*/ /* canOverlayLocals - returns true if the local variables can overlayed */ /*-----------------------------------------------------------------*/ -static bool +static bool canOverlayLocals (eBBlock ** ebbs, int count) { int i; @@ -1029,7 +1125,7 @@ canOverlayLocals (eBBlock ** ebbs, int count) options.stackAuto || (currFunc && (IFFUNC_ISREENT (currFunc->type) || - FUNC_ISISR (currFunc->type))) || + FUNC_ISISR (currFunc->type))) || elementsInSet (overlay->syms) == 0) return FALSE; @@ -1044,13 +1140,13 @@ canOverlayLocals (eBBlock ** ebbs, int count) 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; - } + 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 */ @@ -1060,9 +1156,13 @@ canOverlayLocals (eBBlock ** ebbs, int count) /*-----------------------------------------------------------------*/ /* doOverlays - move the overlay segment to appropriate location */ /*-----------------------------------------------------------------*/ -void +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 @@ -1081,23 +1181,39 @@ doOverlays (eBBlock ** ebbs, int count) /*-----------------------------------------------------------------*/ /* 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; + if (!func) + return; /* 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); + 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"); }