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