/*-----------------------------------------------------------------*/ 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 (bit && 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); }
/*-----------------------------------------------------------------*/ 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 + (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; }
/*-----------------------------------------------------------------*/ bool defaultOClass (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; } /* Other initialized global */ else if (sym->ival && port->mem.initialized_name && sym->level == 0) { SPEC_OCLS (sym->etype) = initialized; } 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; } return TRUE; }
/*-----------------------------------------------------------------*/ 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 (bit && IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT) { SPEC_OCLS (sym->type) = bit; allocIntoSeg (sym); return; } if (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 || SPEC_SCLS (sym->etype) == S_AUTO) { if (port->mem.default_globl_map != xdata) { if (sym->ival && SPEC_ABSA (sym->etype)) { /* absolute initialized global */ SPEC_OCLS (sym->etype) = x_abs; } else if (sym->ival && sym->level == 0 && port->mem.initialized_name) { SPEC_OCLS (sym->etype) = initialized; } else { /* 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; }
/*-----------------------------------------------------------------*/ 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; }