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