-------------------------------------------------------------------------*/
#include "common.h"
+#include "asm.h"
#include <time.h>
+#if !defined(__BORLANDC__) && !defined(_MSC_VER)
+#if 0 /* This should no longer be necessary. */
+// This is a bit messy because we define link ourself
+#define link NoLiNk
+#include <unistd.h>
+#undef link
+#else
+
+#include <unistd.h>
+#endif
+#else
+// No unistd.h in Borland C++
+#endif
+
symbol *interrupts[256];
-/*extern char *aopLiteral (value *, int);*//* drdani Jan 30 2000 */
-void printIval (symbol *, link *, initList *, FILE *);
-extern int noAlloc;
+
+void printIval (symbol *, sym_link *, initList *, FILE *);
set *publics = NULL; /* public variables */
+set *externs = NULL; /* Varibles that are declared as extern */
/* TODO: this should be configurable (DS803C90 uses more than 6) */
int maxInterrupts = 6;
-extern int maxRegBank ;
+int allocInfo = 1;
symbol *mainf;
extern char *VersionString;
-extern FILE *codeOutFile;
set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
+set *tmpfileNameSet = NULL; /* All are unlinked at close. */
+
/*-----------------------------------------------------------------*/
/* closeTmpFiles - closes all tmp files created by the compiler */
/* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
return 0;
}
+/*-----------------------------------------------------------------*/
+/* rmTmpFiles - closes all tmp files created by the compiler */
+/* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
+/*-----------------------------------------------------------------*/
+DEFSETFUNC(rmTmpFiles)
+{
+ char *name = item;
+
+ if (name) {
+ unlink(name);
+ free(name);
+ }
+ return 0;
+}
+
/*-----------------------------------------------------------------*/
/* copyFile - copies source file to destination file */
/*-----------------------------------------------------------------*/
fputc (ch, dest);
}
-/*-----------------------------------------------------------------*/
-/* aopLiteral - string from a literal value */
-/*-----------------------------------------------------------------*/
-char *aopLiteral (value *val, int offset)
+char *aopLiteralLong(value *val, int offset, int size)
{
char *rs;
union {
unsigned long v = floatFromVal(val);
v >>= (offset * 8);
- sprintf(buffer,"#0x%02x",((char) v) & 0xff);
- ALLOC_ATOMIC(rs,strlen(buffer)+1);
+ switch (size) {
+ case 1:
+ tsprintf(buffer, "!immedbyte", (unsigned int)v & 0xff);
+ break;
+ case 2:
+ tsprintf(buffer, "!immedword", (unsigned int)v & 0xffff);
+ break;
+ default:
+ /* Hmm. Too big for now. */
+ assert(0);
+ }
+ ALLOC(rs,strlen(buffer)+1);
return strcpy (rs,buffer);
}
+ /* PENDING: For now size must be 1 */
+ assert(size == 1);
+
/* it is type float */
fl.f = (float) floatFromVal(val);
-#ifdef _BIG_ENDIAN
- sprintf(buffer,"#0x%02x",fl.c[3-offset]);
+#ifdef _BIG_ENDIAN
+ tsprintf(buffer, "!immedbyte", fl.c[3-offset]);
#else
- sprintf(buffer,"#0x%02x",fl.c[offset]);
+ tsprintf(buffer, "!immedbyte", fl.c[offset]);
#endif
- ALLOC_ATOMIC(rs,strlen(buffer)+1);
+ ALLOC(rs,strlen(buffer)+1);
return strcpy (rs,buffer);
}
+/*-----------------------------------------------------------------*/
+/* aopLiteral - string from a literal value */
+/*-----------------------------------------------------------------*/
+char *aopLiteral (value *val, int offset)
+{
+ return aopLiteralLong(val, offset, 1);
+}
+
/*-----------------------------------------------------------------*/
/* emitRegularMap - emit code for maps with no special cases */
/*-----------------------------------------------------------------*/
{
symbol *sym;
- if (addPublics)
- fprintf (map->oFile, "\t.area\t%s\n", map->sname);
+ if (addPublics) {
+ /* PENDING: special case here - should remove */
+ if (!strcmp(map->sname, CODE_NAME))
+ tfprintf(map->oFile, "\t!areacode\n", map->sname);
+ else if (!strcmp(map->sname, DATA_NAME))
+ tfprintf(map->oFile, "\t!areadata\n", map->sname);
+ else if (!strcmp(map->sname, HOME_NAME))
+ tfprintf(map->oFile, "\t!areahome\n", map->sname);
+ else
+ tfprintf(map->oFile, "\t!area\n", map->sname);
+ }
/* print the area name */
for (sym = setFirstItem (map->syms); sym;
sym = setNextItem (map->syms)) {
- /* if extern then do nothing */
- if (IS_EXTERN (sym->etype))
+ /* if extern then add it into the extern list */
+ if (IS_EXTERN (sym->etype)) {
+ addSetHead (&externs, sym);
continue;
+ }
/* if allocation required check is needed
then check if the symbol really requires
if ((sym->level == 0 ||
(sym->_isparm && !IS_REGPARM(sym->etype))) &&
addPublics &&
- !IS_STATIC (sym->etype))
+ !IS_STATIC (sym->etype) &&
+ (sym->used || sym->fbody)) {
addSetHead (&publics, sym);
+ }
/* if extern then do nothing or is a function
then do nothing */
continue;
/* print extra debug info if required */
- if (options.debug || sym->level == 0) {
+ if ((options.debug || sym->level == 0) && !options.nodebug) {
cdbSymbol(sym,cdbFile,FALSE,FALSE);
/* 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)
+ if ((options.debug || sym->level == 0) && !options.nodebug)
fprintf (map->oFile," == 0x%04x\n",SPEC_ADDR (sym->etype));
fprintf (map->oFile, "%s\t=\t0x%04x\n",
}
else {
/* allocate space */
- if (options.debug || sym->level == 0)
+ if ((options.debug || sym->level == 0) && !options.nodebug)
fprintf(map->oFile,"==.\n");
- fprintf (map->oFile, "%s:\n", sym->rname);
- fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
+ if (IS_STATIC(sym->etype))
+ tfprintf(map->oFile, "!slabeldef\n", sym->rname);
+ else
+ tfprintf(map->oFile, "!labeldef\n", sym->rname);
+ tfprintf(map->oFile, "\t!ds\n", (unsigned int)getSize (sym->type) & 0xffff);
}
- /* if it has a initial value then do it only if
+ /* if it has an initial value then do it only if
it is a global variable */
if (sym->ival && sym->level == 0) {
ast *ival = NULL;
if (IS_AGGREGATE (sym->type))
ival = initAggregates (sym, sym->ival, NULL);
else
- ival = newNode ('=', newAst (EX_VALUE, symbolVal (sym)),
+ ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
decorateType (resolveSymbols (list2expr (sym->ival))));
codeOutFile = statsg->oFile;
+ allocInfo = 0;
eBBlockFromiCode (iCodeFromAst (ival));
+ allocInfo = 1;
sym->ival = NULL;
}
}
}
-
/*-----------------------------------------------------------------*/
/* initPointer - pointer initialization code massaging */
/*-----------------------------------------------------------------*/
val->type = newLink();
if (SPEC_SCLS(expr->left->etype) == S_CODE) {
DCL_TYPE(val->type) = CPOINTER ;
- DCL_PTR_CONST(val->type) = 1;
+ DCL_PTR_CONST(val->type) = port->mem.code_ro;
}
else
if (SPEC_SCLS(expr->left->etype) == S_XDATA)
if (SPEC_SCLS(expr->left->etype) == S_IDATA)
DCL_TYPE(val->type) = IPOINTER ;
else
- if (SPEC_SCLS(expr->left->etype) == S_FLASH)
- DCL_TYPE(val->type) = FLPOINTER ;
+ if (SPEC_SCLS(expr->left->etype) == S_EEPROM)
+ DCL_TYPE(val->type) = EEPPOINTER ;
else
DCL_TYPE(val->type) = POINTER ;
val->type->next = expr->left->ftype;
expr->left->opval.op == PTR_OP &&
IS_ADDRESS_OF_OP(expr->left->left))
return valForStructElem(expr->left->left->left,
- expr->left->right);
+ expr->left->right);
+
+ }
+ /* case 3. (((char *) &a) +/- constant) */
+ if (IS_AST_OP(expr) &&
+ (expr->opval.op == '+' || expr->opval.op == '-') &&
+ IS_AST_OP(expr->left) && expr->left->opval.op == CAST &&
+ IS_AST_OP(expr->left->right) &&
+ expr->left->right->opval.op == '&' &&
+ IS_AST_LIT_VALUE(expr->right)) {
+
+ return valForCastAggr(expr->left->right->left,
+ expr->left->left->opval.lnk,
+ expr->right,expr->opval.op);
+
}
wrong:
int i;
int len = strlen (s);
int pplen = 0;
-
- while (len && pplen < plen) {
+ char buf[100];
+ char *p = buf;
- fprintf (ofile, "\t.ascii /");
+ while (len && pplen < plen) {
i = 60;
while (i && *s && pplen < plen) {
- if (*s < ' ' || *s == '/') {
- fprintf (ofile, "/\n\t.byte 0x%02x\n\t.ascii /", *s++);
+ if (*s < ' ' || *s == '\"') {
+ *p = '\0';
+ if (p != buf)
+ tfprintf(ofile, "\t!ascii\n", buf);
+ tfprintf(ofile, "\t!db !constbyte\n", *s);
+ p = buf;
}
- else
- fprintf (ofile, "%c", *s++);
+ else {
+ *p = *s;
+ p++;
+ }
+ s++;
pplen++;
i--;
}
- fprintf (ofile, "/\n");
+ if (p != buf) {
+ *p = '\0';
+ tfprintf(ofile, "\t!ascii\n", buf);
+ p = buf;
+ }
if (len > 60)
len -= 60;
else
len = 0;
}
- if (pplen < plen)
- fprintf(ofile,"\t.byte\t0\n");
+ tfprintf(ofile, "\t!db !constbyte\n", 0);
+}
+
+/*-----------------------------------------------------------------*/
+/* return the generic pointer high byte for a given pointer type. */
+/*-----------------------------------------------------------------*/
+int pointerTypeToGPByte(const int p_type)
+{
+ switch (p_type)
+ {
+ case IPOINTER:
+ case POINTER:
+ return 0;
+ case GPOINTER:
+ /* hack - if we get a generic pointer, we just assume
+ * it's an FPOINTER (i.e. in XDATA space).
+ */
+ case FPOINTER:
+ return 1;
+ case CPOINTER:
+ return 2;
+ case PPOINTER:
+ return 3;
+ default:
+ fprintf(stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
+ p_type);
+ break;
+ }
+ return -1;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* printPointerType - generates ival for pointer type */
+/*-----------------------------------------------------------------*/
+void _printPointerType(FILE *oFile, const char *name)
+{
+ if (IS_DS390_PORT)
+ {
+ fprintf(oFile, "\t.byte %s,(%s >> 8),(%s >> 16)",name,name,name);
+ }
+ else
+ {
+ fprintf(oFile, "\t.byte %s,(%s >> 8)",name,name);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* printPointerType - generates ival for pointer type */
+/*-----------------------------------------------------------------*/
+void printPointerType(FILE *oFile, const char *name)
+{
+ _printPointerType(oFile, name);
+ fprintf(oFile, "\n");
+}
+
+/*-----------------------------------------------------------------*/
+/* printGPointerType - generates ival for generic pointer type */
+/*-----------------------------------------------------------------*/
+void printGPointerType(FILE *oFile, const char *name,
+ const unsigned int type)
+{
+ _printPointerType(oFile,name);
+ fprintf(oFile, ",#0x%02x\n", pointerTypeToGPByte(type));
}
/*-----------------------------------------------------------------*/
/* printIvalType - generates ival for int/char */
/*-----------------------------------------------------------------*/
-void printIvalType (link * type, initList * ilist, FILE * oFile)
+void printIvalType (sym_link * type, initList * ilist, FILE * oFile)
{
value *val;
switch (getSize (type)) {
case 1:
if (!val)
- fprintf (oFile, "\t.byte 0\n");
+ tfprintf(oFile, "\t!db !constbyte\n", 0);
else
- fprintf (oFile, "\t.byte %s\n",
+ tfprintf(oFile, "\t!dbs\n",
aopLiteral (val, 0));
break;
case 2:
- if (!val)
- fprintf (oFile, "\t.word 0\n");
+ if (port->use_dw_for_init)
+ tfprintf(oFile, "\t!dws\n", aopLiteralLong(val, 0, 2));
else
- fprintf (oFile, "\t.byte %s,%s\n",
- aopLiteral (val, 0), aopLiteral (val, 1));
+ fprintf(oFile, "\t.byte %s,%s\n", aopLiteral(val, 0),aopLiteral(val, 1));
break;
-
case 4:
- if (!val)
- fprintf (oFile, "\t.word 0,0\n");
- else
+ if (!val) {
+ tfprintf (oFile, "\t!dw !constword\n", 0);
+ tfprintf (oFile, "\t!dw !constword\n", 0);
+ }
+ else {
fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
aopLiteral (val, 0), aopLiteral (val, 1),
aopLiteral (val, 2), aopLiteral (val, 3));
+ }
break;
}
-
- return;
}
/*-----------------------------------------------------------------*/
/* printIvalStruct - generates initial value for structures */
/*-----------------------------------------------------------------*/
-void printIvalStruct (symbol * sym,link * type,
+void printIvalStruct (symbol * sym,sym_link * type,
initList * ilist, FILE * oFile)
{
symbol *sflds;
/*-----------------------------------------------------------------*/
/* printIvalChar - generates initital value for character array */
/*-----------------------------------------------------------------*/
-int printIvalChar (link * type, initList * ilist, FILE * oFile, char *s)
+int printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
{
value *val;
int remain;
if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) -1))>0)
while (remain--)
- fprintf (oFile, "\t.byte 0\n");
+ tfprintf (oFile, "\t!db !constbyte\n", 0);
return 1;
}
/*-----------------------------------------------------------------*/
/* printIvalArray - generates code for array initialization */
/*-----------------------------------------------------------------*/
-void printIvalArray (symbol * sym, link * type, initList * ilist,
+void printIvalArray (symbol * sym, sym_link * type, initList * ilist,
FILE * oFile)
{
initList *iloop;
/*-----------------------------------------------------------------*/
/* printIvalFuncPtr - generate initial value for function pointers */
/*-----------------------------------------------------------------*/
-void printIvalFuncPtr (link * type, initList * ilist, FILE * oFile)
+void printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
{
value *val;
int dLvl = 0;
val = list2val (ilist);
/* check the types */
if ((dLvl = checkType (val->type, type->next)) <= 0) {
-
- fprintf (oFile, "\t.word 0\n");
+ tfprintf(oFile, "\t!dw !constword\n", 0);
return;
}
/* now generate the name */
if (!val->sym) {
- if (IS_LITERAL (val->etype))
- fprintf (oFile, "\t.byte %s,%s\n",
- aopLiteral (val, 0), aopLiteral (val, 1));
- else
- fprintf (oFile, "\t.byte %s,(%s >> 8)\n",
- val->name, val->name);
+ if (port->use_dw_for_init)
+ {
+ tfprintf(oFile, "\t!dws\n", val->name);
+ }
+ else
+ {
+ printPointerType(oFile, val->name);
+ }
}
- else
- fprintf (oFile, "\t.byte %s,(%s >> 8)\n",
- val->sym->rname, val->sym->rname);
+ else
+ if (port->use_dw_for_init)
+ {
+ tfprintf(oFile, "\t!dws\n", val->sym->rname);
+ }
+ else
+ {
+ printPointerType(oFile, val->sym->rname);
+ }
return;
}
/*-----------------------------------------------------------------*/
/* printIvalCharPtr - generates initial values for character pointers */
/*-----------------------------------------------------------------*/
-int printIvalCharPtr (symbol * sym, link * type, value * val, FILE * oFile)
+int printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
{
int size = 0;
+ /* PENDING: this is _very_ mcs51 specific, including a magic
+ number...
+ It's also endin specific.
+ */
size = getSize (type);
-
- if (size == 1)
- fprintf(oFile,
- "\t.byte %s", val->name) ;
- else
- fprintf (oFile,
- "\t.byte %s,(%s >> 8)",
- val->name, val->name);
-
- if (size > 2)
- fprintf (oFile, ",#0x02\n");
- else
- fprintf (oFile, "\n");
-
+
+ if (val->name && strlen(val->name)) {
+ if (size == 1) /* This appears to be Z80 specific?? */
+ {
+ tfprintf(oFile,
+ "\t!dbs\n", val->name);
+ }
+ else if (size == FPTRSIZE)
+ {
+ if (port->use_dw_for_init)
+ {
+ tfprintf(oFile, "\t!dws\n", val->name);
+ }
+ else
+ {
+ printPointerType(oFile, val->name);
+ }
+ }
+ else if (size == GPTRSIZE)
+ {
+ /* PENDING: 0x02 or 0x%02x, CDATA? */
+ printGPointerType(oFile, val->name,
+ (IS_PTR(val->type) ? DCL_TYPE(val->type) :
+ PTR_TYPE(SPEC_OCLS(val->etype))));
+ }
+ else
+ {
+ fprintf(stderr, "*** internal error: unknown size in "
+ "printIvalCharPtr.\n");
+ }
+ }
+ else {
+ /* What is this case? Are these pointers? */
+ switch (size) {
+ case 1:
+ tfprintf(oFile, "\t!dbs\n", aopLiteral(val, 0));
+ break;
+ case 2:
+ if (port->use_dw_for_init)
+ tfprintf(oFile, "\t!dws\n", aopLiteralLong(val, 0, size));
+ else
+ tfprintf(oFile, "\t.byte %s,%s\n",
+ aopLiteral(val, 0),aopLiteral(val, 1));
+ break;
+ case 3:
+ /* PENDING: 0x02 or 0x%02x, CDATA? */
+ fprintf(oFile, "\t.byte %s,%s,#0x02\n",
+ aopLiteral (val, 0), aopLiteral (val, 1));
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+
if (val->sym && val->sym->isstrlit)
addSet (&statsg->syms, val->sym);
/*-----------------------------------------------------------------*/
/* printIvalPtr - generates initial value for pointers */
/*-----------------------------------------------------------------*/
-void printIvalPtr (symbol * sym, link * type, initList * ilist, FILE * oFile)
+void printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
{
value *val;
+ int size;
/* if deep then */
if (ilist->type == INIT_DEEP)
if (IS_LITERAL (val->etype)) {
switch (getSize (type)) {
case 1:
- fprintf (oFile, "\t.byte 0x%02x\n", ((char) floatFromVal (val)) & 0xff);
+ tfprintf(oFile, "\t!db !constbyte\n", (unsigned int)floatFromVal(val) & 0xff);
break;
case 2:
- fprintf (oFile, "\t.byte %s,%s\n",
- aopLiteral (val, 0), aopLiteral (val, 1));
-
+ if (port->use_dw_for_init)
+ tfprintf(oFile, "\t!dws\n", aopLiteralLong(val, 0, 2));
+ else
+ tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral(val, 0),aopLiteral(val, 1));
break;
case 3:
- fprintf (oFile, "\t.byte %s,%s,0x%02x\n",
- aopLiteral (val, 0), aopLiteral (val, 1), CPOINTER);
+ fprintf (oFile, "\t.byte %s,%s,#0x02\n",
+ aopLiteral (val, 0), aopLiteral (val, 1));
}
return;
}
- switch (getSize (type)) {
- case 1:
- fprintf (oFile, "\t.byte %s\n", val->name);
- break;
- case 2:
- fprintf (oFile, "\t.byte %s,(%s >> 8)\n", val->name, val->name);
- break;
-
- case 3:
- fprintf (oFile, "\t.byte %s,(%s >> 8),0x%02x\n",
- val->name, val->name, DCL_TYPE(val->type));
+ size = getSize (type);
+
+ if (size == 1) /* Z80 specific?? */
+ {
+ tfprintf (oFile, "\t!dbs\n", val->name);
+ }
+ else if (size == FPTRSIZE)
+ {
+ tfprintf (oFile, "\t!dws\n", val->name);
+ }
+ else if (size == GPTRSIZE)
+ {
+ printGPointerType(oFile, val->name,
+ (IS_PTR(val->type) ? DCL_TYPE(val->type) :
+ PTR_TYPE(SPEC_OCLS(val->etype))));
}
return;
}
/*-----------------------------------------------------------------*/
/* printIval - generates code for initial value */
/*-----------------------------------------------------------------*/
-void printIval (symbol * sym, link * type, initList * ilist, FILE * oFile)
+void printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
{
if (!ilist)
return;
/*-----------------------------------------------------------------*/
/* emitStaticSeg - emitcode for the static segment */
/*-----------------------------------------------------------------*/
-void emitStaticSeg (memmap * map)
+void emitStaticSeg(memmap * map, FILE *out)
{
symbol *sym;
/* fprintf(map->oFile,"\t.area\t%s\n",map->sname); */
-
-
+ if (!out)
+ out = code->oFile;
+
/* for all variables in this segment do */
for (sym = setFirstItem (map->syms); sym;
sym = setNextItem (map->syms)) {
addSetHead (&publics, sym);
/* print extra debug info if required */
- if (options.debug || sym->level == 0) {
+ if ((options.debug || sym->level == 0) && !options.nodebug) {
cdbSymbol(sym,cdbFile,FALSE,FALSE);
if (!sym->level) { /* global */
if (IS_STATIC(sym->etype))
- fprintf(code->oFile,"F%s$",moduleName); /* scope is file */
+ fprintf(out,"F%s$",moduleName); /* scope is file */
else
- fprintf(code->oFile,"G$"); /* scope is global */
+ fprintf(out,"G$"); /* scope is global */
}
else
/* symbol is local */
- fprintf(code->oFile,"L%s$",
+ fprintf(out,"L%s$",
(sym->localof ? sym->localof->name : "-null-"));
- fprintf(code->oFile,"%s$%d$%d",sym->name,sym->level,sym->block);
+ fprintf(out,"%s$%d$%d",sym->name,sym->level,sym->block);
}
/* if it has an absolute address */
if (SPEC_ABSA (sym->etype)) {
- if (options.debug || sym->level == 0)
- fprintf(code->oFile," == 0x%04x\n", SPEC_ADDR (sym->etype));
+ if ((options.debug || sym->level == 0) && !options.nodebug)
+ fprintf(out," == 0x%04x\n", SPEC_ADDR (sym->etype));
- fprintf (code->oFile, "%s\t=\t0x%04x\n",
+ fprintf (out, "%s\t=\t0x%04x\n",
sym->rname,
SPEC_ADDR (sym->etype));
}
else {
- if (options.debug || sym->level == 0)
- fprintf(code->oFile," == .\n");
+ if ((options.debug || sym->level == 0) && !options.nodebug)
+ fprintf(out," == .\n");
/* if it has an initial value */
if (sym->ival) {
- fprintf (code->oFile, "%s:\n", sym->rname);
+ fprintf (out, "%s:\n", sym->rname);
noAlloc++;
resolveIvalSym (sym->ival);
- printIval (sym, sym->type, sym->ival, code->oFile);
+ printIval (sym, sym->type, sym->ival, out);
noAlloc--;
}
else {
/* allocate space */
- fprintf (code->oFile, "%s:\n", sym->rname);
+ fprintf (out, "%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)
- printChar (code->oFile,
+ printChar (out,
SPEC_CVAL (sym->etype).v_char,
strlen(SPEC_CVAL (sym->etype).v_char)+1);
- else
- fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type)& 0xffff);
+ else
+ tfprintf(out, "\t!ds\n", (unsigned int)getSize (sym->type)& 0xffff);
}
}
}
emitRegularMap (xdata, TRUE,TRUE);
emitRegularMap (sfr, FALSE,FALSE);
emitRegularMap (sfrbit, FALSE,FALSE);
+ emitRegularMap (home, TRUE,FALSE);
emitRegularMap (code, TRUE,FALSE);
- emitStaticSeg (statsg);
+
+ emitStaticSeg (statsg, code->oFile);
+}
+
+/*-----------------------------------------------------------------*/
+/* flushStatics - flush all currently defined statics out to file */
+/* and delete. Temporary function */
+/*-----------------------------------------------------------------*/
+void flushStatics(void)
+{
+ emitStaticSeg(statsg, codeOutFile);
+ statsg->syms = NULL;
}
/*-----------------------------------------------------------------*/
return;
}
- fprintf (vFile, "\t.area\t%s\n", CODE_NAME);
+ tfprintf(vFile, "\t!areacode\n", CODE_NAME);
fprintf (vFile, "__interrupt_vect:\n");
symbol *sym;
fprintf (afile, "%s", iComments2);
- fprintf (afile, "; publics variables in this module\n");
+ fprintf (afile, "; Public variables in this module\n");
fprintf (afile, "%s", iComments2);
for (sym = setFirstItem (publics); sym;
sym = setNextItem (publics))
- fprintf (afile, "\t.globl %s\n", sym->rname);
+ tfprintf(afile, "\t!global\n", sym->rname);
+}
+
+/*-----------------------------------------------------------------*/
+/* printExterns - generates .global for externs */
+/*-----------------------------------------------------------------*/
+void printExterns (FILE * afile)
+{
+ symbol *sym;
+
+ fprintf (afile, "%s", iComments2);
+ fprintf (afile, "; Externals used\n");
+ fprintf (afile, "%s", iComments2);
+
+ for (sym = setFirstItem (externs); sym;
+ sym = setNextItem (externs))
+ tfprintf(afile, "\t!global\n", sym->rname);
}
/*-----------------------------------------------------------------*/
set *ovrset;
if (!elementsInSet(ovrSetSets))
- fprintf(afile,"\t.area\t%s\n", port->mem.overlay_name);
+ tfprintf(afile,"\t!area\n", port->mem.overlay_name);
/* for each of the sets in the overlay segment do */
for (ovrset = setFirstItem(ovrSetSets); ovrset;
for (sym = setFirstItem(ovrset); sym;
sym = setNextItem(ovrset)) {
-
- /* if extern then do nothing */
+
+ /* if extern then add it to the publics tabledo nothing */
if (IS_EXTERN (sym->etype))
continue;
continue;
/* print extra debug info if required */
- if (options.debug || sym->level == 0) {
+ if ((options.debug || sym->level == 0) && !options.nodebug) {
cdbSymbol(sym,cdbFile,FALSE,FALSE);
an equate for this no need to allocate space */
if (SPEC_ABSA (sym->etype)) {
- if (options.debug || sym->level == 0)
+ if ((options.debug || sym->level == 0) && !options.nodebug)
fprintf (afile," == 0x%04x\n",SPEC_ADDR (sym->etype));
fprintf (afile, "%s\t=\t0x%04x\n",
SPEC_ADDR (sym->etype));
}
else {
- if (options.debug || sym->level == 0)
+ if ((options.debug || sym->level == 0) && !options.nodebug)
fprintf(afile,"==.\n");
/* allocate space */
- fprintf (afile, "%s:\n", sym->rname);
- fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
+ tfprintf(afile, "!labeldef\n", sym->rname);
+ tfprintf(afile, "\t!ds\n", (unsigned int)getSize (sym->type) & 0xffff);
}
}
{
FILE *vFile;
FILE *asmFile;
- FILE *ovrFile = tmpfile();
+ FILE *ovrFile = tempfile();
addSetHead(&tmpfileSet,ovrFile);
/* print the global struct definitions */
- if (options.debug)
+ if (options.debug && !options.nodebug)
cdbStructBlock (0,cdbFile);
- /* create the interrupt vector table */
- createInterruptVect ((vFile = tmpfile ()));
+ vFile = tempfile();
+ /* PENDING: this isnt the best place but it will do */
+ if (port->general.glue_up_main) {
+ /* create the interrupt vector table */
+ createInterruptVect (vFile);
+ }
+
addSetHead(&tmpfileSet,vFile);
/* emit code for the all the variables declared */
/* now put it all together into the assembler file */
/* create the assembler file name */
- sprintf (buffer, srcFileName);
- strcat (buffer, ".asm");
+
+ if (!options.c1mode) {
+ sprintf (buffer, srcFileName);
+ strcat (buffer, ".asm");
+ }
+ else {
+ strcpy(buffer, options.out_name);
+ }
+
if (!(asmFile = fopen (buffer, "w"))) {
werror (E_FILE_OPEN_ERR, buffer);
exit (1);
initialComments (asmFile);
/* print module name */
- fprintf (asmFile, "\t.module %s\n", moduleName);
-
+ tfprintf(asmFile, "\t!module\n", moduleName);
+ tfprintf(asmFile, "\t!fileprelude\n");
+
/* Let the port generate any global directives, etc. */
if (port->genAssemblerPreamble)
{
/* print the global variables in this module */
printPublics (asmFile);
+ if (port->assembler.externGlobal)
+ printExterns (asmFile);
-
/* copy the sfr segment */
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; special function registers\n");
if (mainf && mainf->fbody) {
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; Stack segment in internal ram \n");
- fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
"__start__stack:\n\t.ds\t1\n\n");
}
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; global & static initialisations\n");
fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "\t.area %s\n", port->mem.static_name); /* MOF */
+
+ /* Everywhere we generate a reference to the static_name area,
+ * (which is currently only here), we immediately follow it with a
+ * definition of the post_static_name area. This guarantees that
+ * the post_static_name area will immediately follow the static_name
+ * area.
+ */
+ tfprintf(asmFile, "\t!area\n", port->mem.static_name); /* MOF */
+ tfprintf(asmFile, "\t!area\n", port->mem.post_static_name);
+ tfprintf(asmFile, "\t!area\n", port->mem.static_name);
+
if (mainf && mainf->fbody) {
fprintf (asmFile,"__sdcc_gsinit_startup:\n");
/* if external stack is specified then the
}
copyFile (asmFile, statsg->oFile);
-
+
+ if (port->general.glue_up_main && mainf && mainf->fbody)
+ {
+ /* This code is generated in the post-static area.
+ * This area is guaranteed to follow the static area
+ * by the ugly shucking and jiving about 20 lines ago.
+ */
+ tfprintf(asmFile, "\t!area\n", port->mem.post_static_name);
+ fprintf (asmFile,"\tljmp\t__sdcc_program_startup\n");
+ }
+
+ fprintf (asmFile,
+ "%s"
+ "; Home\n"
+ "%s", iComments2, iComments2);
+ tfprintf(asmFile, "\t!areahome\n", HOME_NAME);
+ copyFile (asmFile, home->oFile);
+
/* copy over code */
fprintf (asmFile, "%s", iComments2);
fprintf (asmFile, "; code\n");
fprintf (asmFile, "%s", iComments2);
- fprintf (asmFile, "\t.area %s\n", port->mem.code_name);
+ tfprintf(asmFile, "\t!areacode\n", CODE_NAME);
if (mainf && mainf->fbody) {
/* entry point @ start of CSEG */
fclose (asmFile);
applyToSet(tmpfileSet,closeTmpFiles);
+ applyToSet(tmpfileNameSet, rmTmpFiles);
+}
+
+/** 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().
+*/
+FILE *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 = tempnam(tmpdir, "sdcc");
+ if (name) {
+ FILE *fp = fopen(name, "w+b");
+ if (fp)
+ {
+ addSetHead(&tmpfileNameSet, name);
+ }
+ return fp;
+ }
+ return NULL;
+ }
+ return tmpfile();
+}
+
+char *gc_strdup(const char *s)
+{
+ char *ret;
+ ALLOC(ret, strlen(s)+1);
+ strcpy(ret, s);
+ return ret;
}