-/* allocLocal - allocate local variables */
-/*-----------------------------------------------------------------*/
-void allocLocal ( symbol *sym )
-{
-
- /* generate an unique name */
- sprintf(sym->rname,"_%s_%s_%d_%d",
- 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);
+/* allocParms - parameters are always passed on stack */
+/*-----------------------------------------------------------------*/
+void
+allocParms (value * val)
+{
+ 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 */
+/*-----------------------------------------------------------------*/
+void
+deallocParms (value * val)
+{
+ 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 */
+ 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);