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