Infrastructure stuff for 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     return ;
375 }
376
377 /*-----------------------------------------------------------------*/
378 /* allocParms - parameters are always passed on stack              */
379 /*-----------------------------------------------------------------*/
380 void allocParms ( value  *val )
381 {
382     value    *lval ;   
383     int      pNum = 1;
384
385     for ( lval = val ; lval ; lval = lval->next, pNum++ ) {
386
387         /* check the declaration */
388         checkDecl (lval->sym);
389         
390         /* if this a register parm then allocate
391            it as a local variable by adding it
392            to the first block we see in the body */
393         if (IS_REGPARM(lval->etype)) 
394             continue ;
395
396         /* mark it as my parameter */
397         lval->sym->ismyparm = 1;
398         lval->sym->localof = currFunc;
399
400         
401         /* if automatic variables r 2b stacked */
402         if ( options.stackAuto || IS_RENT(currFunc->etype)) {
403
404             if (lval->sym)
405                 lval->sym->onStack = 1;
406
407             /* choose which stack 2 use   */
408             /*  use xternal stack */
409             if ( options.useXstack )    {
410                 /* PENDING: stack direction support */
411                 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xstack ;
412                 SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack =
413                     xstackPtr - getSize(lval->type);            
414                 xstackPtr -= getSize (lval->type);
415             }
416             else   {    /* use internal stack   */
417                 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = istack ;
418                 if (port->stack.direction > 0) {
419                     SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack = 
420                         stackPtr - ( SPEC_BANK(currFunc->etype) ? port->stack.bank_overhead : 0) - 
421                         getSize(lval->type) -
422                         (IS_ISR(currFunc->etype) ? port->stack.isr_overhead : 0); 
423                     stackPtr -= getSize (lval->type);
424                 }
425                 else {
426                     /* This looks like the wrong order but it turns out OK... */
427                     /* PENDING: isr, bank overhead, ... */
428                     SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack = stackPtr;
429                     stackPtr += getSize (lval->type);
430                 }                   
431             }
432             allocIntoSeg(lval->sym);
433         }
434         else   {        /* allocate them in the automatic space */
435             /* generate a unique name  */
436             sprintf (lval->sym->rname,"_%s_PARM_%d",currFunc->name,pNum);
437             strcpy  (lval->name,lval->sym->rname);
438             
439             /* if declared in external storage */
440             if (SPEC_SCLS(lval->etype) == S_XDATA) 
441                  SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xdata;
442             else
443                 /* other wise depending on the memory model 
444                    note here that we put it into the overlay segment
445                    first, we will remove it from the overlay segment
446                    after the overlay determination has been done */
447                 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = 
448                     ( options.model  ? port->mem.default_local_map : 
449                       (options.noOverlay ? port->mem.default_local_map
450                        :overlay ));
451             
452             allocIntoSeg(lval->sym);
453         }
454     }
455     
456     return ;
457 }
458
459 /*-----------------------------------------------------------------*/
460 /* deallocParms - parameters are always passed on stack                */
461 /*-----------------------------------------------------------------*/
462 void  deallocParms ( value *val )
463 {
464     value    *lval ;
465     
466     for ( lval = val ; lval ; lval = lval->next ) {
467
468         /* unmark is myparm */
469         lval->sym->ismyparm = 0;
470         /* if on stack then depending on which stack */
471         
472         /* delete it from the symbol table  */
473         deleteSym (SymbolTab,lval->sym,lval->sym->name); 
474
475         if (!lval->sym->isref) {
476             lval->sym->allocreq = 1;
477             werror(W_NO_REFERENCE,currFunc->name,
478                    "function argument",lval->sym->name);
479         }
480
481         /* move the rname if any to the name for both val & sym */
482         /* and leave a copy of it in the symbol table           */
483         if (lval->sym->rname[0]) {
484             char buffer[SDCC_NAME_MAX];
485             strcpy(buffer,lval->sym->rname);
486             lval->sym = copySymbol(lval->sym);
487             strcpy(lval->sym->rname,buffer);
488             strcpy(lval->name,strcpy(lval->sym->name,lval->sym->rname));
489             addSym (SymbolTab, lval->sym, lval->sym->name, 
490                     lval->sym->level,lval->sym->block);     
491             lval->sym->_isparm = 1;
492             addSet(&operKeyReset,lval->sym);
493         }
494
495     }
496     
497     return ;
498 }
499
500 /*-----------------------------------------------------------------*/
501 /* allocLocal - allocate local variables                           */
502 /*-----------------------------------------------------------------*/
503 void allocLocal ( symbol *sym  )
504 {   
505     
506     /* generate an unique name */
507     sprintf(sym->rname,"_%s_%s_%d_%d",
508             currFunc->name,sym->name,sym->level,sym->block);
509     
510     sym->islocal = 1;
511     sym->localof = currFunc;
512
513     /* if this is a static variable */
514     if ( IS_STATIC (sym->etype)) {
515 /*      SPEC_OCLS(sym->etype) = (options.model ? xdata : data ); */
516         SPEC_OCLS(sym->etype) = port->mem.default_local_map;
517         allocIntoSeg (sym);
518         sym->allocreq = 1;
519         return   ;
520     }
521     
522     /* if volatile then */
523     if (IS_VOLATILE(sym->etype))
524         sym->allocreq = 1;
525
526     /* this is automatic           */
527
528     /* if it to be placed on the stack */
529     if ( options.stackAuto || reentrant) {
530                
531         sym->onStack = 1;
532         if ( options.useXstack ) { 
533             /* PENDING: stack direction for xstack */
534             SPEC_OCLS(sym->etype) = xstack ;
535             SPEC_STAK(sym->etype) = sym->stack = (xstackPtr + 1);
536             xstackPtr += getSize (sym->type) ;
537         }
538         else {
539             SPEC_OCLS(sym->etype) = istack ;
540             if (port->stack.direction > 0) {
541                 SPEC_STAK(sym->etype) = sym->stack = ( stackPtr + 1);
542                 stackPtr += getSize (sym->type) ;
543             }
544             else {
545                 stackPtr -= getSize (sym->type);
546                 SPEC_STAK(sym->etype) = sym->stack = stackPtr;
547             }
548         }
549         allocIntoSeg(sym);
550         return ;
551     }
552     
553     /* else depending on the storage class specified */
554     if ( SPEC_SCLS(sym->etype) == S_XDATA  )    {
555         SPEC_OCLS(sym->etype) = xdata  ;
556         allocIntoSeg(sym)  ;
557         return ;
558     }
559
560     if ( (SPEC_SCLS(sym->etype) == S_CODE   ||
561           SPEC_SCLS(sym->etype) == S_CONSTANT) &&
562          !sym->_isparm)  {
563         SPEC_OCLS(sym->etype) = statsg   ;
564         allocIntoSeg (sym)  ;
565         return ;
566     }
567
568     if ( SPEC_SCLS(sym->etype) == S_IDATA  )    {
569         SPEC_OCLS(sym->etype) = idata ;
570         sym->iaccess = 1;
571         allocIntoSeg (sym)  ;
572         return ;
573     }    
574
575         /* if this is a function then assign code space    */
576     if (IS_FUNC(sym->type)) {
577         SPEC_OCLS(sym->etype)  = code ;
578         return ;
579     }
580         
581     /* if this is a  SFR or SBIT */
582     if (  SPEC_SCLS(sym->etype) == S_SFR   ||
583           SPEC_SCLS(sym->etype) == S_SBIT  )  {
584         
585         /* if both absolute address & initial  */
586         /* value specified then error        */
587         if ( IS_ABSOLUTE (sym->etype) && sym->ival ) {
588             werror(E_SFR_INIT,sym->name);
589             sym->ival = NULL ;
590         }
591         
592         SPEC_OCLS(sym->etype) = 
593             (SPEC_SCLS(sym->etype) == S_SFR ? sfr : sfrbit);
594         
595         allocIntoSeg (sym);
596         return ;
597     }
598     
599     /* if this is a bit variable and no storage class */
600     if ( SPEC_NOUN(sym->etype) == V_BIT  
601          && (SPEC_SCLS(sym->etype) == S_BIT)) {       
602         SPEC_OCLS(sym->etype) = bit ;
603         allocIntoSeg (sym);
604         return  ;
605     }
606
607     if ( SPEC_SCLS(sym->etype) == S_DATA  )    {
608         SPEC_OCLS(sym->etype) = (options.noOverlay ? data : overlay );
609         allocIntoSeg(sym)  ;
610         return ;
611     }
612     
613     /* again note that we have put it into the overlay segment
614        will remove and put into the 'data' segment if required after 
615        overlay  analysis has been done */   
616     SPEC_OCLS(sym->etype) = ( options.model  ? port->mem.default_local_map : 
617                               (options.noOverlay ? port->mem.default_local_map
618                                : overlay )) ;
619     allocIntoSeg (sym); 
620 }
621
622 /*-----------------------------------------------------------------*/
623 /* deallocLocal - deallocates the local variables                  */
624 /*-----------------------------------------------------------------*/
625 void  deallocLocal ( symbol *csym )
626 {
627     symbol *sym ;
628     
629     for ( sym = csym ; sym ; sym = sym->next) {
630         if (sym->_isparm)
631             continue ;
632
633         /* if it is on the stack */
634         if (sym->onStack) { 
635             if (options.useXstack)
636                 xstackPtr -= getSize(sym->type);
637             else
638                 stackPtr  -= getSize(sym->type);
639         }
640         /* if not used give a warning */
641         if (!sym->isref && !IS_STATIC(sym->etype))
642             werror(W_NO_REFERENCE,currFunc->name,
643                    "local variable",sym->name);
644         /* now delete it from the symbol table */
645         deleteSym (SymbolTab,sym,sym->name);    
646     }
647 }
648
649 /*-----------------------------------------------------------------*/
650 /* overlay2data - moves declarations from the overlay seg to data  */
651 /*-----------------------------------------------------------------*/
652 void overlay2data()
653 {
654     symbol *sym;
655
656     for (sym = setFirstItem(overlay->syms); sym;
657          sym = setNextItem(overlay->syms)) {
658
659         SPEC_OCLS(sym->etype) = data;
660         allocIntoSeg(sym);
661     }
662
663     setToNull((void **) &overlay->syms);
664         
665 }
666
667 /*-----------------------------------------------------------------*/
668 /* overlay2Set - will add all symbols from the overlay segment to  */
669 /*               the set of sets containing the overlable symbols  */
670 /*-----------------------------------------------------------------*/
671 void overlay2Set ()
672 {
673     symbol *sym;
674     set *oset = NULL;
675
676     for (sym = setFirstItem(overlay->syms); sym;
677          sym = setNextItem(overlay->syms)) {
678
679         addSet(&oset,sym);
680     }
681     
682     setToNull((void **) &overlay->syms);
683     addSet (&ovrSetSets,oset);
684
685 }
686
687 /*-----------------------------------------------------------------*/
688 /* allocVariables - creates decl & assign storage class for a v    */
689 /*-----------------------------------------------------------------*/
690 int allocVariables ( symbol *symChain )
691 {
692     symbol   *sym;
693     symbol   *csym;
694     int      stack = 0;    
695     int      saveLevel = 0 ;
696     
697     /* go thru the symbol chain   */
698     for ( sym = symChain ; sym ;  sym = sym->next   ) {
699         
700         /* if this is a typedef then add it */
701         /* to the typedef table             */
702         if (IS_TYPEDEF(sym->etype)) {
703             /* check if the typedef already exists    */
704             csym = findSym (TypedefTab, NULL, sym->name );
705             if ( csym && csym->level == sym->level )
706                 werror(E_DUPLICATE_TYPEDEF,sym->name);
707             
708             addSym (TypedefTab, sym , sym->name,sym->level,sym->block);
709             continue ;  /* go to the next one         */
710         }
711         /* make sure it already exist */
712         csym = findSymWithLevel (SymbolTab, sym);
713         if (! csym || (csym && csym->level != sym->level) )
714             csym = sym;
715                 
716         /* check the declaration */
717         checkDecl   (csym);
718                 
719         /* if this is a function or a pointer to function */
720         /* then args  processing  */
721         if (funcInChain(csym->type)) {
722
723             processFuncArgs (csym, 1);
724             /* if register bank specified then update maxRegBank */
725             if (maxRegBank < SPEC_BANK(csym->etype))
726                 maxRegBank = SPEC_BANK(csym->etype);
727         }
728         
729         /* if this is a extern variable then change the */
730         /* level to zero temporarily                                    */
731         if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type) ) {
732             saveLevel = csym->level ;
733             csym->level = 0 ;
734         }
735         
736         /* if this is a literal then it is an enumerated */
737         /* type so need not allocate it space for it     */
738         if (IS_LITERAL(sym->etype))
739             continue ;
740         
741         /* generate the actual declaration  */
742         if ( csym->level  ) {
743             allocLocal  (csym);
744             if (csym->onStack)
745                 stack += getSize(csym->type) ;              
746         }
747         else 
748             allocGlobal (csym);
749
750         /* restore the level */
751         if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type)) 
752             csym->level = saveLevel;            
753     }
754     
755     return stack ;
756 }
757
758 /*-----------------------------------------------------------------*/
759 /* redoStackOffsets :- will reassign the values for stack offsets  */
760 /*-----------------------------------------------------------------*/
761 void redoStackOffsets ()
762 {
763     symbol *sym;
764     int sPtr = 0;
765     int xsPtr=-1;
766
767     /* after register allocation is complete we know
768        which variables will need to be assigned space
769        on the stack. We will eliminate those variables
770        which do not have the allocReq flag thus reducing
771        the stack space */
772     for ( sym = setFirstItem(istack->syms); sym;
773           sym = setNextItem(istack->syms)) {
774         
775         int size = getSize(sym->type);
776         /* nothing to do with parameters so continue */
777         if ((sym->_isparm && !IS_REGPARM(sym->etype)))
778             continue ;
779         
780         if ( IS_AGGREGATE(sym->type)) {
781             if (port->stack.direction > 0) {
782                 SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1);
783                 sPtr += size;
784             }
785             else {
786                 sPtr -= size;
787                 SPEC_STAK(sym->etype) = sym->stack = sPtr;
788             }
789             continue;
790         }
791
792         /* if allocation not required then subtract
793            size from overall stack size & continue */   
794         if (!sym->allocreq) {
795             currFunc->stack -= size;
796             SPEC_STAK(currFunc->etype) -= size;
797             continue ;
798         }
799
800         if (port->stack.direction > 0) {
801             SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1);
802             sPtr += size ;
803         }
804         else {
805             sPtr -= size ;
806             SPEC_STAK(sym->etype) = sym->stack = sPtr;
807         }
808     }
809
810     /* do the same for the external stack */
811     
812     for ( sym = setFirstItem(xstack->syms); sym;
813           sym = setNextItem(xstack->syms)) {
814         
815         int size  = getSize(sym->type);
816         /* nothing to do with parameters so continue */
817         if ((sym->_isparm && !IS_REGPARM(sym->etype)))
818             continue ;
819         
820         if (IS_AGGREGATE(sym->type)) {
821             SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1);
822             xsPtr += size ;
823             continue ;
824         }      
825
826         /* if allocation not required then subtract
827            size from overall stack size & continue */   
828         if (!sym->allocreq) {
829             currFunc->xstack -= size;
830             SPEC_STAK(currFunc->etype) -= size;
831             continue ;
832         }
833
834         SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1);
835         xsPtr += size ;
836     }
837
838     /* if the debug option is set then output the
839        symbols to the map file */
840     if (options.debug) {
841         for (sym = setFirstItem(istack->syms); sym;
842              sym = setNextItem(istack->syms))
843             cdbSymbol(sym,cdbFile,FALSE,FALSE);
844
845         for (sym = setFirstItem(xstack->syms); sym;
846              sym = setNextItem(xstack->syms))
847             cdbSymbol(sym,cdbFile,FALSE,FALSE); 
848     }
849 }