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