/*-----------------------------------------------------------------*/ static symbol * createStackSpil (symbol * sym) { symbol *sloc = NULL; struct dbuf_s dbuf; D (D_ALLOC, ("createStackSpil: for sym %p %s\n", sym, sym->name)); /* first go try and find a free one that is already existing on the stack */ if (applyToSet (_G.stackSpil, isFreeSTM8, &sloc, sym)) { /* found a free one : just update & return */ sym->usl.spillLoc = sloc; sym->stackSpil = 1; sloc->isFree = 0; addSetHead (&sloc->usl.itmpStack, sym); D (D_ALLOC, ("createStackSpil: found existing\n")); return sym; } /* could not then have to create one , this is the hard part we need to allocate this on the stack : this is really a hack!! but cannot think of anything better at this time */ dbuf_init (&dbuf, 128); dbuf_printf (&dbuf, "sloc%d", _G.slocNum++); sloc = newiTemp (dbuf_c_str (&dbuf)); dbuf_destroy (&dbuf); /* set the type to the spilling symbol */ sloc->type = copyLinkChain (sym->type); sloc->etype = getSpec (sloc->type); SPEC_SCLS (sloc->etype) = S_AUTO; SPEC_EXTR (sloc->etype) = 0; SPEC_STAT (sloc->etype) = 0; SPEC_VOLATILE (sloc->etype) = 0; allocLocal (sloc); sloc->isref = 1; /* to prevent compiler warning */ wassertl (currFunc, "Local variable used outside of function."); /* if it is on the stack then update the stack */ if (IN_STACK (sloc->etype)) { if (currFunc) currFunc->stack += getSize (sloc->type); _G.stackExtend += getSize (sloc->type); } else { _G.dataExtend += getSize (sloc->type); } /* add it to the stackSpil set */ addSetHead (&_G.stackSpil, sloc); sym->usl.spillLoc = sloc; sym->stackSpil = 1; /* add it to the set of itempStack set of the spill location */ addSetHead (&sloc->usl.itmpStack, sym); D (D_ALLOC, ("createStackSpil: created new\n")); return sym; }
/*-----------------------------------------------------------------*/ 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; }