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, pCodeOp *arg2);
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);
116 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
118 /* print the area name */
119 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
121 fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
122 printTypeChain( sym->type, stderr );
125 /* if extern then add to externs */
126 if (IS_EXTERN (sym->etype)) {
127 // if(sym->used) // fixme
128 addSetHead(&externs, sym);
131 /* if allocation required check is needed
132 * then check if the symbol really requires
133 * allocation only for local variables */
134 if (arFlag && !IS_AGGREGATE (sym->type) &&
135 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
136 !sym->allocreq && sym->level)
140 /* if global variable & not static or extern
141 * and addPublics allowed then add it to the public set */
142 if ((sym->used) && (sym->level == 0 ||
143 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
145 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type))
147 addSetHead (&publics, sym);
149 /* if extern then do nothing or is a function
151 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
152 if(SPEC_OCLS(sym->etype) == code) {
153 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
154 addSetHead(&publics, sym);
160 /* print extra debug info if required */
161 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)) {
183 // if (options.debug || sym->level == 0)
184 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
185 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
187 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
189 SPEC_ADDR (sym->etype));
191 /* emit only if it is global */
192 if(sym->level == 0) {
195 // fprintf(stderr, "%s: implicit add of symbol = %s\n", __FUNCTION__, sym->name);
196 op = operandFromSymbol( sym );
197 reg = pic16_allocDirReg( op );
200 checkAddReg(&pic16_fix_udata, reg);
201 /* and add to globals list */
202 addSetHead(&publics, sym);
208 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
209 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
210 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
211 if (IS_BITVAR (sym->etype)) {
214 fprintf (map->oFile, "\t%s\n", sym->rname);
215 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
216 for (i = 1; i < size; i++)
217 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
220 // fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
223 /* FIXME -- VR Fix the following, so that syms to be placed
224 * in the idata section and let linker decide about their fate */
226 /* if it has an initial value then do it only if
227 it is a global variable */
230 if (sym->ival && sym->level == 0) {
233 // if(SPEC_OCLS(sym->etype)==data) {
234 // fprintf(stderr, "%s: sym %s placed in data\n", map->sname, sym->name);
237 // fprintf(stderr, "'%s': sym '%s' has initial value\n", map->sname, sym->name);
239 if (IS_AGGREGATE (sym->type))
240 ival = initAggregates (sym, sym->ival, NULL);
242 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
243 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK));
244 codeOutFile = statsg->oFile;
246 eBBlockFromiCode (iCodeFromAst (ival));
254 /*-----------------------------------------------------------------*/
255 /* printIvalType - generates ival for int/char */
256 /*-----------------------------------------------------------------*/
258 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
263 //fprintf(stderr, "%s\n",__FUNCTION__);
265 /* if initList is deep */
266 if (ilist->type == INIT_DEEP)
267 ilist = ilist->init.deep;
269 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
270 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
273 if (!(val = list2val (ilist))) {
274 // assuming a warning has been thrown
278 if (val->type != type) {
279 val = valCastLiteral(type, floatFromVal(val));
283 ulval = (unsigned long) floatFromVal (val);
287 switch (getSize (type)) {
289 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
293 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
294 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
298 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
299 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
300 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
301 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
306 /*-----------------------------------------------------------------*/
307 /* printIvalChar - generates initital value for character array */
308 /*-----------------------------------------------------------------*/
310 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
318 fprintf(stderr, "%s\n",__FUNCTION__);
322 val = list2val (ilist);
323 /* if the value is a character string */
324 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
326 if (!DCL_ELEM (type))
327 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
329 //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
330 //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
331 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";omitting call to printChar"));
333 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
335 //tfprintf (oFile, "\t!db !constbyte\n", 0);
336 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(0)));
343 //printChar (oFile, s, strlen (s) + 1);
345 for(remain=0; remain<strlen(s); remain++) {
346 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(s[remain])));
347 //fprintf(stderr,"0x%02x ",s[remain]);
349 //fprintf(stderr,"\n");
354 /*-----------------------------------------------------------------*/
355 /* printIvalArray - generates code for array initialization */
356 /*-----------------------------------------------------------------*/
358 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
362 int lcnt = 0, size = 0;
367 /* take care of the special case */
368 /* array of characters can be init */
370 if (IS_CHAR (type->next)) {
371 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
372 if (!IS_LITERAL(list2val(ilist)->etype)) {
373 werror (W_INIT_WRONG);
376 if (printIvalChar (type,
377 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
378 pb, SPEC_CVAL (sym->etype).v_char))
381 /* not the special case */
382 if (ilist->type != INIT_DEEP)
384 werror (E_INIT_STRUCT, sym->name);
388 iloop = ilist->init.deep;
389 lcnt = DCL_ELEM (type);
393 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
395 printIval (sym, type->next, iloop, pb);
396 iloop = (iloop ? iloop->next : NULL);
399 /* if not array limits given & we */
400 /* are out of initialisers then */
401 if (!DCL_ELEM (type) && !iloop)
404 /* no of elements given and we */
405 /* have generated for all of them */
407 /* if initializers left */
409 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
415 /* if we have not been given a size */
416 if (!DCL_ELEM (type))
417 DCL_ELEM (type) = size;
422 /*-----------------------------------------------------------------*/
423 /* printIval - generates code for initial value */
424 /*-----------------------------------------------------------------*/
426 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
431 /* if structure then */
432 if (IS_STRUCT (type))
434 //fprintf(stderr,"%s struct\n",__FUNCTION__);
435 //printIvalStruct (sym, type, ilist, oFile);
439 /* if this is a pointer */
442 //fprintf(stderr,"%s pointer\n",__FUNCTION__);
443 //printIvalPtr (sym, type, ilist, oFile);
447 /* if this is an array */
450 //fprintf(stderr,"%s array\n",__FUNCTION__);
451 printIvalArray (sym, type, ilist, pb);
455 /* if type is SPECIFIER */
458 //fprintf(stderr,"%s spec\n",__FUNCTION__);
459 printIvalType (sym, type, ilist, pb);
464 extern void pic16_pCodeConstString(char *name, char *value);
465 /*-----------------------------------------------------------------*/
466 /* emitStaticSeg - emitcode for the static segment */
467 /*-----------------------------------------------------------------*/
469 pic16emitStaticSeg (memmap * map)
473 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
475 //fprintf(stderr, "%s\n",__FUNCTION__);
477 /* for all variables in this segment do */
478 for (sym = setFirstItem (map->syms); sym;
479 sym = setNextItem (map->syms))
483 fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
484 printTypeChain( sym->type, stderr );
489 /* if it is "extern" then do nothing */
490 if (IS_EXTERN (sym->etype))
493 /* if it is not static add it to the public
495 if (!IS_STATIC (sym->etype))
496 addSetHead (&publics, sym);
499 /* print extra debug info if required */
500 if (options.debug || sym->level == 0)
502 /* NOTE to me - cdbFile may be null in which case,
503 * the sym name will be printed to stdout. oh well */
505 cdbSymbol (sym, cdbFile, FALSE, FALSE);
509 if (IS_STATIC (sym->etype))
510 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
512 fprintf (code->oFile, "G_"); /* scope is global */
515 /* symbol is local */
516 fprintf (code->oFile, "L%s_",
517 (sym->localof ? sym->localof->name : "-null-"));
518 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
523 /* if it has an absolute address */
524 if (SPEC_ABSA (sym->etype))
526 if (options.debug || sym->level == 0)
527 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
529 fprintf (code->oFile, "%s\t=\t0x%04x\n",
531 SPEC_ADDR (sym->etype));
535 if (options.debug || sym->level == 0)
536 fprintf (code->oFile, " == .\n");
538 /* if it has an initial value */
543 fprintf (code->oFile, "%s:\n", sym->rname);
545 resolveIvalSym (sym->ival);
546 //printIval (sym, sym->type, sym->ival, code->oFile);
547 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
549 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
551 printIval (sym, sym->type, sym->ival, pb);
558 fprintf (code->oFile, "%s:\n", sym->rname);
559 /* special case for character strings */
560 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
561 SPEC_CVAL (sym->etype).v_char)
562 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
563 /*printChar (code->oFile,
564 SPEC_CVAL (sym->etype).v_char,
565 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
567 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
575 /*-----------------------------------------------------------------*/
576 /* emitMaps - emits the code for the data portion the code */
577 /*-----------------------------------------------------------------*/
581 /* no special considerations for the following
582 data, idata & bit & xdata */
583 pic16emitRegularMap (data, TRUE, TRUE);
584 pic16emitRegularMap (idata, TRUE, TRUE);
585 pic16emitRegularMap (bit, TRUE, FALSE);
586 pic16emitRegularMap (xdata, TRUE, TRUE);
587 pic16emitRegularMap (sfr, FALSE, FALSE);
588 pic16emitRegularMap (sfrbit, FALSE, FALSE);
589 pic16emitRegularMap (code, TRUE, FALSE);
590 pic16emitStaticSeg (statsg);
593 /*-----------------------------------------------------------------*/
594 /* createInterruptVect - creates the interrupt vector */
595 /*-----------------------------------------------------------------*/
597 pic16createInterruptVect (FILE * vFile)
599 /* if the main is only a prototype ie. no body then do nothing */
601 if (!IFFUNC_HASBODY(mainf->type)) {
602 /* if ! compile only then main function should be present */
603 if (!options.cc_only)
609 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
610 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
611 fprintf(vFile, ".intvecs\tcode\t0x0000\n");
612 fprintf (vFile, "__interrupt_vect:\n");
614 /* this is an overkill since WE are the port,
615 * and we know if we have a genIVT function! */
617 port->genIVT(vFile, interrupts, maxInterrupts);
624 /*-----------------------------------------------------------------*/
625 /* initialComments - puts in some initial comments */
626 /*-----------------------------------------------------------------*/
628 pic16initialComments (FILE * afile)
630 initialComments (afile);
631 fprintf (afile, "; PIC port for the 16-bit core\n");
632 fprintf (afile, iComments2);
636 /*-----------------------------------------------------------------*/
637 /* printPublics - generates global declarations for publics */
638 /*-----------------------------------------------------------------*/
640 pic16printPublics (FILE *afile)
644 fprintf (afile, "%s", iComments2);
645 fprintf (afile, "; public variables in this module\n");
646 fprintf (afile, "%s", iComments2);
648 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
649 fprintf(afile, "\tglobal %s\n", sym->rname);
652 /*-----------------------------------------------------------------*/
653 /* printExterns - generates extern declarations for externs */
654 /*-----------------------------------------------------------------*/
656 pic16_printExterns(FILE *afile)
660 fprintf(afile, "%s", iComments2);
661 fprintf(afile, "; extern variables in this module\n");
662 fprintf(afile, "%s", iComments2);
664 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
665 fprintf(afile, "\textern %s\n", sym->rname);
667 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
668 fprintf(afile, "\textern _%s\n", sym->name);
671 /*-----------------------------------------------------------------*/
672 /* emitOverlay - will emit code for the overlay stuff */
673 /*-----------------------------------------------------------------*/
675 pic16emitOverlay (FILE * afile)
679 if (!elementsInSet (ovrSetSets))
680 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
682 /* for each of the sets in the overlay segment do */
683 for (ovrset = setFirstItem (ovrSetSets); ovrset;
684 ovrset = setNextItem (ovrSetSets))
689 if (elementsInSet (ovrset))
691 /* this dummy area is used to fool the assembler
692 otherwise the assembler will append each of these
693 declarations into one chunk and will not overlay
695 fprintf (afile, ";\t.area _DUMMY\n");
696 /* output the area informtion */
697 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
700 for (sym = setFirstItem (ovrset); sym;
701 sym = setNextItem (ovrset))
704 /* if extern then do nothing */
705 if (IS_EXTERN (sym->etype))
708 /* if allocation required check is needed
709 then check if the symbol really requires
710 allocation only for local variables */
711 if (!IS_AGGREGATE (sym->type) &&
712 !(sym->_isparm && !IS_REGPARM (sym->etype))
713 && !sym->allocreq && sym->level)
716 /* if global variable & not static or extern
717 and addPublics allowed then add it to the public set */
718 if ((sym->_isparm && !IS_REGPARM (sym->etype))
719 && !IS_STATIC (sym->etype))
720 addSetHead (&publics, sym);
722 /* if extern then do nothing or is a function
724 if (IS_FUNC (sym->type))
728 /* print extra debug info if required */
729 if (options.debug || sym->level == 0)
732 cdbSymbol (sym, cdbFile, FALSE, FALSE);
736 if (IS_STATIC (sym->etype))
737 fprintf (afile, "F%s_", moduleName); /* scope is file */
739 fprintf (afile, "G_"); /* scope is global */
742 /* symbol is local */
743 fprintf (afile, "L%s_",
744 (sym->localof ? sym->localof->name : "-null-"));
745 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
749 /* if is has an absolute address then generate
750 an equate for this no need to allocate space */
751 if (SPEC_ABSA (sym->etype))
754 if (options.debug || sym->level == 0)
755 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
757 fprintf (afile, "%s\t=\t0x%04x\n",
759 SPEC_ADDR (sym->etype));
763 if (options.debug || sym->level == 0)
764 fprintf (afile, "==.\n");
767 fprintf (afile, "%s:\n", sym->rname);
768 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
776 /*-----------------------------------------------------------------*/
777 /* glue - the final glue that hold the whole thing together */
778 /*-----------------------------------------------------------------*/
785 FILE *ovrFile = tempfile();
788 mainf = newSymbol ("main", 0);
791 mainf = findSymWithLevel(SymbolTab, mainf);
793 /* only if the main function exists */
794 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
795 if (!options.cc_only)
801 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
803 addSetHead(&tmpfileSet,ovrFile);
804 pic16_pCodeInitRegisters();
806 if (mainf && IFFUNC_HASBODY(mainf->type)) {
807 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
811 /* entry point @ start of CSEG */
812 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup\t;VR1",-1));
816 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
817 pic16_popGetLit2(1, pic16_popGetLit(stackPos))));
818 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
819 pic16_popGetLit2(2, pic16_popGetLit(stackPos))));
821 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
822 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("stack"))));
823 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
824 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("stack"))));
828 /* put in the call to main */
829 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
831 if (options.mainreturn) {
832 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
833 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
835 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
836 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
840 /* At this point we've got all the code in the form of pCode structures */
841 /* Now it needs to be rearranged into the order it should be placed in the */
844 pic16_movepBlock2Head('P'); // Last
845 pic16_movepBlock2Head(code->dbName);
846 pic16_movepBlock2Head('X');
847 pic16_movepBlock2Head(statsg->dbName); // First
849 /* print the global struct definitions */
850 // if (options.debug)
851 // cdbStructBlock (0); //,cdbFile);
854 /* PENDING: this isnt the best place but it will do */
855 if (port->general.glue_up_main) {
856 /* create the interrupt vector table */
857 pic16createInterruptVect (vFile);
860 addSetHead(&tmpfileSet,vFile);
862 /* emit code for the all the variables declared */
864 /* do the overlay segments */
865 pic16emitOverlay(ovrFile);
866 pic16_AnalyzepCode('*');
871 sprintf(buffer, dstFileName);
872 strcat(buffer, ".calltree");
873 cFile = fopen(buffer, "w");
874 pic16_printCallTree( cFile );
880 pic16_AnalyzepCode('*');
882 if(pic16_debug_verbose)
885 /* now put it all together into the assembler file */
886 /* create the assembler file name */
887 if ((noAssemble || options.c1mode) && fullDstFileName) {
888 sprintf (buffer, fullDstFileName);
890 sprintf (buffer, dstFileName);
891 strcat (buffer, ".asm");
894 if (!(asmFile = fopen (buffer, "w"))) {
895 werror (E_FILE_OPEN_ERR, buffer);
899 /* initial comments */
900 pic16initialComments (asmFile);
902 /* print module name */
903 fprintf (asmFile, ";\t.module %s\n", moduleName);
905 /* Let the port generate any global directives, etc. */
906 if (port->genAssemblerPreamble) {
907 port->genAssemblerPreamble(asmFile);
910 /* print the extern variables to this module */
911 pic16_printExterns(asmFile);
913 /* print the global variables in this module */
914 pic16printPublics (asmFile);
917 /* copy the sfr segment */
918 fprintf (asmFile, "%s", iComments2);
919 fprintf (asmFile, "; special function registers\n");
920 fprintf (asmFile, "%s", iComments2);
921 copyFile (asmFile, sfr->oFile);
925 /* Put all variables into a cblock */
926 pic16_AnalyzeBanking();
927 pic16_writeUsedRegs(asmFile);
929 /* create the overlay segments */
930 fprintf (asmFile, "%s", iComments2);
931 fprintf (asmFile, "; overlayable items in internal ram \n");
932 fprintf (asmFile, "%s", iComments2);
933 copyFile (asmFile, ovrFile);
935 /* create the stack segment MOF */
936 if (mainf && IFFUNC_HASBODY(mainf->type)) {
937 fprintf (asmFile, "%s", iComments2);
938 fprintf (asmFile, "; Stack segment in internal ram \n");
939 fprintf (asmFile, "%s", iComments2);
940 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
941 ";__start__stack:\n;\t.ds\t1\n\n");
945 /* no indirect data in pic */
946 /* create the idata segment */
947 fprintf (asmFile, "%s", iComments2);
948 fprintf (asmFile, "; indirectly addressable internal ram data\n");
949 fprintf (asmFile, "%s", iComments2);
950 copyFile (asmFile, idata->oFile);
955 /* no xdata in pic */
956 /* if external stack then reserve space of it */
957 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
958 fprintf (asmFile, "%s", iComments2);
959 fprintf (asmFile, "; external stack \n");
960 fprintf (asmFile, "%s", iComments2);
961 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
962 fprintf (asmFile,";\t.ds 256\n");
967 /* no xdata in pic */
968 /* copy xtern ram data */
969 fprintf (asmFile, "%s", iComments2);
970 fprintf (asmFile, "; external ram data\n");
971 fprintf (asmFile, "%s", iComments2);
972 copyFile (asmFile, xdata->oFile);
975 /* copy the bit segment */
976 fprintf (asmFile, "%s", iComments2);
977 fprintf (asmFile, "; bit data\n");
978 fprintf (asmFile, "%s", iComments2);
979 copyFile (asmFile, bit->oFile);
982 /* copy the interrupt vector table */
983 if(mainf && IFFUNC_HASBODY(mainf->type)) {
984 fprintf (asmFile, "%s", iComments2);
985 fprintf (asmFile, "; interrupt vector \n");
986 fprintf (asmFile, "%s", iComments2);
987 copyFile (asmFile, vFile);
990 /* copy global & static initialisations */
991 fprintf (asmFile, "%s", iComments2);
992 fprintf (asmFile, "; global & static initialisations\n");
993 fprintf (asmFile, "%s", iComments2);
996 /* FIXME 8051 Legacy -- VR */
997 /* Everywhere we generate a reference to the static_name area,
998 * (which is currently only here), we immediately follow it with a
999 * definition of the post_static_name area. This guarantees that
1000 * the post_static_name area will immediately follow the static_name
1003 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
1004 fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
1005 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
1009 /* copy over code */
1010 fprintf (asmFile, "%s", iComments2);
1011 fprintf (asmFile, "\tcode\n");
1012 fprintf (asmFile, "%s", iComments2);
1015 fprintf(asmFile, "; A code from now on!\n");
1016 pic16_copypCode(asmFile, 'A');
1019 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1020 fprintf (asmFile,"__sdcc_gsinit_startup:\t\t;VRokas\n");
1023 /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
1024 /* if external stack is specified then the
1025 * higher order byte of the xdatalocation is
1026 * going into P2 and the lower order going into */
1028 if (options.useXstack) {
1029 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
1030 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
1031 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
1032 (unsigned int)options.xdata_loc & 0xff);
1037 // copyFile (stderr, code->oFile);
1039 fprintf(asmFile, "; I code from now on!\n");
1040 pic16_copypCode(asmFile, 'I');
1042 // if(pic16_debug_verbose)
1043 fprintf(asmFile, "; dbName from now on!\n");
1044 pic16_copypCode(asmFile, statsg->dbName);
1047 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1048 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\t;VR2\n");
1052 // if(pic16_debug_verbose)
1053 fprintf(asmFile, "; X code from now on!\n");
1054 pic16_copypCode(asmFile, 'X');
1056 // if(pic16_debug_verbose)
1057 fprintf(asmFile, "; M code from now on!\n");
1058 pic16_copypCode(asmFile, 'M');
1061 pic16_copypCode(asmFile, code->dbName);
1063 pic16_copypCode(asmFile, 'P');
1065 fprintf (asmFile,"\tend\n");