* device/include/pic16/stdbool.h: removed, since already exists in
[fw/sdcc] / src / pic16 / glue.c
1 /*-------------------------------------------------------------------------
2
3   glue.c - glues everything we have done together into one file.
4                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5
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
9    later version.
10
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.
15
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.
19
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 -------------------------------------------------------------------------*/
24
25 #include "../common.h"
26 #include <time.h>
27 #include "ralloc.h"
28 #include "pcode.h"
29 #include "newalloc.h"
30 #include "gen.h"
31 #include "device.h"
32 #include "main.h"
33 #include "dbuf_string.h"
34 #include <string.h>
35
36
37 extern symbol *interrupts[256];
38 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p);
39 extern int noAlloc;
40 extern set *publics;
41 extern set *externs;
42 extern unsigned maxInterrupts;
43 extern symbol *mainf;
44 extern char *VersionString;
45 extern struct dbuf_s *codeOutBuf;
46 extern char *iComments1;
47 extern char *iComments2;
48
49 extern int initsfpnt;
50 extern unsigned long pFile_isize;
51
52 extern unsigned long pic16_countInstructions();
53 set *pic16_localFunctions = NULL;
54 set *rel_idataSymSet=NULL;
55 set *fix_idataSymSet=NULL;
56
57 extern DEFSETFUNC (closeTmpFiles);
58 extern DEFSETFUNC (rmTmpFiles);
59
60 extern void pic16_AnalyzeBanking (void);
61 extern void pic16_OptimizeJumps ();
62 extern void pic16_OptimizeBanksel ();
63 extern void pic16_InlinepCode(void);
64 extern void pic16_writeUsedRegs(FILE *);
65
66 extern void initialComments (FILE * afile);
67 extern void printPublics (FILE * afile);
68
69 void  pic16_pCodeInitRegisters(void);
70 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
71 extern void pic16_pCodeConstString(char *name, char *value);
72
73
74 /*-----------------------------------------------------------------*/
75 /* aopLiteral - string from a literal value                        */
76 /*-----------------------------------------------------------------*/
77 unsigned int pic16aopLiteral (value *val, int offset)
78 {
79   union {
80     float f;
81     unsigned char c[4];
82   } fl;
83
84   /* if it is a float then it gets tricky */
85   /* otherwise it is fairly simple */
86   if (!(IS_FLOAT(val->type) || IS_FIXED(val->type))) {
87     unsigned long v = ulFromVal (val);
88
89     return ( (v >> (offset * 8)) & 0xff);
90   }
91
92   if(IS_FIXED16X16(val->type)) {
93     unsigned long v = (unsigned long)fixed16x16FromDouble( floatFromVal( val ) );
94
95     return ( (v >> (offset * 8)) & 0xff);
96   }
97
98   /* it is type float */
99   fl.f = (float) floatFromVal(val);
100 #ifdef WORDS_BIGENDIAN
101   return fl.c[3-offset];
102 #else
103   return fl.c[offset];
104 #endif
105
106 }
107
108 iCode *tic;
109 symbol *nsym;
110 char tbuffer[512], *tbuf=tbuffer;;
111
112
113 /*-----------------------------------------------------------------*/
114 /* emitRegularMap - emit code for maps with no special cases       */
115 /*-----------------------------------------------------------------*/
116 static void
117 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
118 {
119   symbol *sym;
120 //  int i, size, bitvars = 0;;
121
122 //      fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
123
124         if(addPublics)
125                 dbuf_printf (&map->oBuf, ";\t.area\t%s\n", map->sname);
126                 /* print the area name */
127
128         for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
129
130 #if 0
131                 fprintf(stderr, "%s\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\taggregate: %d\tregister: 0x%x\tfunction: %d\n",
132                         __FUNCTION__,
133                         map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype),
134                         IS_AGGREGATE(sym->type), (SPEC_SCLS(sym->etype) == S_REGISTER), IS_FUNC(sym->type));
135                 printTypeChain( sym->type, stderr );
136                 fprintf(stderr, "\n");
137 #endif
138
139                 /* if extern then add to externs */
140                 if (IS_EXTERN (sym->etype)) {
141                         /* reduce overhead while linking by not declaring
142                          * extern unused external functions (usually declared
143                          * in header files) */
144                         if(IS_FUNC(sym->type) && !sym->used)continue;
145
146                         /* make sure symbol is not in publics section */
147                         if(!checkSym(publics, sym))
148                                 checkAddSym(&externs, sym);
149                         continue;
150                 }
151
152                 /* if allocation required check is needed
153                  * then check if the symbol really requires
154                  * allocation only for local variables */
155                  if (arFlag && !IS_AGGREGATE (sym->type) &&
156                         !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
157                         !sym->allocreq && sym->level) {
158
159 //                      fprintf(stderr, "%s:%d special case, continuing...\n", __FILE__, __LINE__);
160
161                         continue;
162                 }
163
164                 /* if global variable & not static or extern
165                  * and addPublics allowed then add it to the public set */
166                 if ((sym->used) && (sym->level == 0 ||
167                         (sym->_isparm && !IS_REGPARM (sym->etype))) &&
168                         addPublics &&
169                         !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
170
171                         checkAddSym(&publics, sym);
172                 } else
173                         /* new version */
174                         if(IS_STATIC(sym->etype)
175                                 && !sym->ival) /* && !sym->level*/ {
176                           regs *reg;
177                           sectSym *ssym;
178                           int found=0;
179
180 //                            debugf("adding symbol %s\n", sym->name);
181 #define SET_IMPLICIT    1
182
183 #if SET_IMPLICIT
184                                 if(IS_STRUCT(sym->type))
185                                         sym->implicit = 1;
186 #endif
187
188                                 reg = pic16_allocDirReg( operandFromSymbol( sym ));
189
190                                 if(reg) {
191                                   for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
192                                     if(!strcmp(ssym->name, reg->name))found=1;
193                                   }
194
195                                   if(!found)
196                                     checkAddReg(&pic16_rel_udata, reg);
197 #if 0
198                                   else
199                                     debugf("Did find %s in pic16_rel_udata already. Check!\n", reg->name);
200 //                                  checkAddSym(&publics, sym);
201 #endif
202
203                                 }
204                         }
205
206                 /* if extern then do nothing or is a function
207                  * then do nothing */
208                 if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
209                         if(SPEC_OCLS(sym->etype) == code) {
210 //                              fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
211                                 checkAddSym(&publics, sym);
212                         }
213                         continue;
214                 }
215
216                 /* if is has an absolute address then generate
217                 an equate for this no need to allocate space */
218                 if (SPEC_ABSA (sym->etype)) {
219 //                              fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
220 //                                      sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
221
222                         dbuf_printf (&map->oBuf, "%s\tEQU\t0x%04x\n",
223                                 sym->rname,
224                                 SPEC_ADDR (sym->etype));
225
226                         /* emit only if it is global */
227                         if(sym->level == 0) {
228                           regs *reg;
229
230                                 reg = pic16_dirregWithName( sym->name );
231                                 if(!reg) {
232                                         /* here */
233 //                                      fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
234 //                                                      __FUNCTION__, __LINE__, sym->name);
235
236                                         /* if IS_STRUCT is omitted the following
237                                          * fixes structures but break char/int etc */
238 #if SET_IMPLICIT
239                                         if(IS_STRUCT(sym->type))
240                                                 sym->implicit = 1;              // mark as implicit
241 #endif
242                                         if(!sym->ival) {
243                                                 reg = pic16_allocDirReg( operandFromSymbol(sym) );
244                                                 if(reg) {
245                                                         if(checkAddReg(&pic16_fix_udata, reg)) {
246                                                                 /* and add to globals list if not exist */
247                                                                 addSet(&publics, sym);
248                                                         }
249                                                 }
250                                         } else
251                                                 addSet(&publics, sym);
252                                 }
253                         }
254                 } else {
255                         if(!sym->used && (sym->level == 0)) {
256                           regs *reg;
257
258                                 /* symbol not used, just declared probably, but its in
259                                  * level 0, so we must declare it fine as global */
260
261 //                              fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
262
263 #if SET_IMPLICIT
264                                 if(IS_STRUCT(sym->type))
265                                         sym->implicit = 1;              // mark as implicit
266 #endif
267                                 if(!sym->ival) {
268                                         if(IS_AGGREGATE(sym->type)) {
269                                                 reg=pic16_allocRegByName(sym->rname, getSize( sym->type ), NULL);
270                                         } else {
271                                                 reg = pic16_allocDirReg( operandFromSymbol( sym ) );
272                                         }
273
274                                         {
275                                           sectSym *ssym;
276                                           int found=0;
277
278 #if 0
279                                                 fprintf(stderr, "%s:%d sym->rname: %s reg: %p reg->name: %s\n", __FILE__, __LINE__,
280                                                         sym->rname, reg, (reg?reg->name:"<<NULL>>"));
281 #endif
282
283                                                 if(reg) {
284                                                   for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
285                                                     if(!strcmp(ssym->name, reg->name))found=1;
286                                                   }
287
288                                                   if(!found)
289                                                     if(checkAddReg(&pic16_rel_udata, reg)) {
290                                                       addSetHead(&publics, sym);
291                                                     }
292                                                 }
293                                         }
294
295
296
297                                 } else
298
299                                         addSetHead(&publics, sym);
300                         }
301
302 #if 0
303                         /* allocate space */
304                         /* If this is a bit variable, then allocate storage after 8 bits have been declared */
305                         /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
306                         /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
307                         if (IS_BITVAR (sym->etype)) {
308                                 bitvars++;
309                         } else {
310                                 dbuf_printf (map->oBuf, "\t%s\n", sym->rname);
311                                 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
312                                         for (i = 1; i < size; i++)
313                                                 dbuf_printf (map->oBuf, "\t%s_%d\n", sym->rname, i);
314                                 }
315                         }
316                         dbuf_printf (map->oBuf, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
317 #endif
318                 }
319
320                 /* FIXME -- VR Fix the following, so that syms to be placed
321                  * in the idata section and let linker decide about their fate */
322
323                 /* if it has an initial value then do it only if
324                         it is a global variable */
325
326                 if (sym->ival
327                   && ((sym->level == 0)
328                       || IS_STATIC(sym->etype)) ) {
329                   ast *ival = NULL;
330
331 #if 0
332                         if(SPEC_OCLS(sym->etype)==data) {
333                                 fprintf(stderr, "%s: sym %s placed in data segment\n", map->sname, sym->name);
334                         }
335
336                         if(SPEC_OCLS(sym->etype)==code) {
337                                 fprintf(stderr, "%s: sym %s placed in code segment\n", map->sname, sym->name);
338                         }
339 #endif
340
341 #if 0
342                         fprintf(stderr, "'%s': sym '%s' has initial value SPEC_ABSA: %d, IS_AGGREGATE: %d\n",
343                                 map->sname, sym->name, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type));
344 #endif
345
346                         if (IS_AGGREGATE (sym->type)) {
347                                 if(SPEC_ABSA(sym->etype))
348                                         addSet(&fix_idataSymSet, copySymbol(sym));
349                                 else
350                                         addSet(&rel_idataSymSet, copySymbol(sym));
351 //                              ival = initAggregates (sym, sym->ival, NULL);
352                         } else {
353                                 if(SPEC_ABSA(sym->etype))
354                                         addSet(&fix_idataSymSet, copySymbol(sym));
355                                 else
356                                         addSet(&rel_idataSymSet, copySymbol(sym));
357
358 //                                      ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
359 //                                              decorateType (resolveSymbols (list2expr (sym->ival)), RESULT_TYPE_NONE));
360                         }
361
362                         if(ival) {
363                                 setAstLineno(ival, sym->lineDef);
364                                 codeOutBuf = &statsg->oBuf;
365                                 GcurMemmap = statsg;
366                                 eBBlockFromiCode (iCodeFromAst (ival));
367                                 sym->ival = NULL;
368                         }
369                 }
370         }
371 }
372
373
374 /*-----------------------------------------------------------------*/
375 /* pic16_initPointer - pointer initialization code massaging       */
376 /*-----------------------------------------------------------------*/
377 value *pic16_initPointer (initList * ilist, sym_link *toType)
378 {
379   value *val;
380   ast *expr;
381
382   if (!ilist) {
383       return valCastLiteral(toType, 0.0);
384   }
385
386   expr = decorateType(resolveSymbols( list2expr (ilist) ), FALSE);
387 //  expr = list2expr( ilist );
388
389   if (!expr)
390     goto wrong;
391
392   /* try it the old way first */
393   if (expr->etype && (val = constExprValue (expr, FALSE)))
394     return val;
395
396   /* ( ptr + constant ) */
397   if (IS_AST_OP (expr) &&
398       (expr->opval.op == '+' || expr->opval.op == '-') &&
399       IS_AST_SYM_VALUE (expr->left) &&
400       (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
401       compareType(toType, expr->left->ftype) &&
402       IS_AST_LIT_VALUE (expr->right)) {
403     return valForCastAggr (expr->left, expr->left->ftype,
404                            expr->right,
405                            expr->opval.op);
406   }
407
408   /* (char *)&a */
409   if (IS_AST_OP(expr) && expr->opval.op==CAST &&
410       IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
411     if (compareType(toType, expr->left->ftype)!=1) {
412       werror (W_INIT_WRONG);
413       printFromToType(expr->left->ftype, toType);
414     }
415     // skip the cast ???
416     expr=expr->right;
417   }
418
419   /* no then we have to do these cludgy checks */
420   /* pointers can be initialized with address of
421      a variable or address of an array element */
422   if (IS_AST_OP (expr) && expr->opval.op == '&') {
423     /* address of symbol */
424     if (IS_AST_SYM_VALUE (expr->left) && expr->left->etype) {
425       val = AST_VALUE (expr->left);
426       val->type = newLink (DECLARATOR);
427       if(SPEC_SCLS (expr->left->etype) == S_CODE) {
428         DCL_TYPE (val->type) = CPOINTER;
429         DCL_PTR_CONST (val->type) = port->mem.code_ro;
430       }
431       else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
432         DCL_TYPE (val->type) = FPOINTER;
433       else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
434         DCL_TYPE (val->type) = PPOINTER;
435       else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
436         DCL_TYPE (val->type) = IPOINTER;
437       else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
438         DCL_TYPE (val->type) = EEPPOINTER;
439       else
440         DCL_TYPE (val->type) = POINTER;
441
442       val->type->next = expr->left->ftype;
443       val->etype = getSpec (val->type);
444       return val;
445     }
446
447     /* if address of indexed array */
448     if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
449       return valForArray (expr->left);
450
451     /* if address of structure element then
452        case 1. a.b ; */
453     if (IS_AST_OP (expr->left) &&
454         expr->left->opval.op == '.') {
455       return valForStructElem (expr->left->left,
456                                expr->left->right);
457     }
458
459     /* case 2. (&a)->b ;
460        (&some_struct)->element */
461     if (IS_AST_OP (expr->left) &&
462         expr->left->opval.op == PTR_OP &&
463         IS_ADDRESS_OF_OP (expr->left->left)) {
464       return valForStructElem (expr->left->left->left,
465                                expr->left->right);
466     }
467   }
468   /* case 3. (((char *) &a) +/- constant) */
469   if (IS_AST_OP (expr) &&
470       (expr->opval.op == '+' || expr->opval.op == '-') &&
471       IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
472       IS_AST_OP (expr->left->right) &&
473       expr->left->right->opval.op == '&' &&
474       IS_AST_LIT_VALUE (expr->right)) {
475
476     return valForCastAggr (expr->left->right->left,
477                            expr->left->left->opval.lnk,
478                            expr->right, expr->opval.op);
479
480   }
481   /* case 4. (char *)(array type) */
482   if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
483       IS_ARRAY(expr->right->ftype)) {
484
485     val = copyValue (AST_VALUE (expr->right));
486     val->type = newLink (DECLARATOR);
487     if (SPEC_SCLS (expr->right->etype) == S_CODE) {
488       DCL_TYPE (val->type) = CPOINTER;
489       DCL_PTR_CONST (val->type) = port->mem.code_ro;
490     }
491     else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
492       DCL_TYPE (val->type) = FPOINTER;
493     else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
494       DCL_TYPE (val->type) = PPOINTER;
495     else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
496       DCL_TYPE (val->type) = IPOINTER;
497     else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
498       DCL_TYPE (val->type) = EEPPOINTER;
499     else
500       DCL_TYPE (val->type) = POINTER;
501     val->type->next = expr->right->ftype->next;
502     val->etype = getSpec (val->type);
503     return val;
504   }
505
506  wrong:
507   if (expr)
508     werrorfl (expr->filename, expr->lineno, E_INCOMPAT_PTYPES);
509   else
510     werror (E_INCOMPAT_PTYPES);
511   return NULL;
512
513 }
514
515
516 /*-----------------------------------------------------------------*/
517 /* printPointerType - generates ival for pointer type              */
518 /*-----------------------------------------------------------------*/
519 void _pic16_printPointerType (const char *name, char ptype, void *p)
520 {
521   char buf[256];
522
523   sprintf (buf, "LOW(%s)", name);
524   pic16_emitDS (buf, ptype, p);
525   sprintf (buf, "HIGH(%s)", name);
526   pic16_emitDS (buf, ptype, p);
527 }
528
529 /*-----------------------------------------------------------------*/
530 /* printPointerType - generates ival for pointer type              */
531 /*-----------------------------------------------------------------*/
532 void pic16_printPointerType (const char *name, char ptype, void *p)
533 {
534   _pic16_printPointerType (name, ptype, p);
535   //pic16_flushDB(ptype, p); /* breaks char* const arr[] = {&c, &c, &c}; */
536 }
537
538 /*-----------------------------------------------------------------*/
539 /* printGPointerType - generates ival for generic pointer type     */
540 /*-----------------------------------------------------------------*/
541 void pic16_printGPointerType (const char *iname, const unsigned int itype,
542   char ptype, void *p)
543 {
544   char buf[256];
545
546   _pic16_printPointerType (iname, ptype, p);
547
548   switch (itype)
549     {
550     case CPOINTER:
551     case FUNCTION:
552       sprintf (buf, "UPPER(%s)", iname);
553       pic16_emitDS (buf, ptype, p);
554       break;
555
556     case GPOINTER:
557     case POINTER:
558       sprintf (buf, "0x80");
559       pic16_emitDS (buf, ptype, p);
560       break;
561
562     /*
563      * FPOINTER and IPOINTER are not used in pic16 port
564       case FPOINTER:
565       case IPOINTER:
566      */
567     default:
568       debugf ("itype = %d\n", itype );
569       assert (0);
570     }
571
572   //pic16_flushDB(ptype, p); /* might break char* const arr[] = {...}; */
573 }
574
575
576 /* set to 0 to disable debug messages */
577 #define DEBUG_PRINTIVAL 0
578
579 /*-----------------------------------------------------------------*/
580 /* pic16_printIvalType - generates ival for int/char               */
581 /*-----------------------------------------------------------------*/
582 static void
583 pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype, void *p)
584 {
585   value *val;
586
587 //  fprintf(stderr, "%s for symbol %s\n",__FUNCTION__, sym->rname);
588
589 #if DEBUG_PRINTIVAL
590   fprintf(stderr, "%s\n",__FUNCTION__);
591 #endif
592
593
594   /* if initList is deep */
595   if (ilist && ilist->type == INIT_DEEP)
596     ilist = ilist->init.deep;
597
598   if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
599     werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
600   }
601
602   if (!(val = list2val (ilist))) {
603     // assuming a warning has been thrown
604     val=constVal("0");
605   }
606
607   if (val->type != type) {
608     val = valCastLiteral(type, floatFromVal(val));
609   }
610
611   switch (getSize (type)) {
612   case 1:
613     pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
614     break;
615
616   case 2:
617     pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
618     pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
619     break;
620   case 3:
621     pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
622     pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
623     pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
624   case 4:
625     pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
626     pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
627     pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
628     pic16_emitDB(pic16aopLiteral(val, 3), ptype, p);
629     break;
630   }
631 }
632
633 /*--------------------------------------------------------------------*/
634 /* pic16_printIvalChar - generates initital value for character array */
635 /*--------------------------------------------------------------------*/
636 static int
637 pic16_printIvalChar (symbol *sym, sym_link * type, initList * ilist, char *s, char ptype, void *p)
638 {
639   value *val;
640   int remain, len, ilen;
641
642   if(!p)
643     return 0;
644
645 #if DEBUG_PRINTIVAL
646   fprintf(stderr, "%s\n",__FUNCTION__);
647 #endif
648
649   if(!s) {
650     val = list2val (ilist);
651
652     /* if the value is a character string  */
653     if(IS_ARRAY (val->type) && IS_CHAR (val->etype)) {
654       /* length of initializer string (might contain \0, so do not use strlen) */
655       ilen = DCL_ELEM(val->type);
656
657       if(!DCL_ELEM (type))
658         DCL_ELEM (type) = ilen;
659
660       /* len is 0 if declartion equals initializer,
661        * >0 if declaration greater than initializer
662        * <0 if declaration less than initializer
663        * Strategy: if >0 emit 0x00 for the rest of the length,
664        * if <0 then emit only the length of declaration elements
665        * and warn user
666        */
667       len = DCL_ELEM (type) - ilen;
668
669 //      fprintf(stderr, "%s:%d ilen = %i len = %i DCL_ELEM(type) = %i SPEC_CVAL-len = %i\n", __FILE__, __LINE__,
670 //        ilen, len, DCL_ELEM(type), strlen(SPEC_CVAL(val->etype).v_char));
671
672       if(len >= 0) {
673         /* emit initializer */
674         for(remain=0; remain<ilen; remain++)
675           pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
676
677           /* fill array with 0x00 */
678           while(len--) {
679             pic16_emitDB(0x00, ptype, p);
680           }
681       } else {
682         werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
683
684         for(remain=0; remain<DCL_ELEM (type); remain++)
685           pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
686       }
687
688
689 //      if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
690 //      }
691       return 1;
692     } else return 0;
693   } else {
694     for(remain=0; remain<strlen(s); remain++) {
695         pic16_emitDB(s[remain], ptype, p);
696     }
697   }
698   return 1;
699 }
700
701 /*-----------------------------------------------------------------*/
702 /* pic16_printIvalArray - generates code for array initialization        */
703 /*-----------------------------------------------------------------*/
704 static void
705 pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
706                 char ptype, void *p)
707 {
708   initList *iloop;
709   int lcnt = 0, size = 0;
710
711   if(!p)
712     return;
713
714
715 #if DEBUG_PRINTIVAL
716   fprintf(stderr, "%s\n",__FUNCTION__);
717 #endif
718   /* take care of the special   case  */
719   /* array of characters can be init  */
720   /* by a string                      */
721   if (IS_CHAR (type->next)) {
722     if (!IS_LITERAL(list2val(ilist)->etype)) {
723       werror (W_INIT_WRONG);
724       return;
725     }
726
727     if(pic16_printIvalChar (sym, type,
728                        (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
729                        SPEC_CVAL (sym->etype).v_char, ptype, p))
730       return;
731   }
732   /* not the special case             */
733   if (ilist && ilist->type != INIT_DEEP)
734     {
735       werror (E_INIT_STRUCT, sym->name);
736       return;
737     }
738
739   iloop = ilist->init.deep;
740   lcnt = DCL_ELEM (type);
741
742   for (;;)
743     {
744       size++;
745       pic16_printIval (sym, type->next, iloop, ptype, p);
746       iloop = (iloop ? iloop->next : NULL);
747
748
749       /* if not array limits given & we */
750       /* are out of initialisers then   */
751       if (!DCL_ELEM (type) && !iloop)
752         break;
753
754       /* no of elements given and we    */
755       /* have generated for all of them */
756       if (!--lcnt) {
757         /* if initializers left */
758         if (iloop) {
759           werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
760         }
761         break;
762       }
763     }
764
765   /* if we have not been given a size  */
766   if (!DCL_ELEM (type))
767     DCL_ELEM (type) = size;
768
769   return;
770 }
771
772 /*-----------------------------------------------------------------*/
773 /* pic16_printIvalBitFields - generate initializer for bitfields   */
774 /*-----------------------------------------------------------------*/
775 void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void *p)
776 {
777   value *val ;
778   symbol *lsym = *sym;
779   initList *lilist = *ilist ;
780   unsigned long ival = 0;
781   int size =0;
782
783
784 #if DEBUG_PRINTIVAL
785   fprintf(stderr, "%s\n",__FUNCTION__);
786 #endif
787
788
789   do {
790     unsigned long i;
791     val = list2val(lilist);
792     if (size) {
793       if (SPEC_BLEN(lsym->etype) > 8) {
794         size += ((SPEC_BLEN (lsym->etype) / 8) +
795                  (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
796       }
797     } else {
798       size = ((SPEC_BLEN (lsym->etype) / 8) +
799               (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
800     }
801     i = ulFromVal (val);
802     i <<= SPEC_BSTR (lsym->etype);
803     ival |= i;
804     if (! ( lsym->next &&
805           (lilist && lilist->next) &&
806           (IS_BITFIELD(lsym->next->type)) &&
807           (SPEC_BSTR(lsym->next->etype)))) break;
808     lsym = lsym->next;
809     lilist = lilist->next;
810   } while (1);
811   switch (size) {
812   case 1:
813         pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
814         break;
815
816   case 2:
817         pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
818         pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
819     break;
820
821   case 4: /* EEP: why is this db and not dw? */
822         pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p);
823         pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p);
824         pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p);
825         pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p);
826     break;
827   default:
828         /* VR - only 1,2,4 size long can be handled???? Why? */
829         fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__);
830         assert(0);
831   }
832   *sym = lsym;
833   *ilist = lilist;
834 }
835
836
837 /*-----------------------------------------------------------------*/
838 /* printIvalStruct - generates initial value for structures        */
839 /*-----------------------------------------------------------------*/
840 void pic16_printIvalStruct (symbol * sym, sym_link * type,
841                  initList * ilist, char ptype, void *p)
842 {
843   symbol *sflds;
844   initList *iloop = NULL;
845
846
847 #if DEBUG_PRINTIVAL
848   fprintf(stderr, "%s\n",__FUNCTION__);
849 #endif
850
851   sflds = SPEC_STRUCT (type)->fields;
852
853   if (ilist) {
854     if (ilist->type != INIT_DEEP) {
855       werrorfl (sym->fileDef, sym->lineDef, E_INIT_STRUCT, sym->name);
856       return;
857     }
858
859     iloop = ilist->init.deep;
860   }
861
862   for (; (sflds && iloop); sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
863 //    fprintf(stderr, "%s:%d sflds: %p\tiloop = %p\n", __FILE__, __LINE__, sflds, iloop);
864     if (IS_BITFIELD(sflds->type)) {
865       pic16_printIvalBitFields(&sflds, &iloop, ptype, p);
866     } else {
867       pic16_printIval (sym, sflds->type, iloop, ptype, p);
868     }
869   }
870   if (iloop) {
871     werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "struct", sym->name);
872   }
873   return;
874 }
875
876 /*-----------------------------------------------------------------*/
877 /* printIvalUnion - generates initial value for unions             */
878 /*-----------------------------------------------------------------*/
879 void pic16_printIvalUnion (symbol * sym, sym_link * type,
880                  initList * ilist, char ptype, void *p)
881 {
882   //symbol *sflds;
883   initList *iloop = NULL;
884   int i, size;
885
886
887 #if DEBUG_PRINTIVAL
888   fprintf(stderr, "%s\n",__FUNCTION__);
889 #endif
890
891   iloop = ilist;
892   i = 0;
893   while (iloop)
894   {
895     i++;
896     iloop = iloop->next;
897   } // while
898
899   size = -1;
900   if (type) size = SPEC_STRUCT(type)->size;
901
902   if (i == 1 && size >= 0 && size <= sizeof(long))
903   {
904     unsigned long val = ulFromVal (list2val(ilist));
905     while (size--)
906     {
907       pic16_emitDB(val, ptype, p);
908       val >>= 8;
909     } // while
910     return;
911   } // if
912
913   fprintf( stderr, "INCOMPLETE SUPPORT FOR INITIALIZED union---FALLING BACK TO struct\n" );
914   fprintf( stderr, "This is a bug. Please file a bug-report with your source attached.\n" );
915   pic16_printIvalStruct( sym, type, ilist, ptype, p );
916 }
917
918 static int
919 pic16_isUnion( symbol *sym, sym_link *type )
920 {
921   if (type && SPEC_STRUCT(type)->type == UNION) return 1;
922   return 0;
923 }
924
925 /*--------------------------------------------------------------------------*/
926 /* pic16_printIvalCharPtr - generates initial values for character pointers */
927 /*--------------------------------------------------------------------------*/
928 int pic16_printIvalCharPtr (symbol * sym, sym_link * type, value * val, char ptype, void *p)
929 {
930   int size = 0;
931
932   /* PENDING: this is _very_ mcs51 specific, including a magic
933      number...
934      It's also endin specific.
935
936      VR - Attempting to port this function to pic16 port - 8-Jun-2004
937    */
938
939
940 #if DEBUG_PRINTIVAL
941   fprintf(stderr, "%s\n",__FUNCTION__);
942 #endif
943
944   size = getSize (type);
945
946   if (val->name && strlen (val->name))
947     {
948       if (size == 1)            /* This appears to be Z80 specific?? */
949         {
950           pic16_emitDS(val->name, ptype, p);
951         }
952       else if (size == 2)
953         {
954           pic16_printPointerType (val->name, ptype, p);
955         }
956       else if (size == 3)
957         {
958           int type;
959           if (IS_PTR (val->type)) {
960             type = DCL_TYPE (val->type);
961           } else {
962             type = PTR_TYPE (SPEC_OCLS (val->etype));
963           }
964           if (val->sym && val->sym->isstrlit) {
965             // this is a literal string
966             type=CPOINTER;
967           }
968           pic16_printGPointerType(val->name, type, ptype, p);
969         }
970       else
971         {
972           fprintf (stderr, "*** internal error: unknown size in "
973                    "printIvalCharPtr.\n");
974           assert(0);
975         }
976     }
977   else
978     {
979       // these are literals assigned to pointers
980       switch (size)
981         {
982         case 1:
983           pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
984           break;
985         case 2:
986           pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
987           pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
988           break;
989         case 3:
990           pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
991           pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
992           pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
993           break;
994
995         default:
996           assert (0);
997         }
998     }
999
1000   if (val->sym && val->sym->isstrlit) { // && !isinSet(statsg->syms, val->sym)) {
1001         if(ptype == 'p' && !isinSet(statsg->syms, val->sym))addSet (&statsg->syms, val->sym);
1002         else if(ptype == 'f' /*&& !isinSet(rel_idataSymSet, val->sym)*/)addSet(&rel_idataSymSet, val->sym);
1003   }
1004
1005   return 1;
1006 }
1007
1008 /*-----------------------------------------------------------------------*/
1009 /* pic16_printIvalFuncPtr - generate initial value for function pointers */
1010 /*-----------------------------------------------------------------------*/
1011 void pic16_printIvalFuncPtr (sym_link * type, initList * ilist, char ptype, void *p)
1012 {
1013   value *val;
1014   int dLvl = 0;
1015
1016
1017 #if DEBUG_PRINTIVAL
1018   fprintf(stderr, "%s\n",__FUNCTION__);
1019 #endif
1020
1021   if (ilist)
1022     val = list2val (ilist);
1023   else
1024     val = valCastLiteral(type, 0.0);
1025
1026   if (!val) {
1027     // an error has been thrown already
1028     val=constVal("0");
1029   }
1030
1031   if (IS_LITERAL(val->etype)) {
1032     if (compareType(type, val->etype) == 0) {
1033       werrorfl (ilist->filename, ilist->lineno, E_INCOMPAT_TYPES);
1034       printFromToType (val->type, type);
1035     }
1036     pic16_printIvalCharPtr (NULL, type, val, ptype, p);
1037     return;
1038   }
1039
1040   /* check the types   */
1041   if ((dLvl = compareType (val->type, type->next)) <= 0)
1042     {
1043       pic16_emitDB(0x00, ptype, p);
1044       return;
1045     }
1046
1047   /* now generate the name */
1048   if (!val->sym) {
1049       pic16_printGPointerType (val->name, DCL_TYPE(val->type), ptype, p);
1050   } else {
1051       pic16_printGPointerType (val->sym->rname, DCL_TYPE(val->type), ptype, p);
1052
1053       if(IS_FUNC(val->sym->type) && !val->sym->used && !IS_STATIC(val->sym->etype)) {
1054
1055         if(!checkSym(publics, val->sym))
1056           if(checkAddSym(&externs, val->sym) && (ptype == 'f')) {
1057             /* this has not been declared as extern
1058              * so declare it as a 'late extern' just after the symbol */
1059             fprintf((FILE *)p, ";\tdeclare symbol as extern\n");
1060             fprintf((FILE *)p, "\textern\t%s\n", val->sym->rname);
1061             fprintf((FILE *)p, ";\tcontinue variable declaration\n");
1062           }
1063       }
1064   }
1065
1066   return;
1067 }
1068
1069
1070 /*-----------------------------------------------------------------*/
1071 /* pic16_printIvalPtr - generates initial value for pointers       */
1072 /*-----------------------------------------------------------------*/
1073 void pic16_printIvalPtr (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1074 {
1075   value *val;
1076   int size;
1077
1078 #if 0
1079         fprintf(stderr, "%s:%d initialising pointer: %s size: %d\n", __FILE__, __LINE__,
1080                 sym->rname, getSize(sym->type));
1081 #endif
1082
1083   /* if deep then   */
1084   if (ilist && (ilist->type == INIT_DEEP))
1085     ilist = ilist->init.deep;
1086
1087   /* function pointer     */
1088   if (IS_FUNC (type->next))
1089     {
1090       pic16_printIvalFuncPtr (type, ilist, ptype, p);
1091       return;
1092     }
1093
1094   if (!(val = pic16_initPointer (ilist, type)))
1095     return;
1096
1097   /* if character pointer */
1098   if (IS_CHAR (type->next))
1099     if (pic16_printIvalCharPtr (sym, type, val, ptype, p))
1100       return;
1101
1102   /* check the type      */
1103   if (compareType (type, val->type) == 0) {
1104     werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
1105     printFromToType (val->type, type);
1106   }
1107
1108   /* if val is literal */
1109   if (IS_LITERAL (val->etype))
1110     {
1111       switch (getSize (type))
1112         {
1113         case 1:
1114             pic16_emitDB((unsigned int) ulFromVal (val) & 0xff, ptype, p);
1115             break;
1116         case 2:
1117             pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1118             pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1119             break;
1120         case 3:
1121             pic16_emitDB(pic16aopLiteral(val, 0), ptype, p);
1122             pic16_emitDB(pic16aopLiteral(val, 1), ptype, p);
1123             pic16_emitDB(pic16aopLiteral(val, 2), ptype, p);
1124             break;
1125         default:
1126                 fprintf(stderr, "%s:%d size = %d\n", __FILE__, __LINE__, getSize(type));
1127                 assert(0);
1128         }
1129       return;
1130     }
1131
1132
1133   size = getSize (type);
1134
1135   if (size == 1)                /* Z80 specific?? */
1136     {
1137       pic16_emitDS(val->name, ptype, p);
1138     }
1139   else if (size == 2)
1140     {
1141         pic16_printPointerType (val->name, ptype, p);
1142     }
1143   else if (size == 3)
1144     {
1145       pic16_printGPointerType (val->name, (IS_PTR(type)?DCL_TYPE(type):PTR_TYPE(SPEC_OCLS(sym->etype))),
1146                           ptype, p);
1147     } else
1148         assert(0);
1149   return;
1150 }
1151
1152
1153
1154 /*-----------------------------------------------------------------*/
1155 /* pic16_printIval - generates code for initial value                    */
1156 /*-----------------------------------------------------------------*/
1157 void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p)
1158 {
1159 //  sym_link *itype;
1160
1161   if (!p)
1162     return;
1163
1164 #if 0
1165         fprintf(stderr, "%s:%d generating init for %s\n", __FILE__, __LINE__, sym->name);
1166         fprintf(stderr, "%s: IS_STRUCT: %d  IS_ARRAY: %d  IS_PTR: %d  IS_SPEC: %d\n", sym->name,
1167                 IS_STRUCT(type), IS_ARRAY(type), IS_PTR(type), IS_SPEC(type));
1168 #endif
1169
1170   /* if structure then */
1171   if (IS_STRUCT (type))
1172     {
1173       if (pic16_isUnion(sym, type))
1174         {
1175           //fprintf(stderr,"%s union\n",__FUNCTION__);
1176           pic16_printIvalUnion (sym, type, ilist, ptype, p);
1177         } else {
1178           //fprintf(stderr,"%s struct\n",__FUNCTION__);
1179           pic16_printIvalStruct (sym, type, ilist, ptype, p);
1180         }
1181       return;
1182     }
1183
1184   /* if this is an array */
1185   if (IS_ARRAY (type))
1186     {
1187 //      fprintf(stderr,"%s array\n",__FUNCTION__);
1188       pic16_printIvalArray (sym, type, ilist, ptype, p);
1189       return;
1190     }
1191
1192 #if 0
1193   if (ilist)
1194     {
1195       // not an aggregate, ilist must be a node
1196       if (ilist->type!=INIT_NODE) {
1197           // or a 1-element list
1198         if (ilist->init.deep->next) {
1199           werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "scalar",
1200                   sym->name);
1201         } else {
1202           ilist=ilist->init.deep;
1203         }
1204       }
1205
1206 #if 0
1207       // and the type must match
1208       itype=ilist->init.node->ftype;
1209
1210       if (compareType(type, itype)==0) {
1211         // special case for literal strings
1212         if (IS_ARRAY (itype) && IS_CHAR (getSpec(itype)) &&
1213             // which are really code pointers
1214             IS_PTR(type) && DCL_TYPE(type)==CPOINTER) {
1215           // no sweat
1216         } else {
1217 //          werrorfl (ilist->filename, ilist->lineno, E_TYPE_MISMATCH, "assignment", " ");
1218 //          printFromToType(itype, type);
1219         }
1220       }
1221 #endif
1222     }
1223 #endif
1224
1225   /* if this is a pointer */
1226   if (IS_PTR (type))
1227     {
1228 //      fprintf(stderr,"%s pointer\n",__FUNCTION__);
1229       pic16_printIvalPtr (sym, type, ilist, ptype, p);
1230       return;
1231     }
1232
1233
1234   /* if type is SPECIFIER */
1235   if (IS_SPEC (type))
1236     {
1237 //      fprintf(stderr,"%s spec\n",__FUNCTION__);
1238       pic16_printIvalType (sym, type, ilist, ptype, p);
1239       return;
1240     }
1241 }
1242
1243 int PIC16_IS_CONFIG_ADDRESS(int address)
1244 {
1245   return ((address >= pic16->cwInfo.confAddrStart && address <= pic16->cwInfo.confAddrEnd));
1246 }
1247
1248 int PIC16_IS_IDLOC_ADDRESS(int address)
1249 {
1250    return ((address >= pic16->idInfo.idAddrStart && address <= pic16->idInfo.idAddrEnd));
1251 }
1252
1253 /* wrapper function for the above */
1254 int PIC16_IS_HWREG_ADDRESS(int address)
1255 {
1256   return (PIC16_IS_CONFIG_ADDRESS(address) || PIC16_IS_IDLOC_ADDRESS(address));
1257 }
1258
1259
1260 /*-----------------------------------------------------------------*/
1261 /* emitStaticSeg - emitcode for the static segment                 */
1262 /*-----------------------------------------------------------------*/
1263 static void
1264 pic16emitStaticSeg (memmap * map)
1265 {
1266   symbol *sym;
1267   static int didcode=0;
1268
1269   //fprintf(stderr, "%s\n",__FUNCTION__);
1270
1271   pic16_initDB();
1272
1273   /* for all variables in this segment do */
1274   for (sym = setFirstItem (map->syms); sym;
1275        sym = setNextItem (map->syms))
1276     {
1277
1278 #if 0
1279         fprintf(stderr, "%s\t%s: sym: %s\tused: %d\tSPEC_ABSA: %d\tSPEC_AGGREGATE: %d\tCODE: %d\n\
1280 CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
1281                 map->sname, sym->name, sym->used, SPEC_ABSA(sym->etype), IS_AGGREGATE(sym->type),
1282                 IS_CODE(sym->etype), IN_CODESPACE( SPEC_OCLS(sym->etype)), IS_CONSTANT(sym->etype),
1283                 IS_PTR_CONST(sym->etype), SPEC_CONST(sym->etype));
1284         printTypeChain( sym->type, stderr );
1285         fprintf(stderr, "\n");
1286 #endif
1287
1288         if(SPEC_ABSA(sym->etype) && PIC16_IS_CONFIG_ADDRESS(SPEC_ADDR(sym->etype))) {
1289                 pic16_assignConfigWordValue(SPEC_ADDR(sym->etype),
1290                         (int) ulFromVal (list2val(sym->ival)));
1291
1292                 continue;
1293         }
1294
1295         if(SPEC_ABSA(sym->etype) && PIC16_IS_IDLOC_ADDRESS(SPEC_ADDR(sym->etype))) {
1296                 pic16_assignIdByteValue(SPEC_ADDR(sym->etype),
1297                         (char) ulFromVal (list2val(sym->ival)));
1298
1299                 continue;
1300         }
1301
1302         /* if it is "extern" then do nothing */
1303         if (IS_EXTERN (sym->etype)/* && !SPEC_ABSA(sym->etype)*/) {
1304                 checkAddSym(&externs, sym);
1305           continue;
1306         }
1307
1308         /* if it is not static add it to the public
1309            table */
1310         if (!IS_STATIC (sym->etype)) {
1311                 /* do not emit if it is a config word declaration */
1312                 checkAddSym(&publics, sym);
1313         }
1314
1315       /* print extra debug info if required */
1316       if (options.debug || sym->level == 0) {
1317           /* NOTE to me - cdbFile may be null in which case,
1318            * the sym name will be printed to stdout. oh well */
1319            debugFile->writeSymbol(sym);
1320       }
1321
1322       /* if it has an absolute address */
1323       if (SPEC_ABSA (sym->etype)) {
1324 //              fprintf(stderr, "%s:%d spec_absa is true for symbol: %s\n",
1325 //                      __FILE__, __LINE__, sym->name);
1326
1327           /* if it has an initial value */
1328           if (sym->ival)
1329             {
1330               pBlock *pb;
1331               symbol *asym;
1332               absSym *abSym;
1333               pCode *pcf;
1334
1335               /* symbol has absolute address and initial value */
1336               noAlloc++;
1337               resolveIvalSym (sym->ival, sym->type);
1338               asym = newSymbol(sym->rname, 0);
1339               abSym = Safe_calloc(1, sizeof(absSym));
1340               strcpy(abSym->name, sym->rname);
1341               abSym->address = SPEC_ADDR( sym->etype );
1342               addSet(&absSymSet, abSym);
1343
1344               pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
1345               pic16_addpBlock(pb);
1346
1347               pcf = pic16_newpCodeFunction(moduleName, asym->name);
1348               PCF(pcf)->absblock = 1;
1349
1350               pic16_addpCode2pBlock(pb,pcf);
1351               pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1352               //fprintf(stderr, "%s:%d [1] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1353               pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1354               pic16_flushDB('p', (void *)pb);
1355
1356               pic16_addpCode2pBlock(pb, pic16_newpCodeFunction(NULL, NULL));
1357               noAlloc--;
1358             }
1359           else
1360             {
1361
1362               /* symbol has absolute address but no initial value */
1363
1364               /* allocate space */
1365               dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
1366
1367               /* special case for character strings */
1368               if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1369                   SPEC_CVAL (sym->etype).v_char) {
1370
1371 //              fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, sym->rname);
1372
1373                 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1374               } else {
1375                 fprintf (stderr, "%s:%u(%s): do not know how to intialize symbol %s\n", __FILE__, __LINE__, __FUNCTION__, sym->rname);
1376                 assert(0);
1377               }
1378             }
1379
1380         } else {
1381 //              fprintf(stderr, "%s:%d spec_absa is false for symbol: %s\n",
1382 //                      __FILE__, __LINE__, sym->name);
1383
1384
1385           /* if it has an initial value */
1386           if (sym->ival) {
1387               pBlock *pb;
1388
1389               /* symbol doesn't have absolute address but has initial value */
1390               dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
1391               ++noAlloc;
1392               resolveIvalSym (sym->ival, sym->type);
1393
1394               pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
1395               pic16_addpBlock(pb);
1396
1397               if(!didcode) {
1398                 /* make sure that 'code' directive is emitted before, once */
1399                 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir("code", NULL));
1400
1401                 didcode++;
1402               }
1403
1404               pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
1405               //fprintf(stderr, "%s:%d [2] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1406               pic16_printIval(sym, sym->type, sym->ival, 'p', (void *)pb);
1407               pic16_flushDB('p', (void *)pb);
1408               --noAlloc;
1409             } else {
1410
1411               /* symbol doesn't have absolute address and no initial value */
1412               /* allocate space */
1413 //            fprintf(stderr, "%s:%d [3] generating init for label: %s\n", __FILE__, __LINE__, sym->rname);
1414               dbuf_printf (&code->oBuf, "%s:\n", sym->rname);
1415               /* special case for character strings */
1416               if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1417                   SPEC_CVAL (sym->etype).v_char) {
1418
1419 //              fprintf(stderr, "%s:%d printing code string for %s\n", __FILE__, __LINE__, sym->rname);
1420
1421                 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
1422               } else {
1423                 assert(0);
1424               }
1425             }
1426         }
1427     }
1428
1429 }
1430
1431
1432 /*-----------------------------------------------------------------*/
1433 /* pic16_emitConfigRegs - emits the configuration registers              */
1434 /*-----------------------------------------------------------------*/
1435 void pic16_emitConfigRegs(FILE *of)
1436 {
1437   int i;
1438
1439         for(i=0;i<=(pic16->cwInfo.confAddrEnd-pic16->cwInfo.confAddrStart);i++)
1440                 if(pic16->cwInfo.crInfo[i].emit)        //mask != -1)
1441                         fprintf (of, "\t__config 0x%x, 0x%hhx\n",
1442                                 pic16->cwInfo.confAddrStart+i,
1443                                 pic16->cwInfo.crInfo[i].value);
1444 }
1445
1446 void pic16_emitIDRegs(FILE *of)
1447 {
1448   int i;
1449
1450         for(i=0;i<=(pic16->idInfo.idAddrEnd-pic16->idInfo.idAddrStart);i++)
1451                 if(pic16->idInfo.irInfo[i].emit)
1452                         fprintf (of, "\t__idlocs 0x%06x, 0x%hhx\n",
1453                                 pic16->idInfo.idAddrStart+i,
1454                                 pic16->idInfo.irInfo[i].value);
1455 }
1456
1457
1458 static void
1459 pic16emitMaps ()
1460 {
1461   /* no special considerations for the following
1462      data, idata & bit & xdata */
1463   pic16emitRegularMap (data, TRUE, TRUE);
1464   pic16emitRegularMap (idata, TRUE, TRUE);
1465   pic16emitRegularMap (bit, TRUE, FALSE);
1466   pic16emitRegularMap (xdata, TRUE, TRUE);
1467   pic16emitRegularMap (sfr, FALSE, FALSE);
1468   pic16emitRegularMap (sfrbit, FALSE, FALSE);
1469   pic16emitRegularMap (code, TRUE, FALSE);
1470   pic16emitStaticSeg (statsg);
1471   pic16emitStaticSeg (c_abs);
1472 }
1473
1474 /*-----------------------------------------------------------------*/
1475 /* createInterruptVect - creates the interrupt vector              */
1476 /*-----------------------------------------------------------------*/
1477 static void
1478 pic16createInterruptVect (struct dbuf_s * vBuf)
1479 {
1480         /* if the main is only a prototype ie. no body then do nothing */
1481 #if 0
1482         if (!IFFUNC_HASBODY(mainf->type)) {
1483                 /* if ! compile only then main function should be present */
1484                 if (!options.cc_only)
1485                         werror (E_NO_MAIN);
1486                 return;
1487         }
1488 #endif
1489 #if 0
1490         if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
1491                 dbuf_printf (vBuf, ";\t.area\t%s\n", CODE_NAME);
1492                 dbuf_printf (vBuf, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
1493
1494                 /* this is an overkill since WE are the port,
1495                  * and we know if we have a genIVT function! */
1496                 if(port->genIVT) {
1497                         port->genIVT(vFile, interrupts, maxInterrupts);
1498                 }
1499         }
1500 #endif
1501
1502 }
1503
1504
1505 /*-----------------------------------------------------------------*/
1506 /* pic16initialComments - puts in some initial comments            */
1507 /*-----------------------------------------------------------------*/
1508 static void
1509 pic16initialComments (FILE * afile)
1510 {
1511         initialComments (afile);
1512         fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n");
1513         if(xinst)
1514           fprintf (afile, "; * Extended Instruction Set\n");
1515
1516         if(pic16_mplab_comp)
1517                 fprintf(afile, "; * MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
1518         fprintf (afile, iComments2);
1519
1520         if(options.debug) {
1521                 fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]%s\"\n",
1522                                 SDCC_VERSION_STR, getBuildNumber(), (!xinst?"":" {extended}") );
1523         }
1524 }
1525
1526 int
1527 pic16_stringInSet(const char *str, set **world, int autoAdd)
1528 {
1529   char *s;
1530
1531   if (!str) return 1;
1532   assert(world);
1533
1534   for (s = setFirstItem(*world); s; s = setNextItem(*world))
1535   {
1536     /* found in set */
1537     if (0 == strcmp(s, str)) return 1;
1538   }
1539
1540   /* not found */
1541   if (autoAdd) addSet(world, Safe_strdup(str));
1542   return 0;
1543 }
1544
1545 static int
1546 pic16_emitSymbolIfNew(FILE *file, const char *fmt, const char *sym, int checkLocals)
1547 {
1548   static set *emitted = NULL;
1549
1550   if (!pic16_stringInSet(sym, &emitted, 1)) {
1551     /* sym was not in emittedSymbols */
1552     if (!checkLocals || !pic16_stringInSet(sym, &pic16_localFunctions, 0)) {
1553       /* sym is not a locally defined function---avoid bug #1443651 */
1554       fprintf( file, fmt, sym );
1555       return 0;
1556     }
1557   }
1558   return 1;
1559 }
1560
1561 /*-----------------------------------------------------------------*/
1562 /* printPublics - generates global declarations for publics        */
1563 /*-----------------------------------------------------------------*/
1564 static void
1565 pic16printPublics (FILE *afile)
1566 {
1567   symbol *sym;
1568
1569         fprintf (afile, "\n%s", iComments2);
1570         fprintf (afile, "; public variables in this module\n");
1571         fprintf (afile, "%s", iComments2);
1572
1573         for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
1574           /* sanity check */
1575           if(!IS_STATIC(sym->etype))
1576                 pic16_emitSymbolIfNew(afile, "\tglobal %s\n", sym->rname, 0);
1577 }
1578
1579 /*-----------------------------------------------------------------*/
1580 /* printExterns - generates extern declarations for externs        */
1581 /*-----------------------------------------------------------------*/
1582 static void
1583 pic16_printExterns(FILE *afile)
1584 {
1585   symbol *sym;
1586
1587         /* print nothing if no externs to declare */
1588         if(!elementsInSet(externs) && !elementsInSet(pic16_builtin_functions))
1589                 return;
1590
1591         fprintf(afile, "\n%s", iComments2);
1592         fprintf(afile, "; extern variables in this module\n");
1593         fprintf(afile, "%s", iComments2);
1594
1595         for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
1596                 pic16_emitSymbolIfNew(afile, "\textern %s\n", sym->rname, 1);
1597
1598         for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
1599                 pic16_emitSymbolIfNew(afile, "\textern _%s\n", sym->name, 1);
1600 }
1601
1602 /*-----------------------------------------------------------------*/
1603 /* emitOverlay - will emit code for the overlay stuff              */
1604 /*-----------------------------------------------------------------*/
1605 static void
1606 pic16emitOverlay (struct dbuf_s *aBuf)
1607 {
1608   set *ovrset;
1609
1610   if (!elementsInSet (ovrSetSets))
1611     dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name);
1612
1613   /* for each of the sets in the overlay segment do */
1614   for (ovrset = setFirstItem (ovrSetSets); ovrset;
1615        ovrset = setNextItem (ovrSetSets))
1616     {
1617
1618       symbol *sym;
1619
1620       if (elementsInSet (ovrset))
1621         {
1622           /* this dummy area is used to fool the assembler
1623              otherwise the assembler will append each of these
1624              declarations into one chunk and will not overlay
1625              sad but true */
1626           dbuf_printf (aBuf, ";\t.area _DUMMY\n");
1627           /* output the area informtion */
1628           dbuf_printf (aBuf, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1629         }
1630
1631       for (sym = setFirstItem (ovrset); sym;
1632            sym = setNextItem (ovrset))
1633         {
1634
1635           /* if extern then do nothing */
1636           if (IS_EXTERN (sym->etype))
1637             continue;
1638
1639           /* if allocation required check is needed
1640              then check if the symbol really requires
1641              allocation only for local variables */
1642           if (!IS_AGGREGATE (sym->type) &&
1643               !(sym->_isparm && !IS_REGPARM (sym->etype))
1644               && !sym->allocreq && sym->level)
1645             continue;
1646
1647           /* if global variable & not static or extern
1648              and addPublics allowed then add it to the public set */
1649           if ((sym->_isparm && !IS_REGPARM (sym->etype))
1650               && !IS_STATIC (sym->etype)) {
1651 //            fprintf(stderr, "%s:%d %s accessed\n", __FILE__, __LINE__, __FUNCTION__);
1652               checkAddSym(&publics, sym);
1653 //          addSetHead (&publics, sym);
1654           }
1655
1656           /* if extern then do nothing or is a function
1657              then do nothing */
1658           if (IS_FUNC (sym->type))
1659             continue;
1660
1661
1662           /* if is has an absolute address then generate
1663              an equate for this no need to allocate space */
1664           if (SPEC_ABSA (sym->etype))
1665             {
1666
1667               if (options.debug || sym->level == 0)
1668                 dbuf_printf (aBuf, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1669
1670               dbuf_printf (aBuf, "%s\t=\t0x%04x\n",
1671                        sym->rname,
1672                        SPEC_ADDR (sym->etype));
1673             }
1674           else
1675             {
1676               if (options.debug || sym->level == 0)
1677                 dbuf_printf (aBuf, "==.\n");
1678
1679               /* allocate space */
1680               dbuf_printf (aBuf, "%s:\n", sym->rname);
1681               dbuf_printf (aBuf, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
1682             }
1683
1684         }
1685     }
1686 }
1687
1688 void emitStatistics(FILE *asmFile)
1689 {
1690   unsigned long isize, udsize, ramsize;
1691   statistics.isize = pic16_countInstructions();
1692   isize = (statistics.isize >= 0) ? statistics.isize : 0;
1693   udsize = (statistics.udsize >= 0) ? statistics.udsize : 0;
1694   ramsize = pic16 ? pic16->RAMsize : 0x200;
1695   ramsize -= 256; /* ignore access bank and SFRs */
1696   if (ramsize == 0) ramsize = 64; /* prevent division by zero (below) */
1697
1698   fprintf (asmFile, "\n\n; Statistics:\n");
1699   fprintf (asmFile, "; code size:\t%5ld (0x%04lx) bytes (%5.2f%%)\n;           \t%5ld (0x%04lx) words\n",
1700     isize, isize, (isize*100.0)/(128UL << 10),
1701     isize>>1, isize>>1);
1702   fprintf (asmFile, "; udata size:\t%5ld (0x%04lx) bytes (%5.2f%%)\n",
1703     udsize, udsize, (udsize*100.0) / (1.0 * ramsize));
1704   fprintf (asmFile, "; access size:\t%5ld (0x%04lx) bytes\n",
1705     statistics.intsize, statistics.intsize);
1706
1707   fprintf (asmFile, "\n\n");
1708 }
1709
1710
1711
1712 /*-----------------------------------------------------------------*/
1713 /* glue - the final glue that hold the whole thing together        */
1714 /*-----------------------------------------------------------------*/
1715 void
1716 pic16glue ()
1717 {
1718   FILE *asmFile;
1719   struct dbuf_s ovrBuf;
1720   struct dbuf_s vBuf;
1721
1722     dbuf_init(&ovrBuf, 4096);
1723     dbuf_init(&vBuf, 4096);
1724
1725     mainf = newSymbol ("main", 0);
1726     mainf->block = 0;
1727
1728     mainf = findSymWithLevel(SymbolTab, mainf);
1729
1730     pic16_pCodeInitRegisters();
1731
1732     if(pic16_options.no_crt && mainf && IFFUNC_HASBODY(mainf->type)) {
1733       pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
1734
1735         pic16_addpBlock(pb);
1736
1737         /* entry point @ start of CSEG */
1738         pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
1739
1740         if(initsfpnt) {
1741           pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1742                   pic16_popGetLit2(1, pic16_newpCodeOpRegFromStr("_stack_end"))));
1743           pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
1744                   pic16_popGetLit2(2, pic16_newpCodeOpRegFromStr("_stack_end"))));
1745         }
1746
1747         /* put in the call to main */
1748         pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
1749
1750         if (options.mainreturn) {
1751           pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
1752           pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
1753         } else {
1754           pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
1755           pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
1756         }
1757     }
1758
1759     /* At this point we've got all the code in the form of pCode structures */
1760     /* Now it needs to be rearranged into the order it should be placed in the */
1761     /* code space */
1762
1763     pic16_movepBlock2Head('P');              // Last
1764     pic16_movepBlock2Head(code->dbName);
1765     pic16_movepBlock2Head('X');
1766     pic16_movepBlock2Head(statsg->dbName);   // First
1767
1768     /* print the global struct definitions */
1769
1770     /* PENDING: this isnt the best place but it will do */
1771     if (port->general.glue_up_main) {
1772       /* create the interrupt vector table */
1773       pic16createInterruptVect (&vBuf);
1774     }
1775
1776     /* emit code for the all the variables declared */
1777     pic16emitMaps ();
1778
1779     /* do the overlay segments */
1780     pic16emitOverlay(&ovrBuf);
1781     pic16_AnalyzepCode('*');
1782
1783 #if 1
1784     if(pic16_options.dumpcalltree) {
1785       FILE *cFile;
1786
1787         sprintf(buffer, dstFileName);
1788         strcat(buffer, ".calltree");
1789         cFile = fopen(buffer, "w");
1790         pic16_printCallTree( cFile );
1791         fclose(cFile);
1792     }
1793 #endif
1794
1795     pic16_InlinepCode();
1796     pic16_AnalyzepCode('*');
1797
1798
1799     if(pic16_debug_verbose)
1800       pic16_pcode_test();
1801
1802     /* now put it all together into the assembler file */
1803     /* create the assembler file name */
1804     if((noAssemble || options.c1mode)  && fullDstFileName) {
1805       sprintf (buffer, fullDstFileName);
1806     } else {
1807       sprintf (buffer, dstFileName);
1808       strcat (buffer, ".asm");
1809     }
1810
1811     if(!(asmFile = fopen (buffer, "w"))) {
1812       werror (E_FILE_OPEN_ERR, buffer);
1813       exit (1);
1814     }
1815
1816     /* initial comments */
1817     pic16initialComments (asmFile);
1818
1819     /* print module name */
1820     if(options.debug)
1821       fprintf(asmFile, "\t.file\t\"%s\"\n", fullSrcFileName);
1822
1823     /* Let the port generate any global directives, etc. */
1824     if(port->genAssemblerPreamble) {
1825       port->genAssemblerPreamble(asmFile);
1826     }
1827
1828     /* Put all variables into a cblock */
1829     pic16_AnalyzeBanking();
1830
1831 #if 0
1832     if(pic16_options.opt_flags & OF_LR_SUPPORT) {
1833       pic16_OptimizeLocalRegs();
1834     }
1835 #endif
1836
1837     /* remove redundant BANKSELs -- added by RN 2005-01-17 */
1838     if(pic16_options.opt_banksel > 1) {
1839       pic16_OptimizeBanksel();
1840     }
1841
1842     /* turn GOTOs into BRAs -- added by RN 2004-11-16 */
1843     if(pic16_options.opt_flags & OF_OPTIMIZE_GOTO) {
1844       pic16_OptimizeJumps();
1845     }
1846
1847     /* print the global variables in this module */
1848     pic16printPublics (asmFile);
1849
1850     /* print the extern variables to this module */
1851     pic16_printExterns(asmFile);
1852
1853     pic16_writeUsedRegs(asmFile);
1854
1855 #if 0
1856     /* no xdata in pic */
1857     /* if external stack then reserve space of it */
1858     if(mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
1859       fprintf (asmFile, "%s", iComments2);
1860       fprintf (asmFile, "; external stack \n");
1861       fprintf (asmFile, "%s", iComments2);
1862       fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
1863       fprintf (asmFile,";\t.ds 256\n");
1864     }
1865 #endif
1866
1867 #if 0
1868     /* no xdata in pic */
1869     /* copy xtern ram data */
1870     fprintf (asmFile, "%s", iComments2);
1871     fprintf (asmFile, "; external ram data\n");
1872     fprintf (asmFile, "%s", iComments2);
1873     dbuf_write_and_destroy (&xdata->oBuf, asmFile);
1874 #endif
1875
1876 #if 0
1877     /* copy the bit segment */
1878     fprintf (asmFile, "%s", iComments2);
1879     fprintf (asmFile, "; bit data\n");
1880     fprintf (asmFile, "%s", iComments2);
1881     dbuf_write_and_destroy (&bit->oBuf, asmFile);
1882 #endif
1883
1884     /* copy the interrupt vector table */
1885     if(mainf && IFFUNC_HASBODY(mainf->type)) {
1886       fprintf (asmFile, "\n%s", iComments2);
1887       fprintf (asmFile, "; interrupt vector \n");
1888       fprintf (asmFile, "%s", iComments2);
1889       dbuf_write_and_destroy (&vBuf, asmFile);
1890     }
1891
1892     /* copy global & static initialisations */
1893     fprintf (asmFile, "\n%s", iComments2);
1894     fprintf (asmFile, "; global & static initialisations\n");
1895     fprintf (asmFile, "%s", iComments2);
1896
1897     if(pic16_debug_verbose)
1898       fprintf(asmFile, "; A code from now on!\n");
1899
1900     pic16_copypCode(asmFile, 'A');
1901
1902     if(pic16_options.no_crt) {
1903       if(mainf && IFFUNC_HASBODY(mainf->type)) {
1904         fprintf(asmFile, "\tcode\n");
1905         fprintf(asmFile,"__sdcc_gsinit_startup:\n");
1906       }
1907     }
1908
1909 //    dbuf_write_and_destroy (&code->oBuf, stderr);
1910
1911     fprintf(asmFile, "; I code from now on!\n");
1912     pic16_copypCode(asmFile, 'I');
1913
1914     if(pic16_debug_verbose)
1915       fprintf(asmFile, "; dbName from now on!\n");
1916
1917     pic16_copypCode(asmFile, statsg->dbName);
1918
1919     if(pic16_options.no_crt) {
1920       if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
1921         fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
1922       }
1923     }
1924
1925     if(pic16_debug_verbose)
1926       fprintf(asmFile, "; X code from now on!\n");
1927
1928     pic16_copypCode(asmFile, 'X');
1929
1930     if(pic16_debug_verbose)
1931       fprintf(asmFile, "; M code from now on!\n");
1932
1933     pic16_copypCode(asmFile, 'M');
1934
1935     pic16_copypCode(asmFile, code->dbName);
1936
1937     pic16_copypCode(asmFile, 'P');
1938
1939     emitStatistics(asmFile);
1940
1941     fprintf (asmFile,"\tend\n");
1942     fclose (asmFile);
1943 }