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"
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);
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);
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);
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)
144 cdbSymbol (sym, cdbFile, FALSE, FALSE);
146 if (!sym->level) /* global */
147 if (IS_STATIC (sym->etype))
148 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
150 fprintf (map->oFile, "G_"); /* scope is global */
152 /* symbol is local */
153 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
154 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
158 /* if is has an absolute address then generate
159 an equate for this no need to allocate space */
160 if (SPEC_ABSA (sym->etype))
162 //if (options.debug || sym->level == 0)
163 //fprintf (map->oFile,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
165 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
167 SPEC_ADDR (sym->etype));
173 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
174 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
175 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
176 if (IS_BITVAR (sym->etype))
182 fprintf (map->oFile, "\t%s\n", sym->rname);
183 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
185 for (i = 1; i < size; i++)
186 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
189 //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
192 /* if it has a initial value then do it only if
193 it is a global variable */
194 if (sym->ival && sym->level == 0) {
197 if (IS_AGGREGATE (sym->type))
198 ival = initAggregates (sym, sym->ival, NULL);
200 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
201 decorateType (resolveSymbols (list2expr (sym->ival))));
202 codeOutFile = statsg->oFile;
204 eBBlockFromiCode (iCodeFromAst (ival));
211 /*-----------------------------------------------------------------*/
212 /* printIvalType - generates ival for int/char */
213 /*-----------------------------------------------------------------*/
215 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
220 //fprintf(stderr, "%s\n",__FUNCTION__);
222 /* if initList is deep */
223 if (ilist->type == INIT_DEEP)
224 ilist = ilist->init.deep;
226 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
227 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
230 if (!(val = list2val (ilist))) {
231 // assuming a warning has been thrown
235 if (val->type != type) {
236 val = valCastLiteral(type, floatFromVal(val));
240 ulval = (unsigned long) floatFromVal (val);
244 switch (getSize (type)) {
246 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
250 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
251 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
255 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
256 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
257 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
258 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
263 /*-----------------------------------------------------------------*/
264 /* printIvalChar - generates initital value for character array */
265 /*-----------------------------------------------------------------*/
267 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
275 fprintf(stderr, "%s\n",__FUNCTION__);
279 val = list2val (ilist);
280 /* if the value is a character string */
281 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
283 if (!DCL_ELEM (type))
284 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
286 //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
287 //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
288 addpCode2pBlock(pb,newpCodeCharP(";omitting call to printChar"));
290 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
292 //tfprintf (oFile, "\t!db !constbyte\n", 0);
293 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
300 //printChar (oFile, s, strlen (s) + 1);
302 for(remain=0; remain<strlen(s); remain++) {
303 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
304 //fprintf(stderr,"0x%02x ",s[remain]);
306 //fprintf(stderr,"\n");
311 /*-----------------------------------------------------------------*/
312 /* printIvalArray - generates code for array initialization */
313 /*-----------------------------------------------------------------*/
315 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
319 int lcnt = 0, size = 0;
324 /* take care of the special case */
325 /* array of characters can be init */
327 if (IS_CHAR (type->next)) {
328 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
329 if (!IS_LITERAL(list2val(ilist)->etype)) {
330 werror (W_INIT_WRONG);
333 if (printIvalChar (type,
334 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
335 pb, SPEC_CVAL (sym->etype).v_char))
338 /* not the special case */
339 if (ilist->type != INIT_DEEP)
341 werror (E_INIT_STRUCT, sym->name);
345 iloop = ilist->init.deep;
346 lcnt = DCL_ELEM (type);
350 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
352 printIval (sym, type->next, iloop, pb);
353 iloop = (iloop ? iloop->next : NULL);
356 /* if not array limits given & we */
357 /* are out of initialisers then */
358 if (!DCL_ELEM (type) && !iloop)
361 /* no of elements given and we */
362 /* have generated for all of them */
364 /* if initializers left */
366 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
372 /* if we have not been given a size */
373 if (!DCL_ELEM (type))
374 DCL_ELEM (type) = size;
379 /*-----------------------------------------------------------------*/
380 /* printIval - generates code for initial value */
381 /*-----------------------------------------------------------------*/
383 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
388 /* if structure then */
389 if (IS_STRUCT (type))
391 //fprintf(stderr,"%s struct\n",__FUNCTION__);
392 //printIvalStruct (sym, type, ilist, oFile);
396 /* if this is a pointer */
399 //fprintf(stderr,"%s pointer\n",__FUNCTION__);
400 //printIvalPtr (sym, type, ilist, oFile);
404 /* if this is an array */
407 //fprintf(stderr,"%s array\n",__FUNCTION__);
408 printIvalArray (sym, type, ilist, pb);
412 /* if type is SPECIFIER */
415 //fprintf(stderr,"%s spec\n",__FUNCTION__);
416 printIvalType (sym, type, ilist, pb);
421 extern void pCodeConstString(char *name, char *value);
422 /*-----------------------------------------------------------------*/
423 /* emitStaticSeg - emitcode for the static segment */
424 /*-----------------------------------------------------------------*/
426 pic14emitStaticSeg (memmap * map)
430 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
432 //fprintf(stderr, "%s\n",__FUNCTION__);
434 /* for all variables in this segment do */
435 for (sym = setFirstItem (map->syms); sym;
436 sym = setNextItem (map->syms))
438 /* if it is "extern" then do nothing */
439 if (IS_EXTERN (sym->etype))
442 /* if it is not static add it to the public
444 if (!IS_STATIC (sym->etype))
445 addSetHead (&publics, sym);
447 /* print extra debug info if required */
448 if (options.debug || sym->level == 0)
450 /* NOTE to me - cdbFile may be null in which case,
451 * the sym name will be printed to stdout. oh well */
453 cdbSymbol (sym, cdbFile, FALSE, FALSE);
457 if (IS_STATIC (sym->etype))
458 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
460 fprintf (code->oFile, "G_"); /* scope is global */
463 /* symbol is local */
464 fprintf (code->oFile, "L%s_",
465 (sym->localof ? sym->localof->name : "-null-"));
466 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
470 /* if it has an absolute address */
471 if (SPEC_ABSA (sym->etype))
473 if (options.debug || sym->level == 0)
474 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
476 fprintf (code->oFile, "%s\t=\t0x%04x\n",
478 SPEC_ADDR (sym->etype));
482 if (options.debug || sym->level == 0)
483 fprintf (code->oFile, " == .\n");
485 /* if it has an initial value */
490 fprintf (code->oFile, "%s:\n", sym->rname);
492 resolveIvalSym (sym->ival);
493 //printIval (sym, sym->type, sym->ival, code->oFile);
494 pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
496 addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
498 printIval (sym, sym->type, sym->ival, pb);
505 fprintf (code->oFile, "%s:\n", sym->rname);
506 /* special case for character strings */
507 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
508 SPEC_CVAL (sym->etype).v_char)
509 pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
510 /*printChar (code->oFile,
511 SPEC_CVAL (sym->etype).v_char,
512 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
514 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
522 /*-----------------------------------------------------------------*/
523 /* emitMaps - emits the code for the data portion the code */
524 /*-----------------------------------------------------------------*/
528 /* no special considerations for the following
529 data, idata & bit & xdata */
530 pic14emitRegularMap (data, TRUE, TRUE);
531 pic14emitRegularMap (idata, TRUE, TRUE);
532 pic14emitRegularMap (bit, TRUE, FALSE);
533 pic14emitRegularMap (xdata, TRUE, TRUE);
534 pic14emitRegularMap (sfr, FALSE, FALSE);
535 pic14emitRegularMap (sfrbit, FALSE, FALSE);
536 pic14emitRegularMap (code, TRUE, FALSE);
537 pic14emitStaticSeg (statsg);
540 /*-----------------------------------------------------------------*/
541 /* createInterruptVect - creates the interrupt vector */
542 /*-----------------------------------------------------------------*/
544 pic14createInterruptVect (FILE * vFile)
547 mainf = newSymbol ("main", 0);
550 /* only if the main function exists */
551 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
553 if (!options.cc_only)
558 /* if the main is only a prototype ie. no body then do nothing */
559 if (!IFFUNC_HASBODY(mainf->type))
561 /* if ! compile only then main function should be present */
562 if (!options.cc_only)
567 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
568 fprintf (vFile, ";__interrupt_vect:\n");
571 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
573 /* "generic" interrupt table header (if port doesn't specify one).
575 * Look suspiciously like 8051 code to me...
578 fprintf (vFile, ";\tljmp\t__sdcc_gsinit_startup\n");
581 /* now for the other interrupts */
582 for (; i < maxInterrupts; i++)
585 fprintf (vFile, ";\tljmp\t%s\n;\t.ds\t5\n", interrupts[i]->rname);
587 fprintf (vFile, ";\treti\n;\t.ds\t7\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 /* printPublics - generates .global for publics */
607 /*-----------------------------------------------------------------*/
609 pic14printPublics (FILE * afile)
613 fprintf (afile, "%s", iComments2);
614 fprintf (afile, "; publics variables in this module\n");
615 fprintf (afile, "%s", iComments2);
617 for (sym = setFirstItem (publics); sym;
618 sym = setNextItem (publics))
619 fprintf (afile, ";\t.globl %s\n", sym->rname);
624 /*-----------------------------------------------------------------*/
625 /* emitOverlay - will emit code for the overlay stuff */
626 /*-----------------------------------------------------------------*/
628 pic14emitOverlay (FILE * afile)
632 if (!elementsInSet (ovrSetSets))
633 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
635 /* for each of the sets in the overlay segment do */
636 for (ovrset = setFirstItem (ovrSetSets); ovrset;
637 ovrset = setNextItem (ovrSetSets))
642 if (elementsInSet (ovrset))
644 /* this dummy area is used to fool the assembler
645 otherwise the assembler will append each of these
646 declarations into one chunk and will not overlay
648 fprintf (afile, ";\t.area _DUMMY\n");
649 /* output the area informtion */
650 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
653 for (sym = setFirstItem (ovrset); sym;
654 sym = setNextItem (ovrset))
657 /* if extern then do nothing */
658 if (IS_EXTERN (sym->etype))
661 /* if allocation required check is needed
662 then check if the symbol really requires
663 allocation only for local variables */
664 if (!IS_AGGREGATE (sym->type) &&
665 !(sym->_isparm && !IS_REGPARM (sym->etype))
666 && !sym->allocreq && sym->level)
669 /* if global variable & not static or extern
670 and addPublics allowed then add it to the public set */
671 if ((sym->_isparm && !IS_REGPARM (sym->etype))
672 && !IS_STATIC (sym->etype))
673 addSetHead (&publics, sym);
675 /* if extern then do nothing or is a function
677 if (IS_FUNC (sym->type))
680 /* print extra debug info if required */
681 if (options.debug || sym->level == 0)
684 cdbSymbol (sym, cdbFile, FALSE, FALSE);
688 if (IS_STATIC (sym->etype))
689 fprintf (afile, "F%s_", moduleName); /* scope is file */
691 fprintf (afile, "G_"); /* scope is global */
694 /* symbol is local */
695 fprintf (afile, "L%s_",
696 (sym->localof ? sym->localof->name : "-null-"));
697 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
700 /* if is has an absolute address then generate
701 an equate for this no need to allocate space */
702 if (SPEC_ABSA (sym->etype))
705 if (options.debug || sym->level == 0)
706 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
708 fprintf (afile, "%s\t=\t0x%04x\n",
710 SPEC_ADDR (sym->etype));
714 if (options.debug || sym->level == 0)
715 fprintf (afile, "==.\n");
718 fprintf (afile, "%s:\n", sym->rname);
719 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
727 /*-----------------------------------------------------------------*/
728 /* glue - the final glue that hold the whole thing together */
729 /*-----------------------------------------------------------------*/
736 FILE *ovrFile = tempfile();
747 DFPRINTF((stderr,"\n\n\n******************\n\n\n"));
748 for(t=s; t; t=t->next) {
750 DFPRINTF((stderr,"Set item %d\n",*(char *)t->item));
754 for(t=s; t; t=t->next) {
756 DFPRINTF((stderr,"Set item %d\n",*(char *)t->item));
760 addSetHead(&tmpfileSet,ovrFile);
763 if (mainf && IFFUNC_HASBODY(mainf->type)) {
765 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
768 /* entry point @ start of CSEG */
769 addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
770 /* put in the call to main */
771 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
773 if (options.mainreturn) {
775 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
776 addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
780 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
781 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
787 /* At this point we've got all the code in the form of pCode structures */
788 /* Now it needs to be rearranged into the order it should be placed in the */
791 movepBlock2Head('P'); // Last
792 movepBlock2Head(code->dbName);
793 movepBlock2Head('X');
794 movepBlock2Head(statsg->dbName); // First
797 /* print the global struct definitions */
799 cdbStructBlock (0,cdbFile);
802 /* PENDING: this isnt the best place but it will do */
803 if (port->general.glue_up_main) {
804 /* create the interrupt vector table */
805 pic14createInterruptVect (vFile);
808 addSetHead(&tmpfileSet,vFile);
810 /* emit code for the all the variables declared */
812 /* do the overlay segments */
813 pic14emitOverlay(ovrFile);
816 AnalyzepCode('*'); //code->dbName);
819 // printCallTree(stderr);
825 /* now put it all together into the assembler file */
826 /* create the assembler file name */
828 if (!options.c1mode) {
829 sprintf (buffer, srcFileName);
830 strcat (buffer, ".asm");
833 strcpy(buffer, options.out_name);
836 if (!(asmFile = fopen (buffer, "w"))) {
837 werror (E_FILE_OPEN_ERR, buffer);
841 /* initial comments */
842 pic14initialComments (asmFile);
844 /* print module name */
845 fprintf (asmFile, ";\t.module %s\n", moduleName);
847 /* Let the port generate any global directives, etc. */
848 if (port->genAssemblerPreamble)
850 port->genAssemblerPreamble(asmFile);
853 /* print the global variables in this module */
854 pic14printPublics (asmFile);
857 /* copy the sfr segment */
858 fprintf (asmFile, "%s", iComments2);
859 fprintf (asmFile, "; special function registers\n");
860 fprintf (asmFile, "%s", iComments2);
861 copyFile (asmFile, sfr->oFile);
864 /* Put all variables into a cblock */
865 writeUsedRegs(asmFile);
868 /* create the overlay segments */
869 fprintf (asmFile, "%s", iComments2);
870 fprintf (asmFile, "; overlayable items in internal ram \n");
871 fprintf (asmFile, "%s", iComments2);
872 copyFile (asmFile, ovrFile);
874 /* create the stack segment MOF */
875 if (mainf && IFFUNC_HASBODY(mainf->type)) {
876 fprintf (asmFile, "%s", iComments2);
877 fprintf (asmFile, "; Stack segment in internal ram \n");
878 fprintf (asmFile, "%s", iComments2);
879 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
880 ";__start__stack:\n;\t.ds\t1\n\n");
883 /* create the idata segment */
884 fprintf (asmFile, "%s", iComments2);
885 fprintf (asmFile, "; indirectly addressable internal ram data\n");
886 fprintf (asmFile, "%s", iComments2);
887 copyFile (asmFile, idata->oFile);
889 /* if external stack then reserve space of it */
890 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
891 fprintf (asmFile, "%s", iComments2);
892 fprintf (asmFile, "; external stack \n");
893 fprintf (asmFile, "%s", iComments2);
894 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
895 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);
906 /* copy the bit segment */
907 fprintf (asmFile, "%s", iComments2);
908 fprintf (asmFile, "; bit data\n");
909 fprintf (asmFile, "%s", iComments2);
910 copyFile (asmFile, bit->oFile);
913 fprintf (asmFile, "\tORG 0\n");
915 /* copy the interrupt vector table */
916 if (mainf && IFFUNC_HASBODY(mainf->type)) {
917 fprintf (asmFile, "%s", iComments2);
918 fprintf (asmFile, "; interrupt vector \n");
919 fprintf (asmFile, "%s", iComments2);
920 copyFile (asmFile, vFile);
923 /* copy global & static initialisations */
924 fprintf (asmFile, "%s", iComments2);
925 fprintf (asmFile, "; global & static initialisations\n");
926 fprintf (asmFile, "%s", iComments2);
928 /* Everywhere we generate a reference to the static_name area,
929 * (which is currently only here), we immediately follow it with a
930 * definition of the post_static_name area. This guarantees that
931 * the post_static_name area will immediately follow the static_name
934 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
935 fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
936 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
938 if (mainf && IFFUNC_HASBODY(mainf->type)) {
939 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
940 /* if external stack is specified then the
941 higher order byte of the xdatalocation is
942 going into P2 and the lower order going into
944 if (options.useXstack) {
945 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
946 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
947 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
948 (unsigned int)options.xdata_loc & 0xff);
953 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
955 /* This code is generated in the post-static area.
956 * This area is guaranteed to follow the static area
957 * by the ugly shucking and jiving about 20 lines ago.
959 fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
960 fprintf (asmFile,";\tljmp\t__sdcc_program_startup\n");
964 fprintf (asmFile, "%s", iComments2);
965 fprintf (asmFile, "; code\n");
966 fprintf (asmFile, "%s", iComments2);
967 fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
969 //copyFile (stderr, code->oFile);
971 copypCode(asmFile, 'I');
972 copypCode(asmFile, statsg->dbName);
973 copypCode(asmFile, 'X');
974 copypCode(asmFile, 'M');
975 copypCode(asmFile, code->dbName);
976 copypCode(asmFile, 'P');
979 fprintf (asmFile,"\tend\n");
982 applyToSet(tmpfileSet,closeTmpFiles);
983 applyToSet(tmpfileNameSet, rmTmpFiles);