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 - byte from a literal value */
71 /*-----------------------------------------------------------------*/
73 _aopLiteral (value * val, int offset)
75 unsigned long ul = (unsigned long) floatFromVal (val);
77 return (ul >> (8*_ENDIAN(offset)) &0xff);
80 /*-----------------------------------------------------------------*/
81 /* aopLiteral - string from a literal value */
82 /*-----------------------------------------------------------------*/
83 int pic14aopLiteral (value *val, int offset)
90 /* if it is a float then it gets tricky */
91 /* otherwise it is fairly simple */
92 if (!IS_FLOAT(val->type)) {
93 unsigned long v = (unsigned long) floatFromVal(val);
95 return ( (v >> (offset * 8)) & 0xff);
98 /* it is type float */
99 fl.f = (float) floatFromVal(val);
101 return fl.c[3-offset];
109 /*-----------------------------------------------------------------*/
110 /* emitRegularMap - emit code for maps with no special cases */
111 /*-----------------------------------------------------------------*/
113 pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
116 int i, size, bitvars = 0;;
119 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
121 /* print the area name */
122 for (sym = setFirstItem (map->syms); sym;
123 sym = setNextItem (map->syms))
126 /* if extern then do nothing */
127 if (IS_EXTERN (sym->etype))
130 /* if allocation required check is needed
131 then check if the symbol really requires
132 allocation only for local variables */
133 if (arFlag && !IS_AGGREGATE (sym->type) &&
134 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
135 !sym->allocreq && sym->level)
138 /* if global variable & not static or extern
139 and addPublics allowed then add it to the public set */
140 if ((sym->level == 0 ||
141 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
143 !IS_STATIC (sym->etype))
144 addSetHead (&publics, sym);
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)
155 cdbSymbol (sym, cdbFile, FALSE, FALSE);
157 if (!sym->level) /* global */
158 if (IS_STATIC (sym->etype))
159 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
161 fprintf (map->oFile, "G_"); /* scope is global */
163 /* symbol is local */
164 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
165 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
169 /* if is has an absolute address then generate
170 an equate for this no need to allocate space */
171 if (SPEC_ABSA (sym->etype))
173 //if (options.debug || sym->level == 0)
174 //fprintf (map->oFile,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
176 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
178 SPEC_ADDR (sym->etype));
184 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
185 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
186 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
187 if (IS_BITVAR (sym->etype))
193 fprintf (map->oFile, "\t%s\n", sym->rname);
194 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
196 for (i = 1; i < size; i++)
197 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
200 //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
203 /* if it has a initial value then do it only if
204 it is a global variable */
205 if (sym->ival && sym->level == 0) {
208 if (IS_AGGREGATE (sym->type))
209 ival = initAggregates (sym, sym->ival, NULL);
211 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
212 decorateType (resolveSymbols (list2expr (sym->ival))));
213 codeOutFile = statsg->oFile;
215 eBBlockFromiCode (iCodeFromAst (ival));
222 /*-----------------------------------------------------------------*/
223 /* printIvalType - generates ival for int/char */
224 /*-----------------------------------------------------------------*/
226 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
231 //fprintf(stderr, "%s\n",__FUNCTION__);
233 /* if initList is deep */
234 if (ilist->type == INIT_DEEP)
235 ilist = ilist->init.deep;
237 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
238 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
241 if (!(val = list2val (ilist))) {
242 // assuming a warning has been thrown
246 if (val->type != type) {
247 val = valCastLiteral(type, floatFromVal(val));
251 ulval = (unsigned long) floatFromVal (val);
255 switch (getSize (type)) {
257 //tfprintf (oFile, "\t!dbs\n",aopLiteral (val, 0));
258 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
259 //fprintf(stderr,"0x%02x\n",_aopLiteral(val,0));
264 // if (port->use_dw_for_init) {
265 //tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
266 // fprintf(stderr,"%s:%d aopLiteralLong\n",__FILE__,__LINE__);
268 //fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
269 //fprintf(stderr,"0x%02x 0x%02x\n",_aopLiteral(val,0),_aopLiteral(val,1));
270 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
271 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
276 tfprintf (oFile, "\t!dw !constword\n", 0);
277 tfprintf (oFile, "\t!dw !constword\n", 0);
280 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
281 aopLiteral (val, 0), aopLiteral (val, 1),
282 aopLiteral (val, 2), aopLiteral (val, 3));
283 fprintf(stderr,"0x%02x 0x%02x 0x%02x 0x%02x\n",
284 _aopLiteral(val,0),_aopLiteral(val,1),
285 _aopLiteral(val,2),_aopLiteral(val,3));
288 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
289 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
290 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
291 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
296 int size = getSize(type);
298 fprintf(stderr," size=%d, val =",size);
300 fprintf(stderr,"0x%02x\n",_aopLiteral(val,0));
302 fprintf(stderr,"none\n");
307 /*-----------------------------------------------------------------*/
308 /* printIvalChar - generates initital value for character array */
309 /*-----------------------------------------------------------------*/
311 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
319 //fprintf(stderr, "%s\n",__FUNCTION__);
323 val = list2val (ilist);
324 /* if the value is a character string */
325 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
327 if (!DCL_ELEM (type))
328 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
330 //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
331 //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
332 addpCode2pBlock(pb,newpCodeCharP(";omitting call to printChar"));
334 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
336 //tfprintf (oFile, "\t!db !constbyte\n", 0);
337 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
344 //printChar (oFile, s, strlen (s) + 1);
346 for(remain=0; remain<strlen(s); remain++) {
347 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
348 //fprintf(stderr,"0x%02x ",s[remain]);
350 //fprintf(stderr,"\n");
355 /*-----------------------------------------------------------------*/
356 /* printIvalArray - generates code for array initialization */
357 /*-----------------------------------------------------------------*/
359 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
363 int lcnt = 0, size = 0;
368 /* take care of the special case */
369 /* array of characters can be init */
371 if (IS_CHAR (type->next)) {
372 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
373 if (!IS_LITERAL(list2val(ilist)->etype)) {
374 werror (W_INIT_WRONG);
377 if (printIvalChar (type,
378 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
379 pb, SPEC_CVAL (sym->etype).v_char))
382 /* not the special case */
383 if (ilist->type != INIT_DEEP)
385 werror (E_INIT_STRUCT, sym->name);
389 iloop = ilist->init.deep;
390 lcnt = DCL_ELEM (type);
394 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
396 printIval (sym, type->next, iloop, pb);
397 iloop = (iloop ? iloop->next : NULL);
400 /* if not array limits given & we */
401 /* are out of initialisers then */
402 if (!DCL_ELEM (type) && !iloop)
405 /* no of elements given and we */
406 /* have generated for all of them */
408 /* if initializers left */
410 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
416 /* if we have not been given a size */
417 if (!DCL_ELEM (type))
418 DCL_ELEM (type) = size;
423 /*-----------------------------------------------------------------*/
424 /* printIval - generates code for initial value */
425 /*-----------------------------------------------------------------*/
427 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
432 /* if structure then */
433 if (IS_STRUCT (type))
435 //fprintf(stderr,"%s struct\n",__FUNCTION__);
436 //printIvalStruct (sym, type, ilist, oFile);
440 /* if this is a pointer */
443 //fprintf(stderr,"%s pointer\n",__FUNCTION__);
444 //printIvalPtr (sym, type, ilist, oFile);
448 /* if this is an array */
451 //fprintf(stderr,"%s array\n",__FUNCTION__);
452 printIvalArray (sym, type, ilist, pb);
456 /* if type is SPECIFIER */
459 //fprintf(stderr,"%s spec\n",__FUNCTION__);
460 printIvalType (sym, type, ilist, pb);
465 extern void pCodeConstString(char *name, char *value);
466 /*-----------------------------------------------------------------*/
467 /* emitStaticSeg - emitcode for the static segment */
468 /*-----------------------------------------------------------------*/
470 pic14emitStaticSeg (memmap * map)
474 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
476 //fprintf(stderr, "%s\n",__FUNCTION__);
478 /* for all variables in this segment do */
479 for (sym = setFirstItem (map->syms); sym;
480 sym = setNextItem (map->syms))
482 /* if it is "extern" then do nothing */
483 if (IS_EXTERN (sym->etype))
486 /* if it is not static add it to the public
488 if (!IS_STATIC (sym->etype))
489 addSetHead (&publics, sym);
491 /* print extra debug info if required */
492 if (options.debug || sym->level == 0)
494 /* NOTE to me - cdbFile may be null in which case,
495 * the sym name will be printed to stdout. oh well */
497 cdbSymbol (sym, cdbFile, FALSE, FALSE);
501 if (IS_STATIC (sym->etype))
502 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
504 fprintf (code->oFile, "G_"); /* scope is global */
507 /* symbol is local */
508 fprintf (code->oFile, "L%s_",
509 (sym->localof ? sym->localof->name : "-null-"));
510 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
514 /* if it has an absolute address */
515 if (SPEC_ABSA (sym->etype))
517 if (options.debug || sym->level == 0)
518 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
520 fprintf (code->oFile, "%s\t=\t0x%04x\n",
522 SPEC_ADDR (sym->etype));
526 if (options.debug || sym->level == 0)
527 fprintf (code->oFile, " == .\n");
529 /* if it has an initial value */
534 fprintf (code->oFile, "%s:\n", sym->rname);
536 resolveIvalSym (sym->ival);
537 //printIval (sym, sym->type, sym->ival, code->oFile);
538 pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
540 addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
542 printIval (sym, sym->type, sym->ival, pb);
549 fprintf (code->oFile, "%s:\n", sym->rname);
550 /* special case for character strings */
551 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
552 SPEC_CVAL (sym->etype).v_char)
553 pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
554 /*printChar (code->oFile,
555 SPEC_CVAL (sym->etype).v_char,
556 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
558 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
566 /*-----------------------------------------------------------------*/
567 /* emitMaps - emits the code for the data portion the code */
568 /*-----------------------------------------------------------------*/
572 /* no special considerations for the following
573 data, idata & bit & xdata */
574 pic14emitRegularMap (data, TRUE, TRUE);
575 pic14emitRegularMap (idata, TRUE, TRUE);
576 pic14emitRegularMap (bit, TRUE, FALSE);
577 pic14emitRegularMap (xdata, TRUE, TRUE);
578 pic14emitRegularMap (sfr, FALSE, FALSE);
579 pic14emitRegularMap (sfrbit, FALSE, FALSE);
580 pic14emitRegularMap (code, TRUE, FALSE);
581 pic14emitStaticSeg (statsg);
584 /*-----------------------------------------------------------------*/
585 /* createInterruptVect - creates the interrupt vector */
586 /*-----------------------------------------------------------------*/
588 pic14createInterruptVect (FILE * vFile)
591 mainf = newSymbol ("main", 0);
594 /* only if the main function exists */
595 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
597 if (!options.cc_only)
602 /* if the main is only a prototype ie. no body then do nothing */
603 if (!IFFUNC_HASBODY(mainf->type))
605 /* if ! compile only then main function should be present */
606 if (!options.cc_only)
611 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
612 fprintf (vFile, ";__interrupt_vect:\n");
615 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
617 /* "generic" interrupt table header (if port doesn't specify one).
619 * Look suspiciously like 8051 code to me...
622 fprintf (vFile, ";\tljmp\t__sdcc_gsinit_startup\n");
625 /* now for the other interrupts */
626 for (; i < maxInterrupts; i++)
629 fprintf (vFile, ";\tljmp\t%s\n;\t.ds\t5\n", interrupts[i]->rname);
631 fprintf (vFile, ";\treti\n;\t.ds\t7\n");
637 /*-----------------------------------------------------------------*/
638 /* initialComments - puts in some initial comments */
639 /*-----------------------------------------------------------------*/
641 pic14initialComments (FILE * afile)
643 initialComments (afile);
644 fprintf (afile, "; PIC port for the 14-bit core\n");
645 fprintf (afile, iComments2);
649 /*-----------------------------------------------------------------*/
650 /* printPublics - generates .global for publics */
651 /*-----------------------------------------------------------------*/
653 pic14printPublics (FILE * afile)
657 fprintf (afile, "%s", iComments2);
658 fprintf (afile, "; publics variables in this module\n");
659 fprintf (afile, "%s", iComments2);
661 for (sym = setFirstItem (publics); sym;
662 sym = setNextItem (publics))
663 fprintf (afile, ";\t.globl %s\n", sym->rname);
668 /*-----------------------------------------------------------------*/
669 /* emitOverlay - will emit code for the overlay stuff */
670 /*-----------------------------------------------------------------*/
672 pic14emitOverlay (FILE * afile)
676 if (!elementsInSet (ovrSetSets))
677 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
679 /* for each of the sets in the overlay segment do */
680 for (ovrset = setFirstItem (ovrSetSets); ovrset;
681 ovrset = setNextItem (ovrSetSets))
686 if (elementsInSet (ovrset))
688 /* this dummy area is used to fool the assembler
689 otherwise the assembler will append each of these
690 declarations into one chunk and will not overlay
692 fprintf (afile, ";\t.area _DUMMY\n");
693 /* output the area informtion */
694 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
697 for (sym = setFirstItem (ovrset); sym;
698 sym = setNextItem (ovrset))
701 /* if extern then do nothing */
702 if (IS_EXTERN (sym->etype))
705 /* if allocation required check is needed
706 then check if the symbol really requires
707 allocation only for local variables */
708 if (!IS_AGGREGATE (sym->type) &&
709 !(sym->_isparm && !IS_REGPARM (sym->etype))
710 && !sym->allocreq && sym->level)
713 /* if global variable & not static or extern
714 and addPublics allowed then add it to the public set */
715 if ((sym->_isparm && !IS_REGPARM (sym->etype))
716 && !IS_STATIC (sym->etype))
717 addSetHead (&publics, sym);
719 /* if extern then do nothing or is a function
721 if (IS_FUNC (sym->type))
724 /* print extra debug info if required */
725 if (options.debug || sym->level == 0)
728 cdbSymbol (sym, cdbFile, FALSE, FALSE);
732 if (IS_STATIC (sym->etype))
733 fprintf (afile, "F%s_", moduleName); /* scope is file */
735 fprintf (afile, "G_"); /* scope is global */
738 /* symbol is local */
739 fprintf (afile, "L%s_",
740 (sym->localof ? sym->localof->name : "-null-"));
741 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
744 /* if is has an absolute address then generate
745 an equate for this no need to allocate space */
746 if (SPEC_ABSA (sym->etype))
749 if (options.debug || sym->level == 0)
750 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
752 fprintf (afile, "%s\t=\t0x%04x\n",
754 SPEC_ADDR (sym->etype));
758 if (options.debug || sym->level == 0)
759 fprintf (afile, "==.\n");
762 fprintf (afile, "%s:\n", sym->rname);
763 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
771 /*-----------------------------------------------------------------*/
772 /* glue - the final glue that hold the whole thing together */
773 /*-----------------------------------------------------------------*/
780 FILE *ovrFile = tempfile();
791 DFPRINTF((stderr,"\n\n\n******************\n\n\n"));
792 for(t=s; t; t=t->next) {
794 DFPRINTF((stderr,"Set item %d\n",*(char *)t->item));
798 for(t=s; t; t=t->next) {
800 DFPRINTF((stderr,"Set item %d\n",*(char *)t->item));
804 addSetHead(&tmpfileSet,ovrFile);
807 if (mainf && IFFUNC_HASBODY(mainf->type)) {
809 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
812 /* entry point @ start of CSEG */
813 addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
814 /* put in the call to main */
815 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
817 if (options.mainreturn) {
819 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
820 addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
824 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
825 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
831 /* At this point we've got all the code in the form of pCode structures */
832 /* Now it needs to be rearranged into the order it should be placed in the */
835 movepBlock2Head('P'); // Last
836 movepBlock2Head(code->dbName);
837 movepBlock2Head('X');
838 movepBlock2Head(statsg->dbName); // First
841 /* print the global struct definitions */
843 cdbStructBlock (0,cdbFile);
846 /* PENDING: this isnt the best place but it will do */
847 if (port->general.glue_up_main) {
848 /* create the interrupt vector table */
849 pic14createInterruptVect (vFile);
852 addSetHead(&tmpfileSet,vFile);
854 /* emit code for the all the variables declared */
856 /* do the overlay segments */
857 pic14emitOverlay(ovrFile);
860 AnalyzepCode('*'); //code->dbName);
863 printCallTree(stderr);
869 /* now put it all together into the assembler file */
870 /* create the assembler file name */
872 if (!options.c1mode) {
873 sprintf (buffer, srcFileName);
874 strcat (buffer, ".asm");
877 strcpy(buffer, options.out_name);
880 if (!(asmFile = fopen (buffer, "w"))) {
881 werror (E_FILE_OPEN_ERR, buffer);
885 /* initial comments */
886 pic14initialComments (asmFile);
888 /* print module name */
889 fprintf (asmFile, ";\t.module %s\n", moduleName);
891 /* Let the port generate any global directives, etc. */
892 if (port->genAssemblerPreamble)
894 port->genAssemblerPreamble(asmFile);
897 /* print the global variables in this module */
898 pic14printPublics (asmFile);
901 /* copy the sfr segment */
902 fprintf (asmFile, "%s", iComments2);
903 fprintf (asmFile, "; special function registers\n");
904 fprintf (asmFile, "%s", iComments2);
905 copyFile (asmFile, sfr->oFile);
908 /* Put all variables into a cblock */
909 writeUsedRegs(asmFile);
912 /* create the overlay segments */
913 fprintf (asmFile, "%s", iComments2);
914 fprintf (asmFile, "; overlayable items in internal ram \n");
915 fprintf (asmFile, "%s", iComments2);
916 copyFile (asmFile, ovrFile);
918 /* create the stack segment MOF */
919 if (mainf && IFFUNC_HASBODY(mainf->type)) {
920 fprintf (asmFile, "%s", iComments2);
921 fprintf (asmFile, "; Stack segment in internal ram \n");
922 fprintf (asmFile, "%s", iComments2);
923 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
924 ";__start__stack:\n;\t.ds\t1\n\n");
927 /* create the idata segment */
928 fprintf (asmFile, "%s", iComments2);
929 fprintf (asmFile, "; indirectly addressable internal ram data\n");
930 fprintf (asmFile, "%s", iComments2);
931 copyFile (asmFile, idata->oFile);
933 /* if external stack then reserve space of it */
934 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
935 fprintf (asmFile, "%s", iComments2);
936 fprintf (asmFile, "; external stack \n");
937 fprintf (asmFile, "%s", iComments2);
938 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
939 fprintf (asmFile,";\t.ds 256\n");
943 /* copy xtern ram data */
944 fprintf (asmFile, "%s", iComments2);
945 fprintf (asmFile, "; external ram data\n");
946 fprintf (asmFile, "%s", iComments2);
947 copyFile (asmFile, xdata->oFile);
950 /* copy the bit segment */
951 fprintf (asmFile, "%s", iComments2);
952 fprintf (asmFile, "; bit data\n");
953 fprintf (asmFile, "%s", iComments2);
954 copyFile (asmFile, bit->oFile);
957 fprintf (asmFile, "\tORG 0\n");
959 /* copy the interrupt vector table */
960 if (mainf && IFFUNC_HASBODY(mainf->type)) {
961 fprintf (asmFile, "%s", iComments2);
962 fprintf (asmFile, "; interrupt vector \n");
963 fprintf (asmFile, "%s", iComments2);
964 copyFile (asmFile, vFile);
967 /* copy global & static initialisations */
968 fprintf (asmFile, "%s", iComments2);
969 fprintf (asmFile, "; global & static initialisations\n");
970 fprintf (asmFile, "%s", iComments2);
972 /* Everywhere we generate a reference to the static_name area,
973 * (which is currently only here), we immediately follow it with a
974 * definition of the post_static_name area. This guarantees that
975 * the post_static_name area will immediately follow the static_name
978 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
979 fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
980 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
982 if (mainf && IFFUNC_HASBODY(mainf->type)) {
983 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
984 /* if external stack is specified then the
985 higher order byte of the xdatalocation is
986 going into P2 and the lower order going into
988 if (options.useXstack) {
989 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
990 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
991 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
992 (unsigned int)options.xdata_loc & 0xff);
997 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
999 /* This code is generated in the post-static area.
1000 * This area is guaranteed to follow the static area
1001 * by the ugly shucking and jiving about 20 lines ago.
1003 fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
1004 fprintf (asmFile,";\tljmp\t__sdcc_program_startup\n");
1007 /* copy over code */
1008 fprintf (asmFile, "%s", iComments2);
1009 fprintf (asmFile, "; code\n");
1010 fprintf (asmFile, "%s", iComments2);
1011 fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
1013 //copyFile (stderr, code->oFile);
1015 copypCode(asmFile, 'I');
1016 copypCode(asmFile, statsg->dbName);
1017 copypCode(asmFile, 'X');
1018 copypCode(asmFile, 'M');
1019 copypCode(asmFile, code->dbName);
1020 copypCode(asmFile, 'P');
1023 fprintf (asmFile,"\tend\n");
1026 applyToSet(tmpfileSet,closeTmpFiles);
1027 applyToSet(tmpfileNameSet, rmTmpFiles);