/*-----------------------------------------------------------------*/ static void pic14emitOverlay (struct dbuf_s * aBuf) { set *ovrset; /* if (!elementsInSet (ovrSetSets))*/ /* the hack below, fixes translates for devices which * only have udata_shr memory */ dbuf_printf (aBuf, "%s\t%s\n", (elementsInSet(ovrSetSets)?"":";"), port->mem.overlay_name); /* for each of the sets in the overlay segment do */ for (ovrset = setFirstItem (ovrSetSets); ovrset; ovrset = setNextItem (ovrSetSets)) { symbol *sym; if (elementsInSet (ovrset)) { /* this dummy area is used to fool the assembler otherwise the assembler will append each of these declarations into one chunk and will not overlay sad but true */ /* I don't think this applies to us. We are using gpasm. CRF */ dbuf_printf (aBuf, ";\t.area _DUMMY\n"); /* output the area informtion */ dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */ } for (sym = setFirstItem (ovrset); sym; sym = setNextItem (ovrset)) { /* if extern then do nothing */ if (IS_EXTERN (sym->etype)) continue; /* if allocation required check is needed then check if the symbol really requires allocation only for local variables */ if (!IS_AGGREGATE (sym->type) && !(sym->_isparm && !IS_REGPARM (sym->etype)) && !sym->allocreq && sym->level) continue; /* if global variable & not static or extern and addPublics allowed then add it to the public set */ if ((sym->_isparm && !IS_REGPARM (sym->etype)) && !IS_STATIC (sym->etype)) addSetHead (&publics, sym); /* if extern then do nothing or is a function then do nothing */ if (IS_FUNC (sym->type)) continue; /* print extra debug info if required */ if (options.debug || sym->level == 0) { if (!sym->level) { /* global */ if (IS_STATIC (sym->etype)) dbuf_printf (aBuf, "F%s_", moduleName); /* scope is file */ else dbuf_printf (aBuf, "G_"); /* scope is global */ } else /* symbol is local */ dbuf_printf (aBuf, "L%s_", (sym->localof ? sym->localof->name : "-null-")); dbuf_printf (aBuf, "%s_%d_%d", sym->name, sym->level, sym->block); } /* if is has an absolute address then generate an equate for this no need to allocate space */ if (SPEC_ABSA (sym->etype)) { if (options.debug || sym->level == 0) dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype)); dbuf_printf (aBuf, "%s\t=\t0x%04x\n", sym->rname, SPEC_ADDR (sym->etype)); } else { if (options.debug || sym->level == 0) dbuf_printf (aBuf, "==.\n"); /* allocate space */ dbuf_printf (aBuf, "%s:\n", sym->rname); dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff); } } } }
/*-----------------------------------------------------------------*/ 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); 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 an 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; }
/* * Emit a set of symbols. * type - 0: have symbol tell whether it is local, extern or global * 1: assume all symbols in set to be global * 2: assume all symbols in set to be extern */ static void emitSymbolSet(set *s, int type) { symbol *sym; initList *list; unsigned sectionNr = 0; for (sym = setFirstItem(s); sym; sym = setNextItem(s)) { #if 0 fprintf (stdout, "; name %s, rname %s, level %d, block %d, key %d, local %d, ival %p, static %d, cdef %d, used %d\n", sym->name, sym->rname, sym->level, sym->block, sym->key, sym->islocal, sym->ival, IS_STATIC(sym->etype), sym->cdef, sym->used); #endif if (sym->etype && SPEC_ABSA(sym->etype) && IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype)) && sym->ival) { // handle config words pic14_assignConfigWordValue(SPEC_ADDR(sym->etype), (int)list2int(sym->ival)); pic14_stringInSet(sym->rname, &emitted, 1); continue; } if (sym->isstrlit) { // special case: string literals emitInitVal(ivalBuf, sym, sym->type, NULL); continue; } if (type != 0 || sym->cdef || (!IS_STATIC(sym->etype) && IS_GLOBAL(sym))) { // bail out for ___fsadd and friends if (sym->cdef && !sym->used) continue; /* export or import non-static globals */ if (!pic14_stringInSet(sym->rname, &emitted, 0)) { if (type == 2 || IS_EXTERN(sym->etype) || sym->cdef) { /* do not add to emitted set, it might occur again! */ //if (!sym->used) continue; // declare symbol emitIfNew (extBuf, &emitted, "\textern\t%s\n", sym->rname); } else { // declare symbol emitIfNew (gloBuf, &emitted, "\tglobal\t%s\n", sym->rname); if (!sym->ival && !IS_FUNC(sym->type)) { // also define symbol if (IS_ABSOLUTE(sym->etype)) { // absolute location? //dbuf_printf (gloDefBuf, "UD_%s_%u\tudata\t0x%04X\n", moduleName, sectionNr++, SPEC_ADDR(sym->etype)); // deferred to pic14_constructAbsMap } else { dbuf_printf (gloDefBuf, "UD_%s_%u\tudata\n", moduleName, sectionNr++); dbuf_printf (gloDefBuf, "%s\tres\t%d\n\n", sym->rname, getSize(sym->type)); } } // if } // if pic14_stringInSet(sym->rname, &emitted, 1); } // if } // if list = sym->ival; //if (list) showInitList(list, 0); if (list) { resolveIvalSym( list, sym->type ); emitInitVal(ivalBuf, sym, sym->type, sym->ival); dbuf_printf (ivalBuf, "\n"); } } // for sym }