/*-----------------------------------------------------------------*/ void deleteFromSeg(symbol *sym) { if (SPEC_OCLS(sym->etype)) { memmap *segment = SPEC_OCLS (sym->etype); deleteSetItem(&segment->syms,sym); } }
/*-----------------------------------------------------------------*/ void allocIntoSeg (symbol *sym) { memmap *segment; if (SPEC_ADDRSPACE (sym->etype)) { namedspacemap *nm; for (nm = namedspacemaps; nm; nm = nm->next) if (!strcmp (nm->name, SPEC_ADDRSPACE (sym->etype)->name)) break; if (!nm) { nm = Safe_alloc (sizeof (namedspacemap)); nm->name = Safe_alloc (strlen(SPEC_ADDRSPACE (sym->etype)->name) + 1); strcpy (nm->name, SPEC_ADDRSPACE (sym->etype)->name); nm->is_const = (SPEC_ADDRSPACE (sym->etype)->type && SPEC_CONST (SPEC_ADDRSPACE (sym->etype)->type)); nm->map = nm->is_const ? allocMap (0, 1, 0, 0, 0, 1, options.code_loc, SPEC_ADDRSPACE (sym->etype)->name, 'C', CPOINTER) : allocMap (0, 0, 0, 1, 0, 0, options.data_loc, SPEC_ADDRSPACE (sym->etype)->name, 'E', POINTER); nm->next = namedspacemaps; namedspacemaps = nm; } addSet (&nm->map->syms, sym); return; } segment = SPEC_OCLS (sym->etype); addSet (&segment->syms, sym); if (segment == pdata) sym->iaccess = 1; }
/*-----------------------------------------------------------------*/ void allocIntoSeg (symbol * sym) { memmap *segment = SPEC_OCLS (sym->etype); addSet (&segment->syms, sym); if (segment == pdata) sym->iaccess = 1; }
/*-----------------------------------------------------------------*/ void overlay2data () { symbol *sym; for (sym = setFirstItem (overlay->syms); sym; sym = setNextItem (overlay->syms)) { SPEC_OCLS (sym->etype) = data; allocIntoSeg (sym); } setToNull ((void *) &overlay->syms); }
/*-----------------------------------------------------------------*/ 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; }
/*-----------------------------------------------------------------*/ 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; }
/*-----------------------------------------------------------------*/ 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; }
/*-----------------------------------------------------------------*/ static int printAllocInfoSeg (memmap * map, symbol * func, struct dbuf_s *oBuf) { symbol *sym; int flg = FALSE; if (!map || !map->syms) return 0; 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); flg = TRUE; /* 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) { int stack_offset = 0; if (options.omitFramePtr) { if (SPEC_OCLS (sym->etype)->paged) stack_offset = func->xstack; else stack_offset = func->stack; } dbuf_printf (oBuf, "to stack - %s %+d\n", SYM_BP (sym), sym->stack - stack_offset); continue; } /* otherwise give rname */ dbuf_printf (oBuf, "with name '%s'\n", sym->rname); } return flg; }
int cdbWriteBasicSymbol (symbol *sym, int isStructSym, int isFunc) { memmap *map; symbol *sym2; if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS")) fprintf (stderr, "cdbFile.c:cdbWriteBasicSymbol()\n"); if (!cdbFilePtr) return 0; if (!sym) return 0; /* WRITE HEADER, Function or Symbol */ if (isFunc) fprintf (cdbFilePtr, "F:"); else fprintf (cdbFilePtr, "S:"); /* STRUCTS do not have scope info.. */ if (!isStructSym) { if (sym->level && sym->localof) /* symbol is local */ { fprintf (cdbFilePtr, "L%s.%s$", moduleName, sym->localof->name); } else if (IS_STATIC (sym->etype)) /* scope is file */ { fprintf (cdbFilePtr, "F%s$", moduleName); } else /* scope is global */ { fprintf (cdbFilePtr, "G$"); } } else { fprintf (cdbFilePtr, "S$"); /* scope is structure */ } /* print the name, & mangled name */ fprintf (cdbFilePtr, "%s$%d$%d(", sym->name, sym->level, sym->block); cdbTypeInfo (sym->type); fprintf (cdbFilePtr, "),"); /* CHECK FOR REGISTER SYMBOL... */ if (!sym->allocreq && sym->reqv) { int a; symbol *TempSym = OP_SYMBOL (sym->reqv); if (!TempSym->isspilt || TempSym->remat) { fprintf (cdbFilePtr, "R,0,0,["); for (a = 0; a < 4; a++) { if (TempSym->regs[a]) { fprintf (cdbFilePtr, "%s%s", port->getRegName(TempSym->regs[a]), ((a < 3) && (TempSym->regs[a+1])) ? "," : ""); } } fprintf (cdbFilePtr, "]"); sym2 = NULL; } else { sym2 = TempSym->usl.spillLoc; } } else { sym2 = sym; } if (sym2) { /* print the address space */ map = SPEC_OCLS (sym2->etype); fprintf (cdbFilePtr, "%c,%d,%d", (map ? map->dbName : 'Z'), sym2->onStack, SPEC_STAK (sym2->etype)); } /* if assigned to registers then output register names */ /* if this is a function then print if is it an interrupt routine & interrupt number and the register bank it is using */ if (isFunc) fprintf (cdbFilePtr, ",%d,%d,%d", FUNC_ISISR (sym->type), FUNC_INTNO (sym->type), FUNC_REGBANK (sym->type)); /* alternate location to find this symbol @ : eg registers or spillocation */ if (!isStructSym) fprintf (cdbFilePtr, "\n"); return 1; }