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