1 /*-------------------------------------------------------------------------
3 SDCCglue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
38 symbol *interrupts[INTNO_MAX+1];
40 void printIval (symbol *, sym_link *, initList *, FILE *);
41 set *publics = NULL; /* public variables */
42 set *externs = NULL; /* Varibles that are declared as extern */
44 /* TODO: this should be configurable (DS803C90 uses more than 6) */
45 unsigned maxInterrupts = 6;
48 set *pipeSet = NULL; /* set of pipes */
49 set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
50 set *tmpfileNameSet = NULL; /* All are unlinked at close. */
52 /*-----------------------------------------------------------------*/
53 /* closePipes - closes all pipes created by the compiler */
54 /*-----------------------------------------------------------------*/
55 DEFSETFUNC (closePipes)
68 /*-----------------------------------------------------------------*/
69 /* closeTmpFiles - closes all tmp files created by the compiler */
70 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
71 /*-----------------------------------------------------------------*/
72 DEFSETFUNC (closeTmpFiles)
85 /*-----------------------------------------------------------------*/
86 /* rmTmpFiles - unlinks all tmp files created by the compiler */
87 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
88 /*-----------------------------------------------------------------*/
89 DEFSETFUNC (rmTmpFiles)
103 /*-----------------------------------------------------------------*/
104 /* rm_tmpfiles - close and remove temporary files and delete sets */
105 /*-----------------------------------------------------------------*/
109 /* close temporary files */
110 applyToSet (pipeSet, closePipes);
111 /* close temporary files */
112 deleteSet (&pipeSet);
114 applyToSet (tmpfileSet, closeTmpFiles);
115 /* remove temporary files */
116 applyToSet (tmpfileNameSet, rmTmpFiles);
117 /* delete temorary file sets */
118 deleteSet (&tmpfileSet);
119 deleteSet (&tmpfileNameSet);
122 /*-----------------------------------------------------------------*/
123 /* copyFile - copies source file to destination file */
124 /*-----------------------------------------------------------------*/
126 copyFile (FILE * dest, FILE * src)
132 if ((ch = fgetc (src)) != EOF)
137 aopLiteralLong (value * val, int offset, int size)
146 // assuming we have been warned before
150 /* if it is a float then it gets tricky */
151 /* otherwise it is fairly simple */
152 if (!IS_FLOAT (val->type)) {
153 unsigned long v = (unsigned long) floatFromVal (val);
158 tsprintf (buffer, sizeof(buffer),
159 "!immedbyte", (unsigned int) v & 0xff);
162 tsprintf (buffer, sizeof(buffer),
163 "!immedword", (unsigned int) v & 0xffff);
166 /* Hmm. Too big for now. */
169 return Safe_strdup (buffer);
172 /* PENDING: For now size must be 1 */
175 /* it is type float */
176 fl.f = (float) floatFromVal (val);
177 #ifdef WORDS_BIGENDIAN
178 tsprintf (buffer, sizeof(buffer),
179 "!immedbyte", fl.c[3 - offset]);
181 tsprintf (buffer, sizeof(buffer),
182 "!immedbyte", fl.c[offset]);
184 return Safe_strdup (buffer);
187 /*-----------------------------------------------------------------*/
188 /* aopLiteral - string from a literal value */
189 /*-----------------------------------------------------------------*/
191 aopLiteral (value * val, int offset)
193 return aopLiteralLong (val, offset, 1);
196 /*-----------------------------------------------------------------*/
197 /* emitRegularMap - emit code for maps with no special cases */
198 /*-----------------------------------------------------------------*/
200 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
210 /* PENDING: special case here - should remove */
211 if (!strcmp (map->sname, CODE_NAME))
212 tfprintf (map->oFile, "\t!areacode\n", map->sname);
213 else if (!strcmp (map->sname, DATA_NAME))
214 tfprintf (map->oFile, "\t!areadata\n", map->sname);
215 else if (!strcmp (map->sname, HOME_NAME))
216 tfprintf (map->oFile, "\t!areahome\n", map->sname);
218 tfprintf (map->oFile, "\t!area\n", map->sname);
221 for (sym = setFirstItem (map->syms); sym;
222 sym = setNextItem (map->syms))
226 /* if extern then add it into the extern list */
227 if (IS_EXTERN (sym->etype))
229 addSetHead (&externs, sym);
233 /* if allocation required check is needed
234 then check if the symbol really requires
235 allocation only for local variables */
237 if (arFlag && !IS_AGGREGATE (sym->type) &&
238 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
239 !sym->allocreq && sym->level)
242 /* for bitvar locals and parameters */
243 if (!arFlag && !sym->allocreq && sym->level
244 && !SPEC_ABSA (sym->etype)) {
248 /* if global variable & not static or extern
249 and addPublics allowed then add it to the public set */
250 if ((sym->level == 0 ||
251 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
253 !IS_STATIC (sym->etype) &&
254 (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
256 addSetHead (&publics, sym);
259 /* if extern then do nothing or is a function
261 if (IS_FUNC (sym->type) && !(sym->isitmp))
264 /* print extra debug info if required */
267 if (!sym->level) /* global */
269 if (IS_STATIC (sym->etype))
270 fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
272 fprintf (map->oFile, "G$"); /* scope is global */
276 /* symbol is local */
277 fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
279 fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
282 /* if it has an initial value then do it only if
283 it is a global variable */
284 if (sym->ival && sym->level == 0) {
285 if (SPEC_OCLS(sym->etype)==xidata) {
286 /* create a new "XINIT (CODE)" symbol, that will be emitted later
288 newSym=copySymbol (sym);
289 SPEC_OCLS(newSym->etype)=xinit;
290 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
291 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
292 if (IS_SPEC (newSym->type))
293 SPEC_CONST (newSym->type) = 1;
295 DCL_PTR_CONST (newSym->type) = 1;
296 SPEC_STAT(newSym->etype)=1;
297 resolveIvalSym(newSym->ival);
299 // add it to the "XINIT (CODE)" segment
300 addSet(&xinit->syms, newSym);
303 if (IS_AGGREGATE (sym->type)) {
304 ival = initAggregates (sym, sym->ival, NULL);
306 if (getNelements(sym->type, sym->ival)>1) {
307 werror (W_EXCESS_INITIALIZERS, "scalar",
308 sym->name, sym->lineDef);
310 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
311 decorateType (resolveSymbols (list2expr (sym->ival))));
313 codeOutFile = statsg->oFile;
316 // set ival's lineno to where the symbol was defined
317 setAstLineno (ival, lineno=sym->lineDef);
318 // check if this is not a constant expression
319 if (!constExprTree(ival)) {
320 werror (E_CONST_EXPECTED, "found expression");
321 // but try to do it anyway
324 eBBlockFromiCode (iCodeFromAst (ival));
331 /* if is has an absolute address then generate
332 an equate for this no need to allocate space */
333 if (SPEC_ABSA (sym->etype))
337 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
339 if (TARGET_IS_XA51) {
342 } else if (map==bit || map==sfrbit) {
346 fprintf (map->oFile, "%s\t%s\t0x%04x\n",
348 SPEC_ADDR (sym->etype));
351 int size = getSize (sym->type);
353 werror(E_UNKNOWN_SIZE,sym->name);
357 fprintf (map->oFile, "==.\n");
359 if (IS_STATIC (sym->etype))
360 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
362 tfprintf (map->oFile, "!labeldef\n", sym->rname);
363 tfprintf (map->oFile, "\t!ds\n",
364 (unsigned int) size & 0xffff);
369 /*-----------------------------------------------------------------*/
370 /* initPointer - pointer initialization code massaging */
371 /*-----------------------------------------------------------------*/
373 initPointer (initList * ilist, sym_link *toType)
376 ast *expr = list2expr (ilist);
381 /* try it the oldway first */
382 if ((val = constExprValue (expr, FALSE)))
385 /* ( ptr + constant ) */
386 if (IS_AST_OP (expr) &&
387 (expr->opval.op == '+' || expr->opval.op == '-') &&
388 IS_AST_SYM_VALUE (expr->left) &&
389 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
390 compareType(toType, expr->left->ftype) &&
391 IS_AST_LIT_VALUE (expr->right)) {
392 return valForCastAggr (expr->left, expr->left->ftype,
398 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
399 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
400 if (compareType(toType, expr->left->ftype)!=1) {
401 werror (W_INIT_WRONG);
402 printFromToType(expr->left->ftype, toType);
408 /* no then we have to do these cludgy checks */
409 /* pointers can be initialized with address of
410 a variable or address of an array element */
411 if (IS_AST_OP (expr) && expr->opval.op == '&') {
412 /* address of symbol */
413 if (IS_AST_SYM_VALUE (expr->left)) {
414 val = copyValue (AST_VALUE (expr->left));
415 val->type = newLink (DECLARATOR);
416 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
417 DCL_TYPE (val->type) = CPOINTER;
418 DCL_PTR_CONST (val->type) = port->mem.code_ro;
420 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
421 DCL_TYPE (val->type) = FPOINTER;
422 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
423 DCL_TYPE (val->type) = PPOINTER;
424 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
425 DCL_TYPE (val->type) = IPOINTER;
426 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
427 DCL_TYPE (val->type) = EEPPOINTER;
429 DCL_TYPE (val->type) = POINTER;
430 val->type->next = expr->left->ftype;
431 val->etype = getSpec (val->type);
435 /* if address of indexed array */
436 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
437 return valForArray (expr->left);
439 /* if address of structure element then
441 if (IS_AST_OP (expr->left) &&
442 expr->left->opval.op == '.') {
443 return valForStructElem (expr->left->left,
448 (&some_struct)->element */
449 if (IS_AST_OP (expr->left) &&
450 expr->left->opval.op == PTR_OP &&
451 IS_ADDRESS_OF_OP (expr->left->left)) {
452 return valForStructElem (expr->left->left->left,
456 /* case 3. (((char *) &a) +/- constant) */
457 if (IS_AST_OP (expr) &&
458 (expr->opval.op == '+' || expr->opval.op == '-') &&
459 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
460 IS_AST_OP (expr->left->right) &&
461 expr->left->right->opval.op == '&' &&
462 IS_AST_LIT_VALUE (expr->right)) {
464 return valForCastAggr (expr->left->right->left,
465 expr->left->left->opval.lnk,
466 expr->right, expr->opval.op);
469 /* case 4. (char *)(array type) */
470 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
471 IS_ARRAY(expr->right->ftype)) {
473 val = copyValue (AST_VALUE (expr->right));
474 val->type = newLink (DECLARATOR);
475 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
476 DCL_TYPE (val->type) = CPOINTER;
477 DCL_PTR_CONST (val->type) = port->mem.code_ro;
479 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
480 DCL_TYPE (val->type) = FPOINTER;
481 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
482 DCL_TYPE (val->type) = PPOINTER;
483 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
484 DCL_TYPE (val->type) = IPOINTER;
485 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
486 DCL_TYPE (val->type) = EEPPOINTER;
488 DCL_TYPE (val->type) = POINTER;
489 val->type->next = expr->right->ftype->next;
490 val->etype = getSpec (val->type);
494 werror (E_INCOMPAT_PTYPES);
499 /*-----------------------------------------------------------------*/
500 /* printChar - formats and prints a characater string with DB */
501 /*-----------------------------------------------------------------*/
503 printChar (FILE * ofile, char *s, int plen)
506 int len = strlen (s);
511 while (len && pplen < plen)
514 while (i && *s && pplen < plen)
516 if (*s < ' ' || *s == '\"' || *s=='\\')
520 tfprintf (ofile, "\t!ascii\n", buf);
521 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
536 tfprintf (ofile, "\t!ascii\n", buf);
545 tfprintf (ofile, "\t!db !constbyte\n", 0);
548 /*-----------------------------------------------------------------*/
549 /* return the generic pointer high byte for a given pointer type. */
550 /*-----------------------------------------------------------------*/
552 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
560 werror (E_CANNOT_USE_GENERIC_POINTER,
561 iname ? iname : "<null>",
562 oname ? oname : "<null>");
569 return GPTYPE_XSTACK;
571 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
579 /*-----------------------------------------------------------------*/
580 /* printPointerType - generates ival for pointer type */
581 /*-----------------------------------------------------------------*/
583 _printPointerType (FILE * oFile, const char *name)
585 if (options.model == MODEL_FLAT24)
587 if (port->little_endian)
588 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
590 fprintf (oFile, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
594 if (port->little_endian)
595 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
597 fprintf (oFile, "\t.byte (%s >> 8),%s", name, name);
601 /*-----------------------------------------------------------------*/
602 /* printPointerType - generates ival for pointer type */
603 /*-----------------------------------------------------------------*/
605 printPointerType (FILE * oFile, const char *name)
607 _printPointerType (oFile, name);
608 fprintf (oFile, "\n");
611 /*-----------------------------------------------------------------*/
612 /* printGPointerType - generates ival for generic pointer type */
613 /*-----------------------------------------------------------------*/
615 printGPointerType (FILE * oFile, const char *iname, const char *oname,
616 const unsigned int type)
618 _printPointerType (oFile, iname);
619 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
622 /*-----------------------------------------------------------------*/
623 /* printIvalType - generates ival for int/char */
624 /*-----------------------------------------------------------------*/
626 printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
630 /* if initList is deep */
631 if (ilist->type == INIT_DEEP)
632 ilist = ilist->init.deep;
634 if (!(val = list2val (ilist))) {
635 // assuming a warning has been thrown
639 if (val->type != type) {
640 val = valCastLiteral(type, floatFromVal(val));
643 switch (getSize (type)) {
646 tfprintf (oFile, "\t!db !constbyte\n", 0);
648 tfprintf (oFile, "\t!dbs\n",
649 aopLiteral (val, 0));
653 if (port->use_dw_for_init)
654 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
655 else if (port->little_endian)
656 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
658 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
662 tfprintf (oFile, "\t!dw !constword\n", 0);
663 tfprintf (oFile, "\t!dw !constword\n", 0);
665 else if (port->little_endian) {
666 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
667 aopLiteral (val, 0), aopLiteral (val, 1),
668 aopLiteral (val, 2), aopLiteral (val, 3));
671 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
672 aopLiteral (val, 3), aopLiteral (val, 2),
673 aopLiteral (val, 1), aopLiteral (val, 0));
679 /*-----------------------------------------------------------------*/
680 /* printIvalBitFields - generate initializer for bitfields */
681 /*-----------------------------------------------------------------*/
682 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
686 initList *lilist = *ilist ;
687 unsigned long ival = 0;
693 val = list2val(lilist);
695 if (SPEC_BLEN(lsym->etype) > 8) {
696 size += ((SPEC_BLEN (lsym->etype) / 8) +
697 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
700 size = ((SPEC_BLEN (lsym->etype) / 8) +
701 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
703 i = (unsigned long)floatFromVal(val);
704 i <<= SPEC_BSTR (lsym->etype);
706 if (! ( lsym->next &&
707 (IS_BITFIELD(lsym->next->type)) &&
708 (SPEC_BSTR(lsym->next->etype)))) break;
710 lilist = lilist->next;
714 tfprintf (oFile, "\t!db !constbyte\n",ival);
718 tfprintf (oFile, "\t!dw !constword\n",ival);
720 case 4: /* EEP: why is this db and not dw? */
721 tfprintf (oFile, "\t!db !constword,!constword\n",
722 (ival >> 8) & 0xffff, (ival & 0xffff));
729 /*-----------------------------------------------------------------*/
730 /* printIvalStruct - generates initial value for structures */
731 /*-----------------------------------------------------------------*/
733 printIvalStruct (symbol * sym, sym_link * type,
734 initList * ilist, FILE * oFile)
739 sflds = SPEC_STRUCT (type)->fields;
740 if (ilist->type != INIT_DEEP) {
741 werror (E_INIT_STRUCT, sym->name);
745 iloop = ilist->init.deep;
747 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
748 if (IS_BITFIELD(sflds->type)) {
749 printIvalBitFields(&sflds,&iloop,oFile);
751 printIval (sym, sflds->type, iloop, oFile);
755 werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
760 /*-----------------------------------------------------------------*/
761 /* printIvalChar - generates initital value for character array */
762 /*-----------------------------------------------------------------*/
764 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
772 val = list2val (ilist);
773 /* if the value is a character string */
774 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
776 if (!DCL_ELEM (type))
777 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
779 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
781 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
783 tfprintf (oFile, "\t!db !constbyte\n", 0);
791 printChar (oFile, s, strlen (s) + 1);
795 /*-----------------------------------------------------------------*/
796 /* printIvalArray - generates code for array initialization */
797 /*-----------------------------------------------------------------*/
799 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
805 /* take care of the special case */
806 /* array of characters can be init */
808 if (IS_CHAR (type->next)) {
809 if (!IS_LITERAL(list2val(ilist)->etype)) {
810 werror (E_CONST_EXPECTED);
813 if (printIvalChar (type,
814 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
815 oFile, SPEC_CVAL (sym->etype).v_char))
818 /* not the special case */
819 if (ilist->type != INIT_DEEP)
821 werror (E_INIT_STRUCT, sym->name);
825 for (iloop=ilist->init.deep; iloop; iloop=iloop->next)
827 printIval (sym, type->next, iloop, oFile);
829 if (++size > DCL_ELEM(type)) {
830 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
835 if (DCL_ELEM(type)) {
836 // pad with zeros if needed
837 if (size<DCL_ELEM(type)) {
838 size = (DCL_ELEM(type) - size) * getSize(type->next);
840 tfprintf (oFile, "\t!db !constbyte\n", 0);
844 // we have not been given a size, but we now know it
845 DCL_ELEM (type) = size;
851 /*-----------------------------------------------------------------*/
852 /* printIvalFuncPtr - generate initial value for function pointers */
853 /*-----------------------------------------------------------------*/
855 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
860 val = list2val (ilist);
863 // an error has been thrown allready
867 if (IS_LITERAL(val->etype)) {
868 if (compareType(type,val->etype)==0) {
869 werror (E_INCOMPAT_TYPES);
870 printFromToType (val->type, type);
872 printIvalCharPtr (NULL, type, val, oFile);
876 /* check the types */
877 if ((dLvl = compareType (val->type, type->next)) <= 0)
879 tfprintf (oFile, "\t!dw !constword\n", 0);
883 /* now generate the name */
886 if (port->use_dw_for_init)
888 tfprintf (oFile, "\t!dws\n", val->name);
892 printPointerType (oFile, val->name);
895 else if (port->use_dw_for_init)
897 tfprintf (oFile, "\t!dws\n", val->sym->rname);
901 printPointerType (oFile, val->sym->rname);
907 /*-----------------------------------------------------------------*/
908 /* printIvalCharPtr - generates initial values for character pointers */
909 /*-----------------------------------------------------------------*/
911 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
915 /* PENDING: this is _very_ mcs51 specific, including a magic
917 It's also endin specific.
919 size = getSize (type);
921 if (val->name && strlen (val->name))
923 if (size == 1) /* This appears to be Z80 specific?? */
926 "\t!dbs\n", val->name);
928 else if (size == FPTRSIZE)
930 if (port->use_dw_for_init)
932 tfprintf (oFile, "\t!dws\n", val->name);
936 printPointerType (oFile, val->name);
939 else if (size == GPTRSIZE)
942 if (IS_PTR (val->type)) {
943 type = DCL_TYPE (val->type);
945 type = PTR_TYPE (SPEC_OCLS (val->etype));
947 if (val->sym && val->sym->isstrlit) {
948 // this is a literal string
951 printGPointerType (oFile, val->name, sym->name, type);
955 fprintf (stderr, "*** internal error: unknown size in "
956 "printIvalCharPtr.\n");
961 // these are literals assigned to pointers
965 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
968 if (port->use_dw_for_init)
969 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
970 else if (port->little_endian)
971 tfprintf (oFile, "\t.byte %s,%s\n",
972 aopLiteral (val, 0), aopLiteral (val, 1));
974 tfprintf (oFile, "\t.byte %s,%s\n",
975 aopLiteral (val, 1), aopLiteral (val, 0));
978 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
979 // non-zero mcs51 generic pointer
980 werror (E_LITERAL_GENERIC);
982 if (port->little_endian) {
983 fprintf (oFile, "\t.byte %s,%s,%s\n",
986 aopLiteral (val, 2));
988 fprintf (oFile, "\t.byte %s,%s,%s\n",
991 aopLiteral (val, 0));
995 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
996 // non-zero ds390 generic pointer
997 werror (E_LITERAL_GENERIC);
999 if (port->little_endian) {
1000 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
1001 aopLiteral (val, 0),
1002 aopLiteral (val, 1),
1003 aopLiteral (val, 2),
1004 aopLiteral (val, 3));
1006 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
1007 aopLiteral (val, 3),
1008 aopLiteral (val, 2),
1009 aopLiteral (val, 1),
1010 aopLiteral (val, 0));
1018 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1019 addSet (&statsg->syms, val->sym);
1025 /*-----------------------------------------------------------------*/
1026 /* printIvalPtr - generates initial value for pointers */
1027 /*-----------------------------------------------------------------*/
1029 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1035 if (ilist->type == INIT_DEEP)
1036 ilist = ilist->init.deep;
1038 /* function pointer */
1039 if (IS_FUNC (type->next))
1041 printIvalFuncPtr (type, ilist, oFile);
1045 if (!(val = initPointer (ilist, type)))
1048 /* if character pointer */
1049 if (IS_CHAR (type->next))
1050 if (printIvalCharPtr (sym, type, val, oFile))
1053 /* check the type */
1054 if (compareType (type, val->type) == 0) {
1055 werror (W_INIT_WRONG);
1056 printFromToType (val->type, type);
1059 /* if val is literal */
1060 if (IS_LITERAL (val->etype))
1062 switch (getSize (type))
1065 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
1068 if (port->use_dw_for_init)
1069 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
1070 else if (port->little_endian)
1071 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1073 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1075 case 3: // how about '390??
1076 if (port->little_endian)
1078 fprintf (oFile, "\t.byte %s,%s,#0x%d\n",
1079 aopLiteral (val, 0), aopLiteral (val, 1), GPTYPE_CODE);
1083 fprintf (oFile, "\t.byte %s,%s,#0x%d\n",
1084 aopLiteral (val, 1), aopLiteral (val, 0), GPTYPE_CODE);
1091 size = getSize (type);
1093 if (size == 1) /* Z80 specific?? */
1095 tfprintf (oFile, "\t!dbs\n", val->name);
1097 else if (size == FPTRSIZE)
1099 if (port->use_dw_for_init) {
1100 tfprintf (oFile, "\t!dws\n", val->name);
1102 printPointerType (oFile, val->name);
1105 else if (size == GPTRSIZE)
1107 printGPointerType (oFile, val->name, sym->name,
1108 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1109 PTR_TYPE (SPEC_OCLS (val->etype))));
1114 /*-----------------------------------------------------------------*/
1115 /* printIval - generates code for initial value */
1116 /*-----------------------------------------------------------------*/
1118 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1125 /* update line number for error msgs */
1126 lineno=sym->lineDef;
1128 /* if structure then */
1129 if (IS_STRUCT (type))
1131 printIvalStruct (sym, type, ilist, oFile);
1135 /* if this is an array */
1136 if (IS_ARRAY (type))
1138 printIvalArray (sym, type, ilist, oFile);
1142 // not an aggregate, ilist must be a node
1143 if (ilist->type!=INIT_NODE) {
1144 // or a 1-element list
1145 if (ilist->init.deep->next) {
1146 werror (W_EXCESS_INITIALIZERS, "scalar",
1147 sym->name, sym->lineDef);
1149 ilist=ilist->init.deep;
1153 // and the type must match
1154 itype=ilist->init.node->ftype;
1156 if (compareType(type, itype)==0) {
1157 // special case for literal strings
1158 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1159 // which are really code pointers
1160 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1163 werror (E_TYPE_MISMATCH, "assignment", " ");
1164 printFromToType(itype, type);
1168 /* if this is a pointer */
1171 printIvalPtr (sym, type, ilist, oFile);
1175 /* if type is SPECIFIER */
1178 printIvalType (sym, type, ilist, oFile);
1183 /*-----------------------------------------------------------------*/
1184 /* emitStaticSeg - emitcode for the static segment */
1185 /*-----------------------------------------------------------------*/
1187 emitStaticSeg (memmap * map, FILE * out)
1191 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1193 /* for all variables in this segment do */
1194 for (sym = setFirstItem (map->syms); sym;
1195 sym = setNextItem (map->syms))
1198 /* if it is "extern" then do nothing */
1199 if (IS_EXTERN (sym->etype))
1202 /* if it is not static add it to the public
1204 if (!IS_STATIC (sym->etype))
1206 addSetHead (&publics, sym);
1209 /* print extra debug info if required */
1210 if (options.debug) {
1214 if (IS_STATIC (sym->etype))
1215 fprintf (out, "F%s$", moduleName); /* scope is file */
1217 fprintf (out, "G$"); /* scope is global */
1220 /* symbol is local */
1221 fprintf (out, "L%s$",
1222 (sym->localof ? sym->localof->name : "-null-"));
1223 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
1226 /* if it has an absolute address */
1227 if (SPEC_ABSA (sym->etype))
1230 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1232 fprintf (out, "%s\t=\t0x%04x\n",
1234 SPEC_ADDR (sym->etype));
1239 fprintf (out, " == .\n");
1241 /* if it has an initial value */
1244 fprintf (out, "%s:\n", sym->rname);
1246 resolveIvalSym (sym->ival);
1247 printIval (sym, sym->type, sym->ival, out);
1249 /* if sym is a simple string and sym->ival is a string,
1250 WE don't need it anymore */
1251 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1252 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1253 list2val(sym->ival)->sym->isstrlit) {
1254 freeStringSymbol(list2val(sym->ival)->sym);
1258 /* allocate space */
1259 int size = getSize (sym->type);
1262 werror(E_UNKNOWN_SIZE,sym->name);
1264 fprintf (out, "%s:\n", sym->rname);
1265 /* special case for character strings */
1266 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1267 SPEC_CVAL (sym->etype).v_char)
1269 SPEC_CVAL (sym->etype).v_char,
1270 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1272 tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff);
1278 /*-----------------------------------------------------------------*/
1279 /* emitMaps - emits the code for the data portion the code */
1280 /*-----------------------------------------------------------------*/
1285 /* no special considerations for the following
1286 data, idata & bit & xdata */
1287 emitRegularMap (data, TRUE, TRUE);
1288 emitRegularMap (idata, TRUE, TRUE);
1289 emitRegularMap (bit, TRUE, FALSE);
1290 emitRegularMap (xdata, TRUE, TRUE);
1291 if (port->genXINIT) {
1292 emitRegularMap (xidata, TRUE, TRUE);
1294 emitRegularMap (sfr, FALSE, FALSE);
1295 emitRegularMap (sfrbit, FALSE, FALSE);
1296 emitRegularMap (home, TRUE, FALSE);
1297 emitRegularMap (code, TRUE, FALSE);
1299 emitStaticSeg (statsg, code->oFile);
1300 if (port->genXINIT) {
1301 tfprintf (code->oFile, "\t!area\n", xinit->sname);
1302 emitStaticSeg (xinit, code->oFile);
1307 /*-----------------------------------------------------------------*/
1308 /* flushStatics - flush all currently defined statics out to file */
1309 /* and delete. Temporary function */
1310 /*-----------------------------------------------------------------*/
1314 emitStaticSeg (statsg, codeOutFile);
1315 statsg->syms = NULL;
1318 /*-----------------------------------------------------------------*/
1319 /* createInterruptVect - creates the interrupt vector */
1320 /*-----------------------------------------------------------------*/
1322 createInterruptVect (FILE * vFile)
1325 mainf = newSymbol ("main", 0);
1328 /* only if the main function exists */
1329 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1331 if (!options.cc_only && !noAssemble && !options.c1mode)
1336 /* if the main is only a prototype ie. no body then do nothing */
1337 if (!IFFUNC_HASBODY(mainf->type))
1339 /* if ! compile only then main function should be present */
1340 if (!options.cc_only && !noAssemble)
1345 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1346 fprintf (vFile, "__interrupt_vect:\n");
1349 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1351 /* "generic" interrupt table header (if port doesn't specify one).
1352 * Look suspiciously like 8051 code to me...
1355 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1358 /* now for the other interrupts */
1359 for (; i < maxInterrupts; i++)
1362 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1364 fprintf (vFile, "\treti\n\t.ds\t7\n");
1371 ";--------------------------------------------------------\n"
1372 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1376 ";--------------------------------------------------------\n"};
1379 /*-----------------------------------------------------------------*/
1380 /* initialComments - puts in some initial comments */
1381 /*-----------------------------------------------------------------*/
1383 initialComments (FILE * afile)
1387 fprintf (afile, "%s", iComments1);
1388 fprintf (afile, "; Version " SDCC_VERSION_STR " %s\n", asctime (localtime (&t)));
1389 fprintf (afile, "%s", iComments2);
1392 /*-----------------------------------------------------------------*/
1393 /* printPublics - generates .global for publics */
1394 /*-----------------------------------------------------------------*/
1396 printPublics (FILE * afile)
1400 fprintf (afile, "%s", iComments2);
1401 fprintf (afile, "; Public variables in this module\n");
1402 fprintf (afile, "%s", iComments2);
1404 for (sym = setFirstItem (publics); sym;
1405 sym = setNextItem (publics))
1406 tfprintf (afile, "\t!global\n", sym->rname);
1409 /*-----------------------------------------------------------------*/
1410 /* printExterns - generates .global for externs */
1411 /*-----------------------------------------------------------------*/
1413 printExterns (FILE * afile)
1417 fprintf (afile, "%s", iComments2);
1418 fprintf (afile, "; Externals used\n");
1419 fprintf (afile, "%s", iComments2);
1421 for (sym = setFirstItem (externs); sym;
1422 sym = setNextItem (externs))
1423 tfprintf (afile, "\t!extern\n", sym->rname);
1426 /*-----------------------------------------------------------------*/
1427 /* emitOverlay - will emit code for the overlay stuff */
1428 /*-----------------------------------------------------------------*/
1430 emitOverlay (FILE * afile)
1434 if (!elementsInSet (ovrSetSets))
1435 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1437 /* for each of the sets in the overlay segment do */
1438 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1439 ovrset = setNextItem (ovrSetSets))
1444 if (elementsInSet (ovrset))
1446 /* output the area informtion */
1447 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1450 for (sym = setFirstItem (ovrset); sym;
1451 sym = setNextItem (ovrset))
1453 /* if extern then it is in the publics table: do nothing */
1454 if (IS_EXTERN (sym->etype))
1457 /* if allocation required check is needed
1458 then check if the symbol really requires
1459 allocation only for local variables */
1460 if (!IS_AGGREGATE (sym->type) &&
1461 !(sym->_isparm && !IS_REGPARM (sym->etype))
1462 && !sym->allocreq && sym->level)
1465 /* if global variable & not static or extern
1466 and addPublics allowed then add it to the public set */
1467 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1468 && !IS_STATIC (sym->etype))
1470 addSetHead (&publics, sym);
1473 /* if extern then do nothing or is a function
1475 if (IS_FUNC (sym->type))
1478 /* print extra debug info if required */
1483 if (IS_STATIC (sym->etype))
1484 fprintf (afile, "F%s$", moduleName); /* scope is file */
1486 fprintf (afile, "G$"); /* scope is global */
1489 /* symbol is local */
1490 fprintf (afile, "L%s$",
1491 (sym->localof ? sym->localof->name : "-null-"));
1492 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1495 /* if is has an absolute address then generate
1496 an equate for this no need to allocate space */
1497 if (SPEC_ABSA (sym->etype))
1501 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1503 fprintf (afile, "%s\t=\t0x%04x\n",
1505 SPEC_ADDR (sym->etype));
1508 int size = getSize(sym->type);
1511 werror(E_UNKNOWN_SIZE,sym->name);
1514 fprintf (afile, "==.\n");
1516 /* allocate space */
1517 tfprintf (afile, "!labeldef\n", sym->rname);
1518 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1526 /*-----------------------------------------------------------------*/
1527 /* spacesToUnderscores - replace spaces with underscores */
1528 /*-----------------------------------------------------------------*/
1530 spacesToUnderscores (char *dest, const char *src, size_t len)
1535 assert(dest != NULL);
1536 assert(src != NULL);
1540 for (p = dest, i = 0; *src != '\0' && i < len; ++src, ++i) {
1541 *p++ = isspace(*src) ? '_' : *src;
1549 /*-----------------------------------------------------------------*/
1550 /* glue - the final glue that hold the whole thing together */
1551 /*-----------------------------------------------------------------*/
1557 FILE *ovrFile = tempfile ();
1558 char moduleBuf[PATH_MAX];
1561 if(port->general.glue_up_main &&
1562 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400))
1564 mcs51_like=1; /*So it has bits, sfr, sbits, data, idata, etc...*/
1571 addSetHead (&tmpfileSet, ovrFile);
1572 /* print the global struct definitions */
1576 vFile = tempfile ();
1577 /* PENDING: this isnt the best place but it will do */
1578 if (port->general.glue_up_main)
1580 /* create the interrupt vector table */
1581 createInterruptVect (vFile);
1584 addSetHead (&tmpfileSet, vFile);
1586 /* emit code for the all the variables declared */
1588 /* do the overlay segments */
1589 emitOverlay (ovrFile);
1591 outputDebugSymbols();
1593 /* now put it all together into the assembler file */
1594 /* create the assembler file name */
1596 /* -o option overrides default name? */
1597 if ((noAssemble || options.c1mode) && fullDstFileName)
1599 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1603 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1604 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1607 if (!(asmFile = fopen (scratchFileName, "w")))
1609 werror (E_FILE_OPEN_ERR, scratchFileName);
1613 /* initial comments */
1614 initialComments (asmFile);
1616 /* print module name */
1617 tfprintf (asmFile, "\t!module\n",
1618 spacesToUnderscores (moduleBuf, moduleName, sizeof moduleBuf));
1621 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1623 switch(options.model)
1625 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1626 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1627 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1628 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1629 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1630 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1633 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1634 if(options.useXstack) fprintf (asmFile, " --xstack");
1635 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1636 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1637 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1638 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1639 fprintf (asmFile, "\n");
1641 else if(TARGET_IS_Z80 || TARGET_IS_GBZ80 )
1643 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1646 tfprintf (asmFile, "\t!fileprelude\n");
1648 /* Let the port generate any global directives, etc. */
1649 if (port->genAssemblerPreamble)
1651 port->genAssemblerPreamble (asmFile);
1654 /* print the global variables in this module */
1655 printPublics (asmFile);
1656 if (port->assembler.externGlobal)
1657 printExterns (asmFile);
1661 /* copy the sfr segment */
1662 fprintf (asmFile, "%s", iComments2);
1663 fprintf (asmFile, "; special function registers\n");
1664 fprintf (asmFile, "%s", iComments2);
1665 copyFile (asmFile, sfr->oFile);
1667 /* copy the sbit segment */
1668 fprintf (asmFile, "%s", iComments2);
1669 fprintf (asmFile, "; special function bits \n");
1670 fprintf (asmFile, "%s", iComments2);
1671 copyFile (asmFile, sfrbit->oFile);
1673 /*JCF: Create the areas for the register banks*/
1674 if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3])
1676 fprintf (asmFile, "%s", iComments2);
1677 fprintf (asmFile, "; overlayable register banks \n");
1678 fprintf (asmFile, "%s", iComments2);
1680 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1681 if(RegBankUsed[1]||options.parms_in_bank1)
1682 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1684 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1686 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1690 /* copy the data segment */
1691 fprintf (asmFile, "%s", iComments2);
1692 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1693 fprintf (asmFile, "%s", iComments2);
1694 copyFile (asmFile, data->oFile);
1697 /* create the overlay segments */
1699 fprintf (asmFile, "%s", iComments2);
1700 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1701 fprintf (asmFile, "%s", iComments2);
1702 copyFile (asmFile, ovrFile);
1705 /* create the stack segment MOF */
1706 if (mainf && IFFUNC_HASBODY(mainf->type))
1708 fprintf (asmFile, "%s", iComments2);
1709 fprintf (asmFile, "; Stack segment in internal ram \n");
1710 fprintf (asmFile, "%s", iComments2);
1711 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1712 "__start__stack:\n\t.ds\t1\n\n");
1715 /* create the idata segment */
1716 if ( (idata) && (mcs51_like) ) {
1717 fprintf (asmFile, "%s", iComments2);
1718 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1719 fprintf (asmFile, "%s", iComments2);
1720 copyFile (asmFile, idata->oFile);
1723 /* copy the bit segment */
1725 fprintf (asmFile, "%s", iComments2);
1726 fprintf (asmFile, "; bit data\n");
1727 fprintf (asmFile, "%s", iComments2);
1728 copyFile (asmFile, bit->oFile);
1731 /* if external stack then reserve space of it */
1732 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1734 fprintf (asmFile, "%s", iComments2);
1735 fprintf (asmFile, "; external stack \n");
1736 fprintf (asmFile, "%s", iComments2);
1737 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1738 fprintf (asmFile, "\t.ds 256\n");
1742 /* copy xtern ram data */
1744 fprintf (asmFile, "%s", iComments2);
1745 fprintf (asmFile, "; external ram data\n");
1746 fprintf (asmFile, "%s", iComments2);
1747 copyFile (asmFile, xdata->oFile);
1750 /* copy xternal initialized ram data */
1751 fprintf (asmFile, "%s", iComments2);
1752 fprintf (asmFile, "; external initialized ram data\n");
1753 fprintf (asmFile, "%s", iComments2);
1754 copyFile (asmFile, xidata->oFile);
1756 /* If the port wants to generate any extra areas, let it do so. */
1757 if (port->extraAreas.genExtraAreaDeclaration)
1759 port->extraAreas.genExtraAreaDeclaration(asmFile,
1760 mainf && IFFUNC_HASBODY(mainf->type));
1763 /* copy the interrupt vector table */
1764 if (mainf && IFFUNC_HASBODY(mainf->type))
1766 fprintf (asmFile, "%s", iComments2);
1767 fprintf (asmFile, "; interrupt vector \n");
1768 fprintf (asmFile, "%s", iComments2);
1769 copyFile (asmFile, vFile);
1772 /* copy global & static initialisations */
1773 fprintf (asmFile, "%s", iComments2);
1774 fprintf (asmFile, "; global & static initialisations\n");
1775 fprintf (asmFile, "%s", iComments2);
1777 /* Everywhere we generate a reference to the static_name area,
1778 * (which is currently only here), we immediately follow it with a
1779 * definition of the post_static_name area. This guarantees that
1780 * the post_static_name area will immediately follow the static_name
1783 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1784 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1785 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1787 if (mainf && IFFUNC_HASBODY(mainf->type))
1789 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1790 /* if external stack is specified then the
1791 higher order byte of the xdatalocation is
1792 going into P2 and the lower order going into
1794 if (options.useXstack)
1796 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1797 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1798 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1799 (unsigned int) options.xdata_loc & 0xff);
1802 // This should probably be a port option, but I'm being lazy.
1803 // on the 400, the firmware boot loader gives us a valid stack
1804 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1805 if (!TARGET_IS_DS400)
1807 /* initialise the stack pointer. JCF: aslink takes care of the location */
1808 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1811 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1812 fprintf (asmFile, "\tmov\ta,dpl\n");
1813 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1814 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1815 fprintf (asmFile, "__sdcc_init_data:\n");
1817 // if the port can copy the XINIT segment to XISEG
1818 if (port->genXINIT) {
1819 port->genXINIT(asmFile);
1823 copyFile (asmFile, statsg->oFile);
1825 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1827 /* This code is generated in the post-static area.
1828 * This area is guaranteed to follow the static area
1829 * by the ugly shucking and jiving about 20 lines ago.
1831 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1832 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1838 "%s", iComments2, iComments2);
1839 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1840 copyFile (asmFile, home->oFile);
1842 /* copy over code */
1843 fprintf (asmFile, "%s", iComments2);
1844 fprintf (asmFile, "; code\n");
1845 fprintf (asmFile, "%s", iComments2);
1846 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1847 if (mainf && IFFUNC_HASBODY(mainf->type))
1850 /* entry point @ start of CSEG */
1851 fprintf (asmFile, "__sdcc_program_startup:\n");
1853 /* put in the call to main */
1854 fprintf (asmFile, "\tlcall\t_main\n");
1855 if (options.mainreturn)
1858 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1859 fprintf (asmFile, "\tret\n");
1865 fprintf (asmFile, ";\treturn from main will lock up\n");
1866 fprintf (asmFile, "\tsjmp .\n");
1869 copyFile (asmFile, code->oFile);
1871 if (port->genAssemblerEnd) {
1872 port->genAssemblerEnd(asmFile);
1880 /** Creates a temporary file with unoque file name
1882 - TMP, TEMP, TMPDIR env. varibles
1883 - if Un*x system: /usr/tmp and /tmp
1884 - root directory using mkstemp() if avaliable
1885 - default location using tempnam()
1888 tempfileandname(char *fname, size_t len)
1890 #define TEMPLATE "sdccXXXXXX"
1891 #define TEMPLATE_LEN ((sizeof TEMPLATE) - 1)
1893 const char *tmpdir = NULL;
1896 if ((tmpdir = getenv ("TMP")) == NULL)
1897 if ((tmpdir = getenv ("TEMP")) == NULL)
1898 tmpdir = getenv ("TMPDIR");
1902 static int warning_emitted;
1907 if (!warning_emitted)
1909 fprintf (stderr, "TMP not defined in environment, using %s for temporary files\n.", tmpdir);
1910 warning_emitted = 1;
1916 /* try with /usr/tmp and /tmp on Un*x systems */
1917 struct stat statbuf;
1919 if (tmpdir == NULL) {
1920 if (stat("/usr/tmp", &statbuf) != -1)
1921 tmpdir = "/usr/tmp";
1922 else if (stat("/tmp", &statbuf) != -1)
1930 char fnamebuf[PATH_MAX];
1933 if (fname == NULL || len == 0) {
1935 len = sizeof fnamebuf;
1939 name_len = strlen(tmpdir) + 1 + TEMPLATE_LEN;
1941 assert(name_len < len);
1942 if (!(name_len < len)) /* in NDEBUG is defined */
1943 return -1; /* buffer too small, temporary file can not be created */
1945 sprintf(fname, "%s" DIR_SEPARATOR_STRING TEMPLATE, tmpdir);
1948 name_len = TEMPLATE_LEN;
1950 assert(name_len < len);
1951 if (!(name_len < len)) /* in NDEBUG is defined */
1952 return -1; /* buffer too small, temporary file can not be created */
1954 strcpy(fname, TEMPLATE);
1957 fd = mkstemp(fname);
1961 char *name = tempnam(tmpdir, "sdcc");
1964 perror("Can't create temporary file name");
1968 assert(strlen(name) < len);
1969 if (!(strlen(name) < len)) /* in NDEBUG is defined */
1970 return -1; /* buffer too small, temporary file can not be created */
1972 strcpy(fname, name);
1974 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE);
1976 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
1982 perror("Can't create temporary file");
1990 /** Create a temporary file name
1996 static char fnamebuf[PATH_MAX];
1998 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
1999 fprintf(stderr, "Can't create temporary file name!");
2010 /** Create a temporary file and add it to tmpfileNameSet,
2011 so that it is removed explicitly by rm_tmpfiles()
2012 or implicitly at program extit.
2020 char fnamebuf[PATH_MAX];
2022 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
2023 fprintf(stderr, "Can't create temporary file!");
2027 tmp = Safe_strdup(fnamebuf);
2029 addSetHead(&tmpfileNameSet, tmp);
2031 if ((fp = fdopen(fd, "w+b")) == NULL) {
2032 perror("Can't create temporary file!");