1 /*-------------------------------------------------------------------------
3 SDCCglue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
31 #include "dbuf_string.h"
39 symbol *interrupts[INTNO_MAX+1];
41 void printIval (symbol *, sym_link *, initList *, struct dbuf_s *);
42 set *publics = NULL; /* public variables */
43 set *externs = NULL; /* Variables that are declared as extern */
45 unsigned maxInterrupts = 0;
48 set *pipeSet = NULL; /* set of pipes */
49 set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
50 set *tmpfileNameSet = NULL; /* All are unlinked at close. */
52 /*-----------------------------------------------------------------*/
53 /* closePipes - closes all pipes created by the compiler */
54 /*-----------------------------------------------------------------*/
55 DEFSETFUNC (closePipes)
68 /*-----------------------------------------------------------------*/
69 /* closeTmpFiles - closes all tmp files created by the compiler */
70 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
71 /*-----------------------------------------------------------------*/
72 DEFSETFUNC (closeTmpFiles)
85 /*-----------------------------------------------------------------*/
86 /* rmTmpFiles - unlinks all tmp files created by the compiler */
87 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
88 /*-----------------------------------------------------------------*/
89 DEFSETFUNC (rmTmpFiles)
104 aopLiteralLong (value * val, int offset, int size)
113 // assuming we have been warned before
117 /* if it is a float then it gets tricky */
118 /* otherwise it is fairly simple */
119 if (!IS_FLOAT (val->type)) {
120 unsigned long v = (unsigned long) floatFromVal (val);
125 tsprintf (buffer, sizeof(buffer),
126 "!immedbyte", (unsigned int) v & 0xff);
129 tsprintf (buffer, sizeof(buffer),
130 "!immedword", (unsigned int) v & 0xffff);
133 /* Hmm. Too big for now. */
136 return Safe_strdup (buffer);
139 /* PENDING: For now size must be 1 */
142 /* it is type float */
143 fl.f = (float) floatFromVal (val);
144 #ifdef WORDS_BIGENDIAN
145 tsprintf (buffer, sizeof(buffer),
146 "!immedbyte", fl.c[3 - offset]);
148 tsprintf (buffer, sizeof(buffer),
149 "!immedbyte", fl.c[offset]);
151 return Safe_strdup (buffer);
154 /*-----------------------------------------------------------------*/
155 /* aopLiteral - string from a literal value */
156 /*-----------------------------------------------------------------*/
158 aopLiteral (value * val, int offset)
160 return aopLiteralLong (val, offset, 1);
163 /*-----------------------------------------------------------------*/
164 /* emitRegularMap - emit code for maps with no special cases */
165 /*-----------------------------------------------------------------*/
167 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
177 /* PENDING: special case here - should remove */
178 if (!strcmp (map->sname, CODE_NAME))
179 dbuf_tprintf (&map->oBuf, "\t!areacode\n", map->sname);
180 else if (!strcmp (map->sname, DATA_NAME))
181 dbuf_tprintf (&map->oBuf, "\t!areadata\n", map->sname);
182 else if (!strcmp (map->sname, HOME_NAME))
183 dbuf_tprintf (&map->oBuf, "\t!areahome\n", map->sname);
185 dbuf_tprintf (&map->oBuf, "\t!area\n", map->sname);
188 for (sym = setFirstItem (map->syms); sym;
189 sym = setNextItem (map->syms))
193 /* if extern then add it into the extern list */
194 if (IS_EXTERN (sym->etype))
196 addSetHead (&externs, sym);
200 /* if allocation required check is needed
201 then check if the symbol really requires
202 allocation only for local variables */
204 if (arFlag && !IS_AGGREGATE (sym->type) &&
205 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
206 !sym->allocreq && sym->level)
209 /* for bitvar locals and parameters */
210 if (!arFlag && !sym->allocreq && sym->level
211 && !SPEC_ABSA (sym->etype)) {
215 /* if global variable & not static or extern
216 and addPublics allowed then add it to the public set */
217 if ((sym->level == 0 ||
218 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
220 !IS_STATIC (sym->etype) &&
221 (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
223 addSetHead (&publics, sym);
226 /* if extern then do nothing or is a function
228 if (IS_FUNC (sym->type) && !(sym->isitmp))
231 /* print extra debug info if required */
234 if (!sym->level) /* global */
236 if (IS_STATIC (sym->etype))
237 dbuf_printf (&map->oBuf, "F%s$", moduleName); /* scope is file */
239 dbuf_printf (&map->oBuf, "G$"); /* scope is global */
243 /* symbol is local */
244 dbuf_printf (&map->oBuf, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
246 dbuf_printf (&map->oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
249 /* if it has an initial value then do it only if
250 it is a global variable */
251 if (sym->ival && sym->level == 0) {
252 if ((SPEC_OCLS(sym->etype)==xidata) && !SPEC_ABSA (sym->etype)) {
253 /* create a new "XINIT (CODE)" symbol, that will be emitted later
255 newSym=copySymbol (sym);
256 SPEC_OCLS(newSym->etype)=xinit;
257 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
258 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
259 if (IS_SPEC (newSym->type))
260 SPEC_CONST (newSym->type) = 1;
262 DCL_PTR_CONST (newSym->type) = 1;
263 SPEC_STAT(newSym->etype)=1;
264 resolveIvalSym(newSym->ival, newSym->type);
266 // add it to the "XINIT (CODE)" segment
267 addSet(&xinit->syms, newSym);
269 if (!SPEC_ABSA (sym->etype))
271 struct dbuf_s tmpBuf;
273 dbuf_init(&tmpBuf, 4096);
274 // before allocation we must parse the sym->ival tree
275 // but without actually generating initialization code
277 resolveIvalSym (sym->ival, sym->type);
278 printIval (sym, sym->type, sym->ival, &tmpBuf);
280 dbuf_destroy(&tmpBuf);
283 if (IS_AGGREGATE (sym->type)) {
284 ival = initAggregates (sym, sym->ival, NULL);
286 if (getNelements(sym->type, sym->ival)>1) {
287 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
290 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
291 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
293 codeOutBuf = &statsg->oBuf;
296 // set ival's lineno to where the symbol was defined
297 setAstLineno (ival, lineno=sym->lineDef);
298 // check if this is not a constant expression
299 if (!constExprTree(ival)) {
300 werror (E_CONST_EXPECTED, "found expression");
301 // but try to do it anyway
304 if (!astErrors(ival))
305 eBBlockFromiCode (iCodeFromAst (ival));
311 /* if it has an absolute address then generate
312 an equate for this no need to allocate space */
313 if (SPEC_ABSA (sym->etype) && !sym->ival)
317 dbuf_printf (&map->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
319 if (TARGET_IS_XA51) {
322 } else if (map==bit || map==sfrbit) {
326 dbuf_printf (&map->oBuf, "%s\t%s\t0x%04x\n",
328 SPEC_ADDR (sym->etype));
332 int size = getSize (sym->type) + sym->flexArrayLength;
334 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
338 dbuf_printf (&map->oBuf, "==.\n");
340 if (SPEC_ABSA (sym->etype))
342 dbuf_tprintf (&map->oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
344 if (IS_STATIC (sym->etype) || sym->level)
345 dbuf_tprintf (&map->oBuf, "!slabeldef\n", sym->rname);
347 dbuf_tprintf (&map->oBuf, "!labeldef\n", sym->rname);
348 dbuf_tprintf (&map->oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
354 /*-----------------------------------------------------------------*/
355 /* initPointer - pointer initialization code massaging */
356 /*-----------------------------------------------------------------*/
358 initPointer (initList * ilist, sym_link *toType)
364 return valCastLiteral(toType, 0.0);
367 expr = list2expr (ilist);
372 /* try it the old way first */
373 if ((val = constExprValue (expr, FALSE)))
376 /* ( ptr + constant ) */
377 if (IS_AST_OP (expr) &&
378 (expr->opval.op == '+' || expr->opval.op == '-') &&
379 IS_AST_SYM_VALUE (expr->left) &&
380 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
381 compareType(toType, expr->left->ftype) &&
382 IS_AST_LIT_VALUE (expr->right)) {
383 return valForCastAggr (expr->left, expr->left->ftype,
389 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
390 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
391 if (compareType(toType, expr->left->ftype)!=1) {
392 werror (W_INIT_WRONG);
393 printFromToType(expr->left->ftype, toType);
399 /* no then we have to do these cludgy checks */
400 /* pointers can be initialized with address of
401 a variable or address of an array element */
402 if (IS_AST_OP (expr) && expr->opval.op == '&') {
403 /* address of symbol */
404 if (IS_AST_SYM_VALUE (expr->left)) {
405 val = AST_VALUE (expr->left);
406 val->type = newLink (DECLARATOR);
407 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
408 DCL_TYPE (val->type) = CPOINTER;
409 DCL_PTR_CONST (val->type) = port->mem.code_ro;
411 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
412 DCL_TYPE (val->type) = FPOINTER;
413 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
414 DCL_TYPE (val->type) = PPOINTER;
415 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
416 DCL_TYPE (val->type) = IPOINTER;
417 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
418 DCL_TYPE (val->type) = EEPPOINTER;
420 DCL_TYPE (val->type) = POINTER;
421 val->type->next = expr->left->ftype;
422 val->etype = getSpec (val->type);
426 /* if address of indexed array */
427 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
428 return valForArray (expr->left);
430 /* if address of structure element then
432 if (IS_AST_OP (expr->left) &&
433 expr->left->opval.op == '.') {
434 return valForStructElem (expr->left->left,
439 (&some_struct)->element */
440 if (IS_AST_OP (expr->left) &&
441 expr->left->opval.op == PTR_OP &&
442 IS_ADDRESS_OF_OP (expr->left->left)) {
443 return valForStructElem (expr->left->left->left,
447 /* case 3. (((char *) &a) +/- constant) */
448 if (IS_AST_OP (expr) &&
449 (expr->opval.op == '+' || expr->opval.op == '-') &&
450 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
451 IS_AST_OP (expr->left->right) &&
452 expr->left->right->opval.op == '&' &&
453 IS_AST_LIT_VALUE (expr->right)) {
455 return valForCastAggr (expr->left->right->left,
456 expr->left->left->opval.lnk,
457 expr->right, expr->opval.op);
460 /* case 4. (char *)(array type) */
461 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
462 IS_ARRAY(expr->right->ftype)) {
464 val = copyValue (AST_VALUE (expr->right));
465 val->type = newLink (DECLARATOR);
466 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
467 DCL_TYPE (val->type) = CPOINTER;
468 DCL_PTR_CONST (val->type) = port->mem.code_ro;
470 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
471 DCL_TYPE (val->type) = FPOINTER;
472 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
473 DCL_TYPE (val->type) = PPOINTER;
474 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
475 DCL_TYPE (val->type) = IPOINTER;
476 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
477 DCL_TYPE (val->type) = EEPPOINTER;
479 DCL_TYPE (val->type) = POINTER;
480 val->type->next = expr->right->ftype->next;
481 val->etype = getSpec (val->type);
486 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
488 werror (E_INCOMPAT_PTYPES);
493 /*-----------------------------------------------------------------*/
494 /* printChar - formats and prints a characater string with DB */
495 /*-----------------------------------------------------------------*/
497 printChar (struct dbuf_s * oBuf, char *s, int plen)
505 while (len && pplen < plen)
508 while (i && pplen < plen)
510 if (*s < ' ' || *s == '\"' || *s=='\\')
514 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
515 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char)*s);
530 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
541 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
546 /*-----------------------------------------------------------------*/
547 /* return the generic pointer high byte for a given pointer type. */
548 /*-----------------------------------------------------------------*/
550 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
558 werror (E_CANNOT_USE_GENERIC_POINTER,
559 iname ? iname : "<null>",
560 oname ? oname : "<null>");
567 return GPTYPE_XSTACK;
569 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
577 /*-----------------------------------------------------------------*/
578 /* printPointerType - generates ival for pointer type */
579 /*-----------------------------------------------------------------*/
581 _printPointerType (struct dbuf_s * oBuf, const char *name)
583 if (options.model == MODEL_FLAT24)
585 if (port->little_endian)
586 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
588 dbuf_printf (oBuf, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
592 if (port->little_endian)
593 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8)", name, name);
595 dbuf_printf (oBuf, "\t.byte (%s >> 8),%s", name, name);
599 /*-----------------------------------------------------------------*/
600 /* printPointerType - generates ival for pointer type */
601 /*-----------------------------------------------------------------*/
603 printPointerType (struct dbuf_s * oBuf, const char *name)
605 _printPointerType (oBuf, name);
606 dbuf_printf (oBuf, "\n");
609 /*-----------------------------------------------------------------*/
610 /* printGPointerType - generates ival for generic pointer type */
611 /*-----------------------------------------------------------------*/
613 printGPointerType (struct dbuf_s * oBuf, const char *iname, const char *oname,
614 const unsigned int type)
616 _printPointerType (oBuf, iname);
617 dbuf_printf (oBuf, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
620 /*-----------------------------------------------------------------*/
621 /* printIvalType - generates ival for int/char */
622 /*-----------------------------------------------------------------*/
624 printIvalType (symbol *sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
628 /* if initList is deep */
629 if (ilist && (ilist->type == INIT_DEEP))
630 ilist = ilist->init.deep;
632 if (!(val = list2val (ilist))) {
633 // assuming a warning has been thrown
637 if (val->type != type) {
638 val = valCastLiteral(type, floatFromVal(val));
641 switch (getSize (type)) {
644 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
646 dbuf_tprintf (oBuf, "\t!dbs\n",
647 aopLiteral (val, 0));
651 if (port->use_dw_for_init)
652 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
653 else if (port->little_endian)
654 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
656 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
660 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
661 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
663 else if (port->little_endian) {
664 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
665 aopLiteral (val, 0), aopLiteral (val, 1),
666 aopLiteral (val, 2), aopLiteral (val, 3));
669 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
670 aopLiteral (val, 3), aopLiteral (val, 2),
671 aopLiteral (val, 1), aopLiteral (val, 0));
677 /*-----------------------------------------------------------------*/
678 /* printIvalBitFields - generate initializer for bitfields */
679 /*-----------------------------------------------------------------*/
680 void printIvalBitFields(symbol **sym, initList **ilist, struct dbuf_s * oBuf)
684 initList *lilist = *ilist ;
685 unsigned long ival = 0;
691 val = list2val(lilist);
693 if (SPEC_BLEN(lsym->etype) > 8) {
694 size += ((SPEC_BLEN (lsym->etype) / 8) +
695 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
698 size = ((SPEC_BLEN (lsym->etype) / 8) +
699 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
701 i = (unsigned long)floatFromVal(val);
702 i <<= SPEC_BSTR (lsym->etype);
704 if (! ( lsym->next &&
705 (IS_BITFIELD(lsym->next->type)) &&
706 (SPEC_BSTR(lsym->next->etype)))) break;
708 lilist = lilist->next;
712 dbuf_tprintf (oBuf, "\t!db !constbyte\n",ival);
716 dbuf_tprintf (oBuf, "\t!dw !constword\n",ival);
718 case 4: /* EEP: why is this db and not dw? */
719 dbuf_tprintf (oBuf, "\t!db !constword,!constword\n",
720 (ival >> 8) & 0xffff, (ival & 0xffff));
727 /*-----------------------------------------------------------------*/
728 /* printIvalStruct - generates initial value for structures */
729 /*-----------------------------------------------------------------*/
731 printIvalStruct (symbol * sym, sym_link * type,
732 initList * ilist, struct dbuf_s * oBuf)
735 initList *iloop = NULL;
737 sflds = SPEC_STRUCT (type)->fields;
740 if (ilist->type != INIT_DEEP) {
741 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
745 iloop = ilist->init.deep;
748 if (SPEC_STRUCT (type)->type == UNION) {
749 printIval (sym, sflds->type, iloop, oBuf);
752 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
753 if (IS_BITFIELD(sflds->type)) {
754 printIvalBitFields(&sflds, &iloop, oBuf);
756 printIval (sym, sflds->type, iloop, oBuf);
761 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
766 /*-----------------------------------------------------------------*/
767 /* printIvalChar - generates initital value for character array */
768 /*-----------------------------------------------------------------*/
770 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s)
773 unsigned int size = DCL_ELEM (type);
777 val = list2val (ilist);
778 /* if the value is a character string */
779 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
783 /* we have not been given a size, but now we know it */
784 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
785 /* but first check, if it's a flexible array */
786 if (sym && IS_STRUCT (sym->type))
787 sym->flexArrayLength = size;
789 DCL_ELEM (type) = size;
792 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
800 printChar (oBuf, s, strlen (s) + 1);
804 /*-----------------------------------------------------------------*/
805 /* printIvalArray - generates code for array initialization */
806 /*-----------------------------------------------------------------*/
808 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
809 struct dbuf_s * oBuf)
813 unsigned int size = 0;
816 /* take care of the special case */
817 /* array of characters can be init */
819 if (IS_CHAR (type->next)) {
820 val = list2val(ilist);
822 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
825 if (!IS_LITERAL(val->etype)) {
826 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
829 if (printIvalChar (sym, type,
830 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
831 oBuf, SPEC_CVAL (sym->etype).v_char))
834 /* not the special case */
835 if (ilist->type != INIT_DEEP) {
836 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
840 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
841 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
842 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
845 printIval (sym, type->next, iloop, oBuf);
849 if (DCL_ELEM(type)) {
850 // pad with zeros if needed
851 if (size<DCL_ELEM(type)) {
852 size = (DCL_ELEM(type) - size) * getSize(type->next);
854 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
858 /* we have not been given a size, but now we know it */
859 /* but first check, if it's a flexible array */
860 if (IS_STRUCT (sym->type))
861 sym->flexArrayLength = size * getSize (type->next);
863 DCL_ELEM (type) = size;
869 /*-----------------------------------------------------------------*/
870 /* printIvalFuncPtr - generate initial value for function pointers */
871 /*-----------------------------------------------------------------*/
873 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
879 val = list2val (ilist);
881 val = valCastLiteral(type, 0.0);
884 // an error has been thrown already
888 if (IS_LITERAL(val->etype)) {
889 if (compareType(type, val->etype) == 0) {
890 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
891 printFromToType (val->type, type);
893 printIvalCharPtr (NULL, type, val, oBuf);
897 /* check the types */
898 if ((dLvl = compareType (val->type, type->next)) <= 0)
900 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
904 /* now generate the name */
907 if (port->use_dw_for_init)
909 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
913 printPointerType (oBuf, val->name);
916 else if (port->use_dw_for_init)
918 dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
922 printPointerType (oBuf, val->sym->rname);
928 /*-----------------------------------------------------------------*/
929 /* printIvalCharPtr - generates initial values for character pointers */
930 /*-----------------------------------------------------------------*/
932 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
936 /* PENDING: this is _very_ mcs51 specific, including a magic
938 It's also endin specific.
940 size = getSize (type);
942 if (val->name && strlen (val->name))
944 if (size == 1) /* This appears to be Z80 specific?? */
947 "\t!dbs\n", val->name);
949 else if (size == FPTRSIZE)
951 if (port->use_dw_for_init)
953 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
957 printPointerType (oBuf, val->name);
960 else if (size == GPTRSIZE)
963 if (IS_PTR (val->type)) {
964 type = DCL_TYPE (val->type);
966 type = PTR_TYPE (SPEC_OCLS (val->etype));
968 if (val->sym && val->sym->isstrlit) {
969 // this is a literal string
972 printGPointerType (oBuf, val->name, sym->name, type);
976 fprintf (stderr, "*** internal error: unknown size in "
977 "printIvalCharPtr.\n");
982 // these are literals assigned to pointers
986 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
989 if (port->use_dw_for_init)
990 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
991 else if (port->little_endian)
992 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
993 aopLiteral (val, 0), aopLiteral (val, 1));
995 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
996 aopLiteral (val, 1), aopLiteral (val, 0));
999 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1000 // non-zero mcs51 generic pointer
1001 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1003 if (port->little_endian) {
1004 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1005 aopLiteral (val, 0),
1006 aopLiteral (val, 1),
1007 aopLiteral (val, 2));
1009 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1010 aopLiteral (val, 2),
1011 aopLiteral (val, 1),
1012 aopLiteral (val, 0));
1016 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1017 // non-zero ds390 generic pointer
1018 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1020 if (port->little_endian) {
1021 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1022 aopLiteral (val, 0),
1023 aopLiteral (val, 1),
1024 aopLiteral (val, 2),
1025 aopLiteral (val, 3));
1027 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1028 aopLiteral (val, 3),
1029 aopLiteral (val, 2),
1030 aopLiteral (val, 1),
1031 aopLiteral (val, 0));
1039 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1040 addSet (&statsg->syms, val->sym);
1046 /*-----------------------------------------------------------------*/
1047 /* printIvalPtr - generates initial value for pointers */
1048 /*-----------------------------------------------------------------*/
1050 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1056 if (ilist && (ilist->type == INIT_DEEP))
1057 ilist = ilist->init.deep;
1059 /* function pointer */
1060 if (IS_FUNC (type->next))
1062 printIvalFuncPtr (type, ilist, oBuf);
1066 if (!(val = initPointer (ilist, type)))
1069 /* if character pointer */
1070 if (IS_CHAR (type->next))
1071 if (printIvalCharPtr (sym, type, val, oBuf))
1074 /* check the type */
1075 if (compareType (type, val->type) == 0) {
1076 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1077 printFromToType (val->type, type);
1080 /* if val is literal */
1081 if (IS_LITERAL (val->etype))
1083 switch (getSize (type))
1086 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
1089 if (port->use_dw_for_init)
1090 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1091 else if (port->little_endian)
1092 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1094 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1096 case 3: // how about '390??
1097 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1098 if (port->little_endian)
1100 dbuf_printf (oBuf, "\t.byte %s,%s",
1101 aopLiteral (val, 0), aopLiteral (val, 1));
1105 dbuf_printf (oBuf, "\t.byte %s,%s",
1106 aopLiteral (val, 1), aopLiteral (val, 0));
1108 if (IS_GENPTR (val->type))
1109 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1110 else if (IS_PTR (val->type))
1111 dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1113 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1119 size = getSize (type);
1121 if (size == 1) /* Z80 specific?? */
1123 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1125 else if (size == FPTRSIZE)
1127 if (port->use_dw_for_init) {
1128 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1130 printPointerType (oBuf, val->name);
1133 else if (size == GPTRSIZE)
1135 printGPointerType (oBuf, val->name, sym->name,
1136 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1137 PTR_TYPE (SPEC_OCLS (val->etype))));
1142 /*-----------------------------------------------------------------*/
1143 /* printIval - generates code for initial value */
1144 /*-----------------------------------------------------------------*/
1146 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1150 /* if structure then */
1151 if (IS_STRUCT (type))
1153 printIvalStruct (sym, type, ilist, oBuf);
1157 /* if this is an array */
1158 if (IS_ARRAY (type))
1160 printIvalArray (sym, type, ilist, oBuf);
1166 // not an aggregate, ilist must be a node
1167 if (ilist->type!=INIT_NODE) {
1168 // or a 1-element list
1169 if (ilist->init.deep->next) {
1170 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1173 ilist=ilist->init.deep;
1177 // and the type must match
1178 itype=ilist->init.node->ftype;
1180 if (compareType(type, itype)==0) {
1181 // special case for literal strings
1182 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1183 // which are really code pointers
1184 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1187 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1188 printFromToType(itype, type);
1193 /* if this is a pointer */
1196 printIvalPtr (sym, type, ilist, oBuf);
1200 /* if type is SPECIFIER */
1203 printIvalType (sym, type, ilist, oBuf);
1208 /*-----------------------------------------------------------------*/
1209 /* emitStaticSeg - emitcode for the static segment */
1210 /*-----------------------------------------------------------------*/
1212 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1216 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1218 /* for all variables in this segment do */
1219 for (sym = setFirstItem (map->syms); sym;
1220 sym = setNextItem (map->syms))
1223 /* if it is "extern" then do nothing */
1224 if (IS_EXTERN (sym->etype))
1227 /* if it is not static add it to the public table */
1228 if (!IS_STATIC (sym->etype))
1230 addSetHead (&publics, sym);
1233 /* print extra debug info if required */
1234 if (options.debug) {
1238 if (IS_STATIC (sym->etype))
1239 dbuf_printf (oBuf, "F%s$", moduleName); /* scope is file */
1241 dbuf_printf (oBuf, "G$"); /* scope is global */
1244 /* symbol is local */
1245 dbuf_printf (oBuf, "L%s$",
1246 (sym->localof ? sym->localof->name : "-null-"));
1247 dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1250 /* if it has an absolute address and no initializer */
1251 if (SPEC_ABSA (sym->etype) && !sym->ival)
1254 dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1256 dbuf_printf (oBuf, "%s\t=\t0x%04x\n",
1258 SPEC_ADDR (sym->etype));
1263 dbuf_printf (oBuf, " == .\n");
1265 /* if it has an initial value */
1268 if (SPEC_ABSA (sym->etype))
1270 dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1272 dbuf_printf (oBuf, "%s:\n", sym->rname);
1274 resolveIvalSym (sym->ival, sym->type);
1275 printIval (sym, sym->type, sym->ival, oBuf);
1277 /* if sym is a simple string and sym->ival is a string,
1278 WE don't need it anymore */
1279 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1280 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1281 list2val(sym->ival)->sym->isstrlit) {
1282 freeStringSymbol(list2val(sym->ival)->sym);
1286 /* allocate space */
1287 int size = getSize (sym->type);
1290 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1292 dbuf_printf (oBuf, "%s:\n", sym->rname);
1293 /* special case for character strings */
1294 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1295 SPEC_CVAL (sym->etype).v_char)
1297 SPEC_CVAL (sym->etype).v_char,
1300 dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1306 /*-----------------------------------------------------------------*/
1307 /* emitMaps - emits the code for the data portion the code */
1308 /*-----------------------------------------------------------------*/
1312 int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */
1313 /* ports but let's be conservative - EEP */
1316 /* no special considerations for the following
1317 data, idata & bit & xdata */
1318 emitRegularMap (data, TRUE, TRUE);
1319 emitRegularMap (idata, TRUE, TRUE);
1320 emitRegularMap (d_abs, TRUE, TRUE);
1321 emitRegularMap (i_abs, TRUE, TRUE);
1322 emitRegularMap (bit, TRUE, TRUE);
1323 emitRegularMap (pdata, TRUE, TRUE);
1324 emitRegularMap (xdata, TRUE, TRUE);
1325 if (port->genXINIT) {
1326 emitRegularMap (xidata, TRUE, TRUE);
1328 emitRegularMap (sfr, publicsfr, FALSE);
1329 emitRegularMap (sfrbit, publicsfr, FALSE);
1330 emitRegularMap (home, TRUE, FALSE);
1331 emitRegularMap (code, TRUE, FALSE);
1333 if (options.const_seg) {
1334 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
1336 emitStaticSeg (statsg, &code->oBuf);
1337 if (port->genXINIT) {
1338 dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
1339 emitStaticSeg (xinit, &code->oBuf);
1341 dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
1342 emitStaticSeg (c_abs, &code->oBuf);
1346 /*-----------------------------------------------------------------*/
1347 /* flushStatics - flush all currently defined statics out to file */
1348 /* and delete. Temporary function */
1349 /*-----------------------------------------------------------------*/
1353 emitStaticSeg (statsg, codeOutBuf);
1354 statsg->syms = NULL;
1357 /*-----------------------------------------------------------------*/
1358 /* createInterruptVect - creates the interrupt vector */
1359 /*-----------------------------------------------------------------*/
1361 createInterruptVect (struct dbuf_s *vBuf)
1363 mainf = newSymbol ("main", 0);
1366 /* only if the main function exists */
1367 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1369 if (!options.cc_only && !noAssemble && !options.c1mode)
1374 /* if the main is only a prototype ie. no body then do nothing */
1375 if (!IFFUNC_HASBODY(mainf->type))
1377 /* if ! compile only then main function should be present */
1378 if (!options.cc_only && !noAssemble)
1383 dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
1384 dbuf_printf (vBuf, "__interrupt_vect:\n");
1387 if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
1389 /* There's no such thing as a "generic" interrupt table header. */
1396 ";--------------------------------------------------------\n"
1397 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1401 ";--------------------------------------------------------\n"};
1404 /*-----------------------------------------------------------------*/
1405 /* initialComments - puts in some initial comments */
1406 /*-----------------------------------------------------------------*/
1408 initialComments (FILE * afile)
1412 fprintf (afile, "%s", iComments1);
1413 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s)\n", getBuildNumber(), __DATE__);
1414 fprintf (afile, "; This file generated %s", asctime (localtime (&t)));
1415 fprintf (afile, "%s", iComments2);
1418 /*-----------------------------------------------------------------*/
1419 /* printPublics - generates .global for publics */
1420 /*-----------------------------------------------------------------*/
1422 printPublics (FILE * afile)
1426 fprintf (afile, "%s", iComments2);
1427 fprintf (afile, "; Public variables in this module\n");
1428 fprintf (afile, "%s", iComments2);
1430 for (sym = setFirstItem (publics); sym;
1431 sym = setNextItem (publics))
1432 tfprintf (afile, "\t!global\n", sym->rname);
1435 /*-----------------------------------------------------------------*/
1436 /* printExterns - generates .global for externs */
1437 /*-----------------------------------------------------------------*/
1439 printExterns (FILE * afile)
1443 fprintf (afile, "%s", iComments2);
1444 fprintf (afile, "; Externals used\n");
1445 fprintf (afile, "%s", iComments2);
1447 for (sym = setFirstItem (externs); sym;
1448 sym = setNextItem (externs))
1449 tfprintf (afile, "\t!extern\n", sym->rname);
1452 /*-----------------------------------------------------------------*/
1453 /* emitOverlay - will emit code for the overlay stuff */
1454 /*-----------------------------------------------------------------*/
1456 emitOverlay (struct dbuf_s * aBuf)
1460 if (!elementsInSet (ovrSetSets))
1461 dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1463 /* for each of the sets in the overlay segment do */
1464 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1465 ovrset = setNextItem (ovrSetSets))
1470 if (elementsInSet (ovrset))
1472 /* output the area informtion */
1473 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1476 for (sym = setFirstItem (ovrset); sym;
1477 sym = setNextItem (ovrset))
1479 /* if extern then it is in the publics table: do nothing */
1480 if (IS_EXTERN (sym->etype))
1483 /* if allocation required check is needed
1484 then check if the symbol really requires
1485 allocation only for local variables */
1486 if (!IS_AGGREGATE (sym->type) &&
1487 !(sym->_isparm && !IS_REGPARM (sym->etype))
1488 && !sym->allocreq && sym->level)
1491 /* if global variable & not static or extern
1492 and addPublics allowed then add it to the public set */
1493 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1494 && !IS_STATIC (sym->etype))
1496 addSetHead (&publics, sym);
1499 /* if extern then do nothing or is a function
1501 if (IS_FUNC (sym->type))
1504 /* print extra debug info if required */
1509 if (IS_STATIC (sym->etype))
1510 dbuf_printf (aBuf, "F%s$", moduleName); /* scope is file */
1512 dbuf_printf (aBuf, "G$"); /* scope is global */
1515 /* symbol is local */
1516 dbuf_printf (aBuf, "L%s$",
1517 (sym->localof ? sym->localof->name : "-null-"));
1518 dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1521 /* if is has an absolute address then generate
1522 an equate for this no need to allocate space */
1523 if (SPEC_ABSA (sym->etype))
1527 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1529 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1531 SPEC_ADDR (sym->etype));
1534 int size = getSize(sym->type);
1537 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1540 dbuf_printf (aBuf, "==.\n");
1542 /* allocate space */
1543 dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1544 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1552 /*-----------------------------------------------------------------*/
1553 /* spacesToUnderscores - replace spaces with underscores */
1554 /*-----------------------------------------------------------------*/
1556 spacesToUnderscores (char *dest, const char *src, size_t len)
1561 assert(dest != NULL);
1562 assert(src != NULL);
1566 for (p = dest, i = 0; *src != '\0' && i < len; ++src, ++i) {
1567 *p++ = isspace((unsigned char)*src) ? '_' : *src;
1575 /*-----------------------------------------------------------------*/
1576 /* glue - the final glue that hold the whole thing together */
1577 /*-----------------------------------------------------------------*/
1582 struct dbuf_s ovrBuf;
1584 char moduleBuf[PATH_MAX];
1587 dbuf_init(&vBuf, 4096);
1588 dbuf_init(&ovrBuf, 4096);
1590 if(port->general.glue_up_main &&
1591 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400))
1593 mcs51_like=1; /*So it has bits, sfr, sbits, data, idata, etc...*/
1600 /* print the global struct definitions */
1604 /* PENDING: this isn't the best place but it will do */
1605 if (port->general.glue_up_main)
1607 /* create the interrupt vector table */
1608 createInterruptVect (&vBuf);
1611 /* emit code for the all the variables declared */
1613 /* do the overlay segments */
1614 emitOverlay (&ovrBuf);
1616 outputDebugSymbols();
1618 /* now put it all together into the assembler file */
1619 /* create the assembler file name */
1621 /* -o option overrides default name? */
1622 if ((noAssemble || options.c1mode) && fullDstFileName)
1624 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1628 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1629 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1632 if (!(asmFile = fopen (scratchFileName, "w")))
1634 werror (E_FILE_OPEN_ERR, scratchFileName);
1638 /* initial comments */
1639 initialComments (asmFile);
1641 /* print module name */
1642 tfprintf (asmFile, "\t!module\n",
1643 spacesToUnderscores (moduleBuf, moduleName, sizeof moduleBuf));
1646 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1648 switch(options.model)
1650 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1651 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1652 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1653 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1654 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1655 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1658 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1659 if(options.useXstack) fprintf (asmFile, " --xstack");
1660 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1661 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1662 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1663 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1664 fprintf (asmFile, "\n");
1666 else if(TARGET_IS_Z80 || TARGET_IS_GBZ80 || TARGET_IS_HC08)
1668 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1671 tfprintf (asmFile, "\t!fileprelude\n");
1673 /* Let the port generate any global directives, etc. */
1674 if (port->genAssemblerPreamble)
1676 port->genAssemblerPreamble (asmFile);
1679 /* print the global variables in this module */
1680 printPublics (asmFile);
1681 if (port->assembler.externGlobal)
1682 printExterns (asmFile);
1685 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1687 /* copy the sfr segment */
1688 fprintf (asmFile, "%s", iComments2);
1689 fprintf (asmFile, "; special function registers\n");
1690 fprintf (asmFile, "%s", iComments2);
1691 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1696 /* copy the sbit segment */
1697 fprintf (asmFile, "%s", iComments2);
1698 fprintf (asmFile, "; special function bits\n");
1699 fprintf (asmFile, "%s", iComments2);
1700 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1702 /*JCF: Create the areas for the register banks*/
1703 if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3])
1705 fprintf (asmFile, "%s", iComments2);
1706 fprintf (asmFile, "; overlayable register banks\n");
1707 fprintf (asmFile, "%s", iComments2);
1709 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1710 if(RegBankUsed[1]||options.parms_in_bank1)
1711 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1713 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1715 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1719 fprintf (asmFile, "%s", iComments2);
1720 fprintf (asmFile, "; overlayable bit register bank\n");
1721 fprintf (asmFile, "%s", iComments2);
1722 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1723 fprintf (asmFile, "bits:\n\t.ds 1\n");
1724 fprintf (asmFile, "\tb0 = bits[0]\n");
1725 fprintf (asmFile, "\tb1 = bits[1]\n");
1726 fprintf (asmFile, "\tb2 = bits[2]\n");
1727 fprintf (asmFile, "\tb3 = bits[3]\n");
1728 fprintf (asmFile, "\tb4 = bits[4]\n");
1729 fprintf (asmFile, "\tb5 = bits[5]\n");
1730 fprintf (asmFile, "\tb6 = bits[6]\n");
1731 fprintf (asmFile, "\tb7 = bits[7]\n");
1735 /* copy the data segment */
1736 fprintf (asmFile, "%s", iComments2);
1737 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1738 fprintf (asmFile, "%s", iComments2);
1739 dbuf_write_and_destroy (&data->oBuf, asmFile);
1742 /* create the overlay segments */
1744 fprintf (asmFile, "%s", iComments2);
1745 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1746 fprintf (asmFile, "%s", iComments2);
1747 dbuf_write_and_destroy (&ovrBuf, asmFile);
1750 /* create the stack segment MOF */
1751 if (mainf && IFFUNC_HASBODY(mainf->type))
1753 fprintf (asmFile, "%s", iComments2);
1754 fprintf (asmFile, "; Stack segment in internal ram \n");
1755 fprintf (asmFile, "%s", iComments2);
1756 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1757 "__start__stack:\n\t.ds\t1\n\n");
1760 /* create the idata segment */
1761 if ( (idata) && (mcs51_like) ) {
1762 fprintf (asmFile, "%s", iComments2);
1763 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1764 fprintf (asmFile, "%s", iComments2);
1765 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1768 /* create the absolute idata/data segment */
1769 if ( (i_abs) && (mcs51_like) ) {
1770 fprintf (asmFile, "%s", iComments2);
1771 fprintf (asmFile, "; absolute internal ram data\n");
1772 fprintf (asmFile, "%s", iComments2);
1773 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1774 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1777 /* copy the bit segment */
1779 fprintf (asmFile, "%s", iComments2);
1780 fprintf (asmFile, "; bit data\n");
1781 fprintf (asmFile, "%s", iComments2);
1782 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1785 /* copy paged external ram data */
1788 fprintf (asmFile, "%s", iComments2);
1789 fprintf (asmFile, "; paged external ram data\n");
1790 fprintf (asmFile, "%s", iComments2);
1791 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1794 /* if external stack then reserve space for it */
1795 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1797 fprintf (asmFile, "%s", iComments2);
1798 fprintf (asmFile, "; external stack \n");
1799 fprintf (asmFile, "%s", iComments2);
1800 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1801 "__start__xstack:\n\t.ds\t1\n\n");
1804 /* copy external ram data */
1806 fprintf (asmFile, "%s", iComments2);
1807 fprintf (asmFile, "; external ram data\n");
1808 fprintf (asmFile, "%s", iComments2);
1809 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1812 /* copy external initialized ram data */
1813 fprintf (asmFile, "%s", iComments2);
1814 fprintf (asmFile, "; external initialized ram data\n");
1815 fprintf (asmFile, "%s", iComments2);
1816 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1818 /* If the port wants to generate any extra areas, let it do so. */
1819 if (port->extraAreas.genExtraAreaDeclaration)
1821 port->extraAreas.genExtraAreaDeclaration(asmFile,
1822 mainf && IFFUNC_HASBODY(mainf->type));
1825 /* copy the interrupt vector table */
1826 if (mainf && IFFUNC_HASBODY(mainf->type))
1828 fprintf (asmFile, "%s", iComments2);
1829 fprintf (asmFile, "; interrupt vector \n");
1830 fprintf (asmFile, "%s", iComments2);
1831 dbuf_write_and_destroy (&vBuf, asmFile);
1834 /* copy global & static initialisations */
1835 fprintf (asmFile, "%s", iComments2);
1836 fprintf (asmFile, "; global & static initialisations\n");
1837 fprintf (asmFile, "%s", iComments2);
1839 /* Everywhere we generate a reference to the static_name area,
1840 * (which is currently only here), we immediately follow it with a
1841 * definition of the post_static_name area. This guarantees that
1842 * the post_static_name area will immediately follow the static_name
1845 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1846 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1847 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1848 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1850 if (mainf && IFFUNC_HASBODY(mainf->type))
1852 if (port->genInitStartup)
1854 port->genInitStartup(asmFile);
1858 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1859 /* if external stack is specified then the
1860 higher order byte of the xdatalocation is
1861 going into P2 and the lower order going into
1863 if (options.useXstack)
1865 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1866 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1867 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1868 (unsigned int) options.xdata_loc & 0xff);
1871 // This should probably be a port option, but I'm being lazy.
1872 // on the 400, the firmware boot loader gives us a valid stack
1873 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1874 if (!TARGET_IS_DS400)
1876 /* initialise the stack pointer. JCF: aslink takes care of the location */
1877 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1880 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1881 fprintf (asmFile, "\tmov\ta,dpl\n");
1882 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1883 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1884 fprintf (asmFile, "__sdcc_init_data:\n");
1886 // if the port can copy the XINIT segment to XISEG
1889 port->genXINIT(asmFile);
1894 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1896 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1898 /* This code is generated in the post-static area.
1899 * This area is guaranteed to follow the static area
1900 * by the ugly shucking and jiving about 20 lines ago.
1902 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1903 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1909 "%s", iComments2, iComments2);
1910 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1911 dbuf_write_and_destroy (&home->oBuf, asmFile);
1913 if (mainf && IFFUNC_HASBODY(mainf->type))
1915 /* entry point @ start of HOME */
1916 fprintf (asmFile, "__sdcc_program_startup:\n");
1918 /* put in jump or call to main */
1919 if (options.mainreturn)
1921 fprintf (asmFile, "\tljmp\t_main\n"); /* needed? */
1922 fprintf (asmFile, ";\treturn from main will return to caller\n");
1926 fprintf (asmFile, "\tlcall\t_main\n");
1927 fprintf (asmFile, ";\treturn from main will lock up\n");
1928 fprintf (asmFile, "\tsjmp .\n");
1931 /* copy over code */
1932 fprintf (asmFile, "%s", iComments2);
1933 fprintf (asmFile, "; code\n");
1934 fprintf (asmFile, "%s", iComments2);
1935 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1936 dbuf_write_and_destroy (&code->oBuf, asmFile);
1938 if (port->genAssemblerEnd) {
1939 port->genAssemblerEnd(asmFile);