* src/pic/ralloc.c (newReg): create aliases for registers with
[fw/sdcc] / as / hc08 / lkarea.c
1 /* lkarea.c */
2
3 /*
4  * (C) Copyright 1989-1995
5  * All Rights Reserved
6  *
7  * Alan R. Baldwin
8  * 721 Berkeley St.
9  * Kent, Ohio  44240
10  *
11  *  3-Nov-97 JLH:
12  *           - change lkparea to use a_type == 0 as "virgin area" flag
13  * 02-Apr-98 JLH: add code to link 8051 data spaces
14  */
15
16 #include <stdio.h>
17 #include <string.h>
18 #include "aslink.h"
19
20 /*)Module       lkarea.c
21  *
22  *      The module lkarea.c contains the functions which
23  *      create and link together all area definitions read
24  *      from the .rel file(s).
25  *
26  *      lkarea.c contains the following functions:
27  *              VOID    lnkarea()
28  *              VOID    lnksect()
29  *              VOID    lkparea()
30  *              VOID    newarea()
31  *
32  *      lkarea.c contains no global variables.
33  */
34
35 /*)Function     VOID    newarea()
36  *
37  *      The function newarea() creates and/or modifies area
38  *      and areax structures for each A directive read from
39  *      the .rel file(s).  The function lkparea() is called
40  *      to find tha area structure associated with this name.
41  *      If the area does not yet exist then a new area
42  *      structure is created and linked to any existing
43  *      linked area structures. The area flags are copied
44  *      into the area flag variable.  For each occurence of
45  *      an A directive an areax structure is created and
46  *      linked to the areax structures associated with this
47  *      area.  The size of this area section is placed into
48  *      the areax structure.  The flag value for all subsequent
49  *      area definitions for the same area are compared and
50  *      flagged as an error if they are not identical.
51  *      The areax structure created for every occurence of
52  *      an A directive is loaded with a pointer to the base
53  *      area structure and a pointer to the associated
54  *      head structure.  And finally, a pointer to this
55  *      areax structure is loaded into the list of areax
56  *      structures in the head structure.  Refer to lkdata.c
57  *      for details of the structures and their linkage.
58  *
59  *      local variables:
60  *              areax **halp            pointer to an array of pointers
61  *              int     i               counter, loop variable, value
62  *              char    id[]            id string
63  *              int     narea           number of areas in this head structure
64  *              areax * taxp            pointer to an areax structure
65  *                                      to areax structures
66  *
67  *      global variables:
68  *              area    *ap             Pointer to the current
69  *                                      area structure
70  *              areax   *axp            Pointer to the current
71  *                                      areax structure
72  *              head    *hp             Pointer to the current
73  *                                      head structure
74  *              int     lkerr           error flag
75  *
76  *      functions called:
77  *              Addr_T  eval()          lkeval.c
78  *              VOID    exit()          c_library
79  *              int     fprintf()       c_library
80  *              VOID    getid()         lklex.c
81  *              VOID    lkparea()       lkarea.c
82  *              VOID    skip()          lklex.c
83  *
84  *      side effects:
85  *              The area and areax structures are created and
86  *              linked with the appropriate head structures.
87  *              Failure to allocate area or areax structure
88  *              space will terminate the linker.  Other internal
89  *              errors most likely caused by corrupted .rel
90  *              files will also terminate the linker.
91  */
92
93 /*
94  * Create an area entry.
95  *
96  * A xxxxxx size nnnn flags mm
97  *   |           |          |
98  *   |           |          `--  ap->a_flag
99  *   |           `------------- axp->a_size
100  *   `-------------------------  ap->a_id
101  *
102  */
103 VOID
104 newarea()
105 {
106     register int i, narea;
107     struct areax *taxp;
108     struct areax **halp;
109     char id[NCPS];
110
111     /*
112      * Create Area entry
113      */
114     getid(id, -1);
115     lkparea(id);
116     /*
117      * Evaluate area size
118      */
119     skip(-1);
120     axp->a_size = eval();
121     /*
122      * Evaluate flags
123      */
124     skip(-1);
125     i = 0;
126     taxp = ap->a_axp;
127     while (taxp->a_axp) {
128         ++i;
129         taxp = taxp->a_axp;
130     }
131     if (i == 0) {
132         ap->a_flag = eval();
133     } else {
134         i = eval();
135 /*      if (i && (ap->a_flag != i)) { */
136 /*          fprintf(stderr, "Conflicting flags in area %8s\n", id); */
137 /*          lkerr++; */
138 /*      } */
139     }
140     /*
141      * Evaluate area address
142      */
143     skip(-1);
144     axp->a_addr = eval();
145     /*
146      * Place pointer in header area list
147      */
148     if (headp == NULL) {
149         fprintf(stderr, "No header defined\n");
150         lkexit(1);
151     }
152     narea = hp->h_narea;
153     halp = hp->a_list;
154     for (i=0; i < narea ;++i) {
155         if (halp[i] == NULL) {
156             halp[i] = taxp;
157             return;
158         }
159     }
160     fprintf(stderr, "Header area list overflow\n");
161     lkexit(1);
162 }
163
164 /*)Function     VOID    lkparea(id)
165  *
166  *              char *  id              pointer to the area name string
167  *
168  *      The function lkparea() searches the linked area structures
169  *      for a name match.  If the name is not found then an area
170  *      structure is created.  An areax structure is created and
171  *      appended to the areax structures linked to the area structure.
172  *      The associated base area and head structure pointers are
173  *      loaded into the areax structure.
174  *
175  *      local variables:
176  *              area *  tap             pointer to an area structure
177  *              areax * taxp            pointer to an areax structure
178  *
179  *      global variables:
180  *              area    *ap             Pointer to the current
181  *                                      area structure
182  *              area    *areap          The pointer to the first
183  *                                      area structure of a linked list
184  *              areax   *axp            Pointer to the current
185  *                                      areax structure
186  *
187  *      functions called:
188  *              VOID *  new()           lksym()
189  *              char *  strcpy()        c_library
190  *              int     symeq()         lksym.c
191  *
192  *      side effects:
193  *              Area and/or areax structures are created.
194  *              Failure to allocate space for created structures
195  *              will terminate the linker.
196  */
197
198 VOID
199 lkparea(char *id)
200 {
201     register struct area *tap;
202     register struct areax *taxp;
203
204     ap = areap;
205     axp = (struct areax *) new (sizeof(struct areax));
206     while (ap) {
207         if (symeq(id, ap->a_id)) {
208             taxp = ap->a_axp;
209             while (taxp->a_axp)
210                 taxp = taxp->a_axp;
211             taxp->a_axp = axp;
212             axp->a_bap = ap;
213             axp->a_bhp = hp;
214             return;
215         }
216         ap = ap->a_ap;
217     }
218     ap = (struct area *) new (sizeof(struct area));
219     if (areap == NULL) {
220         areap = ap;
221     } else {
222         tap = areap;
223         while (tap->a_ap)
224             tap = tap->a_ap;
225         tap->a_ap = ap;
226     }
227     ap->a_axp = axp;
228     axp->a_bap = ap;
229     axp->a_bhp = hp;
230     strncpy(ap->a_id, id, NCPS);
231     ap->a_addr = 0;
232 }
233
234 /*)Function     VOID    lnkarea()
235  *
236  *      The function lnkarea() resolves all area addresses.
237  *      The function evaluates each area structure (and all
238  *      the associated areax structures) in sequence.  The
239  *      linking process supports four (4) possible area types:
240  *
241  *      ABS/OVR -       All sections (each individual areax
242  *                      section) starts at the identical base
243  *                      area address overlaying all other
244  *                      areax sections for this area.  The
245  *                      size of the area is largest of the area
246  *                      sections.
247  *
248  *      ABS/CON -       All sections (each individual areax
249  *                      section) are concatenated with the
250  *                      first section starting at the base
251  *                      area address.  The size of the area
252  *                      is the sum of the section sizes.
253  *
254  *      NOTE:   Multiple absolute (ABS) areas are
255  *                      never concatenated with each other,
256  *                      thus absolute area A and absolute area
257  *                      B will overlay each other if they begin
258  *                      at the same location (the default is
259  *                      always address 0 for absolute areas).
260  *
261  *      REL/OVR -       All sections (each individual areax
262  *                      section) starts at the identical base
263  *                      area address overlaying all other
264  *                      areax sections for this area.  The
265  *                      size of the area is largest of the area
266  *                      sections.
267  *
268  *      REL/CON -       All sections (each individual areax
269  *                      section) are concatenated with the
270  *                      first section starting at the base
271  *                      area address.  The size of the area
272  *                      is the sum of the section sizes.
273  *
274  *      NOTE:   Relocatable (REL) areas ae always concatenated
275  *                      with each other, thus relocatable area B
276  *                      (defined after area A) will follow
277  *                      relocatable area A independent of the
278  *                      starting address of area A.  Within a
279  *                      specific area each areax section may be
280  *                      overlayed or concatenated with other
281  *                      areax sections.
282  *
283  *
284  *      If a base address for an area is specified then the
285  *      area will start at that address.  Any relocatable
286  *      areas defined subsequently will be concatenated to the
287  *      previous relocatable area if it does not have a base
288  *      address specified.
289  *
290  *      The names s_<areaname> and l_<areaname> are created to
291  *      define the starting address and length of each area.
292  *
293  *      local variables:
294  *              Addr_T  rloc            ;current relocation address
295  *              char    temp[]          ;temporary string
296  *              struct symbol   *sp     ;symbol structure
297  *
298  *      global variables:
299  *              area    *ap                     Pointer to the current
300  *                                                      area structure
301  *              area    *areap          The pointer to the first
302  *                                                      area structure of a linked list
303  *
304  *      functions called:
305  *              int             fprintf()       c_library
306  *              VOID    lnksect()       lkarea.c
307  *              symbol *lkpsym()        lksysm.c
308  *              char *  strncpy()       c_library
309  *              int             symeq()         lksysm.c
310  *
311  *      side effects:
312  *              All area and areax addresses and sizes are
313  *              determined and saved in their respective
314  *              structures.
315  */
316
317 unsigned long codemap[2048];
318 /*
319  * Resolve all area addresses.
320  */
321 VOID
322 lnkarea()
323 {
324     Addr_T rloc[4] = {0, 0, 0, 0};
325     Addr_T gs_size = 0;
326     int  locIndex;
327     char temp[NCPS];
328     struct sym *sp;
329     /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/
330     struct area *ta[5];
331     int j;
332     struct area *abs_ap = NULL;
333     struct area *gs0_ap = NULL;
334
335     memset(codemap, 0, sizeof(codemap));
336
337     /* first sort all absolute areas to the front */
338     ap = areap;
339     /* no need to check first area, it's in front anyway */
340     while (ap && ap->a_ap)
341     {
342         if (ap->a_ap->a_flag & A_ABS)
343         {/* next area is absolute, move it to front,
344             reversed sequence is no problem for absolutes */
345             abs_ap = ap->a_ap;
346             ap->a_ap = abs_ap->a_ap;
347             abs_ap->a_ap = areap;
348             areap = abs_ap;
349         }
350         ap = ap->a_ap;
351     }
352
353     /* next accumulate all GSINITx/GSFINAL area sizes
354        into GSINIT so they stay together */
355     ap = areap;
356     while (ap)
357     {
358         if (!strncmp(ap->a_id, "GS", 2))
359         {/* GSxxxxx area */
360             if (ap->a_size == 0)
361             {
362                 axp = ap->a_axp;
363                 while (axp)
364                 {
365                     ap->a_size += axp->a_size;
366                     axp = axp->a_axp;
367                 }
368             }
369             gs_size += ap->a_size;
370             if (!strcmp(ap->a_id, "GSINIT0"))
371             {/* GSINIT0 area */
372                 gs0_ap = ap;
373             }
374         }
375         ap = ap->a_ap;
376     }
377     if (gs0_ap)
378         gs0_ap->a_size = gs_size;
379
380     ap = areap;
381     while (ap) {
382         if (ap->a_flag & A_ABS) {
383             /*
384              * Absolute sections
385              */
386             lnksect(ap);
387         } else {
388             /* Determine memory space */
389             locIndex = 0;
390             #if 0
391             if (ap->a_flag & A_CODE) {
392                 locIndex = 1;
393             }
394             if (ap->a_flag & A_XDATA) {
395                 locIndex = 2;
396             }
397             if (ap->a_flag & A_BIT) {
398                 locIndex = 3;
399             }
400             #endif
401             /*
402              * Relocatable sections
403              */
404             if (ap->a_type == 0) {  /* JLH */
405                 if (ap->a_flag & A_NOLOAD) {
406                     locIndex = 2;
407                     ap->a_addr = 0;
408                 } else {
409                     ap->a_addr = rloc[ locIndex ];
410                 }
411                 ap->a_type = 1;
412             }
413             rloc[ locIndex ] = lnksect(ap);
414         }
415
416         /*
417          * Create symbols called:
418          *      s_<areaname>    the start address of the area
419          *      l_<areaname>    the length of the area
420          */
421
422         if (! symeq(ap->a_id, _abs_)) {
423             strncpy(temp+2,ap->a_id,NCPS-2);
424             *(temp+1) = '_';
425
426             *temp = 's';
427             sp = lkpsym(temp, 1);
428             sp->s_addr = ap->a_addr ;
429             /* sp->s_axp = ap->a_axp;  JLH: was NULL; */
430             sp->s_type |= S_DEF;
431
432             *temp = 'l';
433             sp = lkpsym(temp, 1);
434             sp->s_addr = ap->a_size;
435             sp->s_axp = NULL;
436             sp->s_type |= S_DEF;
437
438         }
439
440         /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
441         to compute the byte size of BSEG_BYTES: */
442         if (!strcmp(ap->a_id, "BSEG")) {
443             ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/
444         }
445         else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap;
446         else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap;
447         else if (!strcmp(ap->a_id, "REG_BANK_2")) ta[2]=ap;
448         else if (!strcmp(ap->a_id, "REG_BANK_3")) ta[3]=ap;
449         else if (!strcmp(ap->a_id, "BSEG_BYTES"))
450         {
451             ta[4]=ap;
452             for(j=4; j>1; j--)
453             {
454                 /*If upper register banks are not used roll back the relocation counter*/
455                 if ( (ta[j]->a_size==0) && (ta[j-1]->a_size==0) )
456                 {
457                     rloc[0]-=8;
458                 }
459                 else break;
460             }
461         }
462         ap = ap->a_ap;
463     }
464 }
465
466 static
467 Addr_T find_empty_space(Addr_T start, Addr_T size)
468 {
469     int i, j, k;
470     unsigned long mask, b;
471
472     while (1)
473     {
474         Addr_T a = start;
475         i = start >> 5;
476         j = (start + size) >> 5;
477         mask = -(1 << (start & 0x1F));
478
479         while (i < j)
480         {
481             if (codemap[i] & mask)
482             {
483                 k = 32;
484                 for (b=0x80000000; b!=0; b>>=1, k--)
485                 {
486                     if (codemap[i] & b)
487                       break;
488                 }
489                 start = a + k;
490                 break;
491             }
492             i++;
493             mask = 0xFFFFFFFF;
494             a += 32;
495         }
496         if (start > a)
497           continue;
498
499         mask &= (1 << ((start + size) & 0x1F)) - 1;
500         if (codemap[i] & mask)
501         {
502             k = 32;
503             for (b=0x80000000; b!=0; b>>=1, k--)
504             {
505                 if (codemap[i] & b)
506                   break;
507             }
508             start = (a & ~0x1F) + k;
509         }
510         if (start <= a)
511           break;
512     }
513     return start;
514 }
515
516 static
517 Addr_T allocate_space(Addr_T start, Addr_T size, char* id)
518 {
519     int i, j;
520     unsigned long mask;
521     Addr_T a = start;
522     i = start >> 5;
523     j = (start + size) >> 5;
524     mask = -(1 << (start & 0x1F));
525
526     while (i < j)
527     {
528         if (codemap[i] & mask)
529         {
530             fprintf(stderr, "memory overlap near 0x%X for %s\n", a, id);
531         }
532         codemap[i++] |= mask;
533         mask = 0xFFFFFFFF;
534         a += 32;
535     }
536     mask &= (1 << ((start + size) & 0x1F)) - 1;
537     if (codemap[i] & mask)
538     {
539         fprintf(stderr, "memory overlap near 0x%X for %s\n", a, id);
540     }
541     codemap[i] |= mask;
542     return start;
543 }
544
545 /*)Function     VOID    lnksect()
546  *
547  *              area *  tap             pointer to an area structure
548  *
549  *      The function lnksect() is the function called by
550  *      lnkarea() to resolve the areax addresses.  Refer
551  *      to the function lnkarea() for more detail. Pageing
552  *      boundary and length errors will be reported by this
553  *      function.
554  *
555  *      local variables:
556  *              Addr_T  size            size of area
557  *              Addr_T  addr            address of area
558  *              areax * taxp            pointer to an areax structure
559  *
560  *      global variables:
561  *              int     lkerr           error flag
562  *
563  *      functions called:
564  *              none
565  *
566  *      side effects:
567  *              All area and areax addresses and sizes area determined
568  *              and linked into the structures.
569  */
570
571 Addr_T lnksect(struct area *tap)
572 {
573     register Addr_T size, addr;
574     register struct areax *taxp;
575
576     size = 0;
577     addr = tap->a_addr;
578
579     /* MB: is this possible for hc08 ??? */
580     if ((tap->a_flag&A_PAG) && (addr & 0xFF)) {
581         fprintf(stderr,
582         "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
583         lkerr++;
584     }
585
586     taxp = tap->a_axp;
587     if (tap->a_flag&A_OVR) {
588         /*
589          * Overlayed sections
590          */
591         while (taxp) {
592             taxp->a_addr = addr;
593             if (taxp->a_size > size)
594                 size = taxp->a_size;
595             taxp = taxp->a_axp;
596         }
597     } else if (tap->a_flag & A_ABS) {
598         /*
599          * Absolute sections
600          */
601         while (taxp) {
602             allocate_space(taxp->a_addr, taxp->a_size, tap->a_id);
603             taxp->a_addr = 0; /* reset to zero so relative addresses become absolute */
604             size += taxp->a_size;
605             taxp = taxp->a_axp;
606         }
607     } else {
608         /*
609          * Concatenated sections
610          */
611         if (tap->a_size) {
612             addr = find_empty_space(addr, tap->a_size);
613         }
614         while (taxp) {
615             //find next unused address now
616             if (taxp->a_size)
617             {
618                 addr = find_empty_space(addr, taxp->a_size);
619                 allocate_space(addr, taxp->a_size, tap->a_id);
620             }
621             taxp->a_addr = addr;
622             addr += taxp->a_size;
623             size += taxp->a_size;
624             taxp = taxp->a_axp;
625         }
626     }
627     tap->a_size = size;
628
629     /* MB: is this possible for hc08 ??? */
630     if ((tap->a_flag&A_PAG) && (size > 256)) {
631         fprintf(stderr,
632         "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
633         lkerr++;
634     }
635
636     return addr;
637 }