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