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);
44 extern unsigned maxInterrupts;
45 extern int maxRegBank;
47 extern char *VersionString;
48 extern FILE *codeOutFile;
49 extern set *tmpfileSet;
50 extern set *tmpfileNameSet;
51 extern char *iComments1;
52 extern char *iComments2;
53 //extern void emitStaticSeg (memmap * map);
55 extern DEFSETFUNC (closeTmpFiles);
56 extern DEFSETFUNC (rmTmpFiles);
58 extern void AnalyzeBanking (void);
59 extern void copyFile (FILE * dest, FILE * src);
60 extern void InlinepCode(void);
61 extern void writeUsedRegs(FILE *);
63 extern void initialComments (FILE * afile);
64 extern void printPublics (FILE * afile);
66 extern void printChar (FILE * ofile, char *s, int plen);
67 void pCodeInitRegisters(void);
69 /*-----------------------------------------------------------------*/
70 /* aopLiteral - string from a literal value */
71 /*-----------------------------------------------------------------*/
72 int pic14aopLiteral (value *val, int offset)
79 /* if it is a float then it gets tricky */
80 /* otherwise it is fairly simple */
81 if (!IS_FLOAT(val->type)) {
82 unsigned long v = (unsigned long) floatFromVal(val);
84 return ( (v >> (offset * 8)) & 0xff);
87 /* it is type float */
88 fl.f = (float) floatFromVal(val);
89 #ifdef WORDS_BIGENDIAN
90 return fl.c[3-offset];
98 /*-----------------------------------------------------------------*/
99 /* emitRegularMap - emit code for maps with no special cases */
100 /*-----------------------------------------------------------------*/
102 pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
105 int i, size, bitvars = 0;;
108 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
110 /* print the area name */
111 for (sym = setFirstItem (map->syms); sym;
112 sym = setNextItem (map->syms))
115 /* if extern then do nothing */
116 if (IS_EXTERN (sym->etype))
119 /* if allocation required check is needed
120 then check if the symbol really requires
121 allocation only for local variables */
122 if (arFlag && !IS_AGGREGATE (sym->type) &&
123 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
124 !sym->allocreq && sym->level)
127 /* if global variable & not static or extern
128 and addPublics allowed then add it to the public set */
129 if ((sym->level == 0 ||
130 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
132 !IS_STATIC (sym->etype))
133 addSetHead (&publics, sym);
135 /* if extern then do nothing or is a function
137 if (IS_FUNC (sym->type))
140 /* print extra debug info if required */
141 if (options.debug || sym->level == 0)
143 if (!sym->level) /* global */
144 if (IS_STATIC (sym->etype))
145 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
147 fprintf (map->oFile, "G_"); /* scope is global */
149 /* symbol is local */
150 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
151 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
155 /* if is has an absolute address then generate
156 an equate for this no need to allocate space */
157 if (SPEC_ABSA (sym->etype))
159 //if (options.debug || sym->level == 0)
160 //fprintf (map->oFile,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
162 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
164 SPEC_ADDR (sym->etype));
170 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
171 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
172 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
173 if (IS_BITVAR (sym->etype))
179 fprintf (map->oFile, "\t%s\n", sym->rname);
180 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
182 for (i = 1; i < size; i++)
183 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
186 //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
189 /* if it has a initial value then do it only if
190 it is a global variable */
191 if (sym->ival && sym->level == 0) {
194 if (IS_AGGREGATE (sym->type))
195 ival = initAggregates (sym, sym->ival, NULL);
197 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
198 decorateType (resolveSymbols (list2expr (sym->ival))));
199 codeOutFile = statsg->oFile;
201 eBBlockFromiCode (iCodeFromAst (ival));
208 /*-----------------------------------------------------------------*/
209 /* printIvalType - generates ival for int/char */
210 /*-----------------------------------------------------------------*/
212 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
217 //fprintf(stderr, "%s\n",__FUNCTION__);
219 /* if initList is deep */
220 if (ilist->type == INIT_DEEP)
221 ilist = ilist->init.deep;
223 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
224 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
227 if (!(val = list2val (ilist))) {
228 // assuming a warning has been thrown
232 if (val->type != type) {
233 val = valCastLiteral(type, floatFromVal(val));
237 ulval = (unsigned long) floatFromVal (val);
241 switch (getSize (type)) {
243 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
247 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
248 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
252 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
253 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
254 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
255 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
260 /*-----------------------------------------------------------------*/
261 /* printIvalChar - generates initital value for character array */
262 /*-----------------------------------------------------------------*/
264 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
272 fprintf(stderr, "%s\n",__FUNCTION__);
276 val = list2val (ilist);
277 /* if the value is a character string */
278 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
280 if (!DCL_ELEM (type))
281 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
283 //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
284 //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
285 addpCode2pBlock(pb,newpCodeCharP(";omitting call to printChar"));
287 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
289 //tfprintf (oFile, "\t!db !constbyte\n", 0);
290 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
297 //printChar (oFile, s, strlen (s) + 1);
299 for(remain=0; remain<strlen(s); remain++) {
300 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
301 //fprintf(stderr,"0x%02x ",s[remain]);
303 //fprintf(stderr,"\n");
308 /*-----------------------------------------------------------------*/
309 /* printIvalArray - generates code for array initialization */
310 /*-----------------------------------------------------------------*/
312 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
316 int lcnt = 0, size = 0;
321 /* take care of the special case */
322 /* array of characters can be init */
324 if (IS_CHAR (type->next)) {
325 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
326 if (!IS_LITERAL(list2val(ilist)->etype)) {
327 werror (W_INIT_WRONG);
330 if (printIvalChar (type,
331 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
332 pb, SPEC_CVAL (sym->etype).v_char))
335 /* not the special case */
336 if (ilist->type != INIT_DEEP)
338 werror (E_INIT_STRUCT, sym->name);
342 iloop = ilist->init.deep;
343 lcnt = DCL_ELEM (type);
347 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
349 printIval (sym, type->next, iloop, pb);
350 iloop = (iloop ? iloop->next : NULL);
353 /* if not array limits given & we */
354 /* are out of initialisers then */
355 if (!DCL_ELEM (type) && !iloop)
358 /* no of elements given and we */
359 /* have generated for all of them */
361 /* if initializers left */
363 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
369 /* if we have not been given a size */
370 if (!DCL_ELEM (type))
371 DCL_ELEM (type) = size;
376 /*-----------------------------------------------------------------*/
377 /* printIval - generates code for initial value */
378 /*-----------------------------------------------------------------*/
380 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
385 /* if structure then */
386 if (IS_STRUCT (type))
388 //fprintf(stderr,"%s struct\n",__FUNCTION__);
389 //printIvalStruct (sym, type, ilist, oFile);
393 /* if this is a pointer */
396 //fprintf(stderr,"%s pointer\n",__FUNCTION__);
397 //printIvalPtr (sym, type, ilist, oFile);
401 /* if this is an array */
404 //fprintf(stderr,"%s array\n",__FUNCTION__);
405 printIvalArray (sym, type, ilist, pb);
409 /* if type is SPECIFIER */
412 //fprintf(stderr,"%s spec\n",__FUNCTION__);
413 printIvalType (sym, type, ilist, pb);
418 extern void pCodeConstString(char *name, char *value);
419 /*-----------------------------------------------------------------*/
420 /* emitStaticSeg - emitcode for the static segment */
421 /*-----------------------------------------------------------------*/
423 pic14emitStaticSeg (memmap * map)
427 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
429 //fprintf(stderr, "%s\n",__FUNCTION__);
431 /* for all variables in this segment do */
432 for (sym = setFirstItem (map->syms); sym;
433 sym = setNextItem (map->syms))
435 /* if it is "extern" then do nothing */
436 if (IS_EXTERN (sym->etype))
439 /* if it is not static add it to the public
441 if (!IS_STATIC (sym->etype))
442 addSetHead (&publics, sym);
444 /* print extra debug info if required */
445 if (options.debug || sym->level == 0)
449 if (IS_STATIC (sym->etype))
450 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
452 fprintf (code->oFile, "G_"); /* scope is global */
455 /* symbol is local */
456 fprintf (code->oFile, "L%s_",
457 (sym->localof ? sym->localof->name : "-null-"));
458 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
462 /* if it has an absolute address */
463 if (SPEC_ABSA (sym->etype))
465 if (options.debug || sym->level == 0)
466 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
468 fprintf (code->oFile, "%s\t=\t0x%04x\n",
470 SPEC_ADDR (sym->etype));
474 if (options.debug || sym->level == 0)
475 fprintf (code->oFile, " == .\n");
477 /* if it has an initial value */
482 fprintf (code->oFile, "%s:\n", sym->rname);
484 resolveIvalSym (sym->ival);
485 //printIval (sym, sym->type, sym->ival, code->oFile);
486 pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
488 addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
490 printIval (sym, sym->type, sym->ival, pb);
497 fprintf (code->oFile, "%s:\n", sym->rname);
498 /* special case for character strings */
499 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
500 SPEC_CVAL (sym->etype).v_char)
501 pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
502 /*printChar (code->oFile,
503 SPEC_CVAL (sym->etype).v_char,
504 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
506 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
514 /*-----------------------------------------------------------------*/
515 /* emitMaps - emits the code for the data portion the code */
516 /*-----------------------------------------------------------------*/
520 /* no special considerations for the following
521 data, idata & bit & xdata */
522 pic14emitRegularMap (data, TRUE, TRUE);
523 pic14emitRegularMap (idata, TRUE, TRUE);
524 pic14emitRegularMap (bit, TRUE, FALSE);
525 pic14emitRegularMap (xdata, TRUE, TRUE);
526 pic14emitRegularMap (sfr, FALSE, FALSE);
527 pic14emitRegularMap (sfrbit, FALSE, FALSE);
528 pic14emitRegularMap (code, TRUE, FALSE);
529 pic14emitStaticSeg (statsg);
532 /*-----------------------------------------------------------------*/
533 /* createInterruptVect - creates the interrupt vector */
534 /*-----------------------------------------------------------------*/
536 pic14createInterruptVect (FILE * vFile)
539 mainf = newSymbol ("main", 0);
542 /* only if the main function exists */
543 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
545 if (!options.cc_only)
550 /* if the main is only a prototype ie. no body then do nothing */
551 if (!IFFUNC_HASBODY(mainf->type))
553 /* if ! compile only then main function should be present */
554 if (!options.cc_only)
559 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
560 fprintf (vFile, ";__interrupt_vect:\n");
563 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
565 /* "generic" interrupt table header (if port doesn't specify one).
567 * Look suspiciously like 8051 code to me...
570 fprintf (vFile, ";\tljmp\t__sdcc_gsinit_startup\n");
573 /* now for the other interrupts */
574 for (; i < maxInterrupts; i++)
577 fprintf (vFile, ";\tljmp\t%s\n;\t.ds\t5\n", interrupts[i]->rname);
579 fprintf (vFile, ";\treti\n;\t.ds\t7\n");
585 /*-----------------------------------------------------------------*/
586 /* initialComments - puts in some initial comments */
587 /*-----------------------------------------------------------------*/
589 pic14initialComments (FILE * afile)
591 initialComments (afile);
592 fprintf (afile, "; PIC port for the 14-bit core\n");
593 fprintf (afile, iComments2);
597 /*-----------------------------------------------------------------*/
598 /* printPublics - generates .global for publics */
599 /*-----------------------------------------------------------------*/
601 pic14printPublics (FILE * afile)
605 fprintf (afile, "%s", iComments2);
606 fprintf (afile, "; publics variables in this module\n");
607 fprintf (afile, "%s", iComments2);
609 for (sym = setFirstItem (publics); sym;
610 sym = setNextItem (publics))
611 fprintf (afile, ";\t.globl %s\n", sym->rname);
616 /*-----------------------------------------------------------------*/
617 /* emitOverlay - will emit code for the overlay stuff */
618 /*-----------------------------------------------------------------*/
620 pic14emitOverlay (FILE * afile)
624 if (!elementsInSet (ovrSetSets))
625 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
627 /* for each of the sets in the overlay segment do */
628 for (ovrset = setFirstItem (ovrSetSets); ovrset;
629 ovrset = setNextItem (ovrSetSets))
634 if (elementsInSet (ovrset))
636 /* this dummy area is used to fool the assembler
637 otherwise the assembler will append each of these
638 declarations into one chunk and will not overlay
640 fprintf (afile, ";\t.area _DUMMY\n");
641 /* output the area informtion */
642 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
645 for (sym = setFirstItem (ovrset); sym;
646 sym = setNextItem (ovrset))
649 /* if extern then do nothing */
650 if (IS_EXTERN (sym->etype))
653 /* if allocation required check is needed
654 then check if the symbol really requires
655 allocation only for local variables */
656 if (!IS_AGGREGATE (sym->type) &&
657 !(sym->_isparm && !IS_REGPARM (sym->etype))
658 && !sym->allocreq && sym->level)
661 /* if global variable & not static or extern
662 and addPublics allowed then add it to the public set */
663 if ((sym->_isparm && !IS_REGPARM (sym->etype))
664 && !IS_STATIC (sym->etype))
665 addSetHead (&publics, sym);
667 /* if extern then do nothing or is a function
669 if (IS_FUNC (sym->type))
672 /* print extra debug info if required */
673 if (options.debug || sym->level == 0)
677 if (IS_STATIC (sym->etype))
678 fprintf (afile, "F%s_", moduleName); /* scope is file */
680 fprintf (afile, "G_"); /* scope is global */
683 /* symbol is local */
684 fprintf (afile, "L%s_",
685 (sym->localof ? sym->localof->name : "-null-"));
686 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
689 /* if is has an absolute address then generate
690 an equate for this no need to allocate space */
691 if (SPEC_ABSA (sym->etype))
694 if (options.debug || sym->level == 0)
695 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
697 fprintf (afile, "%s\t=\t0x%04x\n",
699 SPEC_ADDR (sym->etype));
703 if (options.debug || sym->level == 0)
704 fprintf (afile, "==.\n");
707 fprintf (afile, "%s:\n", sym->rname);
708 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
716 /*-----------------------------------------------------------------*/
717 /* glue - the final glue that hold the whole thing together */
718 /*-----------------------------------------------------------------*/
725 FILE *ovrFile = tempfile();
727 addSetHead(&tmpfileSet,ovrFile);
728 pCodeInitRegisters();
730 if (mainf && IFFUNC_HASBODY(mainf->type)) {
732 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
735 /* entry point @ start of CSEG */
736 addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
737 /* put in the call to main */
738 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
740 if (options.mainreturn) {
742 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
743 addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
747 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
748 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
754 /* At this point we've got all the code in the form of pCode structures */
755 /* Now it needs to be rearranged into the order it should be placed in the */
758 movepBlock2Head('P'); // Last
759 movepBlock2Head(code->dbName);
760 movepBlock2Head('X');
761 movepBlock2Head(statsg->dbName); // First
764 /* print the global struct definitions */
769 /* PENDING: this isnt the best place but it will do */
770 if (port->general.glue_up_main) {
771 /* create the interrupt vector table */
772 pic14createInterruptVect (vFile);
775 addSetHead(&tmpfileSet,vFile);
777 /* emit code for the all the variables declared */
779 /* do the overlay segments */
780 pic14emitOverlay(ovrFile);
786 //printCallTree(stderr);
796 /* now put it all together into the assembler file */
797 /* create the assembler file name */
799 if ((noAssemble || options.c1mode) && fullDstFileName)
801 sprintf (buffer, fullDstFileName);
805 sprintf (buffer, dstFileName);
806 strcat (buffer, ".asm");
809 if (!(asmFile = fopen (buffer, "w"))) {
810 werror (E_FILE_OPEN_ERR, buffer);
814 /* initial comments */
815 pic14initialComments (asmFile);
817 /* print module name */
818 fprintf (asmFile, ";\t.module %s\n", moduleName);
820 /* Let the port generate any global directives, etc. */
821 if (port->genAssemblerPreamble)
823 port->genAssemblerPreamble(asmFile);
826 /* print the global variables in this module */
827 pic14printPublics (asmFile);
830 /* copy the sfr segment */
831 fprintf (asmFile, "%s", iComments2);
832 fprintf (asmFile, "; special function registers\n");
833 fprintf (asmFile, "%s", iComments2);
834 copyFile (asmFile, sfr->oFile);
837 /* Put all variables into a cblock */
839 writeUsedRegs(asmFile);
841 /* create the overlay segments */
842 fprintf (asmFile, "%s", iComments2);
843 fprintf (asmFile, "; overlayable items in internal ram \n");
844 fprintf (asmFile, "%s", iComments2);
845 copyFile (asmFile, ovrFile);
847 /* create the stack segment MOF */
848 if (mainf && IFFUNC_HASBODY(mainf->type)) {
849 fprintf (asmFile, "%s", iComments2);
850 fprintf (asmFile, "; Stack segment in internal ram \n");
851 fprintf (asmFile, "%s", iComments2);
852 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
853 ";__start__stack:\n;\t.ds\t1\n\n");
856 /* create the idata segment */
857 fprintf (asmFile, "%s", iComments2);
858 fprintf (asmFile, "; indirectly addressable internal ram data\n");
859 fprintf (asmFile, "%s", iComments2);
860 copyFile (asmFile, idata->oFile);
862 /* if external stack then reserve space of it */
863 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
864 fprintf (asmFile, "%s", iComments2);
865 fprintf (asmFile, "; external stack \n");
866 fprintf (asmFile, "%s", iComments2);
867 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
868 fprintf (asmFile,";\t.ds 256\n");
872 /* copy xtern ram data */
873 fprintf (asmFile, "%s", iComments2);
874 fprintf (asmFile, "; external ram data\n");
875 fprintf (asmFile, "%s", iComments2);
876 copyFile (asmFile, xdata->oFile);
879 /* copy the bit segment */
880 fprintf (asmFile, "%s", iComments2);
881 fprintf (asmFile, "; bit data\n");
882 fprintf (asmFile, "%s", iComments2);
883 copyFile (asmFile, bit->oFile);
886 fprintf (asmFile, "\tORG 0\n");
888 /* copy the interrupt vector table */
889 if (mainf && IFFUNC_HASBODY(mainf->type)) {
890 fprintf (asmFile, "%s", iComments2);
891 fprintf (asmFile, "; interrupt vector \n");
892 fprintf (asmFile, "%s", iComments2);
893 copyFile (asmFile, vFile);
896 /* copy global & static initialisations */
897 fprintf (asmFile, "%s", iComments2);
898 fprintf (asmFile, "; global & static initialisations\n");
899 fprintf (asmFile, "%s", iComments2);
901 /* Everywhere we generate a reference to the static_name area,
902 * (which is currently only here), we immediately follow it with a
903 * definition of the post_static_name area. This guarantees that
904 * the post_static_name area will immediately follow the static_name
907 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
908 fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
909 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
911 if (mainf && IFFUNC_HASBODY(mainf->type)) {
912 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
913 /* if external stack is specified then the
914 higher order byte of the xdatalocation is
915 going into P2 and the lower order going into
917 if (options.useXstack) {
918 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
919 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
920 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
921 (unsigned int)options.xdata_loc & 0xff);
926 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
928 /* This code is generated in the post-static area.
929 * This area is guaranteed to follow the static area
930 * by the ugly shucking and jiving about 20 lines ago.
932 fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
933 fprintf (asmFile,";\tljmp\t__sdcc_program_startup\n");
937 fprintf (asmFile, "%s", iComments2);
938 fprintf (asmFile, "; code\n");
939 fprintf (asmFile, "%s", iComments2);
940 fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
942 //copyFile (stderr, code->oFile);
944 copypCode(asmFile, 'I');
945 copypCode(asmFile, statsg->dbName);
946 copypCode(asmFile, 'X');
947 copypCode(asmFile, 'M');
948 copypCode(asmFile, code->dbName);
949 copypCode(asmFile, 'P');
952 fprintf (asmFile,"\tend\n");