Beautified (indented) compiler source tree
[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_SCLS (sym->etype) == S_CONSTANT)
381     {
382       SPEC_OCLS (sym->etype) = statsg;
383       allocIntoSeg (sym);
384       return;
385     }
386
387   if (SPEC_SCLS (sym->etype) == S_XDATA)
388     {
389       SPEC_OCLS (sym->etype) = xdata;
390       allocIntoSeg (sym);
391       return;
392     }
393
394   if (SPEC_SCLS (sym->etype) == S_IDATA)
395     {
396       SPEC_OCLS (sym->etype) = idata;
397       sym->iaccess = 1;
398       allocIntoSeg (sym);
399       return;
400     }
401
402   if (SPEC_SCLS (sym->etype) == S_EEPROM)
403     {
404       SPEC_OCLS (sym->etype) = eeprom;
405       allocIntoSeg (sym);
406       return;
407     }
408
409   return;
410 }
411
412 /*-----------------------------------------------------------------*/
413 /* allocParms - parameters are always passed on stack              */
414 /*-----------------------------------------------------------------*/
415 void 
416 allocParms (value * val)
417 {
418   value *lval;
419   int pNum = 1;
420
421   for (lval = val; lval; lval = lval->next, pNum++)
422     {
423
424       /* check the declaration */
425       checkDecl (lval->sym);
426
427       /* if this a register parm then allocate
428          it as a local variable by adding it
429          to the first block we see in the body */
430       if (IS_REGPARM (lval->etype))
431         continue;
432
433       /* mark it as my parameter */
434       lval->sym->ismyparm = 1;
435       lval->sym->localof = currFunc;
436
437
438       /* if automatic variables r 2b stacked */
439       if (options.stackAuto || IS_RENT (currFunc->etype))
440         {
441
442           if (lval->sym)
443             lval->sym->onStack = 1;
444
445           /* choose which stack 2 use   */
446           /*  use xternal stack */
447           if (options.useXstack)
448             {
449               /* PENDING: stack direction support */
450               SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
451               SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
452                 xstackPtr - getSize (lval->type);
453               xstackPtr -= getSize (lval->type);
454             }
455           else
456             {                   /* use internal stack   */
457               SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
458               if (port->stack.direction > 0)
459                 {
460                   SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
461                     stackPtr - (SPEC_BANK (currFunc->etype) ? port->stack.bank_overhead : 0) -
462                     getSize (lval->type) -
463                     (IS_ISR (currFunc->etype) ? port->stack.isr_overhead : 0);
464                   stackPtr -= getSize (lval->type);
465                 }
466               else
467                 {
468                   /* This looks like the wrong order but it turns out OK... */
469                   /* PENDING: isr, bank overhead, ... */
470                   SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
471                     stackPtr +
472                     (IS_BANKEDCALL (currFunc->etype) ? port->stack.banked_overhead : 0) +
473                     (IS_ISR (currFunc->etype) ? port->stack.isr_overhead : 0) +
474                     0;
475                   stackPtr += getSize (lval->type);
476                 }
477             }
478           allocIntoSeg (lval->sym);
479         }
480       else
481         {                       /* allocate them in the automatic space */
482           /* generate a unique name  */
483           sprintf (lval->sym->rname, "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
484           strcpy (lval->name, lval->sym->rname);
485
486           /* if declared in external storage */
487           if (SPEC_SCLS (lval->etype) == S_XDATA)
488             SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
489           else
490             /* other wise depending on the memory model 
491                note here that we put it into the overlay segment
492                first, we will remove it from the overlay segment
493                after the overlay determination has been done */
494           if (options.model == MODEL_SMALL)
495             {
496               SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
497                 (options.model == MODEL_SMALL ? port->mem.default_local_map :
498                  (options.noOverlay ? port->mem.default_local_map
499                   : overlay));
500             }
501           else
502             {
503               SPEC_SCLS (lval->etype) = S_XDATA;
504               SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
505             }
506           allocIntoSeg (lval->sym);
507         }
508     }
509
510   return;
511 }
512
513 /*-----------------------------------------------------------------*/
514 /* deallocParms - parameters are always passed on stack                */
515 /*-----------------------------------------------------------------*/
516 void 
517 deallocParms (value * val)
518 {
519   value *lval;
520
521   for (lval = val; lval; lval = lval->next)
522     {
523
524       /* unmark is myparm */
525       lval->sym->ismyparm = 0;
526       /* if on stack then depending on which stack */
527
528       /* delete it from the symbol table  */
529       deleteSym (SymbolTab, lval->sym, lval->sym->name);
530
531       if (!lval->sym->isref)
532         {
533           lval->sym->allocreq = 1;
534           werror (W_NO_REFERENCE, currFunc->name,
535                   "function argument", lval->sym->name);
536         }
537
538       /* move the rname if any to the name for both val & sym */
539       /* and leave a copy of it in the symbol table           */
540       if (lval->sym->rname[0])
541         {
542           char buffer[SDCC_NAME_MAX];
543           strcpy (buffer, lval->sym->rname);
544           lval->sym = copySymbol (lval->sym);
545           strcpy (lval->sym->rname, buffer);
546           strcpy (lval->name, strcpy (lval->sym->name, lval->sym->rname));
547           addSym (SymbolTab, lval->sym, lval->sym->name,
548                   lval->sym->level, lval->sym->block);
549           lval->sym->_isparm = 1;
550           addSet (&operKeyReset, lval->sym);
551         }
552
553     }
554
555   return;
556 }
557
558 /*-----------------------------------------------------------------*/
559 /* allocLocal - allocate local variables                           */
560 /*-----------------------------------------------------------------*/
561 void 
562 allocLocal (symbol * sym)
563 {
564
565   /* generate an unique name */
566   sprintf (sym->rname, "%s%s_%s_%d_%d",
567            port->fun_prefix,
568            currFunc->name, sym->name, sym->level, sym->block);
569
570   sym->islocal = 1;
571   sym->localof = currFunc;
572
573   /* if this is a static variable */
574   if (IS_STATIC (sym->etype))
575     {
576       allocGlobal (sym);
577       sym->allocreq = 1;
578       return;
579     }
580
581   /* if volatile then */
582   if (IS_VOLATILE (sym->etype))
583     sym->allocreq = 1;
584
585   /* this is automatic           */
586
587   /* if it to be placed on the stack */
588   if (options.stackAuto || reentrant)
589     {
590
591       sym->onStack = 1;
592       if (options.useXstack)
593         {
594           /* PENDING: stack direction for xstack */
595           SPEC_OCLS (sym->etype) = xstack;
596           SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
597           xstackPtr += getSize (sym->type);
598         }
599       else
600         {
601           SPEC_OCLS (sym->etype) = istack;
602           if (port->stack.direction > 0)
603             {
604               SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
605               stackPtr += getSize (sym->type);
606             }
607           else
608             {
609               stackPtr -= getSize (sym->type);
610               SPEC_STAK (sym->etype) = sym->stack = stackPtr;
611             }
612         }
613       allocIntoSeg (sym);
614       return;
615     }
616
617   /* else depending on the storage class specified */
618   if (SPEC_SCLS (sym->etype) == S_XDATA)
619     {
620       SPEC_OCLS (sym->etype) = xdata;
621       allocIntoSeg (sym);
622       return;
623     }
624
625   if ((SPEC_SCLS (sym->etype) == S_CODE ||
626        SPEC_SCLS (sym->etype) == S_CONSTANT) &&
627       !sym->_isparm)
628     {
629       SPEC_OCLS (sym->etype) = statsg;
630       allocIntoSeg (sym);
631       return;
632     }
633
634   if (SPEC_SCLS (sym->etype) == S_IDATA)
635     {
636       SPEC_OCLS (sym->etype) = idata;
637       sym->iaccess = 1;
638       allocIntoSeg (sym);
639       return;
640     }
641
642   /* if this is a function then assign code space    */
643   if (IS_FUNC (sym->type))
644     {
645       SPEC_OCLS (sym->etype) = code;
646       return;
647     }
648
649   /* if this is a  SFR or SBIT */
650   if (SPEC_SCLS (sym->etype) == S_SFR ||
651       SPEC_SCLS (sym->etype) == S_SBIT)
652     {
653
654       /* if both absolute address & initial  */
655       /* value specified then error        */
656       if (IS_ABSOLUTE (sym->etype) && sym->ival)
657         {
658           werror (E_SFR_INIT, sym->name);
659           sym->ival = NULL;
660         }
661
662       SPEC_OCLS (sym->etype) =
663         (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
664
665       allocIntoSeg (sym);
666       return;
667     }
668
669   /* if this is a bit variable and no storage class */
670   if (SPEC_NOUN (sym->etype) == V_BIT
671       && (SPEC_SCLS (sym->etype) == S_BIT))
672     {
673       SPEC_OCLS (sym->etype) = bit;
674       allocIntoSeg (sym);
675       return;
676     }
677
678   if (SPEC_SCLS (sym->etype) == S_DATA)
679     {
680       SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
681       allocIntoSeg (sym);
682       return;
683     }
684
685   if (SPEC_SCLS (sym->etype) == S_EEPROM)
686     {
687       SPEC_OCLS (sym->etype) = eeprom;
688       allocIntoSeg (sym);
689       return;
690     }
691
692   /* again note that we have put it into the overlay segment
693      will remove and put into the 'data' segment if required after 
694      overlay  analysis has been done */
695   SPEC_OCLS (sym->etype) = (options.model == MODEL_SMALL ? port->mem.default_local_map :
696                             (options.noOverlay ? port->mem.default_local_map
697                              : overlay));
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);
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);
807
808       /* if this is a function or a pointer to function */
809       /* then args  processing  */
810       if (funcInChain (csym->type))
811         {
812
813           processFuncArgs (csym, 1);
814           /* if register bank specified then update maxRegBank */
815           if (maxRegBank < SPEC_BANK (csym->etype))
816             maxRegBank = SPEC_BANK (csym->etype);
817         }
818
819       /* if this is a extern variable then change the */
820       /* level to zero temporarily                                    */
821       if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
822         {
823           saveLevel = csym->level;
824           csym->level = 0;
825         }
826
827       /* if this is a literal then it is an enumerated */
828       /* type so need not allocate it space for it     */
829       if (IS_LITERAL (sym->etype))
830         continue;
831
832       /* generate the actual declaration  */
833       if (csym->level)
834         {
835           allocLocal (csym);
836           if (csym->onStack)
837             stack += getSize (csym->type);
838         }
839       else
840         allocGlobal (csym);
841
842       /* restore the level */
843       if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
844         csym->level = saveLevel;
845     }
846
847   return stack;
848 }
849
850 /*-----------------------------------------------------------------*/
851 /* redoStackOffsets :- will reassign the values for stack offsets  */
852 /*-----------------------------------------------------------------*/
853 void 
854 redoStackOffsets (void)
855 {
856   symbol *sym;
857   int sPtr = 0;
858   int xsPtr = -1;
859
860   /* after register allocation is complete we know
861      which variables will need to be assigned space
862      on the stack. We will eliminate those variables
863      which do not have the allocReq flag thus reducing
864      the stack space */
865   for (sym = setFirstItem (istack->syms); sym;
866        sym = setNextItem (istack->syms))
867     {
868
869       int size = getSize (sym->type);
870       /* nothing to do with parameters so continue */
871       if ((sym->_isparm && !IS_REGPARM (sym->etype)))
872         continue;
873
874       if (IS_AGGREGATE (sym->type))
875         {
876           if (port->stack.direction > 0)
877             {
878               SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
879               sPtr += size;
880             }
881           else
882             {
883               sPtr -= size;
884               SPEC_STAK (sym->etype) = sym->stack = sPtr;
885             }
886           continue;
887         }
888
889       /* if allocation not required then subtract
890          size from overall stack size & continue */
891       if (!sym->allocreq)
892         {
893           currFunc->stack -= size;
894           SPEC_STAK (currFunc->etype) -= size;
895           continue;
896         }
897
898       if (port->stack.direction > 0)
899         {
900           SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
901           sPtr += size;
902         }
903       else
904         {
905           sPtr -= size;
906           SPEC_STAK (sym->etype) = sym->stack = sPtr;
907         }
908     }
909
910   /* do the same for the external stack */
911
912   for (sym = setFirstItem (xstack->syms); sym;
913        sym = setNextItem (xstack->syms))
914     {
915
916       int size = getSize (sym->type);
917       /* nothing to do with parameters so continue */
918       if ((sym->_isparm && !IS_REGPARM (sym->etype)))
919         continue;
920
921       if (IS_AGGREGATE (sym->type))
922         {
923           SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
924           xsPtr += size;
925           continue;
926         }
927
928       /* if allocation not required then subtract
929          size from overall stack size & continue */
930       if (!sym->allocreq)
931         {
932           currFunc->xstack -= size;
933           SPEC_STAK (currFunc->etype) -= size;
934           continue;
935         }
936
937       SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
938       xsPtr += size;
939     }
940
941   /* if the debug option is set then output the
942      symbols to the map file */
943   if (options.debug && !options.nodebug)
944     {
945       for (sym = setFirstItem (istack->syms); sym;
946            sym = setNextItem (istack->syms))
947         cdbSymbol (sym, cdbFile, FALSE, FALSE);
948
949       for (sym = setFirstItem (xstack->syms); sym;
950            sym = setNextItem (xstack->syms))
951         cdbSymbol (sym, cdbFile, FALSE, FALSE);
952     }
953 }
954
955 /*-----------------------------------------------------------------*/
956 /* printAllocInfoSeg- print the allocation for a given section     */
957 /*-----------------------------------------------------------------*/
958 static void 
959 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
960 {
961   symbol *sym;
962
963   if (!map)
964     return;
965   if (!map->syms)
966     return;
967
968   for (sym = setFirstItem (map->syms); sym;
969        sym = setNextItem (map->syms))
970     {
971
972       if (sym->level == 0)
973         continue;
974       if (sym->localof != func)
975         continue;
976       fprintf (of, ";%-25s Allocated to ", sym->name);
977
978       /* if assigned to registers */
979       if (!sym->allocreq && sym->reqv)
980         {
981           int i;
982           sym = OP_SYMBOL (sym->reqv);
983           fprintf (of, "registers ");
984           for (i = 0; i < 4 && sym->regs[i]; i++)
985             fprintf (of, "%s ", port->getRegName (sym->regs[i]));
986           fprintf (of, "\n");
987           continue;
988         }
989
990       /* if on stack */
991       if (sym->onStack)
992         {
993           fprintf (of, "stack - offset %d\n", sym->stack);
994           continue;
995         }
996
997       /* otherwise give rname */
998       fprintf (of, "in memory with name '%s'\n", sym->rname);
999     }
1000 }
1001
1002 /*-----------------------------------------------------------------*/
1003 /* canOverlayLocals - returns true if the local variables can overlayed */
1004 /*-----------------------------------------------------------------*/
1005 static bool 
1006 canOverlayLocals (eBBlock ** ebbs, int count)
1007 {
1008   int i;
1009   /* if staticAuto is in effect or the current function
1010      being compiled is reentrant or the overlay segment
1011      is empty or no overlay option is in effect then */
1012   if (options.noOverlay ||
1013       options.stackAuto ||
1014       (currFunc &&
1015        (IS_RENT (currFunc->etype) ||
1016         IS_ISR (currFunc->etype))) ||
1017       elementsInSet (overlay->syms) == 0)
1018
1019     return FALSE;
1020
1021   /* otherwise do thru the blocks and see if there
1022      any function calls if found then return false */
1023   for (i = 0; i < count; i++)
1024     {
1025       iCode *ic;
1026
1027       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1028         if (ic && (ic->op == CALL || ic->op == PCALL))
1029           return FALSE;
1030     }
1031
1032   /* no function calls found return TRUE */
1033   return TRUE;
1034 }
1035
1036 /*-----------------------------------------------------------------*/
1037 /* doOverlays - move the overlay segment to appropriate location   */
1038 /*-----------------------------------------------------------------*/
1039 void 
1040 doOverlays (eBBlock ** ebbs, int count)
1041 {
1042   /* check if the parameters and local variables
1043      of this function can be put in the overlay segment
1044      This check is essentially to see if the function
1045      calls any other functions if yes then we cannot
1046      overlay */
1047   if (canOverlayLocals (ebbs, count))
1048     /* if we can then put the parameters &
1049        local variables in the overlay set */
1050     overlay2Set ();
1051   else
1052     /* otherwise put them into data where
1053        they belong */
1054     overlay2data ();
1055 }
1056
1057 /*-----------------------------------------------------------------*/
1058 /* printAllocInfo - prints allocation information for a function   */
1059 /*-----------------------------------------------------------------*/
1060 void 
1061 printAllocInfo (symbol * func, FILE * of)
1062 {
1063   if (!of)
1064     of = stdout;
1065
1066   /* must be called after register allocation is complete */
1067   fprintf (of, ";------------------------------------------------------------\n");
1068   fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1069   fprintf (of, ";------------------------------------------------------------\n");
1070
1071   printAllocInfoSeg (xstack, func, of);
1072   printAllocInfoSeg (istack, func, of);
1073   printAllocInfoSeg (code, func, of);
1074   printAllocInfoSeg (data, func, of);
1075   printAllocInfoSeg (xdata, func, of);
1076   printAllocInfoSeg (idata, func, of);
1077   printAllocInfoSeg (sfr, func, of);
1078   printAllocInfoSeg (sfrbit, func, of);
1079 }