X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCglue.c;h=5ba2b3670c109593da6d25f2dd4a672bb03811af;hb=e00a006bbf7426dc06f853b0f7547e216467f3a4;hp=75c40870403e09a3b6afb4ada19a4d72ef3579b4;hpb=7acf410d97f954d4aa6f2a728e2faa39b555ba13;p=fw%2Fsdcc diff --git a/src/SDCCglue.c b/src/SDCCglue.c index 75c40870..5ba2b367 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -26,12 +26,16 @@ #include "asm.h" #include #include "newalloc.h" +#include +#include -#if !defined(__BORLANDC__) && !defined(_MSC_VER) +#ifdef _WIN32 +#include +#else #include #endif -symbol *interrupts[256]; +symbol *interrupts[INTNO_MAX+1]; void printIval (symbol *, sym_link *, initList *, FILE *); set *publics = NULL; /* public variables */ @@ -41,10 +45,26 @@ set *externs = NULL; /* Varibles that are declared as extern */ unsigned maxInterrupts = 6; int allocInfo = 1; symbol *mainf; -extern char *VersionString; +set *pipeSet = NULL; /* set of pipes */ set *tmpfileSet = NULL; /* set of tmp file created by the compiler */ set *tmpfileNameSet = NULL; /* All are unlinked at close. */ +/*-----------------------------------------------------------------*/ +/* closePipes - closes all pipes created by the compiler */ +/*-----------------------------------------------------------------*/ +DEFSETFUNC (closePipes) +{ + FILE *pfile = item; + int ret; + + if (pfile) { + ret = pclose (pfile); + assert(ret != -1); + } + + return 0; +} + /*-----------------------------------------------------------------*/ /* closeTmpFiles - closes all tmp files created by the compiler */ /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */ @@ -52,9 +72,12 @@ set *tmpfileNameSet = NULL; /* All are unlinked at close. */ DEFSETFUNC (closeTmpFiles) { FILE *tfile = item; + int ret; - if (tfile) - fclose (tfile); + if (tfile) { + ret = fclose (tfile); + assert(ret == 0); + } return 0; } @@ -66,12 +89,14 @@ DEFSETFUNC (closeTmpFiles) DEFSETFUNC (rmTmpFiles) { char *name = item; + int ret; - if (name) - { - unlink (name); + if (name) { + ret = unlink (name); + assert(ret == 0); Safe_free (name); - } + } + return 0; } @@ -82,6 +107,10 @@ void rm_tmpfiles (void) { /* close temporary files */ + applyToSet (pipeSet, closePipes); + /* close temporary files */ + deleteSet (&pipeSet); + applyToSet (tmpfileSet, closeTmpFiles); /* remove temporary files */ applyToSet (tmpfileNameSet, rmTmpFiles); @@ -107,7 +136,6 @@ copyFile (FILE * dest, FILE * src) char * aopLiteralLong (value * val, int offset, int size) { - char *rs; union { float f; unsigned char c[4]; @@ -127,17 +155,18 @@ aopLiteralLong (value * val, int offset, int size) v >>= (offset * 8); switch (size) { case 1: - tsprintf (buffer, "!immedbyte", (unsigned int) v & 0xff); + tsprintf (buffer, sizeof(buffer), + "!immedbyte", (unsigned int) v & 0xff); break; case 2: - tsprintf (buffer, "!immedword", (unsigned int) v & 0xffff); + tsprintf (buffer, sizeof(buffer), + "!immedword", (unsigned int) v & 0xffff); break; default: /* Hmm. Too big for now. */ assert (0); } - rs = Safe_calloc (1, strlen (buffer) + 1); - return strcpy (rs, buffer); + return Safe_strdup (buffer); } /* PENDING: For now size must be 1 */ @@ -145,13 +174,14 @@ aopLiteralLong (value * val, int offset, int size) /* it is type float */ fl.f = (float) floatFromVal (val); -#ifdef _BIG_ENDIAN - tsprintf (buffer, "!immedbyte", fl.c[3 - offset]); +#ifdef WORDS_BIGENDIAN + tsprintf (buffer, sizeof(buffer), + "!immedbyte", fl.c[3 - offset]); #else - tsprintf (buffer, "!immedbyte", fl.c[offset]); + tsprintf (buffer, sizeof(buffer), + "!immedbyte", fl.c[offset]); #endif - rs = Safe_calloc (1, strlen (buffer) + 1); - return strcpy (rs, buffer); + return Safe_strdup (buffer); } /*-----------------------------------------------------------------*/ @@ -228,35 +258,43 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) /* if extern then do nothing or is a function then do nothing */ - if (IS_FUNC (sym->type)) + if (IS_FUNC (sym->type) && !(sym->isitmp)) continue; /* print extra debug info if required */ - if (options.debug) { - cdbSymbol (sym, cdbFile, FALSE, FALSE); - if (!sym->level) /* global */ - if (IS_STATIC (sym->etype)) - fprintf (map->oFile, "F%s$", moduleName); /* scope is file */ + if (options.debug) + { + if (!sym->level) /* global */ + { + if (IS_STATIC (sym->etype)) + fprintf (map->oFile, "F%s$", moduleName); /* scope is file */ + else + fprintf (map->oFile, "G$"); /* scope is global */ + } else - fprintf (map->oFile, "G$"); /* scope is global */ - else - /* symbol is local */ - fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-")); - fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block); - } + { + /* symbol is local */ + fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-")); + } + fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block); + } /* if it has an initial value then do it only if it is a global variable */ if (sym->ival && sym->level == 0) { if (SPEC_OCLS(sym->etype)==xidata) { - // create a new "XINIT (CODE)" symbol, that will be emitted later + /* create a new "XINIT (CODE)" symbol, that will be emitted later + in the static seg */ newSym=copySymbol (sym); SPEC_OCLS(newSym->etype)=xinit; - sprintf (newSym->name, "__xinit_%s", sym->name); - sprintf (newSym->rname,"__xinit_%s", sym->rname); - SPEC_CONST(newSym->etype)=1; + SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name); + SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname); + if (IS_SPEC (newSym->type)) + SPEC_CONST (newSym->type) = 1; + else + DCL_PTR_CONST (newSym->type) = 1; SPEC_STAT(newSym->etype)=1; - resolveIvalSym(newSym->ival); + resolveIvalSym(newSym->ival, newSym->type); // add it to the "XINIT (CODE)" segment addSet(&xinit->syms, newSym); @@ -266,11 +304,11 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) ival = initAggregates (sym, sym->ival, NULL); } else { if (getNelements(sym->type, sym->ival)>1) { - werror (W_EXCESS_INITIALIZERS, "scalar", - sym->name, sym->lineDef); + werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", + sym->name); } ival = newNode ('=', newAst_VALUE (symbolVal (sym)), - decorateType (resolveSymbols (list2expr (sym->ival)))); + decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK)); } codeOutFile = statsg->oFile; @@ -283,7 +321,8 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) // but try to do it anyway } allocInfo = 0; - eBBlockFromiCode (iCodeFromAst (ival)); + if (!astErrors(ival)) + eBBlockFromiCode (iCodeFromAst (ival)); allocInfo = 1; } } @@ -312,7 +351,7 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) else { int size = getSize (sym->type); if (size==0) { - werror(E_UNKNOWN_SIZE,sym->name); + werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name); } /* allocate space */ if (options.debug) { @@ -374,7 +413,7 @@ initPointer (initList * ilist, sym_link *toType) /* address of symbol */ if (IS_AST_SYM_VALUE (expr->left)) { val = copyValue (AST_VALUE (expr->left)); - val->type = newLink (); + val->type = newLink (DECLARATOR); if (SPEC_SCLS (expr->left->etype) == S_CODE) { DCL_TYPE (val->type) = CPOINTER; DCL_PTR_CONST (val->type) = port->mem.code_ro; @@ -433,7 +472,7 @@ initPointer (initList * ilist, sym_link *toType) IS_ARRAY(expr->right->ftype)) { val = copyValue (AST_VALUE (expr->right)); - val->type = newLink (); + val->type = newLink (DECLARATOR); if (SPEC_SCLS (expr->right->etype) == S_CODE) { DCL_TYPE (val->type) = CPOINTER; DCL_PTR_CONST (val->type) = port->mem.code_ro; @@ -453,7 +492,10 @@ initPointer (initList * ilist, sym_link *toType) return val; } wrong: - werror (E_INCOMPAT_PTYPES); + if (expr) + werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES); + else + werror (E_INCOMPAT_PTYPES); return NULL; } @@ -473,7 +515,7 @@ printChar (FILE * ofile, char *s, int plen) while (len && pplen < plen) { i = 60; - while (i && *s && pplen < plen) + while (i && pplen < plen) { if (*s < ' ' || *s == '\"' || *s=='\\') { @@ -504,7 +546,11 @@ printChar (FILE * ofile, char *s, int plen) else len = 0; } - tfprintf (ofile, "\t!db !constbyte\n", 0); + while (pplen < plen) + { + tfprintf (ofile, "\t!db !constbyte\n", 0); + pplen++; + } } /*-----------------------------------------------------------------*/ @@ -544,14 +590,19 @@ pointerTypeToGPByte (const int p_type, const char *iname, const char *oname) void _printPointerType (FILE * oFile, const char *name) { - /* if (TARGET_IS_DS390) */ if (options.model == MODEL_FLAT24) { - fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name); + if (port->little_endian) + fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name); + else + fprintf (oFile, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name); } else { - fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name); + if (port->little_endian) + fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name); + else + fprintf (oFile, "\t.byte (%s >> 8),%s", name, name); } } @@ -588,10 +639,6 @@ printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile) if (ilist->type == INIT_DEEP) ilist = ilist->init.deep; - if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) { - werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef); - } - if (!(val = list2val (ilist))) { // assuming a warning has been thrown val=constVal("0"); @@ -613,19 +660,26 @@ printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile) case 2: if (port->use_dw_for_init) tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2)); - else + else if (port->little_endian) fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1)); + else + fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0)); break; case 4: if (!val) { tfprintf (oFile, "\t!dw !constword\n", 0); tfprintf (oFile, "\t!dw !constword\n", 0); } - else { + else if (port->little_endian) { fprintf (oFile, "\t.byte %s,%s,%s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1), aopLiteral (val, 2), aopLiteral (val, 3)); } + else { + fprintf (oFile, "\t.byte %s,%s,%s,%s\n", + aopLiteral (val, 3), aopLiteral (val, 2), + aopLiteral (val, 1), aopLiteral (val, 0)); + } break; } } @@ -671,7 +725,7 @@ void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile) case 2: tfprintf (oFile, "\t!dw !constword\n",ival); break; - case 4: + case 4: /* EEP: why is this db and not dw? */ tfprintf (oFile, "\t!db !constword,!constword\n", (ival >> 8) & 0xffff, (ival & 0xffff)); break; @@ -692,7 +746,7 @@ printIvalStruct (symbol * sym, sym_link * type, sflds = SPEC_STRUCT (type)->fields; if (ilist->type != INIT_DEEP) { - werror (E_INIT_STRUCT, sym->name); + werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name); return; } @@ -706,7 +760,7 @@ printIvalStruct (symbol * sym, sym_link * type, } } if (iloop) { - werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef); + werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name); } return; } @@ -718,7 +772,6 @@ int printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s) { value *val; - int remain; if (!s) { @@ -732,10 +785,6 @@ printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s) printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type)); - if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) - while (remain--) - tfprintf (oFile, "\t!db !constbyte\n", 0); - return 1; } else @@ -754,15 +803,14 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) { initList *iloop; - int lcnt = 0, size = 0; - sym_link *last_type; + int size = 0; /* take care of the special case */ /* array of characters can be init */ /* by a string */ if (IS_CHAR (type->next)) { if (!IS_LITERAL(list2val(ilist)->etype)) { - werror (E_CONST_EXPECTED); + werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED); return; } if (printIvalChar (type, @@ -773,41 +821,32 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist, /* not the special case */ if (ilist->type != INIT_DEEP) { - werror (E_INIT_STRUCT, sym->name); + werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name); return; } - iloop = ilist->init.deep; - lcnt = DCL_ELEM (type); - for (last_type = type->next; last_type && DCL_ELEM (last_type); last_type = last_type->next) - lcnt *= DCL_ELEM (last_type); - - for (;;) + for (iloop=ilist->init.deep; iloop; iloop=iloop->next) { - size++; printIval (sym, type->next, iloop, oFile); - iloop = (iloop ? iloop->next : NULL); - - - /* if not array limits given & we */ - /* are out of initialisers then */ - if (!DCL_ELEM (type) && !iloop) - break; - - /* no of elements given and we */ - /* have generated for all of them */ - if (!--lcnt) { - /* if initializers left */ - if (iloop) { - werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef); - } + + if (++size > DCL_ELEM(type)) { + werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name); break; } } - - /* if we have not been given a size */ - if (!DCL_ELEM (type)) + + if (DCL_ELEM(type)) { + // pad with zeros if needed + if (sizenext); + while (size--) { + tfprintf (oFile, "\t!db !constbyte\n", 0); + } + } + } else { + // we have not been given a size, but we now know it DCL_ELEM (type) = size; + } return; } @@ -830,7 +869,7 @@ printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile) if (IS_LITERAL(val->etype)) { if (compareType(type,val->etype)==0) { - werror (E_INCOMPAT_TYPES); + werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES); printFromToType (val->type, type); } printIvalCharPtr (NULL, type, val, oFile); @@ -931,30 +970,48 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile) case 2: if (port->use_dw_for_init) tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size)); - else + else if (port->little_endian) tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1)); + else + tfprintf (oFile, "\t.byte %s,%s\n", + aopLiteral (val, 1), aopLiteral (val, 0)); break; case 3: if (IS_GENPTR(type) && floatFromVal(val)!=0) { // non-zero mcs51 generic pointer - werror (E_LITERAL_GENERIC); + werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC); + } + if (port->little_endian) { + fprintf (oFile, "\t.byte %s,%s,%s\n", + aopLiteral (val, 0), + aopLiteral (val, 1), + aopLiteral (val, 2)); + } else { + fprintf (oFile, "\t.byte %s,%s,%s\n", + aopLiteral (val, 2), + aopLiteral (val, 1), + aopLiteral (val, 0)); } - fprintf (oFile, "\t.byte %s,%s,%s\n", - aopLiteral (val, 0), - aopLiteral (val, 1), - aopLiteral (val, 2)); break; case 4: if (IS_GENPTR(type) && floatFromVal(val)!=0) { // non-zero ds390 generic pointer - werror (E_LITERAL_GENERIC); + werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC); + } + if (port->little_endian) { + fprintf (oFile, "\t.byte %s,%s,%s,%s\n", + aopLiteral (val, 0), + aopLiteral (val, 1), + aopLiteral (val, 2), + aopLiteral (val, 3)); + } else { + fprintf (oFile, "\t.byte %s,%s,%s,%s\n", + aopLiteral (val, 3), + aopLiteral (val, 2), + aopLiteral (val, 1), + aopLiteral (val, 0)); } - fprintf (oFile, "\t.byte %s,%s,%s,%s\n", - aopLiteral (val, 0), - aopLiteral (val, 1), - aopLiteral (val, 2), - aopLiteral (val, 3)); break; default: assert (0); @@ -998,7 +1055,7 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) /* check the type */ if (compareType (type, val->type) == 0) { - werror (W_INIT_WRONG); + werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG); printFromToType (val->type, type); } @@ -1013,12 +1070,29 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) case 2: if (port->use_dw_for_init) tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2)); - else + else if (port->little_endian) tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1)); + else + tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0)); break; case 3: // how about '390?? - fprintf (oFile, "\t.byte %s,%s,#0x%d\n", - aopLiteral (val, 0), aopLiteral (val, 1), GPTYPE_CODE); + fprintf (oFile, "; generic printIvalPtr\n"); + if (port->little_endian) + { + fprintf (oFile, "\t.byte %s,%s", + aopLiteral (val, 0), aopLiteral (val, 1)); + } + else + { + fprintf (oFile, "\t.byte %s,%s", + aopLiteral (val, 1), aopLiteral (val, 0)); + } + if (IS_GENPTR (val->type)) + fprintf (oFile, ",%s\n", aopLiteral (val, 2)); + else if (IS_PTR (val->type)) + fprintf (oFile, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL)); + else + fprintf (oFile, ",%s\n", aopLiteral (val, 2)); } return; } @@ -1053,12 +1127,11 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) void printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) { + sym_link *itype; + if (!ilist) return; - /* update line number for error msgs */ - lineno=sym->lineDef; - /* if structure then */ if (IS_STRUCT (type)) { @@ -1066,17 +1139,43 @@ printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) return; } - /* if this is a pointer */ - if (IS_PTR (type)) + /* if this is an array */ + if (IS_ARRAY (type)) { - printIvalPtr (sym, type, ilist, oFile); + printIvalArray (sym, type, ilist, oFile); return; } - /* if this is an array */ - if (IS_ARRAY (type)) + // not an aggregate, ilist must be a node + if (ilist->type!=INIT_NODE) { + // or a 1-element list + if (ilist->init.deep->next) { + werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", + sym->name); + } else { + ilist=ilist->init.deep; + } + } + + // and the type must match + itype=ilist->init.node->ftype; + + if (compareType(type, itype)==0) { + // special case for literal strings + if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) && + // which are really code pointers + IS_PTR(type) && DCL_TYPE(type)==CPOINTER) { + // no sweat + } else { + werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " "); + printFromToType(itype, type); + } + } + + /* if this is a pointer */ + if (IS_PTR (type)) { - printIvalArray (sym, type, ilist, oFile); + printIvalPtr (sym, type, ilist, oFile); return; } @@ -1116,7 +1215,7 @@ emitStaticSeg (memmap * map, FILE * out) /* print extra debug info if required */ if (options.debug) { - cdbSymbol (sym, cdbFile, FALSE, FALSE); + if (!sym->level) { /* global */ if (IS_STATIC (sym->etype)) @@ -1151,16 +1250,23 @@ emitStaticSeg (memmap * map, FILE * out) { fprintf (out, "%s:\n", sym->rname); noAlloc++; - resolveIvalSym (sym->ival); + resolveIvalSym (sym->ival, sym->type); printIval (sym, sym->type, sym->ival, out); noAlloc--; + /* if sym is a simple string and sym->ival is a string, + WE don't need it anymore */ + if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) && + IS_AST_SYM_VALUE(list2expr(sym->ival)) && + list2val(sym->ival)->sym->isstrlit) { + freeStringSymbol(list2val(sym->ival)->sym); + } } else { /* allocate space */ int size = getSize (sym->type); if (size==0) { - werror(E_UNKNOWN_SIZE,sym->name); + werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name); } fprintf (out, "%s:\n", sym->rname); /* special case for character strings */ @@ -1168,7 +1274,7 @@ emitStaticSeg (memmap * map, FILE * out) SPEC_CVAL (sym->etype).v_char) printChar (out, SPEC_CVAL (sym->etype).v_char, - strlen (SPEC_CVAL (sym->etype).v_char) + 1); + size); else tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff); } @@ -1182,6 +1288,9 @@ emitStaticSeg (memmap * map, FILE * out) void emitMaps (void) { + int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */ + /* ports but let's be conservative - EEP */ + inInitMode++; /* no special considerations for the following data, idata & bit & xdata */ @@ -1192,8 +1301,8 @@ emitMaps (void) if (port->genXINIT) { emitRegularMap (xidata, TRUE, TRUE); } - emitRegularMap (sfr, FALSE, FALSE); - emitRegularMap (sfrbit, FALSE, FALSE); + emitRegularMap (sfr, publicsfr, FALSE); + emitRegularMap (sfrbit, publicsfr, FALSE); emitRegularMap (home, TRUE, FALSE); emitRegularMap (code, TRUE, FALSE); @@ -1229,7 +1338,7 @@ createInterruptVect (FILE * vFile) /* only if the main function exists */ if (!(mainf = findSymWithLevel (SymbolTab, mainf))) { - if (!options.cc_only && !noAssemble) + if (!options.cc_only && !noAssemble && !options.c1mode) werror (E_NO_MAIN); return; } @@ -1255,14 +1364,21 @@ createInterruptVect (FILE * vFile) fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n"); - /* now for the other interrupts */ for (; i < maxInterrupts; i++) { if (interrupts[i]) - fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname); + { + fprintf (vFile, "\tljmp\t%s\n", interrupts[i]->rname); + if ( i != maxInterrupts - 1 ) + fprintf (vFile, "\t.ds\t5\n"); + } else - fprintf (vFile, "\treti\n\t.ds\t7\n"); + { + fprintf (vFile, "\treti\n"); + if ( i != maxInterrupts - 1 ) + fprintf (vFile, "\t.ds\t7\n"); + } } } } @@ -1286,7 +1402,8 @@ initialComments (FILE * afile) time_t t; time (&t); fprintf (afile, "%s", iComments1); - fprintf (afile, "; Version %s %s\n", VersionString, asctime (localtime (&t))); + fprintf (afile, "; Version " SDCC_VERSION_STR " (%s)\n", __DATE__); + fprintf (afile, "; This file generated %s", asctime (localtime (&t))); fprintf (afile, "%s", iComments2); } @@ -1379,8 +1496,6 @@ emitOverlay (FILE * afile) /* print extra debug info if required */ if (options.debug) { - cdbSymbol (sym, cdbFile, FALSE, FALSE); - if (!sym->level) { /* global */ if (IS_STATIC (sym->etype)) @@ -1411,7 +1526,7 @@ emitOverlay (FILE * afile) int size = getSize(sym->type); if (size==0) { - werror(E_UNKNOWN_SIZE,sym->name); + werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE); } if (options.debug) fprintf (afile, "==.\n"); @@ -1425,6 +1540,30 @@ emitOverlay (FILE * afile) } } + +/*-----------------------------------------------------------------*/ +/* spacesToUnderscores - replace spaces with underscores */ +/*-----------------------------------------------------------------*/ +static char * +spacesToUnderscores (char *dest, const char *src, size_t len) +{ + int i; + char *p; + + assert(dest != NULL); + assert(src != NULL); + assert(len > 0); + + --len; + for (p = dest, i = 0; *src != '\0' && i < len; ++src, ++i) { + *p++ = isspace(*src) ? '_' : *src; + } + *p = '\0'; + + return dest; +} + + /*-----------------------------------------------------------------*/ /* glue - the final glue that hold the whole thing together */ /*-----------------------------------------------------------------*/ @@ -1434,11 +1573,23 @@ glue (void) FILE *vFile; FILE *asmFile; FILE *ovrFile = tempfile (); + char moduleBuf[PATH_MAX]; + int mcs51_like; + + if(port->general.glue_up_main && + (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400)) + { + mcs51_like=1; /*So it has bits, sfr, sbits, data, idata, etc...*/ + } + else + { + mcs51_like=0; + } addSetHead (&tmpfileSet, ovrFile); /* print the global struct definitions */ if (options.debug) - cdbStructBlock (0, cdbFile); + cdbStructBlock (0); vFile = tempfile (); /* PENDING: this isnt the best place but it will do */ @@ -1455,25 +1606,20 @@ glue (void) /* do the overlay segments */ emitOverlay (ovrFile); + outputDebugSymbols(); + /* now put it all together into the assembler file */ /* create the assembler file name */ - if (!options.c1mode) + /* -o option overrides default name? */ + if ((noAssemble || options.c1mode) && fullDstFileName) { - /* -o option overrides default name? */ - if (noAssemble && fullDstFileName) - { - strcpy (scratchFileName, fullDstFileName); - } - else - { - strcpy (scratchFileName, dstFileName); - strcat (scratchFileName, port->assembler.file_ext); - } + strncpyz (scratchFileName, fullDstFileName, PATH_MAX); } else { - strcpy (scratchFileName, options.out_name); + strncpyz (scratchFileName, dstFileName, PATH_MAX); + strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX); } if (!(asmFile = fopen (scratchFileName, "w"))) @@ -1486,7 +1632,35 @@ glue (void) initialComments (asmFile); /* print module name */ - tfprintf (asmFile, "\t!module\n", moduleName); + tfprintf (asmFile, "\t!module\n", + spacesToUnderscores (moduleBuf, moduleName, sizeof moduleBuf)); + if(mcs51_like) + { + fprintf (asmFile, "\t.optsdcc -m%s", port->target); + + switch(options.model) + { + case MODEL_SMALL: fprintf (asmFile, " --model-small"); break; + case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break; + case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break; + case MODEL_LARGE: fprintf (asmFile, " --model-large"); break; + case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break; + case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break; + default: break; + } + /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/ + if(options.useXstack) fprintf (asmFile, " --xstack"); + /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/ + /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/ + if(options.noRegParams) fprintf (asmFile, " --no-reg-params"); + if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1"); + fprintf (asmFile, "\n"); + } + else if(TARGET_IS_Z80 || TARGET_IS_GBZ80 ) + { + fprintf (asmFile, "\t.optsdcc -m%s\n", port->target); + } + tfprintf (asmFile, "\t!fileprelude\n"); /* Let the port generate any global directives, etc. */ @@ -1500,21 +1674,25 @@ glue (void) if (port->assembler.externGlobal) printExterns (asmFile); - /* copy the sfr segment */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; special function registers\n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, sfr->oFile); - - /* copy the sbit segment */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; special function bits \n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, sfrbit->oFile); + if(( mcs51_like ) + ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */ + { + /* copy the sfr segment */ + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; special function registers\n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, sfr->oFile); + } - /*JCF: Create the areas for the register banks*/ - if( TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 ) + if(mcs51_like) { + /* copy the sbit segment */ + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; special function bits \n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, sfrbit->oFile); + + /*JCF: Create the areas for the register banks*/ if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3]) { fprintf (asmFile, "%s", iComments2); @@ -1533,7 +1711,7 @@ glue (void) /* copy the data segment */ fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; internal ram data\n"); + fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":""); fprintf (asmFile, "%s", iComments2); copyFile (asmFile, data->oFile); @@ -1541,7 +1719,7 @@ glue (void) /* create the overlay segments */ if (overlay) { fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; overlayable items in internal ram \n"); + fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":""); fprintf (asmFile, "%s", iComments2); copyFile (asmFile, ovrFile); } @@ -1557,7 +1735,7 @@ glue (void) } /* create the idata segment */ - if (idata) { + if ( (idata) && (mcs51_like) ) { fprintf (asmFile, "%s", iComments2); fprintf (asmFile, "; indirectly addressable internal ram data\n"); fprintf (asmFile, "%s", iComments2); @@ -1565,10 +1743,12 @@ glue (void) } /* copy the bit segment */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; bit data\n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, bit->oFile); + if (mcs51_like) { + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; bit data\n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, bit->oFile); + } /* if external stack then reserve space of it */ if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack) @@ -1582,10 +1762,12 @@ glue (void) /* copy xtern ram data */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; external ram data\n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, xdata->oFile); + if (mcs51_like) { + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; external ram data\n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, xdata->oFile); + } /* copy xternal initialized ram data */ fprintf (asmFile, "%s", iComments2); @@ -1593,6 +1775,13 @@ glue (void) fprintf (asmFile, "%s", iComments2); copyFile (asmFile, xidata->oFile); + /* If the port wants to generate any extra areas, let it do so. */ + if (port->extraAreas.genExtraAreaDeclaration) + { + port->extraAreas.genExtraAreaDeclaration(asmFile, + mainf && IFFUNC_HASBODY(mainf->type)); + } + /* copy the interrupt vector table */ if (mainf && IFFUNC_HASBODY(mainf->type)) { @@ -1619,32 +1808,46 @@ glue (void) if (mainf && IFFUNC_HASBODY(mainf->type)) { - fprintf (asmFile, "__sdcc_gsinit_startup:\n"); - /* if external stack is specified then the - higher order byte of the xdatalocation is - going into P2 and the lower order going into - spx */ - if (options.useXstack) - { - fprintf (asmFile, "\tmov\tP2,#0x%02x\n", - (((unsigned int) options.xdata_loc) >> 8) & 0xff); - fprintf (asmFile, "\tmov\t_spx,#0x%02x\n", - (unsigned int) options.xdata_loc & 0xff); + if (port->genInitStartup) + { + port->genInitStartup(asmFile); } + else + { + fprintf (asmFile, "__sdcc_gsinit_startup:\n"); + /* if external stack is specified then the + higher order byte of the xdatalocation is + going into P2 and the lower order going into + spx */ + if (options.useXstack) + { + fprintf (asmFile, "\tmov\tP2,#0x%02x\n", + (((unsigned int) options.xdata_loc) >> 8) & 0xff); + fprintf (asmFile, "\tmov\t_spx,#0x%02x\n", + (unsigned int) options.xdata_loc & 0xff); + } - /* initialise the stack pointer. JCF: aslink takes care of the location */ - fprintf (asmFile, "\tmov\tsp,#__start__stack\n"); /* MOF */ + // This should probably be a port option, but I'm being lazy. + // on the 400, the firmware boot loader gives us a valid stack + // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code) + if (!TARGET_IS_DS400) + { + /* initialise the stack pointer. JCF: aslink takes care of the location */ + fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */ + } - fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n"); - fprintf (asmFile, "\tmov\ta,dpl\n"); - fprintf (asmFile, "\tjz\t__sdcc_init_data\n"); - fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n"); - fprintf (asmFile, "__sdcc_init_data:\n"); + fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n"); + fprintf (asmFile, "\tmov\ta,dpl\n"); + fprintf (asmFile, "\tjz\t__sdcc_init_data\n"); + fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n"); + fprintf (asmFile, "__sdcc_init_data:\n"); - // if the port can copy the XINIT segment to XISEG - if (port->genXINIT) { - port->genXINIT(asmFile); - } + // if the port can copy the XINIT segment to XISEG + if (port->genXINIT) + { + port->genXINIT(asmFile); + } + } } copyFile (asmFile, statsg->oFile); @@ -1703,58 +1906,162 @@ glue (void) rm_tmpfiles (); } -/** Creates a temporary file name a'la tmpnam which avoids the bugs - in cygwin wrt c:\tmp. - Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile(). + +/** Creates a temporary file with unoque file name + Scans, in order: + - TMP, TEMP, TMPDIR env. varibles + - if Un*x system: /usr/tmp and /tmp + - root directory using mkstemp() if avaliable + - default location using tempnam() */ -char * -tempfilename (void) +static int +tempfileandname(char *fname, size_t len) { +#define TEMPLATE "sdccXXXXXX" +#define TEMPLATE_LEN ((sizeof TEMPLATE) - 1) + const char *tmpdir = NULL; - if (getenv ("TMP")) - tmpdir = getenv ("TMP"); - else if (getenv ("TEMP")) - tmpdir = getenv ("TEMP"); - else if (getenv ("TMPDIR")) - tmpdir = getenv ("TMPDIR"); - if (tmpdir) - { - char *name = tempnam (tmpdir, "sdcc"); - if (name) - { - return name; - } + int fd; + + if ((tmpdir = getenv ("TMP")) == NULL) + if ((tmpdir = getenv ("TEMP")) == NULL) + tmpdir = getenv ("TMPDIR"); + +#if defined(_WIN32) + { + static int warning_emitted; + + if (tmpdir == NULL) + { + tmpdir = "c:\\"; + if (!warning_emitted) + { + fprintf (stderr, "TMP not defined in environment, using %s for temporary files\n.", tmpdir); + warning_emitted = 1; + } + } + } +#else + { + /* try with /usr/tmp and /tmp on Un*x systems */ + struct stat statbuf; + + if (tmpdir == NULL) { + if (stat("/usr/tmp", &statbuf) != -1) + tmpdir = "/usr/tmp"; + else if (stat("/tmp", &statbuf) != -1) + tmpdir = "/tmp"; + } + } +#endif + +#ifdef HAVE_MKSTEMP + { + char fnamebuf[PATH_MAX]; + size_t name_len; + + if (fname == NULL || len == 0) { + fname = fnamebuf; + len = sizeof fnamebuf; + } + + if (tmpdir) { + name_len = strlen(tmpdir) + 1 + TEMPLATE_LEN; + + assert(name_len < len); + if (!(name_len < len)) /* in NDEBUG is defined */ + return -1; /* buffer too small, temporary file can not be created */ + + sprintf(fname, "%s" DIR_SEPARATOR_STRING TEMPLATE, tmpdir); + } + else { + name_len = TEMPLATE_LEN; + + assert(name_len < len); + if (!(name_len < len)) /* in NDEBUG is defined */ + return -1; /* buffer too small, temporary file can not be created */ + + strcpy(fname, TEMPLATE); } - return tmpnam (NULL); + + fd = mkstemp(fname); + } +#else + { + char *name = tempnam(tmpdir, "sdcc"); + + if (name == NULL) { + perror("Can't create temporary file name"); + exit(1); + } + + assert(strlen(name) < len); + if (!(strlen(name) < len)) /* in NDEBUG is defined */ + return -1; /* buffer too small, temporary file can not be created */ + + strcpy(fname, name); +#ifdef _WIN32 + fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE); +#else + fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); +#endif + } +#endif + + if (fd == -1) { + perror("Can't create temporary file"); + exit(1); + } + + return fd; } -/** Creates a temporary file a'la tmpfile which avoids the bugs - in cygwin wrt c:\tmp. - Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile(). + +/** Create a temporary file name +*/ +char * +tempfilename(void) +{ + int fd; + static char fnamebuf[PATH_MAX]; + + if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) { + fprintf(stderr, "Can't create temporary file name!"); + exit(1); + } + + fd = close(fd); + assert(fd != -1); + + return fnamebuf; +} + + +/** Create a temporary file and add it to tmpfileNameSet, + so that it is removed explicitly by rm_tmpfiles() + or implicitly at program extit. */ FILE * -tempfile (void) +tempfile(void) { - const char *tmpdir = NULL; - if (getenv ("TMP")) - tmpdir = getenv ("TMP"); - else if (getenv ("TEMP")) - tmpdir = getenv ("TEMP"); - else if (getenv ("TMPDIR")) - tmpdir = getenv ("TMPDIR"); - if (tmpdir) - { - char *name = Safe_strdup( tempnam (tmpdir, "sdcc")); - if (name) - { - FILE *fp = fopen (name, "w+b"); - if (fp) - { - addSetHead (&tmpfileNameSet, name); - } - return fp; - } - return NULL; - } - return tmpfile (); + int fd; + char *tmp; + FILE *fp; + char fnamebuf[PATH_MAX]; + + if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) { + fprintf(stderr, "Can't create temporary file!"); + exit(1); + } + + tmp = Safe_strdup(fnamebuf); + if (tmp) + addSetHead(&tmpfileNameSet, tmp); + + if ((fp = fdopen(fd, "w+b")) == NULL) { + perror("Can't create temporary file!"); + exit(1); + } + + return fp; }