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 = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
370 // expr = list2expr( ilist );
375 /* try it the old way first */
376 if ((val = constExprValue (expr, FALSE)))
379 /* ( ptr + constant ) */
380 if (IS_AST_OP (expr) &&
381 (expr->opval.op == '+' || expr->opval.op == '-') &&
382 IS_AST_SYM_VALUE (expr->left) &&
383 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
384 compareType(toType, expr->left->ftype) &&
385 IS_AST_LIT_VALUE (expr->right)) {
386 return valForCastAggr (expr->left, expr->left->ftype,
392 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
393 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
394 if (compareType(toType, expr->left->ftype)!=1) {
395 werror (W_INIT_WRONG);
396 printFromToType(expr->left->ftype, toType);
402 /* no then we have to do these cludgy checks */
403 /* pointers can be initialized with address of
404 a variable or address of an array element */
405 if (IS_AST_OP (expr) && expr->opval.op == '&') {
406 /* address of symbol */
407 if (IS_AST_SYM_VALUE (expr->left)) {
408 val = copyValue (AST_VALUE (expr->left));
409 val->type = newLink (DECLARATOR);
410 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
411 DCL_TYPE (val->type) = CPOINTER;
412 DCL_PTR_CONST (val->type) = port->mem.code_ro;
414 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
415 DCL_TYPE (val->type) = FPOINTER;
416 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
417 DCL_TYPE (val->type) = PPOINTER;
418 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
419 DCL_TYPE (val->type) = IPOINTER;
420 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
421 DCL_TYPE (val->type) = EEPPOINTER;
423 DCL_TYPE (val->type) = POINTER;
425 val->type->next = expr->left->ftype;
426 val->etype = getSpec (val->type);
430 /* if address of indexed array */
431 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
432 return valForArray (expr->left);
434 /* if address of structure element then
436 if (IS_AST_OP (expr->left) &&
437 expr->left->opval.op == '.') {
438 return valForStructElem (expr->left->left,
443 (&some_struct)->element */
444 if (IS_AST_OP (expr->left) &&
445 expr->left->opval.op == PTR_OP &&
446 IS_ADDRESS_OF_OP (expr->left->left)) {
447 return valForStructElem (expr->left->left->left,
451 /* case 3. (((char *) &a) +/- constant) */
452 if (IS_AST_OP (expr) &&
453 (expr->opval.op == '+' || expr->opval.op == '-') &&
454 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
455 IS_AST_OP (expr->left->right) &&
456 expr->left->right->opval.op == '&' &&
457 IS_AST_LIT_VALUE (expr->right)) {
459 return valForCastAggr (expr->left->right->left,
460 expr->left->left->opval.lnk,
461 expr->right, expr->opval.op);
464 /* case 4. (char *)(array type) */
465 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
466 IS_ARRAY(expr->right->ftype)) {
468 val = copyValue (AST_VALUE (expr->right));
469 val->type = newLink (DECLARATOR);
470 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
471 DCL_TYPE (val->type) = CPOINTER;
472 DCL_PTR_CONST (val->type) = port->mem.code_ro;
474 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
475 DCL_TYPE (val->type) = FPOINTER;
476 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
477 DCL_TYPE (val->type) = PPOINTER;
478 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
479 DCL_TYPE (val->type) = IPOINTER;
480 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
481 DCL_TYPE (val->type) = EEPPOINTER;
483 DCL_TYPE (val->type) = POINTER;
484 val->type->next = expr->right->ftype->next;
485 val->etype = getSpec (val->type);
491 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
493 werror (E_INCOMPAT_PTYPES);
499 /*-----------------------------------------------------------------*/
500 /* printPointerType - generates ival for pointer type */
501 /*-----------------------------------------------------------------*/
502 void _pic16_printPointerType (const char *name, char ptype, void *p)
506 sprintf(buf, "LOW(%s)", name);
507 pic16_emitDS(buf, ptype, p);
508 sprintf(buf, "HIGH(%s)", name);
509 pic16_emitDS(buf, ptype, p);
512 /*-----------------------------------------------------------------*/
513 /* printPointerType - generates ival for pointer type */
514 /*-----------------------------------------------------------------*/
515 void pic16_printPointerType (const char *name, char ptype, void *p)
517 _pic16_printPointerType (name, ptype, p);
518 pic16_flushDB(ptype, p);
521 /*-----------------------------------------------------------------*/
522 /* printGPointerType - generates ival for generic pointer type */
523 /*-----------------------------------------------------------------*/
524 void pic16_printGPointerType (const char *iname, const char *oname, const unsigned int itype,
525 const unsigned int type, char ptype, void *p)
527 _pic16_printPointerType (iname, ptype, p);
529 if(itype == FPOINTER || itype == CPOINTER) { // || itype == GPOINTER) {
532 sprintf(buf, "UPPER(%s)", iname);
533 pic16_emitDS(buf, ptype, p);
536 pic16_flushDB(ptype, p);
541 /*-----------------------------------------------------------------*/
542 /* pic16_printIvalType - generates ival for int/char */
543 /*-----------------------------------------------------------------*/
545 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
550 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
552 /* if initList is deep */
553 if (ilist && ilist->type == INIT_DEEP)
554 ilist = ilist->init.deep;
556 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
557 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
560 if (!(val = list2val (ilist))) {
561 // assuming a warning has been thrown
565 if (val->type != type) {
566 val = valCastLiteral(type, floatFromVal(val));
570 ulval = (unsigned long) floatFromVal (val);
574 switch (getSize (type)) {
576 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
580 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
581 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
585 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
586 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
587 pic16_emitDB(BYTE_IN_LONG(ulval,2), ptype, p);
588 pic16_emitDB(BYTE_IN_LONG(ulval,3), ptype, p);
593 /*--------------------------------------------------------------------*/
594 /* pic16_printIvalChar - generates initital value for character array */
595 /*--------------------------------------------------------------------*/
597 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
606 // fprintf(stderr, "%s\n",__FUNCTION__);
610 val = list2val (ilist);
611 /* if the value is a character string */
612 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
614 if (!DCL_ELEM (type))
615 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
617 for(remain=0; remain<DCL_ELEM(type); remain++)
618 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
620 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
622 pic16_emitDB(0x00, ptype, p);
631 for(remain=0; remain<strlen(s); remain++) {
632 pic16_emitDB(s[remain], ptype, p);
638 /*-----------------------------------------------------------------*/
639 /* pic16_printIvalArray - generates code for array initialization */
640 /*-----------------------------------------------------------------*/
642 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
646 int lcnt = 0, size = 0;
652 /* take care of the special case */
653 /* array of characters can be init */
655 if (IS_CHAR (type->next)) {
656 if (!IS_LITERAL(list2val(ilist)->etype)) {
657 werror (W_INIT_WRONG);
661 if(pic16_printIvalChar (type,
662 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
663 SPEC_CVAL (sym->etype).v_char, ptype, p))
666 /* not the special case */
667 if (ilist && ilist->type != INIT_DEEP)
669 werror (E_INIT_STRUCT, sym->name);
673 iloop = ilist->init.deep;
674 lcnt = DCL_ELEM (type);
679 pic16_printIval (sym, type->next, iloop, ptype, p);
680 iloop = (iloop ? iloop->next : NULL);
683 /* if not array limits given & we */
684 /* are out of initialisers then */
685 if (!DCL_ELEM (type) && !iloop)
688 /* no of elements given and we */
689 /* have generated for all of them */
691 /* if initializers left */
693 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
699 /* if we have not been given a size */
700 if (!DCL_ELEM (type))
701 DCL_ELEM (type) = size;
706 /*-----------------------------------------------------------------*/
707 /* pic16_printIvalBitFields - generate initializer for bitfields */
708 /*-----------------------------------------------------------------*/
709 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
713 initList *lilist = *ilist ;
714 unsigned long ival = 0;
720 val = list2val(lilist);
722 if (SPEC_BLEN(lsym->etype) > 8) {
723 size += ((SPEC_BLEN (lsym->etype) / 8) +
724 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
727 size = ((SPEC_BLEN (lsym->etype) / 8) +
728 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
730 i = (unsigned long)floatFromVal(val);
731 i <<= SPEC_BSTR (lsym->etype);
733 if (! ( lsym->next &&
734 (IS_BITFIELD(lsym->next->type)) &&
735 (SPEC_BSTR(lsym->next->etype)))) break;
737 lilist = lilist->next;
741 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
745 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
746 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
749 case 4: /* EEP: why is this db and not dw? */
750 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
751 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
752 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
753 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
756 /* VR - only 1,2,4 size long can be handled???? Why? */
757 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
765 /*-----------------------------------------------------------------*/
766 /* printIvalStruct - generates initial value for structures */
767 /*-----------------------------------------------------------------*/
768 void pic16_printIvalStruct (symbol * sym, sym_link * type,
769 initList * ilist, char ptype, void *p)
772 initList *iloop = NULL;
774 sflds = SPEC_STRUCT (type)->fields;
777 if (ilist->type != INIT_DEEP) {
778 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
782 iloop = ilist->init.deep;
785 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
786 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
787 if (IS_BITFIELD(sflds->type)) {
788 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
790 pic16_printIval (sym, sflds->type, iloop, ptype, p);
794 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
799 /*--------------------------------------------------------------------------*/
800 /* pic16_printIvalCharPtr - generates initial values for character pointers */
801 /*--------------------------------------------------------------------------*/
802 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
806 /* PENDING: this is _very_ mcs51 specific, including a magic
808 It's also endin specific.
810 VR - Attempting to port this function to pic16 port - 8-Jun-2004
813 // fprintf(stderr, "%s\n",__FUNCTION__);
815 size = getSize (type);
817 if (val->name && strlen (val->name))
819 if (size == 1) /* This appears to be Z80 specific?? */
821 pic16_emitDS(val->name, ptype, p);
825 pic16_printPointerType (val->name, ptype, p);
830 if (IS_PTR (val->type)) {
831 type = DCL_TYPE (val->type);
833 type = PTR_TYPE (SPEC_OCLS (val->etype));
835 if (val->sym && val->sym->isstrlit) {
836 // this is a literal string
839 pic16_printGPointerType(val->name, sym->name, type, type, ptype, p);
843 fprintf (stderr, "*** internal error: unknown size in "
844 "printIvalCharPtr.\n");
849 // these are literals assigned to pointers
853 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
856 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
857 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
860 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
861 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
862 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
871 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
872 addSet (&statsg->syms, val->sym);
878 /*-----------------------------------------------------------------------*/
879 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
880 /*-----------------------------------------------------------------------*/
881 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
887 val = list2val (ilist);
889 val = valCastLiteral(type, 0.0);
892 // an error has been thrown already
896 if (IS_LITERAL(val->etype)) {
897 if (compareType(type, val->etype) == 0) {
898 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
899 printFromToType (val->type, type);
901 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
905 /* check the types */
906 if ((dLvl = compareType (val->type, type->next)) <= 0)
908 pic16_emitDB(0x00, ptype, p);
912 /* now generate the name */
914 pic16_printPointerType (val->name, ptype, p);
916 pic16_printPointerType (val->sym->rname, ptype, p);
923 /*-----------------------------------------------------------------*/
924 /* pic16_printIvalPtr - generates initial value for pointers */
925 /*-----------------------------------------------------------------*/
926 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
933 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
934 sym->rname, getSize(sym->type));
938 if (ilist && (ilist->type == INIT_DEEP))
939 ilist = ilist->init.deep;
941 /* function pointer */
942 if (IS_FUNC (type->next))
944 pic16_printIvalFuncPtr (type, ilist, ptype, p);
948 if (!(val = pic16_initPointer (ilist, type)))
951 /* if character pointer */
952 if (IS_CHAR (type->next))
953 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
957 if (compareType (type, val->type) == 0) {
958 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
959 printFromToType (val->type, type);
962 /* if val is literal */
963 if (IS_LITERAL (val->etype))
965 switch (getSize (type))
968 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
971 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
972 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
975 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
976 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
977 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
983 size = getSize (type);
985 if (size == 1) /* Z80 specific?? */
987 pic16_emitDS(val->name, ptype, p);
991 pic16_printPointerType (val->name, ptype, p);
995 pic16_printGPointerType (val->name, sym->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
996 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
997 PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
1004 /*-----------------------------------------------------------------*/
1005 /* pic16_printIval - generates code for initial value */
1006 /*-----------------------------------------------------------------*/
1007 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1014 // fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1016 /* if structure then */
1017 if (IS_STRUCT (type))
1019 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1020 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1024 /* if this is an array */
1025 if (IS_ARRAY (type))
1027 // fprintf(stderr,"%s array\n",__FUNCTION__);
1028 pic16_printIvalArray (sym, type, ilist, ptype, p);
1035 // not an aggregate, ilist must be a node
1036 if (ilist->type!=INIT_NODE) {
1037 // or a 1-element list
1038 if (ilist->init.deep->next) {
1039 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1042 ilist=ilist->init.deep;
1047 // and the type must match
1048 itype=ilist->init.node->ftype;
1050 if (compareType(type, itype)==0) {
1051 // special case for literal strings
1052 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1053 // which are really code pointers
1054 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1057 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1058 // printFromToType(itype, type);
1065 /* if this is a pointer */
1068 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1069 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1074 /* if type is SPECIFIER */
1077 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1078 pic16_printIvalType (sym, type, ilist, ptype, p);
1083 int PIC16_IS_CONFIG_ADDRESS(int address)
1086 return (address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd);
1089 /*-----------------------------------------------------------------*/
1090 /* emitStaticSeg - emitcode for the static segment */
1091 /*-----------------------------------------------------------------*/
1093 pic16emitStaticSeg (memmap * map)
1097 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
1099 //fprintf(stderr, "%s\n",__FUNCTION__);
1103 /* for all variables in this segment do */
1104 for (sym = setFirstItem (map->syms); sym;
1105 sym = setNextItem (map->syms))
1109 fprintf(stderr, "\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1110 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n",
1111 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1112 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1113 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1114 printTypeChain( sym->type, stderr );
1115 fprintf(stderr, "\n");
1118 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1119 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1120 (int) floatFromVal(list2val(sym->ival)));
1125 /* if it is "extern" then do nothing */
1126 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1127 checkAddSym(&externs, sym);
1131 /* if it is not static add it to the public
1133 if (!IS_STATIC (sym->etype)) {
1134 /* do not emit if it is a config word declaration */
1135 checkAddSym(&publics, sym);
1138 /* print extra debug info if required */
1139 if (options.debug || sym->level == 0) {
1140 /* NOTE to me - cdbFile may be null in which case,
1141 * the sym name will be printed to stdout. oh well */
1142 debugFile->writeSymbol(sym);
1145 /* if it has an absolute address */
1146 if (SPEC_ABSA (sym->etype)) {
1147 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1148 // __FILE__, __LINE__, sym->name);
1150 /* if it has an initial value */
1158 /* symbol has absolute address and initial value */
1160 resolveIvalSym (sym->ival, sym->type);
1161 asym = newSymbol(sym->rname, 0);
1162 abSym = Safe_calloc(1, sizeof(absSym));
1163 abSym->name = Safe_strdup( sym->rname );
1164 abSym->address = SPEC_ADDR( sym->etype );
1165 addSet(&absSymSet, abSym);
1167 pb = pic16_newpCodeChain(NULL, 'A',pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1168 pic16_addpBlock(pb);
1170 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1171 PCF(pcf)->absblock = 1;
1173 pic16_addpCode2pBlock(pb,pcf);
1174 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1175 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1176 pic16_flushDB('p', (void *)pb);
1178 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1184 /* symbol has absolute address but no initial value */
1186 /* allocate space */
1187 fprintf (code->oFile, "%s:\n", sym->rname);
1189 /* special case for character strings */
1190 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1191 SPEC_CVAL (sym->etype).v_char)
1192 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1195 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1200 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1201 // __FILE__, __LINE__, sym->name);
1203 /* if it has an initial value */
1207 /* symbol doesn't have absolute address but has initial value */
1208 fprintf (code->oFile, "%s:\n", sym->rname);
1210 resolveIvalSym (sym->ival, sym->type);
1212 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1213 pic16_addpBlock(pb);
1214 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1216 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1217 pic16_flushDB('p', (void *)pb);
1221 /* symbol doesn't have absolute address and no initial value */
1222 /* allocate space */
1223 fprintf (code->oFile, "%s:\n", sym->rname);
1224 /* special case for character strings */
1225 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1226 SPEC_CVAL (sym->etype).v_char)
1227 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1230 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1239 /*-----------------------------------------------------------------*/
1240 /* pic16_emitConfigRegs - emits the configuration registers */
1241 /*-----------------------------------------------------------------*/
1242 void pic16_emitConfigRegs(FILE *of)
1246 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1247 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1248 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1249 pic16->cwInfo.confAddrStart+i,
1250 pic16->cwInfo.crInfo[i].value);
1257 /* no special considerations for the following
1258 data, idata & bit & xdata */
1259 pic16emitRegularMap (data, TRUE, TRUE);
1260 pic16emitRegularMap (idata, TRUE, TRUE);
1261 pic16emitRegularMap (bit, TRUE, FALSE);
1262 pic16emitRegularMap (xdata, TRUE, TRUE);
1263 pic16emitRegularMap (sfr, FALSE, FALSE);
1264 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1265 pic16emitRegularMap (code, TRUE, FALSE);
1266 pic16emitStaticSeg (statsg);
1269 /*-----------------------------------------------------------------*/
1270 /* createInterruptVect - creates the interrupt vector */
1271 /*-----------------------------------------------------------------*/
1273 pic16createInterruptVect (FILE * vFile)
1275 /* if the main is only a prototype ie. no body then do nothing */
1277 if (!IFFUNC_HASBODY(mainf->type)) {
1278 /* if ! compile only then main function should be present */
1279 if (!options.cc_only)
1285 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1286 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1287 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1288 fprintf (vFile, "__interrupt_vect:\n");
1290 /* this is an overkill since WE are the port,
1291 * and we know if we have a genIVT function! */
1293 port->genIVT(vFile, interrupts, maxInterrupts);
1300 /*-----------------------------------------------------------------*/
1301 /* pic16initialComments - puts in some initial comments */
1302 /*-----------------------------------------------------------------*/
1304 pic16initialComments (FILE * afile)
1306 initialComments (afile);
1307 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1308 fprintf (afile, iComments2);
1312 /*-----------------------------------------------------------------*/
1313 /* printPublics - generates global declarations for publics */
1314 /*-----------------------------------------------------------------*/
1316 pic16printPublics (FILE *afile)
1320 fprintf (afile, "%s", iComments2);
1321 fprintf (afile, "; public variables in this module\n");
1322 fprintf (afile, "%s", iComments2);
1324 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1325 fprintf(afile, "\tglobal %s\n", sym->rname);
1328 /*-----------------------------------------------------------------*/
1329 /* printExterns - generates extern declarations for externs */
1330 /*-----------------------------------------------------------------*/
1332 pic16_printExterns(FILE *afile)
1336 fprintf(afile, "%s", iComments2);
1337 fprintf(afile, "; extern variables in this module\n");
1338 fprintf(afile, "%s", iComments2);
1340 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1341 fprintf(afile, "\textern %s\n", sym->rname);
1343 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1344 fprintf(afile, "\textern _%s\n", sym->name);
1347 /*-----------------------------------------------------------------*/
1348 /* emitOverlay - will emit code for the overlay stuff */
1349 /*-----------------------------------------------------------------*/
1351 pic16emitOverlay (FILE * afile)
1355 if (!elementsInSet (ovrSetSets))
1356 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1358 /* for each of the sets in the overlay segment do */
1359 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1360 ovrset = setNextItem (ovrSetSets))
1365 if (elementsInSet (ovrset))
1367 /* this dummy area is used to fool the assembler
1368 otherwise the assembler will append each of these
1369 declarations into one chunk and will not overlay
1371 fprintf (afile, ";\t.area _DUMMY\n");
1372 /* output the area informtion */
1373 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1376 for (sym = setFirstItem (ovrset); sym;
1377 sym = setNextItem (ovrset))
1380 /* if extern then do nothing */
1381 if (IS_EXTERN (sym->etype))
1384 /* if allocation required check is needed
1385 then check if the symbol really requires
1386 allocation only for local variables */
1387 if (!IS_AGGREGATE (sym->type) &&
1388 !(sym->_isparm && !IS_REGPARM (sym->etype))
1389 && !sym->allocreq && sym->level)
1392 /* if global variable & not static or extern
1393 and addPublics allowed then add it to the public set */
1394 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1395 && !IS_STATIC (sym->etype)) {
1396 checkAddSym(&publics, sym);
1397 // addSetHead (&publics, sym);
1400 /* if extern then do nothing or is a function
1402 if (IS_FUNC (sym->type))
1406 /* print extra debug info if required */
1407 if (options.debug || sym->level == 0)
1410 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1414 if (IS_STATIC (sym->etype))
1415 fprintf (afile, "F%s_", moduleName); /* scope is file */
1417 fprintf (afile, "G_"); /* scope is global */
1420 /* symbol is local */
1421 fprintf (afile, "L%s_",
1422 (sym->localof ? sym->localof->name : "-null-"));
1423 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1427 /* if is has an absolute address then generate
1428 an equate for this no need to allocate space */
1429 if (SPEC_ABSA (sym->etype))
1432 if (options.debug || sym->level == 0)
1433 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1435 fprintf (afile, "%s\t=\t0x%04x\n",
1437 SPEC_ADDR (sym->etype));
1441 if (options.debug || sym->level == 0)
1442 fprintf (afile, "==.\n");
1444 /* allocate space */
1445 fprintf (afile, "%s:\n", sym->rname);
1446 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1454 /*-----------------------------------------------------------------*/
1455 /* glue - the final glue that hold the whole thing together */
1456 /*-----------------------------------------------------------------*/
1463 FILE *ovrFile = tempfile();
1466 mainf = newSymbol ("main", 0);
1469 mainf = findSymWithLevel(SymbolTab, mainf);
1471 /* only if the main function exists */
1472 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
1473 if (!options.cc_only)
1479 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
1481 addSetHead(&tmpfileSet,ovrFile);
1482 pic16_pCodeInitRegisters();
1484 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1485 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1487 pic16_addpBlock(pb);
1489 /* entry point @ start of CSEG */
1490 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1493 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1494 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("stack"))));
1495 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1496 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("stack"))));
1499 /* put in the call to main */
1500 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1502 if (options.mainreturn) {
1503 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1504 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1506 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1507 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1511 /* At this point we've got all the code in the form of pCode structures */
1512 /* Now it needs to be rearranged into the order it should be placed in the */
1515 pic16_movepBlock2Head('P'); // Last
1516 pic16_movepBlock2Head(code->dbName);
1517 pic16_movepBlock2Head('X');
1518 pic16_movepBlock2Head(statsg->dbName); // First
1520 /* print the global struct definitions */
1521 // if (options.debug)
1522 // cdbStructBlock (0); //,cdbFile);
1525 /* PENDING: this isnt the best place but it will do */
1526 if (port->general.glue_up_main) {
1527 /* create the interrupt vector table */
1528 pic16createInterruptVect (vFile);
1531 addSetHead(&tmpfileSet,vFile);
1533 /* emit code for the all the variables declared */
1535 /* do the overlay segments */
1536 pic16emitOverlay(ovrFile);
1537 pic16_AnalyzepCode('*');
1542 sprintf(buffer, dstFileName);
1543 strcat(buffer, ".calltree");
1544 cFile = fopen(buffer, "w");
1545 pic16_printCallTree( cFile );
1550 pic16_InlinepCode();
1551 pic16_AnalyzepCode('*');
1553 if(pic16_debug_verbose)
1556 /* now put it all together into the assembler file */
1557 /* create the assembler file name */
1558 if ((noAssemble || options.c1mode) && fullDstFileName) {
1559 sprintf (buffer, fullDstFileName);
1561 sprintf (buffer, dstFileName);
1562 strcat (buffer, ".asm");
1565 if (!(asmFile = fopen (buffer, "w"))) {
1566 werror (E_FILE_OPEN_ERR, buffer);
1570 /* initial comments */
1571 pic16initialComments (asmFile);
1573 /* print module name */
1574 fprintf(asmFile, "#FILE\t\"%s\"\n", fullSrcFileName);
1576 /* Let the port generate any global directives, etc. */
1577 if (port->genAssemblerPreamble) {
1578 port->genAssemblerPreamble(asmFile);
1581 /* print the extern variables to this module */
1582 pic16_printExterns(asmFile);
1584 /* print the global variables in this module */
1585 pic16printPublics (asmFile);
1588 /* copy the sfr segment */
1589 fprintf (asmFile, "%s", iComments2);
1590 fprintf (asmFile, "; special function registers\n");
1591 fprintf (asmFile, "%s", iComments2);
1592 copyFile (asmFile, sfr->oFile);
1596 /* Put all variables into a cblock */
1597 pic16_AnalyzeBanking();
1598 pic16_writeUsedRegs(asmFile);
1601 /* create the overlay segments */
1602 fprintf (asmFile, "%s", iComments2);
1603 fprintf (asmFile, "; overlayable items in internal ram \n");
1604 fprintf (asmFile, "%s", iComments2);
1605 copyFile (asmFile, ovrFile);
1610 /* create the stack segment MOF */
1611 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1612 fprintf (asmFile, "%s", iComments2);
1613 fprintf (asmFile, "; Stack segment in internal ram \n");
1614 fprintf (asmFile, "%s", iComments2);
1615 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
1616 ";__start__stack:\n;\t.ds\t1\n\n");
1621 /* no indirect data in pic */
1622 /* create the idata segment */
1623 fprintf (asmFile, "%s", iComments2);
1624 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1625 fprintf (asmFile, "%s", iComments2);
1626 copyFile (asmFile, idata->oFile);
1631 /* no xdata in pic */
1632 /* if external stack then reserve space of it */
1633 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1634 fprintf (asmFile, "%s", iComments2);
1635 fprintf (asmFile, "; external stack \n");
1636 fprintf (asmFile, "%s", iComments2);
1637 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1638 fprintf (asmFile,";\t.ds 256\n");
1643 /* no xdata in pic */
1644 /* copy xtern ram data */
1645 fprintf (asmFile, "%s", iComments2);
1646 fprintf (asmFile, "; external ram data\n");
1647 fprintf (asmFile, "%s", iComments2);
1648 copyFile (asmFile, xdata->oFile);
1652 /* copy the bit segment */
1653 fprintf (asmFile, "%s", iComments2);
1654 fprintf (asmFile, "; bit data\n");
1655 fprintf (asmFile, "%s", iComments2);
1656 copyFile (asmFile, bit->oFile);
1659 /* copy the interrupt vector table */
1660 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1661 fprintf (asmFile, "%s", iComments2);
1662 fprintf (asmFile, "; interrupt vector \n");
1663 fprintf (asmFile, "%s", iComments2);
1664 copyFile (asmFile, vFile);
1667 /* copy global & static initialisations */
1668 fprintf (asmFile, "%s", iComments2);
1669 fprintf (asmFile, "; global & static initialisations\n");
1670 fprintf (asmFile, "%s", iComments2);
1673 /* copy over code */
1674 fprintf (asmFile, "%s", iComments2);
1675 fprintf (asmFile, "\tcode\n");
1676 fprintf (asmFile, "%s", iComments2);
1679 if(pic16_debug_verbose)
1680 fprintf(asmFile, "; A code from now on!\n");
1681 pic16_copypCode(asmFile, 'A');
1684 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1685 fprintf(asmFile, "\tcode\n");
1686 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1689 /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
1690 /* if external stack is specified then the
1691 * higher order byte of the xdatalocation is
1692 * going into P2 and the lower order going into */
1694 if (options.useXstack) {
1695 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
1696 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
1697 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
1698 (unsigned int)options.xdata_loc & 0xff);
1703 // copyFile (stderr, code->oFile);
1705 fprintf(asmFile, "; I code from now on!\n");
1706 pic16_copypCode(asmFile, 'I');
1708 if(pic16_debug_verbose)
1709 fprintf(asmFile, "; dbName from now on!\n");
1710 pic16_copypCode(asmFile, statsg->dbName);
1713 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1714 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1718 if(pic16_debug_verbose)
1719 fprintf(asmFile, "; X code from now on!\n");
1720 pic16_copypCode(asmFile, 'X');
1722 if(pic16_debug_verbose)
1723 fprintf(asmFile, "; M code from now on!\n");
1724 pic16_copypCode(asmFile, 'M');
1727 pic16_copypCode(asmFile, code->dbName);
1729 pic16_copypCode(asmFile, 'P');
1731 fprintf (asmFile,"\tend\n");