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 -------------------------------------------------------------------------*/
25 #include "../common.h"
32 #ifdef WORDS_BIGENDIAN
33 #define _ENDIAN(x) (3-x)
35 #define _ENDIAN(x) (x)
38 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
40 extern symbol *interrupts[256];
41 static void printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb);
45 extern unsigned maxInterrupts;
46 extern int maxRegBank;
48 extern char *VersionString;
49 extern FILE *codeOutFile;
50 extern set *tmpfileSet;
51 extern set *tmpfileNameSet;
52 extern char *iComments1;
53 extern char *iComments2;
54 //extern void emitStaticSeg (memmap * map);
56 extern DEFSETFUNC (closeTmpFiles);
57 extern DEFSETFUNC (rmTmpFiles);
59 extern void AnalyzeBanking (void);
60 extern void copyFile (FILE * dest, FILE * src);
61 extern void InlinepCode(void);
62 extern void writeUsedRegs(FILE *);
64 extern void initialComments (FILE * afile);
65 extern void printPublics (FILE * afile);
67 extern void printChar (FILE * ofile, char *s, int plen);
68 void pCodeInitRegisters(void);
69 int getConfigWord(int address);
71 /*-----------------------------------------------------------------*/
72 /* aopLiteral - string from a literal value */
73 /*-----------------------------------------------------------------*/
74 int pic14aopLiteral (value *val, int offset)
81 /* if it is a float then it gets tricky */
82 /* otherwise it is fairly simple */
83 if (!IS_FLOAT(val->type)) {
84 unsigned long v = (unsigned long) floatFromVal(val);
86 return ( (v >> (offset * 8)) & 0xff);
89 /* it is type float */
90 fl.f = (float) floatFromVal(val);
91 #ifdef WORDS_BIGENDIAN
92 return fl.c[3-offset];
100 /*-----------------------------------------------------------------*/
101 /* emitRegularMap - emit code for maps with no special cases */
102 /*-----------------------------------------------------------------*/
104 pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
107 int i, size, bitvars = 0;;
110 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
112 /* print the area name */
113 for (sym = setFirstItem (map->syms); sym;
114 sym = setNextItem (map->syms)) {
116 printf("%s\n",sym->name);
118 /* if extern then add it into the extern list */
119 if (IS_EXTERN (sym->etype)) {
120 addSetHead (&externs, sym);
124 /* if allocation required check is needed
125 then check if the symbol really requires
126 allocation only for local variables */
127 if (arFlag && !IS_AGGREGATE (sym->type) &&
128 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
129 !sym->allocreq && sym->level)
132 /* if global variable & not static or extern
133 and addPublics allowed then add it to the public set */
134 if ((sym->level == 0 ||
135 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
137 !IS_STATIC (sym->etype))
138 addSetHead (&publics, sym);
140 /* if extern then do nothing or is a function
142 if (IS_FUNC (sym->type))
145 /* print extra debug info if required */
146 if (options.debug || sym->level == 0)
148 if (!sym->level) /* global */
149 if (IS_STATIC (sym->etype))
150 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
152 fprintf (map->oFile, "G_"); /* scope is global */
154 /* symbol is local */
155 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
156 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
160 /* if it has an absolute address then generate
161 an equate for this no need to allocate space */
162 if (SPEC_ABSA (sym->etype))
164 //if (options.debug || sym->level == 0)
165 //fprintf (map->oFile,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
167 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
169 SPEC_ADDR (sym->etype));
175 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
176 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
177 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
178 if (IS_BITVAR (sym->etype))
184 fprintf (map->oFile, "%s\tres\t%d\n", sym->rname,getSize (sym->type) & 0xffff);
186 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
188 for (i = 1; i < size; i++)
189 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
193 //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
196 /* if it has a initial value then do it only if
197 it is a global variable */
198 if (sym->ival && sym->level == 0) {
201 if (IS_AGGREGATE (sym->type))
202 ival = initAggregates (sym, sym->ival, NULL);
204 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
205 decorateType (resolveSymbols (list2expr (sym->ival))));
206 codeOutFile = statsg->oFile;
208 eBBlockFromiCode (iCodeFromAst (ival));
215 /*-----------------------------------------------------------------*/
216 /* printIvalType - generates ival for int/char */
217 /*-----------------------------------------------------------------*/
219 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
224 //fprintf(stderr, "%s\n",__FUNCTION__);
226 /* if initList is deep */
227 if (ilist->type == INIT_DEEP)
228 ilist = ilist->init.deep;
230 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
231 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
234 if (!(val = list2val (ilist))) {
235 // assuming a warning has been thrown
239 if (val->type != type) {
240 val = valCastLiteral(type, floatFromVal(val));
244 ulval = (unsigned long) floatFromVal (val);
248 switch (getSize (type)) {
250 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
254 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
255 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
259 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
260 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
261 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
262 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
267 /*-----------------------------------------------------------------*/
268 /* printIvalChar - generates initital value for character array */
269 /*-----------------------------------------------------------------*/
271 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
279 fprintf(stderr, "%s\n",__FUNCTION__);
283 val = list2val (ilist);
284 /* if the value is a character string */
285 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
287 if (!DCL_ELEM (type))
288 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
290 //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
291 //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
292 addpCode2pBlock(pb,newpCodeCharP(";omitting call to printChar"));
294 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
296 //tfprintf (oFile, "\t!db !constbyte\n", 0);
297 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
304 //printChar (oFile, s, strlen (s) + 1);
306 for(remain=0; remain<strlen(s); remain++) {
307 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
308 //fprintf(stderr,"0x%02x ",s[remain]);
310 //fprintf(stderr,"\n");
315 /*-----------------------------------------------------------------*/
316 /* printIvalArray - generates code for array initialization */
317 /*-----------------------------------------------------------------*/
319 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
323 int lcnt = 0, size = 0;
328 /* take care of the special case */
329 /* array of characters can be init */
331 if (IS_CHAR (type->next)) {
332 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
333 if (!IS_LITERAL(list2val(ilist)->etype)) {
334 werror (W_INIT_WRONG);
337 if (printIvalChar (type,
338 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
339 pb, SPEC_CVAL (sym->etype).v_char))
342 /* not the special case */
343 if (ilist->type != INIT_DEEP)
345 werror (E_INIT_STRUCT, sym->name);
349 iloop = ilist->init.deep;
350 lcnt = DCL_ELEM (type);
354 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
356 printIval (sym, type->next, iloop, pb);
357 iloop = (iloop ? iloop->next : NULL);
360 /* if not array limits given & we */
361 /* are out of initialisers then */
362 if (!DCL_ELEM (type) && !iloop)
365 /* no of elements given and we */
366 /* have generated for all of them */
368 /* if initializers left */
370 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
376 /* if we have not been given a size */
377 if (!DCL_ELEM (type))
378 DCL_ELEM (type) = size;
383 /*-----------------------------------------------------------------*/
384 /* printIval - generates code for initial value */
385 /*-----------------------------------------------------------------*/
387 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
392 /* if structure then */
393 if (IS_STRUCT (type))
395 //fprintf(stderr,"%s struct\n",__FUNCTION__);
396 //printIvalStruct (sym, type, ilist, oFile);
400 /* if this is a pointer */
403 //fprintf(stderr,"%s pointer\n",__FUNCTION__);
404 //printIvalPtr (sym, type, ilist, oFile);
408 /* if this is an array */
411 //fprintf(stderr,"%s array\n",__FUNCTION__);
412 printIvalArray (sym, type, ilist, pb);
416 /* if type is SPECIFIER */
419 //fprintf(stderr,"%s spec\n",__FUNCTION__);
420 printIvalType (sym, type, ilist, pb);
425 extern void pCodeConstString(char *name, char *value);
426 /*-----------------------------------------------------------------*/
427 /* emitStaticSeg - emitcode for the static segment */
428 /*-----------------------------------------------------------------*/
430 pic14emitStaticSeg (memmap * map)
434 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
436 //fprintf(stderr, "%s\n",__FUNCTION__);
438 /* for all variables in this segment do */
439 for (sym = setFirstItem (map->syms); sym;
440 sym = setNextItem (map->syms))
442 /* if it is "extern" then do nothing */
443 if (IS_EXTERN (sym->etype))
446 /* if it is not static add it to the public
448 if (!IS_STATIC (sym->etype))
449 addSetHead (&publics, sym);
451 /* print extra debug info if required */
452 if (options.debug || sym->level == 0)
456 if (IS_STATIC (sym->etype))
457 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
459 fprintf (code->oFile, "G_"); /* scope is global */
462 /* symbol is local */
463 fprintf (code->oFile, "L%s_",
464 (sym->localof ? sym->localof->name : "-null-"));
465 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
469 /* if it has an absolute address */
470 if (SPEC_ABSA (sym->etype))
472 if (options.debug || sym->level == 0)
473 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
475 fprintf (code->oFile, "%s\t=\t0x%04x\n",
477 SPEC_ADDR (sym->etype));
481 if (options.debug || sym->level == 0)
482 fprintf (code->oFile, " == .\n");
484 /* if it has an initial value */
489 fprintf (code->oFile, "%s:\n", sym->rname);
491 resolveIvalSym (sym->ival);
492 //printIval (sym, sym->type, sym->ival, code->oFile);
493 pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
495 addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
497 printIval (sym, sym->type, sym->ival, pb);
504 fprintf (code->oFile, "%s:\n", sym->rname);
505 /* special case for character strings */
506 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
507 SPEC_CVAL (sym->etype).v_char)
508 pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
509 /*printChar (code->oFile,
510 SPEC_CVAL (sym->etype).v_char,
511 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
513 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
521 /*-----------------------------------------------------------------*/
522 /* emitMaps - emits the code for the data portion the code */
523 /*-----------------------------------------------------------------*/
527 /* no special considerations for the following
528 data, idata & bit & xdata */
529 pic14emitRegularMap (data, TRUE, TRUE);
530 pic14emitRegularMap (idata, TRUE, TRUE);
531 pic14emitRegularMap (bit, TRUE, FALSE);
532 pic14emitRegularMap (xdata, TRUE, TRUE);
533 pic14emitRegularMap (sfr, FALSE, FALSE);
534 pic14emitRegularMap (sfrbit, FALSE, FALSE);
535 pic14emitRegularMap (code, TRUE, FALSE);
536 pic14emitStaticSeg (statsg);
539 /*-----------------------------------------------------------------*/
540 /* createInterruptVect - creates the interrupt vector */
541 /*-----------------------------------------------------------------*/
543 pic14createInterruptVect (FILE * vFile)
545 mainf = newSymbol ("main", 0);
548 /* only if the main function exists */
549 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
551 if (!options.cc_only)
556 /* if the main is only a prototype ie. no body then do nothing */
557 if (!IFFUNC_HASBODY(mainf->type))
559 /* if ! compile only then main function should be present */
560 if (!options.cc_only)
565 fprintf (vFile, "%s", iComments2);
566 fprintf (vFile, "; config word \n");
567 fprintf (vFile, "%s", iComments2);
568 fprintf (vFile, "\t__config 0x%x\n", getConfigWord(0x2007));
570 fprintf (vFile, "%s", iComments2);
571 fprintf (vFile, "; reset and interrupt vectors \n");
572 fprintf (vFile, "%s", iComments2);
573 fprintf (vFile, "STARTUP\t%s\n", CODE_NAME);
574 fprintf (vFile, "\tgoto\t__sdcc_gsinit_startup\n");
575 fprintf (vFile, "\tnop\n");
576 fprintf (vFile, "\tnop\n");
577 fprintf (vFile, "\tgoto\t__sdcc_interrupt\n");
582 /*-----------------------------------------------------------------*/
583 /* initialComments - puts in some initial comments */
584 /*-----------------------------------------------------------------*/
586 pic14initialComments (FILE * afile)
588 initialComments (afile);
589 fprintf (afile, "; PIC port for the 14-bit core\n");
590 fprintf (afile, iComments2);
594 /*-----------------------------------------------------------------*/
595 /* printExterns - generates extern for external variables */
596 /*-----------------------------------------------------------------*/
598 pic14printExterns (FILE * afile)
602 fprintf (afile, "%s", iComments2);
603 fprintf (afile, "; extern variables in this module\n");
604 fprintf (afile, "%s", iComments2);
606 for (sym = setFirstItem (externs); sym;
607 sym = setNextItem (externs))
608 fprintf (afile, "\textern %s\n", sym->rname);
611 /*-----------------------------------------------------------------*/
612 /* printPublics - generates .global for publics */
613 /*-----------------------------------------------------------------*/
615 pic14printPublics (FILE * afile)
619 fprintf (afile, "%s", iComments2);
620 fprintf (afile, "; publics variables in this module\n");
621 fprintf (afile, "%s", iComments2);
623 for (sym = setFirstItem (publics); sym;
624 sym = setNextItem (publics)) {
625 if(!IS_BITFIELD(sym->type) && ((IS_FUNC(sym->type) || sym->allocreq)))
626 fprintf (afile, "\tglobal %s\n", sym->rname);
628 fprintf (afile, ";\tglobal %s\n", sym->rname);
632 /*-----------------------------------------------------------------*/
633 /* emitOverlay - will emit code for the overlay stuff */
634 /*-----------------------------------------------------------------*/
636 pic14emitOverlay (FILE * afile)
640 if (!elementsInSet (ovrSetSets))
641 fprintf (afile, "\t%s\n", port->mem.overlay_name);
643 /* for each of the sets in the overlay segment do */
644 for (ovrset = setFirstItem (ovrSetSets); ovrset;
645 ovrset = setNextItem (ovrSetSets))
650 if (elementsInSet (ovrset))
652 /* this dummy area is used to fool the assembler
653 otherwise the assembler will append each of these
654 declarations into one chunk and will not overlay
657 /* I don't think this applies to us. We are using gpasm. CRF */
659 fprintf (afile, ";\t.area _DUMMY\n");
660 /* output the area informtion */
661 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
664 for (sym = setFirstItem (ovrset); sym;
665 sym = setNextItem (ovrset))
668 /* if extern then do nothing */
669 if (IS_EXTERN (sym->etype))
672 /* if allocation required check is needed
673 then check if the symbol really requires
674 allocation only for local variables */
675 if (!IS_AGGREGATE (sym->type) &&
676 !(sym->_isparm && !IS_REGPARM (sym->etype))
677 && !sym->allocreq && sym->level)
680 /* if global variable & not static or extern
681 and addPublics allowed then add it to the public set */
682 if ((sym->_isparm && !IS_REGPARM (sym->etype))
683 && !IS_STATIC (sym->etype))
684 addSetHead (&publics, sym);
686 /* if extern then do nothing or is a function
688 if (IS_FUNC (sym->type))
691 /* print extra debug info if required */
692 if (options.debug || sym->level == 0)
696 if (IS_STATIC (sym->etype))
697 fprintf (afile, "F%s_", moduleName); /* scope is file */
699 fprintf (afile, "G_"); /* scope is global */
702 /* symbol is local */
703 fprintf (afile, "L%s_",
704 (sym->localof ? sym->localof->name : "-null-"));
705 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
708 /* if is has an absolute address then generate
709 an equate for this no need to allocate space */
710 if (SPEC_ABSA (sym->etype))
713 if (options.debug || sym->level == 0)
714 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
716 fprintf (afile, "%s\t=\t0x%04x\n",
718 SPEC_ADDR (sym->etype));
722 if (options.debug || sym->level == 0)
723 fprintf (afile, "==.\n");
726 fprintf (afile, "%s:\n", sym->rname);
727 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
735 /*-----------------------------------------------------------------*/
736 /* glue - the final glue that hold the whole thing together */
737 /*-----------------------------------------------------------------*/
744 FILE *ovrFile = tempfile();
746 addSetHead(&tmpfileSet,ovrFile);
747 pCodeInitRegisters();
749 if (mainf && IFFUNC_HASBODY(mainf->type)) {
751 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
754 /* entry point @ start of CSEG */
755 addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
756 /* put in the call to main */
757 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
759 if (options.mainreturn) {
761 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
762 addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
766 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
767 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
773 /* At this point we've got all the code in the form of pCode structures */
774 /* Now it needs to be rearranged into the order it should be placed in the */
777 movepBlock2Head('P'); // Last
778 movepBlock2Head(code->dbName);
779 movepBlock2Head('X');
780 movepBlock2Head(statsg->dbName); // First
783 /* print the global struct definitions */
788 /* PENDING: this isnt the best place but it will do */
789 if (port->general.glue_up_main) {
790 /* create the interrupt vector table */
791 pic14createInterruptVect (vFile);
794 addSetHead(&tmpfileSet,vFile);
796 /* emit code for the all the variables declared */
798 /* do the overlay segments */
799 pic14emitOverlay(ovrFile);
805 //printCallTree(stderr);
815 /* now put it all together into the assembler file */
816 /* create the assembler file name */
818 if ((noAssemble || options.c1mode) && fullDstFileName)
820 sprintf (buffer, fullDstFileName);
824 sprintf (buffer, dstFileName);
825 strcat (buffer, ".asm");
828 if (!(asmFile = fopen (buffer, "w"))) {
829 werror (E_FILE_OPEN_ERR, buffer);
833 /* initial comments */
834 pic14initialComments (asmFile);
836 /* print module name */
837 fprintf (asmFile, ";\t.module %s\n", moduleName);
839 /* Let the port generate any global directives, etc. */
840 if (port->genAssemblerPreamble)
842 port->genAssemblerPreamble(asmFile);
845 /* print the extern variables in this module */
846 pic14printExterns (asmFile);
848 /* print the global variables in this module */
849 pic14printPublics (asmFile);
851 /* copy the sfr segment */
852 fprintf (asmFile, "%s", iComments2);
853 fprintf (asmFile, "; special function registers\n");
854 fprintf (asmFile, "%s", iComments2);
855 copyFile (asmFile, sfr->oFile);
857 fprintf (asmFile, "%s", iComments2);
858 fprintf (asmFile, "; udata\n");
859 fprintf (asmFile, "%s", iComments2);
860 fprintf (asmFile, "\tudata\n");
861 copyFile (asmFile, data->oFile);
863 /* Put all variables into a cblock */
865 writeUsedRegs(asmFile);
867 /* create the overlay segments */
868 fprintf (asmFile, "%s", iComments2);
869 fprintf (asmFile, "; overlayable items in internal ram \n");
870 fprintf (asmFile, "%s", iComments2);
871 copyFile (asmFile, ovrFile);
875 /* create the stack segment MOF */
876 if (mainf && IFFUNC_HASBODY(mainf->type)) {
877 fprintf (asmFile, "%s", iComments2);
878 fprintf (asmFile, "; Stack segment in internal ram \n");
879 fprintf (asmFile, "%s", iComments2);
880 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
881 ";__start__stack:\n;\t.ds\t1\n\n");
884 /* create the idata segment */
885 fprintf (asmFile, "%s", iComments2);
886 fprintf (asmFile, "; indirectly addressable internal ram data\n");
887 fprintf (asmFile, "%s", iComments2);
888 copyFile (asmFile, idata->oFile);
890 /* if external stack then reserve space of it */
891 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
892 fprintf (asmFile, "%s", iComments2);
893 fprintf (asmFile, "; external stack \n");
894 fprintf (asmFile, "%s", iComments2);
895 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
896 fprintf (asmFile,";\t.ds 256\n");
899 /* copy xtern ram data */
900 fprintf (asmFile, "%s", iComments2);
901 fprintf (asmFile, "; external ram data\n");
902 fprintf (asmFile, "%s", iComments2);
903 copyFile (asmFile, xdata->oFile);
907 /* copy the bit segment */
908 fprintf (asmFile, "%s", iComments2);
909 fprintf (asmFile, "; bit data\n");
910 fprintf (asmFile, "%s", iComments2);
911 copyFile (asmFile, bit->oFile);
913 /* copy the interrupt vector table */
914 if (mainf && IFFUNC_HASBODY(mainf->type)) {
915 copyFile (asmFile, vFile);
917 fprintf (asmFile, "%s", iComments2);
918 fprintf (asmFile, "; initialization and interrupt code \n");
919 fprintf (asmFile, "%s", iComments2);
921 /* initialize data memory */
922 fprintf (asmFile, "code_init\t%s\t0x10\n", CODE_NAME);
923 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
924 /* FIXME: This is temporary. The idata section should be used. If
925 not, we could add a special feature to the linker. This will
926 work in the mean time. Put all initalized data in main.c */
927 copypCode(asmFile, statsg->dbName);
928 fprintf (asmFile,"\tpagesel _main\n");
929 fprintf (asmFile,"\tgoto _main\n");
931 /* interrupt service routine */
932 fprintf (asmFile, "__sdcc_interrupt:\n");
933 copypCode(asmFile, 'I');
934 fprintf (asmFile,"\tgoto $\n");
939 /* copy global & static initialisations */
940 fprintf (asmFile, "%s", iComments2);
941 fprintf (asmFile, "; global & static initialisations\n");
942 fprintf (asmFile, "%s", iComments2);
943 copypCode(asmFile, statsg->dbName);
948 fprintf (asmFile, "%s", iComments2);
949 fprintf (asmFile, "; code\n");
950 fprintf (asmFile, "%s", iComments2);
951 fprintf (asmFile, "code_%s\t%s\n", moduleName, port->mem.code_name);
954 copypCode(asmFile, 'X');
957 copypCode(asmFile, 'M');
959 /* other functions */
960 copypCode(asmFile, code->dbName);
963 copypCode(asmFile, 'P');
965 fprintf (asmFile,"\tend\n");