#include "gen.h"
#include "device.h"
#include "main.h"
-#include <string.h>
-
+#include "dbuf_string.h"
#include <string.h>
-
extern symbol *interrupts[256];
void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p);
extern int noAlloc;
extern int maxRegBank;
extern symbol *mainf;
extern char *VersionString;
-extern FILE *codeOutFile;
-extern set *tmpfileSet;
-extern set *tmpfileNameSet;
+extern struct dbuf_s *codeOutBuf;
extern char *iComments1;
extern char *iComments2;
extern unsigned long pFile_isize;
extern unsigned long pic16_countInstructions();
+set *pic16_localFunctions = NULL;
set *rel_idataSymSet=NULL;
set *fix_idataSymSet=NULL;
extern void pic16_AnalyzeBanking (void);
extern void pic16_OptimizeJumps ();
extern void pic16_OptimizeBanksel ();
-extern void copyFile (FILE * dest, FILE * src);
extern void pic16_InlinepCode(void);
extern void pic16_writeUsedRegs(FILE *);
/*-----------------------------------------------------------------*/
/* aopLiteral - string from a literal value */
/*-----------------------------------------------------------------*/
-int pic16aopLiteral (value *val, int offset)
+unsigned int pic16aopLiteral (value *val, int offset)
{
union {
float f;
// fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
if(addPublics)
- fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
+ dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
/* print the area name */
for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
// fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
// sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
- fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
+ dbuf_printf (&map->oBuf, "%s\tEQU\t0x%04x\n",
sym->rname,
SPEC_ADDR (sym->etype));
if (IS_BITVAR (sym->etype)) {
bitvars++;
} else {
- fprintf (map->oFile, "\t%s\n", sym->rname);
+ dbuf_printf (map->oBuf, "\t%s\n", sym->rname);
if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
for (i = 1; i < size; i++)
- fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
+ dbuf_printf (map->oBuf, "\t%s_%d\n", sym->rname, i);
}
}
- fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
+ dbuf_printf (map->oBuf, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
#endif
}
if(ival) {
setAstLineno(ival, sym->lineDef);
- codeOutFile = statsg->oFile;
+ codeOutBuf = &statsg->oBuf;
GcurMemmap = statsg;
eBBlockFromiCode (iCodeFromAst (ival));
sym->ival = NULL;
goto wrong;
/* try it the old way first */
- if ((val = constExprValue (expr, FALSE)))
+ if (expr->etype && (val = constExprValue (expr, FALSE)))
return val;
/* ( ptr + constant ) */
a variable or address of an array element */
if (IS_AST_OP (expr) && expr->opval.op == '&') {
/* address of symbol */
- if (IS_AST_SYM_VALUE (expr->left)) {
- val = copyValue (AST_VALUE (expr->left));
+ if (IS_AST_SYM_VALUE (expr->left) && expr->left->etype) {
+ val = AST_VALUE (expr->left);
val->type = newLink (DECLARATOR);
if(SPEC_SCLS (expr->left->etype) == S_CODE) {
DCL_TYPE (val->type) = CPOINTER;
iloop = ilist->init.deep;
}
- for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
+ for (; (sflds && iloop); sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
// fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
if (IS_BITFIELD(sflds->type)) {
pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
/* symbol has absolute address but no initial value */
/* allocate space */
- fprintf (code->oFile, "%s:\n", sym->rname);
+ dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
/* special case for character strings */
if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
pBlock *pb;
/* symbol doesn't have absolute address but has initial value */
- fprintf (code->oFile, "%s:\n", sym->rname);
+ dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
noAlloc++;
resolveIvalSym (sym->ival, sym->type);
/* symbol doesn't have absolute address and no initial value */
/* allocate space */
// fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
- fprintf (code->oFile, "%s:\n", sym->rname);
+ dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
/* special case for character strings */
if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
SPEC_CVAL (sym->etype).v_char) {
{
int i;
- for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
+ for(i=0;i<=(pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart);i++)
if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
fprintf (of, "\t__config 0x%x, 0x%hhx\n",
pic16->cwInfo.confAddrStart+i,
{
int i;
- for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
+ for(i=0;i<=(pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart);i++)
if(pic16->idInfo.irInfo[i].emit)
fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
pic16->idInfo.idAddrStart+i,
pic16emitRegularMap (sfrbit, FALSE, FALSE);
pic16emitRegularMap (code, TRUE, FALSE);
pic16emitStaticSeg (statsg);
+ pic16emitStaticSeg (c_abs);
}
/*-----------------------------------------------------------------*/
/* createInterruptVect - creates the interrupt vector */
/*-----------------------------------------------------------------*/
static void
-pic16createInterruptVect (FILE * vFile)
+pic16createInterruptVect (struct dbuf_s * vBuf)
{
/* if the main is only a prototype ie. no body then do nothing */
#if 0
#endif
#if 0
if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
- fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
- fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
+ dbuf_printf (vBuf, ";\t.area\t%s\n", CODE_NAME);
+ dbuf_printf (vBuf, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
/* this is an overkill since WE are the port,
* and we know if we have a genIVT function! */
}
}
+int
+pic16_stringInSet(const char *str, set **world, int autoAdd)
+{
+ char *s;
+
+ if (!str) return 1;
+ assert(world);
+
+ for (s = setFirstItem(*world); s; s = setNextItem(*world))
+ {
+ /* found in set */
+ if (0 == strcmp(s, str)) return 1;
+ }
+
+ /* not found */
+ if (autoAdd) addSet(world, Safe_strdup(str));
+ return 0;
+}
+
+static int
+pic16_emitSymbolIfNew(FILE *file, const char *fmt, const char *sym, int checkLocals)
+{
+ static set *emitted = NULL;
+
+ if (!pic16_stringInSet(sym, &emitted, 1)) {
+ /* sym was not in emittedSymbols */
+ if (!checkLocals || !pic16_stringInSet(sym, &pic16_localFunctions, 0)) {
+ /* sym is not a locally defined function---avoid bug #1443651 */
+ fprintf( file, fmt, sym );
+ return 0;
+ }
+ }
+ return 1;
+}
+
/*-----------------------------------------------------------------*/
/* printPublics - generates global declarations for publics */
/*-----------------------------------------------------------------*/
for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
/* sanity check */
if(!IS_STATIC(sym->etype))
- fprintf(afile, "\tglobal %s\n", sym->rname);
+ pic16_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0);
}
/*-----------------------------------------------------------------*/
fprintf(afile, "%s", iComments2);
for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
- fprintf(afile, "\textern %s\n", sym->rname);
+ pic16_emitSymbolIfNew(afile, "\textern %s\n", sym->rname, 1);
for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
- fprintf(afile, "\textern _%s\n", sym->name);
+ pic16_emitSymbolIfNew(afile, "\textern _%s\n", sym->name, 1);
}
/*-----------------------------------------------------------------*/
/* emitOverlay - will emit code for the overlay stuff */
/*-----------------------------------------------------------------*/
static void
-pic16emitOverlay (FILE * afile)
+pic16emitOverlay (struct dbuf_s *aBuf)
{
set *ovrset;
if (!elementsInSet (ovrSetSets))
- fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
+ dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name);
/* for each of the sets in the overlay segment do */
for (ovrset = setFirstItem (ovrSetSets); ovrset;
otherwise the assembler will append each of these
declarations into one chunk and will not overlay
sad but true */
- fprintf (afile, ";\t.area _DUMMY\n");
+ dbuf_printf (aBuf, ";\t.area _DUMMY\n");
/* output the area informtion */
- fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
+ dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
}
for (sym = setFirstItem (ovrset); sym;
{
if (options.debug || sym->level == 0)
- fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
+ dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
- fprintf (afile, "%s\t=\t0x%04x\n",
+ dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
sym->rname,
SPEC_ADDR (sym->etype));
}
else
{
if (options.debug || sym->level == 0)
- fprintf (afile, "==.\n");
+ dbuf_printf (aBuf, "==.\n");
/* allocate space */
- fprintf (afile, "%s:\n", sym->rname);
- fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
+ dbuf_printf (aBuf, "%s:\n", sym->rname);
+ dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
}
}
void
pic16glue ()
{
- FILE *vFile;
FILE *asmFile;
- FILE *ovrFile = tempfile();
+ struct dbuf_s ovrBuf;
+ struct dbuf_s vBuf;
+
+ dbuf_init(&ovrBuf, 4096);
+ dbuf_init(&vBuf, 4096);
mainf = newSymbol ("main", 0);
mainf->block = 0;
mainf = findSymWithLevel(SymbolTab, mainf);
- addSetHead(&tmpfileSet,ovrFile);
pic16_pCodeInitRegisters();
if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
/* print the global struct definitions */
- vFile = tempfile();
/* PENDING: this isnt the best place but it will do */
if (port->general.glue_up_main) {
/* create the interrupt vector table */
- pic16createInterruptVect (vFile);
+ pic16createInterruptVect (&vBuf);
}
- addSetHead(&tmpfileSet,vFile);
-
/* emit code for the all the variables declared */
pic16emitMaps ();
/* do the overlay segments */
- pic16emitOverlay(ovrFile);
+ pic16emitOverlay(&ovrBuf);
pic16_AnalyzepCode('*');
#if 1
pic16_OptimizeJumps();
}
- /* print the extern variables to this module */
- pic16_printExterns(asmFile);
-
/* print the global variables in this module */
pic16printPublics (asmFile);
+ /* print the extern variables to this module */
+ pic16_printExterns(asmFile);
+
pic16_writeUsedRegs(asmFile);
#if 0
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; external ram data\n");
fprintf (asmFile, "%s", iComments2);
- copyFile (asmFile, xdata->oFile);
+ dbuf_write_and_destroy (&xdata->oBuf, asmFile);
#endif
#if 0
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; bit data\n");
fprintf (asmFile, "%s", iComments2);
- copyFile (asmFile, bit->oFile);
+ dbuf_write_and_destroy (&bit->oBuf, asmFile);
#endif
/* copy the interrupt vector table */
fprintf (asmFile, "\n%s", iComments2);
fprintf (asmFile, "; interrupt vector \n");
fprintf (asmFile, "%s", iComments2);
- copyFile (asmFile, vFile);
+ dbuf_write_and_destroy (&vBuf, asmFile);
}
/* copy global & static initialisations */
}
}
-// copyFile (stderr, code->oFile);
+// dbuf_write_and_destroy (&code->oBuf, stderr);
fprintf(asmFile, "; I code from now on!\n");
pic16_copypCode(asmFile, 'I');
fprintf (asmFile,"\tend\n");
fclose (asmFile);
-
- rm_tmpfiles();
}