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"
38 #ifdef WORDS_BIGENDIAN
39 #define _ENDIAN(x) (3-x)
41 #define _ENDIAN(x) (x)
44 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
46 extern symbol *interrupts[256];
47 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p);
51 extern unsigned maxInterrupts;
52 extern int maxRegBank;
54 extern char *VersionString;
55 extern FILE *codeOutFile;
56 extern set *tmpfileSet;
57 extern set *tmpfileNameSet;
58 extern char *iComments1;
59 extern char *iComments2;
62 extern unsigned long pFile_isize;
64 extern unsigned long pic16_countInstructions();
65 set *rel_idataSymSet=NULL;
66 set *fix_idataSymSet=NULL;
68 extern DEFSETFUNC (closeTmpFiles);
69 extern DEFSETFUNC (rmTmpFiles);
71 extern void pic16_AnalyzeBanking (void);
72 extern void pic16_OptimizeJumps ();
73 extern void copyFile (FILE * dest, FILE * src);
74 extern void pic16_InlinepCode(void);
75 extern void pic16_writeUsedRegs(FILE *);
77 extern void initialComments (FILE * afile);
78 extern void printPublics (FILE * afile);
80 void pic16_pCodeInitRegisters(void);
81 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
82 extern void pic16_pCodeConstString(char *name, char *value);
85 /*-----------------------------------------------------------------*/
86 /* aopLiteral - string from a literal value */
87 /*-----------------------------------------------------------------*/
88 int pic16aopLiteral (value *val, int offset)
95 /* if it is a float then it gets tricky */
96 /* otherwise it is fairly simple */
97 if (!IS_FLOAT(val->type)) {
98 unsigned long v = (unsigned long) floatFromVal(val);
100 return ( (v >> (offset * 8)) & 0xff);
103 /* it is type float */
104 fl.f = (float) floatFromVal(val);
105 #ifdef WORDS_BIGENDIAN
106 return fl.c[3-offset];
115 char tbuffer[512], *tbuf=tbuffer;;
118 /*-----------------------------------------------------------------*/
119 /* emitRegularMap - emit code for maps with no special cases */
120 /*-----------------------------------------------------------------*/
122 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
125 // int i, size, bitvars = 0;;
127 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
130 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
131 /* print the area name */
133 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
136 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
138 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
139 IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
140 printTypeChain( sym->type, stderr );
141 fprintf(stderr, "\n");
144 /* if extern then add to externs */
145 if (IS_EXTERN (sym->etype)) {
146 /* reduce overhead while linking by not declaring
147 * extern unused external functions (usually declared
148 * in header files) */
149 if(IS_FUNC(sym->type) && !sym->used)continue;
151 /* make sure symbol is not in publics section */
152 if(!checkSym(publics, sym))
153 checkAddSym(&externs, sym);
157 /* if allocation required check is needed
158 * then check if the symbol really requires
159 * allocation only for local variables */
160 if (arFlag && !IS_AGGREGATE (sym->type) &&
161 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
162 !sym->allocreq && sym->level) {
164 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
169 /* if global variable & not static or extern
170 * and addPublics allowed then add it to the public set */
171 if ((sym->used) && (sym->level == 0 ||
172 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
174 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
176 checkAddSym(&publics, sym);
178 if(IS_STATIC(sym->etype)
179 && !(sym->ival && !sym->level)
184 #define SET_IMPLICIT 1
187 if(IS_STRUCT(sym->type))
191 reg = pic16_allocDirReg( operandFromSymbol( sym ));
195 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
196 if(!strcmp(ssym->name, reg->name))found=1;
200 checkAddReg(&pic16_rel_udata, reg);
202 checkAddSym(&publics, sym);
207 /* if extern then do nothing or is a function
209 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
210 if(SPEC_OCLS(sym->etype) == code) {
211 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
212 checkAddSym(&publics, sym);
218 /* print extra debug info if required */
219 if (options.debug || sym->level == 0) {
220 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
222 if (!sym->level) /* global */
223 if (IS_STATIC (sym->etype))
224 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
226 fprintf (map->oFile, "G_"); /* scope is global */
228 /* symbol is local */
229 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
230 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
235 /* if is has an absolute address then generate
236 an equate for this no need to allocate space */
237 if (SPEC_ABSA (sym->etype)) {
238 // if (options.debug || sym->level == 0)
239 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
240 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
242 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
244 SPEC_ADDR (sym->etype));
246 /* emit only if it is global */
247 if(sym->level == 0) {
250 reg = pic16_dirregWithName( sym->name );
253 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
254 // __FUNCTION__, __LINE__, sym->name);
256 /* if IS_STRUCT is omitted the following
257 * fixes structures but break char/int etc */
259 if(IS_STRUCT(sym->type))
260 sym->implicit = 1; // mark as implicit
263 reg = pic16_allocDirReg( operandFromSymbol(sym) );
265 if(checkAddReg(&pic16_fix_udata, reg)) {
266 /* and add to globals list if not exist */
267 addSet(&publics, sym);
271 addSet(&publics, sym);
275 if(!sym->used && (sym->level == 0)) {
278 /* symbol not used, just declared probably, but its in
279 * level 0, so we must declare it fine as global */
281 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
284 if(IS_STRUCT(sym->type))
285 sym->implicit = 1; // mark as implicit
288 if(IS_AGGREGATE(sym->type)) {
289 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
291 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
299 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
300 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
304 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
305 if(!strcmp(ssym->name, reg->name))found=1;
309 if(checkAddReg(&pic16_rel_udata, reg)) {
310 addSetHead(&publics, sym);
319 addSetHead(&publics, sym);
324 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
325 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
326 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
327 if (IS_BITVAR (sym->etype)) {
330 fprintf (map->oFile, "\t%s\n", sym->rname);
331 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
332 for (i = 1; i < size; i++)
333 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
336 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
340 /* FIXME -- VR Fix the following, so that syms to be placed
341 * in the idata section and let linker decide about their fate */
343 /* if it has an initial value then do it only if
344 it is a global variable */
346 if (sym->ival && sym->level == 0) {
350 if(SPEC_OCLS(sym->etype)==data) {
351 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
354 if(SPEC_OCLS(sym->etype)==code) {
355 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
360 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
361 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
364 if (IS_AGGREGATE (sym->type)) {
365 if(SPEC_ABSA(sym->etype))
366 addSet(&fix_idataSymSet, copySymbol(sym));
368 addSet(&rel_idataSymSet, copySymbol(sym));
369 // ival = initAggregates (sym, sym->ival, NULL);
371 if(SPEC_ABSA(sym->etype))
372 addSet(&fix_idataSymSet, copySymbol(sym));
374 addSet(&rel_idataSymSet, copySymbol(sym));
376 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
377 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
381 setAstLineno(ival, sym->lineDef);
382 codeOutFile = statsg->oFile;
384 eBBlockFromiCode (iCodeFromAst (ival));
392 /*-----------------------------------------------------------------*/
393 /* pic16_initPointer - pointer initialization code massaging */
394 /*-----------------------------------------------------------------*/
395 value *pic16_initPointer (initList * ilist, sym_link *toType)
401 return valCastLiteral(toType, 0.0);
404 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
405 // expr = list2expr( ilist );
410 /* try it the old way first */
411 if ((val = constExprValue (expr, FALSE)))
414 /* ( ptr + constant ) */
415 if (IS_AST_OP (expr) &&
416 (expr->opval.op == '+' || expr->opval.op == '-') &&
417 IS_AST_SYM_VALUE (expr->left) &&
418 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
419 compareType(toType, expr->left->ftype) &&
420 IS_AST_LIT_VALUE (expr->right)) {
421 return valForCastAggr (expr->left, expr->left->ftype,
427 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
428 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
429 if (compareType(toType, expr->left->ftype)!=1) {
430 werror (W_INIT_WRONG);
431 printFromToType(expr->left->ftype, toType);
437 /* no then we have to do these cludgy checks */
438 /* pointers can be initialized with address of
439 a variable or address of an array element */
440 if (IS_AST_OP (expr) && expr->opval.op == '&') {
441 /* address of symbol */
442 if (IS_AST_SYM_VALUE (expr->left)) {
443 val = copyValue (AST_VALUE (expr->left));
444 val->type = newLink (DECLARATOR);
445 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
446 DCL_TYPE (val->type) = CPOINTER;
447 DCL_PTR_CONST (val->type) = port->mem.code_ro;
449 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
450 DCL_TYPE (val->type) = FPOINTER;
451 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
452 DCL_TYPE (val->type) = PPOINTER;
453 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
454 DCL_TYPE (val->type) = IPOINTER;
455 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
456 DCL_TYPE (val->type) = EEPPOINTER;
458 DCL_TYPE (val->type) = POINTER;
460 val->type->next = expr->left->ftype;
461 val->etype = getSpec (val->type);
465 /* if address of indexed array */
466 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
467 return valForArray (expr->left);
469 /* if address of structure element then
471 if (IS_AST_OP (expr->left) &&
472 expr->left->opval.op == '.') {
473 return valForStructElem (expr->left->left,
478 (&some_struct)->element */
479 if (IS_AST_OP (expr->left) &&
480 expr->left->opval.op == PTR_OP &&
481 IS_ADDRESS_OF_OP (expr->left->left)) {
482 return valForStructElem (expr->left->left->left,
486 /* case 3. (((char *) &a) +/- constant) */
487 if (IS_AST_OP (expr) &&
488 (expr->opval.op == '+' || expr->opval.op == '-') &&
489 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
490 IS_AST_OP (expr->left->right) &&
491 expr->left->right->opval.op == '&' &&
492 IS_AST_LIT_VALUE (expr->right)) {
494 return valForCastAggr (expr->left->right->left,
495 expr->left->left->opval.lnk,
496 expr->right, expr->opval.op);
499 /* case 4. (char *)(array type) */
500 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
501 IS_ARRAY(expr->right->ftype)) {
503 val = copyValue (AST_VALUE (expr->right));
504 val->type = newLink (DECLARATOR);
505 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
506 DCL_TYPE (val->type) = CPOINTER;
507 DCL_PTR_CONST (val->type) = port->mem.code_ro;
509 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
510 DCL_TYPE (val->type) = FPOINTER;
511 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
512 DCL_TYPE (val->type) = PPOINTER;
513 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
514 DCL_TYPE (val->type) = IPOINTER;
515 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
516 DCL_TYPE (val->type) = EEPPOINTER;
518 DCL_TYPE (val->type) = POINTER;
519 val->type->next = expr->right->ftype->next;
520 val->etype = getSpec (val->type);
526 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
528 werror (E_INCOMPAT_PTYPES);
534 /*-----------------------------------------------------------------*/
535 /* printPointerType - generates ival for pointer type */
536 /*-----------------------------------------------------------------*/
537 void _pic16_printPointerType (const char *name, char ptype, void *p)
541 sprintf(buf, "LOW(%s)", name);
542 pic16_emitDS(buf, ptype, p);
543 sprintf(buf, "HIGH(%s)", name);
544 pic16_emitDS(buf, ptype, p);
547 /*-----------------------------------------------------------------*/
548 /* printPointerType - generates ival for pointer type */
549 /*-----------------------------------------------------------------*/
550 void pic16_printPointerType (const char *name, char ptype, void *p)
552 _pic16_printPointerType (name, ptype, p);
553 pic16_flushDB(ptype, p);
556 /*-----------------------------------------------------------------*/
557 /* printGPointerType - generates ival for generic pointer type */
558 /*-----------------------------------------------------------------*/
559 void pic16_printGPointerType (const char *iname, const unsigned int itype,
564 _pic16_printPointerType (iname, ptype, p);
571 sprintf(buf, "UPPER(%s)", iname);
572 pic16_emitDS(buf, ptype, p);
576 sprintf(buf, "0x80");
577 pic16_emitDS(buf, ptype, p);
580 debugf("itype = %d\n", itype );
584 pic16_flushDB(ptype, p);
588 /* set to 0 to disable debug messages */
589 #define DEBUG_PRINTIVAL 0
591 /*-----------------------------------------------------------------*/
592 /* pic16_printIvalType - generates ival for int/char */
593 /*-----------------------------------------------------------------*/
595 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
599 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
602 fprintf(stderr, "%s\n",__FUNCTION__);
606 /* if initList is deep */
607 if (ilist && ilist->type == INIT_DEEP)
608 ilist = ilist->init.deep;
610 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
611 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
614 if (!(val = list2val (ilist))) {
615 // assuming a warning has been thrown
619 if (val->type != type) {
620 val = valCastLiteral(type, floatFromVal(val));
623 switch (getSize (type)) {
625 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
629 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
630 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
633 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
634 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
635 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
637 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
638 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
639 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
640 pic16_emitDB(pic16aopLiteral(val, 3), ptype, p);
645 /*--------------------------------------------------------------------*/
646 /* pic16_printIvalChar - generates initital value for character array */
647 /*--------------------------------------------------------------------*/
649 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
658 fprintf(stderr, "%s\n",__FUNCTION__);
662 val = list2val (ilist);
663 /* if the value is a character string */
664 if(IS_ARRAY (val->type) && IS_CHAR (val->etype)) {
666 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
668 for(remain=0; remain<strlen(SPEC_CVAL(val->etype).v_char)+1; remain++)
669 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
671 if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
673 pic16_emitDB(0x00, ptype, p);
679 for(remain=0; remain<strlen(s); remain++) {
680 pic16_emitDB(s[remain], ptype, p);
686 /*-----------------------------------------------------------------*/
687 /* pic16_printIvalArray - generates code for array initialization */
688 /*-----------------------------------------------------------------*/
690 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
694 int lcnt = 0, size = 0;
701 fprintf(stderr, "%s\n",__FUNCTION__);
703 /* take care of the special case */
704 /* array of characters can be init */
706 if (IS_CHAR (type->next)) {
707 if (!IS_LITERAL(list2val(ilist)->etype)) {
708 werror (W_INIT_WRONG);
712 if(pic16_printIvalChar (type,
713 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
714 SPEC_CVAL (sym->etype).v_char, ptype, p))
717 /* not the special case */
718 if (ilist && ilist->type != INIT_DEEP)
720 werror (E_INIT_STRUCT, sym->name);
724 iloop = ilist->init.deep;
725 lcnt = DCL_ELEM (type);
730 pic16_printIval (sym, type->next, iloop, ptype, p);
731 iloop = (iloop ? iloop->next : NULL);
734 /* if not array limits given & we */
735 /* are out of initialisers then */
736 if (!DCL_ELEM (type) && !iloop)
739 /* no of elements given and we */
740 /* have generated for all of them */
742 /* if initializers left */
744 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
750 /* if we have not been given a size */
751 if (!DCL_ELEM (type))
752 DCL_ELEM (type) = size;
757 /*-----------------------------------------------------------------*/
758 /* pic16_printIvalBitFields - generate initializer for bitfields */
759 /*-----------------------------------------------------------------*/
760 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
764 initList *lilist = *ilist ;
765 unsigned long ival = 0;
770 fprintf(stderr, "%s\n",__FUNCTION__);
776 val = list2val(lilist);
778 if (SPEC_BLEN(lsym->etype) > 8) {
779 size += ((SPEC_BLEN (lsym->etype) / 8) +
780 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
783 size = ((SPEC_BLEN (lsym->etype) / 8) +
784 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
786 i = (unsigned long)floatFromVal(val);
787 i <<= SPEC_BSTR (lsym->etype);
789 if (! ( lsym->next &&
790 (IS_BITFIELD(lsym->next->type)) &&
791 (SPEC_BSTR(lsym->next->etype)))) break;
793 lilist = lilist->next;
797 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
801 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
802 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
805 case 4: /* EEP: why is this db and not dw? */
806 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
807 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
808 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
809 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
812 /* VR - only 1,2,4 size long can be handled???? Why? */
813 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
821 /*-----------------------------------------------------------------*/
822 /* printIvalStruct - generates initial value for structures */
823 /*-----------------------------------------------------------------*/
824 void pic16_printIvalStruct (symbol * sym, sym_link * type,
825 initList * ilist, char ptype, void *p)
828 initList *iloop = NULL;
832 fprintf(stderr, "%s\n",__FUNCTION__);
835 sflds = SPEC_STRUCT (type)->fields;
838 if (ilist->type != INIT_DEEP) {
839 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
843 iloop = ilist->init.deep;
846 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
847 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
848 if (IS_BITFIELD(sflds->type)) {
849 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
851 pic16_printIval (sym, sflds->type, iloop, ptype, p);
855 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
860 /*--------------------------------------------------------------------------*/
861 /* pic16_printIvalCharPtr - generates initial values for character pointers */
862 /*--------------------------------------------------------------------------*/
863 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
867 /* PENDING: this is _very_ mcs51 specific, including a magic
869 It's also endin specific.
871 VR - Attempting to port this function to pic16 port - 8-Jun-2004
876 fprintf(stderr, "%s\n",__FUNCTION__);
879 size = getSize (type);
881 if (val->name && strlen (val->name))
883 if (size == 1) /* This appears to be Z80 specific?? */
885 pic16_emitDS(val->name, ptype, p);
889 pic16_printPointerType (val->name, ptype, p);
894 if (IS_PTR (val->type)) {
895 type = DCL_TYPE (val->type);
897 type = PTR_TYPE (SPEC_OCLS (val->etype));
899 if (val->sym && val->sym->isstrlit) {
900 // this is a literal string
903 pic16_printGPointerType(val->name, type, ptype, p);
907 fprintf (stderr, "*** internal error: unknown size in "
908 "printIvalCharPtr.\n");
914 // these are literals assigned to pointers
918 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
921 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
922 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
925 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
926 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
927 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
935 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
936 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
937 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
943 /*-----------------------------------------------------------------------*/
944 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
945 /*-----------------------------------------------------------------------*/
946 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
953 fprintf(stderr, "%s\n",__FUNCTION__);
957 val = list2val (ilist);
959 val = valCastLiteral(type, 0.0);
962 // an error has been thrown already
966 if (IS_LITERAL(val->etype)) {
967 if (compareType(type, val->etype) == 0) {
968 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
969 printFromToType (val->type, type);
971 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
975 /* check the types */
976 if ((dLvl = compareType (val->type, type->next)) <= 0)
978 pic16_emitDB(0x00, ptype, p);
982 /* now generate the name */
984 pic16_printGPointerType (val->name, DCL_TYPE(val->type), ptype, p);
986 pic16_printGPointerType (val->sym->rname, DCL_TYPE(val->type), ptype, p);
988 if(IS_FUNC(val->sym->type) && !val->sym->used && !IS_STATIC(val->sym->etype)) {
990 if(!checkSym(publics, val->sym))
991 if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
992 /* this has not been declared as extern
993 * so declare it as a 'late extern' just after the symbol */
994 fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
995 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
996 fprintf((FILE *)p, ";\tcontinue variable declaration\n");
1005 /*-----------------------------------------------------------------*/
1006 /* pic16_printIvalPtr - generates initial value for pointers */
1007 /*-----------------------------------------------------------------*/
1008 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1014 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1015 sym->rname, getSize(sym->type));
1019 if (ilist && (ilist->type == INIT_DEEP))
1020 ilist = ilist->init.deep;
1022 /* function pointer */
1023 if (IS_FUNC (type->next))
1025 pic16_printIvalFuncPtr (type, ilist, ptype, p);
1029 if (!(val = pic16_initPointer (ilist, type)))
1032 /* if character pointer */
1033 if (IS_CHAR (type->next))
1034 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1037 /* check the type */
1038 if (compareType (type, val->type) == 0) {
1039 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1040 printFromToType (val->type, type);
1043 /* if val is literal */
1044 if (IS_LITERAL (val->etype))
1046 switch (getSize (type))
1049 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1052 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1053 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1056 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1057 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1058 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1061 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1068 size = getSize (type);
1070 if (size == 1) /* Z80 specific?? */
1072 pic16_emitDS(val->name, ptype, p);
1076 pic16_printPointerType (val->name, ptype, p);
1080 pic16_printGPointerType (val->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1089 /*-----------------------------------------------------------------*/
1090 /* pic16_printIval - generates code for initial value */
1091 /*-----------------------------------------------------------------*/
1092 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1100 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1101 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1102 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1105 /* if structure then */
1106 if (IS_STRUCT (type))
1108 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1109 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1113 /* if this is an array */
1114 if (IS_ARRAY (type))
1116 // fprintf(stderr,"%s array\n",__FUNCTION__);
1117 pic16_printIvalArray (sym, type, ilist, ptype, p);
1124 // not an aggregate, ilist must be a node
1125 if (ilist->type!=INIT_NODE) {
1126 // or a 1-element list
1127 if (ilist->init.deep->next) {
1128 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1131 ilist=ilist->init.deep;
1136 // and the type must match
1137 itype=ilist->init.node->ftype;
1139 if (compareType(type, itype)==0) {
1140 // special case for literal strings
1141 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1142 // which are really code pointers
1143 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1146 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1147 // printFromToType(itype, type);
1154 /* if this is a pointer */
1157 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1158 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1163 /* if type is SPECIFIER */
1166 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1167 pic16_printIvalType (sym, type, ilist, ptype, p);
1172 int PIC16_IS_CONFIG_ADDRESS(int address)
1174 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1177 int PIC16_IS_IDLOC_ADDRESS(int address)
1179 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1182 /* wrapper function for the above */
1183 int PIC16_IS_HWREG_ADDRESS(int address)
1185 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1189 /*-----------------------------------------------------------------*/
1190 /* emitStaticSeg - emitcode for the static segment */
1191 /*-----------------------------------------------------------------*/
1193 pic16emitStaticSeg (memmap * map)
1196 static int didcode=0;
1198 //fprintf(stderr, "%s\n",__FUNCTION__);
1202 /* for all variables in this segment do */
1203 for (sym = setFirstItem (map->syms); sym;
1204 sym = setNextItem (map->syms))
1208 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1209 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1210 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1211 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1212 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1213 printTypeChain( sym->type, stderr );
1214 fprintf(stderr, "\n");
1217 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1218 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1219 (int) floatFromVal(list2val(sym->ival)));
1224 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1225 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1226 (char) floatFromVal(list2val(sym->ival)));
1231 /* if it is "extern" then do nothing */
1232 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1233 checkAddSym(&externs, sym);
1237 /* if it is not static add it to the public
1239 if (!IS_STATIC (sym->etype)) {
1240 /* do not emit if it is a config word declaration */
1241 checkAddSym(&publics, sym);
1244 /* print extra debug info if required */
1245 if (options.debug || sym->level == 0) {
1246 /* NOTE to me - cdbFile may be null in which case,
1247 * the sym name will be printed to stdout. oh well */
1248 debugFile->writeSymbol(sym);
1251 /* if it has an absolute address */
1252 if (SPEC_ABSA (sym->etype)) {
1253 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1254 // __FILE__, __LINE__, sym->name);
1256 /* if it has an initial value */
1264 /* symbol has absolute address and initial value */
1266 resolveIvalSym (sym->ival, sym->type);
1267 asym = newSymbol(sym->rname, 0);
1268 abSym = Safe_calloc(1, sizeof(absSym));
1269 strcpy(abSym->name, sym->rname);
1270 abSym->address = SPEC_ADDR( sym->etype );
1271 addSet(&absSymSet, abSym);
1273 pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1274 pic16_addpBlock(pb);
1276 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1277 PCF(pcf)->absblock = 1;
1279 pic16_addpCode2pBlock(pb,pcf);
1280 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1281 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1282 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1283 pic16_flushDB('p', (void *)pb);
1285 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1291 /* symbol has absolute address but no initial value */
1293 /* allocate space */
1294 fprintf (code->oFile, "%s:\n", sym->rname);
1296 /* special case for character strings */
1297 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1298 SPEC_CVAL (sym->etype).v_char) {
1300 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1302 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1309 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1310 // __FILE__, __LINE__, sym->name);
1313 /* if it has an initial value */
1317 /* symbol doesn't have absolute address but has initial value */
1318 fprintf (code->oFile, "%s:\n", sym->rname);
1320 resolveIvalSym (sym->ival, sym->type);
1322 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1323 pic16_addpBlock(pb);
1326 /* make sure that 'code' directive is emitted before, once */
1327 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1332 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1334 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1335 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1336 pic16_flushDB('p', (void *)pb);
1340 /* symbol doesn't have absolute address and no initial value */
1341 /* allocate space */
1342 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1343 fprintf (code->oFile, "%s:\n", sym->rname);
1344 /* special case for character strings */
1345 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1346 SPEC_CVAL (sym->etype).v_char) {
1348 // fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
1350 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1361 /*-----------------------------------------------------------------*/
1362 /* pic16_emitConfigRegs - emits the configuration registers */
1363 /*-----------------------------------------------------------------*/
1364 void pic16_emitConfigRegs(FILE *of)
1368 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1369 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1370 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1371 pic16->cwInfo.confAddrStart+i,
1372 pic16->cwInfo.crInfo[i].value);
1375 void pic16_emitIDRegs(FILE *of)
1379 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1380 if(pic16->idInfo.irInfo[i].emit)
1381 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1382 pic16->idInfo.idAddrStart+i,
1383 pic16->idInfo.irInfo[i].value);
1390 /* no special considerations for the following
1391 data, idata & bit & xdata */
1392 pic16emitRegularMap (data, TRUE, TRUE);
1393 pic16emitRegularMap (idata, TRUE, TRUE);
1394 pic16emitRegularMap (bit, TRUE, FALSE);
1395 pic16emitRegularMap (xdata, TRUE, TRUE);
1396 pic16emitRegularMap (sfr, FALSE, FALSE);
1397 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1398 pic16emitRegularMap (code, TRUE, FALSE);
1399 pic16emitStaticSeg (statsg);
1402 /*-----------------------------------------------------------------*/
1403 /* createInterruptVect - creates the interrupt vector */
1404 /*-----------------------------------------------------------------*/
1406 pic16createInterruptVect (FILE * vFile)
1408 /* if the main is only a prototype ie. no body then do nothing */
1410 if (!IFFUNC_HASBODY(mainf->type)) {
1411 /* if ! compile only then main function should be present */
1412 if (!options.cc_only)
1418 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1419 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1420 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1422 /* this is an overkill since WE are the port,
1423 * and we know if we have a genIVT function! */
1425 port->genIVT(vFile, interrupts, maxInterrupts);
1432 /*-----------------------------------------------------------------*/
1433 /* pic16initialComments - puts in some initial comments */
1434 /*-----------------------------------------------------------------*/
1436 pic16initialComments (FILE * afile)
1438 initialComments (afile);
1439 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1440 if(pic16_mplab_comp)
1441 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1442 fprintf (afile, iComments2);
1445 fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n",
1446 SDCC_VERSION_STR, getBuildNumber() );
1450 /*-----------------------------------------------------------------*/
1451 /* printPublics - generates global declarations for publics */
1452 /*-----------------------------------------------------------------*/
1454 pic16printPublics (FILE *afile)
1458 fprintf (afile, "\n%s", iComments2);
1459 fprintf (afile, "; public variables in this module\n");
1460 fprintf (afile, "%s", iComments2);
1462 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1463 fprintf(afile, "\tglobal %s\n", sym->rname);
1466 /*-----------------------------------------------------------------*/
1467 /* printExterns - generates extern declarations for externs */
1468 /*-----------------------------------------------------------------*/
1470 pic16_printExterns(FILE *afile)
1474 /* print nothing if no externs to declare */
1475 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1478 fprintf(afile, "\n%s", iComments2);
1479 fprintf(afile, "; extern variables in this module\n");
1480 fprintf(afile, "%s", iComments2);
1482 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1483 fprintf(afile, "\textern %s\n", sym->rname);
1485 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1486 fprintf(afile, "\textern _%s\n", sym->name);
1489 /*-----------------------------------------------------------------*/
1490 /* emitOverlay - will emit code for the overlay stuff */
1491 /*-----------------------------------------------------------------*/
1493 pic16emitOverlay (FILE * afile)
1497 if (!elementsInSet (ovrSetSets))
1498 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1500 /* for each of the sets in the overlay segment do */
1501 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1502 ovrset = setNextItem (ovrSetSets))
1507 if (elementsInSet (ovrset))
1509 /* this dummy area is used to fool the assembler
1510 otherwise the assembler will append each of these
1511 declarations into one chunk and will not overlay
1513 fprintf (afile, ";\t.area _DUMMY\n");
1514 /* output the area informtion */
1515 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1518 for (sym = setFirstItem (ovrset); sym;
1519 sym = setNextItem (ovrset))
1522 /* if extern then do nothing */
1523 if (IS_EXTERN (sym->etype))
1526 /* if allocation required check is needed
1527 then check if the symbol really requires
1528 allocation only for local variables */
1529 if (!IS_AGGREGATE (sym->type) &&
1530 !(sym->_isparm && !IS_REGPARM (sym->etype))
1531 && !sym->allocreq && sym->level)
1534 /* if global variable & not static or extern
1535 and addPublics allowed then add it to the public set */
1536 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1537 && !IS_STATIC (sym->etype)) {
1538 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1539 checkAddSym(&publics, sym);
1540 // addSetHead (&publics, sym);
1543 /* if extern then do nothing or is a function
1545 if (IS_FUNC (sym->type))
1549 /* print extra debug info if required */
1550 if (options.debug || sym->level == 0)
1553 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1557 if (IS_STATIC (sym->etype))
1558 fprintf (afile, "F%s_", moduleName); /* scope is file */
1560 fprintf (afile, "G_"); /* scope is global */
1563 /* symbol is local */
1564 fprintf (afile, "L%s_",
1565 (sym->localof ? sym->localof->name : "-null-"));
1566 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1570 /* if is has an absolute address then generate
1571 an equate for this no need to allocate space */
1572 if (SPEC_ABSA (sym->etype))
1575 if (options.debug || sym->level == 0)
1576 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1578 fprintf (afile, "%s\t=\t0x%04x\n",
1580 SPEC_ADDR (sym->etype));
1584 if (options.debug || sym->level == 0)
1585 fprintf (afile, "==.\n");
1587 /* allocate space */
1588 fprintf (afile, "%s:\n", sym->rname);
1589 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1596 void emitStatistics(FILE *asmFile)
1598 statistics.isize = pic16_countInstructions();
1600 fprintf (asmFile, "\n\n; Statistics:\n");
1601 fprintf (asmFile, "; code size:\t%ld (0x%lx) bytes\n;\t\t%ld (0x%lx) words\n",
1602 statistics.isize, statistics.isize,
1603 statistics.isize>>1, statistics.isize>>1);
1604 fprintf (asmFile, "; udata size:\t%ld (0x%lx) bytes\n",
1605 statistics.udsize, statistics.udsize);
1606 fprintf (asmFile, "; access size:\t%ld (0x%lx) bytes\n",
1607 statistics.intsize, statistics.intsize);
1609 fprintf (asmFile, "\n\n");
1614 /*-----------------------------------------------------------------*/
1615 /* glue - the final glue that hold the whole thing together */
1616 /*-----------------------------------------------------------------*/
1622 FILE *ovrFile = tempfile();
1624 mainf = newSymbol ("main", 0);
1627 mainf = findSymWithLevel(SymbolTab, mainf);
1629 addSetHead(&tmpfileSet,ovrFile);
1630 pic16_pCodeInitRegisters();
1632 if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1633 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1635 pic16_addpBlock(pb);
1637 /* entry point @ start of CSEG */
1638 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1641 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1642 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1643 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1644 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1647 /* put in the call to main */
1648 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1650 if (options.mainreturn) {
1651 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1652 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1654 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1655 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1659 /* At this point we've got all the code in the form of pCode structures */
1660 /* Now it needs to be rearranged into the order it should be placed in the */
1663 pic16_movepBlock2Head('P'); // Last
1664 pic16_movepBlock2Head(code->dbName);
1665 pic16_movepBlock2Head('X');
1666 pic16_movepBlock2Head(statsg->dbName); // First
1668 /* print the global struct definitions */
1671 /* PENDING: this isnt the best place but it will do */
1672 if (port->general.glue_up_main) {
1673 /* create the interrupt vector table */
1674 pic16createInterruptVect (vFile);
1677 addSetHead(&tmpfileSet,vFile);
1679 /* emit code for the all the variables declared */
1682 /* do the overlay segments */
1683 pic16emitOverlay(ovrFile);
1684 pic16_AnalyzepCode('*');
1687 if(pic16_options.dumpcalltree) {
1690 sprintf(buffer, dstFileName);
1691 strcat(buffer, ".calltree");
1692 cFile = fopen(buffer, "w");
1693 pic16_printCallTree( cFile );
1698 pic16_InlinepCode();
1699 pic16_AnalyzepCode('*');
1702 if(pic16_debug_verbose)
1705 /* now put it all together into the assembler file */
1706 /* create the assembler file name */
1707 if((noAssemble || options.c1mode) && fullDstFileName) {
1708 sprintf (buffer, fullDstFileName);
1710 sprintf (buffer, dstFileName);
1711 strcat (buffer, ".asm");
1714 if(!(asmFile = fopen (buffer, "w"))) {
1715 werror (E_FILE_OPEN_ERR, buffer);
1719 /* initial comments */
1720 pic16initialComments (asmFile);
1722 /* print module name */
1724 fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
1726 /* Let the port generate any global directives, etc. */
1727 if(port->genAssemblerPreamble) {
1728 port->genAssemblerPreamble(asmFile);
1731 /* Put all variables into a cblock */
1732 pic16_AnalyzeBanking();
1734 if(pic16_options.opt_flags & OF_LR_SUPPORT) {
1735 pic16_OptimizeLocalRegs();
1738 /* turn GOTOs into BRAs -- added by RN 2004-11-16 */
1739 if(pic16_options.opt_flags & OF_OPTIMIZE_GOTO) {
1740 pic16_OptimizeJumps();
1743 /* print the extern variables to this module */
1744 pic16_printExterns(asmFile);
1746 /* print the global variables in this module */
1747 pic16printPublics (asmFile);
1749 pic16_writeUsedRegs(asmFile);
1752 /* no xdata in pic */
1753 /* if external stack then reserve space of it */
1754 if(mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1755 fprintf (asmFile, "%s", iComments2);
1756 fprintf (asmFile, "; external stack \n");
1757 fprintf (asmFile, "%s", iComments2);
1758 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1759 fprintf (asmFile,";\t.ds 256\n");
1764 /* no xdata in pic */
1765 /* copy xtern ram data */
1766 fprintf (asmFile, "%s", iComments2);
1767 fprintf (asmFile, "; external ram data\n");
1768 fprintf (asmFile, "%s", iComments2);
1769 copyFile (asmFile, xdata->oFile);
1773 /* copy the bit segment */
1774 fprintf (asmFile, "%s", iComments2);
1775 fprintf (asmFile, "; bit data\n");
1776 fprintf (asmFile, "%s", iComments2);
1777 copyFile (asmFile, bit->oFile);
1780 /* copy the interrupt vector table */
1781 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1782 fprintf (asmFile, "\n%s", iComments2);
1783 fprintf (asmFile, "; interrupt vector \n");
1784 fprintf (asmFile, "%s", iComments2);
1785 copyFile (asmFile, vFile);
1788 /* copy global & static initialisations */
1789 fprintf (asmFile, "\n%s", iComments2);
1790 fprintf (asmFile, "; global & static initialisations\n");
1791 fprintf (asmFile, "%s", iComments2);
1793 if(pic16_debug_verbose)
1794 fprintf(asmFile, "; A code from now on!\n");
1796 pic16_copypCode(asmFile, 'A');
1798 if(pic16_options.no_crt) {
1799 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1800 fprintf(asmFile, "\tcode\n");
1801 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1805 // copyFile (stderr, code->oFile);
1807 fprintf(asmFile, "; I code from now on!\n");
1808 pic16_copypCode(asmFile, 'I');
1810 if(pic16_debug_verbose)
1811 fprintf(asmFile, "; dbName from now on!\n");
1813 pic16_copypCode(asmFile, statsg->dbName);
1815 if(pic16_options.no_crt) {
1816 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1817 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1821 if(pic16_debug_verbose)
1822 fprintf(asmFile, "; X code from now on!\n");
1824 pic16_copypCode(asmFile, 'X');
1826 if(pic16_debug_verbose)
1827 fprintf(asmFile, "; M code from now on!\n");
1829 pic16_copypCode(asmFile, 'M');
1831 pic16_copypCode(asmFile, code->dbName);
1833 pic16_copypCode(asmFile, 'P');
1835 emitStatistics(asmFile);
1837 fprintf (asmFile,"\tend\n");