Merge out from the z80 far branch
[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 = 
433                         stackPtr +
434                         (IS_BANKED(currFunc->etype) ? port->stack.banked_overhead : 0) +
435                         (IS_ISR(currFunc->etype) ? port->stack.isr_overhead : 0) +
436                         0;
437                     stackPtr += getSize (lval->type);
438                 }                   
439             }
440             allocIntoSeg(lval->sym);
441         }
442         else   {        /* allocate them in the automatic space */
443             /* generate a unique name  */
444             sprintf (lval->sym->rname,"%s%s_PARM_%d", port->fun_prefix, currFunc->name,pNum);
445             strcpy  (lval->name,lval->sym->rname);
446             
447             /* if declared in external storage */
448             if (SPEC_SCLS(lval->etype) == S_XDATA) 
449                  SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xdata;
450             else
451                 /* other wise depending on the memory model 
452                    note here that we put it into the overlay segment
453                    first, we will remove it from the overlay segment
454                    after the overlay determination has been done */
455                 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = 
456                     ( options.model  ? port->mem.default_local_map : 
457                       (options.noOverlay ? port->mem.default_local_map
458                        :overlay ));
459             
460             allocIntoSeg(lval->sym);
461         }
462     }
463     
464     return ;
465 }
466
467 /*-----------------------------------------------------------------*/
468 /* deallocParms - parameters are always passed on stack                */
469 /*-----------------------------------------------------------------*/
470 void  deallocParms ( value *val )
471 {
472     value    *lval ;
473     
474     for ( lval = val ; lval ; lval = lval->next ) {
475
476         /* unmark is myparm */
477         lval->sym->ismyparm = 0;
478         /* if on stack then depending on which stack */
479         
480         /* delete it from the symbol table  */
481         deleteSym (SymbolTab,lval->sym,lval->sym->name); 
482
483         if (!lval->sym->isref) {
484             lval->sym->allocreq = 1;
485             werror(W_NO_REFERENCE,currFunc->name,
486                    "function argument",lval->sym->name);
487         }
488
489         /* move the rname if any to the name for both val & sym */
490         /* and leave a copy of it in the symbol table           */
491         if (lval->sym->rname[0]) {
492             char buffer[SDCC_NAME_MAX];
493             strcpy(buffer,lval->sym->rname);
494             lval->sym = copySymbol(lval->sym);
495             strcpy(lval->sym->rname,buffer);
496             strcpy(lval->name,strcpy(lval->sym->name,lval->sym->rname));
497             addSym (SymbolTab, lval->sym, lval->sym->name, 
498                     lval->sym->level,lval->sym->block);     
499             lval->sym->_isparm = 1;
500             addSet(&operKeyReset,lval->sym);
501         }
502
503     }
504     
505     return ;
506 }
507
508 /*-----------------------------------------------------------------*/
509 /* allocLocal - allocate local variables                           */
510 /*-----------------------------------------------------------------*/
511 void allocLocal ( symbol *sym  )
512 {   
513     
514     /* generate an unique name */
515     sprintf(sym->rname,"%s%s_%s_%d_%d",
516             port->fun_prefix,
517             currFunc->name,sym->name,sym->level,sym->block);
518     
519     sym->islocal = 1;
520     sym->localof = currFunc;
521
522     /* if this is a static variable */
523     if ( IS_STATIC (sym->etype)) {
524 /*      SPEC_OCLS(sym->etype) = (options.model ? xdata : data ); */
525         SPEC_OCLS(sym->etype) = port->mem.default_local_map;
526         allocIntoSeg (sym);
527         sym->allocreq = 1;
528         return   ;
529     }
530     
531     /* if volatile then */
532     if (IS_VOLATILE(sym->etype))
533         sym->allocreq = 1;
534
535     /* this is automatic           */
536
537     /* if it to be placed on the stack */
538     if ( options.stackAuto || reentrant) {
539                
540         sym->onStack = 1;
541         if ( options.useXstack ) { 
542             /* PENDING: stack direction for xstack */
543             SPEC_OCLS(sym->etype) = xstack ;
544             SPEC_STAK(sym->etype) = sym->stack = (xstackPtr + 1);
545             xstackPtr += getSize (sym->type) ;
546         }
547         else {
548             SPEC_OCLS(sym->etype) = istack ;
549             if (port->stack.direction > 0) {
550                 SPEC_STAK(sym->etype) = sym->stack = ( stackPtr + 1);
551                 stackPtr += getSize (sym->type) ;
552             }
553             else {
554                 stackPtr -= getSize (sym->type);
555                 SPEC_STAK(sym->etype) = sym->stack = stackPtr;
556             }
557         }
558         allocIntoSeg(sym);
559         return ;
560     }
561     
562     /* else depending on the storage class specified */
563     if ( SPEC_SCLS(sym->etype) == S_XDATA  )    {
564         SPEC_OCLS(sym->etype) = xdata  ;
565         allocIntoSeg(sym)  ;
566         return ;
567     }
568
569     if ( (SPEC_SCLS(sym->etype) == S_CODE   ||
570           SPEC_SCLS(sym->etype) == S_CONSTANT) &&
571          !sym->_isparm)  {
572         SPEC_OCLS(sym->etype) = statsg   ;
573         allocIntoSeg (sym)  ;
574         return ;
575     }
576
577     if ( SPEC_SCLS(sym->etype) == S_IDATA  )    {
578         SPEC_OCLS(sym->etype) = idata ;
579         sym->iaccess = 1;
580         allocIntoSeg (sym)  ;
581         return ;
582     }    
583
584         /* if this is a function then assign code space    */
585     if (IS_FUNC(sym->type)) {
586         SPEC_OCLS(sym->etype)  = code ;
587         return ;
588     }
589         
590     /* if this is a  SFR or SBIT */
591     if (  SPEC_SCLS(sym->etype) == S_SFR   ||
592           SPEC_SCLS(sym->etype) == S_SBIT  )  {
593         
594         /* if both absolute address & initial  */
595         /* value specified then error        */
596         if ( IS_ABSOLUTE (sym->etype) && sym->ival ) {
597             werror(E_SFR_INIT,sym->name);
598             sym->ival = NULL ;
599         }
600         
601         SPEC_OCLS(sym->etype) = 
602             (SPEC_SCLS(sym->etype) == S_SFR ? sfr : sfrbit);
603         
604         allocIntoSeg (sym);
605         return ;
606     }
607     
608     /* if this is a bit variable and no storage class */
609     if ( SPEC_NOUN(sym->etype) == V_BIT  
610          && (SPEC_SCLS(sym->etype) == S_BIT)) {       
611         SPEC_OCLS(sym->etype) = bit ;
612         allocIntoSeg (sym);
613         return  ;
614     }
615
616     if ( SPEC_SCLS(sym->etype) == S_DATA  ) {
617         SPEC_OCLS(sym->etype) = (options.noOverlay ? data : overlay );
618         allocIntoSeg(sym)  ;
619         return ;
620     }
621
622     if ( SPEC_SCLS(sym->etype) == S_EEPROM  ) {
623         SPEC_OCLS(sym->etype) = eeprom;
624         allocIntoSeg(sym)  ;
625         return ;
626     }
627     
628     /* again note that we have put it into the overlay segment
629        will remove and put into the 'data' segment if required after 
630        overlay  analysis has been done */   
631     SPEC_OCLS(sym->etype) = ( options.model  ? port->mem.default_local_map : 
632                               (options.noOverlay ? port->mem.default_local_map
633                                : overlay )) ;
634     allocIntoSeg (sym); 
635 }
636
637 /*-----------------------------------------------------------------*/
638 /* deallocLocal - deallocates the local variables                  */
639 /*-----------------------------------------------------------------*/
640 void  deallocLocal ( symbol *csym )
641 {
642     symbol *sym ;
643     
644     for ( sym = csym ; sym ; sym = sym->next) {
645         if (sym->_isparm)
646             continue ;
647
648         /* if it is on the stack */
649         if (sym->onStack) { 
650             if (options.useXstack)
651                 xstackPtr -= getSize(sym->type);
652             else
653                 stackPtr  -= getSize(sym->type);
654         }
655         /* if not used give a warning */
656         if (!sym->isref && !IS_STATIC(sym->etype))
657             werror(W_NO_REFERENCE,currFunc->name,
658                    "local variable",sym->name);
659         /* now delete it from the symbol table */
660         deleteSym (SymbolTab,sym,sym->name);    
661     }
662 }
663
664 /*-----------------------------------------------------------------*/
665 /* overlay2data - moves declarations from the overlay seg to data  */
666 /*-----------------------------------------------------------------*/
667 void overlay2data()
668 {
669     symbol *sym;
670
671     for (sym = setFirstItem(overlay->syms); sym;
672          sym = setNextItem(overlay->syms)) {
673
674         SPEC_OCLS(sym->etype) = data;
675         allocIntoSeg(sym);
676     }
677
678     setToNull((void **) &overlay->syms);
679         
680 }
681
682 /*-----------------------------------------------------------------*/
683 /* overlay2Set - will add all symbols from the overlay segment to  */
684 /*               the set of sets containing the overlable symbols  */
685 /*-----------------------------------------------------------------*/
686 void overlay2Set ()
687 {
688     symbol *sym;
689     set *oset = NULL;
690
691     for (sym = setFirstItem(overlay->syms); sym;
692          sym = setNextItem(overlay->syms)) {
693
694         addSet(&oset,sym);
695     }
696     
697     setToNull((void **) &overlay->syms);
698     addSet (&ovrSetSets,oset);
699
700 }
701
702 /*-----------------------------------------------------------------*/
703 /* allocVariables - creates decl & assign storage class for a v    */
704 /*-----------------------------------------------------------------*/
705 int allocVariables ( symbol *symChain )
706 {
707     symbol   *sym;
708     symbol   *csym;
709     int      stack = 0;    
710     int      saveLevel = 0 ;
711     
712     /* go thru the symbol chain   */
713     for ( sym = symChain ; sym ;  sym = sym->next   ) {
714         
715         /* if this is a typedef then add it */
716         /* to the typedef table             */
717         if (IS_TYPEDEF(sym->etype)) {
718             /* check if the typedef already exists    */
719             csym = findSym (TypedefTab, NULL, sym->name );
720             if ( csym && csym->level == sym->level )
721                 werror(E_DUPLICATE_TYPEDEF,sym->name);
722             
723             addSym (TypedefTab, sym , sym->name,sym->level,sym->block);
724             continue ;  /* go to the next one         */
725         }
726         /* make sure it already exist */
727         csym = findSymWithLevel (SymbolTab, sym);
728         if (! csym || (csym && csym->level != sym->level) )
729             csym = sym;
730                 
731         /* check the declaration */
732         checkDecl   (csym);
733                 
734         /* if this is a function or a pointer to function */
735         /* then args  processing  */
736         if (funcInChain(csym->type)) {
737
738             processFuncArgs (csym, 1);
739             /* if register bank specified then update maxRegBank */
740             if (maxRegBank < SPEC_BANK(csym->etype))
741                 maxRegBank = SPEC_BANK(csym->etype);
742         }
743         
744         /* if this is a extern variable then change the */
745         /* level to zero temporarily                                    */
746         if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type) ) {
747             saveLevel = csym->level ;
748             csym->level = 0 ;
749         }
750         
751         /* if this is a literal then it is an enumerated */
752         /* type so need not allocate it space for it     */
753         if (IS_LITERAL(sym->etype))
754             continue ;
755         
756         /* generate the actual declaration  */
757         if ( csym->level  ) {
758             allocLocal  (csym);
759             if (csym->onStack)
760                 stack += getSize(csym->type) ;              
761         }
762         else 
763             allocGlobal (csym);
764
765         /* restore the level */
766         if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type)) 
767             csym->level = saveLevel;            
768     }
769     
770     return stack ;
771 }
772
773 /*-----------------------------------------------------------------*/
774 /* redoStackOffsets :- will reassign the values for stack offsets  */
775 /*-----------------------------------------------------------------*/
776 void redoStackOffsets ()
777 {
778     symbol *sym;
779     int sPtr = 0;
780     int xsPtr=-1;
781
782     /* after register allocation is complete we know
783        which variables will need to be assigned space
784        on the stack. We will eliminate those variables
785        which do not have the allocReq flag thus reducing
786        the stack space */
787     for ( sym = setFirstItem(istack->syms); sym;
788           sym = setNextItem(istack->syms)) {
789         
790         int size = getSize(sym->type);
791         /* nothing to do with parameters so continue */
792         if ((sym->_isparm && !IS_REGPARM(sym->etype)))
793             continue ;
794         
795         if ( IS_AGGREGATE(sym->type)) {
796             if (port->stack.direction > 0) {
797                 SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1);
798                 sPtr += size;
799             }
800             else {
801                 sPtr -= size;
802                 SPEC_STAK(sym->etype) = sym->stack = sPtr;
803             }
804             continue;
805         }
806
807         /* if allocation not required then subtract
808            size from overall stack size & continue */   
809         if (!sym->allocreq) {
810             currFunc->stack -= size;
811             SPEC_STAK(currFunc->etype) -= size;
812             continue ;
813         }
814
815         if (port->stack.direction > 0) {
816             SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1);
817             sPtr += size ;
818         }
819         else {
820             sPtr -= size ;
821             SPEC_STAK(sym->etype) = sym->stack = sPtr;
822         }
823     }
824
825     /* do the same for the external stack */
826     
827     for ( sym = setFirstItem(xstack->syms); sym;
828           sym = setNextItem(xstack->syms)) {
829         
830         int size  = getSize(sym->type);
831         /* nothing to do with parameters so continue */
832         if ((sym->_isparm && !IS_REGPARM(sym->etype)))
833             continue ;
834         
835         if (IS_AGGREGATE(sym->type)) {
836             SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1);
837             xsPtr += size ;
838             continue ;
839         }      
840
841         /* if allocation not required then subtract
842            size from overall stack size & continue */   
843         if (!sym->allocreq) {
844             currFunc->xstack -= size;
845             SPEC_STAK(currFunc->etype) -= size;
846             continue ;
847         }
848
849         SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1);
850         xsPtr += size ;
851     }
852
853     /* if the debug option is set then output the
854        symbols to the map file */
855     if (options.debug) {
856         for (sym = setFirstItem(istack->syms); sym;
857              sym = setNextItem(istack->syms))
858             cdbSymbol(sym,cdbFile,FALSE,FALSE);
859
860         for (sym = setFirstItem(xstack->syms); sym;
861              sym = setNextItem(xstack->syms))
862             cdbSymbol(sym,cdbFile,FALSE,FALSE); 
863     }
864 }
865
866 /*-----------------------------------------------------------------*/
867 /* printAllocInfoSeg- print the allocation for a given section     */
868 /*-----------------------------------------------------------------*/
869 static void printAllocInfoSeg ( memmap *map, symbol *func, FILE *of)
870 {
871     symbol *sym;
872     
873     if (!map) return;
874     if (!map->syms) return;
875
876     for (sym = setFirstItem(map->syms); sym;
877          sym = setNextItem(map->syms)) {
878         
879         if (sym->level == 0) continue;
880         if (sym->localof != func) continue ;
881         fprintf(of,";%-25s Allocated to ",sym->name);
882
883         /* if assigned to registers */
884         if (!sym->allocreq && sym->reqv) {
885             int i;
886             sym = OP_SYMBOL(sym->reqv);
887             fprintf(of,"registers ");
888             for (i = 0 ; i < 4 && sym->regs[i] ; i++)
889                 fprintf(of,"%s ",port->getRegName(sym->regs[i]));
890             fprintf(of,"\n");
891             continue ;
892         }
893
894         /* if on stack */
895         if (sym->onStack) {
896             fprintf(of,"stack - offset %d\n",sym->stack);
897             continue;
898         }
899         
900         /* otherwise give rname */
901         fprintf(of,"in memory with name '%s'\n",sym->rname);
902     }
903 }
904
905 /*-----------------------------------------------------------------*/
906 /* printAllocInfo - prints allocation information for a function   */
907 /*-----------------------------------------------------------------*/
908 void printAllocInfo( symbol * func, FILE *of)
909 {
910     if (!of) of = stdout;
911
912     /* must be called after register allocation is complete */
913     fprintf(of,";------------------------------------------------------------\n");
914     fprintf(of,";Allocation info for local variables in function '%s'\n",func->name);
915     fprintf(of,";------------------------------------------------------------\n");
916     
917     printAllocInfoSeg(xstack,func,of);
918     printAllocInfoSeg(istack,func,of);
919     printAllocInfoSeg(code,func,of);
920     printAllocInfoSeg(data,func,of);
921     printAllocInfoSeg(xdata,func,of);
922     printAllocInfoSeg(idata,func,of);
923     printAllocInfoSeg(sfr,func,of);
924     printAllocInfoSeg(sfrbit,func,of);
925 }