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;
60 //extern void emitStaticSeg (memmap * map);
64 set *rel_idataSymSet=NULL;
65 set *fix_idataSymSet=NULL;
67 extern DEFSETFUNC (closeTmpFiles);
68 extern DEFSETFUNC (rmTmpFiles);
70 extern void pic16_AnalyzeBanking (void);
71 extern void copyFile (FILE * dest, FILE * src);
72 extern void pic16_InlinepCode(void);
73 extern void pic16_writeUsedRegs(FILE *);
75 extern void initialComments (FILE * afile);
76 extern void printPublics (FILE * afile);
78 void pic16_pCodeInitRegisters(void);
79 pCodeOp *pic16_popGetLit(unsigned int lit);
80 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2);
81 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
82 extern void pic16_pCodeConstString(char *name, char *value);
84 /*-----------------------------------------------------------------*/
85 /* aopLiteral - string from a literal value */
86 /*-----------------------------------------------------------------*/
87 int pic16aopLiteral (value *val, int offset)
94 /* if it is a float then it gets tricky */
95 /* otherwise it is fairly simple */
96 if (!IS_FLOAT(val->type)) {
97 unsigned long v = (unsigned long) floatFromVal(val);
99 return ( (v >> (offset * 8)) & 0xff);
102 /* it is type float */
103 fl.f = (float) floatFromVal(val);
104 #ifdef WORDS_BIGENDIAN
105 return fl.c[3-offset];
114 char tbuffer[512], *tbuf=tbuffer;;
117 /*-----------------------------------------------------------------*/
118 /* emitRegularMap - emit code for maps with no special cases */
119 /*-----------------------------------------------------------------*/
121 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
124 // int i, size, bitvars = 0;;
126 // fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
129 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
130 /* print the area name */
132 for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
135 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
137 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
138 IS_AGGREGATE(sym->type), SPEC_SCLS(sym->etype), IS_FUNC(sym->type));
139 printTypeChain( sym->type, stderr );
140 fprintf(stderr, "\n");
143 /* if extern then add to externs */
144 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 checkAddSym(&externs, sym);
155 /* if allocation required check is needed
156 * then check if the symbol really requires
157 * allocation only for local variables */
158 if (arFlag && !IS_AGGREGATE (sym->type) &&
159 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
160 !sym->allocreq && sym->level) {
162 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
167 /* if global variable & not static or extern
168 * and addPublics allowed then add it to the public set */
169 if ((sym->used) && (sym->level == 0 ||
170 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
172 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
174 checkAddSym(&publics, sym);
176 if(IS_STATIC(sym->etype)
177 && !(sym->ival && !sym->level)
180 /* add it to udata list */
182 // fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
183 // sym->name, sym->rname, sym->remat);
185 //, OP_SYMBOL(operandFromSymbol(sym))->name);
186 #define SET_IMPLICIT 1
189 if(IS_STRUCT(sym->type))
193 reg = pic16_allocDirReg( operandFromSymbol( sym ));
200 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
201 if(!strcmp(ssym->name, reg->name))found=1;
205 if(!found)checkAddReg(&pic16_rel_udata, reg);
209 /* if extern then do nothing or is a function
211 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
212 if(SPEC_OCLS(sym->etype) == code) {
213 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
214 checkAddSym(&publics, sym);
220 /* print extra debug info if required */
221 if (options.debug || sym->level == 0) {
222 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
224 if (!sym->level) /* global */
225 if (IS_STATIC (sym->etype))
226 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
228 fprintf (map->oFile, "G_"); /* scope is global */
230 /* symbol is local */
231 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
232 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
237 /* if is has an absolute address then generate
238 an equate for this no need to allocate space */
239 if (SPEC_ABSA (sym->etype)) {
240 // if (options.debug || sym->level == 0)
241 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
242 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
244 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
246 SPEC_ADDR (sym->etype));
248 /* emit only if it is global */
249 if(sym->level == 0) {
252 reg = pic16_dirregWithName( sym->name );
255 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
256 // __FUNCTION__, __LINE__, sym->name);
258 /* if IS_STRUCT is omitted the following
259 * fixes structures but break char/int etc */
261 if(IS_STRUCT(sym->type))
262 sym->implicit = 1; // mark as implicit
265 reg = pic16_allocDirReg( operandFromSymbol(sym) );
267 if(checkAddReg(&pic16_fix_udata, reg)) {
268 /* and add to globals list if not exist */
269 addSet(&publics, sym);
273 addSet(&publics, sym);
277 if(!sym->used && (sym->level == 0)) {
280 /* symbol not used, just declared probably, but its in
281 * level 0, so we must declare it fine as global */
283 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
286 if(IS_STRUCT(sym->type))
287 sym->implicit = 1; // mark as implicit
290 if(IS_AGGREGATE(sym->type)) {
291 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
293 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
300 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
301 sym->rname, reg, (reg?reg->name:"<<NULL>>"));
303 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
304 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_CHECK));
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 char *oname, const unsigned int itype,
560 const unsigned int type, char ptype, void *p)
562 _pic16_printPointerType (iname, ptype, p);
564 if(itype == FPOINTER || itype == CPOINTER) { // || itype == GPOINTER) {
567 sprintf(buf, "UPPER(%s)", iname);
568 pic16_emitDS(buf, ptype, p);
571 pic16_flushDB(ptype, p);
575 /* set to 0 to disable debug messages */
576 #define DEBUG_PRINTIVAL 1
578 /*-----------------------------------------------------------------*/
579 /* pic16_printIvalType - generates ival for int/char */
580 /*-----------------------------------------------------------------*/
582 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
587 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
590 fprintf(stderr, "%s\n",__FUNCTION__);
594 /* if initList is deep */
595 if (ilist && ilist->type == INIT_DEEP)
596 ilist = ilist->init.deep;
598 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
599 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
602 if (!(val = list2val (ilist))) {
603 // assuming a warning has been thrown
607 if (val->type != type) {
608 val = valCastLiteral(type, floatFromVal(val));
612 ulval = (unsigned long) floatFromVal (val);
616 switch (getSize (type)) {
618 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
622 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
623 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
627 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
628 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
629 pic16_emitDB(BYTE_IN_LONG(ulval,2), ptype, p);
630 pic16_emitDB(BYTE_IN_LONG(ulval,3), ptype, p);
635 /*--------------------------------------------------------------------*/
636 /* pic16_printIvalChar - generates initital value for character array */
637 /*--------------------------------------------------------------------*/
639 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
648 fprintf(stderr, "%s\n",__FUNCTION__);
654 val = list2val (ilist);
655 /* if the value is a character string */
656 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
658 if (!DCL_ELEM (type))
659 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
661 for(remain=0; remain<DCL_ELEM(type); remain++)
662 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
664 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
666 pic16_emitDB(0x00, ptype, p);
675 for(remain=0; remain<strlen(s); remain++) {
676 pic16_emitDB(s[remain], ptype, p);
682 /*-----------------------------------------------------------------*/
683 /* pic16_printIvalArray - generates code for array initialization */
684 /*-----------------------------------------------------------------*/
686 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
690 int lcnt = 0, size = 0;
697 fprintf(stderr, "%s\n",__FUNCTION__);
699 /* take care of the special case */
700 /* array of characters can be init */
702 if (IS_CHAR (type->next)) {
703 if (!IS_LITERAL(list2val(ilist)->etype)) {
704 werror (W_INIT_WRONG);
708 if(pic16_printIvalChar (type,
709 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
710 SPEC_CVAL (sym->etype).v_char, ptype, p))
713 /* not the special case */
714 if (ilist && ilist->type != INIT_DEEP)
716 werror (E_INIT_STRUCT, sym->name);
720 iloop = ilist->init.deep;
721 lcnt = DCL_ELEM (type);
726 pic16_printIval (sym, type->next, iloop, ptype, p);
727 iloop = (iloop ? iloop->next : NULL);
730 /* if not array limits given & we */
731 /* are out of initialisers then */
732 if (!DCL_ELEM (type) && !iloop)
735 /* no of elements given and we */
736 /* have generated for all of them */
738 /* if initializers left */
740 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
746 /* if we have not been given a size */
747 if (!DCL_ELEM (type))
748 DCL_ELEM (type) = size;
753 /*-----------------------------------------------------------------*/
754 /* pic16_printIvalBitFields - generate initializer for bitfields */
755 /*-----------------------------------------------------------------*/
756 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
760 initList *lilist = *ilist ;
761 unsigned long ival = 0;
766 fprintf(stderr, "%s\n",__FUNCTION__);
772 val = list2val(lilist);
774 if (SPEC_BLEN(lsym->etype) > 8) {
775 size += ((SPEC_BLEN (lsym->etype) / 8) +
776 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
779 size = ((SPEC_BLEN (lsym->etype) / 8) +
780 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
782 i = (unsigned long)floatFromVal(val);
783 i <<= SPEC_BSTR (lsym->etype);
785 if (! ( lsym->next &&
786 (IS_BITFIELD(lsym->next->type)) &&
787 (SPEC_BSTR(lsym->next->etype)))) break;
789 lilist = lilist->next;
793 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
797 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
798 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
801 case 4: /* EEP: why is this db and not dw? */
802 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
803 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
804 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
805 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
808 /* VR - only 1,2,4 size long can be handled???? Why? */
809 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
817 /*-----------------------------------------------------------------*/
818 /* printIvalStruct - generates initial value for structures */
819 /*-----------------------------------------------------------------*/
820 void pic16_printIvalStruct (symbol * sym, sym_link * type,
821 initList * ilist, char ptype, void *p)
824 initList *iloop = NULL;
828 fprintf(stderr, "%s\n",__FUNCTION__);
831 sflds = SPEC_STRUCT (type)->fields;
834 if (ilist->type != INIT_DEEP) {
835 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
839 iloop = ilist->init.deep;
842 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
843 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
844 if (IS_BITFIELD(sflds->type)) {
845 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
847 pic16_printIval (sym, sflds->type, iloop, ptype, p);
851 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
856 /*--------------------------------------------------------------------------*/
857 /* pic16_printIvalCharPtr - generates initial values for character pointers */
858 /*--------------------------------------------------------------------------*/
859 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
863 /* PENDING: this is _very_ mcs51 specific, including a magic
865 It's also endin specific.
867 VR - Attempting to port this function to pic16 port - 8-Jun-2004
872 fprintf(stderr, "%s\n",__FUNCTION__);
875 size = getSize (type);
877 if (val->name && strlen (val->name))
879 if (size == 1) /* This appears to be Z80 specific?? */
881 pic16_emitDS(val->name, ptype, p);
885 pic16_printPointerType (val->name, ptype, p);
890 if (IS_PTR (val->type)) {
891 type = DCL_TYPE (val->type);
893 type = PTR_TYPE (SPEC_OCLS (val->etype));
895 if (val->sym && val->sym->isstrlit) {
896 // this is a literal string
899 pic16_printGPointerType(val->name, sym->name, type, type, ptype, p);
903 fprintf (stderr, "*** internal error: unknown size in "
904 "printIvalCharPtr.\n");
910 // these are literals assigned to pointers
914 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
917 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
918 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
921 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
922 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
923 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
931 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
932 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
933 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
939 /*-----------------------------------------------------------------------*/
940 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
941 /*-----------------------------------------------------------------------*/
942 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
949 fprintf(stderr, "%s\n",__FUNCTION__);
953 val = list2val (ilist);
955 val = valCastLiteral(type, 0.0);
958 // an error has been thrown already
962 if (IS_LITERAL(val->etype)) {
963 if (compareType(type, val->etype) == 0) {
964 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
965 printFromToType (val->type, type);
967 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
971 /* check the types */
972 if ((dLvl = compareType (val->type, type->next)) <= 0)
974 pic16_emitDB(0x00, ptype, p);
978 /* now generate the name */
980 pic16_printPointerType (val->name, ptype, p);
982 pic16_printPointerType (val->sym->rname, ptype, p);
984 if(IS_FUNC(val->sym->type) && !val->sym->used) {
986 /* this has not been declared as extern
987 * so declare it as a late extern just after the symbol */
989 pic16_addpCode2pBlock((pBlock *)p, pic16_newpCodeCharP("declare symbol as extern"));
990 pic16_addpCode2pBlock((pBlock *)p, pic16_newpCodeAsmDir("extern", "%s", val->sym->rname));
991 pic16_addpCode2pBlock((pBlock *)p, pic16_newpCodeCharP("continue variable declaration"));
994 fprintf((FILE *)p, "declare symbol as extern");
995 fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
996 fprintf((FILE *)p, "continue variable declaration");
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);
1066 size = getSize (type);
1068 if (size == 1) /* Z80 specific?? */
1070 pic16_emitDS(val->name, ptype, p);
1074 pic16_printPointerType (val->name, ptype, p);
1078 pic16_printGPointerType (val->name, sym->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1079 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1080 PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
1088 /*-----------------------------------------------------------------*/
1089 /* pic16_printIval - generates code for initial value */
1090 /*-----------------------------------------------------------------*/
1091 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1099 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1100 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1101 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1104 /* if structure then */
1105 if (IS_STRUCT (type))
1107 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1108 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1112 /* if this is an array */
1113 if (IS_ARRAY (type))
1115 // fprintf(stderr,"%s array\n",__FUNCTION__);
1116 pic16_printIvalArray (sym, type, ilist, ptype, p);
1123 // not an aggregate, ilist must be a node
1124 if (ilist->type!=INIT_NODE) {
1125 // or a 1-element list
1126 if (ilist->init.deep->next) {
1127 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1130 ilist=ilist->init.deep;
1135 // and the type must match
1136 itype=ilist->init.node->ftype;
1138 if (compareType(type, itype)==0) {
1139 // special case for literal strings
1140 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1141 // which are really code pointers
1142 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1145 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1146 // printFromToType(itype, type);
1153 /* if this is a pointer */
1156 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1157 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1162 /* if type is SPECIFIER */
1165 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1166 pic16_printIvalType (sym, type, ilist, ptype, p);
1171 int PIC16_IS_CONFIG_ADDRESS(int address)
1173 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1176 int PIC16_IS_IDLOC_ADDRESS(int address)
1178 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1181 /* wrapper function for the above */
1182 int PIC16_IS_HWREG_ADDRESS(int address)
1184 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1188 /*-----------------------------------------------------------------*/
1189 /* emitStaticSeg - emitcode for the static segment */
1190 /*-----------------------------------------------------------------*/
1192 pic16emitStaticSeg (memmap * map)
1195 static int didcode=0;
1197 //fprintf(stderr, "%s\n",__FUNCTION__);
1201 /* for all variables in this segment do */
1202 for (sym = setFirstItem (map->syms); sym;
1203 sym = setNextItem (map->syms))
1207 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1208 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1209 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1210 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1211 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1212 printTypeChain( sym->type, stderr );
1213 fprintf(stderr, "\n");
1216 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1217 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1218 (int) floatFromVal(list2val(sym->ival)));
1223 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1224 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1225 (char) floatFromVal(list2val(sym->ival)));
1230 /* if it is "extern" then do nothing */
1231 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1232 checkAddSym(&externs, sym);
1236 /* if it is not static add it to the public
1238 if (!IS_STATIC (sym->etype)) {
1239 /* do not emit if it is a config word declaration */
1240 checkAddSym(&publics, sym);
1243 /* print extra debug info if required */
1244 if (options.debug || sym->level == 0) {
1245 /* NOTE to me - cdbFile may be null in which case,
1246 * the sym name will be printed to stdout. oh well */
1247 debugFile->writeSymbol(sym);
1250 /* if it has an absolute address */
1251 if (SPEC_ABSA (sym->etype)) {
1252 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1253 // __FILE__, __LINE__, sym->name);
1255 /* if it has an initial value */
1263 /* symbol has absolute address and initial value */
1265 resolveIvalSym (sym->ival, sym->type);
1266 asym = newSymbol(sym->rname, 0);
1267 abSym = Safe_calloc(1, sizeof(absSym));
1268 abSym->name = Safe_strdup( sym->rname );
1269 abSym->address = SPEC_ADDR( sym->etype );
1270 addSet(&absSymSet, abSym);
1272 pb = pic16_newpCodeChain(NULL, 'A',pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1273 pic16_addpBlock(pb);
1275 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1276 PCF(pcf)->absblock = 1;
1278 pic16_addpCode2pBlock(pb,pcf);
1279 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1280 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1281 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1282 pic16_flushDB('p', (void *)pb);
1284 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1290 /* symbol has absolute address but no initial value */
1292 /* allocate space */
1293 fprintf (code->oFile, "%s:\n", sym->rname);
1295 /* special case for character strings */
1296 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1297 SPEC_CVAL (sym->etype).v_char) {
1299 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1301 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1308 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1309 // __FILE__, __LINE__, sym->name);
1312 /* if it has an initial value */
1316 /* symbol doesn't have absolute address but has initial value */
1317 fprintf (code->oFile, "%s:\n", sym->rname);
1319 resolveIvalSym (sym->ival, sym->type);
1321 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1322 pic16_addpBlock(pb);
1325 /* make sure that 'code' directive is emitted before, once */
1326 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1331 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1333 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1334 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1335 pic16_flushDB('p', (void *)pb);
1339 /* symbol doesn't have absolute address and no initial value */
1340 /* allocate space */
1341 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1342 fprintf (code->oFile, "%s:\n", sym->rname);
1343 /* special case for character strings */
1344 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1345 SPEC_CVAL (sym->etype).v_char) {
1347 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1349 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1360 /*-----------------------------------------------------------------*/
1361 /* pic16_emitConfigRegs - emits the configuration registers */
1362 /*-----------------------------------------------------------------*/
1363 void pic16_emitConfigRegs(FILE *of)
1367 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1368 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1369 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1370 pic16->cwInfo.confAddrStart+i,
1371 pic16->cwInfo.crInfo[i].value);
1374 void pic16_emitIDRegs(FILE *of)
1378 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1379 if(pic16->idInfo.irInfo[i].emit)
1380 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1381 pic16->idInfo.idAddrStart+i,
1382 pic16->idInfo.irInfo[i].value);
1389 /* no special considerations for the following
1390 data, idata & bit & xdata */
1391 pic16emitRegularMap (data, TRUE, TRUE);
1392 pic16emitRegularMap (idata, TRUE, TRUE);
1393 pic16emitRegularMap (bit, TRUE, FALSE);
1394 pic16emitRegularMap (xdata, TRUE, TRUE);
1395 pic16emitRegularMap (sfr, FALSE, FALSE);
1396 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1397 pic16emitRegularMap (code, TRUE, FALSE);
1398 pic16emitStaticSeg (statsg);
1401 /*-----------------------------------------------------------------*/
1402 /* createInterruptVect - creates the interrupt vector */
1403 /*-----------------------------------------------------------------*/
1405 pic16createInterruptVect (FILE * vFile)
1407 /* if the main is only a prototype ie. no body then do nothing */
1409 if (!IFFUNC_HASBODY(mainf->type)) {
1410 /* if ! compile only then main function should be present */
1411 if (!options.cc_only)
1417 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1418 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1419 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1421 /* this is an overkill since WE are the port,
1422 * and we know if we have a genIVT function! */
1424 port->genIVT(vFile, interrupts, maxInterrupts);
1431 /*-----------------------------------------------------------------*/
1432 /* pic16initialComments - puts in some initial comments */
1433 /*-----------------------------------------------------------------*/
1435 pic16initialComments (FILE * afile)
1437 initialComments (afile);
1438 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1439 if(pic16_mplab_comp)
1440 fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1441 fprintf (afile, iComments2);
1444 /*-----------------------------------------------------------------*/
1445 /* printPublics - generates global declarations for publics */
1446 /*-----------------------------------------------------------------*/
1448 pic16printPublics (FILE *afile)
1452 fprintf (afile, "\n%s", iComments2);
1453 fprintf (afile, "; public variables in this module\n");
1454 fprintf (afile, "%s", iComments2);
1456 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1457 fprintf(afile, "\tglobal %s\n", sym->rname);
1460 /*-----------------------------------------------------------------*/
1461 /* printExterns - generates extern declarations for externs */
1462 /*-----------------------------------------------------------------*/
1464 pic16_printExterns(FILE *afile)
1468 /* print nothing if no externs to declare */
1469 if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1472 fprintf(afile, "\n%s", iComments2);
1473 fprintf(afile, "; extern variables in this module\n");
1474 fprintf(afile, "%s", iComments2);
1476 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1477 fprintf(afile, "\textern %s\n", sym->rname);
1479 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1480 fprintf(afile, "\textern _%s\n", sym->name);
1483 /*-----------------------------------------------------------------*/
1484 /* emitOverlay - will emit code for the overlay stuff */
1485 /*-----------------------------------------------------------------*/
1487 pic16emitOverlay (FILE * afile)
1491 if (!elementsInSet (ovrSetSets))
1492 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1494 /* for each of the sets in the overlay segment do */
1495 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1496 ovrset = setNextItem (ovrSetSets))
1501 if (elementsInSet (ovrset))
1503 /* this dummy area is used to fool the assembler
1504 otherwise the assembler will append each of these
1505 declarations into one chunk and will not overlay
1507 fprintf (afile, ";\t.area _DUMMY\n");
1508 /* output the area informtion */
1509 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1512 for (sym = setFirstItem (ovrset); sym;
1513 sym = setNextItem (ovrset))
1516 /* if extern then do nothing */
1517 if (IS_EXTERN (sym->etype))
1520 /* if allocation required check is needed
1521 then check if the symbol really requires
1522 allocation only for local variables */
1523 if (!IS_AGGREGATE (sym->type) &&
1524 !(sym->_isparm && !IS_REGPARM (sym->etype))
1525 && !sym->allocreq && sym->level)
1528 /* if global variable & not static or extern
1529 and addPublics allowed then add it to the public set */
1530 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1531 && !IS_STATIC (sym->etype)) {
1532 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1533 checkAddSym(&publics, sym);
1534 // addSetHead (&publics, sym);
1537 /* if extern then do nothing or is a function
1539 if (IS_FUNC (sym->type))
1543 /* print extra debug info if required */
1544 if (options.debug || sym->level == 0)
1547 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1551 if (IS_STATIC (sym->etype))
1552 fprintf (afile, "F%s_", moduleName); /* scope is file */
1554 fprintf (afile, "G_"); /* scope is global */
1557 /* symbol is local */
1558 fprintf (afile, "L%s_",
1559 (sym->localof ? sym->localof->name : "-null-"));
1560 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1564 /* if is has an absolute address then generate
1565 an equate for this no need to allocate space */
1566 if (SPEC_ABSA (sym->etype))
1569 if (options.debug || sym->level == 0)
1570 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1572 fprintf (afile, "%s\t=\t0x%04x\n",
1574 SPEC_ADDR (sym->etype));
1578 if (options.debug || sym->level == 0)
1579 fprintf (afile, "==.\n");
1581 /* allocate space */
1582 fprintf (afile, "%s:\n", sym->rname);
1583 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1591 /*-----------------------------------------------------------------*/
1592 /* glue - the final glue that hold the whole thing together */
1593 /*-----------------------------------------------------------------*/
1600 FILE *ovrFile = tempfile();
1603 mainf = newSymbol ("main", 0);
1606 mainf = findSymWithLevel(SymbolTab, mainf);
1608 /* only if the main function exists */
1609 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
1610 if (!options.cc_only)
1616 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
1618 addSetHead(&tmpfileSet,ovrFile);
1619 pic16_pCodeInitRegisters();
1621 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1622 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1624 pic16_addpBlock(pb);
1626 /* entry point @ start of CSEG */
1627 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1630 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1631 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1632 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1633 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1636 /* put in the call to main */
1637 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1639 if (options.mainreturn) {
1640 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1641 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1643 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1644 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1648 /* At this point we've got all the code in the form of pCode structures */
1649 /* Now it needs to be rearranged into the order it should be placed in the */
1652 pic16_movepBlock2Head('P'); // Last
1653 pic16_movepBlock2Head(code->dbName);
1654 pic16_movepBlock2Head('X');
1655 pic16_movepBlock2Head(statsg->dbName); // First
1657 /* print the global struct definitions */
1658 // if (options.debug)
1659 // cdbStructBlock (0); //,cdbFile);
1662 /* PENDING: this isnt the best place but it will do */
1663 if (port->general.glue_up_main) {
1664 /* create the interrupt vector table */
1665 pic16createInterruptVect (vFile);
1668 addSetHead(&tmpfileSet,vFile);
1670 /* emit code for the all the variables declared */
1672 /* do the overlay segments */
1673 pic16emitOverlay(ovrFile);
1674 pic16_AnalyzepCode('*');
1677 if(pic16_options.dumpcalltree) {
1679 sprintf(buffer, dstFileName);
1680 strcat(buffer, ".calltree");
1681 cFile = fopen(buffer, "w");
1682 pic16_printCallTree( cFile );
1687 pic16_InlinepCode();
1688 pic16_AnalyzepCode('*');
1690 if(pic16_debug_verbose)
1693 /* now put it all together into the assembler file */
1694 /* create the assembler file name */
1695 if ((noAssemble || options.c1mode) && fullDstFileName) {
1696 sprintf (buffer, fullDstFileName);
1698 sprintf (buffer, dstFileName);
1699 strcat (buffer, ".asm");
1702 if (!(asmFile = fopen (buffer, "w"))) {
1703 werror (E_FILE_OPEN_ERR, buffer);
1707 /* initial comments */
1708 pic16initialComments (asmFile);
1710 /* print module name */
1711 fprintf(asmFile, "#FILE\t\"%s\"\n", fullSrcFileName);
1713 /* Let the port generate any global directives, etc. */
1714 if (port->genAssemblerPreamble) {
1715 port->genAssemblerPreamble(asmFile);
1718 /* print the extern variables to this module */
1719 pic16_printExterns(asmFile);
1721 /* print the global variables in this module */
1722 pic16printPublics (asmFile);
1725 /* copy the sfr segment */
1726 fprintf (asmFile, "%s", iComments2);
1727 fprintf (asmFile, "; special function registers\n");
1728 fprintf (asmFile, "%s", iComments2);
1729 copyFile (asmFile, sfr->oFile);
1732 /* Put all variables into a cblock */
1733 pic16_AnalyzeBanking();
1734 pic16_writeUsedRegs(asmFile);
1737 /* no xdata in pic */
1738 /* if external stack then reserve space of it */
1739 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1740 fprintf (asmFile, "%s", iComments2);
1741 fprintf (asmFile, "; external stack \n");
1742 fprintf (asmFile, "%s", iComments2);
1743 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1744 fprintf (asmFile,";\t.ds 256\n");
1749 /* no xdata in pic */
1750 /* copy xtern ram data */
1751 fprintf (asmFile, "%s", iComments2);
1752 fprintf (asmFile, "; external ram data\n");
1753 fprintf (asmFile, "%s", iComments2);
1754 copyFile (asmFile, xdata->oFile);
1758 /* copy the bit segment */
1759 fprintf (asmFile, "%s", iComments2);
1760 fprintf (asmFile, "; bit data\n");
1761 fprintf (asmFile, "%s", iComments2);
1762 copyFile (asmFile, bit->oFile);
1765 /* copy the interrupt vector table */
1766 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1767 fprintf (asmFile, "\n%s", iComments2);
1768 fprintf (asmFile, "; interrupt vector \n");
1769 fprintf (asmFile, "%s", iComments2);
1770 copyFile (asmFile, vFile);
1773 /* copy global & static initialisations */
1774 fprintf (asmFile, "\n%s", iComments2);
1775 fprintf (asmFile, "; global & static initialisations\n");
1776 fprintf (asmFile, "%s", iComments2);
1779 /* copy over code */
1780 fprintf (asmFile, "%s", iComments2);
1781 fprintf (asmFile, "\tcode\n");
1782 fprintf (asmFile, "%s", iComments2);
1785 if(pic16_debug_verbose)
1786 fprintf(asmFile, "; A code from now on!\n");
1787 pic16_copypCode(asmFile, 'A');
1790 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1791 fprintf(asmFile, "\tcode\n");
1792 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1795 /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
1796 /* if external stack is specified then the
1797 * higher order byte of the xdatalocation is
1798 * going into P2 and the lower order going into */
1800 if (options.useXstack) {
1801 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
1802 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
1803 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
1804 (unsigned int)options.xdata_loc & 0xff);
1809 // copyFile (stderr, code->oFile);
1811 fprintf(asmFile, "; I code from now on!\n");
1812 pic16_copypCode(asmFile, 'I');
1814 if(pic16_debug_verbose)
1815 fprintf(asmFile, "; dbName from now on!\n");
1816 pic16_copypCode(asmFile, statsg->dbName);
1819 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1820 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1824 if(pic16_debug_verbose)
1825 fprintf(asmFile, "; X code from now on!\n");
1826 pic16_copypCode(asmFile, 'X');
1828 if(pic16_debug_verbose)
1829 fprintf(asmFile, "; M code from now on!\n");
1830 pic16_copypCode(asmFile, 'M');
1833 pic16_copypCode(asmFile, code->dbName);
1835 pic16_copypCode(asmFile, 'P');
1837 fprintf (asmFile,"\tend\n");