mmmm, that could be better
[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   addSet (&segment->syms, sym);
268 }
269
270 /*-----------------------------------------------------------------*/
271 /* allocGlobal - assigns the output segment to a global var       */
272 /*-----------------------------------------------------------------*/
273 void 
274 allocGlobal (symbol * sym)
275 {
276
277   /* symbol name is internal name  */
278   if (!sym->level)              /* local statics can come here */
279     sprintf (sym->rname, "%s%s", port->fun_prefix, sym->name);
280
281   /* add it to the operandKey reset */
282   addSet (&operKeyReset, sym);
283
284   /* if this is a literal e.g. enumerated type */
285   /* put it in the data segment & do nothing   */
286   if (IS_LITERAL (sym->etype))
287     {
288       SPEC_OCLS (sym->etype) = data;
289       return;
290     }
291
292   /* if this is a function then assign code space    */
293   if (IS_FUNC (sym->type))
294     {
295       SPEC_OCLS (sym->etype) = code;
296       /* if this is an interrupt service routine
297          then put it in the interrupt service array */
298       if (FUNC_ISISR (sym->type))
299         {
300
301           if (interrupts[FUNC_INTNO (sym->type)])
302             werror (E_INT_DEFINED,
303                     FUNC_INTNO (sym->type),
304                     interrupts[FUNC_INTNO (sym->type)]->name);
305           else
306             interrupts[FUNC_INTNO (sym->type)] = sym;
307
308           /* automagically extend the maximum interrupts */
309           if (FUNC_INTNO (sym->type) >= maxInterrupts)
310             maxInterrupts = FUNC_INTNO (sym->type) + 1;
311         }
312       /* if it is not compiler defined */
313       if (!sym->cdef)
314         allocIntoSeg (sym);
315
316       return;
317     }
318
319   /* if this is a  SFR or SBIT */
320   if (SPEC_SCLS (sym->etype) == S_SFR ||
321       SPEC_SCLS (sym->etype) == S_SBIT)
322     {
323
324       /* if both absolute address & initial  */
325       /* value specified then error        */
326       if (IS_ABSOLUTE (sym->etype) && sym->ival)
327         {
328           werror (E_SFR_INIT, sym->name);
329           sym->ival = NULL;
330         }
331
332       SPEC_OCLS (sym->etype) =
333         (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
334
335       allocIntoSeg (sym);
336       return;
337     }
338
339   /* if this is a bit variable and no storage class */
340   if (SPEC_NOUN (sym->etype) == V_BIT
341       && SPEC_SCLS (sym->etype) == S_BIT)
342     {
343       SPEC_OCLS (sym->etype) = bit;
344       allocIntoSeg (sym);
345       return;
346     }
347
348   /* if bit storage class */
349   if (SPEC_SCLS (sym->etype) == S_SBIT)
350     {
351       SPEC_OCLS (sym->etype) = bit;
352       allocIntoSeg (sym);
353       return;
354     }
355
356   /* register storage class ignored changed to FIXED */
357   if (SPEC_SCLS (sym->etype) == S_REGISTER)
358     SPEC_SCLS (sym->etype) = S_FIXED;
359
360   /* if data specified then  */
361   if (SPEC_SCLS (sym->etype) == S_DATA)
362     {
363       /* set the output class */
364       SPEC_OCLS (sym->etype) = data;
365       /* generate the symbol  */
366       allocIntoSeg (sym);
367       return;
368     }
369
370   /* if it is fixed, then allocate depending on the  */
371   /* current memory model,same for automatics        */
372   if (SPEC_SCLS (sym->etype) == S_FIXED ||
373       SPEC_SCLS (sym->etype) == S_AUTO)
374     {
375       /* set the output class */
376       SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
377       /* generate the symbol  */
378       allocIntoSeg (sym);
379       return;
380     }
381
382   /* if code change to constant */
383   if (SPEC_SCLS (sym->etype) == S_CODE) {
384     SPEC_OCLS (sym->etype) = statsg;
385     allocIntoSeg (sym);
386     return;
387   }
388
389   if (SPEC_SCLS (sym->etype) == S_XDATA)
390     {
391       SPEC_OCLS (sym->etype) = xdata;
392       // should we move this to the initialized data segment?
393       if (port->genXINIT &&
394           sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
395         SPEC_OCLS(sym->etype)=xidata;
396         addSet(&xidata->syms, sym);
397       }
398       allocIntoSeg (sym);
399       return;
400     }
401
402   if (SPEC_SCLS (sym->etype) == S_IDATA)
403     {
404       SPEC_OCLS (sym->etype) = idata;
405       sym->iaccess = 1;
406       allocIntoSeg (sym);
407       return;
408     }
409
410   if (SPEC_SCLS (sym->etype) == S_EEPROM)
411     {
412       SPEC_OCLS (sym->etype) = eeprom;
413       allocIntoSeg (sym);
414       return;
415     }
416
417   return;
418 }
419
420 /*-----------------------------------------------------------------*/
421 /* allocParms - parameters are always passed on stack              */
422 /*-----------------------------------------------------------------*/
423 void 
424 allocParms (value * val)
425 {
426   value *lval;
427   int pNum = 1;
428
429   for (lval = val; lval; lval = lval->next, pNum++)
430     {
431
432       /* check the declaration */
433       checkDecl (lval->sym, 0);
434
435       /* if this a register parm then allocate
436          it as a local variable by adding it
437          to the first block we see in the body */
438       if (IS_REGPARM (lval->etype))
439         continue;
440
441       /* mark it as my parameter */
442       lval->sym->ismyparm = 1;
443       lval->sym->localof = currFunc;
444
445
446       /* if automatic variables r 2b stacked */
447       if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
448         {
449
450           if (lval->sym)
451             lval->sym->onStack = 1;
452
453           /* choose which stack 2 use   */
454           /*  use xternal stack */
455           if (options.useXstack)
456             {
457               /* PENDING: stack direction support */
458               SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
459               SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
460                 xstackPtr - getSize (lval->type);
461               xstackPtr -= getSize (lval->type);
462             }
463           else
464             {                   /* use internal stack   */
465               SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
466               if (port->stack.direction > 0)
467                 {
468                   SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
469                     stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
470                     getSize (lval->type) -
471                     (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
472                   stackPtr -= getSize (lval->type);
473                 }
474               else
475                 {
476                   /* This looks like the wrong order but it turns out OK... */
477                   /* PENDING: isr, bank overhead, ... */
478                   SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
479                     stackPtr +
480                     ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
481                     (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
482                     0;
483                   stackPtr += getSize (lval->type);
484                 }
485             }
486           allocIntoSeg (lval->sym);
487         }
488       else
489         { /* allocate them in the automatic space */
490           /* generate a unique name  */
491           sprintf (lval->sym->rname, "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
492           strcpy (lval->name, lval->sym->rname);
493           
494           /* if declared in external storage */
495           if (SPEC_SCLS (lval->etype) == S_XDATA)
496             SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
497           else
498             /* other wise depending on the memory model 
499                note here that we put it into the overlay segment
500                first, we will remove it from the overlay segment
501                after the overlay determination has been done */
502             if (options.model == MODEL_SMALL)
503               {
504                 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
505                   (options.noOverlay ? port->mem.default_local_map
506                    : overlay);
507               }
508             else
509               {
510                 SPEC_SCLS (lval->etype) = S_XDATA;
511                 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
512               }
513           allocIntoSeg (lval->sym);
514         }
515     }
516
517   return;
518 }
519
520 /*-----------------------------------------------------------------*/
521 /* deallocParms - parameters are always passed on stack                */
522 /*-----------------------------------------------------------------*/
523 void 
524 deallocParms (value * val)
525 {
526   value *lval;
527
528   for (lval = val; lval; lval = lval->next)
529     {
530
531       /* unmark is myparm */
532       lval->sym->ismyparm = 0;
533       /* if on stack then depending on which stack */
534
535       /* delete it from the symbol table  */
536       deleteSym (SymbolTab, lval->sym, lval->sym->name);
537
538       if (!lval->sym->isref)
539         {
540           lval->sym->allocreq = 1;
541           werror (W_NO_REFERENCE, currFunc->name,
542                   "function argument", lval->sym->name);
543         }
544
545       /* move the rname if any to the name for both val & sym */
546       /* and leave a copy of it in the symbol table           */
547       if (lval->sym->rname[0])
548         {
549           char buffer[SDCC_NAME_MAX];
550           strcpy (buffer, lval->sym->rname);
551           lval->sym = copySymbol (lval->sym);
552           strcpy (lval->sym->rname, buffer);
553           strcpy (lval->name, strcpy (lval->sym->name, lval->sym->rname));
554           addSym (SymbolTab, lval->sym, lval->sym->name,
555                   lval->sym->level, lval->sym->block, 1);
556           lval->sym->_isparm = 1;
557           addSet (&operKeyReset, lval->sym);
558         }
559
560     }
561
562   return;
563 }
564
565 /*-----------------------------------------------------------------*/
566 /* allocLocal - allocate local variables                           */
567 /*-----------------------------------------------------------------*/
568 void 
569 allocLocal (symbol * sym)
570 {
571
572   /* generate an unique name */
573   sprintf (sym->rname, "%s%s_%s_%d_%d",
574            port->fun_prefix,
575            currFunc->name, sym->name, sym->level, sym->block);
576
577   sym->islocal = 1;
578   sym->localof = currFunc;
579
580   /* if this is a static variable */
581   if (IS_STATIC (sym->etype))
582     {
583       allocGlobal (sym);
584       sym->allocreq = 1;
585       return;
586     }
587
588   /* if volatile then */
589   if (IS_VOLATILE (sym->etype))
590     sym->allocreq = 1;
591
592   /* this is automatic           */
593
594   /* if it to be placed on the stack */
595   if (options.stackAuto || reentrant) {
596     sym->onStack = 1;
597     if (options.useXstack) {
598       /* PENDING: stack direction for xstack */
599       SPEC_OCLS (sym->etype) = xstack;
600       SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
601       xstackPtr += getSize (sym->type);
602     } else {
603       SPEC_OCLS (sym->etype) = istack;
604       if (port->stack.direction > 0) {
605         SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
606         stackPtr += getSize (sym->type);
607       } else {
608         stackPtr -= getSize (sym->type);
609         SPEC_STAK (sym->etype) = sym->stack = stackPtr;
610       }
611     }
612     allocIntoSeg (sym);
613     return;
614   }
615   
616   /* else depending on the storage class specified */
617   if (SPEC_SCLS (sym->etype) == S_XDATA)
618     {
619       SPEC_OCLS (sym->etype) = xdata;
620       allocIntoSeg (sym);
621       return;
622     }
623
624   if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
625     SPEC_OCLS (sym->etype) = statsg;
626     allocIntoSeg (sym);
627     return;
628   }
629   
630   if (SPEC_SCLS (sym->etype) == S_IDATA)
631     {
632       SPEC_OCLS (sym->etype) = idata;
633       sym->iaccess = 1;
634       allocIntoSeg (sym);
635       return;
636     }
637
638   /* if this is a function then assign code space    */
639   if (IS_FUNC (sym->type))
640     {
641       SPEC_OCLS (sym->etype) = code;
642       return;
643     }
644
645   /* if this is a  SFR or SBIT */
646   if (SPEC_SCLS (sym->etype) == S_SFR ||
647       SPEC_SCLS (sym->etype) == S_SBIT)
648     {
649
650       /* if both absolute address & initial  */
651       /* value specified then error        */
652       if (IS_ABSOLUTE (sym->etype) && sym->ival)
653         {
654           werror (E_SFR_INIT, sym->name);
655           sym->ival = NULL;
656         }
657
658       SPEC_OCLS (sym->etype) =
659         (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
660
661       allocIntoSeg (sym);
662       return;
663     }
664
665   /* if this is a bit variable and no storage class */
666   if (SPEC_NOUN (sym->etype) == V_BIT
667       && (SPEC_SCLS (sym->etype) == S_BIT))
668     {
669       SPEC_OCLS (sym->etype) = bit;
670       allocIntoSeg (sym);
671       return;
672     }
673
674   if (SPEC_SCLS (sym->etype) == S_DATA)
675     {
676       SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
677       allocIntoSeg (sym);
678       return;
679     }
680
681   if (SPEC_SCLS (sym->etype) == S_EEPROM)
682     {
683       SPEC_OCLS (sym->etype) = eeprom;
684       allocIntoSeg (sym);
685       return;
686     }
687
688   /* again note that we have put it into the overlay segment
689      will remove and put into the 'data' segment if required after 
690      overlay  analysis has been done */
691   if (options.model == MODEL_SMALL) {
692     SPEC_OCLS (sym->etype) = 
693       (options.noOverlay ? port->mem.default_local_map
694        : overlay);
695   } else {
696     SPEC_OCLS (sym->etype) = port->mem.default_local_map;
697   }
698   allocIntoSeg (sym);
699 }
700
701 /*-----------------------------------------------------------------*/
702 /* deallocLocal - deallocates the local variables                  */
703 /*-----------------------------------------------------------------*/
704 void 
705 deallocLocal (symbol * csym)
706 {
707   symbol *sym;
708
709   for (sym = csym; sym; sym = sym->next)
710     {
711       if (sym->_isparm)
712         continue;
713
714       /* if it is on the stack */
715       if (sym->onStack)
716         {
717           if (options.useXstack)
718             xstackPtr -= getSize (sym->type);
719           else
720             stackPtr -= getSize (sym->type);
721         }
722       /* if not used give a warning */
723       if (!sym->isref && !IS_STATIC (sym->etype))
724         werror (W_NO_REFERENCE, currFunc->name,
725                 "local variable", sym->name);
726       /* now delete it from the symbol table */
727       deleteSym (SymbolTab, sym, sym->name);
728     }
729 }
730
731 /*-----------------------------------------------------------------*/
732 /* overlay2data - moves declarations from the overlay seg to data  */
733 /*-----------------------------------------------------------------*/
734 void 
735 overlay2data ()
736 {
737   symbol *sym;
738
739   for (sym = setFirstItem (overlay->syms); sym;
740        sym = setNextItem (overlay->syms))
741     {
742
743       SPEC_OCLS (sym->etype) = data;
744       allocIntoSeg (sym);
745     }
746
747   setToNull ((void **) &overlay->syms);
748
749 }
750
751 /*-----------------------------------------------------------------*/
752 /* overlay2Set - will add all symbols from the overlay segment to  */
753 /*               the set of sets containing the overlable symbols  */
754 /*-----------------------------------------------------------------*/
755 void 
756 overlay2Set ()
757 {
758   symbol *sym;
759   set *oset = NULL;
760
761   for (sym = setFirstItem (overlay->syms); sym;
762        sym = setNextItem (overlay->syms))
763     {
764
765       addSet (&oset, sym);
766     }
767
768   setToNull ((void **) &overlay->syms);
769   addSet (&ovrSetSets, oset);
770
771 }
772
773 /*-----------------------------------------------------------------*/
774 /* allocVariables - creates decl & assign storage class for a v    */
775 /*-----------------------------------------------------------------*/
776 int 
777 allocVariables (symbol * symChain)
778 {
779   symbol *sym;
780   symbol *csym;
781   int stack = 0;
782   int saveLevel = 0;
783
784   /* go thru the symbol chain   */
785   for (sym = symChain; sym; sym = sym->next)
786     {
787
788       /* if this is a typedef then add it */
789       /* to the typedef table             */
790       if (IS_TYPEDEF (sym->etype))
791         {
792           /* check if the typedef already exists    */
793           csym = findSym (TypedefTab, NULL, sym->name);
794           if (csym && csym->level == sym->level)
795             werror (E_DUPLICATE_TYPEDEF, sym->name);
796
797           addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
798           continue;             /* go to the next one         */
799         }
800       /* make sure it already exist */
801       csym = findSymWithLevel (SymbolTab, sym);
802       if (!csym || (csym && csym->level != sym->level))
803         csym = sym;
804
805       /* check the declaration */
806       checkDecl (csym,0);
807
808       /* if this is a function or a pointer to function */
809       /* then args  processing  */
810       if (funcInChain (csym->type))
811         {
812 #if 1 // jwk: TODO should have been done already in addDecl() (oclass????)
813           processFuncArgs (csym);
814 #endif
815           /* if register bank specified then update maxRegBank */
816           if (maxRegBank < FUNC_REGBANK (csym->type))
817             maxRegBank = FUNC_REGBANK (csym->type);
818         }
819
820       /* if this is a extern variable then change the */
821       /* level to zero temporarily                                    */
822       if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
823         {
824           saveLevel = csym->level;
825           csym->level = 0;
826         }
827
828       /* if this is a literal then it is an enumerated */
829       /* type so need not allocate it space for it     */
830       if (IS_LITERAL (sym->etype))
831         continue;
832
833       /* generate the actual declaration  */
834       if (csym->level)
835         {
836           allocLocal (csym);
837           if (csym->onStack)
838             stack += getSize (csym->type);
839         }
840       else
841         allocGlobal (csym);
842
843       /* restore the level */
844       if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
845         csym->level = saveLevel;
846     }
847
848   return stack;
849 }
850
851 /*-----------------------------------------------------------------*/
852 /* redoStackOffsets :- will reassign the values for stack offsets  */
853 /*-----------------------------------------------------------------*/
854 void 
855 redoStackOffsets (void)
856 {
857   symbol *sym;
858   int sPtr = 0;
859   int xsPtr = -1;
860
861   /* after register allocation is complete we know
862      which variables will need to be assigned space
863      on the stack. We will eliminate those variables
864      which do not have the allocReq flag thus reducing
865      the stack space */
866   for (sym = setFirstItem (istack->syms); sym;
867        sym = setNextItem (istack->syms))
868     {
869
870       int size = getSize (sym->type);
871       /* nothing to do with parameters so continue */
872       if ((sym->_isparm && !IS_REGPARM (sym->etype)))
873         continue;
874
875       if (IS_AGGREGATE (sym->type))
876         {
877           if (port->stack.direction > 0)
878             {
879               SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
880               sPtr += size;
881             }
882           else
883             {
884               sPtr -= size;
885               SPEC_STAK (sym->etype) = sym->stack = sPtr;
886             }
887           continue;
888         }
889
890       /* if allocation not required then subtract
891          size from overall stack size & continue */
892       if (!sym->allocreq)
893         {
894           currFunc->stack -= size;
895           SPEC_STAK (currFunc->etype) -= size;
896           continue;
897         }
898
899       if (port->stack.direction > 0)
900         {
901           SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
902           sPtr += size;
903         }
904       else
905         {
906           sPtr -= size;
907           SPEC_STAK (sym->etype) = sym->stack = sPtr;
908         }
909     }
910
911   /* do the same for the external stack */
912
913   for (sym = setFirstItem (xstack->syms); sym;
914        sym = setNextItem (xstack->syms))
915     {
916
917       int size = getSize (sym->type);
918       /* nothing to do with parameters so continue */
919       if ((sym->_isparm && !IS_REGPARM (sym->etype)))
920         continue;
921
922       if (IS_AGGREGATE (sym->type))
923         {
924           SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
925           xsPtr += size;
926           continue;
927         }
928
929       /* if allocation not required then subtract
930          size from overall stack size & continue */
931       if (!sym->allocreq)
932         {
933           currFunc->xstack -= size;
934           SPEC_STAK (currFunc->etype) -= size;
935           continue;
936         }
937
938       SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
939       xsPtr += size;
940     }
941
942   /* if the debug option is set then output the
943      symbols to the map file */
944   if (options.debug)
945     {
946       for (sym = setFirstItem (istack->syms); sym;
947            sym = setNextItem (istack->syms))
948         cdbSymbol (sym, cdbFile, FALSE, FALSE);
949
950       for (sym = setFirstItem (xstack->syms); sym;
951            sym = setNextItem (xstack->syms))
952         cdbSymbol (sym, cdbFile, FALSE, FALSE);
953     }
954 }
955
956 /*-----------------------------------------------------------------*/
957 /* printAllocInfoSeg- print the allocation for a given section     */
958 /*-----------------------------------------------------------------*/
959 static void 
960 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
961 {
962   symbol *sym;
963
964   if (!map)
965     return;
966   if (!map->syms)
967     return;
968
969   for (sym = setFirstItem (map->syms); sym;
970        sym = setNextItem (map->syms))
971     {
972
973       if (sym->level == 0)
974         continue;
975       if (sym->localof != func)
976         continue;
977       fprintf (of, ";%-25s Allocated to ", sym->name);
978
979       /* if assigned to registers */
980       if (!sym->allocreq && sym->reqv)
981         {
982           int i;
983           sym = OP_SYMBOL (sym->reqv);
984           fprintf (of, "registers ");
985           for (i = 0; i < 4 && sym->regs[i]; i++)
986             fprintf (of, "%s ", port->getRegName (sym->regs[i]));
987           fprintf (of, "\n");
988           continue;
989         }
990
991       /* if on stack */
992       if (sym->onStack)
993         {
994           fprintf (of, "stack - offset %d\n", sym->stack);
995           continue;
996         }
997
998       /* otherwise give rname */
999       fprintf (of, "in memory with name '%s'\n", sym->rname);
1000     }
1001 }
1002
1003 /*-----------------------------------------------------------------*/
1004 /* canOverlayLocals - returns true if the local variables can overlayed */
1005 /*-----------------------------------------------------------------*/
1006 static bool 
1007 canOverlayLocals (eBBlock ** ebbs, int count)
1008 {
1009   int i;
1010   /* if staticAuto is in effect or the current function
1011      being compiled is reentrant or the overlay segment
1012      is empty or no overlay option is in effect then */
1013   if (options.noOverlay ||
1014       options.stackAuto ||
1015       (currFunc &&
1016        (IFFUNC_ISREENT (currFunc->type) ||
1017         FUNC_ISISR (currFunc->type))) ||
1018       elementsInSet (overlay->syms) == 0)
1019
1020     return FALSE;
1021
1022   /* otherwise do thru the blocks and see if there
1023      any function calls if found then return false */
1024   for (i = 0; i < count; i++)
1025     {
1026       iCode *ic;
1027
1028       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1029           if (ic) {
1030               if (ic->op == CALL) {
1031                   sym_link *ftype = operandType(IC_LEFT(ic));
1032                   /* builtins only can use overlays */
1033                   if (!IFFUNC_ISBUILTIN(ftype)) return FALSE; 
1034               } else if (ic->op == PCALL) return FALSE;
1035           }
1036     }
1037
1038   /* no function calls found return TRUE */
1039   return TRUE;
1040 }
1041
1042 /*-----------------------------------------------------------------*/
1043 /* doOverlays - move the overlay segment to appropriate location   */
1044 /*-----------------------------------------------------------------*/
1045 void 
1046 doOverlays (eBBlock ** ebbs, int count)
1047 {
1048   /* check if the parameters and local variables
1049      of this function can be put in the overlay segment
1050      This check is essentially to see if the function
1051      calls any other functions if yes then we cannot
1052      overlay */
1053   if (canOverlayLocals (ebbs, count))
1054     /* if we can then put the parameters &
1055        local variables in the overlay set */
1056     overlay2Set ();
1057   else
1058     /* otherwise put them into data where
1059        they belong */
1060     overlay2data ();
1061 }
1062
1063 /*-----------------------------------------------------------------*/
1064 /* printAllocInfo - prints allocation information for a function   */
1065 /*-----------------------------------------------------------------*/
1066 void 
1067 printAllocInfo (symbol * func, FILE * of)
1068 {
1069   if (!of)
1070     of = stdout;
1071
1072   /* must be called after register allocation is complete */
1073   fprintf (of, ";------------------------------------------------------------\n");
1074   fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1075   fprintf (of, ";------------------------------------------------------------\n");
1076
1077   printAllocInfoSeg (xstack, func, of);
1078   printAllocInfoSeg (istack, func, of);
1079   printAllocInfoSeg (code, func, of);
1080   printAllocInfoSeg (data, func, of);
1081   printAllocInfoSeg (xdata, func, of);
1082   printAllocInfoSeg (idata, func, of);
1083   printAllocInfoSeg (sfr, func, of);
1084   printAllocInfoSeg (sfrbit, func, of);
1085 }