change to initialized data segment before emitting the segment
[fw/sdcc] / src / SDCCmem.c
1 /*-----------------------------------------------------------------*/
2 /* SDCCmem.c - 8051 memory management routines                     */
3 /*-----------------------------------------------------------------*/
4
5 #include "common.h"
6
7 /* memory segments */
8 memmap *xstack = NULL;          /* xternal stack data          */
9 memmap *istack = NULL;          /* internal stack              */
10 memmap *code = NULL;            /* code segment                */
11 memmap *data = NULL;            /* internal data upto 128      */
12 memmap *xdata = NULL;           /* external data               */
13 memmap *xidata = NULL;          /* the initialized xdata       */
14 memmap *xinit = NULL;           /* the initializers for xidata */
15 memmap *idata = NULL;           /* internal data upto 256      */
16 memmap *bit = NULL;             /* bit addressable space       */
17 memmap *statsg = NULL;          /* the constant data segment   */
18 memmap *sfr = NULL;             /* register space              */
19 memmap *reg = NULL;             /* register space              */
20 memmap *sfrbit = NULL;          /* sfr bit space               */
21 memmap *generic = NULL;         /* is a generic pointer        */
22 memmap *overlay = NULL;         /* overlay segment             */
23 memmap *eeprom = NULL;          /* eeprom location             */
24 memmap *home = NULL;            /* Unswitchable code bank      */
25
26 /* this is a set of sets each set containing
27    symbols in a single overlay */
28 set *ovrSetSets = NULL;
29
30 int maxRegBank = 0;
31 int fatalError = 0;             /* fatal error flag                   */
32
33 /*-----------------------------------------------------------------*/
34 /* allocMap - allocates a memory map                               */
35 /*-----------------------------------------------------------------*/
36 memmap *
37 allocMap (char rspace,          /* sfr space            */
38           char farmap,          /* far or near segment  */
39           char paged,           /* can this segment be paged  */
40           char direct,          /* directly addressable */
41           char bitaddr,         /* bit addressable space */
42           char codemap,         /* this is code space   */
43           unsigned sloc,        /* starting location    */
44           const char *name,     /* 2 character name     */
45           char dbName,          /* debug name                 */
46           int ptrType           /* pointer type for this space */
47 )
48 {
49   memmap *map;
50
51   if (!(map = Safe_alloc (sizeof (memmap))))
52     {
53       werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap));
54       exit (1);
55     }
56
57   memset (map, ZERO, sizeof (memmap));
58   map->regsp = rspace;
59   map->fmap = farmap;
60   map->paged = paged;
61   map->direct = direct;
62   map->bitsp = bitaddr;
63   map->codesp = codemap;
64   map->sloc = sloc;
65   map->sname = name;
66   map->dbName = dbName;
67   map->ptrType = ptrType;
68   if (!(map->oFile = tempfile ()))
69     {
70       werror (E_TMPFILE_FAILED);
71       exit (1);
72     }
73   addSetHead (&tmpfileSet, map->oFile);
74   map->syms = NULL;
75   return map;
76 }
77
78 /*-----------------------------------------------------------------*/
79 /* initMem - allocates and initializes all the segments            */
80 /*-----------------------------------------------------------------*/
81 void 
82 initMem ()
83 {
84   /* allocate all the segments */
85   /* xternal stack segment ;   
86      SFRSPACE       -   NO
87      FAR-SPACE      -   YES
88      PAGED          -   YES
89      DIRECT-ACCESS  -   NO
90      BIT-ACCESS     -   NO
91      CODE-ACESS     -   NO 
92      DEBUG-NAME     -   'A'
93      POINTER-TYPE   -   FPOINTER
94    */
95   xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER);
96
97   /* internal stack segment ;   
98      SFRSPACE       -   NO
99      FAR-SPACE      -   NO
100      PAGED          -   NO
101      DIRECT-ACCESS  -   NO
102      BIT-ACCESS     -   NO
103      CODE-ACESS     -   NO 
104      DEBUG-NAME     -   'B'
105      POINTER-TYPE   -   POINTER
106    */
107   istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER);
108
109   /* code  segment ;   
110      SFRSPACE       -   NO
111      FAR-SPACE      -   YES
112      PAGED          -   NO
113      DIRECT-ACCESS  -   NO
114      BIT-ACCESS     -   NO
115      CODE-ACESS     -   YES 
116      DEBUG-NAME     -   'C'
117      POINTER-TYPE   -   CPOINTER
118    */
119   code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
120
121   /* home  segment ;   
122      SFRSPACE       -   NO
123      FAR-SPACE      -   YES
124      PAGED          -   NO
125      DIRECT-ACCESS  -   NO
126      BIT-ACCESS     -   NO
127      CODE-ACESS     -   YES 
128      DEBUG-NAME     -   'C'
129      POINTER-TYPE   -   CPOINTER
130    */
131   home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
132
133   /* Static segment (code for variables );
134      SFRSPACE       -   NO
135      FAR-SPACE      -   YES
136      PAGED          -   NO
137      DIRECT-ACCESS  -   NO
138      BIT-ACCESS     -   NO
139      CODE-ACESS     -   YES 
140      DEBUG-NAME     -   'D'
141      POINTER-TYPE   -   CPOINTER
142    */
143   statsg = allocMap (0, 1, 0, 0, 0, 1, 0, STATIC_NAME, 'D', CPOINTER);
144
145   /* Data segment - internal storage segment ;
146      SFRSPACE       -   NO
147      FAR-SPACE      -   NO
148      PAGED          -   NO
149      DIRECT-ACCESS  -   YES
150      BIT-ACCESS     -   NO
151      CODE-ACESS     -   NO 
152      DEBUG-NAME     -   'E'
153      POINTER-TYPE   -   POINTER
154    */
155   data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
156
157   /* overlay segment - same as internal storage segment ;
158      SFRSPACE       -   NO
159      FAR-SPACE      -   NO
160      PAGED          -   NO
161      DIRECT-ACCESS  -   YES
162      BIT-ACCESS     -   NO
163      CODE-ACESS     -   NO 
164      DEBUG-NAME     -   'E'
165      POINTER-TYPE   -   POINTER
166    */
167   overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
168
169   /* Xternal Data segment - 
170      SFRSPACE       -   NO
171      FAR-SPACE      -   YES
172      PAGED          -   NO
173      DIRECT-ACCESS  -   NO
174      BIT-ACCESS     -   NO
175      CODE-ACESS     -   NO 
176      DEBUG-NAME     -   'F'
177      POINTER-TYPE   -   FPOINTER
178    */
179   xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
180   xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
181   xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
182
183   /* Inderectly addressed internal data segment
184      SFRSPACE       -   NO
185      FAR-SPACE      -   NO
186      PAGED          -   NO
187      DIRECT-ACCESS  -   NO
188      BIT-ACCESS     -   NO
189      CODE-ACESS     -   NO 
190      DEBUG-NAME     -   'G'
191      POINTER-TYPE   -   IPOINTER
192    */
193   idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER);
194
195   /* Static segment (code for variables );
196      SFRSPACE       -   NO
197      FAR-SPACE      -   NO
198      PAGED          -   NO
199      DIRECT-ACCESS  -   YES
200      BIT-ACCESS     -   YES
201      CODE-ACESS     -   NO 
202      DEBUG-NAME     -   'H'
203      POINTER-TYPE   -  _NONE_
204    */
205   bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0);
206
207   /* Special function register space :-
208      SFRSPACE       -   YES
209      FAR-SPACE      -   NO
210      PAGED          -   NO
211      DIRECT-ACCESS  -   YES
212      BIT-ACCESS     -   NO
213      CODE-ACESS     -   NO 
214      DEBUG-NAME     -   'I'
215      POINTER-TYPE   -   _NONE_
216    */
217   sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0);
218
219   /* Register space ;
220      SFRSPACE       -   YES
221      FAR-SPACE      -   NO
222      PAGED          -   NO
223      DIRECT-ACCESS  -   NO
224      BIT-ACCESS     -   NO
225      CODE-ACESS     -   NO 
226      DEBUG-NAME     -   ' '
227      POINTER-TYPE   -   _NONE_
228    */
229   reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
230
231   /* SFR bit space 
232      SFRSPACE       -   YES
233      FAR-SPACE      -   NO
234      PAGED          -   NO
235      DIRECT-ACCESS  -   YES
236      BIT-ACCESS     -   YES
237      CODE-ACESS     -   NO 
238      DEBUG-NAME     -   'J'
239      POINTER-TYPE   -   _NONE_
240    */
241   sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
242
243   /* EEPROM bit space 
244      SFRSPACE       -   NO
245      FAR-SPACE      -   YES
246      PAGED          -   NO
247      DIRECT-ACCESS  -   NO
248      BIT-ACCESS     -   NO
249      CODE-ACESS     -   NO 
250      DEBUG-NAME     -   'K'
251      POINTER-TYPE   -   EEPPOINTER
252    */
253   eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER);
254
255   /* the unknown map */
256   generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER);
257
258 }
259
260 /*-----------------------------------------------------------------*/
261 /* allocIntoSeg - puts a symbol into a memory segment              */
262 /*-----------------------------------------------------------------*/
263 void 
264 allocIntoSeg (symbol * sym)
265 {
266   memmap *segment = SPEC_OCLS (sym->etype);
267   // should we move this to the initialized data segment?
268   if (port->genXINIT && segment==xdata &&
269       sym->ival && sym->level==0 && !SPEC_ABSA(sym->etype)) {
270     segment=SPEC_OCLS(sym->etype)=xidata;
271   }
272   addSet (&segment->syms, sym);
273 }
274
275 /*-----------------------------------------------------------------*/
276 /* allocGlobal - assigns the output segment to a global var       */
277 /*-----------------------------------------------------------------*/
278 void 
279 allocGlobal (symbol * sym)
280 {
281
282   /* symbol name is internal name  */
283   if (!sym->level)              /* local statics can come here */
284     sprintf (sym->rname, "%s%s", port->fun_prefix, sym->name);
285
286   /* add it to the operandKey reset */
287   addSet (&operKeyReset, sym);
288
289   /* if this is a literal e.g. enumerated type */
290   /* put it in the data segment & do nothing   */
291   if (IS_LITERAL (sym->etype))
292     {
293       SPEC_OCLS (sym->etype) = data;
294       return;
295     }
296
297   /* if this is a function then assign code space    */
298   if (IS_FUNC (sym->type))
299     {
300       SPEC_OCLS (sym->etype) = code;
301       /* if this is an interrupt service routine
302          then put it in the interrupt service array */
303       if (FUNC_ISISR (sym->type))
304         {
305
306           if (interrupts[FUNC_INTNO (sym->type)])
307             werror (E_INT_DEFINED,
308                     FUNC_INTNO (sym->type),
309                     interrupts[FUNC_INTNO (sym->type)]->name);
310           else
311             interrupts[FUNC_INTNO (sym->type)] = sym;
312
313           /* automagically extend the maximum interrupts */
314           if (FUNC_INTNO (sym->type) >= maxInterrupts)
315             maxInterrupts = FUNC_INTNO (sym->type) + 1;
316         }
317       /* if it is not compiler defined */
318       if (!sym->cdef)
319         allocIntoSeg (sym);
320
321       return;
322     }
323
324   /* if this is a  SFR or SBIT */
325   if (SPEC_SCLS (sym->etype) == S_SFR ||
326       SPEC_SCLS (sym->etype) == S_SBIT)
327     {
328
329       /* if both absolute address & initial  */
330       /* value specified then error        */
331       if (IS_ABSOLUTE (sym->etype) && sym->ival)
332         {
333           werror (E_SFR_INIT, sym->name);
334           sym->ival = NULL;
335         }
336
337       SPEC_OCLS (sym->etype) =
338         (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
339
340       allocIntoSeg (sym);
341       return;
342     }
343
344   /* if this is a bit variable and no storage class */
345   if (SPEC_NOUN (sym->etype) == V_BIT
346       && SPEC_SCLS (sym->etype) == S_BIT)
347     {
348       SPEC_OCLS (sym->etype) = bit;
349       allocIntoSeg (sym);
350       return;
351     }
352
353   /* if bit storage class */
354   if (SPEC_SCLS (sym->etype) == S_SBIT)
355     {
356       SPEC_OCLS (sym->etype) = bit;
357       allocIntoSeg (sym);
358       return;
359     }
360
361   /* register storage class ignored changed to FIXED */
362   if (SPEC_SCLS (sym->etype) == S_REGISTER)
363     SPEC_SCLS (sym->etype) = S_FIXED;
364
365   /* if data specified then  */
366   if (SPEC_SCLS (sym->etype) == S_DATA)
367     {
368       /* set the output class */
369       SPEC_OCLS (sym->etype) = data;
370       /* generate the symbol  */
371       allocIntoSeg (sym);
372       return;
373     }
374
375   /* if it is fixed, then allocate depending on the  */
376   /* current memory model,same for automatics        */
377   if (SPEC_SCLS (sym->etype) == S_FIXED ||
378       SPEC_SCLS (sym->etype) == S_AUTO)
379     {
380       /* set the output class */
381       SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
382       /* generate the symbol  */
383       allocIntoSeg (sym);
384       return;
385     }
386
387   /* if code change to constant */
388   if (SPEC_SCLS (sym->etype) == S_CODE) {
389     SPEC_OCLS (sym->etype) = statsg;
390     allocIntoSeg (sym);
391     return;
392   }
393
394   if (SPEC_SCLS (sym->etype) == S_XDATA)
395     {
396       SPEC_OCLS (sym->etype) = xdata;
397       allocIntoSeg (sym);
398       return;
399     }
400
401   if (SPEC_SCLS (sym->etype) == S_IDATA)
402     {
403       SPEC_OCLS (sym->etype) = idata;
404       sym->iaccess = 1;
405       allocIntoSeg (sym);
406       return;
407     }
408
409   if (SPEC_SCLS (sym->etype) == S_EEPROM)
410     {
411       SPEC_OCLS (sym->etype) = eeprom;
412       allocIntoSeg (sym);
413       return;
414     }
415
416   return;
417 }
418
419 /*-----------------------------------------------------------------*/
420 /* allocParms - parameters are always passed on stack              */
421 /*-----------------------------------------------------------------*/
422 void 
423 allocParms (value * val)
424 {
425   value *lval;
426   int pNum = 1;
427
428   for (lval = val; lval; lval = lval->next, pNum++)
429     {
430
431       /* check the declaration */
432       checkDecl (lval->sym, 0);
433
434       /* if this a register parm then allocate
435          it as a local variable by adding it
436          to the first block we see in the body */
437       if (IS_REGPARM (lval->etype))
438         continue;
439
440       /* mark it as my parameter */
441       lval->sym->ismyparm = 1;
442       lval->sym->localof = currFunc;
443
444
445       /* if automatic variables r 2b stacked */
446       if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
447         {
448
449           if (lval->sym)
450             lval->sym->onStack = 1;
451
452           /* choose which stack 2 use   */
453           /*  use xternal stack */
454           if (options.useXstack)
455             {
456               /* PENDING: stack direction support */
457               SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
458               SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
459                 xstackPtr - getSize (lval->type);
460               xstackPtr -= getSize (lval->type);
461             }
462           else
463             {                   /* use internal stack   */
464               SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
465               if (port->stack.direction > 0)
466                 {
467                   SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
468                     stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
469                     getSize (lval->type) -
470                     (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
471                   stackPtr -= getSize (lval->type);
472                 }
473               else
474                 {
475                   /* This looks like the wrong order but it turns out OK... */
476                   /* PENDING: isr, bank overhead, ... */
477                   SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
478                     stackPtr +
479                     ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
480                     (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
481                     0;
482                   stackPtr += getSize (lval->type);
483                 }
484             }
485           allocIntoSeg (lval->sym);
486         }
487       else
488         { /* allocate them in the automatic space */
489           /* generate a unique name  */
490           sprintf (lval->sym->rname, "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
491           strcpy (lval->name, lval->sym->rname);
492           
493           /* if declared in external storage */
494           if (SPEC_SCLS (lval->etype) == S_XDATA)
495             SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
496           else
497             /* other wise depending on the memory model 
498                note here that we put it into the overlay segment
499                first, we will remove it from the overlay segment
500                after the overlay determination has been done */
501             if (options.model == MODEL_SMALL)
502               {
503                 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
504                   (options.noOverlay ? port->mem.default_local_map
505                    : overlay);
506               }
507             else
508               {
509                 SPEC_SCLS (lval->etype) = S_XDATA;
510                 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
511               }
512           allocIntoSeg (lval->sym);
513         }
514     }
515
516   return;
517 }
518
519 /*-----------------------------------------------------------------*/
520 /* deallocParms - parameters are always passed on stack                */
521 /*-----------------------------------------------------------------*/
522 void 
523 deallocParms (value * val)
524 {
525   value *lval;
526
527   for (lval = val; lval; lval = lval->next)
528     {
529
530       /* unmark is myparm */
531       lval->sym->ismyparm = 0;
532       /* if on stack then depending on which stack */
533
534       /* delete it from the symbol table  */
535       deleteSym (SymbolTab, lval->sym, lval->sym->name);
536
537       if (!lval->sym->isref)
538         {
539           lval->sym->allocreq = 1;
540           werror (W_NO_REFERENCE, currFunc->name,
541                   "function argument", lval->sym->name);
542         }
543
544       /* move the rname if any to the name for both val & sym */
545       /* and leave a copy of it in the symbol table           */
546       if (lval->sym->rname[0])
547         {
548           char buffer[SDCC_NAME_MAX];
549           strcpy (buffer, lval->sym->rname);
550           lval->sym = copySymbol (lval->sym);
551           strcpy (lval->sym->rname, buffer);
552           strcpy (lval->name, strcpy (lval->sym->name, lval->sym->rname));
553           addSym (SymbolTab, lval->sym, lval->sym->name,
554                   lval->sym->level, lval->sym->block, 1);
555           lval->sym->_isparm = 1;
556           addSet (&operKeyReset, lval->sym);
557         }
558
559     }
560
561   return;
562 }
563
564 /*-----------------------------------------------------------------*/
565 /* allocLocal - allocate local variables                           */
566 /*-----------------------------------------------------------------*/
567 void 
568 allocLocal (symbol * sym)
569 {
570
571   /* generate an unique name */
572   sprintf (sym->rname, "%s%s_%s_%d_%d",
573            port->fun_prefix,
574            currFunc->name, sym->name, sym->level, sym->block);
575
576   sym->islocal = 1;
577   sym->localof = currFunc;
578
579   /* if this is a static variable */
580   if (IS_STATIC (sym->etype))
581     {
582       allocGlobal (sym);
583       sym->allocreq = 1;
584       return;
585     }
586
587   /* if volatile then */
588   if (IS_VOLATILE (sym->etype))
589     sym->allocreq = 1;
590
591   /* this is automatic           */
592
593   /* if it to be placed on the stack */
594   if (options.stackAuto || reentrant) {
595     sym->onStack = 1;
596     if (options.useXstack) {
597       /* PENDING: stack direction for xstack */
598       SPEC_OCLS (sym->etype) = xstack;
599       SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
600       xstackPtr += getSize (sym->type);
601     } else {
602       SPEC_OCLS (sym->etype) = istack;
603       if (port->stack.direction > 0) {
604         SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
605         stackPtr += getSize (sym->type);
606       } else {
607         stackPtr -= getSize (sym->type);
608         SPEC_STAK (sym->etype) = sym->stack = stackPtr;
609       }
610     }
611     allocIntoSeg (sym);
612     return;
613   }
614   
615   /* else depending on the storage class specified */
616   if (SPEC_SCLS (sym->etype) == S_XDATA)
617     {
618       SPEC_OCLS (sym->etype) = xdata;
619       allocIntoSeg (sym);
620       return;
621     }
622
623   if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
624     SPEC_OCLS (sym->etype) = statsg;
625     allocIntoSeg (sym);
626     return;
627   }
628   
629   if (SPEC_SCLS (sym->etype) == S_IDATA)
630     {
631       SPEC_OCLS (sym->etype) = idata;
632       sym->iaccess = 1;
633       allocIntoSeg (sym);
634       return;
635     }
636
637   /* if this is a function then assign code space    */
638   if (IS_FUNC (sym->type))
639     {
640       SPEC_OCLS (sym->etype) = code;
641       return;
642     }
643
644   /* if this is a  SFR or SBIT */
645   if (SPEC_SCLS (sym->etype) == S_SFR ||
646       SPEC_SCLS (sym->etype) == S_SBIT)
647     {
648
649       /* if both absolute address & initial  */
650       /* value specified then error        */
651       if (IS_ABSOLUTE (sym->etype) && sym->ival)
652         {
653           werror (E_SFR_INIT, sym->name);
654           sym->ival = NULL;
655         }
656
657       SPEC_OCLS (sym->etype) =
658         (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
659
660       allocIntoSeg (sym);
661       return;
662     }
663
664   /* if this is a bit variable and no storage class */
665   if (SPEC_NOUN (sym->etype) == V_BIT
666       && (SPEC_SCLS (sym->etype) == S_BIT))
667     {
668       SPEC_OCLS (sym->etype) = bit;
669       allocIntoSeg (sym);
670       return;
671     }
672
673   if (SPEC_SCLS (sym->etype) == S_DATA)
674     {
675       SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
676       allocIntoSeg (sym);
677       return;
678     }
679
680   if (SPEC_SCLS (sym->etype) == S_EEPROM)
681     {
682       SPEC_OCLS (sym->etype) = eeprom;
683       allocIntoSeg (sym);
684       return;
685     }
686
687   /* again note that we have put it into the overlay segment
688      will remove and put into the 'data' segment if required after 
689      overlay  analysis has been done */
690   if (options.model == MODEL_SMALL) {
691     SPEC_OCLS (sym->etype) = 
692       (options.noOverlay ? port->mem.default_local_map
693        : overlay);
694   } else {
695     SPEC_OCLS (sym->etype) = port->mem.default_local_map;
696   }
697   allocIntoSeg (sym);
698 }
699
700 /*-----------------------------------------------------------------*/
701 /* deallocLocal - deallocates the local variables                  */
702 /*-----------------------------------------------------------------*/
703 void 
704 deallocLocal (symbol * csym)
705 {
706   symbol *sym;
707
708   for (sym = csym; sym; sym = sym->next)
709     {
710       if (sym->_isparm)
711         continue;
712
713       /* if it is on the stack */
714       if (sym->onStack)
715         {
716           if (options.useXstack)
717             xstackPtr -= getSize (sym->type);
718           else
719             stackPtr -= getSize (sym->type);
720         }
721       /* if not used give a warning */
722       if (!sym->isref && !IS_STATIC (sym->etype))
723         werror (W_NO_REFERENCE, currFunc->name,
724                 "local variable", sym->name);
725       /* now delete it from the symbol table */
726       deleteSym (SymbolTab, sym, sym->name);
727     }
728 }
729
730 /*-----------------------------------------------------------------*/
731 /* overlay2data - moves declarations from the overlay seg to data  */
732 /*-----------------------------------------------------------------*/
733 void 
734 overlay2data ()
735 {
736   symbol *sym;
737
738   for (sym = setFirstItem (overlay->syms); sym;
739        sym = setNextItem (overlay->syms))
740     {
741
742       SPEC_OCLS (sym->etype) = data;
743       allocIntoSeg (sym);
744     }
745
746   setToNull ((void **) &overlay->syms);
747
748 }
749
750 /*-----------------------------------------------------------------*/
751 /* overlay2Set - will add all symbols from the overlay segment to  */
752 /*               the set of sets containing the overlable symbols  */
753 /*-----------------------------------------------------------------*/
754 void 
755 overlay2Set ()
756 {
757   symbol *sym;
758   set *oset = NULL;
759
760   for (sym = setFirstItem (overlay->syms); sym;
761        sym = setNextItem (overlay->syms))
762     {
763
764       addSet (&oset, sym);
765     }
766
767   setToNull ((void **) &overlay->syms);
768   addSet (&ovrSetSets, oset);
769
770 }
771
772 /*-----------------------------------------------------------------*/
773 /* allocVariables - creates decl & assign storage class for a v    */
774 /*-----------------------------------------------------------------*/
775 int 
776 allocVariables (symbol * symChain)
777 {
778   symbol *sym;
779   symbol *csym;
780   int stack = 0;
781   int saveLevel = 0;
782
783   /* go thru the symbol chain   */
784   for (sym = symChain; sym; sym = sym->next)
785     {
786
787       /* if this is a typedef then add it */
788       /* to the typedef table             */
789       if (IS_TYPEDEF (sym->etype))
790         {
791           /* check if the typedef already exists    */
792           csym = findSym (TypedefTab, NULL, sym->name);
793           if (csym && csym->level == sym->level)
794             werror (E_DUPLICATE_TYPEDEF, sym->name);
795
796           addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
797           continue;             /* go to the next one         */
798         }
799       /* make sure it already exist */
800       csym = findSymWithLevel (SymbolTab, sym);
801       if (!csym || (csym && csym->level != sym->level))
802         csym = sym;
803
804       /* check the declaration */
805       checkDecl (csym,0);
806
807       /* if this is a function or a pointer to function */
808       /* then args  processing  */
809       if (funcInChain (csym->type))
810         {
811 #if 1 // jwk: TODO should have been done already in addDecl() (oclass????)
812           processFuncArgs (csym);
813 #endif
814           /* if register bank specified then update maxRegBank */
815           if (maxRegBank < FUNC_REGBANK (csym->type))
816             maxRegBank = FUNC_REGBANK (csym->type);
817         }
818
819       /* if this is a extern variable then change the */
820       /* level to zero temporarily                                    */
821       if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
822         {
823           saveLevel = csym->level;
824           csym->level = 0;
825         }
826
827       /* if this is a literal then it is an enumerated */
828       /* type so need not allocate it space for it     */
829       if (IS_LITERAL (sym->etype))
830         continue;
831
832       /* generate the actual declaration  */
833       if (csym->level)
834         {
835           allocLocal (csym);
836           if (csym->onStack)
837             stack += getSize (csym->type);
838         }
839       else
840         allocGlobal (csym);
841
842       /* restore the level */
843       if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
844         csym->level = saveLevel;
845     }
846
847   return stack;
848 }
849
850 /*-----------------------------------------------------------------*/
851 /* redoStackOffsets :- will reassign the values for stack offsets  */
852 /*-----------------------------------------------------------------*/
853 void 
854 redoStackOffsets (void)
855 {
856   symbol *sym;
857   int sPtr = 0;
858   int xsPtr = -1;
859
860   /* after register allocation is complete we know
861      which variables will need to be assigned space
862      on the stack. We will eliminate those variables
863      which do not have the allocReq flag thus reducing
864      the stack space */
865   for (sym = setFirstItem (istack->syms); sym;
866        sym = setNextItem (istack->syms))
867     {
868
869       int size = getSize (sym->type);
870       /* nothing to do with parameters so continue */
871       if ((sym->_isparm && !IS_REGPARM (sym->etype)))
872         continue;
873
874       if (IS_AGGREGATE (sym->type))
875         {
876           if (port->stack.direction > 0)
877             {
878               SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
879               sPtr += size;
880             }
881           else
882             {
883               sPtr -= size;
884               SPEC_STAK (sym->etype) = sym->stack = sPtr;
885             }
886           continue;
887         }
888
889       /* if allocation not required then subtract
890          size from overall stack size & continue */
891       if (!sym->allocreq)
892         {
893           currFunc->stack -= size;
894           SPEC_STAK (currFunc->etype) -= size;
895           continue;
896         }
897
898       if (port->stack.direction > 0)
899         {
900           SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
901           sPtr += size;
902         }
903       else
904         {
905           sPtr -= size;
906           SPEC_STAK (sym->etype) = sym->stack = sPtr;
907         }
908     }
909
910   /* do the same for the external stack */
911
912   for (sym = setFirstItem (xstack->syms); sym;
913        sym = setNextItem (xstack->syms))
914     {
915
916       int size = getSize (sym->type);
917       /* nothing to do with parameters so continue */
918       if ((sym->_isparm && !IS_REGPARM (sym->etype)))
919         continue;
920
921       if (IS_AGGREGATE (sym->type))
922         {
923           SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
924           xsPtr += size;
925           continue;
926         }
927
928       /* if allocation not required then subtract
929          size from overall stack size & continue */
930       if (!sym->allocreq)
931         {
932           currFunc->xstack -= size;
933           SPEC_STAK (currFunc->etype) -= size;
934           continue;
935         }
936
937       SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
938       xsPtr += size;
939     }
940
941   /* if the debug option is set then output the
942      symbols to the map file */
943   if (options.debug)
944     {
945       for (sym = setFirstItem (istack->syms); sym;
946            sym = setNextItem (istack->syms))
947         cdbSymbol (sym, cdbFile, FALSE, FALSE);
948
949       for (sym = setFirstItem (xstack->syms); sym;
950            sym = setNextItem (xstack->syms))
951         cdbSymbol (sym, cdbFile, FALSE, FALSE);
952     }
953 }
954
955 /*-----------------------------------------------------------------*/
956 /* printAllocInfoSeg- print the allocation for a given section     */
957 /*-----------------------------------------------------------------*/
958 static void 
959 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
960 {
961   symbol *sym;
962
963   if (!map)
964     return;
965   if (!map->syms)
966     return;
967
968   for (sym = setFirstItem (map->syms); sym;
969        sym = setNextItem (map->syms))
970     {
971
972       if (sym->level == 0)
973         continue;
974       if (sym->localof != func)
975         continue;
976       fprintf (of, ";%-25s Allocated to ", sym->name);
977
978       /* if assigned to registers */
979       if (!sym->allocreq && sym->reqv)
980         {
981           int i;
982           sym = OP_SYMBOL (sym->reqv);
983           fprintf (of, "registers ");
984           for (i = 0; i < 4 && sym->regs[i]; i++)
985             fprintf (of, "%s ", port->getRegName (sym->regs[i]));
986           fprintf (of, "\n");
987           continue;
988         }
989
990       /* if on stack */
991       if (sym->onStack)
992         {
993           fprintf (of, "stack - offset %d\n", sym->stack);
994           continue;
995         }
996
997       /* otherwise give rname */
998       fprintf (of, "in memory with name '%s'\n", sym->rname);
999     }
1000 }
1001
1002 /*-----------------------------------------------------------------*/
1003 /* canOverlayLocals - returns true if the local variables can overlayed */
1004 /*-----------------------------------------------------------------*/
1005 static bool 
1006 canOverlayLocals (eBBlock ** ebbs, int count)
1007 {
1008   int i;
1009   /* if staticAuto is in effect or the current function
1010      being compiled is reentrant or the overlay segment
1011      is empty or no overlay option is in effect then */
1012   if (options.noOverlay ||
1013       options.stackAuto ||
1014       (currFunc &&
1015        (IFFUNC_ISREENT (currFunc->type) ||
1016         FUNC_ISISR (currFunc->type))) ||
1017       elementsInSet (overlay->syms) == 0)
1018
1019     return FALSE;
1020
1021   /* otherwise do thru the blocks and see if there
1022      any function calls if found then return false */
1023   for (i = 0; i < count; i++)
1024     {
1025       iCode *ic;
1026
1027       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1028           if (ic) {
1029               if (ic->op == CALL) {
1030                   sym_link *ftype = operandType(IC_LEFT(ic));
1031                   /* builtins only can use overlays */
1032                   if (!IFFUNC_ISBUILTIN(ftype)) return FALSE; 
1033               } else if (ic->op == PCALL) return FALSE;
1034           }
1035     }
1036
1037   /* no function calls found return TRUE */
1038   return TRUE;
1039 }
1040
1041 /*-----------------------------------------------------------------*/
1042 /* doOverlays - move the overlay segment to appropriate location   */
1043 /*-----------------------------------------------------------------*/
1044 void 
1045 doOverlays (eBBlock ** ebbs, int count)
1046 {
1047   /* check if the parameters and local variables
1048      of this function can be put in the overlay segment
1049      This check is essentially to see if the function
1050      calls any other functions if yes then we cannot
1051      overlay */
1052   if (canOverlayLocals (ebbs, count))
1053     /* if we can then put the parameters &
1054        local variables in the overlay set */
1055     overlay2Set ();
1056   else
1057     /* otherwise put them into data where
1058        they belong */
1059     overlay2data ();
1060 }
1061
1062 /*-----------------------------------------------------------------*/
1063 /* printAllocInfo - prints allocation information for a function   */
1064 /*-----------------------------------------------------------------*/
1065 void 
1066 printAllocInfo (symbol * func, FILE * of)
1067 {
1068   if (!of)
1069     of = stdout;
1070
1071   /* must be called after register allocation is complete */
1072   fprintf (of, ";------------------------------------------------------------\n");
1073   fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1074   fprintf (of, ";------------------------------------------------------------\n");
1075
1076   printAllocInfoSeg (xstack, func, of);
1077   printAllocInfoSeg (istack, func, of);
1078   printAllocInfoSeg (code, func, of);
1079   printAllocInfoSeg (data, func, of);
1080   printAllocInfoSeg (xdata, func, of);
1081   printAllocInfoSeg (idata, func, of);
1082   printAllocInfoSeg (sfr, func, of);
1083   printAllocInfoSeg (sfrbit, func, of);
1084 }