1 /*-------------------------------------------------------------------------
3 SDCCglue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
30 #include "dbuf_string.h"
38 symbol *interrupts[INTNO_MAX+1];
40 void printIval (symbol *, sym_link *, initList *, struct dbuf_s *, bool check);
41 set *publics = NULL; /* public variables */
42 set *externs = NULL; /* Variables that are declared as extern */
44 unsigned maxInterrupts = 0;
47 int noInit = 0; /* no initialization */
50 /*-----------------------------------------------------------------*/
51 /* closePipes - closes all pipes created by the compiler */
52 /*-----------------------------------------------------------------*/
53 DEFSETFUNC (closePipes)
66 /*-----------------------------------------------------------------*/
67 /* closeTmpFiles - closes all tmp files created by the compiler */
68 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
69 /*-----------------------------------------------------------------*/
70 DEFSETFUNC (closeTmpFiles)
83 /*-----------------------------------------------------------------*/
84 /* rmTmpFiles - unlinks all tmp files created by the compiler */
85 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
86 /*-----------------------------------------------------------------*/
87 DEFSETFUNC (rmTmpFiles)
102 aopLiteralLong (value * val, int offset, int size)
111 // assuming we have been warned before
112 val = constCharVal (0);
115 /* if it is a float then it gets tricky */
116 /* otherwise it is fairly simple */
117 if (!IS_FLOAT (val->type)) {
118 unsigned long v = ulFromVal (val);
123 tsprintf (buffer, sizeof(buffer),
124 "!immedbyte", (unsigned int) v & 0xff);
127 tsprintf (buffer, sizeof(buffer),
128 "!immedword", (unsigned int) v & 0xffff);
131 /* Hmm. Too big for now. */
134 return Safe_strdup (buffer);
137 /* PENDING: For now size must be 1 */
140 /* it is type float */
141 fl.f = (float) floatFromVal (val);
142 #ifdef WORDS_BIGENDIAN
143 tsprintf (buffer, sizeof(buffer),
144 "!immedbyte", fl.c[3 - offset]);
146 tsprintf (buffer, sizeof(buffer),
147 "!immedbyte", fl.c[offset]);
149 return Safe_strdup (buffer);
152 /*-----------------------------------------------------------------*/
153 /* aopLiteral - string from a literal value */
154 /*-----------------------------------------------------------------*/
156 aopLiteral (value * val, int offset)
158 return aopLiteralLong (val, offset, 1);
161 /*-----------------------------------------------------------------*/
162 /* emitRegularMap - emit code for maps with no special cases */
163 /*-----------------------------------------------------------------*/
165 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
175 /* PENDING: special case here - should remove */
176 if (!strcmp (map->sname, CODE_NAME))
177 dbuf_tprintf (&map->oBuf, "\t!areacode\n", map->sname);
178 else if (!strcmp (map->sname, DATA_NAME))
179 dbuf_tprintf (&map->oBuf, "\t!areadata\n", map->sname);
180 else if (!strcmp (map->sname, HOME_NAME))
181 dbuf_tprintf (&map->oBuf, "\t!areahome\n", map->sname);
183 dbuf_tprintf (&map->oBuf, "\t!area\n", map->sname);
186 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms))
188 symbol *newSym = NULL;
190 /* if extern then add it into the extern list */
191 if (IS_EXTERN (sym->etype))
193 addSetHead (&externs, sym);
197 /* if allocation required check is needed
198 then check if the symbol really requires
199 allocation only for local variables */
201 if (arFlag && !IS_AGGREGATE (sym->type) &&
202 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
203 !sym->allocreq && sym->level)
206 /* for bitvar locals and parameters */
207 if (!arFlag && !sym->allocreq && sym->level
208 && !SPEC_ABSA (sym->etype))
213 /* if global variable & not static or extern
214 and addPublics allowed then add it to the public set */
215 if ((sym->level == 0 ||
216 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
218 !IS_STATIC (sym->etype) &&
219 (IS_FUNC (sym->type) ? (sym->used || IFFUNC_HASBODY (sym->type)) : 1))
221 addSetHead (&publics, sym);
224 /* if extern then do nothing or is a function
226 if (IS_FUNC (sym->type) && !(sym->isitmp))
229 /* print extra debug info if required */
232 if (!sym->level) /* global */
234 if (IS_STATIC (sym->etype))
235 dbuf_printf (&map->oBuf, "F%s$", moduleName); /* scope is file */
237 dbuf_printf (&map->oBuf, "G$"); /* scope is global */
241 /* symbol is local */
242 dbuf_printf (&map->oBuf, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
244 dbuf_printf (&map->oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
247 /* if it has an initial value then do it only if
248 it is a global variable */
249 if (sym->ival && sym->level == 0)
251 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);
279 printIval (sym, sym->type, sym->ival, &tmpBuf, TRUE);
282 dbuf_destroy(&tmpBuf);
287 if (IS_AGGREGATE (sym->type))
289 ival = initAggregates (sym, sym->ival, NULL);
293 if (getNelements (sym->type, sym->ival)>1)
295 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar", sym->name);
297 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
298 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
300 codeOutBuf = &statsg->oBuf;
304 // set ival's lineno to where the symbol was defined
305 setAstFileLine (ival, filename = sym->fileDef, lineno = sym->lineDef);
306 // check if this is not a constant expression
307 if (!constExprTree (ival))
309 werror (E_CONST_EXPECTED, "found expression");
310 // but try to do it anyway
313 if (!astErrors (ival))
314 eBBlockFromiCode (iCodeFromAst (ival));
320 /* if it has an absolute address then generate
321 an equate for this no need to allocate space */
322 if (SPEC_ABSA (sym->etype) && !sym->ival)
326 dbuf_printf (&map->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
334 else if (map == bit || map == sfrbit)
339 dbuf_printf (&map->oBuf, "%s\t%s\t0x%04x\n", sym->rname, equ, SPEC_ADDR (sym->etype));
343 int size = getSize (sym->type) + sym->flexArrayLength;
346 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE, sym->name);
351 dbuf_printf (&map->oBuf, "==.\n");
353 if (SPEC_ABSA (sym->etype))
355 dbuf_tprintf (&map->oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
357 if (IS_STATIC (sym->etype) || sym->level)
358 dbuf_tprintf (&map->oBuf, "!slabeldef\n", sym->rname);
360 dbuf_tprintf (&map->oBuf, "!labeldef\n", sym->rname);
361 dbuf_tprintf (&map->oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
367 /*-----------------------------------------------------------------*/
368 /* initPointer - pointer initialization code massaging */
369 /*-----------------------------------------------------------------*/
371 initPointer (initList * ilist, sym_link *toType)
377 return valCastLiteral(toType, 0.0);
380 expr = list2expr (ilist);
385 /* try it the old way first */
386 if ((val = constExprValue (expr, FALSE)))
389 /* ( ptr + constant ) */
390 if (IS_AST_OP (expr) &&
391 (expr->opval.op == '+' || expr->opval.op == '-') &&
392 IS_AST_SYM_VALUE (expr->left) &&
393 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
394 compareType(toType, expr->left->ftype) &&
395 IS_AST_LIT_VALUE (expr->right)) {
396 return valForCastAggr (expr->left, expr->left->ftype,
402 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
403 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
404 if (compareType(toType, expr->left->ftype)!=1) {
405 werror (W_INIT_WRONG);
406 printFromToType(expr->left->ftype, toType);
412 /* no then we have to do these cludgy checks */
413 /* pointers can be initialized with address of
414 a variable or address of an array element */
415 if (IS_AST_OP (expr) && expr->opval.op == '&') {
416 /* address of symbol */
417 if (IS_AST_SYM_VALUE (expr->left)) {
418 val = AST_VALUE (expr->left);
419 val->type = newLink (DECLARATOR);
420 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
421 DCL_TYPE (val->type) = CPOINTER;
422 DCL_PTR_CONST (val->type) = port->mem.code_ro;
424 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
425 DCL_TYPE (val->type) = FPOINTER;
426 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
427 DCL_TYPE (val->type) = PPOINTER;
428 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
429 DCL_TYPE (val->type) = IPOINTER;
430 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
431 DCL_TYPE (val->type) = EEPPOINTER;
433 DCL_TYPE (val->type) = POINTER;
434 val->type->next = expr->left->ftype;
435 val->etype = getSpec (val->type);
439 /* if address of indexed array */
440 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
441 return valForArray (expr->left);
443 /* if address of structure element then
445 if (IS_AST_OP (expr->left) &&
446 expr->left->opval.op == '.') {
447 return valForStructElem (expr->left->left,
452 (&some_struct)->element */
453 if (IS_AST_OP (expr->left) &&
454 expr->left->opval.op == PTR_OP &&
455 IS_ADDRESS_OF_OP (expr->left->left)) {
456 return valForStructElem (expr->left->left->left,
460 /* case 3. (((char *) &a) +/- constant) */
461 if (IS_AST_OP (expr) &&
462 (expr->opval.op == '+' || expr->opval.op == '-') &&
463 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
464 IS_AST_OP (expr->left->right) &&
465 expr->left->right->opval.op == '&' &&
466 IS_AST_LIT_VALUE (expr->right)) {
468 return valForCastAggr (expr->left->right->left,
469 expr->left->left->opval.lnk,
470 expr->right, expr->opval.op);
473 /* case 4. (char *)(array type) */
474 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
475 IS_ARRAY(expr->right->ftype)) {
477 val = copyValue (AST_VALUE (expr->right));
478 val->type = newLink (DECLARATOR);
479 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
480 DCL_TYPE (val->type) = CPOINTER;
481 DCL_PTR_CONST (val->type) = port->mem.code_ro;
483 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
484 DCL_TYPE (val->type) = FPOINTER;
485 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
486 DCL_TYPE (val->type) = PPOINTER;
487 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
488 DCL_TYPE (val->type) = IPOINTER;
489 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
490 DCL_TYPE (val->type) = EEPPOINTER;
492 DCL_TYPE (val->type) = POINTER;
493 val->type->next = expr->right->ftype->next;
494 val->etype = getSpec (val->type);
499 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
501 werror (E_INCOMPAT_PTYPES);
506 /*-----------------------------------------------------------------*/
507 /* printChar - formats and prints a characater string with DB */
508 /*-----------------------------------------------------------------*/
510 printChar (struct dbuf_s * oBuf, char *s, int plen)
518 while (len && pplen < plen)
521 while (i && pplen < plen)
523 if (*s < ' ' || *s == '\"' || *s=='\\')
527 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
528 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned char)*s);
543 dbuf_tprintf (oBuf, "\t!ascii\n", buf);
554 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
559 /*-----------------------------------------------------------------*/
560 /* return the generic pointer high byte for a given pointer type. */
561 /*-----------------------------------------------------------------*/
563 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
571 werror (E_CANNOT_USE_GENERIC_POINTER,
572 iname ? iname : "<null>",
573 oname ? oname : "<null>");
580 return GPTYPE_XSTACK;
582 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
590 /*-----------------------------------------------------------------*/
591 /* printPointerType - generates ival for pointer type */
592 /*-----------------------------------------------------------------*/
594 _printPointerType (struct dbuf_s * oBuf, const char *name)
596 if (options.model == MODEL_FLAT24)
598 if (port->little_endian)
599 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
601 dbuf_printf (oBuf, "\t.byte (%s >> 16),(%s >> 8),%s", name, name, name);
605 if (port->little_endian)
606 dbuf_printf (oBuf, "\t.byte %s,(%s >> 8)", name, name);
608 dbuf_printf (oBuf, "\t.byte (%s >> 8),%s", name, name);
612 /*-----------------------------------------------------------------*/
613 /* printPointerType - generates ival for pointer type */
614 /*-----------------------------------------------------------------*/
616 printPointerType (struct dbuf_s * oBuf, const char *name)
618 _printPointerType (oBuf, name);
619 dbuf_printf (oBuf, "\n");
622 /*-----------------------------------------------------------------*/
623 /* printGPointerType - generates ival for generic pointer type */
624 /*-----------------------------------------------------------------*/
626 printGPointerType (struct dbuf_s * oBuf, const char *iname, const char *oname,
627 const unsigned int type)
629 _printPointerType (oBuf, iname);
630 dbuf_printf (oBuf, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
633 /*-----------------------------------------------------------------*/
634 /* printIvalType - generates ival for int/char */
635 /*-----------------------------------------------------------------*/
637 printIvalType (symbol *sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
641 /* if initList is deep */
642 if (ilist && (ilist->type == INIT_DEEP))
643 ilist = ilist->init.deep;
645 if (!(val = list2val (ilist))) {
646 // assuming a warning has been thrown
647 val = constCharVal (0);
650 /* check if the literal value is within bounds */
651 if (checkConstantRange (type, val->etype, '=', FALSE) == CCR_OVL &&
652 !options.lessPedantic)
654 werror (W_LIT_OVERFLOW);
657 if (val->type != type) {
658 val = valCastLiteral(type, floatFromVal(val));
661 switch (getSize (type)) {
664 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
666 dbuf_tprintf (oBuf, "\t!dbs\n",
667 aopLiteral (val, 0));
671 if (port->use_dw_for_init)
672 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
673 else if (port->little_endian)
674 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
676 dbuf_printf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
680 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
681 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
683 else if (port->little_endian) {
684 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
685 aopLiteral (val, 0), aopLiteral (val, 1),
686 aopLiteral (val, 2), aopLiteral (val, 3));
689 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
690 aopLiteral (val, 3), aopLiteral (val, 2),
691 aopLiteral (val, 1), aopLiteral (val, 0));
697 /*-----------------------------------------------------------------*/
698 /* printIvalBitFields - generate initializer for bitfields */
699 /*-----------------------------------------------------------------*/
700 void printIvalBitFields(symbol **sym, initList **ilist, struct dbuf_s * oBuf)
704 initList *lilist = *ilist ;
705 unsigned long ival = 0;
711 val = list2val (lilist);
714 if (SPEC_BLEN (lsym->etype) > 8)
716 size += ((SPEC_BLEN (lsym->etype) / 8) +
717 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
722 size = ((SPEC_BLEN (lsym->etype) / 8) +
723 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
726 /* check if the literal value is within bounds */
728 checkConstantRange (lsym->etype, val->etype, '=', FALSE) == CCR_OVL &&
729 !options.lessPedantic)
731 werror (W_LIT_OVERFLOW);
735 i &= (1 << SPEC_BLEN (lsym->etype)) - 1;
736 i <<= SPEC_BSTR (lsym->etype);
739 (IS_BITFIELD (lsym->next->type)) &&
740 (SPEC_BSTR (lsym->next->etype))))
743 lilist = lilist ? lilist->next : NULL;
750 dbuf_tprintf (oBuf, "\t!db !constbyte\n", ival);
754 dbuf_tprintf (oBuf, "\t!dw !constword\n", ival);
758 dbuf_tprintf (oBuf, "\t!dw !constword,!constword\n",
759 (ival >> 16) & 0xffff, (ival & 0xffff));
766 /*-----------------------------------------------------------------*/
767 /* printIvalStruct - generates initial value for structures */
768 /*-----------------------------------------------------------------*/
770 printIvalStruct (symbol * sym, sym_link * type,
771 initList * ilist, struct dbuf_s * oBuf)
774 initList *iloop = NULL;
776 sflds = SPEC_STRUCT (type)->fields;
779 if (ilist->type != INIT_DEEP) {
780 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
784 iloop = ilist->init.deep;
787 if (SPEC_STRUCT (type)->type == UNION) {
788 printIval (sym, sflds->type, iloop, oBuf, TRUE);
789 iloop = iloop ? iloop->next : NULL;
791 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
792 if (IS_BITFIELD(sflds->type)) {
793 printIvalBitFields(&sflds, &iloop, oBuf);
795 printIval (sym, sflds->type, iloop, oBuf, TRUE);
800 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
805 /*-----------------------------------------------------------------*/
806 /* printIvalChar - generates initital value for character array */
807 /*-----------------------------------------------------------------*/
809 printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s, bool check)
812 unsigned int size = DCL_ELEM (type);
816 val = list2val (ilist);
817 /* if the value is a character string */
818 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
822 /* we have not been given a size, but now we know it */
823 size = strlen (SPEC_CVAL (val->etype).v_char) + 1;
824 /* but first check, if it's a flexible array */
825 if (sym && IS_STRUCT (sym->type))
826 sym->flexArrayLength = size;
828 DCL_ELEM (type) = size;
831 if (check && DCL_ELEM (val->type) > size)
832 werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
834 printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
842 printChar (oBuf, s, strlen (s) + 1);
846 /*-----------------------------------------------------------------*/
847 /* printIvalArray - generates code for array initialization */
848 /*-----------------------------------------------------------------*/
850 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
851 struct dbuf_s * oBuf, bool check)
855 unsigned int size = 0;
858 /* take care of the special case */
859 /* array of characters can be init */
861 if (IS_CHAR (type->next)) {
862 val = list2val(ilist);
864 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
867 if (!IS_LITERAL(val->etype)) {
868 werrorfl (ilist->filename, ilist->lineno, E_CONST_EXPECTED);
871 if (printIvalChar (sym, type,
872 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
873 oBuf, SPEC_CVAL (sym->etype).v_char, check))
876 /* not the special case */
877 if (ilist->type != INIT_DEEP) {
878 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
882 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
883 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
884 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
887 printIval (sym, type->next, iloop, oBuf, TRUE);
891 if (DCL_ELEM(type)) {
892 // pad with zeros if needed
893 if (size<DCL_ELEM(type)) {
894 size = (DCL_ELEM(type) - size) * getSize(type->next);
896 dbuf_tprintf (oBuf, "\t!db !constbyte\n", 0);
900 /* we have not been given a size, but now we know it */
901 /* but first check, if it's a flexible array */
902 if (IS_STRUCT (sym->type))
903 sym->flexArrayLength = size * getSize (type->next);
905 DCL_ELEM (type) = size;
911 /*-----------------------------------------------------------------*/
912 /* printIvalFuncPtr - generate initial value for function pointers */
913 /*-----------------------------------------------------------------*/
915 printIvalFuncPtr (sym_link * type, initList * ilist, struct dbuf_s * oBuf)
921 val = list2val (ilist);
923 val = valCastLiteral(type, 0.0);
926 // an error has been thrown already
927 val = constCharVal (0);
930 if (IS_LITERAL(val->etype)) {
931 if (compareType(type, val->etype) == 0) {
932 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
933 printFromToType (val->type, type);
935 printIvalCharPtr (NULL, type, val, oBuf);
939 /* check the types */
940 if ((dLvl = compareType (val->type, type->next)) <= 0)
942 dbuf_tprintf (oBuf, "\t!dw !constword\n", 0);
946 /* now generate the name */
949 if (port->use_dw_for_init)
951 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
955 printPointerType (oBuf, val->name);
958 else if (port->use_dw_for_init)
960 dbuf_tprintf (oBuf, "\t!dws\n", val->sym->rname);
964 printPointerType (oBuf, val->sym->rname);
970 /*-----------------------------------------------------------------*/
971 /* printIvalCharPtr - generates initial values for character pointers */
972 /*-----------------------------------------------------------------*/
974 printIvalCharPtr (symbol * sym, sym_link * type, value * val, struct dbuf_s * oBuf)
978 /* PENDING: this is _very_ mcs51 specific, including a magic
980 It's also endian specific.
982 size = getSize (type);
984 if (val->name && strlen (val->name))
986 if (size == 1) /* This appears to be Z80 specific?? */
989 "\t!dbs\n", val->name);
991 else if (size == FPTRSIZE)
993 if (port->use_dw_for_init)
995 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
999 printPointerType (oBuf, val->name);
1002 else if (size == GPTRSIZE)
1005 if (IS_PTR (val->type)) {
1006 type = DCL_TYPE (val->type);
1008 type = PTR_TYPE (SPEC_OCLS (val->etype));
1010 if (val->sym && val->sym->isstrlit) {
1011 // this is a literal string
1014 printGPointerType (oBuf, val->name, sym->name, type);
1018 fprintf (stderr, "*** internal error: unknown size in "
1019 "printIvalCharPtr.\n");
1024 // these are literals assigned to pointers
1028 dbuf_tprintf (oBuf, "\t!dbs\n", aopLiteral (val, 0));
1031 if (port->use_dw_for_init)
1032 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, size));
1033 else if (port->little_endian)
1034 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
1035 aopLiteral (val, 0), aopLiteral (val, 1));
1037 dbuf_tprintf (oBuf, "\t.byte %s,%s\n",
1038 aopLiteral (val, 1), aopLiteral (val, 0));
1041 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1042 // non-zero mcs51 generic pointer
1043 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1045 if (port->little_endian) {
1046 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1047 aopLiteral (val, 0),
1048 aopLiteral (val, 1),
1049 aopLiteral (val, 2));
1051 dbuf_printf (oBuf, "\t.byte %s,%s,%s\n",
1052 aopLiteral (val, 2),
1053 aopLiteral (val, 1),
1054 aopLiteral (val, 0));
1058 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
1059 // non-zero ds390 generic pointer
1060 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
1062 if (port->little_endian) {
1063 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1064 aopLiteral (val, 0),
1065 aopLiteral (val, 1),
1066 aopLiteral (val, 2),
1067 aopLiteral (val, 3));
1069 dbuf_printf (oBuf, "\t.byte %s,%s,%s,%s\n",
1070 aopLiteral (val, 3),
1071 aopLiteral (val, 2),
1072 aopLiteral (val, 1),
1073 aopLiteral (val, 0));
1081 if (!noInit && val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1082 addSet (&statsg->syms, val->sym);
1088 /*-----------------------------------------------------------------*/
1089 /* printIvalPtr - generates initial value for pointers */
1090 /*-----------------------------------------------------------------*/
1092 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
1098 if (ilist && (ilist->type == INIT_DEEP))
1099 ilist = ilist->init.deep;
1101 /* function pointer */
1102 if (IS_FUNC (type->next))
1104 printIvalFuncPtr (type, ilist, oBuf);
1108 if (!(val = initPointer (ilist, type)))
1111 /* if character pointer */
1112 if (IS_CHAR (type->next))
1113 if (printIvalCharPtr (sym, type, val, oBuf))
1116 /* check the type */
1117 if (compareType (type, val->type) == 0) {
1118 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1119 printFromToType (val->type, type);
1122 /* if val is literal */
1123 if (IS_LITERAL (val->etype))
1125 switch (getSize (type))
1128 dbuf_tprintf (oBuf, "\t!db !constbyte\n", (unsigned int) ulFromVal (val) & 0xff);
1131 if (port->use_dw_for_init)
1132 dbuf_tprintf (oBuf, "\t!dws\n", aopLiteralLong (val, 0, 2));
1133 else if (port->little_endian)
1134 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1136 dbuf_tprintf (oBuf, "\t.byte %s,%s\n", aopLiteral (val, 1), aopLiteral (val, 0));
1138 case 3: // how about '390??
1139 dbuf_printf (oBuf, "; generic printIvalPtr\n");
1140 if (port->little_endian)
1142 dbuf_printf (oBuf, "\t.byte %s,%s",
1143 aopLiteral (val, 0), aopLiteral (val, 1));
1147 dbuf_printf (oBuf, "\t.byte %s,%s",
1148 aopLiteral (val, 1), aopLiteral (val, 0));
1150 if (IS_GENPTR (val->type))
1151 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1152 else if (IS_PTR (val->type))
1153 dbuf_printf (oBuf, ",#%x\n", pointerTypeToGPByte (DCL_TYPE (val->type), NULL, NULL));
1155 dbuf_printf (oBuf, ",%s\n", aopLiteral (val, 2));
1161 size = getSize (type);
1163 if (size == 1) /* Z80 specific?? */
1165 dbuf_tprintf (oBuf, "\t!dbs\n", val->name);
1167 else if (size == FPTRSIZE)
1169 if (port->use_dw_for_init) {
1170 dbuf_tprintf (oBuf, "\t!dws\n", val->name);
1172 printPointerType (oBuf, val->name);
1175 else if (size == GPTRSIZE)
1177 printGPointerType (oBuf, val->name, sym->name,
1178 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1179 PTR_TYPE (SPEC_OCLS (val->etype))));
1184 /*-----------------------------------------------------------------*/
1185 /* printIval - generates code for initial value */
1186 /*-----------------------------------------------------------------*/
1188 printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, bool check)
1192 /* if structure then */
1193 if (IS_STRUCT (type))
1195 printIvalStruct (sym, type, ilist, oBuf);
1199 /* if this is an array */
1200 if (IS_ARRAY (type))
1202 printIvalArray (sym, type, ilist, oBuf, check);
1208 // not an aggregate, ilist must be a node
1209 if (ilist->type!=INIT_NODE) {
1210 // or a 1-element list
1211 if (ilist->init.deep->next) {
1212 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1215 ilist=ilist->init.deep;
1219 // and the type must match
1220 itype=ilist->init.node->ftype;
1222 if (compareType(type, itype)==0) {
1223 // special case for literal strings
1224 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1225 // which are really code pointers
1226 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1229 werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1230 printFromToType(itype, type);
1235 /* if this is a pointer */
1238 printIvalPtr (sym, type, ilist, oBuf);
1242 /* if type is SPECIFIER */
1245 printIvalType (sym, type, ilist, oBuf);
1250 /*-----------------------------------------------------------------*/
1251 /* emitStaticSeg - emitcode for the static segment */
1252 /*-----------------------------------------------------------------*/
1254 emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
1258 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1260 /* for all variables in this segment do */
1261 for (sym = setFirstItem (map->syms); sym;
1262 sym = setNextItem (map->syms))
1265 /* if it is "extern" then do nothing */
1266 if (IS_EXTERN (sym->etype))
1269 /* if it is not static add it to the public table */
1270 if (!IS_STATIC (sym->etype))
1272 addSetHead (&publics, sym);
1275 /* print extra debug info if required */
1280 if (IS_STATIC (sym->etype))
1281 dbuf_printf (oBuf, "F%s$", moduleName); /* scope is file */
1283 dbuf_printf (oBuf, "G$"); /* scope is global */
1287 /* symbol is local */
1288 dbuf_printf (oBuf, "L%s$",
1289 (sym->localof ? sym->localof->name : "-null-"));
1291 dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1294 /* if it has an absolute address and no initializer */
1295 if (SPEC_ABSA (sym->etype) && !sym->ival)
1298 dbuf_printf (oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1300 dbuf_printf (oBuf, "%s\t=\t0x%04x\n",
1302 SPEC_ADDR (sym->etype));
1307 dbuf_printf (oBuf, " == .\n");
1309 /* if it has an initial value */
1312 if (SPEC_ABSA (sym->etype))
1314 dbuf_tprintf (oBuf, "\t!org\n", SPEC_ADDR (sym->etype));
1316 dbuf_printf (oBuf, "%s:\n", sym->rname);
1318 resolveIvalSym (sym->ival, sym->type);
1319 printIval (sym, sym->type, sym->ival, oBuf, map != xinit);
1321 /* if sym is a simple string and sym->ival is a string,
1322 WE don't need it anymore */
1323 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1324 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1325 list2val(sym->ival)->sym->isstrlit) {
1326 freeStringSymbol(list2val(sym->ival)->sym);
1330 /* allocate space */
1331 int size = getSize (sym->type);
1334 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE,sym->name);
1336 dbuf_printf (oBuf, "%s:\n", sym->rname);
1337 /* special case for character strings */
1338 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1339 SPEC_CVAL (sym->etype).v_char)
1341 SPEC_CVAL (sym->etype).v_char,
1344 dbuf_tprintf (oBuf, "\t!ds\n", (unsigned int) size & 0xffff);
1350 /*-----------------------------------------------------------------*/
1351 /* emitMaps - emits the code for the data portion the code */
1352 /*-----------------------------------------------------------------*/
1356 int publicsfr = TARGET_IS_MCS51; /* Ideally, this should be true for all */
1357 /* ports but let's be conservative - EEP */
1360 /* no special considerations for the following
1361 data, idata & bit & xdata */
1362 emitRegularMap (data, TRUE, TRUE);
1363 emitRegularMap (idata, TRUE, TRUE);
1364 emitRegularMap (d_abs, TRUE, TRUE);
1365 emitRegularMap (i_abs, TRUE, TRUE);
1366 emitRegularMap (bit, TRUE, TRUE);
1367 emitRegularMap (pdata, TRUE, TRUE);
1368 emitRegularMap (xdata, TRUE, TRUE);
1369 emitRegularMap (x_abs, TRUE, TRUE);
1370 if (port->genXINIT) {
1371 emitRegularMap (xidata, TRUE, TRUE);
1373 emitRegularMap (sfr, publicsfr, FALSE);
1374 emitRegularMap (sfrbit, publicsfr, FALSE);
1375 emitRegularMap (home, TRUE, FALSE);
1376 emitRegularMap (code, TRUE, FALSE);
1378 if (options.const_seg) {
1379 dbuf_tprintf (&code->oBuf, "\t!area\n", options.const_seg);
1381 emitStaticSeg (statsg, &code->oBuf);
1382 if (port->genXINIT) {
1383 dbuf_tprintf (&code->oBuf, "\t!area\n", xinit->sname);
1384 emitStaticSeg (xinit, &code->oBuf);
1386 dbuf_tprintf (&code->oBuf, "\t!area\n", c_abs->sname);
1387 emitStaticSeg (c_abs, &code->oBuf);
1391 /*-----------------------------------------------------------------*/
1392 /* flushStatics - flush all currently defined statics out to file */
1393 /* and delete. Temporary function */
1394 /*-----------------------------------------------------------------*/
1398 emitStaticSeg (statsg, codeOutBuf);
1399 statsg->syms = NULL;
1402 /*-----------------------------------------------------------------*/
1403 /* createInterruptVect - creates the interrupt vector */
1404 /*-----------------------------------------------------------------*/
1406 createInterruptVect (struct dbuf_s *vBuf)
1408 mainf = newSymbol ("main", 0);
1411 /* only if the main function exists */
1412 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1414 if (!options.cc_only && !noAssemble && !options.c1mode)
1419 /* if the main is only a prototype ie. no body then do nothing */
1420 if (!IFFUNC_HASBODY(mainf->type))
1422 /* if ! compile only then main function should be present */
1423 if (!options.cc_only && !noAssemble)
1428 dbuf_tprintf (vBuf, "\t!areacode\n", HOME_NAME);
1429 dbuf_printf (vBuf, "__interrupt_vect:\n");
1432 if (!port->genIVT || !(port->genIVT (vBuf, interrupts, maxInterrupts)))
1434 /* There's no such thing as a "generic" interrupt table header. */
1441 ";--------------------------------------------------------\n"
1442 "; File Created by SDCC : free open source ANSI-C Compiler\n"};
1446 ";--------------------------------------------------------\n"};
1449 /*-----------------------------------------------------------------*/
1450 /* initialComments - puts in some initial comments */
1451 /*-----------------------------------------------------------------*/
1453 initialComments (FILE * afile)
1457 fprintf (afile, "%s", iComments1);
1458 fprintf (afile, "; Version " SDCC_VERSION_STR " #%s (%s) (%s)\n",
1459 getBuildNumber(), getBuildDate(), getBuildEnvironment());
1460 fprintf (afile, "; This file was generated %s", asctime (localtime (&t)));
1461 fprintf (afile, "%s", iComments2);
1464 /*-----------------------------------------------------------------*/
1465 /* printPublics - generates .global for publics */
1466 /*-----------------------------------------------------------------*/
1468 printPublics (FILE * afile)
1472 fprintf (afile, "%s", iComments2);
1473 fprintf (afile, "; Public variables in this module\n");
1474 fprintf (afile, "%s", iComments2);
1476 for (sym = setFirstItem (publics); sym;
1477 sym = setNextItem (publics))
1478 tfprintf (afile, "\t!global\n", sym->rname);
1481 /*-----------------------------------------------------------------*/
1482 /* printExterns - generates .global for externs */
1483 /*-----------------------------------------------------------------*/
1485 printExterns (FILE * afile)
1489 fprintf (afile, "%s", iComments2);
1490 fprintf (afile, "; Externals used\n");
1491 fprintf (afile, "%s", iComments2);
1493 for (sym = setFirstItem (externs); sym;
1494 sym = setNextItem (externs))
1495 tfprintf (afile, "\t!extern\n", sym->rname);
1498 /*-----------------------------------------------------------------*/
1499 /* emitOverlay - will emit code for the overlay stuff */
1500 /*-----------------------------------------------------------------*/
1502 emitOverlay (struct dbuf_s * aBuf)
1506 if (!elementsInSet (ovrSetSets))
1507 dbuf_tprintf (aBuf, "\t!area\n", port->mem.overlay_name);
1509 /* for each of the sets in the overlay segment do */
1510 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1511 ovrset = setNextItem (ovrSetSets))
1516 if (elementsInSet (ovrset))
1518 /* output the area informtion */
1519 dbuf_printf (aBuf, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1522 for (sym = setFirstItem (ovrset); sym;
1523 sym = setNextItem (ovrset))
1525 /* if extern then it is in the publics table: do nothing */
1526 if (IS_EXTERN (sym->etype))
1529 /* if allocation required check is needed
1530 then check if the symbol really requires
1531 allocation only for local variables */
1532 if (!IS_AGGREGATE (sym->type) &&
1533 !(sym->_isparm && !IS_REGPARM (sym->etype))
1534 && !sym->allocreq && sym->level)
1537 /* if global variable & not static or extern
1538 and addPublics allowed then add it to the public set */
1539 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1540 && !IS_STATIC (sym->etype))
1542 addSetHead (&publics, sym);
1545 /* if extern then do nothing or is a function
1547 if (IS_FUNC (sym->type))
1550 /* print extra debug info if required */
1555 if (IS_STATIC (sym->etype))
1556 dbuf_printf (aBuf, "F%s$", moduleName); /* scope is file */
1558 dbuf_printf (aBuf, "G$"); /* scope is global */
1561 /* symbol is local */
1562 dbuf_printf (aBuf, "L%s$",
1563 (sym->localof ? sym->localof->name : "-null-"));
1564 dbuf_printf (aBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
1567 /* if is has an absolute address then generate
1568 an equate for this no need to allocate space */
1569 if (SPEC_ABSA (sym->etype))
1573 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1575 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1577 SPEC_ADDR (sym->etype));
1581 int size = getSize(sym->type);
1584 werrorfl (sym->fileDef, sym->lineDef, E_UNKNOWN_SIZE);
1587 dbuf_printf (aBuf, "==.\n");
1589 /* allocate space */
1590 dbuf_tprintf (aBuf, "!labeldef\n", sym->rname);
1591 dbuf_tprintf (aBuf, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1598 /*-----------------------------------------------------------------*/
1599 /* glue - the final glue that hold the whole thing together */
1600 /*-----------------------------------------------------------------*/
1605 struct dbuf_s ovrBuf;
1609 dbuf_init (&vBuf, 4096);
1610 dbuf_init (&ovrBuf, 4096);
1612 mcs51_like = (port->general.glue_up_main &&
1613 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51 || TARGET_IS_DS400));
1615 /* print the global struct definitions */
1619 /* PENDING: this isn't the best place but it will do */
1620 if (port->general.glue_up_main)
1622 /* create the interrupt vector table */
1623 createInterruptVect (&vBuf);
1626 /* emit code for the all the variables declared */
1628 /* do the overlay segments */
1629 emitOverlay (&ovrBuf);
1631 outputDebugSymbols ();
1633 /* now put it all together into the assembler file */
1634 /* create the assembler file name */
1636 /* -o option overrides default name? */
1637 if ((noAssemble || options.c1mode) && fullDstFileName)
1639 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1643 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1644 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1647 if (!(asmFile = fopen (scratchFileName, "w")))
1649 werror (E_FILE_OPEN_ERR, scratchFileName);
1650 exit (EXIT_FAILURE);
1653 /* initial comments */
1654 initialComments (asmFile);
1656 /* print module name */
1657 tfprintf (asmFile, "\t!module\n", moduleName);
1660 fprintf (asmFile, "\t.optsdcc -m%s", port->target);
1662 switch(options.model)
1664 case MODEL_SMALL: fprintf (asmFile, " --model-small"); break;
1665 case MODEL_COMPACT: fprintf (asmFile, " --model-compact"); break;
1666 case MODEL_MEDIUM: fprintf (asmFile, " --model-medium"); break;
1667 case MODEL_LARGE: fprintf (asmFile, " --model-large"); break;
1668 case MODEL_FLAT24: fprintf (asmFile, " --model-flat24"); break;
1669 case MODEL_PAGE0: fprintf (asmFile, " --model-page0"); break;
1672 /*if(options.stackAuto) fprintf (asmFile, " --stack-auto");*/
1673 if(options.useXstack) fprintf (asmFile, " --xstack");
1674 /*if(options.intlong_rent) fprintf (asmFile, " --int-long-rent");*/
1675 /*if(options.float_rent) fprintf (asmFile, " --float-rent");*/
1676 if(options.noRegParams) fprintf (asmFile, " --no-reg-params");
1677 if(options.parms_in_bank1) fprintf (asmFile, " --parms-in-bank1");
1678 fprintf (asmFile, "\n");
1680 else if (TARGET_Z80_LIKE || TARGET_IS_HC08)
1682 fprintf (asmFile, "\t.optsdcc -m%s\n", port->target);
1685 tfprintf (asmFile, "\t!fileprelude\n");
1687 /* Let the port generate any global directives, etc. */
1688 if (port->genAssemblerPreamble)
1690 port->genAssemblerPreamble (asmFile);
1693 /* print the global variables in this module */
1694 printPublics (asmFile);
1695 if (port->assembler.externGlobal)
1696 printExterns (asmFile);
1699 ||( TARGET_IS_Z80 )) /*.p.t.20030924 need to output SFR table for Z80 as well */
1701 /* copy the sfr segment */
1702 fprintf (asmFile, "%s", iComments2);
1703 fprintf (asmFile, "; special function registers\n");
1704 fprintf (asmFile, "%s", iComments2);
1705 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1710 /* copy the sbit segment */
1711 fprintf (asmFile, "%s", iComments2);
1712 fprintf (asmFile, "; special function bits\n");
1713 fprintf (asmFile, "%s", iComments2);
1714 dbuf_write_and_destroy (&sfrbit->oBuf, asmFile);
1716 /*JCF: Create the areas for the register banks*/
1717 if (RegBankUsed[0] || RegBankUsed[1] || RegBankUsed[2] || RegBankUsed[3])
1719 fprintf (asmFile, "%s", iComments2);
1720 fprintf (asmFile, "; overlayable register banks\n");
1721 fprintf (asmFile, "%s", iComments2);
1723 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1724 if (RegBankUsed[1] || options.parms_in_bank1)
1725 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1727 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1729 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1733 fprintf (asmFile, "%s", iComments2);
1734 fprintf (asmFile, "; overlayable bit register bank\n");
1735 fprintf (asmFile, "%s", iComments2);
1736 fprintf (asmFile, "\t.area BIT_BANK\t(REL,OVR,DATA)\n");
1737 fprintf (asmFile, "bits:\n\t.ds 1\n");
1738 fprintf (asmFile, "\tb0 = bits[0]\n");
1739 fprintf (asmFile, "\tb1 = bits[1]\n");
1740 fprintf (asmFile, "\tb2 = bits[2]\n");
1741 fprintf (asmFile, "\tb3 = bits[3]\n");
1742 fprintf (asmFile, "\tb4 = bits[4]\n");
1743 fprintf (asmFile, "\tb5 = bits[5]\n");
1744 fprintf (asmFile, "\tb6 = bits[6]\n");
1745 fprintf (asmFile, "\tb7 = bits[7]\n");
1749 /* copy the data segment */
1750 fprintf (asmFile, "%s", iComments2);
1751 fprintf (asmFile, "; %s ram data\n", mcs51_like?"internal":"");
1752 fprintf (asmFile, "%s", iComments2);
1753 dbuf_write_and_destroy (&data->oBuf, asmFile);
1756 /* create the overlay segments */
1759 fprintf (asmFile, "%s", iComments2);
1760 fprintf (asmFile, "; overlayable items in %s ram \n", mcs51_like?"internal":"");
1761 fprintf (asmFile, "%s", iComments2);
1762 dbuf_write_and_destroy (&ovrBuf, asmFile);
1765 /* create the stack segment MOF */
1766 if (mainf && IFFUNC_HASBODY (mainf->type))
1768 fprintf (asmFile, "%s", iComments2);
1769 fprintf (asmFile, "; Stack segment in internal ram \n");
1770 fprintf (asmFile, "%s", iComments2);
1771 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1772 "__start__stack:\n\t.ds\t1\n\n");
1775 /* create the idata segment */
1776 if ((idata) && (mcs51_like))
1778 fprintf (asmFile, "%s", iComments2);
1779 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1780 fprintf (asmFile, "%s", iComments2);
1781 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1784 /* create the absolute idata/data segment */
1785 if ((i_abs) && (mcs51_like))
1787 fprintf (asmFile, "%s", iComments2);
1788 fprintf (asmFile, "; absolute internal ram data\n");
1789 fprintf (asmFile, "%s", iComments2);
1790 dbuf_write_and_destroy (&d_abs->oBuf, asmFile);
1791 dbuf_write_and_destroy (&i_abs->oBuf, asmFile);
1794 /* copy the bit segment */
1797 fprintf (asmFile, "%s", iComments2);
1798 fprintf (asmFile, "; bit data\n");
1799 fprintf (asmFile, "%s", iComments2);
1800 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1803 /* copy paged external ram data */
1806 fprintf (asmFile, "%s", iComments2);
1807 fprintf (asmFile, "; paged external ram data\n");
1808 fprintf (asmFile, "%s", iComments2);
1809 dbuf_write_and_destroy (&pdata->oBuf, asmFile);
1812 /* if external stack then reserve space for it */
1813 if (mainf && IFFUNC_HASBODY (mainf->type) && options.useXstack)
1815 fprintf (asmFile, "%s", iComments2);
1816 fprintf (asmFile, "; external stack \n");
1817 fprintf (asmFile, "%s", iComments2);
1818 fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n"
1819 "__start__xstack:\n\t.ds\t1\n\n");
1822 /* copy external ram data */
1825 fprintf (asmFile, "%s", iComments2);
1826 fprintf (asmFile, "; external ram data\n");
1827 fprintf (asmFile, "%s", iComments2);
1828 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1831 /* create the absolute xdata segment */
1832 if (mcs51_like || TARGET_IS_HC08)
1834 fprintf (asmFile, "%s", iComments2);
1835 fprintf (asmFile, "; absolute external ram data\n");
1836 fprintf (asmFile, "%s", iComments2);
1837 dbuf_write_and_destroy (&x_abs->oBuf, asmFile);
1840 /* copy external initialized ram data */
1841 fprintf (asmFile, "%s", iComments2);
1842 fprintf (asmFile, "; external initialized ram data\n");
1843 fprintf (asmFile, "%s", iComments2);
1844 dbuf_write_and_destroy (&xidata->oBuf, asmFile);
1846 /* If the port wants to generate any extra areas, let it do so. */
1847 if (port->extraAreas.genExtraAreaDeclaration)
1849 port->extraAreas.genExtraAreaDeclaration(asmFile,
1850 mainf && IFFUNC_HASBODY(mainf->type));
1853 /* copy the interrupt vector table */
1854 if (mainf && IFFUNC_HASBODY (mainf->type))
1856 fprintf (asmFile, "%s", iComments2);
1857 fprintf (asmFile, "; interrupt vector \n");
1858 fprintf (asmFile, "%s", iComments2);
1859 dbuf_write_and_destroy (&vBuf, asmFile);
1862 /* copy global & static initialisations */
1863 fprintf (asmFile, "%s", iComments2);
1864 fprintf (asmFile, "; global & static initialisations\n");
1865 fprintf (asmFile, "%s", iComments2);
1867 /* Everywhere we generate a reference to the static_name area,
1868 * (which is currently only here), we immediately follow it with a
1869 * definition of the post_static_name area. This guarantees that
1870 * the post_static_name area will immediately follow the static_name
1873 tfprintf (asmFile, "\t!area\n", port->mem.home_name);
1874 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1875 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1876 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1878 if (mainf && IFFUNC_HASBODY (mainf->type))
1880 if (port->genInitStartup)
1882 port->genInitStartup (asmFile);
1886 assert (mcs51_like);
1887 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1888 /* if external stack is specified then the
1889 higher order byte of the xdatalocation is
1890 going into P2 and the lower order going into
1892 if (options.useXstack)
1894 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1895 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1896 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1897 (unsigned int) options.xdata_loc & 0xff);
1900 // This should probably be a port option, but I'm being lazy.
1901 // on the 400, the firmware boot loader gives us a valid stack
1902 // (see '400 data sheet pg. 85 (TINI400 ROM Initialization code)
1903 if (!TARGET_IS_DS400)
1905 /* initialise the stack pointer. JCF: aslink takes care of the location */
1906 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1909 fprintf (asmFile, "\t%ccall\t__sdcc_external_startup\n", options.acall_ajmp?'a':'l');
1910 fprintf (asmFile, "\tmov\ta,dpl\n");
1911 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1912 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1913 fprintf (asmFile, "__sdcc_init_data:\n");
1915 // if the port can copy the XINIT segment to XISEG
1918 port->genXINIT (asmFile);
1922 dbuf_write_and_destroy (&statsg->oBuf, asmFile);
1924 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY (mainf->type))
1926 /* This code is generated in the post-static area.
1927 * This area is guaranteed to follow the static area
1928 * by the ugly shucking and jiving about 20 lines ago.
1930 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1931 fprintf (asmFile, "\t%cjmp\t__sdcc_program_startup\n", options.acall_ajmp?'a':'l');
1937 "%s", iComments2, iComments2);
1938 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1939 dbuf_write_and_destroy (&home->oBuf, asmFile);
1941 if (mainf && IFFUNC_HASBODY (mainf->type))
1943 /* entry point @ start of HOME */
1944 fprintf (asmFile, "__sdcc_program_startup:\n");
1946 /* put in jump or call to main */
1947 if (options.mainreturn)
1949 fprintf (asmFile, "\t%cjmp\t_main\n", options.acall_ajmp?'a':'l'); /* needed? */
1950 fprintf (asmFile, ";\treturn from main will return to caller\n");
1954 fprintf (asmFile, "\t%ccall\t_main\n", options.acall_ajmp?'a':'l');
1955 fprintf (asmFile, ";\treturn from main will lock up\n");
1956 fprintf (asmFile, "\tsjmp .\n");
1959 /* copy over code */
1960 fprintf (asmFile, "%s", iComments2);
1961 fprintf (asmFile, "; code\n");
1962 fprintf (asmFile, "%s", iComments2);
1963 tfprintf (asmFile, "\t!areacode\n", options.code_seg);
1964 dbuf_write_and_destroy (&code->oBuf, asmFile);
1966 if (port->genAssemblerEnd)
1968 port->genAssemblerEnd (asmFile);