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