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, "\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\n",
136 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
137 IS_AGGREGATE(sym->type));
138 printTypeChain( sym->type, stderr );
139 fprintf(stderr, "\n");
142 // if(PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype)))
146 /* if extern then add to externs */
147 if (IS_EXTERN (sym->etype)) {
148 checkAddSym(&externs, sym);
152 /* if allocation required check is needed
153 * then check if the symbol really requires
154 * allocation only for local variables */
155 if (arFlag && !IS_AGGREGATE (sym->type) &&
156 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
157 !sym->allocreq && sym->level) {
159 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
164 /* if global variable & not static or extern
165 * and addPublics allowed then add it to the public set */
166 if ((sym->used) && (sym->level == 0 ||
167 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
169 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
171 checkAddSym(&publics, sym);
173 if(IS_STATIC(sym->etype)
174 && !(sym->ival && !sym->level)
177 /* add it to udata list */
179 // fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
180 // sym->name, sym->rname, sym->remat);
182 //, OP_SYMBOL(operandFromSymbol(sym))->name);
183 #define SET_IMPLICIT 1
186 if(IS_STRUCT(sym->type))
190 reg = pic16_allocDirReg( operandFromSymbol( sym ));
191 checkAddReg(&pic16_rel_udata, reg);
194 /* if extern then do nothing or is a function
196 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
197 if(SPEC_OCLS(sym->etype) == code) {
198 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
199 checkAddSym(&publics, sym);
205 /* print extra debug info if required */
206 if (options.debug || sym->level == 0) {
207 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
209 if (!sym->level) /* global */
210 if (IS_STATIC (sym->etype))
211 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
213 fprintf (map->oFile, "G_"); /* scope is global */
215 /* symbol is local */
216 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
217 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
222 /* if is has an absolute address then generate
223 an equate for this no need to allocate space */
224 if (SPEC_ABSA (sym->etype)) {
225 // if (options.debug || sym->level == 0)
226 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
227 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
229 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
231 SPEC_ADDR (sym->etype));
233 /* emit only if it is global */
234 if(sym->level == 0) {
237 reg = pic16_dirregWithName( sym->name );
240 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
241 // __FUNCTION__, __LINE__, sym->name);
243 /* if IS_STRUCT is omitted the following
244 * fixes structures but break char/int etc */
246 if(IS_STRUCT(sym->type))
247 sym->implicit = 1; // mark as implicit
250 reg = pic16_allocDirReg( operandFromSymbol(sym) );
252 if(checkAddReg(&pic16_fix_udata, reg)) {
253 /* and add to globals list if not exist */
254 addSet(&publics, sym);
258 addSet(&publics, sym);
262 if(!sym->used && (sym->level == 0)) {
265 /* symbol not used, just declared probably, but its in
266 * level 0, so we must declare it fine as global */
268 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
271 if(IS_STRUCT(sym->type))
272 sym->implicit = 1; // mark as implicit
275 if(IS_AGGREGATE(sym->type)) {
276 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
278 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
280 if(checkAddReg(&pic16_rel_udata, reg)) {
281 addSetHead(&publics, sym);
284 addSetHead(&publics, sym);
289 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
290 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
291 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
292 if (IS_BITVAR (sym->etype)) {
295 fprintf (map->oFile, "\t%s\n", sym->rname);
296 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
297 for (i = 1; i < size; i++)
298 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
301 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
305 /* FIXME -- VR Fix the following, so that syms to be placed
306 * in the idata section and let linker decide about their fate */
308 /* if it has an initial value then do it only if
309 it is a global variable */
311 if (sym->ival && sym->level == 0) {
315 if(SPEC_OCLS(sym->etype)==data) {
316 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
319 if(SPEC_OCLS(sym->etype)==code) {
320 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
325 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
326 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
329 if (IS_AGGREGATE (sym->type)) {
330 if(SPEC_ABSA(sym->etype))
331 addSet(&fix_idataSymSet, copySymbol(sym));
333 addSet(&rel_idataSymSet, copySymbol(sym));
334 // ival = initAggregates (sym, sym->ival, NULL);
336 if(SPEC_ABSA(sym->etype))
337 addSet(&fix_idataSymSet, copySymbol(sym));
339 addSet(&rel_idataSymSet, copySymbol(sym));
341 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
342 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK));
346 setAstLineno(ival, sym->lineDef);
347 codeOutFile = statsg->oFile;
349 eBBlockFromiCode (iCodeFromAst (ival));
357 /*-----------------------------------------------------------------*/
358 /* pic16_initPointer - pointer initialization code massaging */
359 /*-----------------------------------------------------------------*/
360 value *pic16_initPointer (initList * ilist, sym_link *toType)
366 return valCastLiteral(toType, 0.0);
369 expr = list2expr (ilist);
374 /* try it the old way first */
375 if ((val = constExprValue (expr, FALSE)))
378 /* ( ptr + constant ) */
379 if (IS_AST_OP (expr) &&
380 (expr->opval.op == '+' || expr->opval.op == '-') &&
381 IS_AST_SYM_VALUE (expr->left) &&
382 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
383 compareType(toType, expr->left->ftype) &&
384 IS_AST_LIT_VALUE (expr->right)) {
385 return valForCastAggr (expr->left, expr->left->ftype,
391 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
392 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
393 if (compareType(toType, expr->left->ftype)!=1) {
394 werror (W_INIT_WRONG);
395 printFromToType(expr->left->ftype, toType);
401 /* no then we have to do these cludgy checks */
402 /* pointers can be initialized with address of
403 a variable or address of an array element */
404 if (IS_AST_OP (expr) && expr->opval.op == '&') {
405 /* address of symbol */
406 if (IS_AST_SYM_VALUE (expr->left)) {
407 val = copyValue (AST_VALUE (expr->left));
408 val->type = newLink (DECLARATOR);
409 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
410 DCL_TYPE (val->type) = CPOINTER;
411 DCL_PTR_CONST (val->type) = port->mem.code_ro;
413 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
414 DCL_TYPE (val->type) = FPOINTER;
415 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
416 DCL_TYPE (val->type) = PPOINTER;
417 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
418 DCL_TYPE (val->type) = IPOINTER;
419 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
420 DCL_TYPE (val->type) = EEPPOINTER;
422 DCL_TYPE (val->type) = POINTER;
423 val->type->next = expr->left->ftype;
424 val->etype = getSpec (val->type);
428 /* if address of indexed array */
429 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
430 return valForArray (expr->left);
432 /* if address of structure element then
434 if (IS_AST_OP (expr->left) &&
435 expr->left->opval.op == '.') {
436 return valForStructElem (expr->left->left,
441 (&some_struct)->element */
442 if (IS_AST_OP (expr->left) &&
443 expr->left->opval.op == PTR_OP &&
444 IS_ADDRESS_OF_OP (expr->left->left)) {
445 return valForStructElem (expr->left->left->left,
449 /* case 3. (((char *) &a) +/- constant) */
450 if (IS_AST_OP (expr) &&
451 (expr->opval.op == '+' || expr->opval.op == '-') &&
452 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
453 IS_AST_OP (expr->left->right) &&
454 expr->left->right->opval.op == '&' &&
455 IS_AST_LIT_VALUE (expr->right)) {
457 return valForCastAggr (expr->left->right->left,
458 expr->left->left->opval.lnk,
459 expr->right, expr->opval.op);
462 /* case 4. (char *)(array type) */
463 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
464 IS_ARRAY(expr->right->ftype)) {
466 val = copyValue (AST_VALUE (expr->right));
467 val->type = newLink (DECLARATOR);
468 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
469 DCL_TYPE (val->type) = CPOINTER;
470 DCL_PTR_CONST (val->type) = port->mem.code_ro;
472 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
473 DCL_TYPE (val->type) = FPOINTER;
474 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
475 DCL_TYPE (val->type) = PPOINTER;
476 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
477 DCL_TYPE (val->type) = IPOINTER;
478 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
479 DCL_TYPE (val->type) = EEPPOINTER;
481 DCL_TYPE (val->type) = POINTER;
482 val->type->next = expr->right->ftype->next;
483 val->etype = getSpec (val->type);
488 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
490 werror (E_INCOMPAT_PTYPES);
496 /*-----------------------------------------------------------------*/
497 /* return the generic pointer high byte for a given pointer type. */
498 /*-----------------------------------------------------------------*/
499 int pic16_pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
505 fprintf(stderr, "%s:%d pointer is IPOINTER/POINTER\n", __FILE__, __LINE__);
508 fprintf(stderr, "%s:%d pointer is GPOINTER\n", __FILE__, __LINE__);
509 werror (E_CANNOT_USE_GENERIC_POINTER,
510 iname ? iname : "<null>",
511 oname ? oname : "<null>");
514 fprintf(stderr, "%s:%d pointer is FPOINTER\n", __FILE__, __LINE__);
517 fprintf(stderr, "%s:%d pointer is CPOINTER\n", __FILE__, __LINE__);
520 fprintf(stderr, "%s:%d pointer is PPOINTER\n", __FILE__, __LINE__);
521 return GPTYPE_XSTACK;
523 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
531 /*-----------------------------------------------------------------*/
532 /* printPointerType - generates ival for pointer type */
533 /*-----------------------------------------------------------------*/
534 void _pic16_printPointerType (const char *name, char ptype, void *p)
538 sprintf(buf, "LOW(%s)", name);
539 pic16_emitDS(buf, ptype, p);
540 sprintf(buf, "HIGH(%s)", name);
541 pic16_emitDS(buf, ptype, p);
544 /*-----------------------------------------------------------------*/
545 /* printPointerType - generates ival for pointer type */
546 /*-----------------------------------------------------------------*/
547 void pic16_printPointerType (const char *name, char ptype, void *p)
549 _pic16_printPointerType (name, ptype, p);
550 pic16_flushDB(ptype, p);
553 /*-----------------------------------------------------------------*/
554 /* printGPointerType - generates ival for generic pointer type */
555 /*-----------------------------------------------------------------*/
556 void pic16_printGPointerType (const char *iname, const char *oname,
557 const unsigned int type, char ptype, void *p)
559 _pic16_printPointerType (iname, ptype, p);
560 pic16_emitDB(pic16_pointerTypeToGPByte(type, iname, oname), ptype, p);
561 pic16_flushDB(ptype, p);
566 /*-----------------------------------------------------------------*/
567 /* pic16_printIvalType - generates ival for int/char */
568 /*-----------------------------------------------------------------*/
570 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
575 //fprintf(stderr, "%s\n",__FUNCTION__);
577 /* if initList is deep */
578 if (ilist && ilist->type == INIT_DEEP)
579 ilist = ilist->init.deep;
581 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
582 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
585 if (!(val = list2val (ilist))) {
586 // assuming a warning has been thrown
590 if (val->type != type) {
591 val = valCastLiteral(type, floatFromVal(val));
595 ulval = (unsigned long) floatFromVal (val);
599 switch (getSize (type)) {
601 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
605 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
606 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
610 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
611 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
612 pic16_emitDB(BYTE_IN_LONG(ulval,2), ptype, p);
613 pic16_emitDB(BYTE_IN_LONG(ulval,3), ptype, p);
618 /*--------------------------------------------------------------------*/
619 /* pic16_printIvalChar - generates initital value for character array */
620 /*--------------------------------------------------------------------*/
622 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
631 // fprintf(stderr, "%s\n",__FUNCTION__);
635 val = list2val (ilist);
636 /* if the value is a character string */
637 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
639 if (!DCL_ELEM (type))
640 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
642 for(remain=0; remain<DCL_ELEM(type); remain++)
643 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
645 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
647 pic16_emitDB(0x00, ptype, p);
656 for(remain=0; remain<strlen(s); remain++) {
657 pic16_emitDB(s[remain], ptype, p);
663 /*-----------------------------------------------------------------*/
664 /* pic16_printIvalArray - generates code for array initialization */
665 /*-----------------------------------------------------------------*/
667 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
671 int lcnt = 0, size = 0;
677 /* take care of the special case */
678 /* array of characters can be init */
680 if (IS_CHAR (type->next)) {
681 if (!IS_LITERAL(list2val(ilist)->etype)) {
682 werror (W_INIT_WRONG);
686 if(pic16_printIvalChar (type,
687 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
688 SPEC_CVAL (sym->etype).v_char, ptype, p))
691 /* not the special case */
692 if (ilist && ilist->type != INIT_DEEP)
694 werror (E_INIT_STRUCT, sym->name);
698 iloop = ilist->init.deep;
699 lcnt = DCL_ELEM (type);
704 pic16_printIval (sym, type->next, iloop, ptype, p);
705 iloop = (iloop ? iloop->next : NULL);
708 /* if not array limits given & we */
709 /* are out of initialisers then */
710 if (!DCL_ELEM (type) && !iloop)
713 /* no of elements given and we */
714 /* have generated for all of them */
716 /* if initializers left */
718 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
724 /* if we have not been given a size */
725 if (!DCL_ELEM (type))
726 DCL_ELEM (type) = size;
731 /*-----------------------------------------------------------------*/
732 /* pic16_printIvalBitFields - generate initializer for bitfields */
733 /*-----------------------------------------------------------------*/
734 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
738 initList *lilist = *ilist ;
739 unsigned long ival = 0;
745 val = list2val(lilist);
747 if (SPEC_BLEN(lsym->etype) > 8) {
748 size += ((SPEC_BLEN (lsym->etype) / 8) +
749 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
752 size = ((SPEC_BLEN (lsym->etype) / 8) +
753 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
755 i = (unsigned long)floatFromVal(val);
756 i <<= SPEC_BSTR (lsym->etype);
758 if (! ( lsym->next &&
759 (IS_BITFIELD(lsym->next->type)) &&
760 (SPEC_BSTR(lsym->next->etype)))) break;
762 lilist = lilist->next;
766 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
770 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
771 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
774 case 4: /* EEP: why is this db and not dw? */
775 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
776 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
777 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
778 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
781 /* VR - only 1,2,4 size long can be handled???? Why? */
782 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
789 /*-----------------------------------------------------------------*/
790 /* printIvalStruct - generates initial value for structures */
791 /*-----------------------------------------------------------------*/
792 void pic16_printIvalStruct (symbol * sym, sym_link * type,
793 initList * ilist, char ptype, void *p)
796 initList *iloop = NULL;
798 sflds = SPEC_STRUCT (type)->fields;
801 if (ilist->type != INIT_DEEP) {
802 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
806 iloop = ilist->init.deep;
809 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
810 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
811 if (IS_BITFIELD(sflds->type)) {
812 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
814 pic16_printIval (sym, sflds->type, iloop, ptype, p);
818 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
823 /*--------------------------------------------------------------------------*/
824 /* pic16_printIvalCharPtr - generates initial values for character pointers */
825 /*--------------------------------------------------------------------------*/
826 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
830 /* PENDING: this is _very_ mcs51 specific, including a magic
832 It's also endin specific.
834 VR - Attempting to port this function to pic16 port - 8-Jun-2004
837 fprintf(stderr, "%s\n",__FUNCTION__);
839 size = getSize (type);
841 if (val->name && strlen (val->name))
843 if (size == 1) /* This appears to be Z80 specific?? */
845 pic16_emitDS(val->name, ptype, p);
847 else if (size == FPTRSIZE)
849 pic16_printPointerType (val->name, ptype, p);
851 else if (size == GPTRSIZE)
854 if (IS_PTR (val->type)) {
855 type = DCL_TYPE (val->type);
857 type = PTR_TYPE (SPEC_OCLS (val->etype));
859 if (val->sym && val->sym->isstrlit) {
860 // this is a literal string
863 pic16_printGPointerType(val->name, sym->name, type, ptype, p);
867 fprintf (stderr, "*** internal error: unknown size in "
868 "printIvalCharPtr.\n");
873 // these are literals assigned to pointers
877 pic16_emitDS(aopLiteral(val, 0), ptype, p);
878 // tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
881 pic16_emitDS(aopLiteral(val, 0), ptype, p);
882 pic16_emitDS(aopLiteral(val, 1), ptype, p);
883 // tfprintf (oFile, "\t.byte %s,%s\n",
884 // aopLiteral (val, 0), aopLiteral (val, 1));
887 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
888 // non-zero mcs51 generic pointer
889 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
892 pic16_emitDS(aopLiteral(val, 0), ptype, p);
893 pic16_emitDS(aopLiteral(val, 1), ptype, p);
894 pic16_emitDS(aopLiteral(val, 2), ptype, p);
896 // fprintf (oFile, "\t.byte %s,%s,%s\n",
897 // aopLiteral (val, 0),
898 // aopLiteral (val, 1),
899 // aopLiteral (val, 2));
903 /* no 4 bytes size long for pic16 port */
905 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
906 // non-zero ds390 generic pointer
907 werrorfl (sym->fileDef, sym->lineDef, E_LITERAL_GENERIC);
910 // fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
911 // aopLiteral (val, 0),
912 // aopLiteral (val, 1),
913 // aopLiteral (val, 2),
914 // aopLiteral (val, 3));
921 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
922 addSet (&statsg->syms, val->sym);
928 /*-----------------------------------------------------------------------*/
929 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
930 /*-----------------------------------------------------------------------*/
931 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
937 val = list2val (ilist);
939 val = valCastLiteral(type, 0.0);
942 // an error has been thrown already
946 if (IS_LITERAL(val->etype)) {
947 if (compareType(type, val->etype) == 0) {
948 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
949 printFromToType (val->type, type);
951 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
955 /* check the types */
956 if ((dLvl = compareType (val->type, type->next)) <= 0)
958 pic16_emitDB(0x00, ptype, p);
962 /* now generate the name */
965 pic16_printPointerType (val->name, ptype, p);
969 pic16_printPointerType (val->sym->rname, ptype, p);
976 /*-----------------------------------------------------------------*/
977 /* pic16_printIvalPtr - generates initial value for pointers */
978 /*-----------------------------------------------------------------*/
979 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
985 if (ilist && (ilist->type == INIT_DEEP))
986 ilist = ilist->init.deep;
988 /* function pointer */
989 if (IS_FUNC (type->next))
991 pic16_printIvalFuncPtr (type, ilist, ptype, p);
995 if (!(val = pic16_initPointer (ilist, type)))
998 /* if character pointer */
999 if (IS_CHAR (type->next))
1000 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1003 /* check the type */
1004 if (compareType (type, val->type) == 0) {
1005 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1006 printFromToType (val->type, type);
1009 /* if val is literal */
1010 if (IS_LITERAL (val->etype))
1012 switch (getSize (type))
1015 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1016 // tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
1019 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1020 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1021 // tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1024 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1025 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1027 if (IS_GENPTR (val->type))
1028 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1029 else if (IS_PTR (val->type))
1030 pic16_emitDB(pic16_pointerTypeToGPByte(DCL_TYPE(val->type), NULL, NULL), ptype, p);
1032 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1038 size = getSize (type);
1040 if (size == 1) /* Z80 specific?? */
1042 pic16_emitDS(val->name, ptype, p);
1044 else if (size == FPTRSIZE)
1046 pic16_printPointerType (val->name, ptype, p);
1048 else if (size == GPTRSIZE)
1050 pic16_printGPointerType (val->name, sym->name,
1051 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1052 PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
1059 /*-----------------------------------------------------------------*/
1060 /* pic16_printIval - generates code for initial value */
1061 /*-----------------------------------------------------------------*/
1062 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1069 // fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1071 /* if structure then */
1072 if (IS_STRUCT (type))
1074 fprintf(stderr,"%s struct\n",__FUNCTION__);
1075 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1079 /* if this is an array */
1080 if (IS_ARRAY (type))
1082 // fprintf(stderr,"%s array\n",__FUNCTION__);
1083 pic16_printIvalArray (sym, type, ilist, ptype, p);
1090 // not an aggregate, ilist must be a node
1091 if (ilist->type!=INIT_NODE) {
1092 // or a 1-element list
1093 if (ilist->init.deep->next) {
1094 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1097 ilist=ilist->init.deep;
1102 // and the type must match
1103 itype=ilist->init.node->ftype;
1105 if (compareType(type, itype)==0) {
1106 // special case for literal strings
1107 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1108 // which are really code pointers
1109 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1112 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1113 // printFromToType(itype, type);
1120 /* if this is a pointer */
1123 fprintf(stderr,"%s pointer\n",__FUNCTION__);
1124 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1129 /* if type is SPECIFIER */
1132 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1133 pic16_printIvalType (sym, type, ilist, ptype, p);
1138 int PIC16_IS_CONFIG_ADDRESS(int address)
1141 return (address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd);
1144 /*-----------------------------------------------------------------*/
1145 /* emitStaticSeg - emitcode for the static segment */
1146 /*-----------------------------------------------------------------*/
1148 pic16emitStaticSeg (memmap * map)
1152 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
1154 //fprintf(stderr, "%s\n",__FUNCTION__);
1158 /* for all variables in this segment do */
1159 for (sym = setFirstItem (map->syms); sym;
1160 sym = setNextItem (map->syms))
1164 fprintf(stderr, "\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1165 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n",
1166 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1167 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1168 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1169 printTypeChain( sym->type, stderr );
1170 fprintf(stderr, "\n");
1173 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1175 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1176 (int) floatFromVal(list2val(sym->ival)));
1181 /* if it is "extern" then do nothing */
1182 if (IS_EXTERN (sym->etype)) {
1184 /* do not emit if it is a config word declaration */
1185 if(!SPEC_ABSA(sym->etype)
1186 || (SPEC_ABSA(sym->etype) && !PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))))
1187 checkAddSym(&externs, sym);
1191 /* if it is not static add it to the public
1193 if (!IS_STATIC (sym->etype)) {
1194 /* do not emit if it is a config word declaration */
1195 checkAddSym(&publics, sym);
1199 /* print extra debug info if required */
1200 if (options.debug || sym->level == 0)
1202 /* NOTE to me - cdbFile may be null in which case,
1203 * the sym name will be printed to stdout. oh well */
1205 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1209 if (IS_STATIC (sym->etype))
1210 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
1212 fprintf (code->oFile, "G_"); /* scope is global */
1215 /* symbol is local */
1216 fprintf (code->oFile, "L%s_",
1217 (sym->localof ? sym->localof->name : "-null-"));
1218 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
1223 /* if it has an absolute address */
1224 if (SPEC_ABSA (sym->etype))
1226 fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1227 __FILE__, __LINE__, sym->name);
1229 if (options.debug || sym->level == 0)
1230 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1232 fprintf (code->oFile, "%s\t=\t0x%04x\n",
1234 SPEC_ADDR (sym->etype));
1236 /* if it has an initial value */
1245 resolveIvalSym (sym->ival, sym->type);
1246 asym = newSymbol(sym->rname, 0);
1247 abSym = Safe_calloc(1, sizeof(absSym));
1248 abSym->name = Safe_strdup( sym->rname );
1249 abSym->address = SPEC_ADDR( sym->etype );
1250 addSet(&absSymSet, abSym);
1252 pb = pic16_newpCodeChain(NULL, 'A',pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1253 pic16_addpBlock(pb);
1255 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1256 PCF(pcf)->absblock = 1;
1258 pic16_addpCode2pBlock(pb,pcf);
1259 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1260 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1261 pic16_flushDB('p', (void *)pb);
1263 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1269 /* allocate space */
1270 fprintf (code->oFile, "%s:\n", sym->rname);
1271 /* special case for character strings */
1272 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1273 SPEC_CVAL (sym->etype).v_char)
1274 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1275 /*printChar (code->oFile,
1276 SPEC_CVAL (sym->etype).v_char,
1277 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
1279 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1283 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1284 // __FILE__, __LINE__, sym->name);
1286 if (options.debug || sym->level == 0)
1287 fprintf (code->oFile, " == .\n");
1289 /* if it has an initial value */
1294 fprintf (code->oFile, "%s:\n", sym->rname);
1296 resolveIvalSym (sym->ival, sym->type);
1298 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1299 pic16_addpBlock(pb);
1300 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1302 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1303 pic16_flushDB('p', (void *)pb);
1309 /* allocate space */
1310 fprintf (code->oFile, "%s:\n", sym->rname);
1311 /* special case for character strings */
1312 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1313 SPEC_CVAL (sym->etype).v_char)
1314 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1315 /*printChar (code->oFile,
1316 SPEC_CVAL (sym->etype).v_char,
1317 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
1319 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1327 /*-----------------------------------------------------------------*/
1328 /* pic16_emitConfigRegs - emits the configuration registers */
1329 /*-----------------------------------------------------------------*/
1330 void pic16_emitConfigRegs(FILE *of)
1334 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1335 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1336 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1337 pic16->cwInfo.confAddrStart+i,
1338 pic16->cwInfo.crInfo[i].value);
1345 /* no special considerations for the following
1346 data, idata & bit & xdata */
1347 pic16emitRegularMap (data, TRUE, TRUE);
1348 pic16emitRegularMap (idata, TRUE, TRUE);
1349 pic16emitRegularMap (bit, TRUE, FALSE);
1350 pic16emitRegularMap (xdata, TRUE, TRUE);
1351 pic16emitRegularMap (sfr, FALSE, FALSE);
1352 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1353 pic16emitRegularMap (code, TRUE, FALSE);
1354 pic16emitStaticSeg (statsg);
1357 /*-----------------------------------------------------------------*/
1358 /* createInterruptVect - creates the interrupt vector */
1359 /*-----------------------------------------------------------------*/
1361 pic16createInterruptVect (FILE * vFile)
1363 /* if the main is only a prototype ie. no body then do nothing */
1365 if (!IFFUNC_HASBODY(mainf->type)) {
1366 /* if ! compile only then main function should be present */
1367 if (!options.cc_only)
1373 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1374 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1375 fprintf(vFile, ".intvecs\tcode\t0x0000\n");
1376 fprintf (vFile, "__interrupt_vect:\n");
1378 /* this is an overkill since WE are the port,
1379 * and we know if we have a genIVT function! */
1381 port->genIVT(vFile, interrupts, maxInterrupts);
1388 /*-----------------------------------------------------------------*/
1389 /* pic16initialComments - puts in some initial comments */
1390 /*-----------------------------------------------------------------*/
1392 pic16initialComments (FILE * afile)
1394 initialComments (afile);
1395 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1396 fprintf (afile, iComments2);
1400 /*-----------------------------------------------------------------*/
1401 /* printPublics - generates global declarations for publics */
1402 /*-----------------------------------------------------------------*/
1404 pic16printPublics (FILE *afile)
1408 fprintf (afile, "%s", iComments2);
1409 fprintf (afile, "; public variables in this module\n");
1410 fprintf (afile, "%s", iComments2);
1412 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1413 fprintf(afile, "\tglobal %s\n", sym->rname);
1416 /*-----------------------------------------------------------------*/
1417 /* printExterns - generates extern declarations for externs */
1418 /*-----------------------------------------------------------------*/
1420 pic16_printExterns(FILE *afile)
1424 fprintf(afile, "%s", iComments2);
1425 fprintf(afile, "; extern variables in this module\n");
1426 fprintf(afile, "%s", iComments2);
1428 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1429 fprintf(afile, "\textern %s\n", sym->rname);
1431 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1432 fprintf(afile, "\textern _%s\n", sym->name);
1435 /*-----------------------------------------------------------------*/
1436 /* emitOverlay - will emit code for the overlay stuff */
1437 /*-----------------------------------------------------------------*/
1439 pic16emitOverlay (FILE * afile)
1443 if (!elementsInSet (ovrSetSets))
1444 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1446 /* for each of the sets in the overlay segment do */
1447 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1448 ovrset = setNextItem (ovrSetSets))
1453 if (elementsInSet (ovrset))
1455 /* this dummy area is used to fool the assembler
1456 otherwise the assembler will append each of these
1457 declarations into one chunk and will not overlay
1459 fprintf (afile, ";\t.area _DUMMY\n");
1460 /* output the area informtion */
1461 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1464 for (sym = setFirstItem (ovrset); sym;
1465 sym = setNextItem (ovrset))
1468 /* if extern then do nothing */
1469 if (IS_EXTERN (sym->etype))
1472 /* if allocation required check is needed
1473 then check if the symbol really requires
1474 allocation only for local variables */
1475 if (!IS_AGGREGATE (sym->type) &&
1476 !(sym->_isparm && !IS_REGPARM (sym->etype))
1477 && !sym->allocreq && sym->level)
1480 /* if global variable & not static or extern
1481 and addPublics allowed then add it to the public set */
1482 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1483 && !IS_STATIC (sym->etype)) {
1484 checkAddSym(&publics, sym);
1485 // addSetHead (&publics, sym);
1488 /* if extern then do nothing or is a function
1490 if (IS_FUNC (sym->type))
1494 /* print extra debug info if required */
1495 if (options.debug || sym->level == 0)
1498 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1502 if (IS_STATIC (sym->etype))
1503 fprintf (afile, "F%s_", moduleName); /* scope is file */
1505 fprintf (afile, "G_"); /* scope is global */
1508 /* symbol is local */
1509 fprintf (afile, "L%s_",
1510 (sym->localof ? sym->localof->name : "-null-"));
1511 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1515 /* if is has an absolute address then generate
1516 an equate for this no need to allocate space */
1517 if (SPEC_ABSA (sym->etype))
1520 if (options.debug || sym->level == 0)
1521 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1523 fprintf (afile, "%s\t=\t0x%04x\n",
1525 SPEC_ADDR (sym->etype));
1529 if (options.debug || sym->level == 0)
1530 fprintf (afile, "==.\n");
1532 /* allocate space */
1533 fprintf (afile, "%s:\n", sym->rname);
1534 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1542 /*-----------------------------------------------------------------*/
1543 /* glue - the final glue that hold the whole thing together */
1544 /*-----------------------------------------------------------------*/
1551 FILE *ovrFile = tempfile();
1554 mainf = newSymbol ("main", 0);
1557 mainf = findSymWithLevel(SymbolTab, mainf);
1559 /* only if the main function exists */
1560 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
1561 if (!options.cc_only)
1567 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
1569 addSetHead(&tmpfileSet,ovrFile);
1570 pic16_pCodeInitRegisters();
1572 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1573 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1575 pic16_addpBlock(pb);
1577 /* entry point @ start of CSEG */
1578 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1581 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1582 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("stack"))));
1583 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1584 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("stack"))));
1587 /* put in the call to main */
1588 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1590 if (options.mainreturn) {
1591 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1592 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1594 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1595 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1599 /* At this point we've got all the code in the form of pCode structures */
1600 /* Now it needs to be rearranged into the order it should be placed in the */
1603 pic16_movepBlock2Head('P'); // Last
1604 pic16_movepBlock2Head(code->dbName);
1605 pic16_movepBlock2Head('X');
1606 pic16_movepBlock2Head(statsg->dbName); // First
1608 /* print the global struct definitions */
1609 // if (options.debug)
1610 // cdbStructBlock (0); //,cdbFile);
1613 /* PENDING: this isnt the best place but it will do */
1614 if (port->general.glue_up_main) {
1615 /* create the interrupt vector table */
1616 pic16createInterruptVect (vFile);
1619 addSetHead(&tmpfileSet,vFile);
1621 /* emit code for the all the variables declared */
1623 /* do the overlay segments */
1624 pic16emitOverlay(ovrFile);
1625 pic16_AnalyzepCode('*');
1630 sprintf(buffer, dstFileName);
1631 strcat(buffer, ".calltree");
1632 cFile = fopen(buffer, "w");
1633 pic16_printCallTree( cFile );
1638 pic16_InlinepCode();
1639 pic16_AnalyzepCode('*');
1641 if(pic16_debug_verbose)
1644 /* now put it all together into the assembler file */
1645 /* create the assembler file name */
1646 if ((noAssemble || options.c1mode) && fullDstFileName) {
1647 sprintf (buffer, fullDstFileName);
1649 sprintf (buffer, dstFileName);
1650 strcat (buffer, ".asm");
1653 if (!(asmFile = fopen (buffer, "w"))) {
1654 werror (E_FILE_OPEN_ERR, buffer);
1658 /* initial comments */
1659 pic16initialComments (asmFile);
1661 /* print module name */
1662 fprintf(asmFile, "#FILE\t\"%s\"\n", fullSrcFileName);
1664 /* Let the port generate any global directives, etc. */
1665 if (port->genAssemblerPreamble) {
1666 port->genAssemblerPreamble(asmFile);
1669 /* print the extern variables to this module */
1670 pic16_printExterns(asmFile);
1672 /* print the global variables in this module */
1673 pic16printPublics (asmFile);
1676 /* copy the sfr segment */
1677 fprintf (asmFile, "%s", iComments2);
1678 fprintf (asmFile, "; special function registers\n");
1679 fprintf (asmFile, "%s", iComments2);
1680 copyFile (asmFile, sfr->oFile);
1684 /* Put all variables into a cblock */
1685 pic16_AnalyzeBanking();
1686 pic16_writeUsedRegs(asmFile);
1689 /* create the overlay segments */
1690 fprintf (asmFile, "%s", iComments2);
1691 fprintf (asmFile, "; overlayable items in internal ram \n");
1692 fprintf (asmFile, "%s", iComments2);
1693 copyFile (asmFile, ovrFile);
1698 /* create the stack segment MOF */
1699 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1700 fprintf (asmFile, "%s", iComments2);
1701 fprintf (asmFile, "; Stack segment in internal ram \n");
1702 fprintf (asmFile, "%s", iComments2);
1703 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
1704 ";__start__stack:\n;\t.ds\t1\n\n");
1709 /* no indirect data in pic */
1710 /* create the idata segment */
1711 fprintf (asmFile, "%s", iComments2);
1712 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1713 fprintf (asmFile, "%s", iComments2);
1714 copyFile (asmFile, idata->oFile);
1719 /* no xdata in pic */
1720 /* if external stack then reserve space of it */
1721 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1722 fprintf (asmFile, "%s", iComments2);
1723 fprintf (asmFile, "; external stack \n");
1724 fprintf (asmFile, "%s", iComments2);
1725 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1726 fprintf (asmFile,";\t.ds 256\n");
1731 /* no xdata in pic */
1732 /* copy xtern ram data */
1733 fprintf (asmFile, "%s", iComments2);
1734 fprintf (asmFile, "; external ram data\n");
1735 fprintf (asmFile, "%s", iComments2);
1736 copyFile (asmFile, xdata->oFile);
1740 /* copy the bit segment */
1741 fprintf (asmFile, "%s", iComments2);
1742 fprintf (asmFile, "; bit data\n");
1743 fprintf (asmFile, "%s", iComments2);
1744 copyFile (asmFile, bit->oFile);
1747 /* copy the interrupt vector table */
1748 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1749 fprintf (asmFile, "%s", iComments2);
1750 fprintf (asmFile, "; interrupt vector \n");
1751 fprintf (asmFile, "%s", iComments2);
1752 copyFile (asmFile, vFile);
1755 /* copy global & static initialisations */
1756 fprintf (asmFile, "%s", iComments2);
1757 fprintf (asmFile, "; global & static initialisations\n");
1758 fprintf (asmFile, "%s", iComments2);
1761 /* copy over code */
1762 fprintf (asmFile, "%s", iComments2);
1763 fprintf (asmFile, "\tcode\n");
1764 fprintf (asmFile, "%s", iComments2);
1767 if(pic16_debug_verbose)
1768 fprintf(asmFile, "; A code from now on!\n");
1769 pic16_copypCode(asmFile, 'A');
1772 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1773 fprintf(asmFile, "\tcode\n");
1774 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1777 /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
1778 /* if external stack is specified then the
1779 * higher order byte of the xdatalocation is
1780 * going into P2 and the lower order going into */
1782 if (options.useXstack) {
1783 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
1784 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
1785 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
1786 (unsigned int)options.xdata_loc & 0xff);
1791 // copyFile (stderr, code->oFile);
1793 fprintf(asmFile, "; I code from now on!\n");
1794 pic16_copypCode(asmFile, 'I');
1796 if(pic16_debug_verbose)
1797 fprintf(asmFile, "; dbName from now on!\n");
1798 pic16_copypCode(asmFile, statsg->dbName);
1801 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1802 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1806 if(pic16_debug_verbose)
1807 fprintf(asmFile, "; X code from now on!\n");
1808 pic16_copypCode(asmFile, 'X');
1810 if(pic16_debug_verbose)
1811 fprintf(asmFile, "; M code from now on!\n");
1812 pic16_copypCode(asmFile, 'M');
1815 pic16_copypCode(asmFile, code->dbName);
1817 pic16_copypCode(asmFile, 'P');
1819 fprintf (asmFile,"\tend\n");