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