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)) {
145 checkAddSym(&externs, sym);
149 /* if allocation required check is needed
150 * then check if the symbol really requires
151 * allocation only for local variables */
152 if (arFlag && !IS_AGGREGATE (sym->type) &&
153 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
154 !sym->allocreq && sym->level) {
156 // fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
161 /* if global variable & not static or extern
162 * and addPublics allowed then add it to the public set */
163 if ((sym->used) && (sym->level == 0 ||
164 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
166 !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
168 checkAddSym(&publics, sym);
170 if(IS_STATIC(sym->etype)
171 && !(sym->ival && !sym->level)
174 /* add it to udata list */
176 // fprintf(stderr, "%s:%d adding %s (%s) remat=%d\n", __FILE__, __LINE__,
177 // sym->name, sym->rname, sym->remat);
179 //, OP_SYMBOL(operandFromSymbol(sym))->name);
180 #define SET_IMPLICIT 1
183 if(IS_STRUCT(sym->type))
187 reg = pic16_allocDirReg( operandFromSymbol( sym ));
194 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
195 if(!strcmp(ssym->name, reg->name))found=1;
199 if(!found)checkAddReg(&pic16_rel_udata, reg);
203 /* if extern then do nothing or is a function
205 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
206 if(SPEC_OCLS(sym->etype) == code) {
207 // fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
208 checkAddSym(&publics, sym);
214 /* print extra debug info if required */
215 if (options.debug || sym->level == 0) {
216 cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
218 if (!sym->level) /* global */
219 if (IS_STATIC (sym->etype))
220 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
222 fprintf (map->oFile, "G_"); /* scope is global */
224 /* symbol is local */
225 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
226 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
231 /* if is has an absolute address then generate
232 an equate for this no need to allocate space */
233 if (SPEC_ABSA (sym->etype)) {
234 // if (options.debug || sym->level == 0)
235 // fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
236 // sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
238 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
240 SPEC_ADDR (sym->etype));
242 /* emit only if it is global */
243 if(sym->level == 0) {
246 reg = pic16_dirregWithName( sym->name );
249 // fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
250 // __FUNCTION__, __LINE__, sym->name);
252 /* if IS_STRUCT is omitted the following
253 * fixes structures but break char/int etc */
255 if(IS_STRUCT(sym->type))
256 sym->implicit = 1; // mark as implicit
259 reg = pic16_allocDirReg( operandFromSymbol(sym) );
261 if(checkAddReg(&pic16_fix_udata, reg)) {
262 /* and add to globals list if not exist */
263 addSet(&publics, sym);
267 addSet(&publics, sym);
271 if(!sym->used && (sym->level == 0)) {
274 /* symbol not used, just declared probably, but its in
275 * level 0, so we must declare it fine as global */
277 // fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
280 if(IS_STRUCT(sym->type))
281 sym->implicit = 1; // mark as implicit
284 if(IS_AGGREGATE(sym->type)) {
285 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
287 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
295 for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
296 if(!strcmp(ssym->name, reg->name))found=1;
301 if(checkAddReg(&pic16_rel_udata, reg)) {
302 addSetHead(&publics, sym);
311 addSetHead(&publics, sym);
316 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
317 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
318 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
319 if (IS_BITVAR (sym->etype)) {
322 fprintf (map->oFile, "\t%s\n", sym->rname);
323 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
324 for (i = 1; i < size; i++)
325 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
328 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
332 /* FIXME -- VR Fix the following, so that syms to be placed
333 * in the idata section and let linker decide about their fate */
335 /* if it has an initial value then do it only if
336 it is a global variable */
338 if (sym->ival && sym->level == 0) {
342 if(SPEC_OCLS(sym->etype)==data) {
343 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
346 if(SPEC_OCLS(sym->etype)==code) {
347 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
352 fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
353 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
356 if (IS_AGGREGATE (sym->type)) {
357 if(SPEC_ABSA(sym->etype))
358 addSet(&fix_idataSymSet, copySymbol(sym));
360 addSet(&rel_idataSymSet, copySymbol(sym));
361 // ival = initAggregates (sym, sym->ival, NULL);
363 if(SPEC_ABSA(sym->etype))
364 addSet(&fix_idataSymSet, copySymbol(sym));
366 addSet(&rel_idataSymSet, copySymbol(sym));
368 // ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
369 // decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_CHECK));
373 setAstLineno(ival, sym->lineDef);
374 codeOutFile = statsg->oFile;
376 eBBlockFromiCode (iCodeFromAst (ival));
384 /*-----------------------------------------------------------------*/
385 /* pic16_initPointer - pointer initialization code massaging */
386 /*-----------------------------------------------------------------*/
387 value *pic16_initPointer (initList * ilist, sym_link *toType)
393 return valCastLiteral(toType, 0.0);
396 expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
397 // expr = list2expr( ilist );
402 /* try it the old way first */
403 if ((val = constExprValue (expr, FALSE)))
406 /* ( ptr + constant ) */
407 if (IS_AST_OP (expr) &&
408 (expr->opval.op == '+' || expr->opval.op == '-') &&
409 IS_AST_SYM_VALUE (expr->left) &&
410 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
411 compareType(toType, expr->left->ftype) &&
412 IS_AST_LIT_VALUE (expr->right)) {
413 return valForCastAggr (expr->left, expr->left->ftype,
419 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
420 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
421 if (compareType(toType, expr->left->ftype)!=1) {
422 werror (W_INIT_WRONG);
423 printFromToType(expr->left->ftype, toType);
429 /* no then we have to do these cludgy checks */
430 /* pointers can be initialized with address of
431 a variable or address of an array element */
432 if (IS_AST_OP (expr) && expr->opval.op == '&') {
433 /* address of symbol */
434 if (IS_AST_SYM_VALUE (expr->left)) {
435 val = copyValue (AST_VALUE (expr->left));
436 val->type = newLink (DECLARATOR);
437 if(SPEC_SCLS (expr->left->etype) == S_CODE) {
438 DCL_TYPE (val->type) = CPOINTER;
439 DCL_PTR_CONST (val->type) = port->mem.code_ro;
441 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
442 DCL_TYPE (val->type) = FPOINTER;
443 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
444 DCL_TYPE (val->type) = PPOINTER;
445 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
446 DCL_TYPE (val->type) = IPOINTER;
447 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
448 DCL_TYPE (val->type) = EEPPOINTER;
450 DCL_TYPE (val->type) = POINTER;
452 val->type->next = expr->left->ftype;
453 val->etype = getSpec (val->type);
457 /* if address of indexed array */
458 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
459 return valForArray (expr->left);
461 /* if address of structure element then
463 if (IS_AST_OP (expr->left) &&
464 expr->left->opval.op == '.') {
465 return valForStructElem (expr->left->left,
470 (&some_struct)->element */
471 if (IS_AST_OP (expr->left) &&
472 expr->left->opval.op == PTR_OP &&
473 IS_ADDRESS_OF_OP (expr->left->left)) {
474 return valForStructElem (expr->left->left->left,
478 /* case 3. (((char *) &a) +/- constant) */
479 if (IS_AST_OP (expr) &&
480 (expr->opval.op == '+' || expr->opval.op == '-') &&
481 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
482 IS_AST_OP (expr->left->right) &&
483 expr->left->right->opval.op == '&' &&
484 IS_AST_LIT_VALUE (expr->right)) {
486 return valForCastAggr (expr->left->right->left,
487 expr->left->left->opval.lnk,
488 expr->right, expr->opval.op);
491 /* case 4. (char *)(array type) */
492 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
493 IS_ARRAY(expr->right->ftype)) {
495 val = copyValue (AST_VALUE (expr->right));
496 val->type = newLink (DECLARATOR);
497 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
498 DCL_TYPE (val->type) = CPOINTER;
499 DCL_PTR_CONST (val->type) = port->mem.code_ro;
501 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
502 DCL_TYPE (val->type) = FPOINTER;
503 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
504 DCL_TYPE (val->type) = PPOINTER;
505 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
506 DCL_TYPE (val->type) = IPOINTER;
507 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
508 DCL_TYPE (val->type) = EEPPOINTER;
510 DCL_TYPE (val->type) = POINTER;
511 val->type->next = expr->right->ftype->next;
512 val->etype = getSpec (val->type);
518 werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
520 werror (E_INCOMPAT_PTYPES);
526 /*-----------------------------------------------------------------*/
527 /* printPointerType - generates ival for pointer type */
528 /*-----------------------------------------------------------------*/
529 void _pic16_printPointerType (const char *name, char ptype, void *p)
533 sprintf(buf, "LOW(%s)", name);
534 pic16_emitDS(buf, ptype, p);
535 sprintf(buf, "HIGH(%s)", name);
536 pic16_emitDS(buf, ptype, p);
539 /*-----------------------------------------------------------------*/
540 /* printPointerType - generates ival for pointer type */
541 /*-----------------------------------------------------------------*/
542 void pic16_printPointerType (const char *name, char ptype, void *p)
544 _pic16_printPointerType (name, ptype, p);
545 pic16_flushDB(ptype, p);
548 /*-----------------------------------------------------------------*/
549 /* printGPointerType - generates ival for generic pointer type */
550 /*-----------------------------------------------------------------*/
551 void pic16_printGPointerType (const char *iname, const char *oname, const unsigned int itype,
552 const unsigned int type, char ptype, void *p)
554 _pic16_printPointerType (iname, ptype, p);
556 if(itype == FPOINTER || itype == CPOINTER) { // || itype == GPOINTER) {
559 sprintf(buf, "UPPER(%s)", iname);
560 pic16_emitDS(buf, ptype, p);
563 pic16_flushDB(ptype, p);
568 /*-----------------------------------------------------------------*/
569 /* pic16_printIvalType - generates ival for int/char */
570 /*-----------------------------------------------------------------*/
572 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
577 // fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
579 /* if initList is deep */
580 if (ilist && ilist->type == INIT_DEEP)
581 ilist = ilist->init.deep;
583 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
584 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
587 if (!(val = list2val (ilist))) {
588 // assuming a warning has been thrown
592 if (val->type != type) {
593 val = valCastLiteral(type, floatFromVal(val));
597 ulval = (unsigned long) floatFromVal (val);
601 switch (getSize (type)) {
603 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
607 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
608 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
612 pic16_emitDB(BYTE_IN_LONG(ulval,0), ptype, p);
613 pic16_emitDB(BYTE_IN_LONG(ulval,1), ptype, p);
614 pic16_emitDB(BYTE_IN_LONG(ulval,2), ptype, p);
615 pic16_emitDB(BYTE_IN_LONG(ulval,3), ptype, p);
620 /*--------------------------------------------------------------------*/
621 /* pic16_printIvalChar - generates initital value for character array */
622 /*--------------------------------------------------------------------*/
624 pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
633 // fprintf(stderr, "%s\n",__FUNCTION__);
637 val = list2val (ilist);
638 /* if the value is a character string */
639 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
641 if (!DCL_ELEM (type))
642 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
644 for(remain=0; remain<DCL_ELEM(type); remain++)
645 pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
647 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
649 pic16_emitDB(0x00, ptype, p);
658 for(remain=0; remain<strlen(s); remain++) {
659 pic16_emitDB(s[remain], ptype, p);
665 /*-----------------------------------------------------------------*/
666 /* pic16_printIvalArray - generates code for array initialization */
667 /*-----------------------------------------------------------------*/
669 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
673 int lcnt = 0, size = 0;
679 /* take care of the special case */
680 /* array of characters can be init */
682 if (IS_CHAR (type->next)) {
683 if (!IS_LITERAL(list2val(ilist)->etype)) {
684 werror (W_INIT_WRONG);
688 if(pic16_printIvalChar (type,
689 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
690 SPEC_CVAL (sym->etype).v_char, ptype, p))
693 /* not the special case */
694 if (ilist && ilist->type != INIT_DEEP)
696 werror (E_INIT_STRUCT, sym->name);
700 iloop = ilist->init.deep;
701 lcnt = DCL_ELEM (type);
706 pic16_printIval (sym, type->next, iloop, ptype, p);
707 iloop = (iloop ? iloop->next : NULL);
710 /* if not array limits given & we */
711 /* are out of initialisers then */
712 if (!DCL_ELEM (type) && !iloop)
715 /* no of elements given and we */
716 /* have generated for all of them */
718 /* if initializers left */
720 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
726 /* if we have not been given a size */
727 if (!DCL_ELEM (type))
728 DCL_ELEM (type) = size;
733 /*-----------------------------------------------------------------*/
734 /* pic16_printIvalBitFields - generate initializer for bitfields */
735 /*-----------------------------------------------------------------*/
736 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
740 initList *lilist = *ilist ;
741 unsigned long ival = 0;
747 val = list2val(lilist);
749 if (SPEC_BLEN(lsym->etype) > 8) {
750 size += ((SPEC_BLEN (lsym->etype) / 8) +
751 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
754 size = ((SPEC_BLEN (lsym->etype) / 8) +
755 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
757 i = (unsigned long)floatFromVal(val);
758 i <<= SPEC_BSTR (lsym->etype);
760 if (! ( lsym->next &&
761 (IS_BITFIELD(lsym->next->type)) &&
762 (SPEC_BSTR(lsym->next->etype)))) break;
764 lilist = lilist->next;
768 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
772 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
773 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
776 case 4: /* EEP: why is this db and not dw? */
777 pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
778 pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
779 pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
780 pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
783 /* VR - only 1,2,4 size long can be handled???? Why? */
784 fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
792 /*-----------------------------------------------------------------*/
793 /* printIvalStruct - generates initial value for structures */
794 /*-----------------------------------------------------------------*/
795 void pic16_printIvalStruct (symbol * sym, sym_link * type,
796 initList * ilist, char ptype, void *p)
799 initList *iloop = NULL;
801 sflds = SPEC_STRUCT (type)->fields;
804 if (ilist->type != INIT_DEEP) {
805 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
809 iloop = ilist->init.deep;
812 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
813 // fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
814 if (IS_BITFIELD(sflds->type)) {
815 pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
817 pic16_printIval (sym, sflds->type, iloop, ptype, p);
821 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
826 /*--------------------------------------------------------------------------*/
827 /* pic16_printIvalCharPtr - generates initial values for character pointers */
828 /*--------------------------------------------------------------------------*/
829 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
833 /* PENDING: this is _very_ mcs51 specific, including a magic
835 It's also endin specific.
837 VR - Attempting to port this function to pic16 port - 8-Jun-2004
840 // fprintf(stderr, "%s\n",__FUNCTION__);
842 size = getSize (type);
844 if (val->name && strlen (val->name))
846 if (size == 1) /* This appears to be Z80 specific?? */
848 pic16_emitDS(val->name, ptype, p);
852 pic16_printPointerType (val->name, ptype, p);
857 if (IS_PTR (val->type)) {
858 type = DCL_TYPE (val->type);
860 type = PTR_TYPE (SPEC_OCLS (val->etype));
862 if (val->sym && val->sym->isstrlit) {
863 // this is a literal string
866 pic16_printGPointerType(val->name, sym->name, type, type, ptype, p);
870 fprintf (stderr, "*** internal error: unknown size in "
871 "printIvalCharPtr.\n");
877 // these are literals assigned to pointers
881 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
884 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
885 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
888 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
889 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
890 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
898 if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
899 if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
900 else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
906 /*-----------------------------------------------------------------------*/
907 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
908 /*-----------------------------------------------------------------------*/
909 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
915 val = list2val (ilist);
917 val = valCastLiteral(type, 0.0);
920 // an error has been thrown already
924 if (IS_LITERAL(val->etype)) {
925 if (compareType(type, val->etype) == 0) {
926 werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
927 printFromToType (val->type, type);
929 pic16_printIvalCharPtr (NULL, type, val, ptype, p);
933 /* check the types */
934 if ((dLvl = compareType (val->type, type->next)) <= 0)
936 pic16_emitDB(0x00, ptype, p);
940 /* now generate the name */
942 pic16_printPointerType (val->name, ptype, p);
944 pic16_printPointerType (val->sym->rname, ptype, p);
951 /*-----------------------------------------------------------------*/
952 /* pic16_printIvalPtr - generates initial value for pointers */
953 /*-----------------------------------------------------------------*/
954 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
960 fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
961 sym->rname, getSize(sym->type));
965 if (ilist && (ilist->type == INIT_DEEP))
966 ilist = ilist->init.deep;
968 /* function pointer */
969 if (IS_FUNC (type->next))
971 pic16_printIvalFuncPtr (type, ilist, ptype, p);
975 if (!(val = pic16_initPointer (ilist, type)))
978 /* if character pointer */
979 if (IS_CHAR (type->next))
980 if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
984 if (compareType (type, val->type) == 0) {
985 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
986 printFromToType (val->type, type);
989 /* if val is literal */
990 if (IS_LITERAL (val->etype))
992 switch (getSize (type))
995 pic16_emitDB((unsigned int)floatFromVal(val) & 0xff, ptype, p);
998 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
999 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1002 pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1003 pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1004 pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1012 size = getSize (type);
1014 if (size == 1) /* Z80 specific?? */
1016 pic16_emitDS(val->name, ptype, p);
1020 pic16_printPointerType (val->name, ptype, p);
1024 pic16_printGPointerType (val->name, sym->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1025 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1026 PTR_TYPE (SPEC_OCLS (val->etype))), ptype, p);
1034 /*-----------------------------------------------------------------*/
1035 /* pic16_printIval - generates code for initial value */
1036 /*-----------------------------------------------------------------*/
1037 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1045 fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1046 fprintf(stderr, "%s: IS_STRUCT: %d IS_ARRAY: %d IS_PTR: %d IS_SPEC: %d\n", sym->name,
1047 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1050 /* if structure then */
1051 if (IS_STRUCT (type))
1053 // fprintf(stderr,"%s struct\n",__FUNCTION__);
1054 pic16_printIvalStruct (sym, type, ilist, ptype, p);
1058 /* if this is an array */
1059 if (IS_ARRAY (type))
1061 // fprintf(stderr,"%s array\n",__FUNCTION__);
1062 pic16_printIvalArray (sym, type, ilist, ptype, p);
1069 // not an aggregate, ilist must be a node
1070 if (ilist->type!=INIT_NODE) {
1071 // or a 1-element list
1072 if (ilist->init.deep->next) {
1073 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1076 ilist=ilist->init.deep;
1081 // and the type must match
1082 itype=ilist->init.node->ftype;
1084 if (compareType(type, itype)==0) {
1085 // special case for literal strings
1086 if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1087 // which are really code pointers
1088 IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1091 // werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1092 // printFromToType(itype, type);
1099 /* if this is a pointer */
1102 // fprintf(stderr,"%s pointer\n",__FUNCTION__);
1103 pic16_printIvalPtr (sym, type, ilist, ptype, p);
1108 /* if type is SPECIFIER */
1111 // fprintf(stderr,"%s spec\n",__FUNCTION__);
1112 pic16_printIvalType (sym, type, ilist, ptype, p);
1117 int PIC16_IS_CONFIG_ADDRESS(int address)
1119 return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1122 int PIC16_IS_IDLOC_ADDRESS(int address)
1124 return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1127 /* wrapper function for the above */
1128 int PIC16_IS_HWREG_ADDRESS(int address)
1130 return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1134 /*-----------------------------------------------------------------*/
1135 /* emitStaticSeg - emitcode for the static segment */
1136 /*-----------------------------------------------------------------*/
1138 pic16emitStaticSeg (memmap * map)
1142 //fprintf(stderr, "%s\n",__FUNCTION__);
1146 /* for all variables in this segment do */
1147 for (sym = setFirstItem (map->syms); sym;
1148 sym = setNextItem (map->syms))
1152 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1153 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1154 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1155 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1156 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1157 printTypeChain( sym->type, stderr );
1158 fprintf(stderr, "\n");
1161 if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1162 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1163 (int) floatFromVal(list2val(sym->ival)));
1168 if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1169 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1170 (char) floatFromVal(list2val(sym->ival)));
1175 /* if it is "extern" then do nothing */
1176 if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
1177 checkAddSym(&externs, sym);
1181 /* if it is not static add it to the public
1183 if (!IS_STATIC (sym->etype)) {
1184 /* do not emit if it is a config word declaration */
1185 checkAddSym(&publics, sym);
1188 /* print extra debug info if required */
1189 if (options.debug || sym->level == 0) {
1190 /* NOTE to me - cdbFile may be null in which case,
1191 * the sym name will be printed to stdout. oh well */
1192 debugFile->writeSymbol(sym);
1195 /* if it has an absolute address */
1196 if (SPEC_ABSA (sym->etype)) {
1197 // fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1198 // __FILE__, __LINE__, sym->name);
1200 /* if it has an initial value */
1208 /* symbol has absolute address and initial value */
1210 resolveIvalSym (sym->ival, sym->type);
1211 asym = newSymbol(sym->rname, 0);
1212 abSym = Safe_calloc(1, sizeof(absSym));
1213 abSym->name = Safe_strdup( sym->rname );
1214 abSym->address = SPEC_ADDR( sym->etype );
1215 addSet(&absSymSet, abSym);
1217 pb = pic16_newpCodeChain(NULL, 'A',pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1218 pic16_addpBlock(pb);
1220 pcf = pic16_newpCodeFunction(moduleName, asym->name);
1221 PCF(pcf)->absblock = 1;
1223 pic16_addpCode2pBlock(pb,pcf);
1224 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1225 // fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1226 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1227 pic16_flushDB('p', (void *)pb);
1229 pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1235 /* symbol has absolute address but no initial value */
1237 /* allocate space */
1238 fprintf (code->oFile, "%s:\n", sym->rname);
1240 /* special case for character strings */
1241 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1242 SPEC_CVAL (sym->etype).v_char) {
1244 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1246 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1253 // fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1254 // __FILE__, __LINE__, sym->name);
1256 /* if it has an initial value */
1260 /* symbol doesn't have absolute address but has initial value */
1261 fprintf (code->oFile, "%s:\n", sym->rname);
1263 resolveIvalSym (sym->ival, sym->type);
1265 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1266 pic16_addpBlock(pb);
1268 // fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1270 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1271 pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1272 pic16_flushDB('p', (void *)pb);
1276 /* symbol doesn't have absolute address and no initial value */
1277 /* allocate space */
1278 // fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1279 fprintf (code->oFile, "%s:\n", sym->rname);
1280 /* special case for character strings */
1281 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1282 SPEC_CVAL (sym->etype).v_char) {
1284 // fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1286 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1297 /*-----------------------------------------------------------------*/
1298 /* pic16_emitConfigRegs - emits the configuration registers */
1299 /*-----------------------------------------------------------------*/
1300 void pic16_emitConfigRegs(FILE *of)
1304 for(i=0;i<pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart;i++)
1305 if(pic16->cwInfo.crInfo[i].emit) //mask != -1)
1306 fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1307 pic16->cwInfo.confAddrStart+i,
1308 pic16->cwInfo.crInfo[i].value);
1311 void pic16_emitIDRegs(FILE *of)
1315 for(i=0;i<pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart;i++)
1316 if(pic16->idInfo.irInfo[i].emit)
1317 fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1318 pic16->idInfo.idAddrStart+i,
1319 pic16->idInfo.irInfo[i].value);
1326 /* no special considerations for the following
1327 data, idata & bit & xdata */
1328 pic16emitRegularMap (data, TRUE, TRUE);
1329 pic16emitRegularMap (idata, TRUE, TRUE);
1330 pic16emitRegularMap (bit, TRUE, FALSE);
1331 pic16emitRegularMap (xdata, TRUE, TRUE);
1332 pic16emitRegularMap (sfr, FALSE, FALSE);
1333 pic16emitRegularMap (sfrbit, FALSE, FALSE);
1334 pic16emitRegularMap (code, TRUE, FALSE);
1335 pic16emitStaticSeg (statsg);
1338 /*-----------------------------------------------------------------*/
1339 /* createInterruptVect - creates the interrupt vector */
1340 /*-----------------------------------------------------------------*/
1342 pic16createInterruptVect (FILE * vFile)
1344 /* if the main is only a prototype ie. no body then do nothing */
1346 if (!IFFUNC_HASBODY(mainf->type)) {
1347 /* if ! compile only then main function should be present */
1348 if (!options.cc_only)
1354 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1355 fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
1356 fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1358 /* this is an overkill since WE are the port,
1359 * and we know if we have a genIVT function! */
1361 port->genIVT(vFile, interrupts, maxInterrupts);
1368 /*-----------------------------------------------------------------*/
1369 /* pic16initialComments - puts in some initial comments */
1370 /*-----------------------------------------------------------------*/
1372 pic16initialComments (FILE * afile)
1374 initialComments (afile);
1375 fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1376 fprintf (afile, iComments2);
1380 /*-----------------------------------------------------------------*/
1381 /* printPublics - generates global declarations for publics */
1382 /*-----------------------------------------------------------------*/
1384 pic16printPublics (FILE *afile)
1388 fprintf (afile, "%s", iComments2);
1389 fprintf (afile, "; public variables in this module\n");
1390 fprintf (afile, "%s", iComments2);
1392 for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1393 fprintf(afile, "\tglobal %s\n", sym->rname);
1396 /*-----------------------------------------------------------------*/
1397 /* printExterns - generates extern declarations for externs */
1398 /*-----------------------------------------------------------------*/
1400 pic16_printExterns(FILE *afile)
1404 fprintf(afile, "%s", iComments2);
1405 fprintf(afile, "; extern variables in this module\n");
1406 fprintf(afile, "%s", iComments2);
1408 for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1409 fprintf(afile, "\textern %s\n", sym->rname);
1411 for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1412 fprintf(afile, "\textern _%s\n", sym->name);
1415 /*-----------------------------------------------------------------*/
1416 /* emitOverlay - will emit code for the overlay stuff */
1417 /*-----------------------------------------------------------------*/
1419 pic16emitOverlay (FILE * afile)
1423 if (!elementsInSet (ovrSetSets))
1424 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
1426 /* for each of the sets in the overlay segment do */
1427 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1428 ovrset = setNextItem (ovrSetSets))
1433 if (elementsInSet (ovrset))
1435 /* this dummy area is used to fool the assembler
1436 otherwise the assembler will append each of these
1437 declarations into one chunk and will not overlay
1439 fprintf (afile, ";\t.area _DUMMY\n");
1440 /* output the area informtion */
1441 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1444 for (sym = setFirstItem (ovrset); sym;
1445 sym = setNextItem (ovrset))
1448 /* if extern then do nothing */
1449 if (IS_EXTERN (sym->etype))
1452 /* if allocation required check is needed
1453 then check if the symbol really requires
1454 allocation only for local variables */
1455 if (!IS_AGGREGATE (sym->type) &&
1456 !(sym->_isparm && !IS_REGPARM (sym->etype))
1457 && !sym->allocreq && sym->level)
1460 /* if global variable & not static or extern
1461 and addPublics allowed then add it to the public set */
1462 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1463 && !IS_STATIC (sym->etype)) {
1464 // fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1465 checkAddSym(&publics, sym);
1466 // addSetHead (&publics, sym);
1469 /* if extern then do nothing or is a function
1471 if (IS_FUNC (sym->type))
1475 /* print extra debug info if required */
1476 if (options.debug || sym->level == 0)
1479 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1483 if (IS_STATIC (sym->etype))
1484 fprintf (afile, "F%s_", moduleName); /* scope is file */
1486 fprintf (afile, "G_"); /* scope is global */
1489 /* symbol is local */
1490 fprintf (afile, "L%s_",
1491 (sym->localof ? sym->localof->name : "-null-"));
1492 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
1496 /* if is has an absolute address then generate
1497 an equate for this no need to allocate space */
1498 if (SPEC_ABSA (sym->etype))
1501 if (options.debug || sym->level == 0)
1502 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1504 fprintf (afile, "%s\t=\t0x%04x\n",
1506 SPEC_ADDR (sym->etype));
1510 if (options.debug || sym->level == 0)
1511 fprintf (afile, "==.\n");
1513 /* allocate space */
1514 fprintf (afile, "%s:\n", sym->rname);
1515 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1523 /*-----------------------------------------------------------------*/
1524 /* glue - the final glue that hold the whole thing together */
1525 /*-----------------------------------------------------------------*/
1532 FILE *ovrFile = tempfile();
1535 mainf = newSymbol ("main", 0);
1538 mainf = findSymWithLevel(SymbolTab, mainf);
1540 /* only if the main function exists */
1541 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
1542 if (!options.cc_only)
1548 // fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
1550 addSetHead(&tmpfileSet,ovrFile);
1551 pic16_pCodeInitRegisters();
1553 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1554 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1556 pic16_addpBlock(pb);
1558 /* entry point @ start of CSEG */
1559 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1562 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1563 pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack"))));
1564 pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1565 pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack"))));
1568 /* put in the call to main */
1569 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1571 if (options.mainreturn) {
1572 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1573 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1575 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1576 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1580 /* At this point we've got all the code in the form of pCode structures */
1581 /* Now it needs to be rearranged into the order it should be placed in the */
1584 pic16_movepBlock2Head('P'); // Last
1585 pic16_movepBlock2Head(code->dbName);
1586 pic16_movepBlock2Head('X');
1587 pic16_movepBlock2Head(statsg->dbName); // First
1589 /* print the global struct definitions */
1590 // if (options.debug)
1591 // cdbStructBlock (0); //,cdbFile);
1594 /* PENDING: this isnt the best place but it will do */
1595 if (port->general.glue_up_main) {
1596 /* create the interrupt vector table */
1597 pic16createInterruptVect (vFile);
1600 addSetHead(&tmpfileSet,vFile);
1602 /* emit code for the all the variables declared */
1604 /* do the overlay segments */
1605 pic16emitOverlay(ovrFile);
1606 pic16_AnalyzepCode('*');
1609 if(pic16_options.dumpcalltree) {
1611 sprintf(buffer, dstFileName);
1612 strcat(buffer, ".calltree");
1613 cFile = fopen(buffer, "w");
1614 pic16_printCallTree( cFile );
1619 pic16_InlinepCode();
1620 pic16_AnalyzepCode('*');
1622 if(pic16_debug_verbose)
1625 /* now put it all together into the assembler file */
1626 /* create the assembler file name */
1627 if ((noAssemble || options.c1mode) && fullDstFileName) {
1628 sprintf (buffer, fullDstFileName);
1630 sprintf (buffer, dstFileName);
1631 strcat (buffer, ".asm");
1634 if (!(asmFile = fopen (buffer, "w"))) {
1635 werror (E_FILE_OPEN_ERR, buffer);
1639 /* initial comments */
1640 pic16initialComments (asmFile);
1642 /* print module name */
1643 fprintf(asmFile, "#FILE\t\"%s\"\n", fullSrcFileName);
1645 /* Let the port generate any global directives, etc. */
1646 if (port->genAssemblerPreamble) {
1647 port->genAssemblerPreamble(asmFile);
1650 /* print the extern variables to this module */
1651 pic16_printExterns(asmFile);
1653 /* print the global variables in this module */
1654 pic16printPublics (asmFile);
1657 /* copy the sfr segment */
1658 fprintf (asmFile, "%s", iComments2);
1659 fprintf (asmFile, "; special function registers\n");
1660 fprintf (asmFile, "%s", iComments2);
1661 copyFile (asmFile, sfr->oFile);
1664 /* Put all variables into a cblock */
1665 pic16_AnalyzeBanking();
1666 pic16_writeUsedRegs(asmFile);
1669 /* no xdata in pic */
1670 /* if external stack then reserve space of it */
1671 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1672 fprintf (asmFile, "%s", iComments2);
1673 fprintf (asmFile, "; external stack \n");
1674 fprintf (asmFile, "%s", iComments2);
1675 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1676 fprintf (asmFile,";\t.ds 256\n");
1681 /* no xdata in pic */
1682 /* copy xtern ram data */
1683 fprintf (asmFile, "%s", iComments2);
1684 fprintf (asmFile, "; external ram data\n");
1685 fprintf (asmFile, "%s", iComments2);
1686 copyFile (asmFile, xdata->oFile);
1690 /* copy the bit segment */
1691 fprintf (asmFile, "%s", iComments2);
1692 fprintf (asmFile, "; bit data\n");
1693 fprintf (asmFile, "%s", iComments2);
1694 copyFile (asmFile, bit->oFile);
1697 /* copy the interrupt vector table */
1698 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1699 fprintf (asmFile, "%s", iComments2);
1700 fprintf (asmFile, "; interrupt vector \n");
1701 fprintf (asmFile, "%s", iComments2);
1702 copyFile (asmFile, vFile);
1705 /* copy global & static initialisations */
1706 fprintf (asmFile, "%s", iComments2);
1707 fprintf (asmFile, "; global & static initialisations\n");
1708 fprintf (asmFile, "%s", iComments2);
1711 /* copy over code */
1712 fprintf (asmFile, "%s", iComments2);
1713 fprintf (asmFile, "\tcode\n");
1714 fprintf (asmFile, "%s", iComments2);
1717 if(pic16_debug_verbose)
1718 fprintf(asmFile, "; A code from now on!\n");
1719 pic16_copypCode(asmFile, 'A');
1722 if(mainf && IFFUNC_HASBODY(mainf->type)) {
1723 fprintf(asmFile, "\tcode\n");
1724 fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1727 /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
1728 /* if external stack is specified then the
1729 * higher order byte of the xdatalocation is
1730 * going into P2 and the lower order going into */
1732 if (options.useXstack) {
1733 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
1734 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
1735 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
1736 (unsigned int)options.xdata_loc & 0xff);
1741 // copyFile (stderr, code->oFile);
1743 fprintf(asmFile, "; I code from now on!\n");
1744 pic16_copypCode(asmFile, 'I');
1746 if(pic16_debug_verbose)
1747 fprintf(asmFile, "; dbName from now on!\n");
1748 pic16_copypCode(asmFile, statsg->dbName);
1751 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1752 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1756 if(pic16_debug_verbose)
1757 fprintf(asmFile, "; X code from now on!\n");
1758 pic16_copypCode(asmFile, 'X');
1760 if(pic16_debug_verbose)
1761 fprintf(asmFile, "; M code from now on!\n");
1762 pic16_copypCode(asmFile, 'M');
1765 pic16_copypCode(asmFile, code->dbName);
1767 pic16_copypCode(asmFile, 'P');
1769 fprintf (asmFile,"\tend\n");