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