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\n",
137 map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
138 IS_AGGREGATE(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 ) );
301 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
302 if(!strcmp(ssym->name, reg->name))found=1;
307 if(checkAddReg(&pic16_rel_udata, reg)) {
308 addSetHead(&publics, sym);
317 addSetHead(&publics, sym);
322 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
323 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
324 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
325 if (IS_BITVAR (sym->etype)) {
328 fprintf (map->oFile, "\t%s\n", sym->rname);
329 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
330 for (i = 1; i < size; i++)
331 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
334 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
338 /* FIXME -- VR Fix the following, so that syms to be placed
339 * in the idata section and let linker decide about their fate */
341 /* if it has an initial value then do it only if
342 it is a global variable */
344 if (sym->ival && sym->level == 0) {
348 if(SPEC_OCLS(sym->etype)==data) {
349 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
352 if(SPEC_OCLS(sym->etype)==code) {
353 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
358 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
359 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
362 if (IS_AGGREGATE (sym->type)) {
363 if(SPEC_ABSA(sym->etype))
364 addSet(&fix_idataSymSet, copySymbol(sym));
366 addSet(&rel_idataSymSet, copySymbol(sym));
367 // ival = initAggregates (sym, sym->ival, NULL);
369 if(SPEC_ABSA(sym->etype))
370 addSet(&fix_idataSymSet, copySymbol(sym));
372 addSet(&rel_idataSymSet, copySymbol(sym));
374 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
375 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK));
379 setAstLineno(ival, sym->lineDef);
380 codeOutFile = statsg->oFile;
382 eBBlockFromiCode (iCodeFromAst (ival));
390 /*-----------------------------------------------------------------*/
391 /* pic16_initPointer - pointer initialization code massaging */
392 /*-----------------------------------------------------------------*/
393 value *pic16_initPointer (initList * ilist, sym_link *toType)
399 return valCastLiteral(toType, 0.0);
402 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
403 // expr = list2expr( ilist );
408 /* try it the old way first */
409 if ((val = constExprValue (expr, FALSE)))
412 /* ( ptr + constant ) */
413 if (IS_AST_OP (expr) &&
414 (expr->opval.op == '+' || expr->opval.op == '-') &&
415 IS_AST_SYM_VALUE (expr->left) &&
416 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
417 compareType(toType, expr->left->ftype) &&
418 IS_AST_LIT_VALUE (expr->right)) {
419 return valForCastAggr (expr->left, expr->left->ftype,
425 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
426 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
427 if (compareType(toType, expr->left->ftype)!=1) {
428 werror (W_INIT_WRONG);
429 printFromToType(expr->left->ftype, toType);
435 /* no then we have to do these cludgy checks */
436 /* pointers can be initialized with address of
437 a variable or address of an array element */
438 if (IS_AST_OP (expr) && expr->opval.op == '&') {
439 /* address of symbol */
440 if (IS_AST_SYM_VALUE (expr->left)) {
441 val = copyValue (AST_VALUE (expr->left));
442 val->type = newLink (DECLARATOR);
443 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
444 DCL_TYPE (val->type) = CPOINTER;
445 DCL_PTR_CONST (val->type) = port->mem.code_ro;
447 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
448 DCL_TYPE (val->type) = FPOINTER;
449 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
450 DCL_TYPE (val->type) = PPOINTER;
451 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
452 DCL_TYPE (val->type) = IPOINTER;
453 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
454 DCL_TYPE (val->type) = EEPPOINTER;
456 DCL_TYPE (val->type) = POINTER;
458 val->type->next = expr->left->ftype;
459 val->etype = getSpec (val->type);
463 /* if address of indexed array */
464 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
465 return valForArray (expr->left);
467 /* if address of structure element then
469 if (IS_AST_OP (expr->left) &&
470 expr->left->opval.op == '.') {
471 return valForStructElem (expr->left->left,
476 (&some_struct)->element */
477 if (IS_AST_OP (expr->left) &&
478 expr->left->opval.op == PTR_OP &&
479 IS_ADDRESS_OF_OP (expr->left->left)) {
480 return valForStructElem (expr->left->left->left,
484 /* case 3. (((char *) &a) +/- constant) */
485 if (IS_AST_OP (expr) &&
486 (expr->opval.op == '+' || expr->opval.op == '-') &&
487 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
488 IS_AST_OP (expr->left->right) &&
489 expr->left->right->opval.op == '&' &&
490 IS_AST_LIT_VALUE (expr->right)) {
492 return valForCastAggr (expr->left->right->left,
493 expr->left->left->opval.lnk,
494 expr->right, expr->opval.op);
497 /* case 4. (char *)(array type) */
498 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
499 IS_ARRAY(expr->right->ftype)) {
501 val = copyValue (AST_VALUE (expr->right));
502 val->type = newLink (DECLARATOR);
503 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
504 DCL_TYPE (val->type) = CPOINTER;
505 DCL_PTR_CONST (val->type) = port->mem.code_ro;
507 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
508 DCL_TYPE (val->type) = FPOINTER;
509 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
510 DCL_TYPE (val->type) = PPOINTER;
511 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
512 DCL_TYPE (val->type) = IPOINTER;
513 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
514 DCL_TYPE (val->type) = EEPPOINTER;
516 DCL_TYPE (val->type) = POINTER;
517 val->type->next = expr->right->ftype->next;
518 val->etype = getSpec (val->type);
524 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
526 werror (E_INCOMPAT_PTYPES);
532 /*-----------------------------------------------------------------*/
533 /* printPointerType - generates ival for pointer type */
534 /*-----------------------------------------------------------------*/
535 void _pic16_printPointerType (const char *name, char ptype, void *p)
539 sprintf(buf, "LOW(%s)", name);
540 pic16_emitDS(buf, ptype, p);
541 sprintf(buf, "HIGH(%s)", name);
542 pic16_emitDS(buf, ptype, p);
545 /*-----------------------------------------------------------------*/
546 /* printPointerType - generates ival for pointer type */
547 /*-----------------------------------------------------------------*/
548 void pic16_printPointerType (const char *name, char ptype, void *p)
550 _pic16_printPointerType (name, ptype, p);
551 pic16_flushDB(ptype, p);
554 /*-----------------------------------------------------------------*/
555 /* printGPointerType - generates ival for generic pointer type */
556 /*-----------------------------------------------------------------*/
557 void pic16_printGPointerType (const char *iname, const char *oname, const unsigned int itype,
558 const unsigned int type, char ptype, void *p)
560 _pic16_printPointerType (iname, ptype, p);
562 if(itype == FPOINTER || itype == CPOINTER) { // || itype == GPOINTER) {
565 sprintf(buf, "UPPER(%s)", iname);
566 pic16_emitDS(buf, ptype, p);
569 pic16_flushDB(ptype, p);
574 /*-----------------------------------------------------------------*/
575 /* pic16_printIvalType - generates ival for int/char */
576 /*-----------------------------------------------------------------*/
578 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
583 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
585 /* if initList is deep */
586 if (ilist && ilist->type == INIT_DEEP)
587 ilist = ilist->init.deep;
589 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
590 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
593 if (!(val = list2val (ilist))) {
594 // assuming a warning has been thrown
598 if (val->type != type) {
599 val = valCastLiteral(type, floatFromVal(val));
603 ulval = (unsigned long) floatFromVal (val);
607 switch (getSize (type)) {
609 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
613 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
614 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
618 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
619 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
620 pic16_emitDB(BYTE_IN_LONG(ulval,2), ptype, p);
621 pic16_emitDB(BYTE_IN_LONG(ulval,3), ptype, p);
626 /*--------------------------------------------------------------------*/
627 /* pic16_printIvalChar - generates initital value for character array */
628 /*--------------------------------------------------------------------*/
630 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
639 // fprintf(stderr, "%s\n",__FUNCTION__);
643 val = list2val (ilist);
644 /* if the value is a character string */
645 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
647 if (!DCL_ELEM (type))
648 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
650 for(remain=0; remain<DCL_ELEM(type); remain++)
651 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
653 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
655 pic16_emitDB(0x00, ptype, p);
664 for(remain=0; remain<strlen(s); remain++) {
665 pic16_emitDB(s[remain], ptype, p);
671 /*-----------------------------------------------------------------*/
672 /* pic16_printIvalArray - generates code for array initialization */
673 /*-----------------------------------------------------------------*/
675 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
679 int lcnt = 0, size = 0;
685 /* take care of the special case */
686 /* array of characters can be init */
688 if (IS_CHAR (type->next)) {
689 if (!IS_LITERAL(list2val(ilist)->etype)) {
690 werror (W_INIT_WRONG);
694 if(pic16_printIvalChar (type,
695 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
696 SPEC_CVAL (sym->etype).v_char, ptype, p))
699 /* not the special case */
700 if (ilist && ilist->type != INIT_DEEP)
702 werror (E_INIT_STRUCT, sym->name);
706 iloop = ilist->init.deep;
707 lcnt = DCL_ELEM (type);
712 pic16_printIval (sym, type->next, iloop, ptype, p);
713 iloop = (iloop ? iloop->next : NULL);
716 /* if not array limits given & we */
717 /* are out of initialisers then */
718 if (!DCL_ELEM (type) && !iloop)
721 /* no of elements given and we */
722 /* have generated for all of them */
724 /* if initializers left */
726 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
732 /* if we have not been given a size */
733 if (!DCL_ELEM (type))
734 DCL_ELEM (type) = size;
739 /*-----------------------------------------------------------------*/
740 /* pic16_printIvalBitFields - generate initializer for bitfields */
741 /*-----------------------------------------------------------------*/
742 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
746 initList *lilist = *ilist ;
747 unsigned long ival = 0;
753 val = list2val(lilist);
755 if (SPEC_BLEN(lsym->etype) > 8) {
756 size += ((SPEC_BLEN (lsym->etype) / 8) +
757 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
760 size = ((SPEC_BLEN (lsym->etype) / 8) +
761 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
763 i = (unsigned long)floatFromVal(val);
764 i <<= SPEC_BSTR (lsym->etype);
766 if (! ( lsym->next &&
767 (IS_BITFIELD(lsym->next->type)) &&
768 (SPEC_BSTR(lsym->next->etype)))) break;
770 lilist = lilist->next;
774 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
778 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
779 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
782 case 4: /* EEP: why is this db and not dw? */
783 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
784 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
785 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
786 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
789 /* VR - only 1,2,4 size long can be handled???? Why? */
790 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
798 /*-----------------------------------------------------------------*/
799 /* printIvalStruct - generates initial value for structures */
800 /*-----------------------------------------------------------------*/
801 void pic16_printIvalStruct (symbol * sym, sym_link * type,
802 initList * ilist, char ptype, void *p)
805 initList *iloop = NULL;
807 sflds = SPEC_STRUCT (type)->fields;
810 if (ilist->type != INIT_DEEP) {
811 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
815 iloop = ilist->init.deep;
818 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
819 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
820 if (IS_BITFIELD(sflds->type)) {
821 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
823 pic16_printIval (sym, sflds->type, iloop, ptype, p);
827 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
832 /*--------------------------------------------------------------------------*/
833 /* pic16_printIvalCharPtr - generates initial values for character pointers */
834 /*--------------------------------------------------------------------------*/
835 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
839 /* PENDING: this is _very_ mcs51 specific, including a magic
841 It's also endin specific.
843 VR - Attempting to port this function to pic16 port - 8-Jun-2004
846 // fprintf(stderr, "%s\n",__FUNCTION__);
848 size = getSize (type);
850 if (val->name && strlen (val->name))
852 if (size == 1) /* This appears to be Z80 specific?? */
854 pic16_emitDS(val->name, ptype, p);
858 pic16_printPointerType (val->name, ptype, p);
863 if (IS_PTR (val->type)) {
864 type = DCL_TYPE (val->type);
866 type = PTR_TYPE (SPEC_OCLS (val->etype));
868 if (val->sym && val->sym->isstrlit) {
869 // this is a literal string
872 pic16_printGPointerType(val->name, sym->name, type, type, ptype, p);
876 fprintf (stderr, "*** internal error: unknown size in "
877 "printIvalCharPtr.\n");
883 // these are literals assigned to pointers
887 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
890 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
891 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
894 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
895 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
896 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
904 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
905 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
906 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
912 /*-----------------------------------------------------------------------*/
913 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
914 /*-----------------------------------------------------------------------*/
915 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
921 val = list2val (ilist);
923 val = valCastLiteral(type, 0.0);
926 // an error has been thrown already
930 if (IS_LITERAL(val->etype)) {
931 if (compareType(type, val->etype) == 0) {
932 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
933 printFromToType (val->type, type);
935 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
939 /* check the types */
940 if ((dLvl = compareType (val->type, type->next)) <= 0)
942 pic16_emitDB(0x00, ptype, p);
946 /* now generate the name */
948 pic16_printPointerType (val->name, ptype, p);
950 pic16_printPointerType (val->sym->rname, ptype, p);
957 /*-----------------------------------------------------------------*/
958 /* pic16_printIvalPtr - generates initial value for pointers */
959 /*-----------------------------------------------------------------*/
960 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
966 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
967 sym->rname, getSize(sym->type));
971 if (ilist && (ilist->type == INIT_DEEP))
972 ilist = ilist->init.deep;
974 /* function pointer */
975 if (IS_FUNC (type->next))
977 pic16_printIvalFuncPtr (type, ilist, ptype, p);
981 if (!(val = pic16_initPointer (ilist, type)))
984 /* if character pointer */
985 if (IS_CHAR (type->next))
986 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
990 if (compareType (type, val->type) == 0) {
991 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
992 printFromToType (val->type, type);
995 /* if val is literal */
996 if (IS_LITERAL (val->etype))
998 switch (getSize (type))
1001 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
1004 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1005 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1008 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1009 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1010 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1018 size = getSize (type);
1020 if (size == 1) /* Z80 specific?? */
1022 pic16_emitDS(val->name, ptype, p);
1026 pic16_printPointerType (val->name, ptype, p);
1030 pic16_printGPointerType (val->name, sym->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1031 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1032 PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
1040 /*-----------------------------------------------------------------*/
1041 /* pic16_printIval - generates code for initial value */
1042 /*-----------------------------------------------------------------*/
1043 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1051 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1052 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1053 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1056 /* if structure then */
1057 if (IS_STRUCT (type))
1059 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1060 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1064 /* if this is an array */
1065 if (IS_ARRAY (type))
1067 // fprintf(stderr,"%s array\n",__FUNCTION__);
1068 pic16_printIvalArray (sym, type, ilist, ptype, p);
1075 // not an aggregate, ilist must be a node
1076 if (ilist->type!=INIT_NODE) {
1077 // or a 1-element list
1078 if (ilist->init.deep->next) {
1079 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1082 ilist=ilist->init.deep;
1087 // and the type must match
1088 itype=ilist->init.node->ftype;
1090 if (compareType(type, itype)==0) {
1091 // special case for literal strings
1092 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1093 // which are really code pointers
1094 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1097 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1098 // printFromToType(itype, type);
1105 /* if this is a pointer */
1108 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1109 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1114 /* if type is SPECIFIER */
1117 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1118 pic16_printIvalType (sym, type, ilist, ptype, p);
1123 int PIC16_IS_CONFIG_ADDRESS(int address)
1125 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1128 int PIC16_IS_IDLOC_ADDRESS(int address)
1130 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1133 /* wrapper function for the above */
1134 int PIC16_IS_HWREG_ADDRESS(int address)
1136 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1140 /*-----------------------------------------------------------------*/
1141 /* emitStaticSeg - emitcode for the static segment */
1142 /*-----------------------------------------------------------------*/
1144 pic16emitStaticSeg (memmap * map)
1148 //fprintf(stderr, "%s\n",__FUNCTION__);
1152 /* for all variables in this segment do */
1153 for (sym = setFirstItem (map->syms); sym;
1154 sym = setNextItem (map->syms))
1158 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1159 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1160 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1161 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1162 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1163 printTypeChain( sym->type, stderr );
1164 fprintf(stderr, "\n");
1167 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1168 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1169 (int) floatFromVal(list2val(sym->ival)));
1174 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1175 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1176 (char) floatFromVal(list2val(sym->ival)));
1181 /* if it is "extern" then do nothing */
1182 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1183 checkAddSym(&externs, sym);
1187 /* if it is not static add it to the public
1189 if (!IS_STATIC (sym->etype)) {
1190 /* do not emit if it is a config word declaration */
1191 checkAddSym(&publics, sym);
1194 /* print extra debug info if required */
1195 if (options.debug || sym->level == 0) {
1196 /* NOTE to me - cdbFile may be null in which case,
1197 * the sym name will be printed to stdout. oh well */
1198 debugFile->writeSymbol(sym);
1201 /* if it has an absolute address */
1202 if (SPEC_ABSA (sym->etype)) {
1203 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1204 // __FILE__, __LINE__, sym->name);
1206 /* if it has an initial value */
1214 /* symbol has absolute address and initial value */
1216 resolveIvalSym (sym->ival, sym->type);
1217 asym = newSymbol(sym->rname, 0);
1218 abSym = Safe_calloc(1, sizeof(absSym));
1219 abSym->name = Safe_strdup( sym->rname );
1220 abSym->address = SPEC_ADDR( sym->etype );
1221 addSet(&absSymSet, abSym);
1223 pb = pic16_newpCodeChain(NULL, 'A',pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1224 pic16_addpBlock(pb);
1226 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1227 PCF(pcf)->absblock = 1;
1229 pic16_addpCode2pBlock(pb,pcf);
1230 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1231 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1232 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1233 pic16_flushDB('p', (void *)pb);
1235 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1241 /* symbol has absolute address but no initial value */
1243 /* allocate space */
1244 fprintf (code->oFile, "%s:\n", sym->rname);
1246 /* special case for character strings */
1247 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1248 SPEC_CVAL (sym->etype).v_char) {
1250 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1252 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1259 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1260 // __FILE__, __LINE__, sym->name);
1262 /* if it has an initial value */
1266 /* symbol doesn't have absolute address but has initial value */
1267 fprintf (code->oFile, "%s:\n", sym->rname);
1269 resolveIvalSym (sym->ival, sym->type);
1271 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1272 pic16_addpBlock(pb);
1274 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1276 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1277 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1278 pic16_flushDB('p', (void *)pb);
1282 /* symbol doesn't have absolute address and no initial value */
1283 /* allocate space */
1284 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1285 fprintf (code->oFile, "%s:\n", sym->rname);
1286 /* special case for character strings */
1287 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1288 SPEC_CVAL (sym->etype).v_char) {
1290 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1292 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1303 /*-----------------------------------------------------------------*/
1304 /* pic16_emitConfigRegs - emits the configuration registers */
1305 /*-----------------------------------------------------------------*/
1306 void pic16_emitConfigRegs(FILE *of)
1310 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1311 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1312 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1313 pic16->cwInfo.confAddrStart+i,
1314 pic16->cwInfo.crInfo[i].value);
1317 void pic16_emitIDRegs(FILE *of)
1321 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1322 if(pic16->idInfo.irInfo[i].emit)
1323 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1324 pic16->idInfo.idAddrStart+i,
1325 pic16->idInfo.irInfo[i].value);
1332 /* no special considerations for the following
1333 data, idata & bit & xdata */
1334 pic16emitRegularMap (data, TRUE, TRUE);
1335 pic16emitRegularMap (idata, TRUE, TRUE);
1336 pic16emitRegularMap (bit, TRUE, FALSE);
1337 pic16emitRegularMap (xdata, TRUE, TRUE);
1338 pic16emitRegularMap (sfr, FALSE, FALSE);
1339 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1340 pic16emitRegularMap (code, TRUE, FALSE);
1341 pic16emitStaticSeg (statsg);
1344 /*-----------------------------------------------------------------*/
1345 /* createInterruptVect - creates the interrupt vector */
1346 /*-----------------------------------------------------------------*/
1348 pic16createInterruptVect (FILE * vFile)
1350 /* if the main is only a prototype ie. no body then do nothing */
1352 if (!IFFUNC_HASBODY(mainf->type)) {
1353 /* if ! compile only then main function should be present */
1354 if (!options.cc_only)
1360 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1361 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1362 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1364 /* this is an overkill since WE are the port,
1365 * and we know if we have a genIVT function! */
1367 port->genIVT(vFile, interrupts, maxInterrupts);
1374 /*-----------------------------------------------------------------*/
1375 /* pic16initialComments - puts in some initial comments */
1376 /*-----------------------------------------------------------------*/
1378 pic16initialComments (FILE * afile)
1380 initialComments (afile);
1381 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1382 fprintf (afile, iComments2);
1386 /*-----------------------------------------------------------------*/
1387 /* printPublics - generates global declarations for publics */
1388 /*-----------------------------------------------------------------*/
1390 pic16printPublics (FILE *afile)
1394 fprintf (afile, "%s", iComments2);
1395 fprintf (afile, "; public variables in this module\n");
1396 fprintf (afile, "%s", iComments2);
1398 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1399 fprintf(afile, "\tglobal %s\n", sym->rname);
1402 /*-----------------------------------------------------------------*/
1403 /* printExterns - generates extern declarations for externs */
1404 /*-----------------------------------------------------------------*/
1406 pic16_printExterns(FILE *afile)
1410 fprintf(afile, "%s", iComments2);
1411 fprintf(afile, "; extern variables in this module\n");
1412 fprintf(afile, "%s", iComments2);
1414 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1415 fprintf(afile, "\textern %s\n", sym->rname);
1417 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1418 fprintf(afile, "\textern _%s\n", sym->name);
1421 /*-----------------------------------------------------------------*/
1422 /* emitOverlay - will emit code for the overlay stuff */
1423 /*-----------------------------------------------------------------*/
1425 pic16emitOverlay (FILE * afile)
1429 if (!elementsInSet (ovrSetSets))
1430 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1432 /* for each of the sets in the overlay segment do */
1433 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1434 ovrset = setNextItem (ovrSetSets))
1439 if (elementsInSet (ovrset))
1441 /* this dummy area is used to fool the assembler
1442 otherwise the assembler will append each of these
1443 declarations into one chunk and will not overlay
1445 fprintf (afile, ";\t.area _DUMMY\n");
1446 /* output the area informtion */
1447 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1450 for (sym = setFirstItem (ovrset); sym;
1451 sym = setNextItem (ovrset))
1454 /* if extern then do nothing */
1455 if (IS_EXTERN (sym->etype))
1458 /* if allocation required check is needed
1459 then check if the symbol really requires
1460 allocation only for local variables */
1461 if (!IS_AGGREGATE (sym->type) &&
1462 !(sym->_isparm && !IS_REGPARM (sym->etype))
1463 && !sym->allocreq && sym->level)
1466 /* if global variable & not static or extern
1467 and addPublics allowed then add it to the public set */
1468 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1469 && !IS_STATIC (sym->etype)) {
1470 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1471 checkAddSym(&publics, sym);
1472 // addSetHead (&publics, sym);
1475 /* if extern then do nothing or is a function
1477 if (IS_FUNC (sym->type))
1481 /* print extra debug info if required */
1482 if (options.debug || sym->level == 0)
1485 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1489 if (IS_STATIC (sym->etype))
1490 fprintf (afile, "F%s_", moduleName); /* scope is file */
1492 fprintf (afile, "G_"); /* scope is global */
1495 /* symbol is local */
1496 fprintf (afile, "L%s_",
1497 (sym->localof ? sym->localof->name : "-null-"));
1498 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1502 /* if is has an absolute address then generate
1503 an equate for this no need to allocate space */
1504 if (SPEC_ABSA (sym->etype))
1507 if (options.debug || sym->level == 0)
1508 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1510 fprintf (afile, "%s\t=\t0x%04x\n",
1512 SPEC_ADDR (sym->etype));
1516 if (options.debug || sym->level == 0)
1517 fprintf (afile, "==.\n");
1519 /* allocate space */
1520 fprintf (afile, "%s:\n", sym->rname);
1521 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1529 /*-----------------------------------------------------------------*/
1530 /* glue - the final glue that hold the whole thing together */
1531 /*-----------------------------------------------------------------*/
1538 FILE *ovrFile = tempfile();
1541 mainf = newSymbol ("main", 0);
1544 mainf = findSymWithLevel(SymbolTab, mainf);
1546 /* only if the main function exists */
1547 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
1548 if (!options.cc_only)
1554 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
1556 addSetHead(&tmpfileSet,ovrFile);
1557 pic16_pCodeInitRegisters();
1559 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1560 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1562 pic16_addpBlock(pb);
1564 /* entry point @ start of CSEG */
1565 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1568 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1569 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack"))));
1570 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1571 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack"))));
1574 /* put in the call to main */
1575 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1577 if (options.mainreturn) {
1578 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1579 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1581 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1582 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1586 /* At this point we've got all the code in the form of pCode structures */
1587 /* Now it needs to be rearranged into the order it should be placed in the */
1590 pic16_movepBlock2Head('P'); // Last
1591 pic16_movepBlock2Head(code->dbName);
1592 pic16_movepBlock2Head('X');
1593 pic16_movepBlock2Head(statsg->dbName); // First
1595 /* print the global struct definitions */
1596 // if (options.debug)
1597 // cdbStructBlock (0); //,cdbFile);
1600 /* PENDING: this isnt the best place but it will do */
1601 if (port->general.glue_up_main) {
1602 /* create the interrupt vector table */
1603 pic16createInterruptVect (vFile);
1606 addSetHead(&tmpfileSet,vFile);
1608 /* emit code for the all the variables declared */
1610 /* do the overlay segments */
1611 pic16emitOverlay(ovrFile);
1612 pic16_AnalyzepCode('*');
1615 if(pic16_options.dumpcalltree) {
1617 sprintf(buffer, dstFileName);
1618 strcat(buffer, ".calltree");
1619 cFile = fopen(buffer, "w");
1620 pic16_printCallTree( cFile );
1625 pic16_InlinepCode();
1626 pic16_AnalyzepCode('*');
1628 if(pic16_debug_verbose)
1631 /* now put it all together into the assembler file */
1632 /* create the assembler file name */
1633 if ((noAssemble || options.c1mode) && fullDstFileName) {
1634 sprintf (buffer, fullDstFileName);
1636 sprintf (buffer, dstFileName);
1637 strcat (buffer, ".asm");
1640 if (!(asmFile = fopen (buffer, "w"))) {
1641 werror (E_FILE_OPEN_ERR, buffer);
1645 /* initial comments */
1646 pic16initialComments (asmFile);
1648 /* print module name */
1649 fprintf(asmFile, "#FILE\t\"%s\"\n", fullSrcFileName);
1651 /* Let the port generate any global directives, etc. */
1652 if (port->genAssemblerPreamble) {
1653 port->genAssemblerPreamble(asmFile);
1656 /* print the extern variables to this module */
1657 pic16_printExterns(asmFile);
1659 /* print the global variables in this module */
1660 pic16printPublics (asmFile);
1663 /* copy the sfr segment */
1664 fprintf (asmFile, "%s", iComments2);
1665 fprintf (asmFile, "; special function registers\n");
1666 fprintf (asmFile, "%s", iComments2);
1667 copyFile (asmFile, sfr->oFile);
1670 /* Put all variables into a cblock */
1671 pic16_AnalyzeBanking();
1672 pic16_writeUsedRegs(asmFile);
1675 /* no xdata in pic */
1676 /* if external stack then reserve space of it */
1677 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1678 fprintf (asmFile, "%s", iComments2);
1679 fprintf (asmFile, "; external stack \n");
1680 fprintf (asmFile, "%s", iComments2);
1681 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1682 fprintf (asmFile,";\t.ds 256\n");
1687 /* no xdata in pic */
1688 /* copy xtern ram data */
1689 fprintf (asmFile, "%s", iComments2);
1690 fprintf (asmFile, "; external ram data\n");
1691 fprintf (asmFile, "%s", iComments2);
1692 copyFile (asmFile, xdata->oFile);
1696 /* copy the bit segment */
1697 fprintf (asmFile, "%s", iComments2);
1698 fprintf (asmFile, "; bit data\n");
1699 fprintf (asmFile, "%s", iComments2);
1700 copyFile (asmFile, bit->oFile);
1703 /* copy the interrupt vector table */
1704 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1705 fprintf (asmFile, "%s", iComments2);
1706 fprintf (asmFile, "; interrupt vector \n");
1707 fprintf (asmFile, "%s", iComments2);
1708 copyFile (asmFile, vFile);
1711 /* copy global & static initialisations */
1712 fprintf (asmFile, "%s", iComments2);
1713 fprintf (asmFile, "; global & static initialisations\n");
1714 fprintf (asmFile, "%s", iComments2);
1717 /* copy over code */
1718 fprintf (asmFile, "%s", iComments2);
1719 fprintf (asmFile, "\tcode\n");
1720 fprintf (asmFile, "%s", iComments2);
1723 if(pic16_debug_verbose)
1724 fprintf(asmFile, "; A code from now on!\n");
1725 pic16_copypCode(asmFile, 'A');
1728 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1729 fprintf(asmFile, "\tcode\n");
1730 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1733 /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
1734 /* if external stack is specified then the
1735 * higher order byte of the xdatalocation is
1736 * going into P2 and the lower order going into */
1738 if (options.useXstack) {
1739 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
1740 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
1741 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
1742 (unsigned int)options.xdata_loc & 0xff);
1747 // copyFile (stderr, code->oFile);
1749 fprintf(asmFile, "; I code from now on!\n");
1750 pic16_copypCode(asmFile, 'I');
1752 if(pic16_debug_verbose)
1753 fprintf(asmFile, "; dbName from now on!\n");
1754 pic16_copypCode(asmFile, statsg->dbName);
1757 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1758 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1762 if(pic16_debug_verbose)
1763 fprintf(asmFile, "; X code from now on!\n");
1764 pic16_copypCode(asmFile, 'X');
1766 if(pic16_debug_verbose)
1767 fprintf(asmFile, "; M code from now on!\n");
1768 pic16_copypCode(asmFile, 'M');
1771 pic16_copypCode(asmFile, code->dbName);
1773 pic16_copypCode(asmFile, 'P');
1775 fprintf (asmFile,"\tend\n");