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 -------------------------------------------------------------------------*/
31 #include "dbuf_string.h"
39 symbol *interrupts[INTNO_MAX+1];
41 void printIval (symbol *, sym_link *, initList *, struct dbuf_s *);
42 set *publics = NULL; /* public variables */
43 set *externs = NULL; /* Variables that are declared as extern */
45 unsigned maxInterrupts = 0;
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)
104 aopLiteralLong (value * val, int offset, int size)
113 // assuming we have been warned before
117 /* if it is a float then it gets tricky */
118 /* otherwise it is fairly simple */
119 if (!IS_FLOAT (val->type)) {
120 unsigned long v = (unsigned long) floatFromVal (val);
125 tsprintf (buffer, sizeof(buffer),
126 "!immedbyte", (unsigned int) v & 0xff);
129 tsprintf (buffer, sizeof(buffer),
130 "!immedword", (unsigned int) v & 0xffff);
133 /* Hmm. Too big for now. */
136 return Safe_strdup (buffer);
139 /* PENDING: For now size must be 1 */
142 /* it is type float */
143 fl.f = (float) floatFromVal (val);
144 #ifdef WORDS_BIGENDIAN
145 tsprintf (buffer, sizeof(buffer),
146 "!immedbyte", fl.c[3 - offset]);
148 tsprintf (buffer, sizeof(buffer),
149 "!immedbyte", fl.c[offset]);
151 return Safe_strdup (buffer);
154 /*-----------------------------------------------------------------*/
155 /* aopLiteral - string from a literal value */
156 /*-----------------------------------------------------------------*/
158 aopLiteral (value * val, int offset)
160 return aopLiteralLong (val, offset, 1);
163 /*-----------------------------------------------------------------*/
164 /* emitRegularMap - emit code for maps with no special cases */
165 /*-----------------------------------------------------------------*/
167 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
177 /* PENDING: special case here - should remove */
178 if (!strcmp (map->sname, CODE_NAME))
179 dbuf_tprintf (&map->oBuf, "\t!areacode\n", map->sname);
180 else if (!strcmp (map->sname, DATA_NAME))
181 dbuf_tprintf (&map->oBuf, "\t!areadata\n", map->sname);
182 else if (!strcmp (map->sname, HOME_NAME))
183 dbuf_tprintf (&map->oBuf, "\t!areahome\n", map->sname);
185 dbuf_tprintf (&map->oBuf, "\t!area\n", map->sname);
188 for (sym = setFirstItem (map->syms); sym;
189 sym = setNextItem (map->syms))
193 /* if extern then add it into the extern list */
194 if (IS_EXTERN (sym->etype))
196 addSetHead (&externs, sym);
200 /* if allocation required check is needed
201 then check if the symbol really requires
202 allocation only for local variables */
204 if (arFlag && !IS_AGGREGATE (sym->type) &&
205 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
206 !sym->allocreq && sym->level)
209 /* for bitvar locals and parameters */
210 if (!arFlag && !sym->allocreq && sym->level
211 && !SPEC_ABSA (sym->etype)) {
215 /* if global variable & not static or extern
216 and addPublics allowed then add it to the public set */
217 if ((sym->level == 0 ||
218 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
220 !IS_STATIC (sym->etype) &&
221 (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
223 addSetHead (&publics, sym);
226 /* if extern then do nothing or is a function
228 if (IS_FUNC (sym->type) && !(sym->isitmp))
231 /* print extra debug info if required */
234 if (!sym->level) /* global */
236 if (IS_STATIC (sym->etype))
237 dbuf_printf (&map->oBuf, "F%s$", moduleName); /* scope is file */
239 dbuf_printf (&map->oBuf, "G$"); /* scope is global */
243 /* symbol is local */
244 dbuf_printf (&map->oBuf, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
246 dbuf_printf (&map->oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
249 /* if it has an initial value then do it only if
250 it is a global variable */
251 if (sym->ival && sym->level == 0) {
252 if ((SPEC_OCLS(sym->etype)==xidata) && !SPEC_ABSA (sym->etype)) {
253 /* create a new "XINIT (CODE)" symbol, that will be emitted later
255 newSym=copySymbol (sym);
256 SPEC_OCLS(newSym->etype)=xinit;
257 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
258 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
259 if (IS_SPEC (newSym->type))
260 SPEC_CONST (newSym->type) = 1;
262 DCL_PTR_CONST (newSym->type) = 1;
263 SPEC_STAT(newSym->etype)=1;
264 resolveIvalSym(newSym->ival, newSym->type);
266 // add it to the "XINIT (CODE)" segment
267 addSet(&xinit->syms, newSym);
269 if (!SPEC_ABSA (sym->etype))
271 struct dbuf_s tmpBuf;
273 dbuf_init(&tmpBuf, 4096);
274 // before allocation we must parse the sym->ival tree
275 // but without actually generating initialization code
277 resolveIvalSym (sym->ival, sym->type);
278 printIval (sym, sym->type, sym->ival, &tmpBuf);
280 dbuf_destroy(&tmpBuf);
283 if (IS_AGGREGATE (sym->type)) {
284 ival = initAggregates (sym, sym->ival, NULL);
286 if (getNelements(sym->type, sym->ival)>1) {
287 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
290 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
291 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
293 codeOutBuf = &statsg->oBuf;
296 // set ival's lineno to where the symbol was defined
297 setAstLineno (ival, lineno=sym->lineDef);
298 // check if this is not a constant expression
299 if (!constExprTree(ival)) {
300 werror (E_CONST_EXPECTED, "found expression");
301 // but try to do it anyway
304 if (!astErrors(ival))
305 eBBlockFromiCode (iCodeFromAst (ival));
311 /* if it has an absolute address then generate
312 an equate for this no need to allocate space */
313 if (SPEC_ABSA (sym->etype) && !sym->ival)
317 dbuf_printf (&map->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
319 if (TARGET_IS_XA51) {
322 } else if (map==bit || map==sfrbit) {
326 dbuf_printf (&map->oBuf, "%s\t%s\t0x%04x\n",
328 SPEC_ADDR (sym->etype));
332 int size = getSize (sym->type) + sym->flexArrayLength;
334 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
338 dbuf_printf (&map->oBuf, "==.\n");
340 if (SPEC_ABSA (sym->etype))
342 dbuf_tprintf (&map->oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
344 if (IS_STATIC (sym->etype) || sym->level)
345 dbuf_tprintf (&map->oBuf, "!slabeldef\n", sym->rname);
347 dbuf_tprintf (&map->oBuf, "!labeldef\n", sym->rname);
348 dbuf_tprintf (&map->oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
354 /*-----------------------------------------------------------------*/
355 /* initPointer - pointer initialization code massaging */
356 /*-----------------------------------------------------------------*/
358 initPointer (initList * ilist, sym_link *toType)
364 return valCastLiteral(toType, 0.0);
367 expr = list2expr (ilist);
372 /* try it the old way first */
373 if ((val = constExprValue (expr, FALSE)))
376 /* ( ptr + constant ) */
377 if (IS_AST_OP (expr) &&
378 (expr->opval.op == '+' || expr->opval.op == '-') &&
379 IS_AST_SYM_VALUE (expr->left) &&
380 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
381 compareType(toType, expr->left->ftype) &&
382 IS_AST_LIT_VALUE (expr->right)) {
383 return valForCastAggr (expr->left, expr->left->ftype,
389 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
390 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
391 if (compareType(toType, expr->left->ftype)!=1) {
392 werror (W_INIT_WRONG);
393 printFromToType(expr->left->ftype, toType);
399 /* no then we have to do these cludgy checks */
400 /* pointers can be initialized with address of
401 a variable or address of an array element */
402 if (IS_AST_OP (expr) && expr->opval.op == '&') {
403 /* address of symbol */
404 if (IS_AST_SYM_VALUE (expr->left)) {
405 val = AST_VALUE (expr->left);
406 val->type = newLink (DECLARATOR);
407 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
408 DCL_TYPE (val->type) = CPOINTER;
409 DCL_PTR_CONST (val->type) = port->mem.code_ro;
411 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
412 DCL_TYPE (val->type) = FPOINTER;
413 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
414 DCL_TYPE (val->type) = PPOINTER;
415 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
416 DCL_TYPE (val->type) = IPOINTER;
417 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
418 DCL_TYPE (val->type) = EEPPOINTER;
420 DCL_TYPE (val->type) = POINTER;
421 val->type->next = expr->left->ftype;
422 val->etype = getSpec (val->type);
426 /* if address of indexed array */
427 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
428 return valForArray (expr->left);
430 /* if address of structure element then
432 if (IS_AST_OP (expr->left) &&
433 expr->left->opval.op == '.') {
434 return valForStructElem (expr->left->left,
439 (&some_struct)->element */
440 if (IS_AST_OP (expr->left) &&
441 expr->left->opval.op == PTR_OP &&
442 IS_ADDRESS_OF_OP (expr->left->left)) {
443 return valForStructElem (expr->left->left->left,
447 /* case 3. (((char *) &a) +/- constant) */
448 if (IS_AST_OP (expr) &&
449 (expr->opval.op == '+' || expr->opval.op == '-') &&
450 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
451 IS_AST_OP (expr->left->right) &&
452 expr->left->right->opval.op == '&' &&
453 IS_AST_LIT_VALUE (expr->right)) {
455 return valForCastAggr (expr->left->right->left,
456 expr->left->left->opval.lnk,
457 expr->right, expr->opval.op);
460 /* case 4. (char *)(array type) */
461 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
462 IS_ARRAY(expr->right->ftype)) {
464 val = copyValue (AST_VALUE (expr->right));
465 val->type = newLink (DECLARATOR);
466 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
467 DCL_TYPE (val->type) = CPOINTER;
468 DCL_PTR_CONST (val->type) = port->mem.code_ro;
470 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
471 DCL_TYPE (val->type) = FPOINTER;
472 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
473 DCL_TYPE (val->type) = PPOINTER;
474 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
475 DCL_TYPE (val->type) = IPOINTER;
476 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
477 DCL_TYPE (val->type) = EEPPOINTER;
479 DCL_TYPE (val->type) = POINTER;
480 val->type->next = expr->right->ftype->next;
481 val->etype = getSpec (val->type);
486 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
488 werror (E_INCOMPAT_PTYPES);
493 /*-----------------------------------------------------------------*/
494 /* printChar - formats and prints a characater string with DB */
495 /*-----------------------------------------------------------------*/
497 printChar (struct dbuf_s * oBuf, char *s, int plen)
505 while (len && pplen < plen)
508 while (i && pplen < plen)
510 if (*s < ' ' || *s == '\"' || *s=='\\')
514 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
515 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char)*s);
530 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
541 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
546 /*-----------------------------------------------------------------*/
547 /* return the generic pointer high byte for a given pointer type. */
548 /*-----------------------------------------------------------------*/
550 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
558 werror (E_CANNOT_USE_GENERIC_POINTER,
559 iname ? iname : "<null>",
560 oname ? oname : "<null>");
567 return GPTYPE_XSTACK;
569 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
577 /*-----------------------------------------------------------------*/
578 /* printPointerType - generates ival for pointer type */
579 /*-----------------------------------------------------------------*/
581 _printPointerType (struct dbuf_s * oBuf, const char *name)
583 if (options.model == MODEL_FLAT24)
585 if (port->little_endian)
586 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
588 dbuf_printf (oBuf, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
592 if (port->little_endian)
593 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8)", name, name);
595 dbuf_printf (oBuf, "\t.byte (%s >> 8),%s", name, name);
599 /*-----------------------------------------------------------------*/
600 /* printPointerType - generates ival for pointer type */
601 /*-----------------------------------------------------------------*/
603 printPointerType (struct dbuf_s * oBuf, const char *name)
605 _printPointerType (oBuf, name);
606 dbuf_printf (oBuf, "\n");
609 /*-----------------------------------------------------------------*/
610 /* printGPointerType - generates ival for generic pointer type */
611 /*-----------------------------------------------------------------*/
613 printGPointerType (struct dbuf_s * oBuf, const char *iname, const char *oname,
614 const unsigned int type)
616 _printPointerType (oBuf, iname);
617 dbuf_printf (oBuf, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
620 /*-----------------------------------------------------------------*/
621 /* printIvalType - generates ival for int/char */
622 /*-----------------------------------------------------------------*/
624 printIvalType (symbol *sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
628 /* if initList is deep */
629 if (ilist && (ilist->type == INIT_DEEP))
630 ilist = ilist->init.deep;
632 if (!(val = list2val (ilist))) {
633 // assuming a warning has been thrown
637 if (val->type != type) {
638 val = valCastLiteral(type, floatFromVal(val));
641 switch (getSize (type)) {
644 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
646 dbuf_tprintf (oBuf, "\t!dbs\n",
647 aopLiteral (val, 0));
651 if (port->use_dw_for_init)
652 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
653 else if (port->little_endian)
654 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
656 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
660 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
661 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
663 else if (port->little_endian) {
664 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
665 aopLiteral (val, 0), aopLiteral (val, 1),
666 aopLiteral (val, 2), aopLiteral (val, 3));
669 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
670 aopLiteral (val, 3), aopLiteral (val, 2),
671 aopLiteral (val, 1), aopLiteral (val, 0));
677 /*-----------------------------------------------------------------*/
678 /* printIvalBitFields - generate initializer for bitfields */
679 /*-----------------------------------------------------------------*/
680 void printIvalBitFields(symbol **sym, initList **ilist, struct dbuf_s * oBuf)
684 initList *lilist = *ilist ;
685 unsigned long ival = 0;
691 val = list2val(lilist);
693 if (SPEC_BLEN(lsym->etype) > 8) {
694 size += ((SPEC_BLEN (lsym->etype) / 8) +
695 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
698 size = ((SPEC_BLEN (lsym->etype) / 8) +
699 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
701 i = (unsigned long)floatFromVal(val);
702 i <<= SPEC_BSTR (lsym->etype);
704 if (! ( lsym->next &&
705 (IS_BITFIELD(lsym->next->type)) &&
706 (SPEC_BSTR(lsym->next->etype)))) break;
708 lilist = lilist->next;
712 dbuf_tprintf (oBuf, "\t!db !constbyte\n",ival);
716 dbuf_tprintf (oBuf, "\t!dw !constword\n",ival);
718 case 4: /* EEP: why is this db and not dw? */
719 dbuf_tprintf (oBuf, "\t!db !constword,!constword\n",
720 (ival >> 8) & 0xffff, (ival & 0xffff));
727 /*-----------------------------------------------------------------*/
728 /* printIvalStruct - generates initial value for structures */
729 /*-----------------------------------------------------------------*/
731 printIvalStruct (symbol * sym, sym_link * type,
732 initList * ilist, struct dbuf_s * oBuf)
735 initList *iloop = NULL;
737 sflds = SPEC_STRUCT (type)->fields;
740 if (ilist->type != INIT_DEEP) {
741 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
745 iloop = ilist->init.deep;
748 if (SPEC_STRUCT (type)->type == UNION) {
749 printIval (sym, sflds->type, iloop, oBuf);
752 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
753 if (IS_BITFIELD(sflds->type)) {
754 printIvalBitFields(&sflds, &iloop, oBuf);
756 printIval (sym, sflds->type, iloop, oBuf);
761 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
766 /*-----------------------------------------------------------------*/
767 /* printIvalChar - generates initital value for character array */
768 /*-----------------------------------------------------------------*/
770 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s)
773 unsigned int size = DCL_ELEM (type);
777 val = list2val (ilist);
778 /* if the value is a character string */
779 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
783 /* we have not been given a size, but now we know it */
784 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
785 /* but first check, if it's a flexible array */
786 if (sym && IS_STRUCT (sym->type))
787 sym->flexArrayLength = size;
789 DCL_ELEM (type) = size;
792 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
800 printChar (oBuf, s, strlen (s) + 1);
804 /*-----------------------------------------------------------------*/
805 /* printIvalArray - generates code for array initialization */
806 /*-----------------------------------------------------------------*/
808 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
809 struct dbuf_s * oBuf)
813 unsigned int size = 0;
816 /* take care of the special case */
817 /* array of characters can be init */
819 if (IS_CHAR (type->next)) {
820 val = list2val(ilist);
822 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
825 if (!IS_LITERAL(val->etype)) {
826 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
829 if (printIvalChar (sym, type,
830 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
831 oBuf, SPEC_CVAL (sym->etype).v_char))
834 /* not the special case */
835 if (ilist->type != INIT_DEEP) {
836 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
840 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
841 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
842 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
845 printIval (sym, type->next, iloop, oBuf);
849 if (DCL_ELEM(type)) {
850 // pad with zeros if needed
851 if (size<DCL_ELEM(type)) {
852 size = (DCL_ELEM(type) - size) * getSize(type->next);
854 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
858 /* we have not been given a size, but now we know it */
859 /* but first check, if it's a flexible array */
860 if (IS_STRUCT (sym->type))
861 sym->flexArrayLength = size * getSize (type->next);
863 DCL_ELEM (type) = size;
869 /*-----------------------------------------------------------------*/
870 /* printIvalFuncPtr - generate initial value for function pointers */
871 /*-----------------------------------------------------------------*/
873 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
879 val = list2val (ilist);
881 val = valCastLiteral(type, 0.0);
884 // an error has been thrown already
888 if (IS_LITERAL(val->etype)) {
889 if (compareType(type, val->etype) == 0) {
890 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
891 printFromToType (val->type, type);
893 printIvalCharPtr (NULL, type, val, oBuf);
897 /* check the types */
898 if ((dLvl = compareType (val->type, type->next)) <= 0)
900 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
904 /* now generate the name */
907 if (port->use_dw_for_init)
909 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
913 printPointerType (oBuf, val->name);
916 else if (port->use_dw_for_init)
918 dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
922 printPointerType (oBuf, val->sym->rname);
928 /*-----------------------------------------------------------------*/
929 /* printIvalCharPtr - generates initial values for character pointers */
930 /*-----------------------------------------------------------------*/
932 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
936 /* PENDING: this is _very_ mcs51 specific, including a magic
938 It's also endian specific.
940 size = getSize (type);
942 if (val->name && strlen (val->name))
944 if (size == 1) /* This appears to be Z80 specific?? */
947 "\t!dbs\n", val->name);
949 else if (size == FPTRSIZE)
951 if (port->use_dw_for_init)
953 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
957 printPointerType (oBuf, val->name);
960 else if (size == GPTRSIZE)
963 if (IS_PTR (val->type)) {
964 type = DCL_TYPE (val->type);
966 type = PTR_TYPE (SPEC_OCLS (val->etype));
968 if (val->sym && val->sym->isstrlit) {
969 // this is a literal string
972 printGPointerType (oBuf, val->name, sym->name, type);
976 fprintf (stderr, "*** internal error: unknown size in "
977 "printIvalCharPtr.\n");
982 // these are literals assigned to pointers
986 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
989 if (port->use_dw_for_init)
990 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
991 else if (port->little_endian)
992 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
993 aopLiteral (val, 0), aopLiteral (val, 1));
995 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
996 aopLiteral (val, 1), aopLiteral (val, 0));
999 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1000 // non-zero mcs51 generic pointer
1001 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1003 if (port->little_endian) {
1004 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1005 aopLiteral (val, 0),
1006 aopLiteral (val, 1),
1007 aopLiteral (val, 2));
1009 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1010 aopLiteral (val, 2),
1011 aopLiteral (val, 1),
1012 aopLiteral (val, 0));
1016 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1017 // non-zero ds390 generic pointer
1018 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1020 if (port->little_endian) {
1021 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1022 aopLiteral (val, 0),
1023 aopLiteral (val, 1),
1024 aopLiteral (val, 2),
1025 aopLiteral (val, 3));
1027 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1028 aopLiteral (val, 3),
1029 aopLiteral (val, 2),
1030 aopLiteral (val, 1),
1031 aopLiteral (val, 0));
1039 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1040 addSet (&statsg->syms, val->sym);
1046 /*-----------------------------------------------------------------*/
1047 /* printIvalPtr - generates initial value for pointers */
1048 /*-----------------------------------------------------------------*/
1050 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1056 if (ilist && (ilist->type == INIT_DEEP))
1057 ilist = ilist->init.deep;
1059 /* function pointer */
1060 if (IS_FUNC (type->next))
1062 printIvalFuncPtr (type, ilist, oBuf);
1066 if (!(val = initPointer (ilist, type)))
1069 /* if character pointer */
1070 if (IS_CHAR (type->next))
1071 if (printIvalCharPtr (sym, type, val, oBuf))
1074 /* check the type */
1075 if (compareType (type, val->type) == 0) {
1076 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1077 printFromToType (val->type, type);
1080 /* if val is literal */
1081 if (IS_LITERAL (val->etype))
1083 switch (getSize (type))
1086 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
1089 if (port->use_dw_for_init)
1090 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1091 else if (port->little_endian)
1092 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1094 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1096 case 3: // how about '390??
1097 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1098 if (port->little_endian)
1100 dbuf_printf (oBuf, "\t.byte %s,%s",
1101 aopLiteral (val, 0), aopLiteral (val, 1));
1105 dbuf_printf (oBuf, "\t.byte %s,%s",
1106 aopLiteral (val, 1), aopLiteral (val, 0));
1108 if (IS_GENPTR (val->type))
1109 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1110 else if (IS_PTR (val->type))
1111 dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1113 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1119 size = getSize (type);
1121 if (size == 1) /* Z80 specific?? */
1123 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1125 else if (size == FPTRSIZE)
1127 if (port->use_dw_for_init) {
1128 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1130 printPointerType (oBuf, val->name);
1133 else if (size == GPTRSIZE)
1135 printGPointerType (oBuf, val->name, sym->name,
1136 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1137 PTR_TYPE (SPEC_OCLS (val->etype))));
1142 /*-----------------------------------------------------------------*/
1143 /* printIval - generates code for initial value */
1144 /*-----------------------------------------------------------------*/
1146 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1150 /* if structure then */
1151 if (IS_STRUCT (type))
1153 printIvalStruct (sym, type, ilist, oBuf);
1157 /* if this is an array */
1158 if (IS_ARRAY (type))
1160 printIvalArray (sym, type, ilist, oBuf);
1166 // not an aggregate, ilist must be a node
1167 if (ilist->type!=INIT_NODE) {
1168 // or a 1-element list
1169 if (ilist->init.deep->next) {
1170 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1173 ilist=ilist->init.deep;
1177 // and the type must match
1178 itype=ilist->init.node->ftype;
1180 if (compareType(type, itype)==0) {
1181 // special case for literal strings
1182 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1183 // which are really code pointers
1184 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1187 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1188 printFromToType(itype, type);
1193 /* if this is a pointer */
1196 printIvalPtr (sym, type, ilist, oBuf);
1200 /* if type is SPECIFIER */
1203 printIvalType (sym, type, ilist, oBuf);
1208 /*-----------------------------------------------------------------*/
1209 /* emitStaticSeg - emitcode for the static segment */
1210 /*-----------------------------------------------------------------*/
1212 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1216 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1218 /* for all variables in this segment do */
1219 for (sym = setFirstItem (map->syms); sym;
1220 sym = setNextItem (map->syms))
1223 /* if it is "extern" then do nothing */
1224 if (IS_EXTERN (sym->etype))
1227 /* if it is not static add it to the public table */
1228 if (!IS_STATIC (sym->etype))
1230 addSetHead (&publics, sym);
1233 /* print extra debug info if required */
1234 if (options.debug) {
1238 if (IS_STATIC (sym->etype))
1239 dbuf_printf (oBuf, "F%s$", moduleName); /* scope is file */
1241 dbuf_printf (oBuf, "G$"); /* scope is global */
1244 /* symbol is local */
1245 dbuf_printf (oBuf, "L%s$",
1246 (sym->localof ? sym->localof->name : "-null-"));
1247 dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1250 /* if it has an absolute address and no initializer */
1251 if (SPEC_ABSA (sym->etype) && !sym->ival)
1254 dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1256 dbuf_printf (oBuf, "%s\t=\t0x%04x\n",
1258 SPEC_ADDR (sym->etype));
1263 dbuf_printf (oBuf, " == .\n");
1265 /* if it has an initial value */
1268 if (SPEC_ABSA (sym->etype))
1270 dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1272 dbuf_printf (oBuf, "%s:\n", sym->rname);
1274 resolveIvalSym (sym->ival, sym->type);
1275 printIval (sym, sym->type, sym->ival, oBuf);
1277 /* if sym is a simple string and sym->ival is a string,
1278 WE don't need it anymore */
1279 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1280 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1281 list2val(sym->ival)->sym->isstrlit) {
1282 freeStringSymbol(list2val(sym->ival)->sym);
1286 /* allocate space */
1287 int size = getSize (sym->type);
1290 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1292 dbuf_printf (oBuf, "%s:\n", sym->rname);
1293 /* special case for character strings */
1294 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1295 SPEC_CVAL (sym->etype).v_char)
1297 SPEC_CVAL (sym->etype).v_char,
1300 dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1306 /*-----------------------------------------------------------------*/
1307 /* emitMaps - emits the code for the data portion the code */
1308 /*-----------------------------------------------------------------*/
1312 int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */
1313 /* ports but let's be conservative - EEP */
1316 /* no special considerations for the following
1317 data, idata & bit & xdata */
1318 emitRegularMap (data, TRUE, TRUE);
1319 emitRegularMap (idata, TRUE, TRUE);
1320 emitRegularMap (d_abs, TRUE, TRUE);
1321 emitRegularMap (i_abs, TRUE, TRUE);
1322 emitRegularMap (bit, TRUE, TRUE);
1323 emitRegularMap (pdata, TRUE, TRUE);
1324 emitRegularMap (xdata, TRUE, TRUE);
1325 emitRegularMap (x_abs, TRUE, TRUE);
1326 if (port->genXINIT) {
1327 emitRegularMap (xidata, TRUE, TRUE);
1329 emitRegularMap (sfr, publicsfr, FALSE);
1330 emitRegularMap (sfrbit, publicsfr, FALSE);
1331 emitRegularMap (home, TRUE, FALSE);
1332 emitRegularMap (code, TRUE, FALSE);
1334 if (options.const_seg) {
1335 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
1337 emitStaticSeg (statsg, &code->oBuf);
1338 if (port->genXINIT) {
1339 dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
1340 emitStaticSeg (xinit, &code->oBuf);
1342 dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
1343 emitStaticSeg (c_abs, &code->oBuf);
1347 /*-----------------------------------------------------------------*/
1348 /* flushStatics - flush all currently defined statics out to file */
1349 /* and delete. Temporary function */
1350 /*-----------------------------------------------------------------*/
1354 emitStaticSeg (statsg, codeOutBuf);
1355 statsg->syms = NULL;
1358 /*-----------------------------------------------------------------*/
1359 /* createInterruptVect - creates the interrupt vector */
1360 /*-----------------------------------------------------------------*/
1362 createInterruptVect (struct dbuf_s *vBuf)
1364 mainf = newSymbol ("main", 0);
1367 /* only if the main function exists */
1368 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1370 if (!options.cc_only && !noAssemble && !options.c1mode)
1375 /* if the main is only a prototype ie. no body then do nothing */
1376 if (!IFFUNC_HASBODY(mainf->type))
1378 /* if ! compile only then main function should be present */
1379 if (!options.cc_only && !noAssemble)
1384 dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
1385 dbuf_printf (vBuf, "__interrupt_vect:\n");
1388 if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
1390 /* There's no such thing as a "generic" interrupt table header. */
1397 ";--------------------------------------------------------\n"
1398 "; File Created by SDCC : free open source ANSI-C Compiler\n"};
1402 ";--------------------------------------------------------\n"};
1405 /*-----------------------------------------------------------------*/
1406 /* initialComments - puts in some initial comments */
1407 /*-----------------------------------------------------------------*/
1409 initialComments (FILE * afile)
1413 fprintf (afile, "%s", iComments1);
1414 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s)\n", getBuildNumber(), __DATE__);
1415 fprintf (afile, "; This file generated %s", asctime (localtime (&t)));
1416 fprintf (afile, "%s", iComments2);
1419 /*-----------------------------------------------------------------*/
1420 /* printPublics - generates .global for publics */
1421 /*-----------------------------------------------------------------*/
1423 printPublics (FILE * afile)
1427 fprintf (afile, "%s", iComments2);
1428 fprintf (afile, "; Public variables in this module\n");
1429 fprintf (afile, "%s", iComments2);
1431 for (sym = setFirstItem (publics); sym;
1432 sym = setNextItem (publics))
1433 tfprintf (afile, "\t!global\n", sym->rname);
1436 /*-----------------------------------------------------------------*/
1437 /* printExterns - generates .global for externs */
1438 /*-----------------------------------------------------------------*/
1440 printExterns (FILE * afile)
1444 fprintf (afile, "%s", iComments2);
1445 fprintf (afile, "; Externals used\n");
1446 fprintf (afile, "%s", iComments2);
1448 for (sym = setFirstItem (externs); sym;
1449 sym = setNextItem (externs))
1450 tfprintf (afile, "\t!extern\n", sym->rname);
1453 /*-----------------------------------------------------------------*/
1454 /* emitOverlay - will emit code for the overlay stuff */
1455 /*-----------------------------------------------------------------*/
1457 emitOverlay (struct dbuf_s * aBuf)
1461 if (!elementsInSet (ovrSetSets))
1462 dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1464 /* for each of the sets in the overlay segment do */
1465 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1466 ovrset = setNextItem (ovrSetSets))
1471 if (elementsInSet (ovrset))
1473 /* output the area informtion */
1474 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1477 for (sym = setFirstItem (ovrset); sym;
1478 sym = setNextItem (ovrset))
1480 /* if extern then it is in the publics table: do nothing */
1481 if (IS_EXTERN (sym->etype))
1484 /* if allocation required check is needed
1485 then check if the symbol really requires
1486 allocation only for local variables */
1487 if (!IS_AGGREGATE (sym->type) &&
1488 !(sym->_isparm && !IS_REGPARM (sym->etype))
1489 && !sym->allocreq && sym->level)
1492 /* if global variable & not static or extern
1493 and addPublics allowed then add it to the public set */
1494 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1495 && !IS_STATIC (sym->etype))
1497 addSetHead (&publics, sym);
1500 /* if extern then do nothing or is a function
1502 if (IS_FUNC (sym->type))
1505 /* print extra debug info if required */
1510 if (IS_STATIC (sym->etype))
1511 dbuf_printf (aBuf, "F%s$", moduleName); /* scope is file */
1513 dbuf_printf (aBuf, "G$"); /* scope is global */
1516 /* symbol is local */
1517 dbuf_printf (aBuf, "L%s$",
1518 (sym->localof ? sym->localof->name : "-null-"));
1519 dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1522 /* if is has an absolute address then generate
1523 an equate for this no need to allocate space */
1524 if (SPEC_ABSA (sym->etype))
1528 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1530 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1532 SPEC_ADDR (sym->etype));
1535 int size = getSize(sym->type);
1538 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1541 dbuf_printf (aBuf, "==.\n");
1543 /* allocate space */
1544 dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1545 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1553 /*-----------------------------------------------------------------*/
1554 /* spacesToUnderscores - replace spaces with underscores */
1555 /*-----------------------------------------------------------------*/
1557 spacesToUnderscores (char *dest, const char *src, size_t len)
1562 assert(dest != NULL);
1563 assert(src != NULL);
1567 for (p = dest, i = 0; *src != '\0' && i < len; ++src, ++i) {
1568 *p++ = isspace((unsigned char)*src) ? '_' : *src;
1576 /*-----------------------------------------------------------------*/
1577 /* glue - the final glue that hold the whole thing together */
1578 /*-----------------------------------------------------------------*/
1583 struct dbuf_s ovrBuf;
1585 char moduleBuf[PATH_MAX];
1588 dbuf_init(&vBuf, 4096);
1589 dbuf_init(&ovrBuf, 4096);
1591 if(port->general.glue_up_main &&
1592 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400))
1594 mcs51_like=1; /*So it has bits, sfr, sbits, data, idata, etc...*/
1601 /* print the global struct definitions */
1605 /* PENDING: this isn't the best place but it will do */
1606 if (port->general.glue_up_main)
1608 /* create the interrupt vector table */
1609 createInterruptVect (&vBuf);
1612 /* emit code for the all the variables declared */
1614 /* do the overlay segments */
1615 emitOverlay (&ovrBuf);
1617 outputDebugSymbols();
1619 /* now put it all together into the assembler file */
1620 /* create the assembler file name */
1622 /* -o option overrides default name? */
1623 if ((noAssemble || options.c1mode) && fullDstFileName)
1625 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1629 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1630 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1633 if (!(asmFile = fopen (scratchFileName, "w")))
1635 werror (E_FILE_OPEN_ERR, scratchFileName);
1639 /* initial comments */
1640 initialComments (asmFile);
1642 /* print module name */
1643 tfprintf (asmFile, "\t!module\n",
1644 spacesToUnderscores (moduleBuf, moduleName, sizeof moduleBuf));
1647 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1649 switch(options.model)
1651 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1652 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1653 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1654 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1655 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1656 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1659 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1660 if(options.useXstack) fprintf (asmFile, " --xstack");
1661 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1662 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1663 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1664 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1665 fprintf (asmFile, "\n");
1667 else if(TARGET_Z80_LIKE || TARGET_IS_HC08)
1669 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1672 tfprintf (asmFile, "\t!fileprelude\n");
1674 /* Let the port generate any global directives, etc. */
1675 if (port->genAssemblerPreamble)
1677 port->genAssemblerPreamble (asmFile);
1680 /* print the global variables in this module */
1681 printPublics (asmFile);
1682 if (port->assembler.externGlobal)
1683 printExterns (asmFile);
1686 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1688 /* copy the sfr segment */
1689 fprintf (asmFile, "%s", iComments2);
1690 fprintf (asmFile, "; special function registers\n");
1691 fprintf (asmFile, "%s", iComments2);
1692 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1697 /* copy the sbit segment */
1698 fprintf (asmFile, "%s", iComments2);
1699 fprintf (asmFile, "; special function bits\n");
1700 fprintf (asmFile, "%s", iComments2);
1701 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1703 /*JCF: Create the areas for the register banks*/
1704 if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3])
1706 fprintf (asmFile, "%s", iComments2);
1707 fprintf (asmFile, "; overlayable register banks\n");
1708 fprintf (asmFile, "%s", iComments2);
1710 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1711 if(RegBankUsed[1]||options.parms_in_bank1)
1712 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1714 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1716 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1720 fprintf (asmFile, "%s", iComments2);
1721 fprintf (asmFile, "; overlayable bit register bank\n");
1722 fprintf (asmFile, "%s", iComments2);
1723 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1724 fprintf (asmFile, "bits:\n\t.ds 1\n");
1725 fprintf (asmFile, "\tb0 = bits[0]\n");
1726 fprintf (asmFile, "\tb1 = bits[1]\n");
1727 fprintf (asmFile, "\tb2 = bits[2]\n");
1728 fprintf (asmFile, "\tb3 = bits[3]\n");
1729 fprintf (asmFile, "\tb4 = bits[4]\n");
1730 fprintf (asmFile, "\tb5 = bits[5]\n");
1731 fprintf (asmFile, "\tb6 = bits[6]\n");
1732 fprintf (asmFile, "\tb7 = bits[7]\n");
1736 /* copy the data segment */
1737 fprintf (asmFile, "%s", iComments2);
1738 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1739 fprintf (asmFile, "%s", iComments2);
1740 dbuf_write_and_destroy (&data->oBuf, asmFile);
1743 /* create the overlay segments */
1746 fprintf (asmFile, "%s", iComments2);
1747 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1748 fprintf (asmFile, "%s", iComments2);
1749 dbuf_write_and_destroy (&ovrBuf, asmFile);
1752 /* create the stack segment MOF */
1753 if (mainf && IFFUNC_HASBODY(mainf->type))
1755 fprintf (asmFile, "%s", iComments2);
1756 fprintf (asmFile, "; Stack segment in internal ram \n");
1757 fprintf (asmFile, "%s", iComments2);
1758 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1759 "__start__stack:\n\t.ds\t1\n\n");
1762 /* create the idata segment */
1763 if ( (idata) && (mcs51_like) )
1765 fprintf (asmFile, "%s", iComments2);
1766 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1767 fprintf (asmFile, "%s", iComments2);
1768 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1771 /* create the absolute idata/data segment */
1772 if ( (i_abs) && (mcs51_like) )
1774 fprintf (asmFile, "%s", iComments2);
1775 fprintf (asmFile, "; absolute internal ram data\n");
1776 fprintf (asmFile, "%s", iComments2);
1777 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1778 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1781 /* copy the bit segment */
1784 fprintf (asmFile, "%s", iComments2);
1785 fprintf (asmFile, "; bit data\n");
1786 fprintf (asmFile, "%s", iComments2);
1787 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1790 /* copy paged external ram data */
1793 fprintf (asmFile, "%s", iComments2);
1794 fprintf (asmFile, "; paged external ram data\n");
1795 fprintf (asmFile, "%s", iComments2);
1796 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1799 /* if external stack then reserve space for it */
1800 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1802 fprintf (asmFile, "%s", iComments2);
1803 fprintf (asmFile, "; external stack \n");
1804 fprintf (asmFile, "%s", iComments2);
1805 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1806 "__start__xstack:\n\t.ds\t1\n\n");
1809 /* copy external ram data */
1812 fprintf (asmFile, "%s", iComments2);
1813 fprintf (asmFile, "; external ram data\n");
1814 fprintf (asmFile, "%s", iComments2);
1815 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1818 /* create the absolute xdata segment */
1819 if (mcs51_like || TARGET_IS_HC08)
1821 fprintf (asmFile, "%s", iComments2);
1822 fprintf (asmFile, "; absolute external ram data\n");
1823 fprintf (asmFile, "%s", iComments2);
1824 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1827 /* copy external initialized ram data */
1828 fprintf (asmFile, "%s", iComments2);
1829 fprintf (asmFile, "; external initialized ram data\n");
1830 fprintf (asmFile, "%s", iComments2);
1831 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1833 /* If the port wants to generate any extra areas, let it do so. */
1834 if (port->extraAreas.genExtraAreaDeclaration)
1836 port->extraAreas.genExtraAreaDeclaration(asmFile,
1837 mainf && IFFUNC_HASBODY(mainf->type));
1840 /* copy the interrupt vector table */
1841 if (mainf && IFFUNC_HASBODY(mainf->type))
1843 fprintf (asmFile, "%s", iComments2);
1844 fprintf (asmFile, "; interrupt vector \n");
1845 fprintf (asmFile, "%s", iComments2);
1846 dbuf_write_and_destroy (&vBuf, asmFile);
1849 /* copy global & static initialisations */
1850 fprintf (asmFile, "%s", iComments2);
1851 fprintf (asmFile, "; global & static initialisations\n");
1852 fprintf (asmFile, "%s", iComments2);
1854 /* Everywhere we generate a reference to the static_name area,
1855 * (which is currently only here), we immediately follow it with a
1856 * definition of the post_static_name area. This guarantees that
1857 * the post_static_name area will immediately follow the static_name
1860 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1861 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1862 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1863 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1865 if (mainf && IFFUNC_HASBODY(mainf->type))
1867 if (port->genInitStartup)
1869 port->genInitStartup(asmFile);
1873 assert (mcs51_like);
1874 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1875 /* if external stack is specified then the
1876 higher order byte of the xdatalocation is
1877 going into P2 and the lower order going into
1879 if (options.useXstack)
1881 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1882 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1883 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1884 (unsigned int) options.xdata_loc & 0xff);
1887 // This should probably be a port option, but I'm being lazy.
1888 // on the 400, the firmware boot loader gives us a valid stack
1889 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1890 if (!TARGET_IS_DS400)
1892 /* initialise the stack pointer. JCF: aslink takes care of the location */
1893 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1896 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1897 fprintf (asmFile, "\tmov\ta,dpl\n");
1898 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1899 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1900 fprintf (asmFile, "__sdcc_init_data:\n");
1902 // if the port can copy the XINIT segment to XISEG
1905 port->genXINIT(asmFile);
1909 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1911 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1913 /* This code is generated in the post-static area.
1914 * This area is guaranteed to follow the static area
1915 * by the ugly shucking and jiving about 20 lines ago.
1917 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1918 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1924 "%s", iComments2, iComments2);
1925 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1926 dbuf_write_and_destroy (&home->oBuf, asmFile);
1928 if (mainf && IFFUNC_HASBODY(mainf->type))
1930 /* entry point @ start of HOME */
1931 fprintf (asmFile, "__sdcc_program_startup:\n");
1933 /* put in jump or call to main */
1934 if (options.mainreturn)
1936 fprintf (asmFile, "\tljmp\t_main\n"); /* needed? */
1937 fprintf (asmFile, ";\treturn from main will return to caller\n");
1941 fprintf (asmFile, "\tlcall\t_main\n");
1942 fprintf (asmFile, ";\treturn from main will lock up\n");
1943 fprintf (asmFile, "\tsjmp .\n");
1946 /* copy over code */
1947 fprintf (asmFile, "%s", iComments2);
1948 fprintf (asmFile, "; code\n");
1949 fprintf (asmFile, "%s", iComments2);
1950 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1951 dbuf_write_and_destroy (&code->oBuf, asmFile);
1953 if (port->genAssemblerEnd)
1955 port->genAssemblerEnd(asmFile);