X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCmem.c;h=5bc6bb92c31ea1354df22ec3801954349b6dbacc;hb=HEAD;hp=b3c8381f50cfae85bac5f6e1ad5e92e08ee72b86;hpb=57b5edb25dcb2872d2c3e9789173bc9423959bec;p=fw%2Fsdcc diff --git a/src/SDCCmem.c b/src/SDCCmem.c index b3c8381f..5bc6bb92 100644 --- a/src/SDCCmem.c +++ b/src/SDCCmem.c @@ -1,938 +1,1219 @@ /*-----------------------------------------------------------------*/ -/* SDCCmem.c - 8051 memory management routines */ +/* SDCCmem.c - 8051 memory management routines */ /*-----------------------------------------------------------------*/ #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 *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 *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 *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; - -extern set *operKeyReset ; -extern set *tmpfileSet ; -extern symbol *interrupts[]; -int maxRegBank = 0; -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 */ - ) +set *ovrSetSets = NULL; + +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 */ +) { - memmap *map ; - - if (!(map = GC_malloc(sizeof(memmap)))) { - werror(E_OUT_OF_MEM,__FILE__,sizeof(memmap)); - exit (1); - } - - memset(map, ZERO, sizeof(memmap)); - map->regsp = rspace ; - map->fmap = farmap ; - map->paged = paged ; - map->direct = direct ; - map->bitsp = bitaddr ; - map->codesp = codemap ; - map->sloc = sloc ; - 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 ; - return map; + memmap *map; + + if (!(map = Safe_alloc (sizeof (memmap)))) + { + werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap)); + exit (1); + } + + memset (map, ZERO, sizeof (memmap)); + map->regsp = rspace; + map->fmap = farmap; + map->paged = paged; + map->direct = direct; + map->bitsp = bitaddr; + map->codesp = codemap; + map->sloc = sloc; + map->sname = name; + map->dbName = dbName; + map->ptrType = ptrType; + map->syms = NULL; + + dbuf_init(&map->oBuf, 4096); + + return map; } /*-----------------------------------------------------------------*/ -/* initMem - allocates and initializes all the segments */ -/*-----------------------------------------------------------------*/ -void initMem () -{ - /* allocate all the segments */ - /* xternal stack segment ; - SFRSPACE - NO - FAR-SPACE - YES - PAGED - YES - DIRECT-ACCESS - NO - BIT-ACCESS - NO - 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 - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - 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 - FAR-SPACE - YES - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - 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 - FAR-SPACE - YES - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - 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 - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - YES - BIT-ACCESS - NO - 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 - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - YES - BIT-ACCESS - NO - 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 - FAR-SPACE - YES - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - 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 - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - 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 - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - YES - BIT-ACCESS - YES - 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 - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - YES - BIT-ACCESS - NO - 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 - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - 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 - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - YES - BIT-ACCESS - YES - CODE-ACESS - NO - DEBUG-NAME - 'J' - POINTER-TYPE - _NONE_ - */ - sfrbit = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,'J',0); - - /* 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); - +/* initMem - allocates and initializes all the segments */ +/*-----------------------------------------------------------------*/ +void +initMem () +{ + /* allocate all the segments */ + /* xternal stack segment ; + SFRSPACE - NO + FAR-SPACE - YES + PAGED - YES + DIRECT-ACCESS - NO + BIT-ACCESS - 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 ; + SFRSPACE - NO + FAR-SPACE - NO + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACCESS - NO + DEBUG-NAME - 'B' + POINTER-TYPE - POINTER + */ + if (ISTACK_NAME) + { + istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER); + } + else + { + istack = NULL; + } + + /* code segment ; + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + 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 ; + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACCESS - YES + DEBUG-NAME - 'C' + POINTER-TYPE - CPOINTER + */ + home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, HOME_NAME, 'C', CPOINTER); + + /* Static segment (code for variables ); + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + 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-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-ACCESS - NO + DEBUG-NAME - 'E' + POINTER-TYPE - 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 - + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACCESS - NO + DEBUG-NAME - 'F' + POINTER-TYPE - FPOINTER + */ + xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER); + 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); + + /* 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-ACCESS - NO + DEBUG-NAME - 'G' + POINTER-TYPE - IPOINTER + */ + if (IDATA_NAME) + { + idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER); + } + else + { + idata = NULL; + } + + /* 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-ACCESS - 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 + FAR-SPACE - NO + PAGED - NO + DIRECT-ACCESS - YES + BIT-ACCESS - NO + CODE-ACCESS - NO + DEBUG-NAME - 'I' + POINTER-TYPE - _NONE_ + */ + sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0); + + /* Register space ; + SFRSPACE - YES + FAR-SPACE - NO + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACCESS - NO + DEBUG-NAME - ' ' + POINTER-TYPE - _NONE_ + */ + reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0); + + /* SFR bit space + SFRSPACE - YES + FAR-SPACE - NO + PAGED - NO + DIRECT-ACCESS - YES + BIT-ACCESS - YES + CODE-ACCESS - NO + DEBUG-NAME - 'J' + POINTER-TYPE - _NONE_ + */ + sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0); + + /* EEPROM space + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACCESS - 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); + } /*-----------------------------------------------------------------*/ /* allocIntoSeg - puts a symbol into a memory segment */ /*-----------------------------------------------------------------*/ -void allocIntoSeg (symbol *sym) +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 */ +/* first declared as "extern" then no extern */ +/*-----------------------------------------------------------------*/ +void deleteFromSeg(symbol *sym) { - memmap *segment = SPEC_OCLS(sym->etype); - addSet (&segment->syms,sym); + if (SPEC_OCLS(sym->etype)) { + memmap *segment = SPEC_OCLS (sym->etype); + deleteSetItem(&segment->syms,sym); + } } /*-----------------------------------------------------------------*/ -/* allocGlobal - aassigns the output segment to a global var */ +/* allocDefault - assigns the output segment based on SCLASS */ /*-----------------------------------------------------------------*/ -void allocGlobal ( symbol *sym ) +bool +allocDefault (symbol * sym) { - /* symbol name is internal name */ - sprintf (sym->rname,"%s%s", port->fun_prefix, sym->name); - - /* add it to the operandKey reset */ - addSet(&operKeyReset,sym); - - /* if this is a literal e.g. enumerated type */ - /* put it in the data segment & do nothing */ - if (IS_LITERAL(sym->etype)) { - SPEC_OCLS(sym->etype) = data ; - return ; - } - - /* if this is a function then assign code space */ - if (IS_FUNC(sym->type)) { - SPEC_OCLS(sym->etype) = code ; - /* if this is an interrupt service routine - then put it in the interrupt service array */ - if (IS_ISR(sym->etype)) { - - if (interrupts[SPEC_INTN(sym->etype)]) - werror(E_INT_DEFINED, - SPEC_INTN(sym->etype), - interrupts[SPEC_INTN(sym->etype)]->name); - else - interrupts[SPEC_INTN(sym->etype)] = sym; - - /* automagically extend the maximum interrupts */ - if (SPEC_INTN(sym->etype) >= maxInterrupts ) - maxInterrupts = SPEC_INTN(sym->etype) + 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); - 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 ) { - SPEC_OCLS(sym->etype) = bit; - allocIntoSeg(sym); - return ; - } - - /* 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 || - SPEC_SCLS(sym->etype) == S_AUTO ) { - /* set the output class */ - SPEC_OCLS(sym->etype) = port->mem.default_globl_map ; - /* generate the symbol */ - allocIntoSeg (sym) ; - return ; - } - - /* if code change to constant */ - if ( SPEC_SCLS(sym->etype) == S_CODE || - SPEC_SCLS(sym->etype) == S_CONSTANT ) { - SPEC_OCLS(sym->etype) = statsg ; - allocIntoSeg (sym) ; - return ; - } - - if ( SPEC_SCLS(sym->etype) == S_XDATA ) { - 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 ; - } - - return ; + 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 +allocGlobal (symbol * sym) +{ + + /* symbol name is internal 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 */ + if (!isinSet (operKeyReset, sym)) { + addSet(&operKeyReset, sym); + } + + /* if this is a literal e.g. enumerated type */ + /* put it in the data segment & do nothing */ + if (IS_LITERAL (sym->etype)) + { + SPEC_OCLS (sym->etype) = data; + return; + } + + /* if this is a function then assign code space */ + if (IS_FUNC (sym->type)) + { + 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) && !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 bit variable and no storage class */ + if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT) + /*&& SPEC_SCLS (sym->etype) == S_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 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 */ + SPEC_OCLS (sym->etype) = port->mem.default_globl_map; + /* generate the symbol */ + allocIntoSeg (sym); + return; + } else { + SPEC_SCLS (sym->etype) = S_XDATA; + } + } + + allocDefault (sym); + return; } /*-----------------------------------------------------------------*/ -/* allocParms - parameters are always passed on stack */ +/* allocParms - parameters are always passed on stack */ /*-----------------------------------------------------------------*/ -void allocParms ( value *val ) +void +allocParms (value * val) { - value *lval ; - int pNum = 1; - - for ( lval = val ; lval ; lval = lval->next, pNum++ ) { - - /* 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 ; - - /* mark it as my parameter */ - lval->sym->ismyparm = 1; - lval->sym->localof = currFunc; - - - /* if automatic variables r 2b stacked */ - if ( options.stackAuto || IS_RENT(currFunc->etype)) { - - 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 - ( SPEC_BANK(currFunc->etype) ? port->stack.bank_overhead : 0) - - getSize(lval->type) - - (IS_ISR(currFunc->etype) ? 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 + - (IS_BANKEDCALL(currFunc->etype) ? port->stack.banked_overhead : 0) + - (IS_ISR(currFunc->etype) ? 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 */ - SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = - ( options.model ? port->mem.default_local_map : - (options.noOverlay ? port->mem.default_local_map - :overlay )); - - allocIntoSeg(lval->sym); - } - } - - return ; + value *lval; + int pNum = 1; + + for (lval = val; lval; lval = lval->next, pNum++) + { + /* check the declaration */ + checkDecl (lval->sym, 0); + + /* 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; + + /* 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); + } + else + { /* 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 */ +/* deallocParms - parameters are always passed on stack */ /*-----------------------------------------------------------------*/ -void deallocParms ( value *val ) +void +deallocParms (value * val) { - value *lval ; - - for ( lval = val ; lval ; lval = lval->next ) { - - /* unmark is myparm */ - lval->sym->ismyparm = 0; - /* if on stack then depending on which stack */ - - /* delete it from the symbol table */ - deleteSym (SymbolTab,lval->sym,lval->sym->name); - - if (!lval->sym->isref) { - lval->sym->allocreq = 1; - werror(W_NO_REFERENCE,currFunc->name, - "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); - lval->sym->_isparm = 1; - addSet(&operKeyReset,lval->sym); - } - - } - - return ; + value *lval; + + for (lval = val; lval; lval = lval->next) + { + /* unmark is myparm */ + lval->sym->ismyparm = 0; + + /* delete it from the symbol table */ + deleteSym (SymbolTab, lval->sym, lval->sym->name); + + if (!lval->sym->isref) + { + 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]; + 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 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); - - sym->islocal = 1; - sym->localof = currFunc; - - /* 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 ; - } - - /* if volatile then */ - if (IS_VOLATILE(sym->etype)) - sym->allocreq = 1; - - /* this is automatic */ - - /* if it to be placed on the stack */ - if ( options.stackAuto || reentrant) { - - sym->onStack = 1; - if ( options.useXstack ) { - /* PENDING: stack direction for xstack */ - SPEC_OCLS(sym->etype) = xstack ; - SPEC_STAK(sym->etype) = sym->stack = (xstackPtr + 1); - xstackPtr += getSize (sym->type) ; - } - else { - SPEC_OCLS(sym->etype) = istack ; - if (port->stack.direction > 0) { - SPEC_STAK(sym->etype) = sym->stack = ( stackPtr + 1); - stackPtr += getSize (sym->type) ; - } - else { - 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 || - SPEC_SCLS(sym->etype) == S_CONSTANT) && - !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 ; - } - - /* if this is a function then assign code space */ - if (IS_FUNC(sym->type)) { - SPEC_OCLS(sym->etype) = code ; - 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)) { - SPEC_OCLS(sym->etype) = bit ; - allocIntoSeg (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 ? port->mem.default_local_map : - (options.noOverlay ? port->mem.default_local_map - : overlay )) ; - allocIntoSeg (sym); +/* allocLocal - allocate local variables */ +/*-----------------------------------------------------------------*/ +void +allocLocal (symbol * sym) +{ + /* generate an unique name */ + 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; + + /* if this is a static variable */ + if (IS_STATIC (sym->etype)) + { + allocGlobal (sym); + sym->allocreq = 1; + return; + } + + /* if volatile then */ + if (IS_VOLATILE (sym->etype)) + sym->allocreq = 1; + + /* this is automatic */ + + /* if it's to be placed on the stack */ + if (options.stackAuto || reentrant) { + sym->onStack = 1; + if (options.useXstack) { + /* PENDING: stack direction for xstack */ + SPEC_OCLS (sym->etype) = xstack; + SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1); + xstackPtr += getSize (sym->type); + } else { + SPEC_OCLS (sym->etype) = istack; + if (port->stack.direction > 0) { + SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1); + stackPtr += getSize (sym->type); + } else { + stackPtr -= getSize (sym->type); + SPEC_STAK (sym->etype) = sym->stack = stackPtr; + } + } + allocIntoSeg (sym); + return; + } + + /* else depending on the storage class specified */ + + /* if this is a function then assign code space */ + if (IS_FUNC (sym->type)) + { + SPEC_OCLS (sym->etype) = code; + return; + } + + /* if this is a bit variable and no storage class */ + if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT) + { + SPEC_SCLS (sym->type) = S_BIT; + SPEC_OCLS (sym->type) = bit; + allocIntoSeg (sym); + return; + } + + 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 (allocDefault (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 */ + if (options.model == MODEL_SMALL) { + SPEC_OCLS (sym->etype) = + (options.noOverlay ? port->mem.default_local_map : overlay); + } else { + SPEC_OCLS (sym->etype) = port->mem.default_local_map; + } + allocIntoSeg (sym); } /*-----------------------------------------------------------------*/ /* deallocLocal - deallocates the local variables */ /*-----------------------------------------------------------------*/ -void deallocLocal ( symbol *csym ) +void +deallocLocal (symbol * csym) { - symbol *sym ; - - for ( sym = csym ; sym ; sym = sym->next) { - 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 not used give a warning */ - if (!sym->isref && !IS_STATIC(sym->etype)) - werror(W_NO_REFERENCE,currFunc->name, - "local variable",sym->name); - /* now delete it from the symbol table */ - deleteSym (SymbolTab,sym,sym->name); + symbol *sym; + + for (sym = csym; sym; sym = sym->next) + { + 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 not used give a warning */ + if (!sym->isref && !IS_STATIC (sym->etype)) + werror (W_NO_REFERENCE, + currFunc ? currFunc->name : "(unknown)", + "local variable", sym->name); + /* now delete it from the symbol table */ + deleteSym (SymbolTab, sym, sym->name); } } /*-----------------------------------------------------------------*/ /* overlay2data - moves declarations from the overlay seg to data */ /*-----------------------------------------------------------------*/ -void overlay2data() +void +overlay2data () { - symbol *sym; + symbol *sym; - for (sym = setFirstItem(overlay->syms); sym; - sym = setNextItem(overlay->syms)) { + for (sym = setFirstItem (overlay->syms); sym; + sym = setNextItem (overlay->syms)) + { - SPEC_OCLS(sym->etype) = data; - allocIntoSeg(sym); + SPEC_OCLS (sym->etype) = data; + allocIntoSeg (sym); } - setToNull((void **) &overlay->syms); - + setToNull ((void *) &overlay->syms); + } /*-----------------------------------------------------------------*/ /* overlay2Set - will add all symbols from the overlay segment to */ /* the set of sets containing the overlable symbols */ /*-----------------------------------------------------------------*/ -void overlay2Set () +void +overlay2Set () { - symbol *sym; - set *oset = NULL; + symbol *sym; + set *oset = NULL; - for (sym = setFirstItem(overlay->syms); sym; - sym = setNextItem(overlay->syms)) { + for (sym = setFirstItem (overlay->syms); sym; + sym = setNextItem (overlay->syms)) + { - addSet(&oset,sym); + addSet (&oset, sym); } - - setToNull((void **) &overlay->syms); - addSet (&ovrSetSets,oset); + + setToNull ((void *) &overlay->syms); + addSet (&ovrSetSets, oset); } /*-----------------------------------------------------------------*/ /* allocVariables - creates decl & assign storage class for a v */ /*-----------------------------------------------------------------*/ -int allocVariables ( symbol *symChain ) +int +allocVariables (symbol * symChain) { - symbol *sym; - symbol *csym; - int stack = 0; - int saveLevel = 0 ; - - /* go thru the symbol chain */ - for ( sym = symChain ; sym ; sym = sym->next ) { - - /* 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); - continue ; /* go to the next one */ - } - /* make sure it already exist */ - csym = findSymWithLevel (SymbolTab, sym); - if (! csym || (csym && csym->level != sym->level) ) - csym = sym; - - /* check the declaration */ - checkDecl (csym); - - /* if this is a function or a pointer to function */ - /* then args processing */ - if (funcInChain(csym->type)) { - - processFuncArgs (csym, 1); - /* if register bank specified then update maxRegBank */ - if (maxRegBank < SPEC_BANK(csym->etype)) - maxRegBank = SPEC_BANK(csym->etype); - } - - /* if this is a extern variable then change the */ - /* level to zero temporarily */ - if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type) ) { - 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 ; - - /* generate the actual declaration */ - if ( csym->level ) { - allocLocal (csym); - if (csym->onStack) - stack += getSize(csym->type) ; - } - else - allocGlobal (csym); - - /* restore the level */ - if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type)) - csym->level = saveLevel; - } - - return stack ; + symbol *sym; + symbol *csym; + int stack = 0; + int saveLevel = 0; + + /* go thru the symbol chain */ + for (sym = symChain; sym; sym = sym->next) + { + + /* 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); + + 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; + + /* check the declaration */ + checkDecl (csym,0); + + /* if this is a function or a pointer to a */ + /* function then do args processing */ + if (funcInChain (csym->type)) + { + processFuncArgs (csym); + } + + /* if this is a extern variable then change the */ + /* level to zero temporarily */ + if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type)) + { + 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; + + /* generate the actual declaration */ + if (csym->level) + { + allocLocal (csym); + if (csym->onStack) + stack += getSize (csym->type); + } + else + allocGlobal (csym); + + /* restore the level */ + if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type)) + csym->level = saveLevel; + } + + return stack; } /*-----------------------------------------------------------------*/ /* redoStackOffsets :- will reassign the values for stack offsets */ /*-----------------------------------------------------------------*/ -void redoStackOffsets () +void +redoStackOffsets (void) { - symbol *sym; - int sPtr = 0; - int xsPtr=-1; - - /* after register allocation is complete we know - which variables will need to be assigned space - on the stack. We will eliminate those variables - which do not have the allocReq flag thus reducing - the stack space */ - for ( sym = setFirstItem(istack->syms); sym; - sym = setNextItem(istack->syms)) { - - int size = getSize(sym->type); - /* nothing to do with parameters so continue */ - if ((sym->_isparm && !IS_REGPARM(sym->etype))) - 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 allocation not required then subtract - size from overall stack size & continue */ - if (!sym->allocreq) { - currFunc->stack -= size; - SPEC_STAK(currFunc->etype) -= size; - 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; - } - } - - /* do the same for the external stack */ - - for ( sym = setFirstItem(xstack->syms); sym; - sym = setNextItem(xstack->syms)) { - - int size = getSize(sym->type); - /* nothing to do with parameters so continue */ - if ((sym->_isparm && !IS_REGPARM(sym->etype))) - continue ; - - if (IS_AGGREGATE(sym->type)) { - 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 ; - } - - 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 && !options.nodebug) { - 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); + symbol *sym; + int sPtr = 0; + int xsPtr = -1; + + /* after register allocation is complete we know + which variables will need to be assigned space + on the stack. We will eliminate those variables + which do not have the allocReq flag thus reducing + the stack space */ + for (sym = setFirstItem (istack->syms); sym; + sym = setNextItem (istack->syms)) + { + + int size = getSize (sym->type); + /* nothing to do with parameters so continue */ + if ((sym->_isparm && !IS_REGPARM (sym->etype))) + 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 allocation not required then subtract + size from overall stack size & continue */ + if (!sym->allocreq) + { + currFunc->stack -= size; + SPEC_STAK (currFunc->etype) -= size; + 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; + } + } + + /* do the same for the external stack */ + + for (sym = setFirstItem (xstack->syms); sym; + sym = setNextItem (xstack->syms)) + { + + int size = getSize (sym->type); + /* nothing to do with parameters so continue */ + if ((sym->_isparm && !IS_REGPARM (sym->etype))) + continue; + + if (IS_AGGREGATE (sym->type)) + { + 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; + } + + SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1); + xsPtr += size; } + } /*-----------------------------------------------------------------*/ /* 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; + + 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; + + dbuf_printf (oBuf, ";%-25s Allocated ", sym->name); + + /* if assigned to registers */ + if (!sym->allocreq && sym->reqv) + { + 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) + { + dbuf_printf (oBuf, "to stack - offset %d\n", sym->stack); + continue; + } + + /* otherwise give rname */ + dbuf_printf (oBuf, "with name '%s'\n", sym->rname); + } +} + +/*-----------------------------------------------------------------*/ +/* canOverlayLocals - returns true if the local variables can overlayed */ +/*-----------------------------------------------------------------*/ +static bool +canOverlayLocals (eBBlock ** ebbs, int count) { - 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); + 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 && + (IFFUNC_ISREENT (currFunc->type) || + FUNC_ISISR (currFunc->type))) || + elementsInSet (overlay->syms) == 0) + + return FALSE; + + /* if this is a forces overlay */ + if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE; + + /* 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) { + 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 */ + return TRUE; +} + +/*-----------------------------------------------------------------*/ +/* doOverlays - move the overlay segment to appropriate location */ +/*-----------------------------------------------------------------*/ +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 + 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) +void +printAllocInfo (symbol * func, struct dbuf_s * oBuf) { - 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); + if (!func) + return; + + /* must be called after register allocation is complete */ + 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"); }