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 -------------------------------------------------------------------------*/
30 #include "dbuf_string.h"
38 symbol *interrupts[INTNO_MAX+1];
40 void printIval (symbol *, sym_link *, initList *, struct dbuf_s *, bool check);
41 set *publics = NULL; /* public variables */
42 set *externs = NULL; /* Variables that are declared as extern */
44 unsigned maxInterrupts = 0;
47 int noInit = 0; /* no initialization */
51 aopLiteralLong (value * val, int offset, int size)
60 // assuming we have been warned before
61 val = constCharVal (0);
64 /* if it is a float then it gets tricky */
65 /* otherwise it is fairly simple */
66 if (!IS_FLOAT (val->type)) {
67 unsigned long v = ulFromVal (val);
72 tsprintf (buffer, sizeof(buffer),
73 "!immedbyte", (unsigned int) v & 0xff);
76 tsprintf (buffer, sizeof(buffer),
77 "!immedword", (unsigned int) v & 0xffff);
80 /* Hmm. Too big for now. */
83 return Safe_strdup (buffer);
86 /* PENDING: For now size must be 1 */
89 /* it is type float */
90 fl.f = (float) floatFromVal (val);
91 #ifdef WORDS_BIGENDIAN
92 tsprintf (buffer, sizeof(buffer),
93 "!immedbyte", fl.c[3 - offset]);
95 tsprintf (buffer, sizeof(buffer),
96 "!immedbyte", fl.c[offset]);
98 return Safe_strdup (buffer);
101 /*-----------------------------------------------------------------*/
102 /* aopLiteral - string from a literal value */
103 /*-----------------------------------------------------------------*/
105 aopLiteral (value * val, int offset)
107 return aopLiteralLong (val, offset, 1);
110 /*-----------------------------------------------------------------*/
111 /* emitRegularMap - emit code for maps with no special cases */
112 /*-----------------------------------------------------------------*/
114 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
124 /* PENDING: special case here - should remove */
125 if (!strcmp (map->sname, CODE_NAME))
126 dbuf_tprintf (&map->oBuf, "\t!areacode\n", map->sname);
127 else if (!strcmp (map->sname, DATA_NAME))
128 dbuf_tprintf (&map->oBuf, "\t!areadata\n", map->sname);
129 else if (!strcmp (map->sname, HOME_NAME))
130 dbuf_tprintf (&map->oBuf, "\t!areahome\n", map->sname);
132 dbuf_tprintf (&map->oBuf, "\t!area\n", map->sname);
135 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
137 symbol *newSym = NULL;
139 /* if extern then add it into the extern list */
140 if (IS_EXTERN (sym->etype))
142 addSetHead (&externs, sym);
146 /* if allocation required check is needed
147 then check if the symbol really requires
148 allocation only for local variables */
150 if (arFlag && !IS_AGGREGATE (sym->type) &&
151 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
152 !sym->allocreq && sym->level)
155 /* for bitvar locals and parameters */
156 if (!arFlag && !sym->allocreq && sym->level
157 && !SPEC_ABSA (sym->etype))
162 /* if global variable & not static or extern
163 and addPublics allowed then add it to the public set */
164 if ((sym->level == 0 ||
165 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
167 !IS_STATIC (sym->etype) &&
168 (IS_FUNC (sym->type) ? (sym->used || IFFUNC_HASBODY (sym->type)) : 1))
170 addSetHead (&publics, sym);
173 /* if extern then do nothing or is a function
175 if (IS_FUNC (sym->type) && !(sym->isitmp))
178 /* print extra debug info if required */
181 if (!sym->level) /* global */
183 if (IS_STATIC (sym->etype))
184 dbuf_printf (&map->oBuf, "F%s$", moduleName); /* scope is file */
186 dbuf_printf (&map->oBuf, "G$"); /* scope is global */
190 /* symbol is local */
191 dbuf_printf (&map->oBuf, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
193 dbuf_printf (&map->oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
196 /* if it has an initial value then do it only if
197 it is a global variable */
198 if (sym->ival && sym->level == 0)
200 if ((SPEC_OCLS (sym->etype) == xidata) && !SPEC_ABSA (sym->etype))
202 /* create a new "XINIT (CODE)" symbol, that will be emitted later
204 newSym=copySymbol (sym);
205 SPEC_OCLS(newSym->etype)=xinit;
206 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
207 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
208 if (IS_SPEC (newSym->type))
209 SPEC_CONST (newSym->type) = 1;
211 DCL_PTR_CONST (newSym->type) = 1;
212 SPEC_STAT(newSym->etype)=1;
213 resolveIvalSym(newSym->ival, newSym->type);
215 // add it to the "XINIT (CODE)" segment
216 addSet(&xinit->syms, newSym);
218 if (!SPEC_ABSA (sym->etype))
220 struct dbuf_s tmpBuf;
222 dbuf_init(&tmpBuf, 4096);
223 // before allocation we must parse the sym->ival tree
224 // but without actually generating initialization code
226 resolveIvalSym (sym->ival, sym->type);
228 printIval (sym, sym->type, sym->ival, &tmpBuf, TRUE);
231 dbuf_destroy(&tmpBuf);
236 if (IS_AGGREGATE (sym->type))
238 ival = initAggregates (sym, sym->ival, NULL);
242 if (getNelements (sym->type, sym->ival)>1)
244 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", sym->name);
246 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
247 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
249 codeOutBuf = &statsg->oBuf;
253 // set ival's lineno to where the symbol was defined
254 setAstFileLine (ival, filename = sym->fileDef, lineno = sym->lineDef);
255 // check if this is not a constant expression
256 if (!constExprTree (ival))
258 werror (E_CONST_EXPECTED, "found expression");
259 // but try to do it anyway
262 if (!astErrors (ival))
263 eBBlockFromiCode (iCodeFromAst (ival));
269 /* if it has an absolute address then generate
270 an equate for this no need to allocate space */
271 if (SPEC_ABSA (sym->etype) && !sym->ival)
275 dbuf_printf (&map->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
283 else if (map == bit || map == sfrbit)
288 dbuf_printf (&map->oBuf, "%s\t%s\t0x%04x\n", sym->rname, equ, SPEC_ADDR (sym->etype));
292 int size = getSize (sym->type) + sym->flexArrayLength;
295 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
300 dbuf_printf (&map->oBuf, "==.\n");
302 if (SPEC_ABSA (sym->etype))
304 dbuf_tprintf (&map->oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
306 if (IS_STATIC (sym->etype) || sym->level)
307 dbuf_tprintf (&map->oBuf, "!slabeldef\n", sym->rname);
309 dbuf_tprintf (&map->oBuf, "!labeldef\n", sym->rname);
310 dbuf_tprintf (&map->oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
316 /*-----------------------------------------------------------------*/
317 /* initPointer - pointer initialization code massaging */
318 /*-----------------------------------------------------------------*/
320 initPointer (initList * ilist, sym_link *toType)
326 return valCastLiteral(toType, 0.0);
329 expr = list2expr (ilist);
334 /* try it the old way first */
335 if ((val = constExprValue (expr, FALSE)))
338 /* ( ptr + constant ) */
339 if (IS_AST_OP (expr) &&
340 (expr->opval.op == '+' || expr->opval.op == '-') &&
341 IS_AST_SYM_VALUE (expr->left) &&
342 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
343 compareType(toType, expr->left->ftype) &&
344 IS_AST_LIT_VALUE (expr->right)) {
345 return valForCastAggr (expr->left, expr->left->ftype,
351 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
352 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
353 if (compareType(toType, expr->left->ftype)!=1) {
354 werror (W_INIT_WRONG);
355 printFromToType(expr->left->ftype, toType);
361 /* no then we have to do these cludgy checks */
362 /* pointers can be initialized with address of
363 a variable or address of an array element */
364 if (IS_AST_OP (expr) && expr->opval.op == '&') {
365 /* address of symbol */
366 if (IS_AST_SYM_VALUE (expr->left)) {
367 val = AST_VALUE (expr->left);
368 val->type = newLink (DECLARATOR);
369 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
370 DCL_TYPE (val->type) = CPOINTER;
371 DCL_PTR_CONST (val->type) = port->mem.code_ro;
373 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
374 DCL_TYPE (val->type) = FPOINTER;
375 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
376 DCL_TYPE (val->type) = PPOINTER;
377 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
378 DCL_TYPE (val->type) = IPOINTER;
379 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
380 DCL_TYPE (val->type) = EEPPOINTER;
382 DCL_TYPE (val->type) = POINTER;
383 val->type->next = expr->left->ftype;
384 val->etype = getSpec (val->type);
388 /* if address of indexed array */
389 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
390 return valForArray (expr->left);
392 /* if address of structure element then
394 if (IS_AST_OP (expr->left) &&
395 expr->left->opval.op == '.') {
396 return valForStructElem (expr->left->left,
401 (&some_struct)->element */
402 if (IS_AST_OP (expr->left) &&
403 expr->left->opval.op == PTR_OP &&
404 IS_ADDRESS_OF_OP (expr->left->left)) {
405 return valForStructElem (expr->left->left->left,
409 /* case 3. (((char *) &a) +/- constant) */
410 if (IS_AST_OP (expr) &&
411 (expr->opval.op == '+' || expr->opval.op == '-') &&
412 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
413 IS_AST_OP (expr->left->right) &&
414 expr->left->right->opval.op == '&' &&
415 IS_AST_LIT_VALUE (expr->right)) {
417 return valForCastAggr (expr->left->right->left,
418 expr->left->left->opval.lnk,
419 expr->right, expr->opval.op);
422 /* case 4. (char *)(array type) */
423 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
424 IS_ARRAY(expr->right->ftype)) {
426 val = copyValue (AST_VALUE (expr->right));
427 val->type = newLink (DECLARATOR);
428 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
429 DCL_TYPE (val->type) = CPOINTER;
430 DCL_PTR_CONST (val->type) = port->mem.code_ro;
432 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
433 DCL_TYPE (val->type) = FPOINTER;
434 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
435 DCL_TYPE (val->type) = PPOINTER;
436 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
437 DCL_TYPE (val->type) = IPOINTER;
438 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
439 DCL_TYPE (val->type) = EEPPOINTER;
441 DCL_TYPE (val->type) = POINTER;
442 val->type->next = expr->right->ftype->next;
443 val->etype = getSpec (val->type);
448 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
450 werror (E_INCOMPAT_PTYPES);
455 /*-----------------------------------------------------------------*/
456 /* printChar - formats and prints a characater string with DB */
457 /*-----------------------------------------------------------------*/
459 printChar (struct dbuf_s * oBuf, char *s, int plen)
467 while (len && pplen < plen)
470 while (i && pplen < plen)
472 if (*s < ' ' || *s == '\"' || *s=='\\')
476 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
477 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char)*s);
492 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
503 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
508 /*-----------------------------------------------------------------*/
509 /* return the generic pointer high byte for a given pointer type. */
510 /*-----------------------------------------------------------------*/
512 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
520 werror (E_CANNOT_USE_GENERIC_POINTER,
521 iname ? iname : "<null>",
522 oname ? oname : "<null>");
529 return GPTYPE_XSTACK;
531 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
539 /*-----------------------------------------------------------------*/
540 /* printPointerType - generates ival for pointer type */
541 /*-----------------------------------------------------------------*/
543 _printPointerType (struct dbuf_s * oBuf, const char *name)
545 if (options.model == MODEL_FLAT24)
547 if (port->little_endian)
548 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
550 dbuf_printf (oBuf, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
554 if (port->little_endian)
555 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8)", name, name);
557 dbuf_printf (oBuf, "\t.byte (%s >> 8),%s", name, name);
561 /*-----------------------------------------------------------------*/
562 /* printPointerType - generates ival for pointer type */
563 /*-----------------------------------------------------------------*/
565 printPointerType (struct dbuf_s * oBuf, const char *name)
567 _printPointerType (oBuf, name);
568 dbuf_printf (oBuf, "\n");
571 /*-----------------------------------------------------------------*/
572 /* printGPointerType - generates ival for generic pointer type */
573 /*-----------------------------------------------------------------*/
575 printGPointerType (struct dbuf_s * oBuf, const char *iname, const char *oname,
576 const unsigned int type)
578 _printPointerType (oBuf, iname);
579 dbuf_printf (oBuf, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
582 /*-----------------------------------------------------------------*/
583 /* printIvalType - generates ival for int/char */
584 /*-----------------------------------------------------------------*/
586 printIvalType (symbol *sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
590 /* if initList is deep */
591 if (ilist && (ilist->type == INIT_DEEP))
592 ilist = ilist->init.deep;
594 if (!(val = list2val (ilist))) {
595 // assuming a warning has been thrown
596 val = constCharVal (0);
599 /* check if the literal value is within bounds */
600 if (checkConstantRange (type, val->etype, '=', FALSE) == CCR_OVL &&
601 !options.lessPedantic)
603 werror (W_LIT_OVERFLOW);
606 if (val->type != type) {
607 val = valCastLiteral(type, floatFromVal(val));
610 switch (getSize (type)) {
613 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
615 dbuf_tprintf (oBuf, "\t!dbs\n",
616 aopLiteral (val, 0));
620 if (port->use_dw_for_init)
621 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
622 else if (port->little_endian)
623 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
625 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
629 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
630 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
632 else if (port->little_endian) {
633 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
634 aopLiteral (val, 0), aopLiteral (val, 1),
635 aopLiteral (val, 2), aopLiteral (val, 3));
638 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
639 aopLiteral (val, 3), aopLiteral (val, 2),
640 aopLiteral (val, 1), aopLiteral (val, 0));
646 /*-----------------------------------------------------------------*/
647 /* printIvalBitFields - generate initializer for bitfields */
648 /*-----------------------------------------------------------------*/
649 void printIvalBitFields(symbol **sym, initList **ilist, struct dbuf_s * oBuf)
653 initList *lilist = *ilist ;
654 unsigned long ival = 0;
660 val = list2val (lilist);
663 if (SPEC_BLEN (lsym->etype) > 8)
665 size += ((SPEC_BLEN (lsym->etype) / 8) +
666 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
671 size = ((SPEC_BLEN (lsym->etype) / 8) +
672 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
675 /* check if the literal value is within bounds */
677 checkConstantRange (lsym->etype, val->etype, '=', FALSE) == CCR_OVL &&
678 !options.lessPedantic)
680 werror (W_LIT_OVERFLOW);
684 i &= (1 << SPEC_BLEN (lsym->etype)) - 1;
685 i <<= SPEC_BSTR (lsym->etype);
688 (IS_BITFIELD (lsym->next->type)) &&
689 (SPEC_BSTR (lsym->next->etype))))
692 lilist = lilist ? lilist->next : NULL;
699 dbuf_tprintf (oBuf, "\t!db !constbyte\n", ival);
703 dbuf_tprintf (oBuf, "\t!dw !constword\n", ival);
707 dbuf_tprintf (oBuf, "\t!dw !constword,!constword\n",
708 (ival >> 16) & 0xffff, (ival & 0xffff));
715 /*-----------------------------------------------------------------*/
716 /* printIvalStruct - generates initial value for structures */
717 /*-----------------------------------------------------------------*/
719 printIvalStruct (symbol * sym, sym_link * type,
720 initList * ilist, struct dbuf_s * oBuf)
723 initList *iloop = NULL;
725 sflds = SPEC_STRUCT (type)->fields;
728 if (ilist->type != INIT_DEEP) {
729 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
733 iloop = ilist->init.deep;
736 if (SPEC_STRUCT (type)->type == UNION) {
737 printIval (sym, sflds->type, iloop, oBuf, TRUE);
738 iloop = iloop ? iloop->next : NULL;
740 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
741 if (IS_BITFIELD(sflds->type)) {
742 printIvalBitFields(&sflds, &iloop, oBuf);
744 printIval (sym, sflds->type, iloop, oBuf, TRUE);
749 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
754 /*-----------------------------------------------------------------*/
755 /* printIvalChar - generates initital value for character array */
756 /*-----------------------------------------------------------------*/
758 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s, bool check)
761 unsigned int size = DCL_ELEM (type);
765 val = list2val (ilist);
766 /* if the value is a character string */
767 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
771 /* we have not been given a size, but now we know it */
772 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
773 /* but first check, if it's a flexible array */
774 if (sym && IS_STRUCT (sym->type))
775 sym->flexArrayLength = size;
777 DCL_ELEM (type) = size;
780 if (check && DCL_ELEM (val->type) > size)
781 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
783 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
791 printChar (oBuf, s, strlen (s) + 1);
795 /*-----------------------------------------------------------------*/
796 /* printIvalArray - generates code for array initialization */
797 /*-----------------------------------------------------------------*/
799 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
800 struct dbuf_s * oBuf, bool check)
804 unsigned int size = 0;
807 /* take care of the special case */
808 /* array of characters can be init */
810 if (IS_CHAR (type->next)) {
811 val = list2val(ilist);
813 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
816 if (!IS_LITERAL(val->etype)) {
817 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
820 if (printIvalChar (sym, type,
821 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
822 oBuf, SPEC_CVAL (sym->etype).v_char, check))
825 /* not the special case */
826 if (ilist->type != INIT_DEEP) {
827 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
831 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
832 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
833 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
836 printIval (sym, type->next, iloop, oBuf, TRUE);
840 if (DCL_ELEM(type)) {
841 // pad with zeros if needed
842 if (size<DCL_ELEM(type)) {
843 size = (DCL_ELEM(type) - size) * getSize(type->next);
845 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
849 /* we have not been given a size, but now we know it */
850 /* but first check, if it's a flexible array */
851 if (IS_STRUCT (sym->type))
852 sym->flexArrayLength = size * getSize (type->next);
854 DCL_ELEM (type) = size;
860 /*-----------------------------------------------------------------*/
861 /* printIvalFuncPtr - generate initial value for function pointers */
862 /*-----------------------------------------------------------------*/
864 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
870 val = list2val (ilist);
872 val = valCastLiteral(type, 0.0);
875 // an error has been thrown already
876 val = constCharVal (0);
879 if (IS_LITERAL(val->etype)) {
880 if (compareType(type, val->etype) == 0) {
881 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
882 printFromToType (val->type, type);
884 printIvalCharPtr (NULL, type, val, oBuf);
888 /* check the types */
889 if ((dLvl = compareType (val->type, type->next)) <= 0)
891 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
895 /* now generate the name */
898 if (port->use_dw_for_init)
900 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
904 printPointerType (oBuf, val->name);
907 else if (port->use_dw_for_init)
909 dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
913 printPointerType (oBuf, val->sym->rname);
919 /*-----------------------------------------------------------------*/
920 /* printIvalCharPtr - generates initial values for character pointers */
921 /*-----------------------------------------------------------------*/
923 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
927 /* PENDING: this is _very_ mcs51 specific, including a magic
929 It's also endian specific.
931 size = getSize (type);
933 if (val->name && strlen (val->name))
935 if (size == 1) /* This appears to be Z80 specific?? */
938 "\t!dbs\n", val->name);
940 else if (size == FPTRSIZE)
942 if (port->use_dw_for_init)
944 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
948 printPointerType (oBuf, val->name);
951 else if (size == GPTRSIZE)
954 if (IS_PTR (val->type)) {
955 type = DCL_TYPE (val->type);
957 type = PTR_TYPE (SPEC_OCLS (val->etype));
959 if (val->sym && val->sym->isstrlit) {
960 // this is a literal string
963 printGPointerType (oBuf, val->name, sym->name, type);
967 fprintf (stderr, "*** internal error: unknown size in "
968 "printIvalCharPtr.\n");
973 // these are literals assigned to pointers
977 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
980 if (port->use_dw_for_init)
981 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
982 else if (port->little_endian)
983 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
984 aopLiteral (val, 0), aopLiteral (val, 1));
986 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
987 aopLiteral (val, 1), aopLiteral (val, 0));
990 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
991 // non-zero mcs51 generic pointer
992 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
994 if (port->little_endian) {
995 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
998 aopLiteral (val, 2));
1000 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1001 aopLiteral (val, 2),
1002 aopLiteral (val, 1),
1003 aopLiteral (val, 0));
1007 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1008 // non-zero ds390 generic pointer
1009 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1011 if (port->little_endian) {
1012 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1013 aopLiteral (val, 0),
1014 aopLiteral (val, 1),
1015 aopLiteral (val, 2),
1016 aopLiteral (val, 3));
1018 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1019 aopLiteral (val, 3),
1020 aopLiteral (val, 2),
1021 aopLiteral (val, 1),
1022 aopLiteral (val, 0));
1030 if (!noInit && val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1031 addSet (&statsg->syms, val->sym);
1037 /*-----------------------------------------------------------------*/
1038 /* printIvalPtr - generates initial value for pointers */
1039 /*-----------------------------------------------------------------*/
1041 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1047 if (ilist && (ilist->type == INIT_DEEP))
1048 ilist = ilist->init.deep;
1050 /* function pointer */
1051 if (IS_FUNC (type->next))
1053 printIvalFuncPtr (type, ilist, oBuf);
1057 if (!(val = initPointer (ilist, type)))
1060 /* if character pointer */
1061 if (IS_CHAR (type->next))
1062 if (printIvalCharPtr (sym, type, val, oBuf))
1065 /* check the type */
1066 if (compareType (type, val->type) == 0) {
1067 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1068 printFromToType (val->type, type);
1071 /* if val is literal */
1072 if (IS_LITERAL (val->etype))
1074 switch (getSize (type))
1077 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1080 if (port->use_dw_for_init)
1081 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1082 else if (port->little_endian)
1083 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1085 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1087 case 3: // how about '390??
1088 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1089 if (port->little_endian)
1091 dbuf_printf (oBuf, "\t.byte %s,%s",
1092 aopLiteral (val, 0), aopLiteral (val, 1));
1096 dbuf_printf (oBuf, "\t.byte %s,%s",
1097 aopLiteral (val, 1), aopLiteral (val, 0));
1099 if (IS_GENPTR (val->type))
1100 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1101 else if (IS_PTR (val->type))
1102 dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1104 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1110 size = getSize (type);
1112 if (size == 1) /* Z80 specific?? */
1114 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1116 else if (size == FPTRSIZE)
1118 if (port->use_dw_for_init) {
1119 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1121 printPointerType (oBuf, val->name);
1124 else if (size == GPTRSIZE)
1126 printGPointerType (oBuf, val->name, sym->name,
1127 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1128 PTR_TYPE (SPEC_OCLS (val->etype))));
1133 /*-----------------------------------------------------------------*/
1134 /* printIval - generates code for initial value */
1135 /*-----------------------------------------------------------------*/
1137 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, bool check)
1141 /* if structure then */
1142 if (IS_STRUCT (type))
1144 printIvalStruct (sym, type, ilist, oBuf);
1148 /* if this is an array */
1149 if (IS_ARRAY (type))
1151 printIvalArray (sym, type, ilist, oBuf, check);
1157 // not an aggregate, ilist must be a node
1158 if (ilist->type!=INIT_NODE) {
1159 // or a 1-element list
1160 if (ilist->init.deep->next) {
1161 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1164 ilist=ilist->init.deep;
1168 // and the type must match
1169 itype=ilist->init.node->ftype;
1171 if (compareType(type, itype)==0) {
1172 // special case for literal strings
1173 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1174 // which are really code pointers
1175 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1178 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1179 printFromToType(itype, type);
1184 /* if this is a pointer */
1187 printIvalPtr (sym, type, ilist, oBuf);
1191 /* if type is SPECIFIER */
1194 printIvalType (sym, type, ilist, oBuf);
1199 /*-----------------------------------------------------------------*/
1200 /* emitStaticSeg - emitcode for the static segment */
1201 /*-----------------------------------------------------------------*/
1203 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1207 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1209 /* for all variables in this segment do */
1210 for (sym = setFirstItem (map->syms); sym;
1211 sym = setNextItem (map->syms))
1214 /* if it is "extern" then do nothing */
1215 if (IS_EXTERN (sym->etype))
1218 /* if it is not static add it to the public table */
1219 if (!IS_STATIC (sym->etype))
1221 addSetHead (&publics, sym);
1224 /* print extra debug info if required */
1229 if (IS_STATIC (sym->etype))
1230 dbuf_printf (oBuf, "F%s$", moduleName); /* scope is file */
1232 dbuf_printf (oBuf, "G$"); /* scope is global */
1236 /* symbol is local */
1237 dbuf_printf (oBuf, "L%s$",
1238 (sym->localof ? sym->localof->name : "-null-"));
1240 dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1243 /* if it has an absolute address and no initializer */
1244 if (SPEC_ABSA (sym->etype) && !sym->ival)
1247 dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1249 dbuf_printf (oBuf, "%s\t=\t0x%04x\n",
1251 SPEC_ADDR (sym->etype));
1256 dbuf_printf (oBuf, " == .\n");
1258 /* if it has an initial value */
1261 if (SPEC_ABSA (sym->etype))
1263 dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1265 dbuf_printf (oBuf, "%s:\n", sym->rname);
1267 resolveIvalSym (sym->ival, sym->type);
1268 printIval (sym, sym->type, sym->ival, oBuf, map != xinit);
1270 /* if sym is a simple string and sym->ival is a string,
1271 WE don't need it anymore */
1272 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1273 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1274 list2val(sym->ival)->sym->isstrlit) {
1275 freeStringSymbol(list2val(sym->ival)->sym);
1279 /* allocate space */
1280 int size = getSize (sym->type);
1283 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1285 dbuf_printf (oBuf, "%s:\n", sym->rname);
1286 /* special case for character strings */
1287 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1288 SPEC_CVAL (sym->etype).v_char)
1290 SPEC_CVAL (sym->etype).v_char,
1293 dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1299 /*-----------------------------------------------------------------*/
1300 /* emitMaps - emits the code for the data portion the code */
1301 /*-----------------------------------------------------------------*/
1305 int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */
1306 /* ports but let's be conservative - EEP */
1309 /* no special considerations for the following
1310 data, idata & bit & xdata */
1311 emitRegularMap (data, TRUE, TRUE);
1312 emitRegularMap (idata, TRUE, TRUE);
1313 emitRegularMap (d_abs, TRUE, TRUE);
1314 emitRegularMap (i_abs, TRUE, TRUE);
1315 emitRegularMap (bit, TRUE, TRUE);
1316 emitRegularMap (pdata, TRUE, TRUE);
1317 emitRegularMap (xdata, TRUE, TRUE);
1318 emitRegularMap (x_abs, TRUE, TRUE);
1319 if (port->genXINIT) {
1320 emitRegularMap (xidata, TRUE, TRUE);
1322 emitRegularMap (sfr, publicsfr, FALSE);
1323 emitRegularMap (sfrbit, publicsfr, FALSE);
1324 emitRegularMap (home, TRUE, FALSE);
1325 emitRegularMap (code, TRUE, FALSE);
1327 if (options.const_seg) {
1328 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
1330 emitStaticSeg (statsg, &code->oBuf);
1331 if (port->genXINIT) {
1332 dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
1333 emitStaticSeg (xinit, &code->oBuf);
1335 dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
1336 emitStaticSeg (c_abs, &code->oBuf);
1340 /*-----------------------------------------------------------------*/
1341 /* flushStatics - flush all currently defined statics out to file */
1342 /* and delete. Temporary function */
1343 /*-----------------------------------------------------------------*/
1347 emitStaticSeg (statsg, codeOutBuf);
1348 statsg->syms = NULL;
1351 /*-----------------------------------------------------------------*/
1352 /* createInterruptVect - creates the interrupt vector */
1353 /*-----------------------------------------------------------------*/
1355 createInterruptVect (struct dbuf_s *vBuf)
1357 mainf = newSymbol ("main", 0);
1360 /* only if the main function exists */
1361 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1363 if (!options.cc_only && !noAssemble && !options.c1mode)
1368 /* if the main is only a prototype ie. no body then do nothing */
1369 if (!IFFUNC_HASBODY(mainf->type))
1371 /* if ! compile only then main function should be present */
1372 if (!options.cc_only && !noAssemble)
1377 dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
1378 dbuf_printf (vBuf, "__interrupt_vect:\n");
1381 if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
1383 /* There's no such thing as a "generic" interrupt table header. */
1390 ";--------------------------------------------------------\n"
1391 "; File Created by SDCC : free open source ANSI-C Compiler\n"};
1395 ";--------------------------------------------------------\n"};
1398 /*-----------------------------------------------------------------*/
1399 /* initialComments - puts in some initial comments */
1400 /*-----------------------------------------------------------------*/
1402 initialComments (FILE * afile)
1406 fprintf (afile, "%s", iComments1);
1407 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s) (%s)\n",
1408 getBuildNumber(), getBuildDate(), getBuildEnvironment());
1409 fprintf (afile, "; This file was generated %s", asctime (localtime (&t)));
1410 fprintf (afile, "%s", iComments2);
1413 /*-----------------------------------------------------------------*/
1414 /* printPublics - generates .global for publics */
1415 /*-----------------------------------------------------------------*/
1417 printPublics (FILE * afile)
1421 fprintf (afile, "%s", iComments2);
1422 fprintf (afile, "; Public variables in this module\n");
1423 fprintf (afile, "%s", iComments2);
1425 for (sym = setFirstItem (publics); sym;
1426 sym = setNextItem (publics))
1427 tfprintf (afile, "\t!global\n", sym->rname);
1430 /*-----------------------------------------------------------------*/
1431 /* printExterns - generates .global for externs */
1432 /*-----------------------------------------------------------------*/
1434 printExterns (FILE * afile)
1438 fprintf (afile, "%s", iComments2);
1439 fprintf (afile, "; Externals used\n");
1440 fprintf (afile, "%s", iComments2);
1442 for (sym = setFirstItem (externs); sym;
1443 sym = setNextItem (externs))
1444 tfprintf (afile, "\t!extern\n", sym->rname);
1447 /*-----------------------------------------------------------------*/
1448 /* emitOverlay - will emit code for the overlay stuff */
1449 /*-----------------------------------------------------------------*/
1451 emitOverlay (struct dbuf_s * aBuf)
1455 if (!elementsInSet (ovrSetSets))
1456 dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1458 /* for each of the sets in the overlay segment do */
1459 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1460 ovrset = setNextItem (ovrSetSets))
1465 if (elementsInSet (ovrset))
1467 /* output the area informtion */
1468 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1471 for (sym = setFirstItem (ovrset); sym;
1472 sym = setNextItem (ovrset))
1474 /* if extern then it is in the publics table: do nothing */
1475 if (IS_EXTERN (sym->etype))
1478 /* if allocation required check is needed
1479 then check if the symbol really requires
1480 allocation only for local variables */
1481 if (!IS_AGGREGATE (sym->type) &&
1482 !(sym->_isparm && !IS_REGPARM (sym->etype))
1483 && !sym->allocreq && sym->level)
1486 /* if global variable & not static or extern
1487 and addPublics allowed then add it to the public set */
1488 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1489 && !IS_STATIC (sym->etype))
1491 addSetHead (&publics, sym);
1494 /* if extern then do nothing or is a function
1496 if (IS_FUNC (sym->type))
1499 /* print extra debug info if required */
1504 if (IS_STATIC (sym->etype))
1505 dbuf_printf (aBuf, "F%s$", moduleName); /* scope is file */
1507 dbuf_printf (aBuf, "G$"); /* scope is global */
1510 /* symbol is local */
1511 dbuf_printf (aBuf, "L%s$",
1512 (sym->localof ? sym->localof->name : "-null-"));
1513 dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1516 /* if is has an absolute address then generate
1517 an equate for this no need to allocate space */
1518 if (SPEC_ABSA (sym->etype))
1522 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1524 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1526 SPEC_ADDR (sym->etype));
1530 int size = getSize(sym->type);
1533 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1536 dbuf_printf (aBuf, "==.\n");
1538 /* allocate space */
1539 dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1540 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1547 /*-----------------------------------------------------------------*/
1548 /* glue - the final glue that hold the whole thing together */
1549 /*-----------------------------------------------------------------*/
1554 struct dbuf_s ovrBuf;
1558 dbuf_init (&vBuf, 4096);
1559 dbuf_init (&ovrBuf, 4096);
1561 mcs51_like = (port->general.glue_up_main &&
1562 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400));
1564 /* print the global struct definitions */
1568 /* PENDING: this isn't the best place but it will do */
1569 if (port->general.glue_up_main)
1571 /* create the interrupt vector table */
1572 createInterruptVect (&vBuf);
1575 /* emit code for the all the variables declared */
1577 /* do the overlay segments */
1578 emitOverlay (&ovrBuf);
1580 outputDebugSymbols ();
1582 /* now put it all together into the assembler file */
1583 /* create the assembler file name */
1585 /* -o option overrides default name? */
1586 if ((noAssemble || options.c1mode) && fullDstFileName)
1588 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1592 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1593 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1596 if (!(asmFile = fopen (scratchFileName, "w")))
1598 werror (E_FILE_OPEN_ERR, scratchFileName);
1599 exit (EXIT_FAILURE);
1602 /* initial comments */
1603 initialComments (asmFile);
1605 /* print module name */
1606 tfprintf (asmFile, "\t!module\n", moduleName);
1609 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1611 switch(options.model)
1613 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1614 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1615 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1616 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1617 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1618 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1621 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1622 if(options.useXstack) fprintf (asmFile, " --xstack");
1623 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1624 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1625 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1626 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1627 fprintf (asmFile, "\n");
1629 else if (TARGET_Z80_LIKE || TARGET_IS_HC08)
1631 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1634 tfprintf (asmFile, "\t!fileprelude\n");
1636 /* Let the port generate any global directives, etc. */
1637 if (port->genAssemblerPreamble)
1639 port->genAssemblerPreamble (asmFile);
1642 /* print the global variables in this module */
1643 printPublics (asmFile);
1644 if (port->assembler.externGlobal)
1645 printExterns (asmFile);
1648 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1650 /* copy the sfr segment */
1651 fprintf (asmFile, "%s", iComments2);
1652 fprintf (asmFile, "; special function registers\n");
1653 fprintf (asmFile, "%s", iComments2);
1654 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1659 /* copy the sbit segment */
1660 fprintf (asmFile, "%s", iComments2);
1661 fprintf (asmFile, "; special function bits\n");
1662 fprintf (asmFile, "%s", iComments2);
1663 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1665 /*JCF: Create the areas for the register banks*/
1666 if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
1668 fprintf (asmFile, "%s", iComments2);
1669 fprintf (asmFile, "; overlayable register banks\n");
1670 fprintf (asmFile, "%s", iComments2);
1672 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1673 if (RegBankUsed[1] || options.parms_in_bank1)
1674 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1676 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1678 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1682 fprintf (asmFile, "%s", iComments2);
1683 fprintf (asmFile, "; overlayable bit register bank\n");
1684 fprintf (asmFile, "%s", iComments2);
1685 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1686 fprintf (asmFile, "bits:\n\t.ds 1\n");
1687 fprintf (asmFile, "\tb0 = bits[0]\n");
1688 fprintf (asmFile, "\tb1 = bits[1]\n");
1689 fprintf (asmFile, "\tb2 = bits[2]\n");
1690 fprintf (asmFile, "\tb3 = bits[3]\n");
1691 fprintf (asmFile, "\tb4 = bits[4]\n");
1692 fprintf (asmFile, "\tb5 = bits[5]\n");
1693 fprintf (asmFile, "\tb6 = bits[6]\n");
1694 fprintf (asmFile, "\tb7 = bits[7]\n");
1698 /* copy the data segment */
1699 fprintf (asmFile, "%s", iComments2);
1700 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1701 fprintf (asmFile, "%s", iComments2);
1702 dbuf_write_and_destroy (&data->oBuf, asmFile);
1705 /* create the overlay segments */
1708 fprintf (asmFile, "%s", iComments2);
1709 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1710 fprintf (asmFile, "%s", iComments2);
1711 dbuf_write_and_destroy (&ovrBuf, asmFile);
1714 /* create the stack segment MOF */
1715 if (mainf && IFFUNC_HASBODY (mainf->type))
1717 fprintf (asmFile, "%s", iComments2);
1718 fprintf (asmFile, "; Stack segment in internal ram \n");
1719 fprintf (asmFile, "%s", iComments2);
1720 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1721 "__start__stack:\n\t.ds\t1\n\n");
1724 /* create the idata segment */
1725 if ((idata) && (mcs51_like))
1727 fprintf (asmFile, "%s", iComments2);
1728 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1729 fprintf (asmFile, "%s", iComments2);
1730 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1733 /* create the absolute idata/data segment */
1734 if ((i_abs) && (mcs51_like))
1736 fprintf (asmFile, "%s", iComments2);
1737 fprintf (asmFile, "; absolute internal ram data\n");
1738 fprintf (asmFile, "%s", iComments2);
1739 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1740 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1743 /* copy the bit segment */
1746 fprintf (asmFile, "%s", iComments2);
1747 fprintf (asmFile, "; bit data\n");
1748 fprintf (asmFile, "%s", iComments2);
1749 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1752 /* copy paged external ram data */
1755 fprintf (asmFile, "%s", iComments2);
1756 fprintf (asmFile, "; paged external ram data\n");
1757 fprintf (asmFile, "%s", iComments2);
1758 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1761 /* if external stack then reserve space for it */
1762 if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
1764 fprintf (asmFile, "%s", iComments2);
1765 fprintf (asmFile, "; external stack \n");
1766 fprintf (asmFile, "%s", iComments2);
1767 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1768 "__start__xstack:\n\t.ds\t1\n\n");
1771 /* copy external ram data */
1774 fprintf (asmFile, "%s", iComments2);
1775 fprintf (asmFile, "; external ram data\n");
1776 fprintf (asmFile, "%s", iComments2);
1777 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1780 /* create the absolute xdata segment */
1781 if (mcs51_like || TARGET_IS_HC08)
1783 fprintf (asmFile, "%s", iComments2);
1784 fprintf (asmFile, "; absolute external ram data\n");
1785 fprintf (asmFile, "%s", iComments2);
1786 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1789 /* copy external initialized ram data */
1790 fprintf (asmFile, "%s", iComments2);
1791 fprintf (asmFile, "; external initialized ram data\n");
1792 fprintf (asmFile, "%s", iComments2);
1793 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1795 /* If the port wants to generate any extra areas, let it do so. */
1796 if (port->extraAreas.genExtraAreaDeclaration)
1798 port->extraAreas.genExtraAreaDeclaration(asmFile,
1799 mainf && IFFUNC_HASBODY(mainf->type));
1802 /* copy the interrupt vector table */
1803 if (mainf && IFFUNC_HASBODY (mainf->type))
1805 fprintf (asmFile, "%s", iComments2);
1806 fprintf (asmFile, "; interrupt vector \n");
1807 fprintf (asmFile, "%s", iComments2);
1808 dbuf_write_and_destroy (&vBuf, asmFile);
1811 /* copy global & static initialisations */
1812 fprintf (asmFile, "%s", iComments2);
1813 fprintf (asmFile, "; global & static initialisations\n");
1814 fprintf (asmFile, "%s", iComments2);
1816 /* Everywhere we generate a reference to the static_name area,
1817 * (which is currently only here), we immediately follow it with a
1818 * definition of the post_static_name area. This guarantees that
1819 * the post_static_name area will immediately follow the static_name
1822 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1823 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1824 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1825 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1827 if (mainf && IFFUNC_HASBODY (mainf->type))
1829 if (port->genInitStartup)
1831 port->genInitStartup (asmFile);
1835 assert (mcs51_like);
1836 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1837 /* if external stack is specified then the
1838 higher order byte of the xdatalocation is
1839 going into P2 and the lower order going into
1841 if (options.useXstack)
1843 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1844 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1845 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1846 (unsigned int) options.xdata_loc & 0xff);
1849 // This should probably be a port option, but I'm being lazy.
1850 // on the 400, the firmware boot loader gives us a valid stack
1851 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1852 if (!TARGET_IS_DS400)
1854 /* initialise the stack pointer. JCF: aslink takes care of the location */
1855 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1858 fprintf (asmFile, "\t%ccall\t__sdcc_external_startup\n", options.acall_ajmp?'a':'l');
1859 fprintf (asmFile, "\tmov\ta,dpl\n");
1860 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1861 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1862 fprintf (asmFile, "__sdcc_init_data:\n");
1864 // if the port can copy the XINIT segment to XISEG
1867 port->genXINIT (asmFile);
1871 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1873 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
1875 /* This code is generated in the post-static area.
1876 * This area is guaranteed to follow the static area
1877 * by the ugly shucking and jiving about 20 lines ago.
1879 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1880 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1886 "%s", iComments2, iComments2);
1887 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1888 dbuf_write_and_destroy (&home->oBuf, asmFile);
1890 if (mainf && IFFUNC_HASBODY (mainf->type))
1892 /* entry point @ start of HOME */
1893 fprintf (asmFile, "__sdcc_program_startup:\n");
1895 /* put in jump or call to main */
1896 if (options.mainreturn)
1898 fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp?'a':'l'); /* needed? */
1899 fprintf (asmFile, ";\treturn from main will return to caller\n");
1903 fprintf (asmFile, "\t%ccall\t_main\n", options.acall_ajmp?'a':'l');
1904 fprintf (asmFile, ";\treturn from main will lock up\n");
1905 fprintf (asmFile, "\tsjmp .\n");
1908 /* copy over code */
1909 fprintf (asmFile, "%s", iComments2);
1910 fprintf (asmFile, "; code\n");
1911 fprintf (asmFile, "%s", iComments2);
1912 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1913 dbuf_write_and_destroy (&code->oBuf, asmFile);
1915 if (port->genAssemblerEnd)
1917 port->genAssemblerEnd (asmFile);