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 char *udata_section_name="udata"; // FIXME Temporary fix to change udata section name -- VR
73 /*-----------------------------------------------------------------*/
74 /* aopLiteral - string from a literal value */
75 /*-----------------------------------------------------------------*/
76 int pic14aopLiteral (value *val, int offset)
83 /* if it is a float then it gets tricky */
84 /* otherwise it is fairly simple */
85 if (!IS_FLOAT(val->type)) {
86 unsigned long v = (unsigned long) floatFromVal(val);
88 return ( (v >> (offset * 8)) & 0xff);
91 /* it is type float */
92 fl.f = (float) floatFromVal(val);
93 #ifdef WORDS_BIGENDIAN
94 return fl.c[3-offset];
102 /*-----------------------------------------------------------------*/
103 /* emitRegularMap - emit code for maps with no special cases */
104 /*-----------------------------------------------------------------*/
106 pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
111 /* print the area name */
113 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
115 for (sym = setFirstItem (map->syms); sym;
116 sym = setNextItem (map->syms)) {
118 //printf("%s\n",sym->name);
120 /* if extern then add it into the extern list */
121 if (IS_EXTERN (sym->etype)) {
122 addSetHead (&externs, sym);
126 /* if allocation required check is needed
127 then check if the symbol really requires
128 allocation only for local variables */
129 if (arFlag && !IS_AGGREGATE (sym->type) &&
130 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
131 !sym->allocreq && sym->level)
134 /* if global variable & not static or extern
135 and addPublics allowed then add it to the public set */
136 if ((sym->level == 0 ||
137 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
139 !IS_STATIC (sym->etype))
140 addSetHead (&publics, sym);
142 /* if extern then do nothing or is a function
144 if (IS_FUNC (sym->type))
147 /* print extra debug info if required */
148 if (options.debug || sym->level == 0)
150 if (!sym->level) /* global */
151 if (IS_STATIC (sym->etype))
152 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
154 fprintf (map->oFile, "G_"); /* scope is global */
156 /* symbol is local */
157 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
158 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
162 /* if it has an absolute address then generate
163 an equate for this no need to allocate space */
164 if (SPEC_ABSA (sym->etype))
166 //if (options.debug || sym->level == 0)
167 //fprintf (map->oFile,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
169 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
171 SPEC_ADDR (sym->etype));
177 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
178 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
179 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
180 if (IS_BITVAR (sym->etype))
186 fprintf (map->oFile, "%s\tres\t%d\n", sym->rname,getSize (sym->type) & 0xffff);
191 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
193 for (i = 1; i < size; i++)
194 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
199 //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
202 /* if it has a initial value then do it only if
203 it is a global variable */
204 if (sym->ival && sym->level == 0) {
207 if (IS_AGGREGATE (sym->type))
208 ival = initAggregates (sym, sym->ival, NULL);
210 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
211 decorateType (resolveSymbols (list2expr (sym->ival))));
212 codeOutFile = statsg->oFile;
214 eBBlockFromiCode (iCodeFromAst (ival));
221 /*-----------------------------------------------------------------*/
222 /* printIvalType - generates ival for int/char */
223 /*-----------------------------------------------------------------*/
225 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
230 //fprintf(stderr, "%s\n",__FUNCTION__);
232 /* if initList is deep */
233 if (ilist->type == INIT_DEEP)
234 ilist = ilist->init.deep;
236 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
237 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
240 if (!(val = list2val (ilist))) {
241 // assuming a warning has been thrown
245 if (val->type != type) {
246 val = valCastLiteral(type, floatFromVal(val));
250 ulval = (unsigned long) floatFromVal (val);
254 switch (getSize (type)) {
256 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
260 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
261 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
265 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
266 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
267 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
268 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
273 /*-----------------------------------------------------------------*/
274 /* printIvalChar - generates initital value for character array */
275 /*-----------------------------------------------------------------*/
277 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
285 //fprintf(stderr, "%s\n",__FUNCTION__);
289 val = list2val (ilist);
290 /* if the value is a character string */
291 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
293 if (!DCL_ELEM (type))
294 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
296 //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
297 //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
298 addpCode2pBlock(pb,newpCodeCharP(";omitting call to printChar"));
300 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
302 //tfprintf (oFile, "\t!db !constbyte\n", 0);
303 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
310 //printChar (oFile, s, strlen (s) + 1);
312 for(remain=0; remain<(int)strlen(s); remain++) {
313 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
314 //fprintf(stderr,"0x%02x ",s[remain]);
316 //fprintf(stderr,"\n");
321 /*-----------------------------------------------------------------*/
322 /* printIvalArray - generates code for array initialization */
323 /*-----------------------------------------------------------------*/
325 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
329 int lcnt = 0, size = 0;
334 /* take care of the special case */
335 /* array of characters can be init */
337 if (IS_CHAR (type->next)) {
338 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
339 if (!IS_LITERAL(list2val(ilist)->etype)) {
340 werror (W_INIT_WRONG);
343 if (printIvalChar (type,
344 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
345 pb, SPEC_CVAL (sym->etype).v_char))
348 /* not the special case */
349 if (ilist->type != INIT_DEEP)
351 werror (E_INIT_STRUCT, sym->name);
355 iloop = ilist->init.deep;
356 lcnt = DCL_ELEM (type);
360 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
362 printIval (sym, type->next, iloop, pb);
363 iloop = (iloop ? iloop->next : NULL);
366 /* if not array limits given & we */
367 /* are out of initialisers then */
368 if (!DCL_ELEM (type) && !iloop)
371 /* no of elements given and we */
372 /* have generated for all of them */
374 /* if initializers left */
376 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
382 /* if we have not been given a size */
383 if (!DCL_ELEM (type))
384 DCL_ELEM (type) = size;
389 /*-----------------------------------------------------------------*/
390 /* printIval - generates code for initial value */
391 /*-----------------------------------------------------------------*/
393 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
398 /* if structure then */
399 if (IS_STRUCT (type))
401 //fprintf(stderr,"%s struct\n",__FUNCTION__);
402 //printIvalStruct (sym, type, ilist, oFile);
406 /* if this is a pointer */
409 //fprintf(stderr,"%s pointer\n",__FUNCTION__);
410 //printIvalPtr (sym, type, ilist, oFile);
414 /* if this is an array */
417 //fprintf(stderr,"%s array\n",__FUNCTION__);
418 printIvalArray (sym, type, ilist, pb);
422 /* if type is SPECIFIER */
425 //fprintf(stderr,"%s spec\n",__FUNCTION__);
426 printIvalType (sym, type, ilist, pb);
431 extern void pCodeConstString(char *name, char *value);
432 /*-----------------------------------------------------------------*/
433 /* emitStaticSeg - emitcode for the static segment */
434 /*-----------------------------------------------------------------*/
436 pic14emitStaticSeg (memmap * map)
440 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
442 //fprintf(stderr, "%s\n",__FUNCTION__);
444 /* for all variables in this segment do */
445 for (sym = setFirstItem (map->syms); sym;
446 sym = setNextItem (map->syms))
448 /* if it is "extern" then do nothing */
449 if (IS_EXTERN (sym->etype))
452 /* if it is not static add it to the public
454 if (!IS_STATIC (sym->etype))
455 addSetHead (&publics, sym);
457 /* print extra debug info if required */
458 if (options.debug || sym->level == 0)
462 if (IS_STATIC (sym->etype))
463 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
465 fprintf (code->oFile, "G_"); /* scope is global */
468 /* symbol is local */
469 fprintf (code->oFile, "L%s_",
470 (sym->localof ? sym->localof->name : "-null-"));
471 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
475 /* if it has an absolute address */
476 if (SPEC_ABSA (sym->etype))
478 if (options.debug || sym->level == 0)
479 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
481 fprintf (code->oFile, "%s\t=\t0x%04x\n",
483 SPEC_ADDR (sym->etype));
487 if (options.debug || sym->level == 0)
488 fprintf (code->oFile, " == .\n");
490 /* if it has an initial value */
495 fprintf (code->oFile, "%s:\n", sym->rname);
497 resolveIvalSym (sym->ival);
498 //printIval (sym, sym->type, sym->ival, code->oFile);
499 pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
501 addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
503 printIval (sym, sym->type, sym->ival, pb);
510 fprintf (code->oFile, "%s:\n", sym->rname);
511 /* special case for character strings */
512 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
513 SPEC_CVAL (sym->etype).v_char)
514 pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
515 /*printChar (code->oFile,
516 SPEC_CVAL (sym->etype).v_char,
517 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
519 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
527 /*-----------------------------------------------------------------*/
528 /* emitMaps - emits the code for the data portion the code */
529 /*-----------------------------------------------------------------*/
533 /* no special considerations for the following
534 data, idata & bit & xdata */
535 pic14emitRegularMap (data, TRUE, TRUE);
536 pic14emitRegularMap (idata, TRUE, TRUE);
537 pic14emitRegularMap (bit, TRUE, FALSE);
538 pic14emitRegularMap (xdata, TRUE, TRUE);
539 pic14emitRegularMap (sfr, FALSE, FALSE);
540 pic14emitRegularMap (sfrbit, FALSE, FALSE);
541 pic14emitRegularMap (code, TRUE, FALSE);
542 pic14emitStaticSeg (statsg);
545 /*-----------------------------------------------------------------*/
546 /* createInterruptVect - creates the interrupt vector */
547 /*-----------------------------------------------------------------*/
549 pic14createInterruptVect (FILE * vFile)
551 mainf = newSymbol ("main", 0);
554 /* only if the main function exists */
555 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
557 if (!options.cc_only)
562 /* if the main is only a prototype ie. no body then do nothing */
563 if (!IFFUNC_HASBODY(mainf->type))
565 /* if ! compile only then main function should be present */
566 if (!options.cc_only)
571 fprintf (vFile, "%s", iComments2);
572 fprintf (vFile, "; config word \n");
573 fprintf (vFile, "%s", iComments2);
574 fprintf (vFile, "\t__config 0x%x\n", getConfigWord(0x2007));
576 fprintf (vFile, "%s", iComments2);
577 fprintf (vFile, "; reset vector \n");
578 fprintf (vFile, "%s", iComments2);
579 fprintf (vFile, "STARTUP\t%s\n", CODE_NAME);
580 fprintf (vFile, "\tnop\n"); /* first location used by incircuit debugger */
581 fprintf (vFile, "\tgoto\t__sdcc_gsinit_startup\n");
582 /* during an interrupt PCLATH must be cleared before a goto - delete me
583 fprintf (vFile, "\tnop\n");
584 fprintf (vFile, "\tgoto\t__sdcc_interrupt\n");
589 /*-----------------------------------------------------------------*/
590 /* initialComments - puts in some initial comments */
591 /*-----------------------------------------------------------------*/
593 pic14initialComments (FILE * afile)
595 initialComments (afile);
596 fprintf (afile, "; PIC port for the 14-bit core\n");
597 fprintf (afile, iComments2);
601 /*-----------------------------------------------------------------*/
602 /* printExterns - generates extern for external variables */
603 /*-----------------------------------------------------------------*/
605 pic14printExterns (FILE * afile)
609 fprintf (afile, "%s", iComments2);
610 fprintf (afile, "; extern variables in this module\n");
611 fprintf (afile, "%s", iComments2);
613 for (sym = setFirstItem (externs); sym;
614 sym = setNextItem (externs))
615 fprintf (afile, "\textern %s\n", sym->rname);
618 /*-----------------------------------------------------------------*/
619 /* printPublics - generates .global for publics */
620 /*-----------------------------------------------------------------*/
622 pic14printPublics (FILE * afile)
626 fprintf (afile, "%s", iComments2);
627 fprintf (afile, "; publics variables in this module\n");
628 fprintf (afile, "%s", iComments2);
630 for (sym = setFirstItem (publics); sym;
631 sym = setNextItem (publics)) {
632 if(!IS_BITFIELD(sym->type) && ((IS_FUNC(sym->type) || sym->allocreq))) {
633 if (!IS_BITVAR(sym->type))
634 fprintf (afile, "\tglobal %s\n", sym->rname);
636 fprintf (afile, ";\tglobal %s\n", sym->rname);
640 /*-----------------------------------------------------------------*/
641 /* emitOverlay - will emit code for the overlay stuff */
642 /*-----------------------------------------------------------------*/
644 pic14emitOverlay (FILE * afile)
648 /* if (!elementsInSet (ovrSetSets))*/
650 /* the hack below, fixes translates for devices which
651 * only have udata_shr memory */
652 fprintf (afile, "%s\t%s\n",
653 (elementsInSet(ovrSetSets)?"":";"),
654 port->mem.overlay_name);
656 /* for each of the sets in the overlay segment do */
657 for (ovrset = setFirstItem (ovrSetSets); ovrset;
658 ovrset = setNextItem (ovrSetSets))
663 if (elementsInSet (ovrset))
665 /* this dummy area is used to fool the assembler
666 otherwise the assembler will append each of these
667 declarations into one chunk and will not overlay
670 /* I don't think this applies to us. We are using gpasm. CRF */
672 fprintf (afile, ";\t.area _DUMMY\n");
673 /* output the area informtion */
674 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
677 for (sym = setFirstItem (ovrset); sym;
678 sym = setNextItem (ovrset))
681 /* if extern then do nothing */
682 if (IS_EXTERN (sym->etype))
685 /* if allocation required check is needed
686 then check if the symbol really requires
687 allocation only for local variables */
688 if (!IS_AGGREGATE (sym->type) &&
689 !(sym->_isparm && !IS_REGPARM (sym->etype))
690 && !sym->allocreq && sym->level)
693 /* if global variable & not static or extern
694 and addPublics allowed then add it to the public set */
695 if ((sym->_isparm && !IS_REGPARM (sym->etype))
696 && !IS_STATIC (sym->etype))
697 addSetHead (&publics, sym);
699 /* if extern then do nothing or is a function
701 if (IS_FUNC (sym->type))
704 /* print extra debug info if required */
705 if (options.debug || sym->level == 0)
709 if (IS_STATIC (sym->etype))
710 fprintf (afile, "F%s_", moduleName); /* scope is file */
712 fprintf (afile, "G_"); /* scope is global */
715 /* symbol is local */
716 fprintf (afile, "L%s_",
717 (sym->localof ? sym->localof->name : "-null-"));
718 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
721 /* if is has an absolute address then generate
722 an equate for this no need to allocate space */
723 if (SPEC_ABSA (sym->etype))
726 if (options.debug || sym->level == 0)
727 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
729 fprintf (afile, "%s\t=\t0x%04x\n",
731 SPEC_ADDR (sym->etype));
735 if (options.debug || sym->level == 0)
736 fprintf (afile, "==.\n");
739 fprintf (afile, "%s:\n", sym->rname);
740 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
748 /*-----------------------------------------------------------------*/
749 /* glue - the final glue that hold the whole thing together */
750 /*-----------------------------------------------------------------*/
757 FILE *ovrFile = tempfile();
759 addSetHead(&tmpfileSet,ovrFile);
760 pCodeInitRegisters();
762 if (mainf && IFFUNC_HASBODY(mainf->type)) {
764 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
767 /* entry point @ start of CSEG */
768 addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
769 /* put in the call to main */
770 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
772 if (options.mainreturn) {
774 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
775 addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
779 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
780 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
786 /* At this point we've got all the code in the form of pCode structures */
787 /* Now it needs to be rearranged into the order it should be placed in the */
790 movepBlock2Head('P'); // Last
791 movepBlock2Head(code->dbName);
792 movepBlock2Head('X');
793 movepBlock2Head(statsg->dbName); // First
796 /* print the global struct definitions */
802 addSetHead(&tmpfileSet,vFile);
804 /* emit code for the all the variables declared */
806 /* do the overlay segments */
807 pic14emitOverlay(ovrFile);
809 /* PENDING: this isnt the best place but it will do */
810 if (port->general.glue_up_main) {
811 /* create the interrupt vector table */
812 pic14createInterruptVect (vFile);
818 //printCallTree(stderr);
828 /* now put it all together into the assembler file */
829 /* create the assembler file name */
831 if ((noAssemble || options.c1mode) && fullDstFileName)
833 sprintf (buffer, fullDstFileName);
837 sprintf (buffer, dstFileName);
838 strcat (buffer, ".asm");
841 if (!(asmFile = fopen (buffer, "w"))) {
842 werror (E_FILE_OPEN_ERR, buffer);
846 /* initial comments */
847 pic14initialComments (asmFile);
849 /* print module name */
850 fprintf (asmFile, ";\t.module %s\n", moduleName);
852 /* Let the port generate any global directives, etc. */
853 if (port->genAssemblerPreamble)
855 port->genAssemblerPreamble(asmFile);
858 /* print the extern variables in this module */
859 pic14printExterns (asmFile);
861 /* print the global variables in this module */
862 pic14printPublics (asmFile);
864 /* copy the sfr segment */
865 fprintf (asmFile, "%s", iComments2);
866 fprintf (asmFile, "; special function registers\n");
867 fprintf (asmFile, "%s", iComments2);
868 copyFile (asmFile, sfr->oFile);
870 fprintf (asmFile, "%s", iComments2);
871 fprintf (asmFile, "; %s\n", udata_section_name);
872 fprintf (asmFile, "%s", iComments2);
873 fprintf (asmFile, "\t%s\n", udata_section_name);
874 copyFile (asmFile, data->oFile);
876 /* Put all variables into a cblock */
878 writeUsedRegs(asmFile);
880 /* create the overlay segments */
881 fprintf (asmFile, "%s", iComments2);
882 fprintf (asmFile, "; overlayable items in internal ram \n");
883 fprintf (asmFile, "%s", iComments2);
884 copyFile (asmFile, ovrFile);
888 /* create the stack segment MOF */
889 if (mainf && IFFUNC_HASBODY(mainf->type)) {
890 fprintf (asmFile, "%s", iComments2);
891 fprintf (asmFile, "; Stack segment in internal ram \n");
892 fprintf (asmFile, "%s", iComments2);
893 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
894 ";__start__stack:\n;\t.ds\t1\n\n");
897 /* create the idata segment */
898 fprintf (asmFile, "%s", iComments2);
899 fprintf (asmFile, "; indirectly addressable internal ram data\n");
900 fprintf (asmFile, "%s", iComments2);
901 copyFile (asmFile, idata->oFile);
903 /* if external stack then reserve space of it */
904 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
905 fprintf (asmFile, "%s", iComments2);
906 fprintf (asmFile, "; external stack \n");
907 fprintf (asmFile, "%s", iComments2);
908 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
909 fprintf (asmFile,";\t.ds 256\n");
912 /* copy xtern ram data */
913 fprintf (asmFile, "%s", iComments2);
914 fprintf (asmFile, "; external ram data\n");
915 fprintf (asmFile, "%s", iComments2);
916 copyFile (asmFile, xdata->oFile);
920 /* copy the bit segment */
921 fprintf (asmFile, "%s", iComments2);
922 fprintf (asmFile, "; bit data\n");
923 fprintf (asmFile, "%s", iComments2);
924 copyFile (asmFile, bit->oFile);
926 /* copy the interrupt vector table */
927 if (mainf && IFFUNC_HASBODY(mainf->type)) {
928 copyFile (asmFile, vFile);
930 fprintf (asmFile, "%s", iComments2);
931 fprintf (asmFile, "; interrupt and initialization code\n");
932 fprintf (asmFile, "%s", iComments2);
933 fprintf (asmFile, "code_init\t%s\t0x4\n", CODE_NAME);
935 /* interrupt service routine */
936 fprintf (asmFile, "__sdcc_interrupt:\n");
937 copypCode(asmFile, 'I');
939 /* initialize data memory */
940 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
941 /* FIXME: This is temporary. The idata section should be used. If
942 not, we could add a special feature to the linker. This will
943 work in the mean time. Put all initalized data in main.c */
944 copypCode(asmFile, statsg->dbName);
945 fprintf (asmFile,"\tpagesel _main\n");
946 fprintf (asmFile,"\tgoto _main\n");
951 /* copy global & static initialisations */
952 fprintf (asmFile, "%s", iComments2);
953 fprintf (asmFile, "; global & static initialisations\n");
954 fprintf (asmFile, "%s", iComments2);
955 copypCode(asmFile, statsg->dbName);
960 fprintf (asmFile, "%s", iComments2);
961 fprintf (asmFile, "; code\n");
962 fprintf (asmFile, "%s", iComments2);
963 fprintf (asmFile, "code_%s\t%s\n", moduleName, port->mem.code_name);
966 copypCode(asmFile, 'X');
969 copypCode(asmFile, 'M');
971 /* other functions */
972 copypCode(asmFile, code->dbName);
975 copypCode(asmFile, 'P');
977 fprintf (asmFile,"\tend\n");