13d175a8923c2b43913c2803bb626ac6fd4ad1c1
[fw/sdcc] / as / asxxsrc / assym.c
1 /* assym.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  * 10-Nov-07 borutr:
12  *           - use strsto instead StoreString and include it in assym.c
13  *             for compatibility with the original asxxxx
14  *           - applied changes from 28-Oct-97 JLH:
15  *             - lookup: Use StoreString for sym construction
16  *             - change symeq() to do length-independent string compare
17  *             - change hash() to do length-independent hash calculation
18  *           - applied changes from 29-Oct-97 JLH:
19  *             - make mnemonics case insensitive ALWAYS
20  *             - make hash() case-insensitive always
21  *             - replace symeq() call in mlookup with strcmpi
22  */
23
24 #include <stdio.h>
25 #include <setjmp.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include "asm.h"
29
30 /*)Module       assym.c
31  *
32  *      The module assym.c contains the functions that operate
33  *      on the mnemonic/directive and symbol structures.
34  *
35  *      assym.c contains the following functions:
36  *              VOID    allglob()
37  *              area *  alookup()
38  *              int     hash()
39  *              sym *   lookup()
40  *              mne *   mlookup()
41  *              VOID *  new()
42  *              int     symeq()
43  *              VOID    syminit()
44  *              VOID    symglob()
45  *
46  *      assym.c contains no local/static variables.
47  */
48
49 /*)Function     VOID    syminit()
50  *
51  *      The function syminit() is called early in the game
52  *      to set up the hashtables.  First all buckets in a
53  *      table are cleared.  Then a pass is made through
54  *      the respective symbol lists, linking them into
55  *      their hash buckets.  Finally the base area pointer
56  *      is set to 'dca'.
57  *
58  *      local variables:
59  *              int     h               computed hash value
60  *              mne *   mp              pointer to a mne structure
61  *              mne **  mpp             pointer to an array of
62  *                                      mne structure pointers
63  *              sym *   sp              pointer to a sym structure
64  *              sym **  spp             pointer to an array of
65  *                                      sym structure pointers
66  *
67  *      global variables:
68  *              area    area[]          single elememt area array
69  *              area    dca             defined as area[0]
70  *              mne * mnehash[]         array of pointers to NHASH
71  *                                      linked mnemonic/directive lists
72  *              sym * symhash[]         array of pointers to NHASH
73  *                                      linked symbol lists
74  *
75  *      functions called:
76  *              none
77  *
78  *      side effects:
79  *              (1)     The symbol hash tables are initialized,
80  *                      the only defined symbol is '.'.
81  *              (2)     The mnemonic/directive hash tables are
82  *                      initialized with the assembler directives
83  *                      and mnemonics found in the machine dependent
84  *                      file ___pst.c.
85  *              (3)     The area pointer is initialized to dca (area[0]).
86  */
87
88 VOID
89 syminit(void)
90 {
91         register struct mne  *mp;
92         struct mne **mpp;
93         register struct sym  *sp;
94         struct sym **spp;
95         register int h;
96
97         mpp = &mnehash[0];
98         while (mpp < &mnehash[NHASH])
99                 *mpp++ = NULL;
100         mp = &mne[0];
101         for (;;) {
102                 h = hash(mp->m_id);
103                 mp->m_mp = mnehash[h];
104                 mnehash[h] = mp;
105                 if (mp->m_flag&S_END)
106                         break;
107                 ++mp;
108         }
109
110         spp = &symhash[0];
111         while (spp < &symhash[NHASH])
112                 *spp++ = NULL;
113         sp = &sym[0];
114         for (;;) {
115                 h = hash(sp->s_id);
116                 sp->s_sp = symhash[h];
117                 symhash[h] = sp;
118                 if (sp->s_flag&S_END)
119                         break;
120                 ++sp;
121         }
122
123         areap = &dca;
124 }
125
126 /*)Function     area *  alookup(id)
127  *
128  *              char *  id              area name string
129  *
130  *      The function alookup() searches the area list for a
131  *      match with id.  If the area is defined then a pointer
132  *      to this area is returned else a NULL is returned.
133  *
134  *      local variables:
135  *              area *  ap              pointer to area structure
136  *
137  *      global variables:
138  *              area *  areap           pointer to an area structure
139  *
140  *      functions called:
141  *              int     symeq()         assym.c
142  *
143  *      side effects:
144  *              none
145  */
146
147 struct area *
148 alookup(char *id)
149 {
150         register struct area *ap;
151
152         ap = areap;
153         while (ap) {
154                 if (symeq(id, ap->a_id)) {
155                         return (ap);
156                 }
157                 ap = ap->a_ap;
158         }
159         return(NULL);
160 }
161
162 /*)Function     mne *   mlookup(id)
163  *
164  *              char *  id              mnemonic/directive name string
165  *
166  *      The function mlookup() searches the mnemonic/directive
167  *      hash tables for a match returning a pointer to the
168  *      mne structure else it returns a NULL.
169  *
170  *      local variables:
171  *              mne *   mp              pointer to mne structure
172  *              int     h               calculated hash value
173  *
174  *      global variables:
175  *              mne * mnehash[]         array of pointers to NHASH
176  *                                      linked mnemonic/directive lists
177  *
178  *      functions called:
179  *              none
180  *
181  *      side effects:
182  *              none
183  */
184
185 struct mne *
186 mlookup(char *id)
187 {
188         register struct mne *mp;
189         register int h;
190
191         h = hash(id);
192         mp = mnehash[h];
193         while (mp) {
194                 if (as_strcmpi(id, mp->m_id) == 0)      /* JLH: case insensitive */
195                         return (mp);
196                 mp = mp->m_mp;
197         }
198         return (NULL);
199 }
200
201 /*)Function     sym *   lookup(id)
202  *
203  *              char *  id              symbol name string
204  *
205  *      The function lookup() searches the symbol hash tables for
206  *      a symbol name match returning a pointer to the sym structure.
207  *      If the symbol is not found then a sym structure is created,
208  *      initialized, and linked to the appropriate hash table.
209  *      A pointer to this new sym structure is returned.
210  *
211  *      local variables:
212  *              int     h               computed hash value
213  *              sym *   sp              pointer to a sym structure
214  *
215  *      global varaibles:
216  *              sym * symhash[]         array of pointers to NHASH
217  *                                      linked symbol lists
218  *
219  *      functions called:
220  *              int     hash()          assym.c
221  *              VOID *  new()           assym.c
222  *              int     symeq()         assym.c
223  *
224  *      side effects:
225  *              If the function new() fails to allocate space
226  *              for the new sym structure the assembly terminates.
227  */
228
229 struct sym *
230 lookup(char *id)
231 {
232         register struct sym *sp;
233         register int h;
234
235         h = hash(id);
236         sp = symhash[h];
237         while (sp) {
238                 if (symeq(id, sp->s_id))
239                         return (sp);
240                 sp = sp->s_sp;
241         }
242         sp = (struct sym *) new (sizeof(struct sym));
243         sp->s_sp = symhash[h];
244         symhash[h] = sp;
245         sp->s_tsym = NULL;
246         sp->s_id = strsto(id);
247         sp->s_type = S_NEW;
248         sp->s_flag = 0;
249         sp->s_area = NULL;
250         sp->s_ref = 0;
251         sp->s_addr = 0;
252         return (sp);
253 }
254
255 /*)Function     VOID    symglob()
256  *
257  *      The function symglob() will mark all symbols of
258  *      type S_NEW as global.  Called at the beginning of pass 1
259  *      if the assembly option -g was specified.
260  *
261  *      local variables:
262  *              sym *   sp              pointer to a sym structure
263  *              int     i               loop index
264  *
265  *      global variables:
266  *              sym * symhash[]         array of pointers to NHASH
267  *                                      linked symbol lists
268  *
269  *      functions called:
270  *              none
271  *
272  *      side effects:
273  *              Symbol types changed.
274  */
275
276 VOID
277 symglob(void)
278 {
279         register struct sym *sp;
280         register int i;
281
282         for (i=0; i<NHASH; ++i) {
283                 sp = symhash[i];
284                 while (sp != NULL) {
285                         if (sp->s_type == S_NEW)
286                                 sp->s_flag |= S_GBL;
287                         sp = sp->s_sp;
288                 }
289         }
290 }
291
292 /*)Function     VOID    allglob()
293  *
294  *      The function allglob() will mark all symbols of
295  *      type S_USER as global.  Called at the beginning of pass 1
296  *      if the assembly option -a was specified.
297  *
298  *      local variables:
299  *              sym *   sp              pointer to a sym structure
300  *              int     i               loop index
301  *
302  *      global variables:
303  *              sym * symhash[]         array of pointers to NHASH
304  *                                      linked symbol lists
305  *
306  *      functions called:
307  *              none
308  *
309  *      side effects:
310  *              Symbol types changed.
311  */
312
313 VOID
314 allglob(void)
315 {
316         register struct sym *sp;
317         register int i;
318
319         for (i=0; i<NHASH; ++i) {
320                 sp = symhash[i];
321                 while (sp != NULL) {
322                         if (sp != &dot && sp->s_type == S_USER)
323                                 sp->s_flag |= S_GBL;
324                         sp = sp->s_sp;
325                 }
326         }
327 }
328
329 /*)Function     int     symeq(p1, p2)
330  *
331  *              char *  p1              name string
332  *              char *  p2              name string
333  *
334  *      The function symeq() compares the two name strings for a match.
335  *      The return value is 1 for a match and 0 for no match.
336  *
337  *      local variables:
338  *              int     h               loop counter
339  *
340  *      global variables:
341  *              char    ccase[]         an array of characters which
342  *                                      perform the case translation function
343  *
344  *      functions called:
345  *              none
346  *
347  *      side effects:
348  *              none
349  *
350  */
351
352 int
353 symeq(char *p1, char *p2)
354 {
355 #if     CASE_SENSITIVE
356                 return (strcmp( p1, p2 ) == 0);
357 #else
358                 return (as_strcmpi( p1, p2 ) == 0);
359 #endif
360 }
361
362 /*)Function     int     hash(p)
363  *
364  *              char *  p               pointer to string to hash
365  *
366  *      The function hash() computes a hash code using the sum
367  *      of all characters mod table size algorithm.
368  *
369  *      local variables:
370  *              int     h               accumulated character sum
371  *              int     n               loop counter
372  *
373  *      global variables:
374  *              char    ccase[]         an array of characters which
375  *                                      perform the case translation function
376  *
377  *      functions called:
378  *              none
379  *
380  *      side effects:
381  *              none
382  */
383
384 int
385 hash(char *p)
386 {
387         register int h;
388
389         h = 0;
390         while (*p) {
391                 /* JLH: case insensitive hash:  Doesn't much affect
392                  * hashing, and allows same function for mnemonics and symbols
393                  */
394                 h += ccase[(int)*p++];
395         }
396         return (h&HMASK);
397 }
398
399 /*)Function     char *  strsto(str)
400  *
401  *              char *  str             pointer to string to save
402  *
403  *      Allocate space for "str", copy str into new space.
404  *      Return a pointer to the allocated string.
405  *
406  *      This function based on code by
407  *              John L. Hartman
408  *              jhartman at compuserve dot com
409  *
410  *      local variables:
411  *              int     l               string length + 1
412  *              int     bytes           bytes remaining in buffer area
413  *              char *  p               pointer to head of copied string
414  *              char *  pnext           next location in buffer area
415  *
416  *      global variables:
417  *              none
418  *
419  *      functions called:
420  *              VOID *  new()           assym.c
421  *              char *  strncpy()       c_library
422  *
423  *      side effects:
424  *              Space allocated for string, string copied
425  *              to space.  Out of Space terminates assembler.
426  */
427
428 /*
429  * To avoid wasting memory headers on small allocations, we
430  * allocate a big chunk and parcel it out as required.
431  * These static variables remember our hunk
432  */
433
434 #define STR_SPC 1024
435 static  char *  pnext = NULL;
436 static  int     bytes = 0;
437
438 char *
439 strsto(char *str)
440 {
441         int  l;
442         char *p;
443
444         /*
445          * What we need, including a null.
446          */
447         l = strlen(str) + 1;
448
449         if (l > bytes) {
450                 /*
451                  * No space.  Allocate a new hunk.
452                  * We lose the pointer to any old hunk.
453                  * We don't care, as the names are never deleted.
454                 */
455                 pnext = (char *) new (STR_SPC);
456                 bytes = STR_SPC;
457         }
458
459         /*
460          * Copy the name and terminating null.
461          */
462         p = pnext;
463         strncpy(p, str, l);
464
465         pnext += l;
466         bytes -= l;
467
468         return(p);
469 }
470
471 /*)Function     VOID *  new(n)
472  *
473  *              unsigned int    n       allocation size in bytes
474  *
475  *      The function new() allocates n bytes of space and returns
476  *      a pointer to this memory.  If no space is available the
477  *      assembly is terminated.
478  *
479  *      local variables:
480  *              VOID *  p               a general pointer
481  *
482  *      global variables:
483  *              none
484  *
485  *      functions called:
486  *              VOID    asexit()        asmain.c
487  *              int     fprintf()       c_library
488  *              VOID *  malloc()        c_library
489  *
490  *      side effects:
491  *              Memory is allocated, if allocation fails
492  *              the assembly is terminated.
493  */
494
495 VOID *
496 new(unsigned int n)
497 {
498         register VOID *p;
499
500         if ((p = (VOID *) malloc(n)) == NULL) {
501                 fprintf(stderr, "Out of space!\n");
502                 asexit(1);
503         }
504         return (p);
505 }