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