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