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