Setting up repository
[linux-libre-firmware.git] / as31 / as31 / symbol.c
1 /* ----------------------------------------------------------------------
2  * FILE: symbol.c
3  * PACKAGE: as31 - 8031/8051 Assembler.
4  *
5  * DESCRIPTION:
6  *      This file contains the symbol table search/insertion routines
7  *      associated with user defined symbols.
8  *
9  *      The reserved keyword (instructions/directives) look up routine
10  *      is defined here.
11  *
12  *      The opcode table for all of the instructions is located in this
13  *      file.
14  *
15  * REVISION HISTORY:
16  *      Jan. 19, 1990 - Created. (Ken Stauffer)
17  *
18  * AUTHOR:
19  *      All code in this file written by Ken Stauffer (University of Calgary)
20  *      January, 1990.
21  *
22  */
23
24 #include <ctype.h>
25 #include <string.h>
26
27 /* normally in stdlib.h, but that include file also defines */
28 /* "div" which conflicts with the div in this file */
29 extern void *malloc(size_t size);
30 extern void free(void *ptr);
31
32
33 #include "as31.h"
34 #include "parser.h"
35
36 #define B(a)            (0xF0+(a))
37 #define ACC(a)          (0xE0+(a))
38 #define PSW(a)          (0xD0+(a))
39 #define T2CON(a)        (0xC8+(a))
40 #define IP(a)           (0xB8+(a))
41 #define P3(a)           (0xB0+(a))
42 #define IE(a)           (0xA8+(a))
43 #define P2(a)           (0xA0+(a))
44 #define SCON(a)         (0x98+(a))
45 #define P1(a)           (0x90+(a))
46 #define TCON(a)         (0x88+(a))
47 #define P0(a)           (0x80+(a))
48
49 /* ---------------------------------------------------------------------- 
50  * sinit[]
51  *      These symbols are not reserved keywords.
52  *      This array contains the initial symbol table entries
53  *      for the user symbol table. The symbols are
54  *      basically convienient names that make writing
55  *      in 8031/8051 bearable.
56  *
57  *      The function syminit() inserts these entries into the
58  *      symbol table.
59  *
60  */
61
62 static struct symbol sinit[] = {
63         { "AC",         1, LABEL,               PSW(6), NULL },
64         { "ACC",        1, LABEL,               ACC(0), NULL },
65         { "B",          1, LABEL,               B(0),   NULL },
66         { "CY",         1, LABEL,               PSW(7), NULL },
67         { "DPH",        1, LABEL,               0x83,   NULL },
68         { "DPL",        1, LABEL,               0x82,   NULL },
69         { "EA",         1, LABEL,               IE(7),  NULL },
70         { "ES",         1, LABEL,               IE(4),  NULL },
71         { "ET0",        1, LABEL,               IE(1),  NULL },
72         { "ET1",        1, LABEL,               IE(3),  NULL },
73         { "ET2",        1, LABEL,               IE(5),  NULL },
74         { "EX0",        1, LABEL,               IE(0),  NULL },
75         { "EX1",        1, LABEL,               IE(2),  NULL },
76         { "EXEN2",      1, LABEL,               T2CON(3),NULL },
77         { "EXF2",       1, LABEL,               T2CON(6),NULL },
78         { "F0",         1, LABEL,               PSW(5), NULL },
79         { "IE",         1, LABEL,               IE(0),  NULL },
80         { "IE0",        1, LABEL,               TCON(1),NULL },
81         { "IE1",        1, LABEL,               TCON(3),NULL },
82         { "INT0",       1, LABEL,               P3(2),  NULL },
83         { "INT1",       1, LABEL,               P3(3),  NULL },
84         { "IP",         1, LABEL,               IP(0),  NULL },
85         { "IT0",        1, LABEL,               TCON(0),NULL },
86         { "IT1",        1, LABEL,               TCON(2),NULL },
87         { "OV",         1, LABEL,               PSW(2), NULL },
88         { "P",          1, LABEL,               PSW(0), NULL },
89         { "P0",         1, LABEL,               P0(0),  NULL },
90         { "P1",         1, LABEL,               P1(0),  NULL },
91         { "P2",         1, LABEL,               P2(0),  NULL },
92         { "P3",         1, LABEL,               P3(0),  NULL },
93         { "PCON",       1, LABEL,               0x87,   NULL },
94         { "PS",         1, LABEL,               IP(4),  NULL },
95         { "PSW",        1, LABEL,               PSW(0), NULL },
96         { "PT0",        1, LABEL,               IP(1),  NULL },
97         { "PT1",        1, LABEL,               IP(3),  NULL },
98         { "PT2",        1, LABEL,               IP(5),  NULL },
99         { "PX0",        1, LABEL,               IP(0),  NULL },
100         { "PX1",        1, LABEL,               IP(2),  NULL },
101         { "RB8",        1, LABEL,               SCON(2),NULL },
102         { "RCAP2H",     1, LABEL,               0xCB,   NULL },
103         { "RCAP2L",     1, LABEL,               0xCA,   NULL },
104         { "RCLK",       1, LABEL,               T2CON(5),NULL },
105         { "REN",        1, LABEL,               SCON(4),NULL },
106         { "RD",         1, LABEL,               P3(7),  NULL },
107         { "RI",         1, LABEL,               SCON(0),NULL },
108         { "RL2",        1, LABEL,               T2CON(0),NULL },
109         { "RS0",        1, LABEL,               PSW(3), NULL },
110         { "RS1",        1, LABEL,               PSW(4), NULL },
111         { "RXD",        1, LABEL,               P3(0),  NULL },
112         { "SBUF",       1, LABEL,               0x99,   NULL },
113         { "SCON",       1, LABEL,               SCON(0),NULL },
114         { "SM0",        1, LABEL,               SCON(7),NULL },
115         { "SM1",        1, LABEL,               SCON(6),NULL },
116         { "SM2",        1, LABEL,               SCON(5),NULL },
117         { "SP",         1, LABEL,               0x81,   NULL },
118         { "T0",         1, LABEL,               P3(4),  NULL },
119         { "T1",         1, LABEL,               P3(5),  NULL },
120         { "T2",         1, LABEL,               P0(0),  NULL },
121         { "T2CON",      1, LABEL,               T2CON(0),NULL },
122         { "T2EX",       1, LABEL,               P0(1),  NULL },
123         { "TB8",        1, LABEL,               SCON(3),NULL },
124         { "TCLK",       1, LABEL,               T2CON(4),NULL },
125         { "TCON",       1, LABEL,               TCON(0),NULL },
126         { "TF0",        1, LABEL,               TCON(5),NULL },
127         { "TF1",        1, LABEL,               TCON(7),NULL },
128         { "TF2",        1, LABEL,               T2CON(7),NULL },
129         { "TH0",        1, LABEL,               0x8C,   NULL },
130         { "TH1",        1, LABEL,               0x8D,   NULL },
131         { "TH2",        1, LABEL,               0xCD,   NULL },
132         { "TI",         1, LABEL,               SCON(1),NULL },
133         { "TL0",        1, LABEL,               0x8A,   NULL },
134         { "TL1",        1, LABEL,               0x8B,   NULL },
135         { "TL2",        1, LABEL,               0xCC,   NULL },
136         { "TMOD",       1, LABEL,               0x89,   NULL },
137         { "TR0",        1, LABEL,               TCON(4),NULL },
138         { "TR1",        1, LABEL,               TCON(6),NULL },
139         { "TR2",        1, LABEL,               T2CON(2),NULL },
140         { "TXD",        1, LABEL,               P3(1),  NULL },
141         { "WR",         1, LABEL,               P3(6),  NULL }
142 };
143
144 #define SINITSIZE       (sizeof(sinit)/sizeof(sinit[0]))
145
146 /* ----------------------------------------------------------------------
147  * opcode vectors:
148  *      These arrays contain the various opcodes for the
149  *      various forms an instruction may take.
150  *
151  *      The ordering of these opcodes is very critical to the
152  *      proper fuctioning of the assembler.
153  *
154  *      When a given form of an instruction is parsed, the parser
155  *      indexes one of these arrays by the correct amount and thus
156  *      obtains the correct opcode for the particular form.
157  *
158  */
159
160 static unsigned char acall[]=   { 0x11 };
161 static unsigned char add[]=     { 0x28, 0x25, 0x26, 0x24 };
162 static unsigned char addc[]=    { 0x38, 0x35, 0x36, 0x34 };
163 static unsigned char ajmp[]=    { 0x01 };
164 static unsigned char anl[]=     { 0x58, 0x55, 0x56, 0x54, 0x52, 0x53, 0x82,
165                                   0xb0 };
166 static unsigned char cjne[]=    { 0xb5, 0xb4, 0xb8, 0xb6 };
167 static unsigned char clr[]=     { 0xe4, 0xc3, 0xc2 };
168 static unsigned char cpl[]=     { 0xf4, 0xb3, 0xb2 };
169 static unsigned char da[]=      { 0xd4 };
170 static unsigned char dec[]=     { 0x14, 0x18, 0x15, 0x16 };
171 static unsigned char div[]=     { 0x84 };
172 static unsigned char djnz[]=    { 0xd8, 0xd5 };
173 static unsigned char inc[]=     { 0x04, 0x08, 0x05, 0x06, 0xa3 };
174 static unsigned char jb[]=      { 0x20 };
175 static unsigned char jbc[]=     { 0x10 };
176 static unsigned char jc[]=      { 0x40 };
177 static unsigned char jmp[]=     { 0x73 };
178 static unsigned char jnb[]=     { 0x30 };
179 static unsigned char jnc[]=     { 0x50 };
180 static unsigned char jnz[]=     { 0x70 };
181 static unsigned char jz[]=      { 0x60 };
182 static unsigned char lcall[]=   { 0x12 };
183 static unsigned char ljmp[]=    { 0x02 };
184 static unsigned char mov[]=     { 0xe8, 0xe5, 0xe6, 0x74, 0xf5, 0x75, 0xf8,
185                                   0xa8, 0x78, 0x88, 0x85, 0x86, 0xf6, 0xa6,
186                                   0x76, 0x90, 0xa2, 0x92 };
187 static unsigned char movc[]=    { 0x93, 0x83 };
188 static unsigned char movx[]=    { 0xe2, 0xe3, 0xe0, 0xf2, 0xf3, 0xf0 };
189 static unsigned char mul[]=     { 0xa4 };
190 static unsigned char nop[]=     { 0x00 };
191 static unsigned char orl[]=     { 0x48, 0x45, 0x46, 0x44, 0x42, 0x43, 0x72,
192                                   0xa0 };
193 static unsigned char pop[]=     { 0xd0 };
194 static unsigned char push[]=    { 0xc0 };
195 static unsigned char ret[]=     { 0x22 };
196 static unsigned char reti[]=    { 0x32 };
197 static unsigned char rl[]=      { 0x23 };
198 static unsigned char rlc[]=     { 0x33 };
199 static unsigned char rr[]=      { 0x03 };
200 static unsigned char rrc[]=     { 0x13 };
201 static unsigned char setb[]=    { 0xd3, 0xd2 };
202 static unsigned char sjmp[]=    { 0x80 };
203 static unsigned char subb[]=    { 0x98, 0x95, 0x96, 0x94 };
204 static unsigned char swap[]=    { 0xc4 };
205 static unsigned char xch[]=     { 0xc8, 0xc5, 0xc6 };
206 static unsigned char xchd[]=    { 0xd6 };
207 static unsigned char xrl[]=     { 0x68, 0x65, 0x66, 0x64, 0x62, 0x63 };
208
209 /* ----------------------------------------------------------------------
210  * optable[]
211  *      This table contains opcodes, directives and a few reserved
212  *      symbols.
213  *
214  *      The second field is the keywords token value.
215  *
216  *      Unless the symbol is an opcode, the third field will
217  *      be NULL.
218  * 
219  *      The third field is a pointer to an array of opcode bytes.
220  *
221  *    --> This list must be in order by the first field
222  */
223
224 static struct opcode optable[] = {
225         {"a",           A,      NULL            },
226         {"ab",          AB,     NULL            },
227         {"acall",       ACALL,  acall           },
228         {"add",         ADD,    add             },
229         {"addc",        ADDC,   addc            },
230         {"ajmp",        AJMP,   ajmp            },
231         {"anl",         ANL,    anl             },
232         {"byte",        D_BYTE, NULL            },
233         {"c",           C,      NULL            },
234         {"cjne",        CJNE,   cjne            },
235         {"clr",         CLR,    clr             },
236         {"cpl",         CPL,    cpl             },
237         {"da",          DA,     da              },
238         {"db",          D_BYTE, NULL            },
239         {"dec",         DEC,    dec             },
240         {"div",         DIV,    div             },
241         {"djnz",        DJNZ,   djnz            },
242         {"dptr",        DPTR,   NULL            },
243         {"dw",          D_WORD, NULL            },
244         {"end",         D_END,  NULL            },
245         {"equ",         D_EQU,  NULL            },
246         {"flag",        D_FLAG, NULL            },
247         {"inc",         INC,    inc             },
248         {"jb",          JB,     jb              },
249         {"jbc",         JBC,    jbc             },
250         {"jc",          JC,     jc              },
251         {"jmp",         JMP,    jmp             },
252         {"jnb",         JNB,    jnb             },
253         {"jnc",         JNC,    jnc             },
254         {"jnz",         JNZ,    jnz             },
255         {"jz",          JZ,     jz              },
256         {"lcall",       LCALL,  lcall           },
257         {"ljmp",        LJMP,   ljmp            },
258         {"mov",         MOV,    mov             },
259         {"movc",        MOVC,   movc            },
260         {"movx",        MOVX,   movx            },
261         {"mul",         MUL,    mul             },
262         {"nop",         NOP,    nop             },
263         {"org",         D_ORG,  NULL            },
264         {"orl",         ORL,    orl             },
265         {"pc",          PC,     NULL            },
266         {"pop",         POP,    pop             },
267         {"push",        PUSH,   push            },
268         {"r0",          R0,     NULL            },
269         {"r1",          R1,     NULL            },
270         {"r2",          R2,     NULL            },
271         {"r3",          R3,     NULL            },
272         {"r4",          R4,     NULL            },
273         {"r5",          R5,     NULL            },
274         {"r6",          R6,     NULL            },
275         {"r7",          R7,     NULL            },
276         {"ret",         RET,    ret             },
277         {"reti",        RETI,   reti            },
278         {"rl",          RL,     rl              },
279         {"rlc",         RLC,    rlc             },
280         {"rr",          RR,     rr              },
281         {"rrc",         RRC,    rrc             },
282         {"setb",        SETB,   setb            },
283         {"sjmp",        SJMP,   sjmp            },
284         {"skip",        D_SKIP, NULL            },
285         {"subb",        SUBB,   subb            },
286         {"swap",        SWAP,   swap            },
287         {"word",        D_WORD, NULL            },
288         {"xch",         XCH,    xch             },
289         {"xchd",        XCHD,   xchd            },
290         {"xrl",         XRL,    xrl             }
291 };
292
293 #define OPTABSIZE       (sizeof(optable)/sizeof(struct opcode))
294
295
296 /* ----------------------------------------------------------------------
297  * lookop:
298  *      Do a binary search through optable[], for a matching
299  *      symbol. Return the symbol found or NULL.
300  *
301  */
302
303 struct opcode *lookop(const char *s)
304 {
305         register int low,high,mid,cond;
306
307         low = 0;
308         high = OPTABSIZE-1;
309         while( low<=high ) {
310                 mid = (low+high)/2;
311                 if( (cond = strcasecmp(s,optable[mid].name)) < 0 )
312                         high = mid-1;
313                 else if(cond > 0 )
314                         low = mid+1;
315                 else
316                         return(&optable[mid]);
317         }
318         return(NULL);
319 }
320
321 /* ----------------------------------------------------------------------
322  * symtab, hash, looksym:
323  *      User symbol table routines.
324  *      symtab is the hash table for the user symbols.
325  *      (chaining is used for collision resolution).
326  *
327  */
328
329 static struct symbol *symtab[HASHTABSIZE];
330
331 int hash(const char *s)
332 {
333         register const char *p;
334         register unsigned h=0, g;
335
336         for (p=s; *p; p++) {
337                 h = (h<<4) + toupper(*p);
338                 if ( (g = h&0xf0000000) ) {
339                         h = h ^ (g >> 24);
340                         h = h ^ g;
341                 }
342         }
343         return( h % HASHTABSIZE );
344 }
345
346 struct symbol *looksym(const char *s)
347 {
348         register struct symbol *ptr, *prev;
349         char *p;
350         register int hv;
351
352         hv = hash(s);
353
354         prev = NULL;
355         for(ptr=symtab[hv]; ptr; ptr = ptr->next) {
356                 if( !strcasecmp(ptr->name,s) ) {
357                         if( prev != NULL ) {
358                                 prev->next = ptr->next;
359                                 ptr->next = symtab[hv];
360                                 symtab[hv] = ptr;
361                         }
362                         return(ptr);
363                 }
364                 prev = ptr;
365         }
366
367         if ( (p = malloc(strlen(s) + 1)) ) {
368                 strcpy(p,s);
369         } else {
370                 error("Cannot allocate %d bytes",strlen(s)+1);
371         }
372
373         ptr = (struct symbol *) malloc( sizeof(struct symbol) );
374         if( ptr == NULL )
375                 error("Cannot allocate %d bytes",sizeof(struct symbol));
376         ptr->name = p;
377         ptr->predefined = 0;
378         ptr->type = UNDEF;
379         ptr->next = symtab[hv];
380         symtab[hv] = ptr;
381         return(ptr);
382 }
383
384 /* ----------------------------------------------------------------------
385  * syminit:
386  *      Initializes the hash table, with the initial symbols from
387  *      sinit[]
388  *
389  */
390
391 // static struct symbol *symtab[HASHTABSIZE];
392
393 void syminit(void)
394 {
395         register int i,hv;
396
397         /* clear all entries in the symbol table */
398         memset(symtab, 0, sizeof(struct symbol *) * HASHTABSIZE);
399
400         /* load all the pre-defined symbols */
401         for(i=0; i<SINITSIZE; i++ ) {
402                 hv = hash(sinit[i].name);
403                 if( symtab[hv] )
404                         sinit[i].next = symtab[hv];
405                 symtab[hv] = &sinit[i];
406                 sinit[i].next = NULL;
407         }
408 }
409
410 /* free all the memory allocated for the symbols */
411
412 void freesym(void)
413 {
414         struct symbol *sym, *next;
415         int i;
416
417         for (i=0; i<HASHTABSIZE; i++) {
418                 sym = symtab[i];
419                 while (sym != NULL) {
420                         if (sym->predefined) {
421                                 sym = sym->next;
422                         } else {
423                                 if (sym->name) free(sym->name);
424                                 next = sym->next;
425                                 free(sym);
426                                 sym = next;
427                         }
428                 }
429         }
430 }
431
432
433