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 if (!astErrors(ival))
325 eBBlockFromiCode (iCodeFromAst (ival));
332 /* if is has an absolute address then generate
333 an equate for this no need to allocate space */
334 if (SPEC_ABSA (sym->etype))
338 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
340 if (TARGET_IS_XA51) {
343 } else if (map==bit || map==sfrbit) {
347 fprintf (map->oFile, "%s\t%s\t0x%04x\n",
349 SPEC_ADDR (sym->etype));
352 int size = getSize (sym->type);
354 werror(E_UNKNOWN_SIZE,sym->name);
358 fprintf (map->oFile, "==.\n");
360 if (IS_STATIC (sym->etype))
361 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
363 tfprintf (map->oFile, "!labeldef\n", sym->rname);
364 tfprintf (map->oFile, "\t!ds\n",
365 (unsigned int) size & 0xffff);
370 /*-----------------------------------------------------------------*/
371 /* initPointer - pointer initialization code massaging */
372 /*-----------------------------------------------------------------*/
374 initPointer (initList * ilist, sym_link *toType)
377 ast *expr = list2expr (ilist);
382 /* try it the oldway first */
383 if ((val = constExprValue (expr, FALSE)))
386 /* ( ptr + constant ) */
387 if (IS_AST_OP (expr) &&
388 (expr->opval.op == '+' || expr->opval.op == '-') &&
389 IS_AST_SYM_VALUE (expr->left) &&
390 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
391 compareType(toType, expr->left->ftype) &&
392 IS_AST_LIT_VALUE (expr->right)) {
393 return valForCastAggr (expr->left, expr->left->ftype,
399 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
400 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
401 if (compareType(toType, expr->left->ftype)!=1) {
402 werror (W_INIT_WRONG);
403 printFromToType(expr->left->ftype, toType);
409 /* no then we have to do these cludgy checks */
410 /* pointers can be initialized with address of
411 a variable or address of an array element */
412 if (IS_AST_OP (expr) && expr->opval.op == '&') {
413 /* address of symbol */
414 if (IS_AST_SYM_VALUE (expr->left)) {
415 val = copyValue (AST_VALUE (expr->left));
416 val->type = newLink (DECLARATOR);
417 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
418 DCL_TYPE (val->type) = CPOINTER;
419 DCL_PTR_CONST (val->type) = port->mem.code_ro;
421 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
422 DCL_TYPE (val->type) = FPOINTER;
423 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
424 DCL_TYPE (val->type) = PPOINTER;
425 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
426 DCL_TYPE (val->type) = IPOINTER;
427 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
428 DCL_TYPE (val->type) = EEPPOINTER;
430 DCL_TYPE (val->type) = POINTER;
431 val->type->next = expr->left->ftype;
432 val->etype = getSpec (val->type);
436 /* if address of indexed array */
437 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
438 return valForArray (expr->left);
440 /* if address of structure element then
442 if (IS_AST_OP (expr->left) &&
443 expr->left->opval.op == '.') {
444 return valForStructElem (expr->left->left,
449 (&some_struct)->element */
450 if (IS_AST_OP (expr->left) &&
451 expr->left->opval.op == PTR_OP &&
452 IS_ADDRESS_OF_OP (expr->left->left)) {
453 return valForStructElem (expr->left->left->left,
457 /* case 3. (((char *) &a) +/- constant) */
458 if (IS_AST_OP (expr) &&
459 (expr->opval.op == '+' || expr->opval.op == '-') &&
460 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
461 IS_AST_OP (expr->left->right) &&
462 expr->left->right->opval.op == '&' &&
463 IS_AST_LIT_VALUE (expr->right)) {
465 return valForCastAggr (expr->left->right->left,
466 expr->left->left->opval.lnk,
467 expr->right, expr->opval.op);
470 /* case 4. (char *)(array type) */
471 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
472 IS_ARRAY(expr->right->ftype)) {
474 val = copyValue (AST_VALUE (expr->right));
475 val->type = newLink (DECLARATOR);
476 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
477 DCL_TYPE (val->type) = CPOINTER;
478 DCL_PTR_CONST (val->type) = port->mem.code_ro;
480 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
481 DCL_TYPE (val->type) = FPOINTER;
482 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
483 DCL_TYPE (val->type) = PPOINTER;
484 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
485 DCL_TYPE (val->type) = IPOINTER;
486 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
487 DCL_TYPE (val->type) = EEPPOINTER;
489 DCL_TYPE (val->type) = POINTER;
490 val->type->next = expr->right->ftype->next;
491 val->etype = getSpec (val->type);
495 werror (E_INCOMPAT_PTYPES);
500 /*-----------------------------------------------------------------*/
501 /* printChar - formats and prints a characater string with DB */
502 /*-----------------------------------------------------------------*/
504 printChar (FILE * ofile, char *s, int plen)
507 int len = strlen (s);
512 while (len && pplen < plen)
515 while (i && *s && pplen < plen)
517 if (*s < ' ' || *s == '\"' || *s=='\\')
521 tfprintf (ofile, "\t!ascii\n", buf);
522 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
537 tfprintf (ofile, "\t!ascii\n", buf);
546 tfprintf (ofile, "\t!db !constbyte\n", 0);
549 /*-----------------------------------------------------------------*/
550 /* return the generic pointer high byte for a given pointer type. */
551 /*-----------------------------------------------------------------*/
553 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
561 werror (E_CANNOT_USE_GENERIC_POINTER,
562 iname ? iname : "<null>",
563 oname ? oname : "<null>");
570 return GPTYPE_XSTACK;
572 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
580 /*-----------------------------------------------------------------*/
581 /* printPointerType - generates ival for pointer type */
582 /*-----------------------------------------------------------------*/
584 _printPointerType (FILE * oFile, const char *name)
586 if (options.model == MODEL_FLAT24)
588 if (port->little_endian)
589 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
591 fprintf (oFile, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
595 if (port->little_endian)
596 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
598 fprintf (oFile, "\t.byte (%s >> 8),%s", name, name);
602 /*-----------------------------------------------------------------*/
603 /* printPointerType - generates ival for pointer type */
604 /*-----------------------------------------------------------------*/
606 printPointerType (FILE * oFile, const char *name)
608 _printPointerType (oFile, name);
609 fprintf (oFile, "\n");
612 /*-----------------------------------------------------------------*/
613 /* printGPointerType - generates ival for generic pointer type */
614 /*-----------------------------------------------------------------*/
616 printGPointerType (FILE * oFile, const char *iname, const char *oname,
617 const unsigned int type)
619 _printPointerType (oFile, iname);
620 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
623 /*-----------------------------------------------------------------*/
624 /* printIvalType - generates ival for int/char */
625 /*-----------------------------------------------------------------*/
627 printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
631 /* if initList is deep */
632 if (ilist->type == INIT_DEEP)
633 ilist = ilist->init.deep;
635 if (!(val = list2val (ilist))) {
636 // assuming a warning has been thrown
640 if (val->type != type) {
641 val = valCastLiteral(type, floatFromVal(val));
644 switch (getSize (type)) {
647 tfprintf (oFile, "\t!db !constbyte\n", 0);
649 tfprintf (oFile, "\t!dbs\n",
650 aopLiteral (val, 0));
654 if (port->use_dw_for_init)
655 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
656 else if (port->little_endian)
657 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
659 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
663 tfprintf (oFile, "\t!dw !constword\n", 0);
664 tfprintf (oFile, "\t!dw !constword\n", 0);
666 else if (port->little_endian) {
667 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
668 aopLiteral (val, 0), aopLiteral (val, 1),
669 aopLiteral (val, 2), aopLiteral (val, 3));
672 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
673 aopLiteral (val, 3), aopLiteral (val, 2),
674 aopLiteral (val, 1), aopLiteral (val, 0));
680 /*-----------------------------------------------------------------*/
681 /* printIvalBitFields - generate initializer for bitfields */
682 /*-----------------------------------------------------------------*/
683 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
687 initList *lilist = *ilist ;
688 unsigned long ival = 0;
694 val = list2val(lilist);
696 if (SPEC_BLEN(lsym->etype) > 8) {
697 size += ((SPEC_BLEN (lsym->etype) / 8) +
698 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
701 size = ((SPEC_BLEN (lsym->etype) / 8) +
702 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
704 i = (unsigned long)floatFromVal(val);
705 i <<= SPEC_BSTR (lsym->etype);
707 if (! ( lsym->next &&
708 (IS_BITFIELD(lsym->next->type)) &&
709 (SPEC_BSTR(lsym->next->etype)))) break;
711 lilist = lilist->next;
715 tfprintf (oFile, "\t!db !constbyte\n",ival);
719 tfprintf (oFile, "\t!dw !constword\n",ival);
721 case 4: /* EEP: why is this db and not dw? */
722 tfprintf (oFile, "\t!db !constword,!constword\n",
723 (ival >> 8) & 0xffff, (ival & 0xffff));
730 /*-----------------------------------------------------------------*/
731 /* printIvalStruct - generates initial value for structures */
732 /*-----------------------------------------------------------------*/
734 printIvalStruct (symbol * sym, sym_link * type,
735 initList * ilist, FILE * oFile)
740 sflds = SPEC_STRUCT (type)->fields;
741 if (ilist->type != INIT_DEEP) {
742 werror (E_INIT_STRUCT, sym->name);
746 iloop = ilist->init.deep;
748 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
749 if (IS_BITFIELD(sflds->type)) {
750 printIvalBitFields(&sflds,&iloop,oFile);
752 printIval (sym, sflds->type, iloop, oFile);
756 werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
761 /*-----------------------------------------------------------------*/
762 /* printIvalChar - generates initital value for character array */
763 /*-----------------------------------------------------------------*/
765 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
773 val = list2val (ilist);
774 /* if the value is a character string */
775 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
777 if (!DCL_ELEM (type))
778 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
780 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
782 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
784 tfprintf (oFile, "\t!db !constbyte\n", 0);
792 printChar (oFile, s, strlen (s) + 1);
796 /*-----------------------------------------------------------------*/
797 /* printIvalArray - generates code for array initialization */
798 /*-----------------------------------------------------------------*/
800 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
806 /* take care of the special case */
807 /* array of characters can be init */
809 if (IS_CHAR (type->next)) {
810 if (!IS_LITERAL(list2val(ilist)->etype)) {
811 werror (E_CONST_EXPECTED);
814 if (printIvalChar (type,
815 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
816 oFile, SPEC_CVAL (sym->etype).v_char))
819 /* not the special case */
820 if (ilist->type != INIT_DEEP)
822 werror (E_INIT_STRUCT, sym->name);
826 for (iloop=ilist->init.deep; iloop; iloop=iloop->next)
828 printIval (sym, type->next, iloop, oFile);
830 if (++size > DCL_ELEM(type)) {
831 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
836 if (DCL_ELEM(type)) {
837 // pad with zeros if needed
838 if (size<DCL_ELEM(type)) {
839 size = (DCL_ELEM(type) - size) * getSize(type->next);
841 tfprintf (oFile, "\t!db !constbyte\n", 0);
845 // we have not been given a size, but we now know it
846 DCL_ELEM (type) = size;
852 /*-----------------------------------------------------------------*/
853 /* printIvalFuncPtr - generate initial value for function pointers */
854 /*-----------------------------------------------------------------*/
856 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
861 val = list2val (ilist);
864 // an error has been thrown allready
868 if (IS_LITERAL(val->etype)) {
869 if (compareType(type,val->etype)==0) {
870 werror (E_INCOMPAT_TYPES);
871 printFromToType (val->type, type);
873 printIvalCharPtr (NULL, type, val, oFile);
877 /* check the types */
878 if ((dLvl = compareType (val->type, type->next)) <= 0)
880 tfprintf (oFile, "\t!dw !constword\n", 0);
884 /* now generate the name */
887 if (port->use_dw_for_init)
889 tfprintf (oFile, "\t!dws\n", val->name);
893 printPointerType (oFile, val->name);
896 else if (port->use_dw_for_init)
898 tfprintf (oFile, "\t!dws\n", val->sym->rname);
902 printPointerType (oFile, val->sym->rname);
908 /*-----------------------------------------------------------------*/
909 /* printIvalCharPtr - generates initial values for character pointers */
910 /*-----------------------------------------------------------------*/
912 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
916 /* PENDING: this is _very_ mcs51 specific, including a magic
918 It's also endin specific.
920 size = getSize (type);
922 if (val->name && strlen (val->name))
924 if (size == 1) /* This appears to be Z80 specific?? */
927 "\t!dbs\n", val->name);
929 else if (size == FPTRSIZE)
931 if (port->use_dw_for_init)
933 tfprintf (oFile, "\t!dws\n", val->name);
937 printPointerType (oFile, val->name);
940 else if (size == GPTRSIZE)
943 if (IS_PTR (val->type)) {
944 type = DCL_TYPE (val->type);
946 type = PTR_TYPE (SPEC_OCLS (val->etype));
948 if (val->sym && val->sym->isstrlit) {
949 // this is a literal string
952 printGPointerType (oFile, val->name, sym->name, type);
956 fprintf (stderr, "*** internal error: unknown size in "
957 "printIvalCharPtr.\n");
962 // these are literals assigned to pointers
966 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
969 if (port->use_dw_for_init)
970 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
971 else if (port->little_endian)
972 tfprintf (oFile, "\t.byte %s,%s\n",
973 aopLiteral (val, 0), aopLiteral (val, 1));
975 tfprintf (oFile, "\t.byte %s,%s\n",
976 aopLiteral (val, 1), aopLiteral (val, 0));
979 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
980 // non-zero mcs51 generic pointer
981 werror (E_LITERAL_GENERIC);
983 if (port->little_endian) {
984 fprintf (oFile, "\t.byte %s,%s,%s\n",
987 aopLiteral (val, 2));
989 fprintf (oFile, "\t.byte %s,%s,%s\n",
992 aopLiteral (val, 0));
996 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
997 // non-zero ds390 generic pointer
998 werror (E_LITERAL_GENERIC);
1000 if (port->little_endian) {
1001 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
1002 aopLiteral (val, 0),
1003 aopLiteral (val, 1),
1004 aopLiteral (val, 2),
1005 aopLiteral (val, 3));
1007 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
1008 aopLiteral (val, 3),
1009 aopLiteral (val, 2),
1010 aopLiteral (val, 1),
1011 aopLiteral (val, 0));
1019 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1020 addSet (&statsg->syms, val->sym);
1026 /*-----------------------------------------------------------------*/
1027 /* printIvalPtr - generates initial value for pointers */
1028 /*-----------------------------------------------------------------*/
1030 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1036 if (ilist->type == INIT_DEEP)
1037 ilist = ilist->init.deep;
1039 /* function pointer */
1040 if (IS_FUNC (type->next))
1042 printIvalFuncPtr (type, ilist, oFile);
1046 if (!(val = initPointer (ilist, type)))
1049 /* if character pointer */
1050 if (IS_CHAR (type->next))
1051 if (printIvalCharPtr (sym, type, val, oFile))
1054 /* check the type */
1055 if (compareType (type, val->type) == 0) {
1056 werror (W_INIT_WRONG);
1057 printFromToType (val->type, type);
1060 /* if val is literal */
1061 if (IS_LITERAL (val->etype))
1063 switch (getSize (type))
1066 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
1069 if (port->use_dw_for_init)
1070 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
1071 else if (port->little_endian)
1072 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1074 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1076 case 3: // how about '390??
1077 if (port->little_endian)
1079 fprintf (oFile, "\t.byte %s,%s,#0x%d\n",
1080 aopLiteral (val, 0), aopLiteral (val, 1), GPTYPE_CODE);
1084 fprintf (oFile, "\t.byte %s,%s,#0x%d\n",
1085 aopLiteral (val, 1), aopLiteral (val, 0), GPTYPE_CODE);
1092 size = getSize (type);
1094 if (size == 1) /* Z80 specific?? */
1096 tfprintf (oFile, "\t!dbs\n", val->name);
1098 else if (size == FPTRSIZE)
1100 if (port->use_dw_for_init) {
1101 tfprintf (oFile, "\t!dws\n", val->name);
1103 printPointerType (oFile, val->name);
1106 else if (size == GPTRSIZE)
1108 printGPointerType (oFile, val->name, sym->name,
1109 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1110 PTR_TYPE (SPEC_OCLS (val->etype))));
1115 /*-----------------------------------------------------------------*/
1116 /* printIval - generates code for initial value */
1117 /*-----------------------------------------------------------------*/
1119 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1126 /* update line number for error msgs */
1127 lineno=sym->lineDef;
1129 /* if structure then */
1130 if (IS_STRUCT (type))
1132 printIvalStruct (sym, type, ilist, oFile);
1136 /* if this is an array */
1137 if (IS_ARRAY (type))
1139 printIvalArray (sym, type, ilist, oFile);
1143 // not an aggregate, ilist must be a node
1144 if (ilist->type!=INIT_NODE) {
1145 // or a 1-element list
1146 if (ilist->init.deep->next) {
1147 werror (W_EXCESS_INITIALIZERS, "scalar",
1148 sym->name, sym->lineDef);
1150 ilist=ilist->init.deep;
1154 // and the type must match
1155 itype=ilist->init.node->ftype;
1157 if (compareType(type, itype)==0) {
1158 // special case for literal strings
1159 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1160 // which are really code pointers
1161 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1164 werror (E_TYPE_MISMATCH, "assignment", " ");
1165 printFromToType(itype, type);
1169 /* if this is a pointer */
1172 printIvalPtr (sym, type, ilist, oFile);
1176 /* if type is SPECIFIER */
1179 printIvalType (sym, type, ilist, oFile);
1184 /*-----------------------------------------------------------------*/
1185 /* emitStaticSeg - emitcode for the static segment */
1186 /*-----------------------------------------------------------------*/
1188 emitStaticSeg (memmap * map, FILE * out)
1192 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1194 /* for all variables in this segment do */
1195 for (sym = setFirstItem (map->syms); sym;
1196 sym = setNextItem (map->syms))
1199 /* if it is "extern" then do nothing */
1200 if (IS_EXTERN (sym->etype))
1203 /* if it is not static add it to the public
1205 if (!IS_STATIC (sym->etype))
1207 addSetHead (&publics, sym);
1210 /* print extra debug info if required */
1211 if (options.debug) {
1215 if (IS_STATIC (sym->etype))
1216 fprintf (out, "F%s$", moduleName); /* scope is file */
1218 fprintf (out, "G$"); /* scope is global */
1221 /* symbol is local */
1222 fprintf (out, "L%s$",
1223 (sym->localof ? sym->localof->name : "-null-"));
1224 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
1227 /* if it has an absolute address */
1228 if (SPEC_ABSA (sym->etype))
1231 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1233 fprintf (out, "%s\t=\t0x%04x\n",
1235 SPEC_ADDR (sym->etype));
1240 fprintf (out, " == .\n");
1242 /* if it has an initial value */
1245 fprintf (out, "%s:\n", sym->rname);
1247 resolveIvalSym (sym->ival);
1248 printIval (sym, sym->type, sym->ival, out);
1250 /* if sym is a simple string and sym->ival is a string,
1251 WE don't need it anymore */
1252 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1253 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1254 list2val(sym->ival)->sym->isstrlit) {
1255 freeStringSymbol(list2val(sym->ival)->sym);
1259 /* allocate space */
1260 int size = getSize (sym->type);
1263 werror(E_UNKNOWN_SIZE,sym->name);
1265 fprintf (out, "%s:\n", sym->rname);
1266 /* special case for character strings */
1267 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1268 SPEC_CVAL (sym->etype).v_char)
1270 SPEC_CVAL (sym->etype).v_char,
1271 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1273 tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff);
1279 /*-----------------------------------------------------------------*/
1280 /* emitMaps - emits the code for the data portion the code */
1281 /*-----------------------------------------------------------------*/
1286 /* no special considerations for the following
1287 data, idata & bit & xdata */
1288 emitRegularMap (data, TRUE, TRUE);
1289 emitRegularMap (idata, TRUE, TRUE);
1290 emitRegularMap (bit, TRUE, FALSE);
1291 emitRegularMap (xdata, TRUE, TRUE);
1292 if (port->genXINIT) {
1293 emitRegularMap (xidata, TRUE, TRUE);
1295 emitRegularMap (sfr, FALSE, FALSE);
1296 emitRegularMap (sfrbit, FALSE, FALSE);
1297 emitRegularMap (home, TRUE, FALSE);
1298 emitRegularMap (code, TRUE, FALSE);
1300 emitStaticSeg (statsg, code->oFile);
1301 if (port->genXINIT) {
1302 tfprintf (code->oFile, "\t!area\n", xinit->sname);
1303 emitStaticSeg (xinit, code->oFile);
1308 /*-----------------------------------------------------------------*/
1309 /* flushStatics - flush all currently defined statics out to file */
1310 /* and delete. Temporary function */
1311 /*-----------------------------------------------------------------*/
1315 emitStaticSeg (statsg, codeOutFile);
1316 statsg->syms = NULL;
1319 /*-----------------------------------------------------------------*/
1320 /* createInterruptVect - creates the interrupt vector */
1321 /*-----------------------------------------------------------------*/
1323 createInterruptVect (FILE * vFile)
1326 mainf = newSymbol ("main", 0);
1329 /* only if the main function exists */
1330 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1332 if (!options.cc_only && !noAssemble && !options.c1mode)
1337 /* if the main is only a prototype ie. no body then do nothing */
1338 if (!IFFUNC_HASBODY(mainf->type))
1340 /* if ! compile only then main function should be present */
1341 if (!options.cc_only && !noAssemble)
1346 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1347 fprintf (vFile, "__interrupt_vect:\n");
1350 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1352 /* "generic" interrupt table header (if port doesn't specify one).
1353 * Look suspiciously like 8051 code to me...
1356 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1359 /* now for the other interrupts */
1360 for (; i < maxInterrupts; i++)
1363 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1365 fprintf (vFile, "\treti\n\t.ds\t7\n");
1372 ";--------------------------------------------------------\n"
1373 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1377 ";--------------------------------------------------------\n"};
1380 /*-----------------------------------------------------------------*/
1381 /* initialComments - puts in some initial comments */
1382 /*-----------------------------------------------------------------*/
1384 initialComments (FILE * afile)
1388 fprintf (afile, "%s", iComments1);
1389 fprintf (afile, "; Version " SDCC_VERSION_STR " %s\n", asctime (localtime (&t)));
1390 fprintf (afile, "%s", iComments2);
1393 /*-----------------------------------------------------------------*/
1394 /* printPublics - generates .global for publics */
1395 /*-----------------------------------------------------------------*/
1397 printPublics (FILE * afile)
1401 fprintf (afile, "%s", iComments2);
1402 fprintf (afile, "; Public variables in this module\n");
1403 fprintf (afile, "%s", iComments2);
1405 for (sym = setFirstItem (publics); sym;
1406 sym = setNextItem (publics))
1407 tfprintf (afile, "\t!global\n", sym->rname);
1410 /*-----------------------------------------------------------------*/
1411 /* printExterns - generates .global for externs */
1412 /*-----------------------------------------------------------------*/
1414 printExterns (FILE * afile)
1418 fprintf (afile, "%s", iComments2);
1419 fprintf (afile, "; Externals used\n");
1420 fprintf (afile, "%s", iComments2);
1422 for (sym = setFirstItem (externs); sym;
1423 sym = setNextItem (externs))
1424 tfprintf (afile, "\t!extern\n", sym->rname);
1427 /*-----------------------------------------------------------------*/
1428 /* emitOverlay - will emit code for the overlay stuff */
1429 /*-----------------------------------------------------------------*/
1431 emitOverlay (FILE * afile)
1435 if (!elementsInSet (ovrSetSets))
1436 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1438 /* for each of the sets in the overlay segment do */
1439 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1440 ovrset = setNextItem (ovrSetSets))
1445 if (elementsInSet (ovrset))
1447 /* output the area informtion */
1448 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1451 for (sym = setFirstItem (ovrset); sym;
1452 sym = setNextItem (ovrset))
1454 /* if extern then it is in the publics table: do nothing */
1455 if (IS_EXTERN (sym->etype))
1458 /* if allocation required check is needed
1459 then check if the symbol really requires
1460 allocation only for local variables */
1461 if (!IS_AGGREGATE (sym->type) &&
1462 !(sym->_isparm && !IS_REGPARM (sym->etype))
1463 && !sym->allocreq && sym->level)
1466 /* if global variable & not static or extern
1467 and addPublics allowed then add it to the public set */
1468 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1469 && !IS_STATIC (sym->etype))
1471 addSetHead (&publics, sym);
1474 /* if extern then do nothing or is a function
1476 if (IS_FUNC (sym->type))
1479 /* print extra debug info if required */
1484 if (IS_STATIC (sym->etype))
1485 fprintf (afile, "F%s$", moduleName); /* scope is file */
1487 fprintf (afile, "G$"); /* scope is global */
1490 /* symbol is local */
1491 fprintf (afile, "L%s$",
1492 (sym->localof ? sym->localof->name : "-null-"));
1493 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1496 /* if is has an absolute address then generate
1497 an equate for this no need to allocate space */
1498 if (SPEC_ABSA (sym->etype))
1502 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1504 fprintf (afile, "%s\t=\t0x%04x\n",
1506 SPEC_ADDR (sym->etype));
1509 int size = getSize(sym->type);
1512 werror(E_UNKNOWN_SIZE,sym->name);
1515 fprintf (afile, "==.\n");
1517 /* allocate space */
1518 tfprintf (afile, "!labeldef\n", sym->rname);
1519 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1527 /*-----------------------------------------------------------------*/
1528 /* spacesToUnderscores - replace spaces with underscores */
1529 /*-----------------------------------------------------------------*/
1531 spacesToUnderscores (char *dest, const char *src, size_t len)
1536 assert(dest != NULL);
1537 assert(src != NULL);
1541 for (p = dest, i = 0; *src != '\0' && i < len; ++src, ++i) {
1542 *p++ = isspace(*src) ? '_' : *src;
1550 /*-----------------------------------------------------------------*/
1551 /* glue - the final glue that hold the whole thing together */
1552 /*-----------------------------------------------------------------*/
1558 FILE *ovrFile = tempfile ();
1559 char moduleBuf[PATH_MAX];
1562 if(port->general.glue_up_main &&
1563 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400))
1565 mcs51_like=1; /*So it has bits, sfr, sbits, data, idata, etc...*/
1572 addSetHead (&tmpfileSet, ovrFile);
1573 /* print the global struct definitions */
1577 vFile = tempfile ();
1578 /* PENDING: this isnt the best place but it will do */
1579 if (port->general.glue_up_main)
1581 /* create the interrupt vector table */
1582 createInterruptVect (vFile);
1585 addSetHead (&tmpfileSet, vFile);
1587 /* emit code for the all the variables declared */
1589 /* do the overlay segments */
1590 emitOverlay (ovrFile);
1592 outputDebugSymbols();
1594 /* now put it all together into the assembler file */
1595 /* create the assembler file name */
1597 /* -o option overrides default name? */
1598 if ((noAssemble || options.c1mode) && fullDstFileName)
1600 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1604 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1605 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1608 if (!(asmFile = fopen (scratchFileName, "w")))
1610 werror (E_FILE_OPEN_ERR, scratchFileName);
1614 /* initial comments */
1615 initialComments (asmFile);
1617 /* print module name */
1618 tfprintf (asmFile, "\t!module\n",
1619 spacesToUnderscores (moduleBuf, moduleName, sizeof moduleBuf));
1622 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1624 switch(options.model)
1626 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1627 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1628 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1629 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1630 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1631 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1634 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1635 if(options.useXstack) fprintf (asmFile, " --xstack");
1636 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1637 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1638 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1639 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1640 fprintf (asmFile, "\n");
1642 else if(TARGET_IS_Z80 || TARGET_IS_GBZ80 )
1644 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1647 tfprintf (asmFile, "\t!fileprelude\n");
1649 /* Let the port generate any global directives, etc. */
1650 if (port->genAssemblerPreamble)
1652 port->genAssemblerPreamble (asmFile);
1655 /* print the global variables in this module */
1656 printPublics (asmFile);
1657 if (port->assembler.externGlobal)
1658 printExterns (asmFile);
1661 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1663 /* copy the sfr segment */
1664 fprintf (asmFile, "%s", iComments2);
1665 fprintf (asmFile, "; special function registers\n");
1666 fprintf (asmFile, "%s", iComments2);
1667 copyFile (asmFile, sfr->oFile);
1672 /* copy the sbit segment */
1673 fprintf (asmFile, "%s", iComments2);
1674 fprintf (asmFile, "; special function bits \n");
1675 fprintf (asmFile, "%s", iComments2);
1676 copyFile (asmFile, sfrbit->oFile);
1678 /*JCF: Create the areas for the register banks*/
1679 if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3])
1681 fprintf (asmFile, "%s", iComments2);
1682 fprintf (asmFile, "; overlayable register banks \n");
1683 fprintf (asmFile, "%s", iComments2);
1685 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1686 if(RegBankUsed[1]||options.parms_in_bank1)
1687 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1689 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1691 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1695 /* copy the data segment */
1696 fprintf (asmFile, "%s", iComments2);
1697 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1698 fprintf (asmFile, "%s", iComments2);
1699 copyFile (asmFile, data->oFile);
1702 /* create the overlay segments */
1704 fprintf (asmFile, "%s", iComments2);
1705 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1706 fprintf (asmFile, "%s", iComments2);
1707 copyFile (asmFile, ovrFile);
1710 /* create the stack segment MOF */
1711 if (mainf && IFFUNC_HASBODY(mainf->type))
1713 fprintf (asmFile, "%s", iComments2);
1714 fprintf (asmFile, "; Stack segment in internal ram \n");
1715 fprintf (asmFile, "%s", iComments2);
1716 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1717 "__start__stack:\n\t.ds\t1\n\n");
1720 /* create the idata segment */
1721 if ( (idata) && (mcs51_like) ) {
1722 fprintf (asmFile, "%s", iComments2);
1723 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1724 fprintf (asmFile, "%s", iComments2);
1725 copyFile (asmFile, idata->oFile);
1728 /* copy the bit segment */
1730 fprintf (asmFile, "%s", iComments2);
1731 fprintf (asmFile, "; bit data\n");
1732 fprintf (asmFile, "%s", iComments2);
1733 copyFile (asmFile, bit->oFile);
1736 /* if external stack then reserve space of it */
1737 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1739 fprintf (asmFile, "%s", iComments2);
1740 fprintf (asmFile, "; external stack \n");
1741 fprintf (asmFile, "%s", iComments2);
1742 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1743 fprintf (asmFile, "\t.ds 256\n");
1747 /* copy xtern ram data */
1749 fprintf (asmFile, "%s", iComments2);
1750 fprintf (asmFile, "; external ram data\n");
1751 fprintf (asmFile, "%s", iComments2);
1752 copyFile (asmFile, xdata->oFile);
1755 /* copy xternal initialized ram data */
1756 fprintf (asmFile, "%s", iComments2);
1757 fprintf (asmFile, "; external initialized ram data\n");
1758 fprintf (asmFile, "%s", iComments2);
1759 copyFile (asmFile, xidata->oFile);
1761 /* If the port wants to generate any extra areas, let it do so. */
1762 if (port->extraAreas.genExtraAreaDeclaration)
1764 port->extraAreas.genExtraAreaDeclaration(asmFile,
1765 mainf && IFFUNC_HASBODY(mainf->type));
1768 /* copy the interrupt vector table */
1769 if (mainf && IFFUNC_HASBODY(mainf->type))
1771 fprintf (asmFile, "%s", iComments2);
1772 fprintf (asmFile, "; interrupt vector \n");
1773 fprintf (asmFile, "%s", iComments2);
1774 copyFile (asmFile, vFile);
1777 /* copy global & static initialisations */
1778 fprintf (asmFile, "%s", iComments2);
1779 fprintf (asmFile, "; global & static initialisations\n");
1780 fprintf (asmFile, "%s", iComments2);
1782 /* Everywhere we generate a reference to the static_name area,
1783 * (which is currently only here), we immediately follow it with a
1784 * definition of the post_static_name area. This guarantees that
1785 * the post_static_name area will immediately follow the static_name
1788 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1789 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1790 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1792 if (mainf && IFFUNC_HASBODY(mainf->type))
1794 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1795 /* if external stack is specified then the
1796 higher order byte of the xdatalocation is
1797 going into P2 and the lower order going into
1799 if (options.useXstack)
1801 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1802 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1803 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1804 (unsigned int) options.xdata_loc & 0xff);
1807 // This should probably be a port option, but I'm being lazy.
1808 // on the 400, the firmware boot loader gives us a valid stack
1809 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1810 if (!TARGET_IS_DS400)
1812 /* initialise the stack pointer. JCF: aslink takes care of the location */
1813 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1816 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1817 fprintf (asmFile, "\tmov\ta,dpl\n");
1818 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1819 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1820 fprintf (asmFile, "__sdcc_init_data:\n");
1822 // if the port can copy the XINIT segment to XISEG
1823 if (port->genXINIT) {
1824 port->genXINIT(asmFile);
1828 copyFile (asmFile, statsg->oFile);
1830 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1832 /* This code is generated in the post-static area.
1833 * This area is guaranteed to follow the static area
1834 * by the ugly shucking and jiving about 20 lines ago.
1836 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1837 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1843 "%s", iComments2, iComments2);
1844 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1845 copyFile (asmFile, home->oFile);
1847 /* copy over code */
1848 fprintf (asmFile, "%s", iComments2);
1849 fprintf (asmFile, "; code\n");
1850 fprintf (asmFile, "%s", iComments2);
1851 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1852 if (mainf && IFFUNC_HASBODY(mainf->type))
1855 /* entry point @ start of CSEG */
1856 fprintf (asmFile, "__sdcc_program_startup:\n");
1858 /* put in the call to main */
1859 fprintf (asmFile, "\tlcall\t_main\n");
1860 if (options.mainreturn)
1863 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1864 fprintf (asmFile, "\tret\n");
1870 fprintf (asmFile, ";\treturn from main will lock up\n");
1871 fprintf (asmFile, "\tsjmp .\n");
1874 copyFile (asmFile, code->oFile);
1876 if (port->genAssemblerEnd) {
1877 port->genAssemblerEnd(asmFile);
1885 /** Creates a temporary file with unoque file name
1887 - TMP, TEMP, TMPDIR env. varibles
1888 - if Un*x system: /usr/tmp and /tmp
1889 - root directory using mkstemp() if avaliable
1890 - default location using tempnam()
1893 tempfileandname(char *fname, size_t len)
1895 #define TEMPLATE "sdccXXXXXX"
1896 #define TEMPLATE_LEN ((sizeof TEMPLATE) - 1)
1898 const char *tmpdir = NULL;
1901 if ((tmpdir = getenv ("TMP")) == NULL)
1902 if ((tmpdir = getenv ("TEMP")) == NULL)
1903 tmpdir = getenv ("TMPDIR");
1907 static int warning_emitted;
1912 if (!warning_emitted)
1914 fprintf (stderr, "TMP not defined in environment, using %s for temporary files\n.", tmpdir);
1915 warning_emitted = 1;
1921 /* try with /usr/tmp and /tmp on Un*x systems */
1922 struct stat statbuf;
1924 if (tmpdir == NULL) {
1925 if (stat("/usr/tmp", &statbuf) != -1)
1926 tmpdir = "/usr/tmp";
1927 else if (stat("/tmp", &statbuf) != -1)
1935 char fnamebuf[PATH_MAX];
1938 if (fname == NULL || len == 0) {
1940 len = sizeof fnamebuf;
1944 name_len = strlen(tmpdir) + 1 + TEMPLATE_LEN;
1946 assert(name_len < len);
1947 if (!(name_len < len)) /* in NDEBUG is defined */
1948 return -1; /* buffer too small, temporary file can not be created */
1950 sprintf(fname, "%s" DIR_SEPARATOR_STRING TEMPLATE, tmpdir);
1953 name_len = TEMPLATE_LEN;
1955 assert(name_len < len);
1956 if (!(name_len < len)) /* in NDEBUG is defined */
1957 return -1; /* buffer too small, temporary file can not be created */
1959 strcpy(fname, TEMPLATE);
1962 fd = mkstemp(fname);
1966 char *name = tempnam(tmpdir, "sdcc");
1969 perror("Can't create temporary file name");
1973 assert(strlen(name) < len);
1974 if (!(strlen(name) < len)) /* in NDEBUG is defined */
1975 return -1; /* buffer too small, temporary file can not be created */
1977 strcpy(fname, name);
1979 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE);
1981 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
1987 perror("Can't create temporary file");
1995 /** Create a temporary file name
2001 static char fnamebuf[PATH_MAX];
2003 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
2004 fprintf(stderr, "Can't create temporary file name!");
2015 /** Create a temporary file and add it to tmpfileNameSet,
2016 so that it is removed explicitly by rm_tmpfiles()
2017 or implicitly at program extit.
2025 char fnamebuf[PATH_MAX];
2027 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
2028 fprintf(stderr, "Can't create temporary file!");
2032 tmp = Safe_strdup(fnamebuf);
2034 addSetHead(&tmpfileNameSet, tmp);
2036 if ((fp = fdopen(fd, "w+b")) == NULL) {
2037 perror("Can't create temporary file!");