1 /*-------------------------------------------------------------------------
3 glue.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"
34 #ifdef WORDS_BIGENDIAN
35 #define _ENDIAN(x) (3-x)
37 #define _ENDIAN(x) (x)
40 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
42 extern symbol *interrupts[256];
43 static void printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb);
47 extern unsigned maxInterrupts;
48 extern int maxRegBank;
50 extern char *VersionString;
51 extern FILE *codeOutFile;
52 extern set *tmpfileSet;
53 extern set *tmpfileNameSet;
54 extern char *iComments1;
55 extern char *iComments2;
56 //extern void emitStaticSeg (memmap * map);
58 extern DEFSETFUNC (closeTmpFiles);
59 extern DEFSETFUNC (rmTmpFiles);
61 extern void pic16_AnalyzeBanking (void);
62 extern void copyFile (FILE * dest, FILE * src);
63 extern void pic16_InlinepCode(void);
64 extern void pic16_writeUsedRegs(FILE *);
66 extern void initialComments (FILE * afile);
67 extern void printPublics (FILE * afile);
69 extern void printChar (FILE * ofile, char *s, int plen);
70 void pic16_pCodeInitRegisters(void);
71 pCodeOp *pic16_popGetLit(unsigned int lit);
72 pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2);
73 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
74 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst);
76 /*-----------------------------------------------------------------*/
77 /* aopLiteral - string from a literal value */
78 /*-----------------------------------------------------------------*/
79 int pic16aopLiteral (value *val, int offset)
86 /* if it is a float then it gets tricky */
87 /* otherwise it is fairly simple */
88 if (!IS_FLOAT(val->type)) {
89 unsigned long v = (unsigned long) floatFromVal(val);
91 return ( (v >> (offset * 8)) & 0xff);
94 /* it is type float */
95 fl.f = (float) floatFromVal(val);
96 #ifdef WORDS_BIGENDIAN
97 return fl.c[3-offset];
104 /*-----------------------------------------------------------------*/
105 /* emitRegularMap - emit code for maps with no special cases */
106 /*-----------------------------------------------------------------*/
108 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
111 int i, size, bitvars = 0;;
113 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
117 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
119 /* print the area name */
120 for (sym = setFirstItem (map->syms); sym;
121 sym = setNextItem (map->syms))
125 fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
126 printTypeChain( sym->type, stderr );
130 /* if extern then add to externs */
131 if (IS_EXTERN (sym->etype)) {
132 addSetHead(&externs, sym);
136 /* if allocation required check is needed
137 then check if the symbol really requires
138 allocation only for local variables */
139 if (arFlag && !IS_AGGREGATE (sym->type) &&
140 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
141 !sym->allocreq && sym->level)
144 /* if global variable & not static or extern
145 and addPublics allowed then add it to the public set */
146 if ((sym->used) && (sym->level == 0 ||
147 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
149 !IS_STATIC (sym->etype))
150 addSetHead (&publics, sym);
152 /* if extern then do nothing or is a function
154 if (IS_FUNC (sym->type))
158 /* print extra debug info if required */
159 if (options.debug || sym->level == 0)
162 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
164 if (!sym->level) /* global */
165 if (IS_STATIC (sym->etype))
166 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
168 fprintf (map->oFile, "G_"); /* scope is global */
170 /* symbol is local */
171 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
172 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
177 * The equates are nice, but do not allow relocatable objects to
178 * be created in the form that I (VR) want to make SDCC to work */
180 /* if is has an absolute address then generate
181 an equate for this no need to allocate space */
182 if (SPEC_ABSA (sym->etype))
184 //if (options.debug || sym->level == 0)
185 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
186 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
188 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
190 SPEC_ADDR (sym->etype));
193 /* emit only if it is global */
194 if(sym->level == 0) {
198 // fprintf(stderr, "%s: implicit add of symbol = %s\n", __FUNCTION__, sym->name);
199 op = operandFromSymbol( sym );
200 reg = pic16_allocDirReg( op );
204 checkAddReg(&pic16_fix_udata, reg);
205 /* and add to globals list */
206 addSetHead(&publics, sym);
215 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
216 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
217 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
218 if (IS_BITVAR (sym->etype))
224 fprintf (map->oFile, "\t%s\n", sym->rname);
225 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
227 for (i = 1; i < size; i++)
228 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
231 //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
235 /* FIXME -- VR Fix the following, so that syms to be placed
236 * in the idata section and let linker decide about their fate */
238 /* if it has an initial value then do it only if
239 it is a global variable */
240 // if(sym->ival && sym->level == 0)
244 if (sym->ival && sym->level == 0) {
247 // if(SPEC_OCLS(sym->etype)==data) {
248 // fprintf(stderr, "%s: sym %s placed in data\n", map->sname, sym->name);
251 // fprintf(stderr, "'%s': sym '%s' has initial value\n", map->sname, sym->name);
253 if (IS_AGGREGATE (sym->type))
254 ival = initAggregates (sym, sym->ival, NULL);
256 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
257 decorateType (resolveSymbols (list2expr (sym->ival))));
258 codeOutFile = statsg->oFile;
260 eBBlockFromiCode (iCodeFromAst (ival));
268 /*-----------------------------------------------------------------*/
269 /* printIvalType - generates ival for int/char */
270 /*-----------------------------------------------------------------*/
272 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
277 //fprintf(stderr, "%s\n",__FUNCTION__);
279 /* if initList is deep */
280 if (ilist->type == INIT_DEEP)
281 ilist = ilist->init.deep;
283 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
284 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
287 if (!(val = list2val (ilist))) {
288 // assuming a warning has been thrown
292 if (val->type != type) {
293 val = valCastLiteral(type, floatFromVal(val));
297 ulval = (unsigned long) floatFromVal (val);
301 switch (getSize (type)) {
303 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
307 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
308 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
312 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
313 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
314 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
315 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
320 /*-----------------------------------------------------------------*/
321 /* printIvalChar - generates initital value for character array */
322 /*-----------------------------------------------------------------*/
324 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
332 fprintf(stderr, "%s\n",__FUNCTION__);
336 val = list2val (ilist);
337 /* if the value is a character string */
338 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
340 if (!DCL_ELEM (type))
341 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
343 //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
344 //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
345 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";omitting call to printChar"));
347 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
349 //tfprintf (oFile, "\t!db !constbyte\n", 0);
350 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(0)));
357 //printChar (oFile, s, strlen (s) + 1);
359 for(remain=0; remain<strlen(s); remain++) {
360 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(s[remain])));
361 //fprintf(stderr,"0x%02x ",s[remain]);
363 //fprintf(stderr,"\n");
368 /*-----------------------------------------------------------------*/
369 /* printIvalArray - generates code for array initialization */
370 /*-----------------------------------------------------------------*/
372 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
376 int lcnt = 0, size = 0;
381 /* take care of the special case */
382 /* array of characters can be init */
384 if (IS_CHAR (type->next)) {
385 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
386 if (!IS_LITERAL(list2val(ilist)->etype)) {
387 werror (W_INIT_WRONG);
390 if (printIvalChar (type,
391 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
392 pb, SPEC_CVAL (sym->etype).v_char))
395 /* not the special case */
396 if (ilist->type != INIT_DEEP)
398 werror (E_INIT_STRUCT, sym->name);
402 iloop = ilist->init.deep;
403 lcnt = DCL_ELEM (type);
407 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
409 printIval (sym, type->next, iloop, pb);
410 iloop = (iloop ? iloop->next : NULL);
413 /* if not array limits given & we */
414 /* are out of initialisers then */
415 if (!DCL_ELEM (type) && !iloop)
418 /* no of elements given and we */
419 /* have generated for all of them */
421 /* if initializers left */
423 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
429 /* if we have not been given a size */
430 if (!DCL_ELEM (type))
431 DCL_ELEM (type) = size;
436 /*-----------------------------------------------------------------*/
437 /* printIval - generates code for initial value */
438 /*-----------------------------------------------------------------*/
440 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
445 /* if structure then */
446 if (IS_STRUCT (type))
448 //fprintf(stderr,"%s struct\n",__FUNCTION__);
449 //printIvalStruct (sym, type, ilist, oFile);
453 /* if this is a pointer */
456 //fprintf(stderr,"%s pointer\n",__FUNCTION__);
457 //printIvalPtr (sym, type, ilist, oFile);
461 /* if this is an array */
464 //fprintf(stderr,"%s array\n",__FUNCTION__);
465 printIvalArray (sym, type, ilist, pb);
469 /* if type is SPECIFIER */
472 //fprintf(stderr,"%s spec\n",__FUNCTION__);
473 printIvalType (sym, type, ilist, pb);
478 extern void pic16_pCodeConstString(char *name, char *value);
479 /*-----------------------------------------------------------------*/
480 /* emitStaticSeg - emitcode for the static segment */
481 /*-----------------------------------------------------------------*/
483 pic16emitStaticSeg (memmap * map)
487 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
489 //fprintf(stderr, "%s\n",__FUNCTION__);
491 /* for all variables in this segment do */
492 for (sym = setFirstItem (map->syms); sym;
493 sym = setNextItem (map->syms))
497 fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
498 printTypeChain( sym->type, stderr );
503 /* if it is "extern" then do nothing */
504 if (IS_EXTERN (sym->etype))
507 /* if it is not static add it to the public
509 if (!IS_STATIC (sym->etype))
510 addSetHead (&publics, sym);
513 /* print extra debug info if required */
514 if (options.debug || sym->level == 0)
516 /* NOTE to me - cdbFile may be null in which case,
517 * the sym name will be printed to stdout. oh well */
519 cdbSymbol (sym, cdbFile, FALSE, FALSE);
523 if (IS_STATIC (sym->etype))
524 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
526 fprintf (code->oFile, "G_"); /* scope is global */
529 /* symbol is local */
530 fprintf (code->oFile, "L%s_",
531 (sym->localof ? sym->localof->name : "-null-"));
532 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
537 /* if it has an absolute address */
538 if (SPEC_ABSA (sym->etype))
540 if (options.debug || sym->level == 0)
541 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
543 fprintf (code->oFile, "%s\t=\t0x%04x\n",
545 SPEC_ADDR (sym->etype));
549 if (options.debug || sym->level == 0)
550 fprintf (code->oFile, " == .\n");
552 /* if it has an initial value */
557 fprintf (code->oFile, "%s:\n", sym->rname);
559 resolveIvalSym (sym->ival);
560 //printIval (sym, sym->type, sym->ival, code->oFile);
561 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
563 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
565 printIval (sym, sym->type, sym->ival, pb);
572 fprintf (code->oFile, "%s:\n", sym->rname);
573 /* special case for character strings */
574 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
575 SPEC_CVAL (sym->etype).v_char)
576 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
577 /*printChar (code->oFile,
578 SPEC_CVAL (sym->etype).v_char,
579 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
581 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
589 /*-----------------------------------------------------------------*/
590 /* emitMaps - emits the code for the data portion the code */
591 /*-----------------------------------------------------------------*/
595 /* no special considerations for the following
596 data, idata & bit & xdata */
597 pic16emitRegularMap (data, TRUE, TRUE);
598 pic16emitRegularMap (idata, TRUE, TRUE);
599 pic16emitRegularMap (bit, TRUE, FALSE);
600 pic16emitRegularMap (xdata, TRUE, TRUE);
601 pic16emitRegularMap (sfr, FALSE, FALSE);
602 pic16emitRegularMap (sfrbit, FALSE, FALSE);
603 pic16emitRegularMap (code, TRUE, FALSE);
604 pic16emitStaticSeg (statsg);
607 /*-----------------------------------------------------------------*/
608 /* createInterruptVect - creates the interrupt vector */
609 /*-----------------------------------------------------------------*/
611 pic16createInterruptVect (FILE * vFile)
613 mainf = newSymbol ("main", 0);
616 /* only if the main function exists */
617 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
619 if (!options.cc_only)
624 /* if the main is only a prototype ie. no body then do nothing */
625 if (!IFFUNC_HASBODY(mainf->type))
627 /* if ! compile only then main function should be present */
628 if (!options.cc_only)
633 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
634 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
635 fprintf(vFile, ".intvecs\tcode\t0x0000\n");
636 fprintf (vFile, "__interrupt_vect:\n");
638 /* this is an overkill since WE are the port,
639 * and we know if we have a genIVT function! */
641 port->genIVT(vFile, interrupts, maxInterrupts);
648 /*-----------------------------------------------------------------*/
649 /* initialComments - puts in some initial comments */
650 /*-----------------------------------------------------------------*/
652 pic16initialComments (FILE * afile)
654 initialComments (afile);
655 fprintf (afile, "; PIC port for the 16-bit core\n");
656 fprintf (afile, iComments2);
660 /*-----------------------------------------------------------------*/
661 /* printPublics - generates global declarations for publics */
662 /*-----------------------------------------------------------------*/
664 pic16printPublics (FILE * afile)
668 fprintf (afile, "%s", iComments2);
669 fprintf (afile, "; publics variables in this module\n");
670 fprintf (afile, "%s", iComments2);
672 for (sym = setFirstItem (publics); sym; sym = setNextItem (publics))
673 fprintf(afile, "\tglobal %s\n", sym->rname);
676 /*-----------------------------------------------------------------*/
677 /* printExterns - generates extern declarations for externs */
678 /*-----------------------------------------------------------------*/
680 pic16_printExterns(FILE *afile)
684 fprintf(afile, "%s", iComments2);
685 fprintf(afile, "; extern variables to this module\n");
686 fprintf(afile, "%s", iComments2);
688 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
689 fprintf(afile, "\textern %s\n", sym->rname);
692 /*-----------------------------------------------------------------*/
693 /* emitOverlay - will emit code for the overlay stuff */
694 /*-----------------------------------------------------------------*/
696 pic16emitOverlay (FILE * afile)
700 if (!elementsInSet (ovrSetSets))
701 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
703 /* for each of the sets in the overlay segment do */
704 for (ovrset = setFirstItem (ovrSetSets); ovrset;
705 ovrset = setNextItem (ovrSetSets))
710 if (elementsInSet (ovrset))
712 /* this dummy area is used to fool the assembler
713 otherwise the assembler will append each of these
714 declarations into one chunk and will not overlay
716 fprintf (afile, ";\t.area _DUMMY\n");
717 /* output the area informtion */
718 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
721 for (sym = setFirstItem (ovrset); sym;
722 sym = setNextItem (ovrset))
725 /* if extern then do nothing */
726 if (IS_EXTERN (sym->etype))
729 /* if allocation required check is needed
730 then check if the symbol really requires
731 allocation only for local variables */
732 if (!IS_AGGREGATE (sym->type) &&
733 !(sym->_isparm && !IS_REGPARM (sym->etype))
734 && !sym->allocreq && sym->level)
737 /* if global variable & not static or extern
738 and addPublics allowed then add it to the public set */
739 if ((sym->_isparm && !IS_REGPARM (sym->etype))
740 && !IS_STATIC (sym->etype))
741 addSetHead (&publics, sym);
743 /* if extern then do nothing or is a function
745 if (IS_FUNC (sym->type))
749 /* print extra debug info if required */
750 if (options.debug || sym->level == 0)
753 cdbSymbol (sym, cdbFile, FALSE, FALSE);
757 if (IS_STATIC (sym->etype))
758 fprintf (afile, "F%s_", moduleName); /* scope is file */
760 fprintf (afile, "G_"); /* scope is global */
763 /* symbol is local */
764 fprintf (afile, "L%s_",
765 (sym->localof ? sym->localof->name : "-null-"));
766 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
770 /* if is has an absolute address then generate
771 an equate for this no need to allocate space */
772 if (SPEC_ABSA (sym->etype))
775 if (options.debug || sym->level == 0)
776 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
778 fprintf (afile, "%s\t=\t0x%04x\n",
780 SPEC_ADDR (sym->etype));
784 if (options.debug || sym->level == 0)
785 fprintf (afile, "==.\n");
788 fprintf (afile, "%s:\n", sym->rname);
789 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
797 /*-----------------------------------------------------------------*/
798 /* glue - the final glue that hold the whole thing together */
799 /*-----------------------------------------------------------------*/
806 FILE *ovrFile = tempfile();
808 addSetHead(&tmpfileSet,ovrFile);
809 pic16_pCodeInitRegisters();
811 if (mainf && IFFUNC_HASBODY(mainf->type)) {
813 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
816 /* entry point @ start of CSEG */
817 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
818 /* put in the call to main */
819 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
821 if (options.mainreturn) {
823 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
824 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
828 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
829 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
836 pBlock *pb = pic16_newpCodeChain(NULL, 'X', pic16_newpCodeCharP("; Setup stack & frame register"));
839 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, pic16_popGetLit2(1, stackPos)));
840 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, pic16_popGetLit2(2, stackPos)));
846 /* At this point we've got all the code in the form of pCode structures */
847 /* Now it needs to be rearranged into the order it should be placed in the */
850 pic16_movepBlock2Head('P'); // Last
851 pic16_movepBlock2Head(code->dbName);
852 pic16_movepBlock2Head('X');
853 pic16_movepBlock2Head(statsg->dbName); // First
856 /* print the global struct definitions */
858 cdbStructBlock (0); //,cdbFile);
861 /* PENDING: this isnt the best place but it will do */
862 if (port->general.glue_up_main) {
863 /* create the interrupt vector table */
865 pic16createInterruptVect (vFile);
868 addSetHead(&tmpfileSet,vFile);
870 /* emit code for the all the variables declared */
872 /* do the overlay segments */
873 pic16emitOverlay(ovrFile);
876 pic16_AnalyzepCode('*');
881 sprintf(buffer, dstFileName);
882 strcat(buffer, ".calltree");
883 cFile = fopen(buffer, "w");
884 pic16_printCallTree( cFile );
890 pic16_AnalyzepCode('*');
893 /* now put it all together into the assembler file */
894 /* create the assembler file name */
896 if ((noAssemble || options.c1mode) && fullDstFileName)
898 sprintf (buffer, fullDstFileName);
902 sprintf (buffer, dstFileName);
903 strcat (buffer, ".asm");
906 if (!(asmFile = fopen (buffer, "w"))) {
907 werror (E_FILE_OPEN_ERR, buffer);
911 /* initial comments */
912 pic16initialComments (asmFile);
914 /* print module name */
915 fprintf (asmFile, ";\t.module %s\n", moduleName);
917 /* Let the port generate any global directives, etc. */
918 if (port->genAssemblerPreamble)
920 port->genAssemblerPreamble(asmFile);
923 /* print the extern variables to this module */
924 pic16_printExterns(asmFile);
926 /* print the global variables in this module */
927 pic16printPublics (asmFile);
930 /* copy the sfr segment */
931 fprintf (asmFile, "%s", iComments2);
932 fprintf (asmFile, "; special function registers\n");
933 fprintf (asmFile, "%s", iComments2);
934 copyFile (asmFile, sfr->oFile);
938 /* Put all variables into a cblock */
939 pic16_AnalyzeBanking();
940 pic16_writeUsedRegs(asmFile);
942 /* create the overlay segments */
943 fprintf (asmFile, "%s", iComments2);
944 fprintf (asmFile, "; overlayable items in internal ram \n");
945 fprintf (asmFile, "%s", iComments2);
946 copyFile (asmFile, ovrFile);
948 /* create the stack segment MOF */
949 if (mainf && IFFUNC_HASBODY(mainf->type)) {
950 fprintf (asmFile, "%s", iComments2);
951 fprintf (asmFile, "; Stack segment in internal ram \n");
952 fprintf (asmFile, "%s", iComments2);
953 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
954 ";__start__stack:\n;\t.ds\t1\n\n");
958 /* no indirect data in pic */
959 /* create the idata segment */
960 fprintf (asmFile, "%s", iComments2);
961 fprintf (asmFile, "; indirectly addressable internal ram data\n");
962 fprintf (asmFile, "%s", iComments2);
963 copyFile (asmFile, idata->oFile);
968 /* no xdata in pic */
969 /* if external stack then reserve space of it */
970 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
971 fprintf (asmFile, "%s", iComments2);
972 fprintf (asmFile, "; external stack \n");
973 fprintf (asmFile, "%s", iComments2);
974 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
975 fprintf (asmFile,";\t.ds 256\n");
980 /* no xdata in pic */
981 /* copy xtern ram data */
982 fprintf (asmFile, "%s", iComments2);
983 fprintf (asmFile, "; external ram data\n");
984 fprintf (asmFile, "%s", iComments2);
985 copyFile (asmFile, xdata->oFile);
988 /* copy the bit segment */
989 fprintf (asmFile, "%s", iComments2);
990 fprintf (asmFile, "; bit data\n");
991 fprintf (asmFile, "%s", iComments2);
992 copyFile (asmFile, bit->oFile);
995 /* the following is commented out. the CODE directive will be
996 used instead before code */
997 // fprintf (asmFile, "\tORG 0\n");
999 /* copy the interrupt vector table */
1000 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1001 fprintf (asmFile, "%s", iComments2);
1002 fprintf (asmFile, "; interrupt vector \n");
1003 fprintf (asmFile, "%s", iComments2);
1004 copyFile (asmFile, vFile);
1007 /* copy global & static initialisations */
1008 fprintf (asmFile, "%s", iComments2);
1009 fprintf (asmFile, "; global & static initialisations\n");
1010 fprintf (asmFile, "%s", iComments2);
1013 /* FIXME 8051 Legacy -- VR */
1014 /* Everywhere we generate a reference to the static_name area,
1015 * (which is currently only here), we immediately follow it with a
1016 * definition of the post_static_name area. This guarantees that
1017 * the post_static_name area will immediately follow the static_name
1020 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
1021 fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
1022 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
1025 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1026 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
1029 /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
1030 /* if external stack is specified then the
1031 higher order byte of the xdatalocation is
1032 going into P2 and the lower order going into
1034 if (options.useXstack) {
1035 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
1036 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
1037 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
1038 (unsigned int)options.xdata_loc & 0xff);
1044 /* copy over code */
1045 fprintf (asmFile, "%s", iComments2);
1046 fprintf (asmFile, "\tcode\n");
1047 fprintf (asmFile, "%s", iComments2);
1048 fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
1050 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1052 /* This code is generated in the post-static area.
1053 * This area is guaranteed to follow the static area
1054 * by the ugly shucking and jiving about 20 lines ago.
1056 // fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
1057 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1061 //copyFile (stderr, code->oFile);
1063 fprintf(asmFile, "; I code from now on!\n");
1064 pic16_copypCode(asmFile, 'I');
1067 // fprintf(asmFile, "; dbName from now on!\n");
1068 fprintf(asmFile, "__sdcc_program_startup:\n");
1069 pic16_copypCode(asmFile, statsg->dbName);
1071 fprintf(asmFile, "; X code from now on!\n");
1072 pic16_copypCode(asmFile, 'X');
1074 fprintf(asmFile, "; M code from now on!\n");
1075 pic16_copypCode(asmFile, 'M');
1077 pic16_copypCode(asmFile, code->dbName);
1079 pic16_copypCode(asmFile, 'P');
1081 fprintf (asmFile,"\tend\n");