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"
35 #ifdef WORDS_BIGENDIAN
36 #define _ENDIAN(x) (3-x)
38 #define _ENDIAN(x) (x)
41 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
43 extern symbol *interrupts[256];
44 static void printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb);
48 extern unsigned maxInterrupts;
49 extern int maxRegBank;
51 extern char *VersionString;
52 extern FILE *codeOutFile;
53 extern set *tmpfileSet;
54 extern set *tmpfileNameSet;
55 extern char *iComments1;
56 extern char *iComments2;
57 //extern void emitStaticSeg (memmap * map);
61 extern DEFSETFUNC (closeTmpFiles);
62 extern DEFSETFUNC (rmTmpFiles);
64 extern void pic16_AnalyzeBanking (void);
65 extern void copyFile (FILE * dest, FILE * src);
66 extern void pic16_InlinepCode(void);
67 extern void pic16_writeUsedRegs(FILE *);
69 extern void initialComments (FILE * afile);
70 extern void printPublics (FILE * afile);
72 extern void printChar (FILE * ofile, char *s, int plen);
73 void pic16_pCodeInitRegisters(void);
74 pCodeOp *pic16_popGetLit(unsigned int lit);
75 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2);
76 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
78 /*-----------------------------------------------------------------*/
79 /* aopLiteral - string from a literal value */
80 /*-----------------------------------------------------------------*/
81 int pic16aopLiteral (value *val, int offset)
88 /* if it is a float then it gets tricky */
89 /* otherwise it is fairly simple */
90 if (!IS_FLOAT(val->type)) {
91 unsigned long v = (unsigned long) floatFromVal(val);
93 return ( (v >> (offset * 8)) & 0xff);
96 /* it is type float */
97 fl.f = (float) floatFromVal(val);
98 #ifdef WORDS_BIGENDIAN
99 return fl.c[3-offset];
106 /*-----------------------------------------------------------------*/
107 /* emitRegularMap - emit code for maps with no special cases */
108 /*-----------------------------------------------------------------*/
110 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
113 int i, size, bitvars = 0;;
115 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
118 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
120 /* print the area name */
121 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
123 fprintf(stderr, "\t%s: sym: %s\tused: %d\textern: %d\n",
124 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype));
125 printTypeChain( sym->type, stderr );
128 /* if extern then add to externs */
129 if (IS_EXTERN (sym->etype)) {
130 // if(sym->used) // fixme
131 addSetHead(&externs, sym);
135 /* if allocation required check is needed
136 * then check if the symbol really requires
137 * allocation only for local variables */
138 if (arFlag && !IS_AGGREGATE (sym->type) &&
139 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
140 !sym->allocreq && sym->level) {
142 fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
147 /* if global variable & not static or extern
148 * and addPublics allowed then add it to the public set */
149 if ((sym->used) && (sym->level == 0 ||
150 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
152 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
155 addSetHead (&publics, sym);
157 // reg = pic16_allocRegByName(sym->name, sym->size); //( operandFromSymbol( sym ));
158 // checkAddReg(&pic16_rel_udata, reg);
161 if(IS_STATIC(sym->etype)) {
163 /* add it to udata list */
165 fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
166 sym->name, sym->rname, sym->remat);
168 //, OP_SYMBOL(operandFromSymbol(sym))->name);
169 reg = pic16_allocDirReg( operandFromSymbol( sym ));
170 checkAddReg(&pic16_rel_udata, reg);
173 /* if extern then do nothing or is a function
175 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
176 if(SPEC_OCLS(sym->etype) == code) {
177 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
178 addSetHead(&publics, sym);
184 /* print extra debug info if required */
185 if (options.debug || sym->level == 0) {
186 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
188 if (!sym->level) /* global */
189 if (IS_STATIC (sym->etype))
190 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
192 fprintf (map->oFile, "G_"); /* scope is global */
194 /* symbol is local */
195 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
196 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
201 * The equates are nice, but do not allow relocatable objects to
202 * be created in the form that I (VR) want to make SDCC to work */
204 /* if is has an absolute address then generate
205 an equate for this no need to allocate space */
206 if (SPEC_ABSA (sym->etype)) {
207 // if (options.debug || sym->level == 0)
208 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
209 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
211 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
213 SPEC_ADDR (sym->etype));
215 /* emit only if it is global */
216 if(sym->level == 0) {
220 reg = pic16_dirregWithName( sym->name );
222 fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
223 __FUNCTION__, __LINE__, sym->name);
225 op = operandFromSymbol( sym );
226 reg = pic16_allocDirReg( op );
228 if(checkAddReg(&pic16_fix_udata, reg)) {
229 /* and add to globals list if not exist */
230 addSetHead(&publics, sym);
236 if(!sym->used && (sym->level == 0)) {
239 /* symbol not used, just declared probably, but its in
240 * level 0, so we must declare it fine as global */
242 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
243 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
244 if(checkAddReg(&pic16_rel_udata, reg)) {
245 addSetHead(&publics, sym);
246 // addSetHead(&externs, sym);
251 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
252 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
253 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
254 if (IS_BITVAR (sym->etype)) {
257 fprintf (map->oFile, "\t%s\n", sym->rname);
258 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
259 for (i = 1; i < size; i++)
260 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
263 // fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
266 /* FIXME -- VR Fix the following, so that syms to be placed
267 * in the idata section and let linker decide about their fate */
269 /* if it has an initial value then do it only if
270 it is a global variable */
273 if (sym->ival && sym->level == 0) {
276 // if(SPEC_OCLS(sym->etype)==data) {
277 // fprintf(stderr, "%s: sym %s placed in data\n", map->sname, sym->name);
280 // fprintf(stderr, "'%s': sym '%s' has initial value\n", map->sname, sym->name);
282 if (IS_AGGREGATE (sym->type))
283 ival = initAggregates (sym, sym->ival, NULL);
285 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
286 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK));
287 codeOutFile = statsg->oFile;
289 eBBlockFromiCode (iCodeFromAst (ival));
297 /*-----------------------------------------------------------------*/
298 /* printIvalType - generates ival for int/char */
299 /*-----------------------------------------------------------------*/
301 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
306 //fprintf(stderr, "%s\n",__FUNCTION__);
308 /* if initList is deep */
309 if (ilist->type == INIT_DEEP)
310 ilist = ilist->init.deep;
312 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
313 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
316 if (!(val = list2val (ilist))) {
317 // assuming a warning has been thrown
321 if (val->type != type) {
322 val = valCastLiteral(type, floatFromVal(val));
326 ulval = (unsigned long) floatFromVal (val);
330 switch (getSize (type)) {
332 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
336 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
337 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
341 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
342 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
343 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
344 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
349 /*-----------------------------------------------------------------*/
350 /* printIvalChar - generates initital value for character array */
351 /*-----------------------------------------------------------------*/
353 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
361 fprintf(stderr, "%s\n",__FUNCTION__);
365 val = list2val (ilist);
366 /* if the value is a character string */
367 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
369 if (!DCL_ELEM (type))
370 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
372 //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
373 //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
374 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";omitting call to printChar"));
376 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
378 //tfprintf (oFile, "\t!db !constbyte\n", 0);
379 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(0)));
386 //printChar (oFile, s, strlen (s) + 1);
388 for(remain=0; remain<strlen(s); remain++) {
389 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(s[remain])));
390 //fprintf(stderr,"0x%02x ",s[remain]);
392 //fprintf(stderr,"\n");
397 /*-----------------------------------------------------------------*/
398 /* printIvalArray - generates code for array initialization */
399 /*-----------------------------------------------------------------*/
401 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
405 int lcnt = 0, size = 0;
410 /* take care of the special case */
411 /* array of characters can be init */
413 if (IS_CHAR (type->next)) {
414 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
415 if (!IS_LITERAL(list2val(ilist)->etype)) {
416 werror (W_INIT_WRONG);
419 if (printIvalChar (type,
420 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
421 pb, SPEC_CVAL (sym->etype).v_char))
424 /* not the special case */
425 if (ilist->type != INIT_DEEP)
427 werror (E_INIT_STRUCT, sym->name);
431 iloop = ilist->init.deep;
432 lcnt = DCL_ELEM (type);
436 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
438 printIval (sym, type->next, iloop, pb);
439 iloop = (iloop ? iloop->next : NULL);
442 /* if not array limits given & we */
443 /* are out of initialisers then */
444 if (!DCL_ELEM (type) && !iloop)
447 /* no of elements given and we */
448 /* have generated for all of them */
450 /* if initializers left */
452 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
458 /* if we have not been given a size */
459 if (!DCL_ELEM (type))
460 DCL_ELEM (type) = size;
465 /*-----------------------------------------------------------------*/
466 /* printIval - generates code for initial value */
467 /*-----------------------------------------------------------------*/
469 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
474 /* if structure then */
475 if (IS_STRUCT (type))
477 //fprintf(stderr,"%s struct\n",__FUNCTION__);
478 //printIvalStruct (sym, type, ilist, oFile);
482 /* if this is a pointer */
485 //fprintf(stderr,"%s pointer\n",__FUNCTION__);
486 //printIvalPtr (sym, type, ilist, oFile);
490 /* if this is an array */
493 //fprintf(stderr,"%s array\n",__FUNCTION__);
494 printIvalArray (sym, type, ilist, pb);
498 /* if type is SPECIFIER */
501 //fprintf(stderr,"%s spec\n",__FUNCTION__);
502 printIvalType (sym, type, ilist, pb);
507 extern void pic16_pCodeConstString(char *name, char *value);
508 /*-----------------------------------------------------------------*/
509 /* emitStaticSeg - emitcode for the static segment */
510 /*-----------------------------------------------------------------*/
512 pic16emitStaticSeg (memmap * map)
516 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
518 //fprintf(stderr, "%s\n",__FUNCTION__);
520 /* for all variables in this segment do */
521 for (sym = setFirstItem (map->syms); sym;
522 sym = setNextItem (map->syms))
526 fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
527 printTypeChain( sym->type, stderr );
532 /* if it is "extern" then do nothing */
533 if (IS_EXTERN (sym->etype))
536 /* if it is not static add it to the public
538 if (!IS_STATIC (sym->etype))
539 addSetHead (&publics, sym);
542 /* print extra debug info if required */
543 if (options.debug || sym->level == 0)
545 /* NOTE to me - cdbFile may be null in which case,
546 * the sym name will be printed to stdout. oh well */
548 cdbSymbol (sym, cdbFile, FALSE, FALSE);
552 if (IS_STATIC (sym->etype))
553 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
555 fprintf (code->oFile, "G_"); /* scope is global */
558 /* symbol is local */
559 fprintf (code->oFile, "L%s_",
560 (sym->localof ? sym->localof->name : "-null-"));
561 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
566 /* if it has an absolute address */
567 if (SPEC_ABSA (sym->etype))
569 if (options.debug || sym->level == 0)
570 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
572 fprintf (code->oFile, "%s\t=\t0x%04x\n",
574 SPEC_ADDR (sym->etype));
578 if (options.debug || sym->level == 0)
579 fprintf (code->oFile, " == .\n");
581 /* if it has an initial value */
586 fprintf (code->oFile, "%s:\n", sym->rname);
588 resolveIvalSym (sym->ival, sym->type);
589 //printIval (sym, sym->type, sym->ival, code->oFile);
590 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
592 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
594 printIval (sym, sym->type, sym->ival, pb);
601 fprintf (code->oFile, "%s:\n", sym->rname);
602 /* special case for character strings */
603 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
604 SPEC_CVAL (sym->etype).v_char)
605 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
606 /*printChar (code->oFile,
607 SPEC_CVAL (sym->etype).v_char,
608 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
610 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
618 /*-----------------------------------------------------------------*/
619 /* emitMaps - emits the code for the data portion the code */
620 /*-----------------------------------------------------------------*/
624 /* no special considerations for the following
625 data, idata & bit & xdata */
626 pic16emitRegularMap (data, TRUE, TRUE);
627 pic16emitRegularMap (idata, TRUE, TRUE);
628 pic16emitRegularMap (bit, TRUE, FALSE);
629 pic16emitRegularMap (xdata, TRUE, TRUE);
630 pic16emitRegularMap (sfr, FALSE, FALSE);
631 pic16emitRegularMap (sfrbit, FALSE, FALSE);
632 pic16emitRegularMap (code, TRUE, FALSE);
633 pic16emitStaticSeg (statsg);
636 /*-----------------------------------------------------------------*/
637 /* createInterruptVect - creates the interrupt vector */
638 /*-----------------------------------------------------------------*/
640 pic16createInterruptVect (FILE * vFile)
642 /* if the main is only a prototype ie. no body then do nothing */
644 if (!IFFUNC_HASBODY(mainf->type)) {
645 /* if ! compile only then main function should be present */
646 if (!options.cc_only)
652 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
653 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
654 fprintf(vFile, ".intvecs\tcode\t0x0000\n");
655 fprintf (vFile, "__interrupt_vect:\n");
657 /* this is an overkill since WE are the port,
658 * and we know if we have a genIVT function! */
660 port->genIVT(vFile, interrupts, maxInterrupts);
667 /*-----------------------------------------------------------------*/
668 /* initialComments - puts in some initial comments */
669 /*-----------------------------------------------------------------*/
671 pic16initialComments (FILE * afile)
673 initialComments (afile);
674 fprintf (afile, "; PIC port for the 16-bit core\n");
675 fprintf (afile, iComments2);
679 /*-----------------------------------------------------------------*/
680 /* printPublics - generates global declarations for publics */
681 /*-----------------------------------------------------------------*/
683 pic16printPublics (FILE *afile)
687 fprintf (afile, "%s", iComments2);
688 fprintf (afile, "; public variables in this module\n");
689 fprintf (afile, "%s", iComments2);
691 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
692 fprintf(afile, "\tglobal %s\n", sym->rname);
695 /*-----------------------------------------------------------------*/
696 /* printExterns - generates extern declarations for externs */
697 /*-----------------------------------------------------------------*/
699 pic16_printExterns(FILE *afile)
703 fprintf(afile, "%s", iComments2);
704 fprintf(afile, "; extern variables in this module\n");
705 fprintf(afile, "%s", iComments2);
707 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
708 fprintf(afile, "\textern %s\n", sym->rname);
710 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
711 fprintf(afile, "\textern _%s\n", sym->name);
714 /*-----------------------------------------------------------------*/
715 /* emitOverlay - will emit code for the overlay stuff */
716 /*-----------------------------------------------------------------*/
718 pic16emitOverlay (FILE * afile)
722 if (!elementsInSet (ovrSetSets))
723 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
725 /* for each of the sets in the overlay segment do */
726 for (ovrset = setFirstItem (ovrSetSets); ovrset;
727 ovrset = setNextItem (ovrSetSets))
732 if (elementsInSet (ovrset))
734 /* this dummy area is used to fool the assembler
735 otherwise the assembler will append each of these
736 declarations into one chunk and will not overlay
738 fprintf (afile, ";\t.area _DUMMY\n");
739 /* output the area informtion */
740 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
743 for (sym = setFirstItem (ovrset); sym;
744 sym = setNextItem (ovrset))
747 /* if extern then do nothing */
748 if (IS_EXTERN (sym->etype))
751 /* if allocation required check is needed
752 then check if the symbol really requires
753 allocation only for local variables */
754 if (!IS_AGGREGATE (sym->type) &&
755 !(sym->_isparm && !IS_REGPARM (sym->etype))
756 && !sym->allocreq && sym->level)
759 /* if global variable & not static or extern
760 and addPublics allowed then add it to the public set */
761 if ((sym->_isparm && !IS_REGPARM (sym->etype))
762 && !IS_STATIC (sym->etype))
763 addSetHead (&publics, sym);
765 /* if extern then do nothing or is a function
767 if (IS_FUNC (sym->type))
771 /* print extra debug info if required */
772 if (options.debug || sym->level == 0)
775 cdbSymbol (sym, cdbFile, FALSE, FALSE);
779 if (IS_STATIC (sym->etype))
780 fprintf (afile, "F%s_", moduleName); /* scope is file */
782 fprintf (afile, "G_"); /* scope is global */
785 /* symbol is local */
786 fprintf (afile, "L%s_",
787 (sym->localof ? sym->localof->name : "-null-"));
788 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
792 /* if is has an absolute address then generate
793 an equate for this no need to allocate space */
794 if (SPEC_ABSA (sym->etype))
797 if (options.debug || sym->level == 0)
798 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
800 fprintf (afile, "%s\t=\t0x%04x\n",
802 SPEC_ADDR (sym->etype));
806 if (options.debug || sym->level == 0)
807 fprintf (afile, "==.\n");
810 fprintf (afile, "%s:\n", sym->rname);
811 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
819 /*-----------------------------------------------------------------*/
820 /* glue - the final glue that hold the whole thing together */
821 /*-----------------------------------------------------------------*/
828 FILE *ovrFile = tempfile();
831 mainf = newSymbol ("main", 0);
834 mainf = findSymWithLevel(SymbolTab, mainf);
836 /* only if the main function exists */
837 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
838 if (!options.cc_only)
844 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
846 addSetHead(&tmpfileSet,ovrFile);
847 pic16_pCodeInitRegisters();
849 if (mainf && IFFUNC_HASBODY(mainf->type)) {
850 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
854 /* entry point @ start of CSEG */
855 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup\t;VR1",-1));
858 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
859 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("stack"))));
860 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
861 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("stack"))));
864 /* put in the call to main */
865 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
867 if (options.mainreturn) {
868 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
869 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
871 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
872 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
876 /* At this point we've got all the code in the form of pCode structures */
877 /* Now it needs to be rearranged into the order it should be placed in the */
880 pic16_movepBlock2Head('P'); // Last
881 pic16_movepBlock2Head(code->dbName);
882 pic16_movepBlock2Head('X');
883 pic16_movepBlock2Head(statsg->dbName); // First
885 /* print the global struct definitions */
886 // if (options.debug)
887 // cdbStructBlock (0); //,cdbFile);
890 /* PENDING: this isnt the best place but it will do */
891 if (port->general.glue_up_main) {
892 /* create the interrupt vector table */
893 pic16createInterruptVect (vFile);
896 addSetHead(&tmpfileSet,vFile);
898 /* emit code for the all the variables declared */
900 /* do the overlay segments */
901 pic16emitOverlay(ovrFile);
902 pic16_AnalyzepCode('*');
907 sprintf(buffer, dstFileName);
908 strcat(buffer, ".calltree");
909 cFile = fopen(buffer, "w");
910 pic16_printCallTree( cFile );
916 pic16_AnalyzepCode('*');
918 if(pic16_debug_verbose)
921 /* now put it all together into the assembler file */
922 /* create the assembler file name */
923 if ((noAssemble || options.c1mode) && fullDstFileName) {
924 sprintf (buffer, fullDstFileName);
926 sprintf (buffer, dstFileName);
927 strcat (buffer, ".asm");
930 if (!(asmFile = fopen (buffer, "w"))) {
931 werror (E_FILE_OPEN_ERR, buffer);
935 /* initial comments */
936 pic16initialComments (asmFile);
938 /* print module name */
939 fprintf (asmFile, ";\t.module %s\n", moduleName);
941 /* Let the port generate any global directives, etc. */
942 if (port->genAssemblerPreamble) {
943 port->genAssemblerPreamble(asmFile);
946 /* print the extern variables to this module */
947 pic16_printExterns(asmFile);
949 /* print the global variables in this module */
950 pic16printPublics (asmFile);
953 /* copy the sfr segment */
954 fprintf (asmFile, "%s", iComments2);
955 fprintf (asmFile, "; special function registers\n");
956 fprintf (asmFile, "%s", iComments2);
957 copyFile (asmFile, sfr->oFile);
961 /* Put all variables into a cblock */
962 pic16_AnalyzeBanking();
963 pic16_writeUsedRegs(asmFile);
965 /* create the overlay segments */
966 fprintf (asmFile, "%s", iComments2);
967 fprintf (asmFile, "; overlayable items in internal ram \n");
968 fprintf (asmFile, "%s", iComments2);
969 copyFile (asmFile, ovrFile);
971 /* create the stack segment MOF */
972 if (mainf && IFFUNC_HASBODY(mainf->type)) {
973 fprintf (asmFile, "%s", iComments2);
974 fprintf (asmFile, "; Stack segment in internal ram \n");
975 fprintf (asmFile, "%s", iComments2);
976 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
977 ";__start__stack:\n;\t.ds\t1\n\n");
981 /* no indirect data in pic */
982 /* create the idata segment */
983 fprintf (asmFile, "%s", iComments2);
984 fprintf (asmFile, "; indirectly addressable internal ram data\n");
985 fprintf (asmFile, "%s", iComments2);
986 copyFile (asmFile, idata->oFile);
991 /* no xdata in pic */
992 /* if external stack then reserve space of it */
993 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
994 fprintf (asmFile, "%s", iComments2);
995 fprintf (asmFile, "; external stack \n");
996 fprintf (asmFile, "%s", iComments2);
997 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
998 fprintf (asmFile,";\t.ds 256\n");
1003 /* no xdata in pic */
1004 /* copy xtern ram data */
1005 fprintf (asmFile, "%s", iComments2);
1006 fprintf (asmFile, "; external ram data\n");
1007 fprintf (asmFile, "%s", iComments2);
1008 copyFile (asmFile, xdata->oFile);
1011 /* copy the bit segment */
1012 fprintf (asmFile, "%s", iComments2);
1013 fprintf (asmFile, "; bit data\n");
1014 fprintf (asmFile, "%s", iComments2);
1015 copyFile (asmFile, bit->oFile);
1018 /* copy the interrupt vector table */
1019 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1020 fprintf (asmFile, "%s", iComments2);
1021 fprintf (asmFile, "; interrupt vector \n");
1022 fprintf (asmFile, "%s", iComments2);
1023 copyFile (asmFile, vFile);
1026 /* copy global & static initialisations */
1027 fprintf (asmFile, "%s", iComments2);
1028 fprintf (asmFile, "; global & static initialisations\n");
1029 fprintf (asmFile, "%s", iComments2);
1032 /* FIXME 8051 Legacy -- VR */
1033 /* Everywhere we generate a reference to the static_name area,
1034 * (which is currently only here), we immediately follow it with a
1035 * definition of the post_static_name area. This guarantees that
1036 * the post_static_name area will immediately follow the static_name
1039 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
1040 fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
1041 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
1045 /* copy over code */
1046 fprintf (asmFile, "%s", iComments2);
1047 fprintf (asmFile, "\tcode\n");
1048 fprintf (asmFile, "%s", iComments2);
1051 fprintf(asmFile, "; A code from now on!\n");
1052 pic16_copypCode(asmFile, 'A');
1055 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1056 fprintf (asmFile,"__sdcc_gsinit_startup:\t\t;VRokas\n");
1059 /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
1060 /* if external stack is specified then the
1061 * higher order byte of the xdatalocation is
1062 * going into P2 and the lower order going into */
1064 if (options.useXstack) {
1065 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
1066 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
1067 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
1068 (unsigned int)options.xdata_loc & 0xff);
1073 // copyFile (stderr, code->oFile);
1075 fprintf(asmFile, "; I code from now on!\n");
1076 pic16_copypCode(asmFile, 'I');
1078 // if(pic16_debug_verbose)
1079 fprintf(asmFile, "; dbName from now on!\n");
1080 pic16_copypCode(asmFile, statsg->dbName);
1083 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1084 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\t;VR2\n");
1088 // if(pic16_debug_verbose)
1089 fprintf(asmFile, "; X code from now on!\n");
1090 pic16_copypCode(asmFile, 'X');
1092 // if(pic16_debug_verbose)
1093 fprintf(asmFile, "; M code from now on!\n");
1094 pic16_copypCode(asmFile, 'M');
1097 pic16_copypCode(asmFile, code->dbName);
1099 pic16_copypCode(asmFile, 'P');
1101 fprintf (asmFile,"\tend\n");