+ if (IS_ARRAY(my_type)) {
+ DEBUGprintf ("(array, %d items, %d byte) below\n", DCL_ELEM(my_type), size);
+ assert (!list || list->type == INIT_DEEP);
+ if (list) list = list->init.deep;
+ for (i = 0; i < DCL_ELEM(my_type); i++) {
+ emitInitVal(oBuf, topsym, my_type->next, list);
+ topsym = NULL;
+ if (list) list = list->next;
+ } // for i
+ return;
+ }
+
+ if (IS_FLOAT(my_type)) {
+ // float, 32 bit
+ DEBUGprintf ("(float, %d byte) %lf\n", size, list ? list2int(list) : 0.0);
+ emitIvals(oBuf, topsym, list, 0, size);
+ return;
+ }
+
+ if (IS_CHAR(my_type) || IS_INT(my_type) || IS_LONG(my_type)) {
+ // integral type, 8, 16, or 32 bit
+ DEBUGprintf ("(integral, %d byte) 0x%lx/%ld\n", size, list ? (long)list2int(list) : 0, list ? (long)list2int(list) : 0);
+ emitIvals(oBuf, topsym, list, 0, size);
+ return;
+
+ } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == STRUCT) {
+ // struct
+ DEBUGprintf ("(struct, %d byte) handled below\n", size);
+ assert (!list || (list->type == INIT_DEEP));
+
+ // iterate over struct members and initList
+ if (list) list = list->init.deep;
+ sym = SPEC_STRUCT(my_type)->fields;
+ while (sym) {
+ long bitfield = 0;
+ int len = 0;
+ if (IS_BITFIELD(sym->type)) {
+ while (sym && IS_BITFIELD(sym->type)) {
+ assert (!list || ((list->type == INIT_NODE)
+ && IS_AST_LIT_VALUE(list->init.node)));
+ lit = (long) (list ? list2int(list) : 0);
+ DEBUGprintf ( "(bitfield member) %02lx (%d bit, starting at %d, bitfield %02lx)\n",
+ lit, SPEC_BLEN(getSpec(sym->type)),
+ SPEC_BSTR(getSpec(sym->type)), bitfield);
+ bitfield |= (lit & ((1ul << SPEC_BLEN(getSpec(sym->type))) - 1)) << SPEC_BSTR(getSpec(sym->type));
+ len += SPEC_BLEN(getSpec(sym->type));
+
+ sym = sym->next;
+ if (list) list = list->next;
+ } // while
+ assert (len < sizeof (long) * 8); // did we overflow our initializer?!?
+ len = (len + 7) & ~0x07; // round up to full bytes
+ emitIvals(oBuf, topsym, NULL, bitfield, len / 8);
+ topsym = NULL;
+ } // if
+
+ if (sym) {
+ emitInitVal(oBuf, topsym, sym->type, list);
+ topsym = NULL;
+ sym = sym->next;
+ if (list) list = list->next;
+ } // if
+ } // while
+ if (list) {
+ assert ( !"Excess initializers." );
+ } // if
+ return;
+
+ } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == UNION) {
+ // union
+ DEBUGprintf ("(union, %d byte) handled below\n", size);
+ assert (list && list->type == INIT_DEEP);
+
+ // iterate over union members and initList, try to map number and type of fields and initializers
+ my_type = matchIvalToUnion(list, my_type, size);
+ if (my_type) {
+ emitInitVal(oBuf, topsym, my_type, list->init.deep);
+ topsym = NULL;
+ size -= getSize(my_type);
+ if (size > 0) {
+ // pad with (leading) zeros
+ emitIvals(oBuf, NULL, NULL, 0, size);
+ }
+ return;
+ } // if
+
+ assert ( !"No UNION member matches the initializer structure.");
+ } else if (IS_BITFIELD(my_type)) {
+ assert ( !"bitfields should only occur in structs..." );
+
+ } else {
+ printf ("SPEC_NOUN: %d\n", SPEC_NOUN(my_type));
+ assert( !"Unhandled initialized type.");
+ }
+}
+
+/*
+ * 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
+}
+
+/*
+ * Iterate over all memmaps and emit their contents (attributes, symbols).
+ */
+static void
+showAllMemmaps(FILE *of)
+{
+ struct dbuf_s locBuf;
+ memmap *maps[] = {
+ xstack, istack, code, data, pdata, xdata, xidata, xinit,
+ idata, bit, statsg, c_abs, x_abs, i_abs, d_abs,
+ sfr, sfrbit, reg, generic, overlay, eeprom, home };
+ memmap * map;
+ int i;
+
+ DEBUGprintf ("---begin memmaps---\n");
+ if (!extBuf) extBuf = dbuf_new(1024);
+ if (!gloBuf) gloBuf = dbuf_new(1024);
+ if (!gloDefBuf) gloDefBuf = dbuf_new(1024);
+ if (!ivalBuf) ivalBuf = dbuf_new(1024);
+ dbuf_init(&locBuf, 1024);
+
+ dbuf_printf (extBuf, "%s; external declarations\n%s", iComments2, iComments2);
+ dbuf_printf (gloBuf, "%s; global declarations\n%s", iComments2, iComments2);
+ dbuf_printf (gloDefBuf, "%s; global definitions\n%s", iComments2, iComments2);
+ dbuf_printf (ivalBuf, "%s; initialized data\n%s", iComments2, iComments2);
+ dbuf_printf (&locBuf, "%s; compiler-defined variables\n%s", iComments2, iComments2);
+
+ for (i = 0; i < sizeof(maps) / sizeof (memmap *); i++) {
+ map = maps[i];
+ //DEBUGprintf ("memmap %i: %p\n", i, map);
+ if (map) {
+#if 0
+ fprintf (stdout, "; pageno %c, sname %s, dbName %c, ptrType %d, slbl %d, sloc %u, fmap %u, paged %u, direct %u, bitsp %u, codesp %u, regsp %u, syms %p\n",
+ map->pageno, map->sname, map->dbName, map->ptrType, map->slbl,
+ map->sloc, map->fmap, map->paged, map->direct, map->bitsp,
+ map->codesp, map->regsp, map->syms);
+#endif
+ emitSymbolSet(map->syms, 0);
+ } // if (map)
+ } // for i
+ DEBUGprintf ("---end of memmaps---\n");
+
+ emitSymbolSet(publics, 1);
+ emitSymbolSet(externs, 2);
+
+ emitPseudoStack(gloBuf, extBuf);
+ pic14_constructAbsMap(gloDefBuf, gloBuf);
+ pic14printLocals (&locBuf);
+ pic14_emitConfigWord(of); // must be done after all the rest
+
+ dbuf_write_and_destroy(extBuf, of);
+ dbuf_write_and_destroy(gloBuf, of);
+ dbuf_write_and_destroy(gloDefBuf, of);
+ dbuf_write_and_destroy(&locBuf, of);
+ dbuf_write_and_destroy(ivalBuf, of);
+
+ extBuf = gloBuf = gloDefBuf = ivalBuf = NULL;