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; /* Variables that are declared as extern */
44 unsigned maxInterrupts = 0;
47 set *pipeSet = NULL; /* set of pipes */
48 set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
49 set *tmpfileNameSet = NULL; /* All are unlinked at close. */
51 /*-----------------------------------------------------------------*/
52 /* closePipes - closes all pipes created by the compiler */
53 /*-----------------------------------------------------------------*/
54 DEFSETFUNC (closePipes)
67 /*-----------------------------------------------------------------*/
68 /* closeTmpFiles - closes all tmp files created by the compiler */
69 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
70 /*-----------------------------------------------------------------*/
71 DEFSETFUNC (closeTmpFiles)
84 /*-----------------------------------------------------------------*/
85 /* rmTmpFiles - unlinks all tmp files created by the compiler */
86 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
87 /*-----------------------------------------------------------------*/
88 DEFSETFUNC (rmTmpFiles)
102 /*-----------------------------------------------------------------*/
103 /* rm_tmpfiles - close and remove temporary files and delete sets */
104 /*-----------------------------------------------------------------*/
108 /* close temporary files */
109 applyToSet (pipeSet, closePipes);
110 /* close temporary files */
111 deleteSet (&pipeSet);
113 applyToSet (tmpfileSet, closeTmpFiles);
114 /* remove temporary files */
115 applyToSet (tmpfileNameSet, rmTmpFiles);
116 /* delete temorary file sets */
117 deleteSet (&tmpfileSet);
118 deleteSet (&tmpfileNameSet);
121 /*-----------------------------------------------------------------*/
122 /* copyFile - copies source file to destination file */
123 /*-----------------------------------------------------------------*/
125 copyFile (FILE * dest, FILE * src)
131 if ((ch = fgetc (src)) != EOF)
136 aopLiteralLong (value * val, int offset, int size)
145 // assuming we have been warned before
149 /* if it is a float then it gets tricky */
150 /* otherwise it is fairly simple */
151 if (!IS_FLOAT (val->type)) {
152 unsigned long v = (unsigned long) floatFromVal (val);
157 tsprintf (buffer, sizeof(buffer),
158 "!immedbyte", (unsigned int) v & 0xff);
161 tsprintf (buffer, sizeof(buffer),
162 "!immedword", (unsigned int) v & 0xffff);
165 /* Hmm. Too big for now. */
168 return Safe_strdup (buffer);
171 /* PENDING: For now size must be 1 */
174 /* it is type float */
175 fl.f = (float) floatFromVal (val);
176 #ifdef WORDS_BIGENDIAN
177 tsprintf (buffer, sizeof(buffer),
178 "!immedbyte", fl.c[3 - offset]);
180 tsprintf (buffer, sizeof(buffer),
181 "!immedbyte", fl.c[offset]);
183 return Safe_strdup (buffer);
186 /*-----------------------------------------------------------------*/
187 /* aopLiteral - string from a literal value */
188 /*-----------------------------------------------------------------*/
190 aopLiteral (value * val, int offset)
192 return aopLiteralLong (val, offset, 1);
195 /*-----------------------------------------------------------------*/
196 /* emitRegularMap - emit code for maps with no special cases */
197 /*-----------------------------------------------------------------*/
199 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
209 /* PENDING: special case here - should remove */
210 if (!strcmp (map->sname, CODE_NAME))
211 tfprintf (map->oFile, "\t!areacode\n", map->sname);
212 else if (!strcmp (map->sname, DATA_NAME))
213 tfprintf (map->oFile, "\t!areadata\n", map->sname);
214 else if (!strcmp (map->sname, HOME_NAME))
215 tfprintf (map->oFile, "\t!areahome\n", map->sname);
217 tfprintf (map->oFile, "\t!area\n", map->sname);
220 for (sym = setFirstItem (map->syms); sym;
221 sym = setNextItem (map->syms))
225 /* if extern then add it into the extern list */
226 if (IS_EXTERN (sym->etype))
228 addSetHead (&externs, sym);
232 /* if allocation required check is needed
233 then check if the symbol really requires
234 allocation only for local variables */
236 if (arFlag && !IS_AGGREGATE (sym->type) &&
237 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
238 !sym->allocreq && sym->level)
241 /* for bitvar locals and parameters */
242 if (!arFlag && !sym->allocreq && sym->level
243 && !SPEC_ABSA (sym->etype)) {
247 /* if global variable & not static or extern
248 and addPublics allowed then add it to the public set */
249 if ((sym->level == 0 ||
250 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
252 !IS_STATIC (sym->etype) &&
253 (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
255 addSetHead (&publics, sym);
258 /* if extern then do nothing or is a function
260 if (IS_FUNC (sym->type) && !(sym->isitmp))
263 /* print extra debug info if required */
266 if (!sym->level) /* global */
268 if (IS_STATIC (sym->etype))
269 fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
271 fprintf (map->oFile, "G$"); /* scope is global */
275 /* symbol is local */
276 fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
278 fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
281 /* if it has an initial value then do it only if
282 it is a global variable */
283 if (sym->ival && sym->level == 0) {
284 if (SPEC_OCLS(sym->etype)==xidata) {
285 /* create a new "XINIT (CODE)" symbol, that will be emitted later
287 newSym=copySymbol (sym);
288 SPEC_OCLS(newSym->etype)=xinit;
289 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
290 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
291 if (IS_SPEC (newSym->type))
292 SPEC_CONST (newSym->type) = 1;
294 DCL_PTR_CONST (newSym->type) = 1;
295 SPEC_STAT(newSym->etype)=1;
296 resolveIvalSym(newSym->ival, newSym->type);
298 // add it to the "XINIT (CODE)" segment
299 addSet(&xinit->syms, newSym);
301 if (!SPEC_ABSA (sym->etype))
303 FILE *tmpFile = tempfile ();
304 addSetHead (&tmpfileSet, tmpFile);
305 // before allocation we must parse the sym->ival tree
306 // but without actually generating initialization code
308 resolveIvalSym (sym->ival, sym->type);
309 printIval (sym, sym->type, sym->ival, tmpFile);
315 if (IS_AGGREGATE (sym->type)) {
316 ival = initAggregates (sym, sym->ival, NULL);
318 if (getNelements(sym->type, sym->ival)>1) {
319 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
322 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
323 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
325 codeOutFile = statsg->oFile;
328 // set ival's lineno to where the symbol was defined
329 setAstLineno (ival, lineno=sym->lineDef);
330 // check if this is not a constant expression
331 if (!constExprTree(ival)) {
332 werror (E_CONST_EXPECTED, "found expression");
333 // but try to do it anyway
336 if (!astErrors(ival))
337 eBBlockFromiCode (iCodeFromAst (ival));
344 /* if it has an absolute address then generate
345 an equate for this no need to allocate space */
346 if (SPEC_ABSA (sym->etype))
350 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
352 if (TARGET_IS_XA51) {
355 } else if (map==bit || map==sfrbit) {
359 fprintf (map->oFile, "%s\t%s\t0x%04x\n",
361 SPEC_ADDR (sym->etype));
364 int size = getSize (sym->type) + sym->flexArrayLength;
366 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
370 fprintf (map->oFile, "==.\n");
372 if (IS_STATIC (sym->etype))
373 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
375 tfprintf (map->oFile, "!labeldef\n", sym->rname);
376 tfprintf (map->oFile, "\t!ds\n",
377 (unsigned int) size & 0xffff);
382 /*-----------------------------------------------------------------*/
383 /* initPointer - pointer initialization code massaging */
384 /*-----------------------------------------------------------------*/
386 initPointer (initList * ilist, sym_link *toType)
392 return valCastLiteral(toType, 0.0);
395 expr = list2expr (ilist);
400 /* try it the old way first */
401 if ((val = constExprValue (expr, FALSE)))
404 /* ( ptr + constant ) */
405 if (IS_AST_OP (expr) &&
406 (expr->opval.op == '+' || expr->opval.op == '-') &&
407 IS_AST_SYM_VALUE (expr->left) &&
408 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
409 compareType(toType, expr->left->ftype) &&
410 IS_AST_LIT_VALUE (expr->right)) {
411 return valForCastAggr (expr->left, expr->left->ftype,
417 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
418 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
419 if (compareType(toType, expr->left->ftype)!=1) {
420 werror (W_INIT_WRONG);
421 printFromToType(expr->left->ftype, toType);
427 /* no then we have to do these cludgy checks */
428 /* pointers can be initialized with address of
429 a variable or address of an array element */
430 if (IS_AST_OP (expr) && expr->opval.op == '&') {
431 /* address of symbol */
432 if (IS_AST_SYM_VALUE (expr->left)) {
433 val = copyValue (AST_VALUE (expr->left));
434 val->type = newLink (DECLARATOR);
435 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
436 DCL_TYPE (val->type) = CPOINTER;
437 DCL_PTR_CONST (val->type) = port->mem.code_ro;
439 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
440 DCL_TYPE (val->type) = FPOINTER;
441 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
442 DCL_TYPE (val->type) = PPOINTER;
443 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
444 DCL_TYPE (val->type) = IPOINTER;
445 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
446 DCL_TYPE (val->type) = EEPPOINTER;
448 DCL_TYPE (val->type) = POINTER;
449 val->type->next = expr->left->ftype;
450 val->etype = getSpec (val->type);
454 /* if address of indexed array */
455 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
456 return valForArray (expr->left);
458 /* if address of structure element then
460 if (IS_AST_OP (expr->left) &&
461 expr->left->opval.op == '.') {
462 return valForStructElem (expr->left->left,
467 (&some_struct)->element */
468 if (IS_AST_OP (expr->left) &&
469 expr->left->opval.op == PTR_OP &&
470 IS_ADDRESS_OF_OP (expr->left->left)) {
471 return valForStructElem (expr->left->left->left,
475 /* case 3. (((char *) &a) +/- constant) */
476 if (IS_AST_OP (expr) &&
477 (expr->opval.op == '+' || expr->opval.op == '-') &&
478 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
479 IS_AST_OP (expr->left->right) &&
480 expr->left->right->opval.op == '&' &&
481 IS_AST_LIT_VALUE (expr->right)) {
483 return valForCastAggr (expr->left->right->left,
484 expr->left->left->opval.lnk,
485 expr->right, expr->opval.op);
488 /* case 4. (char *)(array type) */
489 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
490 IS_ARRAY(expr->right->ftype)) {
492 val = copyValue (AST_VALUE (expr->right));
493 val->type = newLink (DECLARATOR);
494 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
495 DCL_TYPE (val->type) = CPOINTER;
496 DCL_PTR_CONST (val->type) = port->mem.code_ro;
498 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
499 DCL_TYPE (val->type) = FPOINTER;
500 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
501 DCL_TYPE (val->type) = PPOINTER;
502 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
503 DCL_TYPE (val->type) = IPOINTER;
504 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
505 DCL_TYPE (val->type) = EEPPOINTER;
507 DCL_TYPE (val->type) = POINTER;
508 val->type->next = expr->right->ftype->next;
509 val->etype = getSpec (val->type);
514 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
516 werror (E_INCOMPAT_PTYPES);
521 /*-----------------------------------------------------------------*/
522 /* printChar - formats and prints a characater string with DB */
523 /*-----------------------------------------------------------------*/
525 printChar (FILE * ofile, char *s, int plen)
533 while (len && pplen < plen)
536 while (i && pplen < plen)
538 if (*s < ' ' || *s == '\"' || *s=='\\')
542 tfprintf (ofile, "\t!ascii\n", buf);
543 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
558 tfprintf (ofile, "\t!ascii\n", buf);
569 tfprintf (ofile, "\t!db !constbyte\n", 0);
574 /*-----------------------------------------------------------------*/
575 /* return the generic pointer high byte for a given pointer type. */
576 /*-----------------------------------------------------------------*/
578 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
586 werror (E_CANNOT_USE_GENERIC_POINTER,
587 iname ? iname : "<null>",
588 oname ? oname : "<null>");
595 return GPTYPE_XSTACK;
597 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
605 /*-----------------------------------------------------------------*/
606 /* printPointerType - generates ival for pointer type */
607 /*-----------------------------------------------------------------*/
609 _printPointerType (FILE * oFile, const char *name)
611 if (options.model == MODEL_FLAT24)
613 if (port->little_endian)
614 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
616 fprintf (oFile, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
620 if (port->little_endian)
621 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
623 fprintf (oFile, "\t.byte (%s >> 8),%s", name, name);
627 /*-----------------------------------------------------------------*/
628 /* printPointerType - generates ival for pointer type */
629 /*-----------------------------------------------------------------*/
631 printPointerType (FILE * oFile, const char *name)
633 _printPointerType (oFile, name);
634 fprintf (oFile, "\n");
637 /*-----------------------------------------------------------------*/
638 /* printGPointerType - generates ival for generic pointer type */
639 /*-----------------------------------------------------------------*/
641 printGPointerType (FILE * oFile, const char *iname, const char *oname,
642 const unsigned int type)
644 _printPointerType (oFile, iname);
645 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
648 /*-----------------------------------------------------------------*/
649 /* printIvalType - generates ival for int/char */
650 /*-----------------------------------------------------------------*/
652 printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
656 /* if initList is deep */
657 if (ilist && (ilist->type == INIT_DEEP))
658 ilist = ilist->init.deep;
660 if (!(val = list2val (ilist))) {
661 // assuming a warning has been thrown
665 if (val->type != type) {
666 val = valCastLiteral(type, floatFromVal(val));
669 switch (getSize (type)) {
672 tfprintf (oFile, "\t!db !constbyte\n", 0);
674 tfprintf (oFile, "\t!dbs\n",
675 aopLiteral (val, 0));
679 if (port->use_dw_for_init)
680 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
681 else if (port->little_endian)
682 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
684 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
688 tfprintf (oFile, "\t!dw !constword\n", 0);
689 tfprintf (oFile, "\t!dw !constword\n", 0);
691 else if (port->little_endian) {
692 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
693 aopLiteral (val, 0), aopLiteral (val, 1),
694 aopLiteral (val, 2), aopLiteral (val, 3));
697 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
698 aopLiteral (val, 3), aopLiteral (val, 2),
699 aopLiteral (val, 1), aopLiteral (val, 0));
705 /*-----------------------------------------------------------------*/
706 /* printIvalBitFields - generate initializer for bitfields */
707 /*-----------------------------------------------------------------*/
708 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
712 initList *lilist = *ilist ;
713 unsigned long ival = 0;
719 val = list2val(lilist);
721 if (SPEC_BLEN(lsym->etype) > 8) {
722 size += ((SPEC_BLEN (lsym->etype) / 8) +
723 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
726 size = ((SPEC_BLEN (lsym->etype) / 8) +
727 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
729 i = (unsigned long)floatFromVal(val);
730 i <<= SPEC_BSTR (lsym->etype);
732 if (! ( lsym->next &&
733 (IS_BITFIELD(lsym->next->type)) &&
734 (SPEC_BSTR(lsym->next->etype)))) break;
736 lilist = lilist->next;
740 tfprintf (oFile, "\t!db !constbyte\n",ival);
744 tfprintf (oFile, "\t!dw !constword\n",ival);
746 case 4: /* EEP: why is this db and not dw? */
747 tfprintf (oFile, "\t!db !constword,!constword\n",
748 (ival >> 8) & 0xffff, (ival & 0xffff));
755 /*-----------------------------------------------------------------*/
756 /* printIvalStruct - generates initial value for structures */
757 /*-----------------------------------------------------------------*/
759 printIvalStruct (symbol * sym, sym_link * type,
760 initList * ilist, FILE * oFile)
763 initList *iloop = NULL;
765 sflds = SPEC_STRUCT (type)->fields;
768 if (ilist->type != INIT_DEEP) {
769 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
773 iloop = ilist->init.deep;
776 if (SPEC_STRUCT (type)->type == UNION) {
777 printIval (sym, sflds->type, iloop, oFile);
780 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
781 if (IS_BITFIELD(sflds->type)) {
782 printIvalBitFields(&sflds,&iloop,oFile);
784 printIval (sym, sflds->type, iloop, oFile);
789 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
794 /*-----------------------------------------------------------------*/
795 /* printIvalChar - generates initital value for character array */
796 /*-----------------------------------------------------------------*/
798 printIvalChar (symbol * sym, sym_link * type, initList * ilist, FILE * oFile, char *s)
801 unsigned int size = DCL_ELEM (type);
805 val = list2val (ilist);
806 /* if the value is a character string */
807 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
811 /* we have not been given a size, but now we know it */
812 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
813 /* but first check, if it's a flexible array */
814 if (sym && IS_STRUCT (sym->type))
815 sym->flexArrayLength = size;
817 DCL_ELEM (type) = size;
820 printChar (oFile, SPEC_CVAL (val->etype).v_char, size);
828 printChar (oFile, s, strlen (s) + 1);
832 /*-----------------------------------------------------------------*/
833 /* printIvalArray - generates code for array initialization */
834 /*-----------------------------------------------------------------*/
836 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
840 unsigned int size = 0;
843 /* take care of the special case */
844 /* array of characters can be init */
846 if (IS_CHAR (type->next)) {
847 if (!IS_LITERAL(list2val(ilist)->etype)) {
848 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
851 if (printIvalChar (sym, type,
852 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
853 oFile, SPEC_CVAL (sym->etype).v_char))
856 /* not the special case */
857 if (ilist->type != INIT_DEEP) {
858 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
862 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
863 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
864 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
867 printIval (sym, type->next, iloop, oFile);
871 if (DCL_ELEM(type)) {
872 // pad with zeros if needed
873 if (size<DCL_ELEM(type)) {
874 size = (DCL_ELEM(type) - size) * getSize(type->next);
876 tfprintf (oFile, "\t!db !constbyte\n", 0);
880 /* we have not been given a size, but now we know it */
881 /* but first check, if it's a flexible array */
882 if (IS_STRUCT (sym->type))
883 sym->flexArrayLength = size * getSize (type->next);
885 DCL_ELEM (type) = size;
891 /*-----------------------------------------------------------------*/
892 /* printIvalFuncPtr - generate initial value for function pointers */
893 /*-----------------------------------------------------------------*/
895 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
901 val = list2val (ilist);
903 val = valCastLiteral(type, 0.0);
906 // an error has been thrown already
910 if (IS_LITERAL(val->etype)) {
911 if (compareType(type, val->etype) == 0) {
912 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
913 printFromToType (val->type, type);
915 printIvalCharPtr (NULL, type, val, oFile);
919 /* check the types */
920 if ((dLvl = compareType (val->type, type->next)) <= 0)
922 tfprintf (oFile, "\t!dw !constword\n", 0);
926 /* now generate the name */
929 if (port->use_dw_for_init)
931 tfprintf (oFile, "\t!dws\n", val->name);
935 printPointerType (oFile, val->name);
938 else if (port->use_dw_for_init)
940 tfprintf (oFile, "\t!dws\n", val->sym->rname);
944 printPointerType (oFile, val->sym->rname);
950 /*-----------------------------------------------------------------*/
951 /* printIvalCharPtr - generates initial values for character pointers */
952 /*-----------------------------------------------------------------*/
954 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
958 /* PENDING: this is _very_ mcs51 specific, including a magic
960 It's also endin specific.
962 size = getSize (type);
964 if (val->name && strlen (val->name))
966 if (size == 1) /* This appears to be Z80 specific?? */
969 "\t!dbs\n", val->name);
971 else if (size == FPTRSIZE)
973 if (port->use_dw_for_init)
975 tfprintf (oFile, "\t!dws\n", val->name);
979 printPointerType (oFile, val->name);
982 else if (size == GPTRSIZE)
985 if (IS_PTR (val->type)) {
986 type = DCL_TYPE (val->type);
988 type = PTR_TYPE (SPEC_OCLS (val->etype));
990 if (val->sym && val->sym->isstrlit) {
991 // this is a literal string
994 printGPointerType (oFile, val->name, sym->name, type);
998 fprintf (stderr, "*** internal error: unknown size in "
999 "printIvalCharPtr.\n");
1004 // these are literals assigned to pointers
1008 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
1011 if (port->use_dw_for_init)
1012 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
1013 else if (port->little_endian)
1014 tfprintf (oFile, "\t.byte %s,%s\n",
1015 aopLiteral (val, 0), aopLiteral (val, 1));
1017 tfprintf (oFile, "\t.byte %s,%s\n",
1018 aopLiteral (val, 1), aopLiteral (val, 0));
1021 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1022 // non-zero mcs51 generic pointer
1023 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1025 if (port->little_endian) {
1026 fprintf (oFile, "\t.byte %s,%s,%s\n",
1027 aopLiteral (val, 0),
1028 aopLiteral (val, 1),
1029 aopLiteral (val, 2));
1031 fprintf (oFile, "\t.byte %s,%s,%s\n",
1032 aopLiteral (val, 2),
1033 aopLiteral (val, 1),
1034 aopLiteral (val, 0));
1038 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1039 // non-zero ds390 generic pointer
1040 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1042 if (port->little_endian) {
1043 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
1044 aopLiteral (val, 0),
1045 aopLiteral (val, 1),
1046 aopLiteral (val, 2),
1047 aopLiteral (val, 3));
1049 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
1050 aopLiteral (val, 3),
1051 aopLiteral (val, 2),
1052 aopLiteral (val, 1),
1053 aopLiteral (val, 0));
1061 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1062 addSet (&statsg->syms, val->sym);
1068 /*-----------------------------------------------------------------*/
1069 /* printIvalPtr - generates initial value for pointers */
1070 /*-----------------------------------------------------------------*/
1072 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1078 if (ilist && (ilist->type == INIT_DEEP))
1079 ilist = ilist->init.deep;
1081 /* function pointer */
1082 if (IS_FUNC (type->next))
1084 printIvalFuncPtr (type, ilist, oFile);
1088 if (!(val = initPointer (ilist, type)))
1091 /* if character pointer */
1092 if (IS_CHAR (type->next))
1093 if (printIvalCharPtr (sym, type, val, oFile))
1096 /* check the type */
1097 if (compareType (type, val->type) == 0) {
1098 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1099 printFromToType (val->type, type);
1102 /* if val is literal */
1103 if (IS_LITERAL (val->etype))
1105 switch (getSize (type))
1108 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
1111 if (port->use_dw_for_init)
1112 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
1113 else if (port->little_endian)
1114 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1116 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1118 case 3: // how about '390??
1119 fprintf (oFile, "; generic printIvalPtr\n");
1120 if (port->little_endian)
1122 fprintf (oFile, "\t.byte %s,%s",
1123 aopLiteral (val, 0), aopLiteral (val, 1));
1127 fprintf (oFile, "\t.byte %s,%s",
1128 aopLiteral (val, 1), aopLiteral (val, 0));
1130 if (IS_GENPTR (val->type))
1131 fprintf (oFile, ",%s\n", aopLiteral (val, 2));
1132 else if (IS_PTR (val->type))
1133 fprintf (oFile, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1135 fprintf (oFile, ",%s\n", aopLiteral (val, 2));
1141 size = getSize (type);
1143 if (size == 1) /* Z80 specific?? */
1145 tfprintf (oFile, "\t!dbs\n", val->name);
1147 else if (size == FPTRSIZE)
1149 if (port->use_dw_for_init) {
1150 tfprintf (oFile, "\t!dws\n", val->name);
1152 printPointerType (oFile, val->name);
1155 else if (size == GPTRSIZE)
1157 printGPointerType (oFile, val->name, sym->name,
1158 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1159 PTR_TYPE (SPEC_OCLS (val->etype))));
1164 /*-----------------------------------------------------------------*/
1165 /* printIval - generates code for initial value */
1166 /*-----------------------------------------------------------------*/
1168 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1172 /* if structure then */
1173 if (IS_STRUCT (type))
1175 printIvalStruct (sym, type, ilist, oFile);
1179 /* if this is an array */
1180 if (IS_ARRAY (type))
1182 printIvalArray (sym, type, ilist, oFile);
1188 // not an aggregate, ilist must be a node
1189 if (ilist->type!=INIT_NODE) {
1190 // or a 1-element list
1191 if (ilist->init.deep->next) {
1192 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1195 ilist=ilist->init.deep;
1199 // and the type must match
1200 itype=ilist->init.node->ftype;
1202 if (compareType(type, itype)==0) {
1203 // special case for literal strings
1204 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1205 // which are really code pointers
1206 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1209 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1210 printFromToType(itype, type);
1215 /* if this is a pointer */
1218 printIvalPtr (sym, type, ilist, oFile);
1222 /* if type is SPECIFIER */
1225 printIvalType (sym, type, ilist, oFile);
1230 /*-----------------------------------------------------------------*/
1231 /* emitStaticSeg - emitcode for the static segment */
1232 /*-----------------------------------------------------------------*/
1234 emitStaticSeg (memmap * map, FILE * out)
1238 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1240 /* for all variables in this segment do */
1241 for (sym = setFirstItem (map->syms); sym;
1242 sym = setNextItem (map->syms))
1245 /* if it is "extern" then do nothing */
1246 if (IS_EXTERN (sym->etype))
1249 /* if it is not static add it to the public
1251 if (!IS_STATIC (sym->etype))
1253 addSetHead (&publics, sym);
1256 /* print extra debug info if required */
1257 if (options.debug) {
1261 if (IS_STATIC (sym->etype))
1262 fprintf (out, "F%s$", moduleName); /* scope is file */
1264 fprintf (out, "G$"); /* scope is global */
1267 /* symbol is local */
1268 fprintf (out, "L%s$",
1269 (sym->localof ? sym->localof->name : "-null-"));
1270 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
1273 /* if it has an absolute address */
1274 if (SPEC_ABSA (sym->etype))
1277 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1279 fprintf (out, "%s\t=\t0x%04x\n",
1281 SPEC_ADDR (sym->etype));
1286 fprintf (out, " == .\n");
1288 /* if it has an initial value */
1291 fprintf (out, "%s:\n", sym->rname);
1293 resolveIvalSym (sym->ival, sym->type);
1294 printIval (sym, sym->type, sym->ival, out);
1296 /* if sym is a simple string and sym->ival is a string,
1297 WE don't need it anymore */
1298 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1299 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1300 list2val(sym->ival)->sym->isstrlit) {
1301 freeStringSymbol(list2val(sym->ival)->sym);
1305 /* allocate space */
1306 int size = getSize (sym->type);
1309 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1311 fprintf (out, "%s:\n", sym->rname);
1312 /* special case for character strings */
1313 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1314 SPEC_CVAL (sym->etype).v_char)
1316 SPEC_CVAL (sym->etype).v_char,
1319 tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff);
1325 /*-----------------------------------------------------------------*/
1326 /* emitMaps - emits the code for the data portion the code */
1327 /*-----------------------------------------------------------------*/
1331 int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */
1332 /* ports but let's be conservative - EEP */
1335 /* no special considerations for the following
1336 data, idata & bit & xdata */
1337 emitRegularMap (data, TRUE, TRUE);
1338 emitRegularMap (idata, TRUE, TRUE);
1339 emitRegularMap (bit, TRUE, TRUE);
1340 emitRegularMap (pdata, TRUE, TRUE);
1341 emitRegularMap (xdata, TRUE, TRUE);
1342 if (port->genXINIT) {
1343 emitRegularMap (xidata, TRUE, TRUE);
1345 emitRegularMap (sfr, publicsfr, FALSE);
1346 emitRegularMap (sfrbit, publicsfr, FALSE);
1347 emitRegularMap (home, TRUE, FALSE);
1348 emitRegularMap (code, TRUE, FALSE);
1350 if (options.const_seg) {
1351 tfprintf (code->oFile, "\t!area\n", options.const_seg);
1353 emitStaticSeg (statsg, code->oFile);
1354 if (port->genXINIT) {
1355 tfprintf (code->oFile, "\t!area\n", xinit->sname);
1356 emitStaticSeg (xinit, code->oFile);
1361 /*-----------------------------------------------------------------*/
1362 /* flushStatics - flush all currently defined statics out to file */
1363 /* and delete. Temporary function */
1364 /*-----------------------------------------------------------------*/
1368 emitStaticSeg (statsg, codeOutFile);
1369 statsg->syms = NULL;
1372 /*-----------------------------------------------------------------*/
1373 /* createInterruptVect - creates the interrupt vector */
1374 /*-----------------------------------------------------------------*/
1376 createInterruptVect (FILE * vFile)
1378 mainf = newSymbol ("main", 0);
1381 /* only if the main function exists */
1382 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1384 if (!options.cc_only && !noAssemble && !options.c1mode)
1389 /* if the main is only a prototype ie. no body then do nothing */
1390 if (!IFFUNC_HASBODY(mainf->type))
1392 /* if ! compile only then main function should be present */
1393 if (!options.cc_only && !noAssemble)
1398 tfprintf (vFile, "\t!areacode\n", HOME_NAME);
1399 fprintf (vFile, "__interrupt_vect:\n");
1402 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1404 /* There's no such thing as a "generic" interrupt table header. */
1411 ";--------------------------------------------------------\n"
1412 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1416 ";--------------------------------------------------------\n"};
1419 /*-----------------------------------------------------------------*/
1420 /* initialComments - puts in some initial comments */
1421 /*-----------------------------------------------------------------*/
1423 initialComments (FILE * afile)
1427 fprintf (afile, "%s", iComments1);
1428 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s)\n", getBuildNumber(), __DATE__);
1429 fprintf (afile, "; This file generated %s", asctime (localtime (&t)));
1430 fprintf (afile, "%s", iComments2);
1433 /*-----------------------------------------------------------------*/
1434 /* printPublics - generates .global for publics */
1435 /*-----------------------------------------------------------------*/
1437 printPublics (FILE * afile)
1441 fprintf (afile, "%s", iComments2);
1442 fprintf (afile, "; Public variables in this module\n");
1443 fprintf (afile, "%s", iComments2);
1445 for (sym = setFirstItem (publics); sym;
1446 sym = setNextItem (publics))
1447 tfprintf (afile, "\t!global\n", sym->rname);
1450 /*-----------------------------------------------------------------*/
1451 /* printExterns - generates .global for externs */
1452 /*-----------------------------------------------------------------*/
1454 printExterns (FILE * afile)
1458 fprintf (afile, "%s", iComments2);
1459 fprintf (afile, "; Externals used\n");
1460 fprintf (afile, "%s", iComments2);
1462 for (sym = setFirstItem (externs); sym;
1463 sym = setNextItem (externs))
1464 tfprintf (afile, "\t!extern\n", sym->rname);
1467 /*-----------------------------------------------------------------*/
1468 /* emitOverlay - will emit code for the overlay stuff */
1469 /*-----------------------------------------------------------------*/
1471 emitOverlay (FILE * afile)
1475 if (!elementsInSet (ovrSetSets))
1476 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1478 /* for each of the sets in the overlay segment do */
1479 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1480 ovrset = setNextItem (ovrSetSets))
1485 if (elementsInSet (ovrset))
1487 /* output the area informtion */
1488 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1491 for (sym = setFirstItem (ovrset); sym;
1492 sym = setNextItem (ovrset))
1494 /* if extern then it is in the publics table: do nothing */
1495 if (IS_EXTERN (sym->etype))
1498 /* if allocation required check is needed
1499 then check if the symbol really requires
1500 allocation only for local variables */
1501 if (!IS_AGGREGATE (sym->type) &&
1502 !(sym->_isparm && !IS_REGPARM (sym->etype))
1503 && !sym->allocreq && sym->level)
1506 /* if global variable & not static or extern
1507 and addPublics allowed then add it to the public set */
1508 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1509 && !IS_STATIC (sym->etype))
1511 addSetHead (&publics, sym);
1514 /* if extern then do nothing or is a function
1516 if (IS_FUNC (sym->type))
1519 /* print extra debug info if required */
1524 if (IS_STATIC (sym->etype))
1525 fprintf (afile, "F%s$", moduleName); /* scope is file */
1527 fprintf (afile, "G$"); /* scope is global */
1530 /* symbol is local */
1531 fprintf (afile, "L%s$",
1532 (sym->localof ? sym->localof->name : "-null-"));
1533 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1536 /* if is has an absolute address then generate
1537 an equate for this no need to allocate space */
1538 if (SPEC_ABSA (sym->etype))
1542 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1544 fprintf (afile, "%s\t=\t0x%04x\n",
1546 SPEC_ADDR (sym->etype));
1549 int size = getSize(sym->type);
1552 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1555 fprintf (afile, "==.\n");
1557 /* allocate space */
1558 tfprintf (afile, "!labeldef\n", sym->rname);
1559 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1567 /*-----------------------------------------------------------------*/
1568 /* spacesToUnderscores - replace spaces with underscores */
1569 /*-----------------------------------------------------------------*/
1571 spacesToUnderscores (char *dest, const char *src, size_t len)
1576 assert(dest != NULL);
1577 assert(src != NULL);
1581 for (p = dest, i = 0; *src != '\0' && i < len; ++src, ++i) {
1582 *p++ = isspace((unsigned char)*src) ? '_' : *src;
1590 /*-----------------------------------------------------------------*/
1591 /* glue - the final glue that hold the whole thing together */
1592 /*-----------------------------------------------------------------*/
1598 FILE *ovrFile = tempfile ();
1599 char moduleBuf[PATH_MAX];
1602 if(port->general.glue_up_main &&
1603 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400))
1605 mcs51_like=1; /*So it has bits, sfr, sbits, data, idata, etc...*/
1612 addSetHead (&tmpfileSet, ovrFile);
1613 /* print the global struct definitions */
1617 vFile = tempfile ();
1618 /* PENDING: this isn't the best place but it will do */
1619 if (port->general.glue_up_main)
1621 /* create the interrupt vector table */
1622 createInterruptVect (vFile);
1625 addSetHead (&tmpfileSet, vFile);
1627 /* emit code for the all the variables declared */
1629 /* do the overlay segments */
1630 emitOverlay (ovrFile);
1632 outputDebugSymbols();
1634 /* now put it all together into the assembler file */
1635 /* create the assembler file name */
1637 /* -o option overrides default name? */
1638 if ((noAssemble || options.c1mode) && fullDstFileName)
1640 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1644 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1645 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1648 if (!(asmFile = fopen (scratchFileName, "w")))
1650 werror (E_FILE_OPEN_ERR, scratchFileName);
1654 /* initial comments */
1655 initialComments (asmFile);
1657 /* print module name */
1658 tfprintf (asmFile, "\t!module\n",
1659 spacesToUnderscores (moduleBuf, moduleName, sizeof moduleBuf));
1662 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1664 switch(options.model)
1666 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1667 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1668 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1669 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1670 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1671 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1674 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1675 if(options.useXstack) fprintf (asmFile, " --xstack");
1676 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1677 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1678 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1679 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1680 fprintf (asmFile, "\n");
1682 else if(TARGET_IS_Z80 || TARGET_IS_GBZ80 || TARGET_IS_HC08)
1684 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1687 tfprintf (asmFile, "\t!fileprelude\n");
1689 /* Let the port generate any global directives, etc. */
1690 if (port->genAssemblerPreamble)
1692 port->genAssemblerPreamble (asmFile);
1695 /* print the global variables in this module */
1696 printPublics (asmFile);
1697 if (port->assembler.externGlobal)
1698 printExterns (asmFile);
1701 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1703 /* copy the sfr segment */
1704 fprintf (asmFile, "%s", iComments2);
1705 fprintf (asmFile, "; special function registers\n");
1706 fprintf (asmFile, "%s", iComments2);
1707 copyFile (asmFile, sfr->oFile);
1712 /* copy the sbit segment */
1713 fprintf (asmFile, "%s", iComments2);
1714 fprintf (asmFile, "; special function bits\n");
1715 fprintf (asmFile, "%s", iComments2);
1716 copyFile (asmFile, sfrbit->oFile);
1718 /*JCF: Create the areas for the register banks*/
1719 if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3])
1721 fprintf (asmFile, "%s", iComments2);
1722 fprintf (asmFile, "; overlayable register banks\n");
1723 fprintf (asmFile, "%s", iComments2);
1725 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1726 if(RegBankUsed[1]||options.parms_in_bank1)
1727 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1729 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1731 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1735 fprintf (asmFile, "%s", iComments2);
1736 fprintf (asmFile, "; overlayable bit register bank\n");
1737 fprintf (asmFile, "%s", iComments2);
1738 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1739 fprintf (asmFile, "bits:\n\t.ds 1\n");
1740 fprintf (asmFile, "\tb0 = bits[0]\n");
1741 fprintf (asmFile, "\tb1 = bits[1]\n");
1742 fprintf (asmFile, "\tb2 = bits[2]\n");
1743 fprintf (asmFile, "\tb3 = bits[3]\n");
1744 fprintf (asmFile, "\tb4 = bits[4]\n");
1745 fprintf (asmFile, "\tb5 = bits[5]\n");
1746 fprintf (asmFile, "\tb6 = bits[6]\n");
1747 fprintf (asmFile, "\tb7 = bits[7]\n");
1751 /* copy the data segment */
1752 fprintf (asmFile, "%s", iComments2);
1753 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1754 fprintf (asmFile, "%s", iComments2);
1755 copyFile (asmFile, data->oFile);
1758 /* create the overlay segments */
1760 fprintf (asmFile, "%s", iComments2);
1761 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1762 fprintf (asmFile, "%s", iComments2);
1763 copyFile (asmFile, ovrFile);
1766 /* create the stack segment MOF */
1767 if (mainf && IFFUNC_HASBODY(mainf->type))
1769 fprintf (asmFile, "%s", iComments2);
1770 fprintf (asmFile, "; Stack segment in internal ram \n");
1771 fprintf (asmFile, "%s", iComments2);
1772 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1773 "__start__stack:\n\t.ds\t1\n\n");
1776 /* create the idata segment */
1777 if ( (idata) && (mcs51_like) ) {
1778 fprintf (asmFile, "%s", iComments2);
1779 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1780 fprintf (asmFile, "%s", iComments2);
1781 copyFile (asmFile, idata->oFile);
1784 /* copy the bit segment */
1786 fprintf (asmFile, "%s", iComments2);
1787 fprintf (asmFile, "; bit data\n");
1788 fprintf (asmFile, "%s", iComments2);
1789 copyFile (asmFile, bit->oFile);
1792 /* copy paged external ram data */
1795 fprintf (asmFile, "%s", iComments2);
1796 fprintf (asmFile, "; paged external ram data\n");
1797 fprintf (asmFile, "%s", iComments2);
1798 copyFile (asmFile, pdata->oFile);
1801 /* if external stack then reserve space for it */
1802 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1804 fprintf (asmFile, "%s", iComments2);
1805 fprintf (asmFile, "; external stack \n");
1806 fprintf (asmFile, "%s", iComments2);
1807 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1808 "__start__xstack:\n\t.ds\t1\n\n");
1811 /* copy external ram data */
1813 fprintf (asmFile, "%s", iComments2);
1814 fprintf (asmFile, "; external ram data\n");
1815 fprintf (asmFile, "%s", iComments2);
1816 copyFile (asmFile, xdata->oFile);
1819 /* copy external initialized ram data */
1820 fprintf (asmFile, "%s", iComments2);
1821 fprintf (asmFile, "; external initialized ram data\n");
1822 fprintf (asmFile, "%s", iComments2);
1823 copyFile (asmFile, xidata->oFile);
1825 /* If the port wants to generate any extra areas, let it do so. */
1826 if (port->extraAreas.genExtraAreaDeclaration)
1828 port->extraAreas.genExtraAreaDeclaration(asmFile,
1829 mainf && IFFUNC_HASBODY(mainf->type));
1832 /* copy the interrupt vector table */
1833 if (mainf && IFFUNC_HASBODY(mainf->type))
1835 fprintf (asmFile, "%s", iComments2);
1836 fprintf (asmFile, "; interrupt vector \n");
1837 fprintf (asmFile, "%s", iComments2);
1838 copyFile (asmFile, vFile);
1841 /* copy global & static initialisations */
1842 fprintf (asmFile, "%s", iComments2);
1843 fprintf (asmFile, "; global & static initialisations\n");
1844 fprintf (asmFile, "%s", iComments2);
1846 /* Everywhere we generate a reference to the static_name area,
1847 * (which is currently only here), we immediately follow it with a
1848 * definition of the post_static_name area. This guarantees that
1849 * the post_static_name area will immediately follow the static_name
1852 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1853 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1854 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1855 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1857 if (mainf && IFFUNC_HASBODY(mainf->type))
1859 if (port->genInitStartup)
1861 port->genInitStartup(asmFile);
1865 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1866 /* if external stack is specified then the
1867 higher order byte of the xdatalocation is
1868 going into P2 and the lower order going into
1870 if (options.useXstack)
1872 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1873 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1874 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1875 (unsigned int) options.xdata_loc & 0xff);
1878 // This should probably be a port option, but I'm being lazy.
1879 // on the 400, the firmware boot loader gives us a valid stack
1880 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1881 if (!TARGET_IS_DS400)
1883 /* initialise the stack pointer. JCF: aslink takes care of the location */
1884 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1887 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1888 fprintf (asmFile, "\tmov\ta,dpl\n");
1889 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1890 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1891 fprintf (asmFile, "__sdcc_init_data:\n");
1893 // if the port can copy the XINIT segment to XISEG
1896 port->genXINIT(asmFile);
1901 copyFile (asmFile, statsg->oFile);
1903 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1905 /* This code is generated in the post-static area.
1906 * This area is guaranteed to follow the static area
1907 * by the ugly shucking and jiving about 20 lines ago.
1909 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1910 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1916 "%s", iComments2, iComments2);
1917 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1918 copyFile (asmFile, home->oFile);
1920 if (mainf && IFFUNC_HASBODY(mainf->type))
1923 /* entry point @ start of HOME */
1924 fprintf (asmFile, "__sdcc_program_startup:\n");
1926 /* put in jump or call to main */
1927 if (options.mainreturn)
1929 fprintf (asmFile, "\tljmp\t_main\n"); /* needed? */
1930 fprintf (asmFile, ";\treturn from main will return to caller\n");
1934 fprintf (asmFile, "\tlcall\t_main\n");
1935 fprintf (asmFile, ";\treturn from main will lock up\n");
1936 fprintf (asmFile, "\tsjmp .\n");
1939 /* copy over code */
1940 fprintf (asmFile, "%s", iComments2);
1941 fprintf (asmFile, "; code\n");
1942 fprintf (asmFile, "%s", iComments2);
1943 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1944 copyFile (asmFile, code->oFile);
1946 if (port->genAssemblerEnd) {
1947 port->genAssemblerEnd(asmFile);
1955 /** Creates a temporary file with unique file name
1957 - TMP, TEMP, TMPDIR env. variables
1958 - if Un*x system: /usr/tmp and /tmp
1959 - root directory using mkstemp() if available
1960 - default location using tempnam()
1963 tempfileandname(char *fname, size_t len)
1965 #define TEMPLATE "sdccXXXXXX"
1966 #define TEMPLATE_LEN ((sizeof TEMPLATE) - 1)
1968 const char *tmpdir = NULL;
1971 if ((tmpdir = getenv ("TMP")) == NULL)
1972 if ((tmpdir = getenv ("TEMP")) == NULL)
1973 tmpdir = getenv ("TMPDIR");
1977 static int warning_emitted;
1982 if (!warning_emitted)
1984 fprintf (stderr, "TMP not defined in environment, using %s for temporary files\n.", tmpdir);
1985 warning_emitted = 1;
1991 /* try with /usr/tmp and /tmp on Un*x systems */
1992 struct stat statbuf;
1994 if (tmpdir == NULL) {
1995 if (stat("/usr/tmp", &statbuf) != -1)
1996 tmpdir = "/usr/tmp";
1997 else if (stat("/tmp", &statbuf) != -1)
2005 char fnamebuf[PATH_MAX];
2008 if (fname == NULL || len == 0) {
2010 len = sizeof fnamebuf;
2014 name_len = strlen(tmpdir) + 1 + TEMPLATE_LEN;
2016 assert(name_len < len);
2017 if (!(name_len < len)) /* in NDEBUG is defined */
2018 return -1; /* buffer too small, temporary file can not be created */
2020 sprintf(fname, "%s" DIR_SEPARATOR_STRING TEMPLATE, tmpdir);
2023 name_len = TEMPLATE_LEN;
2025 assert(name_len < len);
2026 if (!(name_len < len)) /* in NDEBUG is defined */
2027 return -1; /* buffer too small, temporary file can not be created */
2029 strcpy(fname, TEMPLATE);
2032 fd = mkstemp(fname);
2036 char *name = tempnam(tmpdir, "sdcc");
2039 perror("Can't create temporary file name");
2043 assert(strlen(name) < len);
2044 if (!(strlen(name) < len)) /* in NDEBUG is defined */
2045 return -1; /* buffer too small, temporary file can not be created */
2047 strcpy(fname, name);
2049 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE);
2051 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
2057 perror("Can't create temporary file");
2065 /** Create a temporary file name
2071 static char fnamebuf[PATH_MAX];
2073 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
2074 fprintf(stderr, "Can't create temporary file name!");
2085 /** Create a temporary file and add it to tmpfileNameSet,
2086 so that it is removed explicitly by rm_tmpfiles()
2087 or implicitly at program extit.
2095 char fnamebuf[PATH_MAX];
2097 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
2098 fprintf(stderr, "Can't create temporary file!");
2102 tmp = Safe_strdup(fnamebuf);
2104 addSetHead(&tmpfileNameSet, tmp);
2106 if ((fp = fdopen(fd, "w+b")) == NULL) {
2107 perror("Can't create temporary file!");