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