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"
36 #ifdef WORDS_BIGENDIAN
37 #define _ENDIAN(x) (3-x)
39 #define _ENDIAN(x) (x)
42 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
44 extern symbol *interrupts[256];
45 static void printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb);
49 extern unsigned maxInterrupts;
50 extern int maxRegBank;
52 extern char *VersionString;
53 extern FILE *codeOutFile;
54 extern set *tmpfileSet;
55 extern set *tmpfileNameSet;
56 extern char *iComments1;
57 extern char *iComments2;
58 //extern void emitStaticSeg (memmap * map);
62 set *idataSymSet=NULL;
64 extern DEFSETFUNC (closeTmpFiles);
65 extern DEFSETFUNC (rmTmpFiles);
67 extern void pic16_AnalyzeBanking (void);
68 extern void copyFile (FILE * dest, FILE * src);
69 extern void pic16_InlinepCode(void);
70 extern void pic16_writeUsedRegs(FILE *);
72 extern void initialComments (FILE * afile);
73 extern void printPublics (FILE * afile);
75 extern void printChar (FILE * ofile, char *s, int plen);
76 void pic16_pCodeInitRegisters(void);
77 pCodeOp *pic16_popGetLit(unsigned int lit);
78 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2);
79 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
81 /*-----------------------------------------------------------------*/
82 /* aopLiteral - string from a literal value */
83 /*-----------------------------------------------------------------*/
84 int pic16aopLiteral (value *val, int offset)
91 /* if it is a float then it gets tricky */
92 /* otherwise it is fairly simple */
93 if (!IS_FLOAT(val->type)) {
94 unsigned long v = (unsigned long) floatFromVal(val);
96 return ( (v >> (offset * 8)) & 0xff);
99 /* it is type float */
100 fl.f = (float) floatFromVal(val);
101 #ifdef WORDS_BIGENDIAN
102 return fl.c[3-offset];
109 /*-----------------------------------------------------------------*/
110 /* emitRegularMap - emit code for maps with no special cases */
111 /*-----------------------------------------------------------------*/
113 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
116 int i, size, bitvars = 0;;
118 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
121 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
123 /* print the area name */
124 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
127 fprintf(stderr, "\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\n",
128 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype));
129 printTypeChain( sym->type, stderr );
130 fprintf(stderr, "\n");
132 /* if extern then add to externs */
133 if (IS_EXTERN (sym->etype)) {
134 checkAddSym(&externs, sym);
138 /* if allocation required check is needed
139 * then check if the symbol really requires
140 * allocation only for local variables */
141 if (arFlag && !IS_AGGREGATE (sym->type) &&
142 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
143 !sym->allocreq && sym->level) {
145 fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
150 /* if global variable & not static or extern
151 * and addPublics allowed then add it to the public set */
152 if ((sym->used) && (sym->level == 0 ||
153 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
155 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
157 checkAddSym(&publics, sym);
158 // addSetHead(&publics, sym);
160 if(IS_STATIC(sym->etype)) {
162 /* add it to udata list */
164 fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
165 sym->name, sym->rname, sym->remat);
167 //, OP_SYMBOL(operandFromSymbol(sym))->name);
168 #define SET_IMPLICIT 1
171 if(IS_STRUCT(sym->type))
175 reg = pic16_allocDirReg( operandFromSymbol( sym ));
176 checkAddReg(&pic16_rel_udata, reg);
179 /* if extern then do nothing or is a function
181 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
182 if(SPEC_OCLS(sym->etype) == code) {
183 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
184 checkAddSym(&publics, sym);
185 // addSetHead(&publics, sym);
191 /* print extra debug info if required */
192 if (options.debug || sym->level == 0) {
193 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
195 if (!sym->level) /* global */
196 if (IS_STATIC (sym->etype))
197 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
199 fprintf (map->oFile, "G_"); /* scope is global */
201 /* symbol is local */
202 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
203 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
208 * The equates are nice, but do not allow relocatable objects to
209 * be created in the form that I (VR) want to make SDCC to work */
211 /* if is has an absolute address then generate
212 an equate for this no need to allocate space */
213 if (SPEC_ABSA (sym->etype)) {
214 // if (options.debug || sym->level == 0)
215 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
216 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
218 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
220 SPEC_ADDR (sym->etype));
222 /* emit only if it is global */
223 if(sym->level == 0) {
226 reg = pic16_dirregWithName( sym->name );
229 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
230 // __FUNCTION__, __LINE__, sym->name);
232 /* if IS_STRUCT is omitted the following
233 * fixes structures but break char/int etc */
235 if(IS_STRUCT(sym->type))
236 sym->implicit = 1; // mark as implicit
238 reg = pic16_allocDirReg( operandFromSymbol(sym) );
240 if(checkAddReg(&pic16_fix_udata, reg)) {
241 /* and add to globals list if not exist */
242 addSet(&publics, sym);
248 if(!sym->used && (sym->level == 0)) {
251 /* symbol not used, just declared probably, but its in
252 * level 0, so we must declare it fine as global */
254 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
257 if(IS_STRUCT(sym->type))
258 sym->implicit = 1; // mark as implicit
260 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
261 if(checkAddReg(&pic16_rel_udata, reg)) {
262 addSetHead(&publics, sym);
263 // addSetHead(&externs, sym);
268 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
269 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
270 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
271 if (IS_BITVAR (sym->etype)) {
274 fprintf (map->oFile, "\t%s\n", sym->rname);
275 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
276 for (i = 1; i < size; i++)
277 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
280 // fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
283 /* FIXME -- VR Fix the following, so that syms to be placed
284 * in the idata section and let linker decide about their fate */
286 /* if it has an initial value then do it only if
287 it is a global variable */
290 if (sym->ival && sym->level == 0) {
293 // if(SPEC_OCLS(sym->etype)==data) {
294 // fprintf(stderr, "%s: sym %s placed in data\n", map->sname, sym->name);
297 // fprintf(stderr, "'%s': sym '%s' has initial value\n", map->sname, sym->name);
299 if (IS_AGGREGATE (sym->type))
300 ival = initAggregates (sym, sym->ival, NULL);
302 addSet(&idataSymSet, copySymbol(sym));
303 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
304 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK));
306 codeOutFile = statsg->oFile;
308 eBBlockFromiCode (iCodeFromAst (ival));
316 /*-----------------------------------------------------------------*/
317 /* printIvalType - generates ival for int/char */
318 /*-----------------------------------------------------------------*/
320 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
325 //fprintf(stderr, "%s\n",__FUNCTION__);
327 /* if initList is deep */
328 if (ilist->type == INIT_DEEP)
329 ilist = ilist->init.deep;
331 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
332 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
335 if (!(val = list2val (ilist))) {
336 // assuming a warning has been thrown
340 if (val->type != type) {
341 val = valCastLiteral(type, floatFromVal(val));
345 ulval = (unsigned long) floatFromVal (val);
349 switch (getSize (type)) {
351 // pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
352 pic16_emitDB(pb, BYTE_IN_LONG(ulval,0));
356 // pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
357 // pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
358 pic16_emitDB(pb, BYTE_IN_LONG(ulval,0));
359 pic16_emitDB(pb, BYTE_IN_LONG(ulval,1));
363 // pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
364 // pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
365 // pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
366 // pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
367 pic16_emitDB(pb, BYTE_IN_LONG(ulval,0));
368 pic16_emitDB(pb, BYTE_IN_LONG(ulval,1));
369 pic16_emitDB(pb, BYTE_IN_LONG(ulval,2));
370 pic16_emitDB(pb, BYTE_IN_LONG(ulval,3));
375 /*-----------------------------------------------------------------*/
376 /* printIvalChar - generates initital value for character array */
377 /*-----------------------------------------------------------------*/
379 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
387 // fprintf(stderr, "%s\n",__FUNCTION__);
391 val = list2val (ilist);
392 /* if the value is a character string */
393 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
395 if (!DCL_ELEM (type))
396 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
398 //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
399 //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
400 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";omitting call to printChar"));
402 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
406 //tfprintf (oFile, "\t!db !constbyte\n", 0);
407 // pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(0)));
417 //printChar (oFile, s, strlen (s) + 1);
419 for(remain=0; remain<strlen(s); remain++)
421 // pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(s[remain])));
422 //fprintf(stderr,"0x%02x ",s[remain]);
423 pic16_emitDB(pb, s[remain]);
425 //fprintf(stderr,"\n");
430 /*-----------------------------------------------------------------*/
431 /* printIvalArray - generates code for array initialization */
432 /*-----------------------------------------------------------------*/
434 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
438 int lcnt = 0, size = 0;
444 /* take care of the special case */
445 /* array of characters can be init */
447 if (IS_CHAR (type->next)) {
448 fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
449 if (!IS_LITERAL(list2val(ilist)->etype)) {
450 werror (W_INIT_WRONG);
453 if (printIvalChar (type,
454 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
455 pb, SPEC_CVAL (sym->etype).v_char))
458 /* not the special case */
459 if (ilist->type != INIT_DEEP)
461 werror (E_INIT_STRUCT, sym->name);
465 iloop = ilist->init.deep;
466 lcnt = DCL_ELEM (type);
470 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
472 printIval (sym, type->next, iloop, pb);
473 iloop = (iloop ? iloop->next : NULL);
476 /* if not array limits given & we */
477 /* are out of initialisers then */
478 if (!DCL_ELEM (type) && !iloop)
481 /* no of elements given and we */
482 /* have generated for all of them */
484 /* if initializers left */
486 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
492 /* if we have not been given a size */
493 if (!DCL_ELEM (type))
494 DCL_ELEM (type) = size;
499 /*-----------------------------------------------------------------*/
500 /* printIval - generates code for initial value */
501 /*-----------------------------------------------------------------*/
503 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
508 /* if structure then */
509 if (IS_STRUCT (type))
511 //fprintf(stderr,"%s struct\n",__FUNCTION__);
512 //printIvalStruct (sym, type, ilist, oFile);
516 /* if this is a pointer */
519 //fprintf(stderr,"%s pointer\n",__FUNCTION__);
520 //printIvalPtr (sym, type, ilist, oFile);
524 /* if this is an array */
527 //fprintf(stderr,"%s array\n",__FUNCTION__);
528 printIvalArray (sym, type, ilist, pb);
532 /* if type is SPECIFIER */
535 //fprintf(stderr,"%s spec\n",__FUNCTION__);
536 printIvalType (sym, type, ilist, pb);
541 extern void pic16_pCodeConstString(char *name, char *value);
542 /*-----------------------------------------------------------------*/
543 /* emitStaticSeg - emitcode for the static segment */
544 /*-----------------------------------------------------------------*/
546 pic16emitStaticSeg (memmap * map)
550 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
552 //fprintf(stderr, "%s\n",__FUNCTION__);
554 /* for all variables in this segment do */
555 for (sym = setFirstItem (map->syms); sym;
556 sym = setNextItem (map->syms))
560 fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
561 printTypeChain( sym->type, stderr );
566 /* if it is "extern" then do nothing */
567 if (IS_EXTERN (sym->etype)) {
568 checkAddSym(&externs, sym);
569 // addSetHead(&externs, sym);
573 /* if it is not static add it to the public
575 if (!IS_STATIC (sym->etype)) {
576 checkAddSym(&publics, sym);
577 // addSetHead (&publics, sym);
581 /* print extra debug info if required */
582 if (options.debug || sym->level == 0)
584 /* NOTE to me - cdbFile may be null in which case,
585 * the sym name will be printed to stdout. oh well */
587 cdbSymbol (sym, cdbFile, FALSE, FALSE);
591 if (IS_STATIC (sym->etype))
592 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
594 fprintf (code->oFile, "G_"); /* scope is global */
597 /* symbol is local */
598 fprintf (code->oFile, "L%s_",
599 (sym->localof ? sym->localof->name : "-null-"));
600 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
605 /* if it has an absolute address */
606 if (SPEC_ABSA (sym->etype))
608 if (options.debug || sym->level == 0)
609 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
611 fprintf (code->oFile, "%s\t=\t0x%04x\n",
613 SPEC_ADDR (sym->etype));
617 if (options.debug || sym->level == 0)
618 fprintf (code->oFile, " == .\n");
620 /* if it has an initial value */
625 fprintf (code->oFile, "%s:\n", sym->rname);
627 resolveIvalSym (sym->ival, sym->type);
628 //printIval (sym, sym->type, sym->ival, code->oFile);
629 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
631 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
633 printIval (sym, sym->type, sym->ival, pb);
641 fprintf (code->oFile, "%s:\n", sym->rname);
642 /* special case for character strings */
643 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
644 SPEC_CVAL (sym->etype).v_char)
645 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
646 /*printChar (code->oFile,
647 SPEC_CVAL (sym->etype).v_char,
648 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
650 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
658 /*-----------------------------------------------------------------*/
659 /* emitMaps - emits the code for the data portion the code */
660 /*-----------------------------------------------------------------*/
664 /* no special considerations for the following
665 data, idata & bit & xdata */
666 pic16emitRegularMap (data, TRUE, TRUE);
667 pic16emitRegularMap (idata, TRUE, TRUE);
668 pic16emitRegularMap (bit, TRUE, FALSE);
669 pic16emitRegularMap (xdata, TRUE, TRUE);
670 pic16emitRegularMap (sfr, FALSE, FALSE);
671 pic16emitRegularMap (sfrbit, FALSE, FALSE);
672 pic16emitRegularMap (code, TRUE, FALSE);
673 pic16emitStaticSeg (statsg);
676 /*-----------------------------------------------------------------*/
677 /* createInterruptVect - creates the interrupt vector */
678 /*-----------------------------------------------------------------*/
680 pic16createInterruptVect (FILE * vFile)
682 /* if the main is only a prototype ie. no body then do nothing */
684 if (!IFFUNC_HASBODY(mainf->type)) {
685 /* if ! compile only then main function should be present */
686 if (!options.cc_only)
692 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
693 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
694 fprintf(vFile, ".intvecs\tcode\t0x0000\n");
695 fprintf (vFile, "__interrupt_vect:\n");
697 /* this is an overkill since WE are the port,
698 * and we know if we have a genIVT function! */
700 port->genIVT(vFile, interrupts, maxInterrupts);
707 /*-----------------------------------------------------------------*/
708 /* initialComments - puts in some initial comments */
709 /*-----------------------------------------------------------------*/
711 pic16initialComments (FILE * afile)
713 initialComments (afile);
714 fprintf (afile, "; PIC port for the 16-bit core\n");
715 fprintf (afile, iComments2);
719 /*-----------------------------------------------------------------*/
720 /* printPublics - generates global declarations for publics */
721 /*-----------------------------------------------------------------*/
723 pic16printPublics (FILE *afile)
727 fprintf (afile, "%s", iComments2);
728 fprintf (afile, "; public variables in this module\n");
729 fprintf (afile, "%s", iComments2);
731 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
732 fprintf(afile, "\tglobal %s\n", sym->rname);
735 /*-----------------------------------------------------------------*/
736 /* printExterns - generates extern declarations for externs */
737 /*-----------------------------------------------------------------*/
739 pic16_printExterns(FILE *afile)
743 fprintf(afile, "%s", iComments2);
744 fprintf(afile, "; extern variables in this module\n");
745 fprintf(afile, "%s", iComments2);
747 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
748 fprintf(afile, "\textern %s\n", sym->rname);
750 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
751 fprintf(afile, "\textern _%s\n", sym->name);
754 /*-----------------------------------------------------------------*/
755 /* emitOverlay - will emit code for the overlay stuff */
756 /*-----------------------------------------------------------------*/
758 pic16emitOverlay (FILE * afile)
762 if (!elementsInSet (ovrSetSets))
763 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
765 /* for each of the sets in the overlay segment do */
766 for (ovrset = setFirstItem (ovrSetSets); ovrset;
767 ovrset = setNextItem (ovrSetSets))
772 if (elementsInSet (ovrset))
774 /* this dummy area is used to fool the assembler
775 otherwise the assembler will append each of these
776 declarations into one chunk and will not overlay
778 fprintf (afile, ";\t.area _DUMMY\n");
779 /* output the area informtion */
780 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
783 for (sym = setFirstItem (ovrset); sym;
784 sym = setNextItem (ovrset))
787 /* if extern then do nothing */
788 if (IS_EXTERN (sym->etype))
791 /* if allocation required check is needed
792 then check if the symbol really requires
793 allocation only for local variables */
794 if (!IS_AGGREGATE (sym->type) &&
795 !(sym->_isparm && !IS_REGPARM (sym->etype))
796 && !sym->allocreq && sym->level)
799 /* if global variable & not static or extern
800 and addPublics allowed then add it to the public set */
801 if ((sym->_isparm && !IS_REGPARM (sym->etype))
802 && !IS_STATIC (sym->etype)) {
803 checkAddSym(&publics, sym);
804 // addSetHead (&publics, sym);
807 /* if extern then do nothing or is a function
809 if (IS_FUNC (sym->type))
813 /* print extra debug info if required */
814 if (options.debug || sym->level == 0)
817 cdbSymbol (sym, cdbFile, FALSE, FALSE);
821 if (IS_STATIC (sym->etype))
822 fprintf (afile, "F%s_", moduleName); /* scope is file */
824 fprintf (afile, "G_"); /* scope is global */
827 /* symbol is local */
828 fprintf (afile, "L%s_",
829 (sym->localof ? sym->localof->name : "-null-"));
830 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
834 /* if is has an absolute address then generate
835 an equate for this no need to allocate space */
836 if (SPEC_ABSA (sym->etype))
839 if (options.debug || sym->level == 0)
840 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
842 fprintf (afile, "%s\t=\t0x%04x\n",
844 SPEC_ADDR (sym->etype));
848 if (options.debug || sym->level == 0)
849 fprintf (afile, "==.\n");
852 fprintf (afile, "%s:\n", sym->rname);
853 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
861 /*-----------------------------------------------------------------*/
862 /* glue - the final glue that hold the whole thing together */
863 /*-----------------------------------------------------------------*/
870 FILE *ovrFile = tempfile();
873 mainf = newSymbol ("main", 0);
876 mainf = findSymWithLevel(SymbolTab, mainf);
878 /* only if the main function exists */
879 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
880 if (!options.cc_only)
886 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
888 addSetHead(&tmpfileSet,ovrFile);
889 pic16_pCodeInitRegisters();
891 if (mainf && IFFUNC_HASBODY(mainf->type)) {
892 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
896 /* entry point @ start of CSEG */
897 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup\t;VR1",-1));
900 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
901 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("stack"))));
902 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
903 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("stack"))));
906 /* put in the call to main */
907 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
909 if (options.mainreturn) {
910 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
911 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
913 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
914 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
918 /* At this point we've got all the code in the form of pCode structures */
919 /* Now it needs to be rearranged into the order it should be placed in the */
922 pic16_movepBlock2Head('P'); // Last
923 pic16_movepBlock2Head(code->dbName);
924 pic16_movepBlock2Head('X');
925 pic16_movepBlock2Head(statsg->dbName); // First
927 /* print the global struct definitions */
928 // if (options.debug)
929 // cdbStructBlock (0); //,cdbFile);
932 /* PENDING: this isnt the best place but it will do */
933 if (port->general.glue_up_main) {
934 /* create the interrupt vector table */
935 pic16createInterruptVect (vFile);
938 addSetHead(&tmpfileSet,vFile);
940 /* emit code for the all the variables declared */
942 /* do the overlay segments */
943 pic16emitOverlay(ovrFile);
944 pic16_AnalyzepCode('*');
949 sprintf(buffer, dstFileName);
950 strcat(buffer, ".calltree");
951 cFile = fopen(buffer, "w");
952 pic16_printCallTree( cFile );
958 pic16_AnalyzepCode('*');
960 if(pic16_debug_verbose)
963 /* now put it all together into the assembler file */
964 /* create the assembler file name */
965 if ((noAssemble || options.c1mode) && fullDstFileName) {
966 sprintf (buffer, fullDstFileName);
968 sprintf (buffer, dstFileName);
969 strcat (buffer, ".asm");
972 if (!(asmFile = fopen (buffer, "w"))) {
973 werror (E_FILE_OPEN_ERR, buffer);
977 /* initial comments */
978 pic16initialComments (asmFile);
980 /* print module name */
981 fprintf (asmFile, ";\t.module %s\n", moduleName);
983 /* Let the port generate any global directives, etc. */
984 if (port->genAssemblerPreamble) {
985 port->genAssemblerPreamble(asmFile);
988 /* print the extern variables to this module */
989 pic16_printExterns(asmFile);
991 /* print the global variables in this module */
992 pic16printPublics (asmFile);
995 /* copy the sfr segment */
996 fprintf (asmFile, "%s", iComments2);
997 fprintf (asmFile, "; special function registers\n");
998 fprintf (asmFile, "%s", iComments2);
999 copyFile (asmFile, sfr->oFile);
1003 /* Put all variables into a cblock */
1004 pic16_AnalyzeBanking();
1005 pic16_writeUsedRegs(asmFile);
1007 /* create the overlay segments */
1008 fprintf (asmFile, "%s", iComments2);
1009 fprintf (asmFile, "; overlayable items in internal ram \n");
1010 fprintf (asmFile, "%s", iComments2);
1011 copyFile (asmFile, ovrFile);
1013 /* create the stack segment MOF */
1014 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1015 fprintf (asmFile, "%s", iComments2);
1016 fprintf (asmFile, "; Stack segment in internal ram \n");
1017 fprintf (asmFile, "%s", iComments2);
1018 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
1019 ";__start__stack:\n;\t.ds\t1\n\n");
1023 /* no indirect data in pic */
1024 /* create the idata segment */
1025 fprintf (asmFile, "%s", iComments2);
1026 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1027 fprintf (asmFile, "%s", iComments2);
1028 copyFile (asmFile, idata->oFile);
1033 /* no xdata in pic */
1034 /* if external stack then reserve space of it */
1035 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1036 fprintf (asmFile, "%s", iComments2);
1037 fprintf (asmFile, "; external stack \n");
1038 fprintf (asmFile, "%s", iComments2);
1039 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1040 fprintf (asmFile,";\t.ds 256\n");
1045 /* no xdata in pic */
1046 /* copy xtern ram data */
1047 fprintf (asmFile, "%s", iComments2);
1048 fprintf (asmFile, "; external ram data\n");
1049 fprintf (asmFile, "%s", iComments2);
1050 copyFile (asmFile, xdata->oFile);
1053 /* copy the bit segment */
1054 fprintf (asmFile, "%s", iComments2);
1055 fprintf (asmFile, "; bit data\n");
1056 fprintf (asmFile, "%s", iComments2);
1057 copyFile (asmFile, bit->oFile);
1060 /* copy the interrupt vector table */
1061 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1062 fprintf (asmFile, "%s", iComments2);
1063 fprintf (asmFile, "; interrupt vector \n");
1064 fprintf (asmFile, "%s", iComments2);
1065 copyFile (asmFile, vFile);
1068 /* copy global & static initialisations */
1069 fprintf (asmFile, "%s", iComments2);
1070 fprintf (asmFile, "; global & static initialisations\n");
1071 fprintf (asmFile, "%s", iComments2);
1074 /* FIXME 8051 Legacy -- VR */
1075 /* Everywhere we generate a reference to the static_name area,
1076 * (which is currently only here), we immediately follow it with a
1077 * definition of the post_static_name area. This guarantees that
1078 * the post_static_name area will immediately follow the static_name
1081 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
1082 fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
1083 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
1087 /* copy over code */
1088 fprintf (asmFile, "%s", iComments2);
1089 fprintf (asmFile, "\tcode\n");
1090 fprintf (asmFile, "%s", iComments2);
1093 fprintf(asmFile, "; A code from now on!\n");
1094 pic16_copypCode(asmFile, 'A');
1097 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1098 fprintf (asmFile,"__sdcc_gsinit_startup:\t\t;VRokas\n");
1101 /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
1102 /* if external stack is specified then the
1103 * higher order byte of the xdatalocation is
1104 * going into P2 and the lower order going into */
1106 if (options.useXstack) {
1107 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
1108 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
1109 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
1110 (unsigned int)options.xdata_loc & 0xff);
1115 // copyFile (stderr, code->oFile);
1117 fprintf(asmFile, "; I code from now on!\n");
1118 pic16_copypCode(asmFile, 'I');
1120 // if(pic16_debug_verbose)
1121 fprintf(asmFile, "; dbName from now on!\n");
1122 pic16_copypCode(asmFile, statsg->dbName);
1125 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1126 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\t;VR2\n");
1130 // if(pic16_debug_verbose)
1131 fprintf(asmFile, "; X code from now on!\n");
1132 pic16_copypCode(asmFile, 'X');
1134 // if(pic16_debug_verbose)
1135 fprintf(asmFile, "; M code from now on!\n");
1136 pic16_copypCode(asmFile, 'M');
1139 pic16_copypCode(asmFile, code->dbName);
1141 pic16_copypCode(asmFile, 'P');
1143 fprintf (asmFile,"\tend\n");