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 ReuseReg(void);
62 extern void InlinepCode(void);
63 extern void writeUsedRegs(FILE *);
65 extern void initialComments (FILE * afile);
66 extern void printPublics (FILE * afile);
68 extern void printChar (FILE * ofile, char *s, int plen);
69 void pCodeInitRegisters(void);
70 int getConfigWord(int address);
72 char *udata_section_name=0; // FIXME Temporary fix to change udata section name -- VR
74 /*-----------------------------------------------------------------*/
75 /* aopLiteral - string from a literal value */
76 /*-----------------------------------------------------------------*/
77 int pic14aopLiteral (value *val, int offset)
84 /* if it is a float then it gets tricky */
85 /* otherwise it is fairly simple */
86 if (!IS_FLOAT(val->type)) {
87 unsigned long v = (unsigned long) floatFromVal(val);
89 return ( (v >> (offset * 8)) & 0xff);
92 /* it is type float */
93 fl.f = (float) floatFromVal(val);
94 #ifdef WORDS_BIGENDIAN
95 return fl.c[3-offset];
103 /*-----------------------------------------------------------------*/
104 /* emitRegularMap - emit code for maps with no special cases */
105 /*-----------------------------------------------------------------*/
107 pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
112 /* print the area name */
114 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
116 for (sym = setFirstItem (map->syms); sym;
117 sym = setNextItem (map->syms)) {
119 //printf("%s\n",sym->name);
121 /* if extern then add it into the extern list */
122 if (IS_EXTERN (sym->etype)) {
123 addSetHead (&externs, sym);
127 /* if allocation required check is needed
128 then check if the symbol really requires
129 allocation only for local variables */
130 if (arFlag && !IS_AGGREGATE (sym->type) &&
131 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
132 !sym->allocreq && sym->level)
135 /* if global variable & not static or extern
136 and addPublics allowed then add it to the public set */
137 if ((sym->level == 0 ||
138 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
140 !IS_STATIC (sym->etype))
141 addSetHead (&publics, sym);
143 // PIC code allocates its own registers - so ignore parameter variable generated by processFuncArgs()
146 /* if extern then do nothing or is a function
148 if (IS_FUNC (sym->type))
151 /* print extra debug info if required */
152 if (options.debug || sym->level == 0)
154 if (!sym->level) /* global */
155 if (IS_STATIC (sym->etype))
156 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
158 fprintf (map->oFile, "G_"); /* scope is global */
160 /* symbol is local */
161 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
162 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
166 /* if it has an absolute address then generate
167 an equate for this no need to allocate space */
168 if (SPEC_ABSA (sym->etype))
170 //if (options.debug || sym->level == 0)
171 //fprintf (map->oFile,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
173 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
175 SPEC_ADDR (sym->etype));
181 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
182 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
183 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
184 if (IS_BITVAR (sym->etype))
190 fprintf (map->oFile, "%s\tres\t%d\n", sym->rname,getSize (sym->type) & 0xffff);
195 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
197 for (i = 1; i < size; i++)
198 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
203 //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
206 /* if it has a initial value then do it only if
207 it is a global variable */
208 if (sym->ival && sym->level == 0) {
211 if (IS_AGGREGATE (sym->type))
212 ival = initAggregates (sym, sym->ival, NULL);
214 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
215 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK));
216 codeOutFile = statsg->oFile;
218 eBBlockFromiCode (iCodeFromAst (ival));
225 /*-----------------------------------------------------------------*/
226 /* printIvalType - generates ival for int/char */
227 /*-----------------------------------------------------------------*/
229 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
234 //fprintf(stderr, "%s\n",__FUNCTION__);
236 /* if initList is deep */
237 if (ilist->type == INIT_DEEP)
238 ilist = ilist->init.deep;
240 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
241 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
244 if (!(val = list2val (ilist))) {
245 // assuming a warning has been thrown
249 if (val->type != type) {
250 val = valCastLiteral(type, floatFromVal(val));
254 ulval = (unsigned long) floatFromVal (val);
258 switch (getSize (type)) {
260 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
264 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
265 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
269 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
270 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
271 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
272 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
277 /*-----------------------------------------------------------------*/
278 /* printIvalChar - generates initital value for character array */
279 /*-----------------------------------------------------------------*/
281 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
289 //fprintf(stderr, "%s\n",__FUNCTION__);
293 val = list2val (ilist);
294 /* if the value is a character string */
295 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
297 if (!DCL_ELEM (type))
298 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
300 //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
301 //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
302 addpCode2pBlock(pb,newpCodeCharP(";omitting call to printChar"));
304 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
306 //tfprintf (oFile, "\t!db !constbyte\n", 0);
307 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
314 //printChar (oFile, s, strlen (s) + 1);
316 for(remain=0; remain<(int)strlen(s); remain++) {
317 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
318 //fprintf(stderr,"0x%02x ",s[remain]);
320 //fprintf(stderr,"\n");
325 /*-----------------------------------------------------------------*/
326 /* printIvalArray - generates code for array initialization */
327 /*-----------------------------------------------------------------*/
329 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
333 int lcnt = 0, size = 0;
338 /* take care of the special case */
339 /* array of characters can be init */
341 if (IS_CHAR (type->next)) {
342 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
343 if (!IS_LITERAL(list2val(ilist)->etype)) {
344 werror (W_INIT_WRONG);
347 if (printIvalChar (type,
348 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
349 pb, SPEC_CVAL (sym->etype).v_char))
352 /* not the special case */
353 if (ilist->type != INIT_DEEP)
355 werror (E_INIT_STRUCT, sym->name);
359 iloop = ilist->init.deep;
360 lcnt = DCL_ELEM (type);
364 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
366 printIval (sym, type->next, iloop, pb);
367 iloop = (iloop ? iloop->next : NULL);
370 /* if not array limits given & we */
371 /* are out of initialisers then */
372 if (!DCL_ELEM (type) && !iloop)
375 /* no of elements given and we */
376 /* have generated for all of them */
378 /* if initializers left */
380 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
386 /* if we have not been given a size */
387 if (!DCL_ELEM (type))
388 DCL_ELEM (type) = size;
393 /*-----------------------------------------------------------------*/
394 /* printIval - generates code for initial value */
395 /*-----------------------------------------------------------------*/
397 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
402 /* if structure then */
403 if (IS_STRUCT (type))
405 //fprintf(stderr,"%s struct\n",__FUNCTION__);
406 //printIvalStruct (sym, type, ilist, oFile);
410 /* if this is a pointer */
413 //fprintf(stderr,"%s pointer\n",__FUNCTION__);
414 //printIvalPtr (sym, type, ilist, oFile);
418 /* if this is an array */
421 //fprintf(stderr,"%s array\n",__FUNCTION__);
422 printIvalArray (sym, type, ilist, pb);
426 /* if type is SPECIFIER */
429 //fprintf(stderr,"%s spec\n",__FUNCTION__);
430 printIvalType (sym, type, ilist, pb);
435 extern void pCodeConstString(char *name, char *value);
436 /*-----------------------------------------------------------------*/
437 /* emitStaticSeg - emitcode for the static segment */
438 /*-----------------------------------------------------------------*/
440 pic14emitStaticSeg (memmap * map)
444 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
446 //fprintf(stderr, "%s\n",__FUNCTION__);
448 /* for all variables in this segment do */
449 for (sym = setFirstItem (map->syms); sym;
450 sym = setNextItem (map->syms))
452 /* if extern then add it into the extern list */
453 if (IS_EXTERN (sym->etype)) {
454 addSetHead (&externs, sym);
458 /* if it is not static add it to the public
460 if (!IS_STATIC (sym->etype))
461 addSetHead (&publics, sym);
463 /* print extra debug info if required */
464 if (options.debug || sym->level == 0)
468 if (IS_STATIC (sym->etype))
469 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
471 fprintf (code->oFile, "G_"); /* scope is global */
474 /* symbol is local */
475 fprintf (code->oFile, "L%s_",
476 (sym->localof ? sym->localof->name : "-null-"));
477 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
481 /* if it has an absolute address */
482 if (SPEC_ABSA (sym->etype))
484 if (options.debug || sym->level == 0)
485 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
487 fprintf (code->oFile, "%s\t=\t0x%04x\n",
489 SPEC_ADDR (sym->etype));
493 if (options.debug || sym->level == 0)
494 fprintf (code->oFile, " == .\n");
496 /* if it has an initial value */
501 fprintf (code->oFile, "%s:\n", sym->rname);
503 resolveIvalSym (sym->ival, sym->type);
504 //printIval (sym, sym->type, sym->ival, code->oFile);
505 pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
507 addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
509 printIval (sym, sym->type, sym->ival, pb);
516 fprintf (code->oFile, "%s:\n", sym->rname);
517 /* special case for character strings */
518 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
519 SPEC_CVAL (sym->etype).v_char)
520 pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
521 /*printChar (code->oFile,
522 SPEC_CVAL (sym->etype).v_char,
523 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
525 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
533 /*-----------------------------------------------------------------*/
534 /* emitMaps - emits the code for the data portion the code */
535 /*-----------------------------------------------------------------*/
539 /* no special considerations for the following
540 data, idata & bit & xdata */
541 pic14emitRegularMap (data, TRUE, TRUE);
542 pic14emitRegularMap (idata, TRUE, TRUE);
543 pic14emitRegularMap (bit, TRUE, FALSE);
544 pic14emitRegularMap (xdata, TRUE, TRUE);
545 pic14emitRegularMap (sfr, FALSE, FALSE);
546 pic14emitRegularMap (sfrbit, FALSE, FALSE);
547 pic14emitRegularMap (code, TRUE, FALSE);
548 pic14emitStaticSeg (statsg);
551 /*-----------------------------------------------------------------*/
552 /* createInterruptVect - creates the interrupt vector */
553 /*-----------------------------------------------------------------*/
555 pic14createInterruptVect (FILE * vFile)
557 mainf = newSymbol ("main", 0);
560 /* only if the main function exists */
561 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
563 if (!options.cc_only)
564 // werror (E_NO_MAIN);
565 fprintf(stderr,"WARNING: function 'main' undefined\n");
569 /* if the main is only a prototype ie. no body then do nothing */
570 if (!IFFUNC_HASBODY(mainf->type))
572 /* if ! compile only then main function should be present */
573 if (!options.cc_only)
574 // werror (E_NO_MAIN);
575 fprintf(stderr,"WARNING: function 'main' undefined\n");
579 fprintf (vFile, "%s", iComments2);
580 fprintf (vFile, "; config word \n");
581 fprintf (vFile, "%s", iComments2);
582 fprintf (vFile, "\t__config 0x%x\n", getConfigWord(0x2007));
584 fprintf (vFile, "%s", iComments2);
585 fprintf (vFile, "; reset vector \n");
586 fprintf (vFile, "%s", iComments2);
587 fprintf (vFile, "STARTUP\t%s\n", CODE_NAME); // Lkr file should place section STARTUP at address 0x0
588 fprintf (vFile, "\tnop\n"); /* first location for used by incircuit debugger */
589 fprintf (vFile, "\tgoto\t__sdcc_gsinit_startup\n");
593 /*-----------------------------------------------------------------*/
594 /* initialComments - puts in some initial comments */
595 /*-----------------------------------------------------------------*/
597 pic14initialComments (FILE * afile)
599 initialComments (afile);
600 fprintf (afile, "; PIC port for the 14-bit core\n");
601 fprintf (afile, iComments2);
605 /*-----------------------------------------------------------------*/
606 /* printExterns - generates extern for external variables */
607 /*-----------------------------------------------------------------*/
609 pic14printExterns (FILE * afile)
613 fprintf (afile, "%s", iComments2);
614 fprintf (afile, "; extern variables in this module\n");
615 fprintf (afile, "%s", iComments2);
617 for (sym = setFirstItem (externs); sym;
618 sym = setNextItem (externs))
619 fprintf (afile, "\textern %s\n", sym->rname);
622 /*-----------------------------------------------------------------*/
623 /* printPublics - generates .global for publics */
624 /*-----------------------------------------------------------------*/
626 pic14printPublics (FILE * afile)
630 fprintf (afile, "%s", iComments2);
631 fprintf (afile, "; publics variables in this module\n");
632 fprintf (afile, "%s", iComments2);
634 for (sym = setFirstItem (publics); sym;
635 sym = setNextItem (publics)) {
637 if(!IS_BITFIELD(sym->type) && ((IS_FUNC(sym->type) || sym->allocreq))) {
638 if (!IS_BITVAR(sym->type))
639 fprintf (afile, "\tglobal %s\n", sym->rname);
641 /* Absolute variables are defines in the asm file as equates and thus can not be made global. */
642 if (!SPEC_ABSA (sym->etype))
643 fprintf (afile, "\tglobal %s\n", sym->rname);
648 /*-----------------------------------------------------------------*/
649 /* emitOverlay - will emit code for the overlay stuff */
650 /*-----------------------------------------------------------------*/
652 pic14emitOverlay (FILE * afile)
656 /* if (!elementsInSet (ovrSetSets))*/
658 /* the hack below, fixes translates for devices which
659 * only have udata_shr memory */
660 fprintf (afile, "%s\t%s\n",
661 (elementsInSet(ovrSetSets)?"":";"),
662 port->mem.overlay_name);
664 /* for each of the sets in the overlay segment do */
665 for (ovrset = setFirstItem (ovrSetSets); ovrset;
666 ovrset = setNextItem (ovrSetSets))
671 if (elementsInSet (ovrset))
673 /* this dummy area is used to fool the assembler
674 otherwise the assembler will append each of these
675 declarations into one chunk and will not overlay
678 /* I don't think this applies to us. We are using gpasm. CRF */
680 fprintf (afile, ";\t.area _DUMMY\n");
681 /* output the area informtion */
682 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
685 for (sym = setFirstItem (ovrset); sym;
686 sym = setNextItem (ovrset))
689 /* if extern then do nothing */
690 if (IS_EXTERN (sym->etype))
693 /* if allocation required check is needed
694 then check if the symbol really requires
695 allocation only for local variables */
696 if (!IS_AGGREGATE (sym->type) &&
697 !(sym->_isparm && !IS_REGPARM (sym->etype))
698 && !sym->allocreq && sym->level)
701 /* if global variable & not static or extern
702 and addPublics allowed then add it to the public set */
703 if ((sym->_isparm && !IS_REGPARM (sym->etype))
704 && !IS_STATIC (sym->etype))
705 addSetHead (&publics, sym);
707 /* if extern then do nothing or is a function
709 if (IS_FUNC (sym->type))
712 /* print extra debug info if required */
713 if (options.debug || sym->level == 0)
717 if (IS_STATIC (sym->etype))
718 fprintf (afile, "F%s_", moduleName); /* scope is file */
720 fprintf (afile, "G_"); /* scope is global */
723 /* symbol is local */
724 fprintf (afile, "L%s_",
725 (sym->localof ? sym->localof->name : "-null-"));
726 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
729 /* if is has an absolute address then generate
730 an equate for this no need to allocate space */
731 if (SPEC_ABSA (sym->etype))
734 if (options.debug || sym->level == 0)
735 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
737 fprintf (afile, "%s\t=\t0x%04x\n",
739 SPEC_ADDR (sym->etype));
743 if (options.debug || sym->level == 0)
744 fprintf (afile, "==.\n");
747 fprintf (afile, "%s:\n", sym->rname);
748 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
756 /*-----------------------------------------------------------------*/
757 /* glue - the final glue that hold the whole thing together */
758 /*-----------------------------------------------------------------*/
765 FILE *ovrFile = tempfile();
767 addSetHead(&tmpfileSet,ovrFile);
768 pCodeInitRegisters();
770 if (mainf && IFFUNC_HASBODY(mainf->type)) {
772 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
775 /* entry point @ start of CSEG */
776 addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
777 /* put in the call to main */
778 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
780 if (options.mainreturn) {
782 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
783 addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
787 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
788 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
794 /* At this point we've got all the code in the form of pCode structures */
795 /* Now it needs to be rearranged into the order it should be placed in the */
798 movepBlock2Head('P'); // Last
799 movepBlock2Head(code->dbName);
800 movepBlock2Head('X');
801 movepBlock2Head(statsg->dbName); // First
804 /* print the global struct definitions */
810 addSetHead(&tmpfileSet,vFile);
812 /* emit code for the all the variables declared */
814 /* do the overlay segments */
815 pic14emitOverlay(ovrFile);
817 /* PENDING: this isnt the best place but it will do */
818 if (port->general.glue_up_main) {
819 /* create the interrupt vector table */
820 pic14createInterruptVect (vFile);
825 ReuseReg(); // ReuseReg where call tree permits
834 /* now put it all together into the assembler file */
835 /* create the assembler file name */
837 if ((noAssemble || options.c1mode) && fullDstFileName)
839 sprintf (buffer, fullDstFileName);
843 sprintf (buffer, dstFileName);
844 strcat (buffer, ".asm");
847 if (!(asmFile = fopen (buffer, "w"))) {
848 werror (E_FILE_OPEN_ERR, buffer);
852 /* initial comments */
853 pic14initialComments (asmFile);
855 /* print module name */
856 fprintf (asmFile, ";\t.module %s\n", moduleName);
858 /* Let the port generate any global directives, etc. */
859 if (port->genAssemblerPreamble)
861 port->genAssemblerPreamble(asmFile);
864 /* print the extern variables in this module */
865 pic14printExterns (asmFile);
867 /* print the global variables in this module */
868 pic14printPublics (asmFile);
870 /* copy the sfr segment */
871 fprintf (asmFile, "%s", iComments2);
872 fprintf (asmFile, "; special function registers\n");
873 fprintf (asmFile, "%s", iComments2);
874 copyFile (asmFile, sfr->oFile);
877 if (udata_section_name) {
878 sprintf(udata_name,"%s",udata_section_name);
880 sprintf(udata_name,"data_%s",moduleName);
882 fprintf (asmFile, "%s", iComments2);
883 fprintf (asmFile, "; udata\n");
884 fprintf (asmFile, "%s", iComments2);
885 fprintf (asmFile, "%s\tudata\n", udata_name);
886 copyFile (asmFile, data->oFile);
888 /* Put all variables into a cblock */
890 writeUsedRegs(asmFile);
892 /* create the overlay segments */
893 fprintf (asmFile, "%s", iComments2);
894 fprintf (asmFile, "; overlayable items in internal ram \n");
895 fprintf (asmFile, "%s", iComments2);
896 copyFile (asmFile, ovrFile);
900 /* create the stack segment MOF */
901 if (mainf && IFFUNC_HASBODY(mainf->type)) {
902 fprintf (asmFile, "%s", iComments2);
903 fprintf (asmFile, "; Stack segment in internal ram \n");
904 fprintf (asmFile, "%s", iComments2);
905 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
906 ";__start__stack:\n;\t.ds\t1\n\n");
909 /* create the idata segment */
910 fprintf (asmFile, "%s", iComments2);
911 fprintf (asmFile, "; indirectly addressable internal ram data\n");
912 fprintf (asmFile, "%s", iComments2);
913 copyFile (asmFile, idata->oFile);
915 /* if external stack then reserve space of it */
916 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
917 fprintf (asmFile, "%s", iComments2);
918 fprintf (asmFile, "; external stack \n");
919 fprintf (asmFile, "%s", iComments2);
920 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
921 fprintf (asmFile,";\t.ds 256\n");
924 /* copy xtern ram data */
925 fprintf (asmFile, "%s", iComments2);
926 fprintf (asmFile, "; external ram data\n");
927 fprintf (asmFile, "%s", iComments2);
928 copyFile (asmFile, xdata->oFile);
932 /* copy the bit segment */
933 fprintf (asmFile, "%s", iComments2);
934 fprintf (asmFile, "; bit data\n");
935 fprintf (asmFile, "%s", iComments2);
936 copyFile (asmFile, bit->oFile);
938 /* copy the interrupt vector table */
939 if (mainf && IFFUNC_HASBODY(mainf->type)) {
940 copyFile (asmFile, vFile);
942 fprintf (asmFile, "%s", iComments2);
943 fprintf (asmFile, "; interrupt and initialization code\n");
944 fprintf (asmFile, "%s", iComments2);
945 fprintf (asmFile, "code_init\t%s\t0x4\n", CODE_NAME); // Note - for mplink may have to enlarge section vectors in .lnk file
947 /* interrupt service routine */
948 fprintf (asmFile, "__sdcc_interrupt:\n");
949 copypCode(asmFile, 'I');
951 /* initialize data memory */
952 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
953 /* FIXME: This is temporary. The idata section should be used. If
954 not, we could add a special feature to the linker. This will
955 work in the mean time. Put all initalized data in main.c */
956 copypCode(asmFile, statsg->dbName);
957 fprintf (asmFile,"\tpagesel _main\n");
958 fprintf (asmFile,"\tgoto _main\n");
963 /* copy global & static initialisations */
964 fprintf (asmFile, "%s", iComments2);
965 fprintf (asmFile, "; global & static initialisations\n");
966 fprintf (asmFile, "%s", iComments2);
967 copypCode(asmFile, statsg->dbName);
972 fprintf (asmFile, "%s", iComments2);
973 fprintf (asmFile, "; code\n");
974 fprintf (asmFile, "%s", iComments2);
975 fprintf (asmFile, "code_%s\t%s\n", moduleName, port->mem.code_name);
978 copypCode(asmFile, 'X');
981 copypCode(asmFile, 'M');
983 /* other functions */
984 copypCode(asmFile, code->dbName);
987 copypCode(asmFile, 'P');
989 fprintf (asmFile,"\tend\n");