#include "ralloc.h"
#include "pcode.h"
#include "newalloc.h"
+#include "gen.h"
+#include "main.h"
#ifdef WORDS_BIGENDIAN
}
+/* Check whether the given reg is shared amongst all .o files of a project.
+ * This is true for the pseudo stack and WSAVE, SSAVE and PSAVE. */
+int is_shared_address (int addr)
+{
+ return ((addr > Gstack_base_addr - 18)
+ && (addr <= Gstack_base_addr));
+}
+
+int
+is_shared (regs *reg)
+{
+ if (!reg) return 0;
+ return is_shared_address (reg->address);
+}
+
+/* set of already emitted symbols; we store only pointers to the emitted
+ * symbol names so these MUST NO BE CHANGED afterwards... */
+static set *symbolsEmitted = NULL;
+
+/*-------------------------------------------------------------------*/
+/* emitSymbolToFile - write a symbol definition only if it is not */
+/* already present */
+/*-------------------------------------------------------------------*/
+void
+emitSymbolToFile (FILE *of, const char *name, const char *section_type, int size, int addr, int useEQU, int globalize)
+{
+ const char *sym;
+ static unsigned int sec_idx = 0;
+
+ /* check whether the symbol is already defined */
+ for (sym = (const char *) setFirstItem (symbolsEmitted);
+ sym;
+ sym = (const char *) setNextItem (symbolsEmitted))
+ {
+ if (!strcmp (sym, name))
+ {
+ //fprintf (stderr, "%s: already emitted: %s\n", __FUNCTION__, name);
+ return;
+ }
+ } // for
+
+ /* new symbol -- define it */
+ //fprintf (stderr, "%s: emitting %s (%d)\n", __FUNCTION__, name, size);
+ if (useEQU)
+ fprintf (of, "%s\tEQU\t0x%04x\n", name, addr);
+ else
+ {
+ /* we place each symbol into a section of its own to allow the linker
+ * to distribute the data into all available memory banks */
+ if (!section_type) section_type = "udata";
+ if (addr != -1)
+ {
+ /* workaround gpasm bug with symbols being EQUated and placed in absolute sections */
+ if (is_shared_address (addr))
+ {
+ if (globalize) fprintf (of, "\tglobal\t%s\n", name);
+ fprintf (of, "udata_%s_%u\t%s\t0x%04x\n", moduleName, sec_idx++, section_type, addr);
+ fprintf (of, "%s\tres\t%d\n", name, size);
+ }
+ else
+ {
+ /* EQUs cannot be exported... */
+ fprintf (of, "%s\tEQU\t0x%04x\n", name, addr);
+ }
+ } else {
+ if (globalize) fprintf (of, "\tglobal\t%s\n", name);
+ fprintf (of, "udata_%s_%u\t%s\n", moduleName, sec_idx++, section_type);
+ fprintf (of, "%s\tres\t%d\n", name, size);
+ }
+ }
+
+ addSet (&symbolsEmitted, (void *) name);
+}
/*-----------------------------------------------------------------*/
/* emitRegularMap - emit code for maps with no special cases */
}
else
{
- fprintf (map->oFile, "%s\tres\t%d\n", sym->rname,getSize (sym->type) & 0xffff);
+ emitSymbolToFile (map->oFile, sym->rname, NULL, getSize (sym->type) & 0xffff, -1, 0, 0);
/*
{
int i, size;
{
initList *iloop;
unsigned size = 0;
-
+
if(!pb)
return;
if (ilist) {
return;
}
+/*-----------------------------------------------------------------*/
+/* printIvalPtr - generates code for initial value of pointers */
+/*-----------------------------------------------------------------*/
+extern value *initPointer (initList *, sym_link *toType);
+
+static void
+printIvalPtr (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
+{
+ value *val;
+
+ if (!ilist || !pb)
+ return;
+
+ fprintf (stderr, "FIXME: initializers for pointers...\n");
+ printTypeChain (type, stderr);
+
+ fprintf (stderr, "symbol: %s, DCL_TYPE():%d, DCL_ELEM():%d, IS_ARRAY():%d", sym->rname, DCL_TYPE(type), DCL_ELEM(type), IS_ARRAY(type));
+ fprintf (stderr, "ilist: type=%d (INIT_DEEP=%d, INIT_NODE=%d)\n", ilist->type, INIT_DEEP, INIT_NODE);
+
+ if (ilist && (ilist->type == INIT_DEEP))
+ ilist = ilist->init.deep;
+
+ /* function pointers */
+ if (IS_FUNC (type->next))
+ {
+ assert ( !"function pointers not yet handled" );
+ //printIvalFuncPtr (type, ilist, pb);
+ }
+
+ if (!(val = initPointer (ilist, type)))
+ return;
+
+ if (IS_CHAR (type->next))
+ {
+ if (printIvalChar (type, ilist, pb, NULL)) return;
+ }
+
+ /* check the type */
+ if (compareType (type, val->type) == 0)
+ {
+ werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
+ printFromToType (val->type, type);
+ }
+
+ if (IS_LITERAL (val->etype))
+ {
+ switch (getSize (type))
+ {
+ case 1:
+ fprintf (stderr, "BYTE: %i\n", (unsigned char)floatFromVal (val) & 0x00FF);
+ break;
+ case 2:
+ fprintf (stderr, "WORD: %i\n", (unsigned int)floatFromVal (val) & 0x00FFFF);
+ break;
+ case 3: /* gneric pointers */
+ assert ( !"generic pointers not yet handled" );
+ case 4:
+ fprintf (stderr, "LONG: %i\n", (unsigned int)floatFromVal (val) & 0x0000FFFFFFFF);
+ break;
+ default:
+ assert ( !"invaild size of value -- aborting" );
+ } // switch
+
+ return;
+ } // if (IS_LITERAL)
+
+ /* now handle symbolic values */
+ switch (getSize (type))
+ {
+ case 1:
+ fprintf (stderr, "BYTE: %s", val->name);
+ break;
+ case 2:
+ fprintf (stderr, "WORD: %s", val->name);
+ break;
+ case 4:
+ fprintf (stderr, "LONG: %s", val->name);
+ break;
+ default:
+ assert ( !"invalid size of (symbolic) value -- aborting" );
+ } // switch
+}
+
/*-----------------------------------------------------------------*/
/* printIval - generates code for initial value */
/*-----------------------------------------------------------------*/
/* if structure then */
if (IS_STRUCT (type))
{
- //fprintf(stderr,"%s struct\n",__FUNCTION__);
+ //fprintf(stderr,"%s struct: %s\n",__FUNCTION__, sym->rname);
printIvalStruct (sym, type, ilist, pb);
return;
}
- /* if this is a pointer */
- if (IS_PTR (type))
+ /* if this is an array */
+ if (IS_ARRAY (type))
{
- //fprintf(stderr,"%s pointer\n",__FUNCTION__);
- //printIvalPtr (sym, type, ilist, oFile);
+ //fprintf(stderr,"%s array: %s\n",__FUNCTION__, sym->rname);
+ printIvalArray (sym, type, ilist, pb);
return;
}
- /* if this is an array */
- if (IS_ARRAY (type))
+ /* if this is a pointer */
+ if (IS_PTR (type))
{
- //fprintf(stderr,"%s array\n",__FUNCTION__);
- printIvalArray (sym, type, ilist, pb);
+ //fprintf(stderr,"%s pointer: %s\n",__FUNCTION__, sym->rname);
+ printIvalPtr (sym, type, ilist, pb);
return;
}
/* if type is SPECIFIER */
if (IS_SPEC (type))
{
- //fprintf(stderr,"%s spec\n",__FUNCTION__);
+ //fprintf(stderr,"%s spec %s\n",__FUNCTION__, sym->rname);
printIvalType (sym, type, ilist, pb);
return;
}
addSetHead(&tmpfileSet,ovrFile);
pCodeInitRegisters();
-
+
+ /* check for main() */
+ mainf = newSymbol ("main", 0);
+ mainf->block = 0;
+ mainf = findSymWithLevel (SymbolTab, mainf);
+
+ if (!mainf || !IFFUNC_HASBODY(mainf->type))
+ {
+ /* main missing -- import stack from main module */
+ //fprintf (stderr, "main() missing -- assuming we are NOT the main module\n");
+ pic14_options.isLibrarySource = 1;
+ }
+
+#if 0
if (mainf && IFFUNC_HASBODY(mainf->type)) {
pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
}
}
-
+#endif
/* At this point we've got all the code in the form of pCode structures */
/* Now it needs to be rearranged into the order it should be placed in the */
werror (E_FILE_OPEN_ERR, buffer);
exit (1);
}
+
+ /* prepare statistics */
+ resetpCodeStatistics ();
/* initial comments */
pic14initialComments (asmFile);
fprintf (asmFile, "; bit data\n");
fprintf (asmFile, "%s", iComments2);
copyFile (asmFile, bit->oFile);
-
+
/* copy the interrupt vector table */
if (mainf && IFFUNC_HASBODY(mainf->type)) {
copyFile (asmFile, vFile);
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; interrupt and initialization code\n");
fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "code_init\t%s\t0x4\n", CODE_NAME); // Note - for mplink may have to enlarge section vectors in .lnk file
+ fprintf (asmFile, "code_interrupt\t%s\t0x4\n", CODE_NAME); // Note - for mplink may have to enlarge section vectors in .lnk file
/* interrupt service routine */
- fprintf (asmFile, "__sdcc_interrupt:\n");
+ fprintf (asmFile, "__sdcc_interrupt\n");
copypCode(asmFile, 'I');
/* initialize data memory */
- fprintf (asmFile,"__sdcc_gsinit_startup:\n");
+ fprintf (asmFile, "code_init\t%s\n", CODE_NAME); // Note - for mplink may have to enlarge section vectors in .lnk file
+ fprintf (asmFile,"__sdcc_gsinit_startup\n");
/* FIXME: This is temporary. The idata section should be used. If
not, we could add a special feature to the linker. This will
work in the mean time. Put all initalized data in main.c */
/* unknown */
copypCode(asmFile, 'P');
+
+ dumppCodeStatistics (asmFile);
fprintf (asmFile,"\tend\n");