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 = ulFromVal (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));
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);
750 iloop = iloop ? iloop->next : NULL;
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) ulFromVal (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) (%s)\n",
1415 getBuildNumber(), __DATE__, getBuildEnvironment());
1416 fprintf (afile, "; This file was generated %s", asctime (localtime (&t)));
1417 fprintf (afile, "%s", iComments2);
1420 /*-----------------------------------------------------------------*/
1421 /* printPublics - generates .global for publics */
1422 /*-----------------------------------------------------------------*/
1424 printPublics (FILE * afile)
1428 fprintf (afile, "%s", iComments2);
1429 fprintf (afile, "; Public variables in this module\n");
1430 fprintf (afile, "%s", iComments2);
1432 for (sym = setFirstItem (publics); sym;
1433 sym = setNextItem (publics))
1434 tfprintf (afile, "\t!global\n", sym->rname);
1437 /*-----------------------------------------------------------------*/
1438 /* printExterns - generates .global for externs */
1439 /*-----------------------------------------------------------------*/
1441 printExterns (FILE * afile)
1445 fprintf (afile, "%s", iComments2);
1446 fprintf (afile, "; Externals used\n");
1447 fprintf (afile, "%s", iComments2);
1449 for (sym = setFirstItem (externs); sym;
1450 sym = setNextItem (externs))
1451 tfprintf (afile, "\t!extern\n", sym->rname);
1454 /*-----------------------------------------------------------------*/
1455 /* emitOverlay - will emit code for the overlay stuff */
1456 /*-----------------------------------------------------------------*/
1458 emitOverlay (struct dbuf_s * aBuf)
1462 if (!elementsInSet (ovrSetSets))
1463 dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1465 /* for each of the sets in the overlay segment do */
1466 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1467 ovrset = setNextItem (ovrSetSets))
1472 if (elementsInSet (ovrset))
1474 /* output the area informtion */
1475 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1478 for (sym = setFirstItem (ovrset); sym;
1479 sym = setNextItem (ovrset))
1481 /* if extern then it is in the publics table: do nothing */
1482 if (IS_EXTERN (sym->etype))
1485 /* if allocation required check is needed
1486 then check if the symbol really requires
1487 allocation only for local variables */
1488 if (!IS_AGGREGATE (sym->type) &&
1489 !(sym->_isparm && !IS_REGPARM (sym->etype))
1490 && !sym->allocreq && sym->level)
1493 /* if global variable & not static or extern
1494 and addPublics allowed then add it to the public set */
1495 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1496 && !IS_STATIC (sym->etype))
1498 addSetHead (&publics, sym);
1501 /* if extern then do nothing or is a function
1503 if (IS_FUNC (sym->type))
1506 /* print extra debug info if required */
1511 if (IS_STATIC (sym->etype))
1512 dbuf_printf (aBuf, "F%s$", moduleName); /* scope is file */
1514 dbuf_printf (aBuf, "G$"); /* scope is global */
1517 /* symbol is local */
1518 dbuf_printf (aBuf, "L%s$",
1519 (sym->localof ? sym->localof->name : "-null-"));
1520 dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1523 /* if is has an absolute address then generate
1524 an equate for this no need to allocate space */
1525 if (SPEC_ABSA (sym->etype))
1529 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1531 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1533 SPEC_ADDR (sym->etype));
1536 int size = getSize(sym->type);
1539 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1542 dbuf_printf (aBuf, "==.\n");
1544 /* allocate space */
1545 dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1546 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1554 /*-----------------------------------------------------------------*/
1555 /* spacesToUnderscores - replace spaces with underscores */
1556 /*-----------------------------------------------------------------*/
1558 spacesToUnderscores (char *dest, const char *src, size_t len)
1563 assert(dest != NULL);
1564 assert(src != NULL);
1568 for (p = dest, i = 0; *src != '\0' && i < len; ++src, ++i) {
1569 *p++ = isspace((unsigned char)*src) ? '_' : *src;
1577 /*-----------------------------------------------------------------*/
1578 /* glue - the final glue that hold the whole thing together */
1579 /*-----------------------------------------------------------------*/
1584 struct dbuf_s ovrBuf;
1586 char moduleBuf[PATH_MAX];
1589 dbuf_init(&vBuf, 4096);
1590 dbuf_init(&ovrBuf, 4096);
1592 if(port->general.glue_up_main &&
1593 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400))
1595 mcs51_like=1; /*So it has bits, sfr, sbits, data, idata, etc...*/
1602 /* print the global struct definitions */
1606 /* PENDING: this isn't the best place but it will do */
1607 if (port->general.glue_up_main)
1609 /* create the interrupt vector table */
1610 createInterruptVect (&vBuf);
1613 /* emit code for the all the variables declared */
1615 /* do the overlay segments */
1616 emitOverlay (&ovrBuf);
1618 outputDebugSymbols();
1620 /* now put it all together into the assembler file */
1621 /* create the assembler file name */
1623 /* -o option overrides default name? */
1624 if ((noAssemble || options.c1mode) && fullDstFileName)
1626 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1630 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1631 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1634 if (!(asmFile = fopen (scratchFileName, "w")))
1636 werror (E_FILE_OPEN_ERR, scratchFileName);
1640 /* initial comments */
1641 initialComments (asmFile);
1643 /* print module name */
1644 tfprintf (asmFile, "\t!module\n",
1645 spacesToUnderscores (moduleBuf, moduleName, sizeof moduleBuf));
1648 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1650 switch(options.model)
1652 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1653 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1654 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1655 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1656 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1657 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1660 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1661 if(options.useXstack) fprintf (asmFile, " --xstack");
1662 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1663 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1664 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1665 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1666 fprintf (asmFile, "\n");
1668 else if(TARGET_Z80_LIKE || TARGET_IS_HC08)
1670 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1673 tfprintf (asmFile, "\t!fileprelude\n");
1675 /* Let the port generate any global directives, etc. */
1676 if (port->genAssemblerPreamble)
1678 port->genAssemblerPreamble (asmFile);
1681 /* print the global variables in this module */
1682 printPublics (asmFile);
1683 if (port->assembler.externGlobal)
1684 printExterns (asmFile);
1687 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1689 /* copy the sfr segment */
1690 fprintf (asmFile, "%s", iComments2);
1691 fprintf (asmFile, "; special function registers\n");
1692 fprintf (asmFile, "%s", iComments2);
1693 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1698 /* copy the sbit segment */
1699 fprintf (asmFile, "%s", iComments2);
1700 fprintf (asmFile, "; special function bits\n");
1701 fprintf (asmFile, "%s", iComments2);
1702 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1704 /*JCF: Create the areas for the register banks*/
1705 if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3])
1707 fprintf (asmFile, "%s", iComments2);
1708 fprintf (asmFile, "; overlayable register banks\n");
1709 fprintf (asmFile, "%s", iComments2);
1711 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1712 if(RegBankUsed[1]||options.parms_in_bank1)
1713 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1715 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1717 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1721 fprintf (asmFile, "%s", iComments2);
1722 fprintf (asmFile, "; overlayable bit register bank\n");
1723 fprintf (asmFile, "%s", iComments2);
1724 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1725 fprintf (asmFile, "bits:\n\t.ds 1\n");
1726 fprintf (asmFile, "\tb0 = bits[0]\n");
1727 fprintf (asmFile, "\tb1 = bits[1]\n");
1728 fprintf (asmFile, "\tb2 = bits[2]\n");
1729 fprintf (asmFile, "\tb3 = bits[3]\n");
1730 fprintf (asmFile, "\tb4 = bits[4]\n");
1731 fprintf (asmFile, "\tb5 = bits[5]\n");
1732 fprintf (asmFile, "\tb6 = bits[6]\n");
1733 fprintf (asmFile, "\tb7 = bits[7]\n");
1737 /* copy the data segment */
1738 fprintf (asmFile, "%s", iComments2);
1739 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1740 fprintf (asmFile, "%s", iComments2);
1741 dbuf_write_and_destroy (&data->oBuf, asmFile);
1744 /* create the overlay segments */
1747 fprintf (asmFile, "%s", iComments2);
1748 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1749 fprintf (asmFile, "%s", iComments2);
1750 dbuf_write_and_destroy (&ovrBuf, asmFile);
1753 /* create the stack segment MOF */
1754 if (mainf && IFFUNC_HASBODY(mainf->type))
1756 fprintf (asmFile, "%s", iComments2);
1757 fprintf (asmFile, "; Stack segment in internal ram \n");
1758 fprintf (asmFile, "%s", iComments2);
1759 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1760 "__start__stack:\n\t.ds\t1\n\n");
1763 /* create the idata segment */
1764 if ( (idata) && (mcs51_like) )
1766 fprintf (asmFile, "%s", iComments2);
1767 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1768 fprintf (asmFile, "%s", iComments2);
1769 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1772 /* create the absolute idata/data segment */
1773 if ( (i_abs) && (mcs51_like) )
1775 fprintf (asmFile, "%s", iComments2);
1776 fprintf (asmFile, "; absolute internal ram data\n");
1777 fprintf (asmFile, "%s", iComments2);
1778 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1779 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1782 /* copy the bit segment */
1785 fprintf (asmFile, "%s", iComments2);
1786 fprintf (asmFile, "; bit data\n");
1787 fprintf (asmFile, "%s", iComments2);
1788 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1791 /* copy paged external ram data */
1794 fprintf (asmFile, "%s", iComments2);
1795 fprintf (asmFile, "; paged external ram data\n");
1796 fprintf (asmFile, "%s", iComments2);
1797 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1800 /* if external stack then reserve space for it */
1801 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1803 fprintf (asmFile, "%s", iComments2);
1804 fprintf (asmFile, "; external stack \n");
1805 fprintf (asmFile, "%s", iComments2);
1806 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1807 "__start__xstack:\n\t.ds\t1\n\n");
1810 /* copy external ram data */
1813 fprintf (asmFile, "%s", iComments2);
1814 fprintf (asmFile, "; external ram data\n");
1815 fprintf (asmFile, "%s", iComments2);
1816 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1819 /* create the absolute xdata segment */
1820 if (mcs51_like || TARGET_IS_HC08)
1822 fprintf (asmFile, "%s", iComments2);
1823 fprintf (asmFile, "; absolute external ram data\n");
1824 fprintf (asmFile, "%s", iComments2);
1825 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1828 /* copy external initialized ram data */
1829 fprintf (asmFile, "%s", iComments2);
1830 fprintf (asmFile, "; external initialized ram data\n");
1831 fprintf (asmFile, "%s", iComments2);
1832 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1834 /* If the port wants to generate any extra areas, let it do so. */
1835 if (port->extraAreas.genExtraAreaDeclaration)
1837 port->extraAreas.genExtraAreaDeclaration(asmFile,
1838 mainf && IFFUNC_HASBODY(mainf->type));
1841 /* copy the interrupt vector table */
1842 if (mainf && IFFUNC_HASBODY(mainf->type))
1844 fprintf (asmFile, "%s", iComments2);
1845 fprintf (asmFile, "; interrupt vector \n");
1846 fprintf (asmFile, "%s", iComments2);
1847 dbuf_write_and_destroy (&vBuf, asmFile);
1850 /* copy global & static initialisations */
1851 fprintf (asmFile, "%s", iComments2);
1852 fprintf (asmFile, "; global & static initialisations\n");
1853 fprintf (asmFile, "%s", iComments2);
1855 /* Everywhere we generate a reference to the static_name area,
1856 * (which is currently only here), we immediately follow it with a
1857 * definition of the post_static_name area. This guarantees that
1858 * the post_static_name area will immediately follow the static_name
1861 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1862 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1863 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1864 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1866 if (mainf && IFFUNC_HASBODY(mainf->type))
1868 if (port->genInitStartup)
1870 port->genInitStartup(asmFile);
1874 assert (mcs51_like);
1875 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1876 /* if external stack is specified then the
1877 higher order byte of the xdatalocation is
1878 going into P2 and the lower order going into
1880 if (options.useXstack)
1882 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1883 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1884 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1885 (unsigned int) options.xdata_loc & 0xff);
1888 // This should probably be a port option, but I'm being lazy.
1889 // on the 400, the firmware boot loader gives us a valid stack
1890 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1891 if (!TARGET_IS_DS400)
1893 /* initialise the stack pointer. JCF: aslink takes care of the location */
1894 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1897 fprintf (asmFile, "\t%ccall\t__sdcc_external_startup\n", options.acall_ajmp?'a':'l');
1898 fprintf (asmFile, "\tmov\ta,dpl\n");
1899 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1900 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1901 fprintf (asmFile, "__sdcc_init_data:\n");
1903 // if the port can copy the XINIT segment to XISEG
1906 port->genXINIT(asmFile);
1910 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1912 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1914 /* This code is generated in the post-static area.
1915 * This area is guaranteed to follow the static area
1916 * by the ugly shucking and jiving about 20 lines ago.
1918 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1919 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1925 "%s", iComments2, iComments2);
1926 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1927 dbuf_write_and_destroy (&home->oBuf, asmFile);
1929 if (mainf && IFFUNC_HASBODY(mainf->type))
1931 /* entry point @ start of HOME */
1932 fprintf (asmFile, "__sdcc_program_startup:\n");
1934 /* put in jump or call to main */
1935 if (options.mainreturn)
1937 fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp?'a':'l'); /* needed? */
1938 fprintf (asmFile, ";\treturn from main will return to caller\n");
1942 fprintf (asmFile, "\t%ccall\t_main\n", options.acall_ajmp?'a':'l');
1943 fprintf (asmFile, ";\treturn from main will lock up\n");
1944 fprintf (asmFile, "\tsjmp .\n");
1947 /* copy over code */
1948 fprintf (asmFile, "%s", iComments2);
1949 fprintf (asmFile, "; code\n");
1950 fprintf (asmFile, "%s", iComments2);
1951 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1952 dbuf_write_and_destroy (&code->oBuf, asmFile);
1954 if (port->genAssemblerEnd)
1956 port->genAssemblerEnd(asmFile);