1 /*-------------------------------------------------------------------------
3 SDCCglue.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"
33 #include "dbuf_string.h"
36 #ifdef WORDS_BIGENDIAN
37 #define _ENDIAN(x) (3-x)
39 #define _ENDIAN(x) (x)
42 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
44 extern symbol *interrupts[256];
45 static void showAllMemmaps(FILE *of); // XXX: emits initialized symbols
49 extern unsigned maxInterrupts;
50 extern int maxRegBank;
52 extern char *VersionString;
53 extern struct dbuf_s *codeOutBuf;
54 extern char *iComments1;
55 extern char *iComments2;
56 //extern void emitStaticSeg (memmap * map);
57 set *pic14_localFunctions = NULL;
59 extern DEFSETFUNC (closeTmpFiles);
60 extern DEFSETFUNC (rmTmpFiles);
62 extern void AnalyzeBanking (void);
63 extern void ReuseReg(void);
64 extern void InlinepCode(void);
65 extern void writeUsedRegs(FILE *);
67 extern void initialComments (FILE * afile);
68 extern void printPublics (FILE * afile);
70 extern void printChar (FILE * ofile, char *s, int plen);
71 void pCodeInitRegisters(void);
72 int getConfigWord(int address);
73 int getHasSecondConfigReg(void);
75 char *udata_section_name=0; // FIXME Temporary fix to change udata section name -- VR
76 int pic14_hasInterrupt = 0; // Indicates whether to emit interrupt handler or not
78 static set *emitted = NULL;
79 int pic14_stringInSet(const char *str, set **world, int autoAdd);
80 static void emitSymbol (struct dbuf_s *oBuf, const char *name, const char *section_type, int size, int addr, int useEQU, int globalize);
82 /*-----------------------------------------------------------------*/
83 /* aopLiteral - string from a literal value */
84 /*-----------------------------------------------------------------*/
85 unsigned int pic14aopLiteral (value *val, int offset)
92 /* if it is a float then it gets tricky */
93 /* otherwise it is fairly simple */
94 if (!IS_FLOAT(val->type)) {
95 unsigned long v = (unsigned long) floatFromVal(val);
97 return ( (v >> (offset * 8)) & 0xff);
100 /* it is type float */
101 fl.f = (float) floatFromVal(val);
102 #ifdef WORDS_BIGENDIAN
103 return fl.c[3-offset];
111 is_valid_identifier( const char *name )
117 /* only accept [a-zA-Z_][a-zA-Z0-9_] */
118 if (!((a >= 'a' && a <= 'z')
119 || (a >= 'A' && a <= 'z')
124 while ((a = *name++))
126 if (!((a >= 'a' && a <= 'z')
127 || (a >= 'A' && a <= 'Z')
128 || (a >= '0' && a <= '9')
133 /* valid identifier */
137 #define IS_DEFINED_HERE(sym) (!IS_EXTERN(sym->etype))
138 extern int IS_CONFIG_ADDRESS( int addr );
140 pic14_constructAbsMap (struct dbuf_s *oBuf)
142 memmap *maps[] = { data, sfr, NULL };
147 int addr, min=-1, max=-1;
150 int low, high, shared;
152 for (i=0; maps[i] != NULL; i++)
154 for (sym = (symbol *)setFirstItem (maps[i]->syms);
155 sym; sym = setNextItem (maps[i]->syms))
157 if (IS_DEFINED_HERE(sym) && SPEC_ABSA(sym->etype))
159 addr = SPEC_ADDR(sym->etype);
161 /* handle CONFIG words here */
162 if (IS_CONFIG_ADDRESS( addr ))
164 //fprintf( stderr, "%s: assignment to CONFIG@0x%x found\n", __FUNCTION__, addr );
165 //fprintf( stderr, "ival: %p (0x%x)\n", sym->ival, (int)list2int( sym->ival ) );
167 pic14_assignConfigWordValue( addr, (int)list2int( sym->ival ) );
169 fprintf( stderr, "ERROR: Symbol %s, which is covering a __CONFIG word must be initialized!\n", sym->name );
174 if (max == -1 || addr > max) max = addr;
175 if (min == -1 || addr < min) min = addr;
176 //fprintf (stderr, "%s: sym %s @ 0x%x\n", __FUNCTION__, sym->name, addr);
177 aliases = hTabItemWithKey (ht, addr);
179 /* May not use addSetHead, as we cannot update the
180 * list's head in the hastable `ht'. */
181 addSet (&aliases, sym);
183 fprintf( stderr, "%s: now %d aliases for %s @ 0x%x\n",
184 __FUNCTION__, elementsInSet(aliases), sym->name, addr);
187 addSet (&aliases, sym);
188 hTabAddItem (&ht, addr, aliases);
194 /* now emit definitions for all absolute symbols */
195 dbuf_printf (oBuf, "%s", iComments2);
196 dbuf_printf (oBuf, "; absolute symbol definitions\n");
197 dbuf_printf (oBuf, "%s", iComments2);
198 for (addr=min; addr <= max; addr++)
201 aliases = hTabItemWithKey (ht, addr);
202 if (aliases && elementsInSet(aliases)) {
203 /* Make sure there is no initialized value at this location! */
204 for (sym = setFirstItem(aliases); sym; sym = setNextItem(aliases)) {
205 if (sym->ival) break;
209 dbuf_printf (oBuf, "udata_abs_%s_%x\tudata_ovr\t0x%04x\n",
210 moduleName, addr, addr);
211 for (sym = setFirstItem (aliases); sym;
212 sym = setNextItem (aliases))
214 if (getSize(sym->type) > size) {
215 size = getSize(sym->type);
218 /* initialized values are handled somewhere else */
219 if (sym->ival) continue;
221 /* emit STATUS as well as _STATUS, required for SFRs only */
222 dbuf_printf (oBuf, "%s\n", sym->name);
223 dbuf_printf (oBuf, "%s\n", sym->rname);
225 // global symbols must be emitted again as 'global sym->name'
226 pic14_stringInSet(sym->name, &emitted, 1);
227 pic14_stringInSet(sym->rname, &emitted, 1);
230 dbuf_printf (oBuf, "\tres\t%d\n", size);
234 /* also emit STK symbols
235 * XXX: This is ugly and fails as soon as devices start to get
236 * differently sized sharebanks, since STK12 will be
237 * required by larger devices but only up to STK03 might
238 * be defined using smaller devices. */
239 dbuf_printf (oBuf, "\n");
240 shared = pic14_getSharedStack(&low, &high, &size);
241 if (!pic14_options.isLibrarySource)
243 pic = pic14_getPIC();
245 dbuf_printf (oBuf, "\tglobal PSAVE\n");
246 dbuf_printf (oBuf, "\tglobal SSAVE\n");
247 dbuf_printf (oBuf, "\tglobal WSAVE\n");
248 for (i = size - 4; i >= 0; i--) {
249 dbuf_printf (oBuf, "\tglobal STK%02d\n", i);
252 // 16f84 has no SHAREBANK (in linkerscript) but memory aliased in two
255 // for single banked devices: use normal, "banked" RAM
256 dbuf_printf (oBuf, "sharebank udata_ovr 0x%04X\n", low);
258 // for devices with at least two banks, require a sharebank section
259 dbuf_printf (oBuf, "sharebank udata_shr\n");
261 dbuf_printf (oBuf, "PSAVE\tres 1\n");
262 dbuf_printf (oBuf, "SSAVE\tres 1\n");
263 dbuf_printf (oBuf, "WSAVE\tres 1\n"); // WSAVE *must* be in sharebank (IRQ handlers)
264 /* fill rest of sharebank with stack STKxx .. STK00 */
265 for (i = size - 4; i >= 0; i--) {
266 dbuf_printf (oBuf, "STK%02d\tres 1\n", i);
269 /* declare STKxx as extern for all files
270 * except the one containing main() */
271 dbuf_printf (oBuf, "\textern PSAVE\n");
272 dbuf_printf (oBuf, "\textern SSAVE\n");
273 dbuf_printf (oBuf, "\textern WSAVE\n");
274 for (i = size - 4; i >= 0; i--) {
276 SNPRINTF(&buffer[0], 127, "STK%02d", i);
277 dbuf_printf (oBuf, "\textern %s\n", &buffer[0]);
278 pic14_stringInSet(&buffer[0], &emitted, 1);
283 /*-----------------------------------------------------------------*/
284 /* emitRegularMap - emit code for maps with no special cases */
285 /*-----------------------------------------------------------------*/
287 pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
292 /* print the area name */
294 dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
296 for (sym = setFirstItem (map->syms); sym;
297 sym = setNextItem (map->syms)) {
299 //printf("%s\n",sym->name);
301 /* ignore if config word */
302 if (SPEC_ABSA(sym->etype)
303 && IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype)))
306 /* if extern then add it into the extern list */
307 if (IS_EXTERN (sym->etype)) {
308 addSetHead (&externs, sym);
312 /* if allocation required check is needed
313 then check if the symbol really requires
314 allocation only for local variables */
315 if (arFlag && !IS_AGGREGATE (sym->type) &&
316 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
317 !sym->allocreq && sym->level)
320 /* if global variable & not static or extern
321 and addPublics allowed then add it to the public set */
322 if ((sym->level == 0 ||
323 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
325 !IS_STATIC (sym->etype))
327 //fprintf( stderr, "%s: made public %s\n", __FUNCTION__, sym->name );
328 addSetHead (&publics, sym);
331 // PIC code allocates its own registers - so ignore parameter variable generated by processFuncArgs()
334 /* if extern then do nothing or is a function
336 if (IS_FUNC (sym->type))
339 /* print extra debug info if required */
340 if (options.debug || sym->level == 0)
342 if (!sym->level) /* global */
343 if (IS_STATIC (sym->etype))
344 dbuf_printf (&map->oBuf, "F%s_", moduleName); /* scope is file */
346 dbuf_printf (&map->oBuf, "G_"); /* scope is global */
348 /* symbol is local */
349 dbuf_printf (&map->oBuf, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
350 dbuf_printf (&map->oBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
353 /* absolute symbols are handled in pic14_constructAbsMap */
354 if (SPEC_ABSA(sym->etype) && IS_DEFINED_HERE(sym))
357 /* if it has an absolute address then generate
358 an equate for this no need to allocate space */
359 if (0 && SPEC_ABSA (sym->etype))
361 //if (options.debug || sym->level == 0)
362 //dbuf_printf (&map->oBuf,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
364 dbuf_printf (&map->oBuf, "%s\tEQU\t0x%04x\n",
366 SPEC_ADDR (sym->etype));
372 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
373 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
374 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
375 if (IS_BITVAR (sym->etype))
382 emitSymbol (&map->oBuf,
385 getSize (sym->type) & 0xffff,
386 SPEC_ABSA(sym->etype)
387 ? SPEC_ADDR(sym->etype)
396 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
398 for (i = 1; i < size; i++)
399 dbuf_printf (&map->oBuf, "\t%s_%d\n", sym->rname, i);
404 //dbuf_printf (&map->oBuf, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
407 /* if it has a initial value then do it only if
408 it is a global variable */
410 /* mark symbol as already defined */
411 pic14_stringInSet(sym->name, &emitted, 1);
412 pic14_stringInSet(sym->rname, &emitted, 1);
415 /* if it has a initial value then do it only if
416 it is a global variable */
417 if (sym->ival && sym->level == 0) {
420 if (IS_AGGREGATE (sym->type))
421 ival = initAggregates (sym, sym->ival, NULL);
423 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
424 decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
425 codeOutBuf = &statsg->oBuf;
427 eBBlockFromiCode (iCodeFromAst (ival));
436 /*-----------------------------------------------------------------*/
437 /* printIvalType - generates ival for int/char */
438 /*-----------------------------------------------------------------*/
440 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
445 //fprintf(stderr, "%s\n",__FUNCTION__);
447 /* if initList is deep */
448 if (ilist->type == INIT_DEEP)
449 ilist = ilist->init.deep;
451 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
452 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
455 if (!(val = list2val (ilist))) {
456 // assuming a warning has been thrown
460 if (val->type != type) {
461 val = valCastLiteral(type, floatFromVal(val));
465 ulval = (unsigned long) floatFromVal (val);
469 switch (getSize (type)) {
471 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
475 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
476 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
480 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
481 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
482 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
483 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
488 /*-----------------------------------------------------------------*/
489 /* printIvalBitFields - generate initializer for bitfields */
490 /*-----------------------------------------------------------------*/
491 static void printIvalBitFields(symbol **sym, initList **ilist, pBlock *pb )
495 initList *lilist = *ilist ;
496 unsigned long ival = 0;
502 val = list2val(lilist);
504 if (SPEC_BLEN(lsym->etype) > 8) {
505 size += ((SPEC_BLEN (lsym->etype) / 8) +
506 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
509 size = ((SPEC_BLEN (lsym->etype) / 8) +
510 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
512 i = (unsigned long)floatFromVal(val);
513 i <<= SPEC_BSTR (lsym->etype);
515 if (! ( lsym->next &&
516 (IS_BITFIELD(lsym->next->type)) &&
517 (SPEC_BSTR(lsym->next->etype)))) break;
519 lilist = lilist->next;
523 //tfprintf (oFile, "\t!db !constbyte\n",ival);
524 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
528 //tfprintf (oFile, "\t!dw !constword\n",ival);
529 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>8)));
530 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
533 //tfprintf (oFile, "\t!db !constword,!constword\n",(ival >> 8) & 0xffff, (ival & 0xffff));
534 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>24)));
535 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>16)));
536 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival>>8)));
537 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(ival)));
544 /*-----------------------------------------------------------------*/
545 /* printIvalStruct - generates initial value for structures */
546 /*-----------------------------------------------------------------*/
547 static void printIvalStruct (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
550 initList *iloop = NULL;
552 sflds = SPEC_STRUCT (type)->fields;
555 if (ilist->type != INIT_DEEP) {
556 werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
560 iloop = ilist->init.deep;
563 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
564 if (IS_BITFIELD(sflds->type)) {
565 printIvalBitFields(&sflds,&iloop,pb);
567 printIval (sym, sflds->type, iloop, pb);
571 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
576 /*-----------------------------------------------------------------*/
577 /* printIvalChar - generates initital value for character array */
578 /*-----------------------------------------------------------------*/
580 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
588 //fprintf(stderr, "%s\n",__FUNCTION__);
592 val = list2val (ilist);
594 /* if the value is a character string */
595 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
597 ilen = DCL_ELEM(val->type);
599 if (!DCL_ELEM (type))
600 DCL_ELEM (type) = ilen;
602 /* emit string constant */
603 for (remain = 0; remain < ilen; remain++) {
604 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(SPEC_CVAL(val->etype).v_char[remain])));
607 /* fill array up to desired size */
608 if ((remain = (DCL_ELEM (type) - ilen)) > 0)
610 //tfprintf (oFile, "\t!db !constbyte\n", 0);
611 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
618 //printChar (oFile, s, strlen (s) + 1);
620 for(remain=0; remain<(int)strlen(s); remain++) {
621 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
622 //fprintf(stderr,"0x%02x ",s[remain]);
624 //fprintf(stderr,"\n");
629 /*-----------------------------------------------------------------*/
630 /* printIvalArray - generates code for array initialization */
631 /*-----------------------------------------------------------------*/
633 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
642 /* take care of the special case */
643 /* array of characters can be init */
645 if (IS_CHAR (type->next)) {
646 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
647 if (!IS_LITERAL(list2val(ilist)->etype)) {
648 werror (W_INIT_WRONG);
651 if (printIvalChar (type,
652 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
653 pb, SPEC_CVAL (sym->etype).v_char))
656 /* not the special case */
657 if (ilist->type != INIT_DEEP) {
658 werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, sym->name);
662 for (iloop=ilist->init.deep; iloop; iloop=iloop->next) {
663 if ((++size > DCL_ELEM(type)) && DCL_ELEM(type)) {
664 werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
667 printIval (sym, type->next, iloop, pb);
671 if (DCL_ELEM(type)) {
672 // pad with zeros if needed
673 if (size<DCL_ELEM(type)) {
674 size = (DCL_ELEM(type) - size) * getSize(type->next);
676 //tfprintf (oFile, "\t!db !constbyte\n", 0);
677 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
681 // we have not been given a size, but we now know it
682 DCL_ELEM (type) = size;
688 /*-----------------------------------------------------------------*/
689 /* printIvalPtr - generates code for initial value of pointers */
690 /*-----------------------------------------------------------------*/
691 extern value *initPointer (initList *, sym_link *toType);
694 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
701 fprintf (stderr, "FIXME: initializers for pointers...\n");
702 printTypeChain (type, stderr);
704 fprintf (stderr, "symbol: %s, DCL_TYPE():%d, DCL_ELEM():%d, IS_ARRAY():%d", sym->rname, DCL_TYPE(type), DCL_ELEM(type), IS_ARRAY(type));
705 fprintf (stderr, "ilist: type=%d (INIT_DEEP=%d, INIT_NODE=%d)\n", ilist->type, INIT_DEEP, INIT_NODE);
707 if (ilist && (ilist->type == INIT_DEEP))
708 ilist = ilist->init.deep;
710 /* function pointers */
711 if (IS_FUNC (type->next))
713 assert ( !"function pointers not yet handled" );
714 //printIvalFuncPtr (type, ilist, pb);
717 if (!(val = initPointer (ilist, type)))
720 if (IS_CHAR (type->next))
722 if (printIvalChar (type, ilist, pb, NULL)) return;
726 if (compareType (type, val->type) == 0)
728 werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
729 printFromToType (val->type, type);
732 if (IS_LITERAL (val->etype))
734 switch (getSize (type))
737 fprintf (stderr, "BYTE: %i\n", (unsigned char)floatFromVal (val) & 0x00FF);
740 fprintf (stderr, "WORD: %i\n", (unsigned int)floatFromVal (val) & 0x00FFFF);
742 case 3: /* gneric pointers */
743 assert ( !"generic pointers not yet handled" );
745 fprintf (stderr, "LONG: %i\n", (unsigned int)floatFromVal (val) & 0x0000FFFFFFFF);
748 assert ( !"invaild size of value -- aborting" );
754 /* now handle symbolic values */
755 switch (getSize (type))
758 fprintf (stderr, "BYTE: %s", val->name);
761 fprintf (stderr, "WORD: %s", val->name);
764 fprintf (stderr, "LONG: %s", val->name);
767 assert ( !"invalid size of (symbolic) value -- aborting" );
771 /*-----------------------------------------------------------------*/
772 /* printIval - generates code for initial value */
773 /*-----------------------------------------------------------------*/
775 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
780 /* if structure then */
781 if (IS_STRUCT (type))
783 //fprintf(stderr,"%s struct: %s\n",__FUNCTION__, sym->rname);
784 printIvalStruct (sym, type, ilist, pb);
788 /* if this is an array */
791 //fprintf(stderr,"%s array: %s\n",__FUNCTION__, sym->rname);
792 printIvalArray (sym, type, ilist, pb);
796 /* if this is a pointer */
799 //fprintf(stderr,"%s pointer: %s\n",__FUNCTION__, sym->rname);
800 printIvalPtr (sym, type, ilist, pb);
804 /* if type is SPECIFIER */
807 //fprintf(stderr,"%s spec %s\n",__FUNCTION__, sym->rname);
808 printIvalType (sym, type, ilist, pb);
814 extern void pCodeConstString(char *name, char *value);
815 /*-----------------------------------------------------------------*/
816 /* emitStaticSeg - emitcode for the static segment */
817 /*-----------------------------------------------------------------*/
819 pic14emitStaticSeg (memmap * map)
823 dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
825 //fprintf(stderr, "%s\n",__FUNCTION__);
827 /* for all variables in this segment do */
828 for (sym = setFirstItem (map->syms); sym;
829 sym = setNextItem (map->syms))
831 /* if extern then add it into the extern list */
832 if (IS_EXTERN (sym->etype)) {
833 addSetHead (&externs, sym);
837 /* if it is not static add it to the public
839 if (!IS_STATIC (sym->etype))
840 addSetHead (&publics, sym);
842 /* print extra debug info if required */
843 if (options.debug || sym->level == 0)
847 if (IS_STATIC (sym->etype))
848 dbuf_printf (&code->oBuf, "F%s_", moduleName); /* scope is file */
850 dbuf_printf (&code->oBuf, "G_"); /* scope is global */
853 /* symbol is local */
854 dbuf_printf (&code->oBuf, "L%s_",
855 (sym->localof ? sym->localof->name : "-null-"));
856 dbuf_printf (&code->oBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
860 /* if it has an absolute address */
861 if (SPEC_ABSA (sym->etype))
863 if (options.debug || sym->level == 0)
864 dbuf_printf (&code->oBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
866 dbuf_printf (&code->oBuf, "%s\t=\t0x%04x\n",
868 SPEC_ADDR (sym->etype));
872 if (options.debug || sym->level == 0)
873 dbuf_printf (&code->oBuf, " == .\n");
875 /* if it has an initial value */
881 dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
883 resolveIvalSym (sym->ival, sym->type);
884 //printIval (sym, sym->type, sym->ival, &code->oBuf);
885 pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
887 addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
889 printIval (sym, sym->type, sym->ival, pb);
897 dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
898 /* special case for character strings */
899 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
900 SPEC_CVAL (sym->etype).v_char)
901 pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
902 /*printChar (code->oFile,
903 SPEC_CVAL (sym->etype).v_char,
904 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
906 dbuf_printf (&code->oBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
914 /*-----------------------------------------------------------------*/
915 /* emitMaps - emits the code for the data portion the code */
916 /*-----------------------------------------------------------------*/
920 pic14_constructAbsMap (&sfr->oBuf);
921 /* no special considerations for the following
922 data, idata & bit & xdata */
923 pic14emitRegularMap (data, TRUE, TRUE);
924 pic14emitRegularMap (idata, TRUE, TRUE);
925 pic14emitRegularMap (bit, TRUE, FALSE);
926 pic14emitRegularMap (xdata, TRUE, TRUE);
927 pic14emitRegularMap (sfr, TRUE, FALSE);
928 pic14emitRegularMap (sfrbit, FALSE, FALSE);
929 pic14emitRegularMap (code, TRUE, FALSE);
930 pic14emitStaticSeg (statsg);
931 pic14emitStaticSeg (c_abs);
934 /*-----------------------------------------------------------------*/
935 /* createInterruptVect - creates the interrupt vector */
936 /*-----------------------------------------------------------------*/
937 pCodeOp *popGetExternal (char *str);
939 pic14createInterruptVect (struct dbuf_s * vBuf)
941 mainf = newSymbol ("main", 0);
944 /* only if the main function exists */
945 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
947 struct options *op = &options;
948 if (!(op->cc_only || noAssemble))
949 // werror (E_NO_MAIN);
950 fprintf(stderr,"WARNING: function 'main' undefined\n");
954 /* if the main is only a prototype ie. no body then do nothing */
955 if (!IFFUNC_HASBODY(mainf->type))
957 /* if ! compile only then main function should be present */
958 if (!(options.cc_only || noAssemble))
959 // werror (E_NO_MAIN);
960 fprintf(stderr,"WARNING: function 'main' undefined\n");
964 dbuf_printf (vBuf, "%s", iComments2);
965 dbuf_printf (vBuf, "; reset vector \n");
966 dbuf_printf (vBuf, "%s", iComments2);
967 dbuf_printf (vBuf, "STARTUP\t%s\n", CODE_NAME); // Lkr file should place section STARTUP at address 0x0
968 dbuf_printf (vBuf, "\tnop\n"); /* first location for used by incircuit debugger */
969 dbuf_printf (vBuf, "\tpagesel __sdcc_gsinit_startup\n");
970 dbuf_printf (vBuf, "\tgoto\t__sdcc_gsinit_startup\n");
971 popGetExternal("__sdcc_gsinit_startup");
975 /*-----------------------------------------------------------------*/
976 /* initialComments - puts in some initial comments */
977 /*-----------------------------------------------------------------*/
979 pic14initialComments (FILE * afile)
981 initialComments (afile);
982 fprintf (afile, "; PIC port for the 14-bit core\n");
983 fprintf (afile, iComments2);
988 pic14_stringInSet(const char *str, set **world, int autoAdd)
995 for (s = setFirstItem(*world); s; s = setNextItem(*world))
998 if (0 == strcmp(s, str)) return 1;
1002 if (autoAdd) addSet(world, Safe_strdup(str));
1007 pic14_emitSymbolIfNew(FILE *file, const char *fmt, const char *sym, int checkLocals)
1009 if (!pic14_stringInSet(sym, &emitted, 1)) {
1010 /* sym was not in emittedSymbols */
1011 if (!checkLocals || !pic14_stringInSet(sym, &pic14_localFunctions, 0)) {
1012 /* sym is not a locally defined function---avoid bug #1443651 */
1013 fprintf( file, fmt, sym );
1020 /*-------------------------------------------------------------------*/
1021 /* emitSymbol - write a symbol definition only if it is not */
1022 /* already present */
1023 /*-------------------------------------------------------------------*/
1026 emitSymbol (struct dbuf_s *oBuf, const char *name, const char *section_type, int size, int addr, int useEQU, int globalize)
1028 static unsigned int sec_idx = 0;
1030 /* workaround: variables declared via `sbit' result in a numeric
1031 * identifier (0xHH), EQU'ing them is invalid, so just ignore it.
1032 * sbit is heavily used in the inc2h-generated header files!
1034 if (!is_valid_identifier(name))
1036 //fprintf( stderr, "%s:%s:%u: ignored symbol: %s\n", __FILE__, __FUNCTION__, __LINE__, name );
1040 /* check whether the symbol is already defined */
1041 if (pic14_stringInSet(name, &emitted, 1)) return;
1043 /* new symbol -- define it */
1044 //fprintf (stderr, "%s: emitting %s (%d)\n", __FUNCTION__, name, size);
1046 dbuf_printf (oBuf, "%s\tEQU\t0x%04x\n", name, addr);
1048 /* we place each symbol into a section of its own to allow the linker
1049 * to distribute the data into all available memory banks */
1050 if (!section_type) section_type = "udata";
1053 /* absolute symbols are handled in pic14_constructAbsMap */
1056 if (globalize) dbuf_printf (oBuf, "\tglobal\t%s\n", name);
1057 dbuf_printf (oBuf, "udata_%s_%u\t%s\n", moduleName,
1058 sec_idx++, section_type);
1059 dbuf_printf (oBuf, "%s\tres\t%d\n", name, size);
1064 /*-----------------------------------------------------------------*/
1065 /* printExterns - generates extern for external variables */
1066 /*-----------------------------------------------------------------*/
1068 pic14printExterns (FILE * afile)
1072 fprintf (afile, "%s", iComments2);
1073 fprintf (afile, "; extern variables in this module\n");
1074 fprintf (afile, "%s", iComments2);
1076 for (sym = setFirstItem (externs); sym; sym = setNextItem (externs))
1077 pic14_emitSymbolIfNew(afile, "\textern %s\n", sym->rname, 1);
1080 /*-----------------------------------------------------------------*/
1081 /* printPublics - generates .global for publics */
1082 /*-----------------------------------------------------------------*/
1084 pic14printPublics (FILE * afile)
1088 fprintf (afile, "%s", iComments2);
1089 fprintf (afile, "; public variables in this module\n");
1090 fprintf (afile, "%s", iComments2);
1092 for (sym = setFirstItem (publics); sym;
1093 sym = setNextItem (publics)) {
1095 if(!IS_BITFIELD(sym->type) && ((IS_FUNC(sym->type) || sym->allocreq))) {
1096 if (!IS_BITVAR(sym->type))
1097 pic14_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0);
1099 /* Absolute variables are defines in the asm file as equates and thus can not be made global. */
1100 /* Not any longer! */
1101 //if (!SPEC_ABSA (sym->etype))
1102 pic14_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0);
1108 pic14printLocals (FILE * afile)
1110 set *allregs[6] = { dynAllocRegs, dynStackRegs, dynProcessorRegs, dynDirectRegs, dynDirectBitRegs, dynInternalRegs };
1115 dbuf_init(&dbuf, 1024);
1116 /* emit all registers from all possible sets */
1117 for (i = 0; i < 6; i++) {
1118 if (allregs[i] == NULL) continue;
1120 for (reg = setFirstItem(allregs[i]); reg; reg = setNextItem(allregs[i])) {
1121 if (reg->isEmitted) continue;
1123 if (reg->wasUsed && !reg->isExtern) {
1124 emitSymbol(&dbuf, reg->name, "udata", reg->size, reg->isFixed ? reg->address : -1, 0, reg->isPublic);
1129 dbuf_write_and_destroy(&dbuf, afile);
1132 /*-----------------------------------------------------------------*/
1133 /* emitOverlay - will emit code for the overlay stuff */
1134 /*-----------------------------------------------------------------*/
1136 pic14emitOverlay (struct dbuf_s * aBuf)
1140 /* if (!elementsInSet (ovrSetSets))*/
1142 /* the hack below, fixes translates for devices which
1143 * only have udata_shr memory */
1144 dbuf_printf (aBuf, "%s\t%s\n",
1145 (elementsInSet(ovrSetSets)?"":";"),
1146 port->mem.overlay_name);
1148 /* for each of the sets in the overlay segment do */
1149 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1150 ovrset = setNextItem (ovrSetSets))
1155 if (elementsInSet (ovrset))
1157 /* this dummy area is used to fool the assembler
1158 otherwise the assembler will append each of these
1159 declarations into one chunk and will not overlay
1162 /* I don't think this applies to us. We are using gpasm. CRF */
1164 dbuf_printf (aBuf, ";\t.area _DUMMY\n");
1165 /* output the area informtion */
1166 dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1169 for (sym = setFirstItem (ovrset); sym;
1170 sym = setNextItem (ovrset))
1173 /* if extern then do nothing */
1174 if (IS_EXTERN (sym->etype))
1177 /* if allocation required check is needed
1178 then check if the symbol really requires
1179 allocation only for local variables */
1180 if (!IS_AGGREGATE (sym->type) &&
1181 !(sym->_isparm && !IS_REGPARM (sym->etype))
1182 && !sym->allocreq && sym->level)
1185 /* if global variable & not static or extern
1186 and addPublics allowed then add it to the public set */
1187 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1188 && !IS_STATIC (sym->etype))
1189 addSetHead (&publics, sym);
1191 /* if extern then do nothing or is a function
1193 if (IS_FUNC (sym->type))
1196 /* print extra debug info if required */
1197 if (options.debug || sym->level == 0)
1201 if (IS_STATIC (sym->etype))
1202 dbuf_printf (aBuf, "F%s_", moduleName); /* scope is file */
1204 dbuf_printf (aBuf, "G_"); /* scope is global */
1207 /* symbol is local */
1208 dbuf_printf (aBuf, "L%s_",
1209 (sym->localof ? sym->localof->name : "-null-"));
1210 dbuf_printf (aBuf, "%s_%d_%d", sym->name, sym->level, sym->block);
1213 /* if is has an absolute address then generate
1214 an equate for this no need to allocate space */
1215 if (SPEC_ABSA (sym->etype))
1218 if (options.debug || sym->level == 0)
1219 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1221 dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1223 SPEC_ADDR (sym->etype));
1227 if (options.debug || sym->level == 0)
1228 dbuf_printf (aBuf, "==.\n");
1230 /* allocate space */
1231 dbuf_printf (aBuf, "%s:\n", sym->rname);
1232 dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1241 pic14_emitInterruptHandler (FILE * asmFile)
1243 if (pic14_hasInterrupt)
1246 fprintf (asmFile, "%s", iComments2);
1247 fprintf (asmFile, "; interrupt and initialization code\n");
1248 fprintf (asmFile, "%s", iComments2);
1249 // Note - for mplink may have to enlarge section vectors in .lnk file
1250 // Note: Do NOT name this code_interrupt to avoid nameclashes with
1251 // source files's code segment (interrupt.c -> code_interrupt)
1252 fprintf (asmFile, "c_interrupt\t%s\t0x4\n", CODE_NAME);
1254 /* interrupt service routine */
1255 fprintf (asmFile, "__sdcc_interrupt\n");
1256 copypCode(asmFile, 'I');
1260 /*-----------------------------------------------------------------*/
1261 /* glue - the final glue that hold the whole thing together */
1262 /*-----------------------------------------------------------------*/
1266 char udata_name[80];
1268 struct dbuf_s ovrBuf;
1271 dbuf_init(&ovrBuf, 4096);
1272 dbuf_init(&vBuf, 4096);
1274 pCodeInitRegisters();
1276 /* check for main() */
1277 mainf = newSymbol ("main", 0);
1279 mainf = findSymWithLevel (SymbolTab, mainf);
1281 if (!mainf || !IFFUNC_HASBODY(mainf->type))
1283 /* main missing -- import stack from main module */
1284 //fprintf (stderr, "main() missing -- assuming we are NOT the main module\n");
1285 pic14_options.isLibrarySource = 1;
1289 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1291 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
1294 /* entry point @ start of CSEG */
1295 addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
1296 /* put in the call to main */
1297 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
1299 if (options.mainreturn) {
1301 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
1302 addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
1306 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
1307 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
1313 /* At this point we've got all the code in the form of pCode structures */
1314 /* Now it needs to be rearranged into the order it should be placed in the */
1317 movepBlock2Head('P'); // Last
1318 movepBlock2Head(code->dbName);
1319 movepBlock2Head('X');
1320 movepBlock2Head(statsg->dbName); // First
1323 /* print the global struct definitions */
1327 /* emit code for the all the variables declared */
1329 /* do the overlay segments */
1330 pic14emitOverlay(&ovrBuf);
1332 /* PENDING: this isnt the best place but it will do */
1333 if (port->general.glue_up_main) {
1334 /* create the interrupt vector table */
1335 pic14createInterruptVect (&vBuf);
1340 ReuseReg(); // ReuseReg where call tree permits
1349 /* now put it all together into the assembler file */
1350 /* create the assembler file name */
1352 if ((noAssemble || options.c1mode) && fullDstFileName)
1354 sprintf (buffer, fullDstFileName);
1358 sprintf (buffer, dstFileName);
1359 strcat (buffer, ".asm");
1362 if (!(asmFile = fopen (buffer, "w"))) {
1363 werror (E_FILE_OPEN_ERR, buffer);
1367 /* prepare statistics */
1368 resetpCodeStatistics ();
1370 /* initial comments */
1371 pic14initialComments (asmFile);
1373 /* print module name */
1374 fprintf (asmFile, ";\t.module %s\n", moduleName);
1376 /* Let the port generate any global directives, etc. */
1377 if (port->genAssemblerPreamble)
1379 port->genAssemblerPreamble(asmFile);
1382 /* Emit the __config directive */
1383 pic14_emitConfigWord (asmFile);
1385 /* print the global variables in this module */
1386 pic14printPublics (asmFile);
1388 /* print the extern variables in this module */
1389 pic14printExterns (asmFile);
1391 /* copy the sfr segment */
1392 fprintf (asmFile, "%s", iComments2);
1393 fprintf (asmFile, "; special function registers\n");
1394 fprintf (asmFile, "%s", iComments2);
1395 dbuf_write_and_destroy (&sfr->oBuf, asmFile);
1398 if (udata_section_name) {
1399 sprintf(udata_name,"%s",udata_section_name);
1401 sprintf(udata_name,"data_%s",moduleName);
1403 fprintf (asmFile, "%s", iComments2);
1404 fprintf (asmFile, "; udata\n");
1405 fprintf (asmFile, "%s", iComments2);
1406 fprintf (asmFile, "%s\tudata\n", udata_name);
1407 dbuf_write_and_destroy(&data->oBuf, asmFile);
1409 /* Put all variables into a cblock */
1412 /* print the locally defined variables in this module */
1413 writeUsedRegs(asmFile);
1414 pic14printLocals (asmFile);
1416 /* create the overlay segments */
1417 fprintf (asmFile, "%s", iComments2);
1418 fprintf (asmFile, "; overlayable items in internal ram \n");
1419 fprintf (asmFile, "%s", iComments2);
1420 dbuf_write_and_destroy (&ovrBuf, asmFile);
1424 /* create the stack segment MOF */
1425 if (mainf && IFFUNC_HASBODY(mainf->type)) {
1426 fprintf (asmFile, "%s", iComments2);
1427 fprintf (asmFile, "; Stack segment in internal ram \n");
1428 fprintf (asmFile, "%s", iComments2);
1429 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
1430 ";__start__stack:\n;\t.ds\t1\n\n");
1433 /* create the idata segment */
1434 fprintf (asmFile, "%s", iComments2);
1435 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1436 fprintf (asmFile, "%s", iComments2);
1437 dbuf_write_and_destroy (&idata->oBuf, asmFile);
1439 /* if external stack then reserve space of it */
1440 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1441 fprintf (asmFile, "%s", iComments2);
1442 fprintf (asmFile, "; external stack \n");
1443 fprintf (asmFile, "%s", iComments2);
1444 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1445 fprintf (asmFile,";\t.ds 256\n");
1448 /* copy xtern ram data */
1449 fprintf (asmFile, "%s", iComments2);
1450 fprintf (asmFile, "; external ram data\n");
1451 fprintf (asmFile, "%s", iComments2);
1452 dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1456 /* copy the bit segment */
1457 fprintf (asmFile, "%s", iComments2);
1458 fprintf (asmFile, "; bit data\n");
1459 fprintf (asmFile, "%s", iComments2);
1460 dbuf_write_and_destroy (&bit->oBuf, asmFile);
1462 /* emit initialized data */
1463 showAllMemmaps(asmFile);
1465 /* copy the interrupt vector table */
1466 if (mainf && IFFUNC_HASBODY(mainf->type))
1467 dbuf_write_and_destroy (&vBuf, asmFile);
1469 dbuf_destroy(&vBuf);
1471 /* create interupt ventor handler */
1472 pic14_emitInterruptHandler (asmFile);
1474 /* copy over code */
1475 fprintf (asmFile, "%s", iComments2);
1476 fprintf (asmFile, "; code\n");
1477 fprintf (asmFile, "%s", iComments2);
1478 fprintf (asmFile, "code_%s\t%s\n", moduleName, port->mem.code_name);
1481 copypCode(asmFile, 'X');
1483 /* _main function */
1484 copypCode(asmFile, 'M');
1486 /* other functions */
1487 copypCode(asmFile, code->dbName);
1490 copypCode(asmFile, 'P');
1492 dumppCodeStatistics (asmFile);
1494 fprintf (asmFile,"\tend\n");
1500 * Deal with initializers.
1505 #define DEBUGprintf printf
1508 #define DEBUGprintf 1 ? (void)0 : (void)printf
1512 void ast_print (ast * tree, FILE *outfile, int indent);
1519 showInitList(initList *list, int level)
1521 static const char *list_type[] = { "INIT_NODE", "INIT_DEEP", "INIT_HOLE" };
1522 static const char *ast_type[] = { "EX_OP", "EX_VALUE", "EX_LINK", "EX_OPERAND" };
1525 printf (" %d: type %u (%s), init %p, next %p\n", level, list->type, list_type[list->type], list->init.node, list->next);
1526 if (list->type == INIT_DEEP) {
1527 showInitList(list->init.deep, level + 1);
1528 } else if (list->type == INIT_NODE) {
1529 ast = list->init.node;
1530 printf (" type %u (%s), level %d, block %d, seqPoint %d\n",
1531 ast->type, ast_type[ast->type], ast->level, ast->block, ast->seqPoint);
1532 if (ast->type == EX_VALUE) {
1533 printf (" VAL %lf\n", floatFromVal(ast->opval.val));
1534 } else if (ast->type == EX_LINK) {
1535 printTypeChain(ast->opval.lnk, NULL);
1536 } else if (ast->type == EX_OP) {
1537 printf (" OP %u\n", ast->opval.op);
1546 * DEBUG: Print a value.
1549 printVal(value *val)
1551 printf ("value %p: name %s, type %p, etype %p, sym %s, vArgs %d, lit 0x%lx/%ld\n",
1552 val, val->name, val->type, val->etype,
1553 val->sym ? val->sym->name : NULL, val->vArgs,
1554 (long)floatFromVal(val), (long)floatFromVal(val));
1555 printTypeChain(val->type, stdout);
1557 printTypeChain(val->etype, stdout);
1561 //prototype from ../SDCCicode.c
1562 operand *operandFromAst (ast * tree,int lvl);
1565 parseIvalAst (ast *node, int *inCodeSpace) {
1567 char *buffer = NULL;
1570 if (IS_AST_VALUE(node)) {
1571 value *val = AST_VALUE(node);
1572 symbol *sym = IS_AST_SYM_VALUE(node) ? AST_SYMBOL(node) : NULL;
1573 if (inCodeSpace && val->type
1574 && (IS_FUNC(val->type) || IS_CODE(getSpec(val->type))))
1578 if (inCodeSpace && sym
1579 && (IS_FUNC(sym->type)
1580 || IS_CODE(getSpec(sym->type))))
1585 DEBUGprintf ("%s: AST_VALUE\n", __FUNCTION__);
1586 if (IS_AST_LIT_VALUE(node)) {
1587 buffer = Safe_alloc(LEN);
1588 SNPRINTF(buffer, LEN, "0x%lx", (long)AST_LIT_VALUE(node));
1589 } else if (IS_AST_SYM_VALUE(node)) {
1590 assert ( AST_SYMBOL(node) );
1592 printf ("sym %s: ", AST_SYMBOL(node)->rname);
1593 printTypeChain(AST_SYMBOL(node)->type, stdout);
1594 printTypeChain(AST_SYMBOL(node)->etype, stdout);
1595 printf ("\n---sym %s: done\n", AST_SYMBOL(node)->rname);
1597 buffer = Safe_strdup(AST_SYMBOL(node)->rname);
1599 assert ( !"Invalid values type for initializers in AST." );
1601 } else if (IS_AST_OP(node)) {
1602 DEBUGprintf ("%s: AST_OP\n", __FUNCTION__);
1603 switch (node->opval.op) {
1605 assert (node->right);
1606 buffer = parseIvalAst(node->right, inCodeSpace);
1607 DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
1610 assert ( node->left && !node->right );
1611 buffer = parseIvalAst(node->left, inCodeSpace);
1612 DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
1615 assert (node->left && node->right );
1616 left = parseIvalAst(node->left, inCodeSpace);
1617 right = parseIvalAst(node->right, inCodeSpace);
1618 buffer = Safe_alloc(LEN);
1619 SNPRINTF(buffer, LEN, "(%s + %s)", left, right);
1620 DEBUGprintf ("%s: %s\n", __FUNCTION__, buffer);
1625 assert ( node->left && node->right );
1626 assert ( IS_AST_VALUE(node->left) && AST_VALUE(node->left)->sym );
1627 right = parseIvalAst(node->right, inCodeSpace);
1628 buffer = Safe_alloc(LEN);
1629 SNPRINTF(buffer, LEN, "(%s + %u * %s)",
1630 AST_VALUE(node->left)->sym->rname, getSize(AST_VALUE(node->left)->type), right);
1632 DEBUGprintf ("%s: %s\n", __FUNCTION__, &buffer[0]);
1635 assert ( !"Unhandled operation in initializer." );
1639 assert ( !"Invalid construct in initializer." );
1646 * Emit the section preamble, absolute location (if any) and
1647 * symbol name(s) for intialized data.
1650 emitIvalLabel(FILE *of, symbol *sym)
1653 static int in_code = 0;
1656 // code or data space?
1657 if (IS_CODE(getSpec(sym->type))) {
1664 fprintf(of, "\nD_%s_%s\t%s", moduleName, sym->name, segname);
1665 if (SPEC_ABSA(getSpec(sym->type))) {
1666 // specify address for absolute symbols
1667 fprintf(of, "\t0x%04X", SPEC_ADDR(getSpec(sym->type)));
1669 fprintf(of, "\n%s\n", sym->rname);
1674 char *get_op(pCodeOp *pcop,char *buffer, size_t size);
1676 * Actually emit the initial values in .asm format.
1679 emitIvals(FILE *of, symbol *sym, initList *list, long lit, int size)
1685 int inCodeSpace = 0;
1689 assert (size <= sizeof(long));
1690 assert (!list || (list->type == INIT_NODE));
1691 node = list ? list->init.node : NULL;
1693 in_code = emitIvalLabel(of, sym);
1694 if (!in_code) fprintf (of, "\tdb\t");
1697 // initialize as zero
1698 for (i=0; i < size; i++) {
1700 fprintf (of, "\tretlw 0x00");
1702 fprintf (of, "%s0x00", (i == 0) ? "" : ", ");
1710 if (constExprTree(node) && (val = constExprValue(node, 0))) {
1711 op = operandFromValue(val);
1712 DEBUGprintf ("%s: constExpr ", __FUNCTION__);
1714 } else if (IS_AST_VALUE(node)) {
1715 op = operandFromAst(node, 0);
1716 } else if (IS_AST_OP(node)) {
1717 str = parseIvalAst(node, &inCodeSpace);
1718 DEBUGprintf("%s: AST_OP: %s\n", __FUNCTION__, str);
1721 assert ( !"Unhandled construct in intializer." );
1727 //printOperand(op, of);
1730 for (i=0; i < size; i++) {
1731 char *text = op ? aopGet(AOP(op), i, 0, 0)
1732 : get_op(newpCodeOpImmd(str, i, 0, inCodeSpace, 0), NULL, 0);
1734 fprintf (of, "\tretlw %s\n", text);
1736 fprintf (of, "%s%s", (i == 0) ? "" : ", ", text);
1743 * For UNIONs, we first have to find the correct alternative to map the
1744 * initializer to. This function maps the structure of the initializer to
1745 * the UNION members recursively.
1746 * Returns the type of the first `fitting' member.
1749 matchIvalToUnion (initList *list, sym_link *type, int size)
1755 if (IS_PTR(type) || IS_CHAR(type) || IS_INT(type) || IS_LONG(type)
1758 if (!list || (list->type == INIT_NODE)) {
1759 DEBUGprintf ("OK, simple type\n");
1762 DEBUGprintf ("ERROR, simple type\n");
1765 } else if (IS_BITFIELD(type)) {
1766 if (!list || (list->type == INIT_NODE)) {
1767 DEBUGprintf ("OK, bitfield\n");
1770 DEBUGprintf ("ERROR, bitfield\n");
1773 } else if (IS_STRUCT(type) && SPEC_STRUCT(getSpec(type))->type == STRUCT) {
1774 if (!list || (list->type == INIT_DEEP)) {
1775 if (list) list = list->init.deep;
1776 sym = SPEC_STRUCT(type)->fields;
1778 DEBUGprintf ("Checking STRUCT member %s\n", sym->name);
1779 if (!matchIvalToUnion(list, sym->type, 0)) {
1780 DEBUGprintf ("ERROR, STRUCT member %s\n", sym->name);
1783 if (list) list = list->next;
1787 // excess initializers?
1789 DEBUGprintf ("ERROR, excess initializers\n");
1793 DEBUGprintf ("OK, struct\n");
1797 } else if (IS_STRUCT(type) && SPEC_STRUCT(getSpec(type))->type == UNION) {
1798 if (!list || (list->type == INIT_DEEP)) {
1799 if (list) list = list->init.deep;
1800 sym = SPEC_STRUCT(type)->fields;
1802 DEBUGprintf ("Checking UNION member %s.\n", sym->name);
1803 if (((IS_STRUCT(sym->type) || getSize(sym->type) == size))
1804 && matchIvalToUnion(list, sym->type, size))
1806 DEBUGprintf ("Matched UNION member %s.\n", sym->name);
1813 DEBUGprintf ("ERROR, no match found.\n");
1816 assert ( !"Unhandled type in UNION." );
1819 assert ( !"No match found in UNION for the given initializer structure." );
1824 * Parse the type and its initializer and emit it (recursively).
1827 emitInitVal(FILE *of, symbol *topsym, sym_link *my_type, initList *list)
1833 size = getSize(my_type);
1835 if (IS_PTR(my_type)) {
1836 DEBUGprintf ("(pointer, %d byte) %p\n", size, list ? (void *)(long)list2int(list) : NULL);
1837 emitIvals(of, topsym, list, 0, size);
1841 if (IS_ARRAY(my_type)) {
1842 DEBUGprintf ("(array, %d items, %d byte) below\n", DCL_ELEM(my_type), size);
1843 assert (!list || list->type == INIT_DEEP);
1844 if (list) list = list->init.deep;
1845 for (i = 0; i < DCL_ELEM(my_type); i++) {
1846 emitInitVal(of, topsym, my_type->next, list);
1848 if (list) list = list->next;
1853 if (IS_FLOAT(my_type)) {
1855 DEBUGprintf ("(float, %d byte) %lf\n", size, list ? list2int(list) : 0.0);
1856 emitIvals(of, topsym, list, 0, size);
1860 if (IS_CHAR(my_type) || IS_INT(my_type) || IS_LONG(my_type)) {
1861 // integral type, 8, 16, or 32 bit
1862 DEBUGprintf ("(integral, %d byte) 0x%lx/%ld\n", size, list ? (long)list2int(list) : 0, list ? (long)list2int(list) : 0);
1863 emitIvals(of, topsym, list, 0, size);
1866 } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == STRUCT) {
1868 DEBUGprintf ("(struct, %d byte) handled below\n", size);
1869 assert (!list || (list->type == INIT_DEEP));
1871 // iterate over struct members and initList
1872 if (list) list = list->init.deep;
1873 sym = SPEC_STRUCT(my_type)->fields;
1877 if (IS_BITFIELD(sym->type)) {
1878 while (sym && IS_BITFIELD(sym->type)) {
1879 assert (!list || ((list->type == INIT_NODE)
1880 && IS_AST_LIT_VALUE(list->init.node)));
1881 lit = list ? list2int(list) : 0;
1882 DEBUGprintf ( "(bitfield member) %02lx (%d bit, starting at %d, bitfield %02lx)\n",
1883 lit, SPEC_BLEN(getSpec(sym->type)),
1884 SPEC_BSTR(getSpec(sym->type)), bitfield);
1885 bitfield |= (lit & ((1ul << SPEC_BLEN(getSpec(sym->type))) - 1)) << SPEC_BSTR(getSpec(sym->type));
1886 len += SPEC_BLEN(getSpec(sym->type));
1889 if (list) list = list->next;
1891 assert (len < sizeof (long) * 8); // did we overflow our initializer?!?
1892 len = (len + 7) & ~0x07; // round up to full bytes
1893 emitIvals(of, topsym, NULL, bitfield, len / 8);
1898 emitInitVal(of, topsym, sym->type, list);
1901 if (list) list = list->next;
1905 assert ( !"Excess initializers." );
1909 } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == UNION) {
1911 DEBUGprintf ("(union, %d byte) handled below\n", size);
1912 assert (list && list->type == INIT_DEEP);
1914 // iterate over union members and initList, try to map number and type of fields and initializers
1915 my_type = matchIvalToUnion(list, my_type, size);
1917 emitInitVal(of, topsym, my_type, list->init.deep);
1919 size -= getSize(my_type);
1921 // pad with (leading) zeros
1922 emitIvals(of, NULL, NULL, 0, size);
1927 assert ( !"No UNION member matches the initializer structure.");
1928 } else if (IS_BITFIELD(my_type)) {
1929 assert ( !"bitfields should only occur in structs..." );
1932 printf ("SPEC_NOUN: %d\n", SPEC_NOUN(my_type));
1933 assert( !"Unhandled initialized type.");
1938 * Iterate over all memmaps and emit their contents (attributes, symbols).
1941 showAllMemmaps(FILE *of)
1944 xstack, istack, code, data, pdata, xdata, xidata, xinit,
1945 idata, bit, statsg, c_abs, x_abs, i_abs, d_abs,
1946 sfr, sfrbit, reg, generic, overlay, eeprom, home };
1952 DEBUGprintf ("---begin memmaps---\n");
1953 for (i = 0; i < sizeof(maps) / sizeof (memmap *); i++) {
1955 //DEBUGprintf ("memmap %i: %p\n", i, map);
1958 DEBUGprintf (" pageno %c, sname %s, dbName %c, ptrType %d, slbl %d, sloc %u, fmap %u, paged %u, direct %u, bitsp %u, codesp %u, regsp %u, syms %p\n",
1959 map->pageno, map->sname, map->dbName, map->ptrType, map->slbl,
1960 map->sloc, map->fmap, map->paged, map->direct, map->bitsp,
1961 map->codesp, map->regsp, map->syms);
1963 for (sym = setFirstItem(map->syms); sym; sym = setNextItem(map->syms)) {
1965 fprintf (of, "; name %s, rname %s, level %d, block %d, key %d, local %d, ival %p\n",
1966 sym->name, sym->rname, sym->level, sym->block, sym->key, sym->islocal, sym->ival);
1969 //if (list) showInitList(list, 0);
1971 resolveIvalSym( list, sym->type );
1972 emitInitVal(of, sym, sym->type, sym->ival);
1977 DEBUGprintf ("---end of memmaps---\n");