Rune - Further Object abstraction work
[rune.git] / ras / sym.c
1 /*
2  * SYM.C
3  *
4  * (c)Copyright 2016, Matthew Dillon, All Rights Reserved.  See the COPYRIGHT
5  * file at the base of the distribution.
6  */
7
8 #include "defs.h"
9
10 /*
11  * Minimum ~8 bits, maximum ~16 bits for hash to work well
12  */
13 #define SHBITS  10
14 #define SHSIZE  (1 << SHBITS)
15 #define SHMASK  (SHSIZE - 1)
16
17 static rsym_t *RasSymHash[SHSIZE];
18
19 static int
20 symhash(const uint8_t *ptr, size_t bytes)
21 {
22     size_t  i;
23     int     hv = 0x71B4FC21;
24
25     for (i = 0; i < bytes; ++i)
26         hv = (hv << 5) ^ ptr[i] ^ (hv >> 23);
27     hv ^= hv >> 16;
28     hv ^= (hv & 0xFFFF) >> SHBITS;
29
30     return hv;
31 }
32
33 static
34 void
35 rasKeywordAdd(const char *str, rastoken_t tok,
36               void (*func) (RASParser *, rinsn_t *),
37               int characterize)
38 {
39     rsym_t *sym;
40
41     sym = RasGetSymbol((const uint8_t *)str, strlen(str));
42     sym->tok = tok;
43     sym->func = func;
44     sym->characterize = characterize;
45 }
46
47 void
48 RasSymInit(void)
49 {
50     /*
51      * Pseudoops
52      */
53
54     rasKeywordAdd("section", RAS_TOK_SECTION, PsopSECTION, 0);
55     rasKeywordAdd("endsection", RAS_TOK_ENDSECTION, PsopENDSECTION, 0);
56     rasKeywordAdd("extern", RAS_TOK_EXTERN, PsopEXTERN, 0);
57     rasKeywordAdd("rodata", RAS_TOK_RODATA, PsopRODATA, 0);
58     rasKeywordAdd("data", RAS_TOK_DATA, PsopDATA, 0);
59     rasKeywordAdd("bss", RAS_TOK_BSS, PsopBSS, 0);
60     rasKeywordAdd("text", RAS_TOK_TEXT, PsopTEXT, 0);
61     rasKeywordAdd("varproc", RAS_TOK_VARPROC, PsopPROC, 0);
62     rasKeywordAdd("proc", RAS_TOK_PROC, PsopPROC, 0);
63     rasKeywordAdd("endproc", RAS_TOK_ENDPROC, NULL, 0);
64     rasKeywordAdd("align", RAS_TOK_ALIGN, PsopALIGN, 0);
65     rasKeywordAdd("weak", RAS_TOK_WEAK, PsopWEAK, 0);
66     rasKeywordAdd("globl", RAS_TOK_GLOBL, PsopGLOBL, 0);
67     rasKeywordAdd("ctors", RAS_TOK_CTORS, PsopCTORS, 0);
68     rasKeywordAdd("loc", RAS_TOK_LOC, PsopLOC, 0);
69     rasKeywordAdd("file", RAS_TOK_FILE, PsopFILE, 0);
70
71     /*
72      * Data layout pseudoops
73      */
74     rasKeywordAdd("zero", RAS_TOK_ZERO, PsopZERO, 0);
75
76     rasKeywordAdd("int8", RAS_TOK_INT8, PsopLAYOUT, 0);
77     rasKeywordAdd("int16", RAS_TOK_INT16, PsopLAYOUT, 0);
78     rasKeywordAdd("int32", RAS_TOK_INT32, PsopLAYOUT, 0);
79     rasKeywordAdd("int64", RAS_TOK_INT64, PsopLAYOUT, 0);
80     rasKeywordAdd("int128", RAS_TOK_INT128, PsopLAYOUT, 0);
81     rasKeywordAdd("uint8", RAS_TOK_UINT8, PsopLAYOUT, 0);
82     rasKeywordAdd("uint16", RAS_TOK_UINT16, PsopLAYOUT, 0);
83     rasKeywordAdd("uint32", RAS_TOK_UINT32, PsopLAYOUT, 0);
84     rasKeywordAdd("uint64", RAS_TOK_UINT64, PsopLAYOUT, 0);
85     rasKeywordAdd("uint128", RAS_TOK_UINT128, PsopLAYOUT, 0);
86
87     rasKeywordAdd("float", RAS_TOK_FLOAT, PsopLAYOUT, 0);
88     rasKeywordAdd("double", RAS_TOK_DOUBLE, PsopLAYOUT, 0);
89     rasKeywordAdd("ldouble", RAS_TOK_LDOUBLE, PsopLAYOUT, 0);
90
91     /*
92      * Constants and specials
93      */
94     rasKeywordAdd("NULL", RAS_TOK_NULL, NULL, 0);
95     rasKeywordAdd("CACHE", RAS_TOK_CACHE, NULL, 0);
96
97     /*
98      * Instruction base codes.  Most instructions have multiple forms but
99      * some flags will be set that allows us to determine what additional
100      * forms are allowed.  For example, if INSNF_COND is set then an
101      * instruction can have an INSNF_BOOLD or INSNF_LABELD form.
102      */
103     rasKeywordAdd("MOVE", INSNF_INSN | INSN_MOVE,
104                   InsnMOVE,
105                   CHF_READ1 | CHF_WRITELST);
106     rasKeywordAdd("ADD", INSNF_INSN | INSN_ADD,
107                   InsnADD,
108                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
109     rasKeywordAdd("SUB", INSNF_INSN | INSN_SUB,
110                   InsnSUB,
111                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
112     rasKeywordAdd("AND", INSNF_INSN | INSN_AND,
113                   InsnAND,
114                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
115     rasKeywordAdd("OR", INSNF_INSN | INSN_OR,
116                   InsnOR,
117                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
118     rasKeywordAdd("XOR", INSNF_INSN | INSN_XOR,
119                   InsnXOR,
120                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
121     rasKeywordAdd("NOT", INSNF_INSN | INSN_NOT,
122                   InsnNOT,
123                   CHF_READ1 | CHF_WRITELST);
124     rasKeywordAdd("COM", INSNF_INSN | INSN_COM,
125                   InsnCOM,
126                   CHF_READ1 | CHF_WRITELST);
127     rasKeywordAdd("NEG", INSNF_INSN | INSN_NEG,
128                   InsnNEG,
129                   CHF_READ1 | CHF_WRITELST);
130     rasKeywordAdd("POS", INSNF_INSN | INSN_POS,
131                   InsnPOS,
132                   CHF_READ1 | CHF_WRITELST);
133     rasKeywordAdd("ASL", INSNF_INSN | INSN_ASL,
134                   InsnASL,
135                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
136     rasKeywordAdd("ASR", INSNF_INSN | INSN_ASR,
137                   InsnASR,
138                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
139     rasKeywordAdd("LSR", INSNF_INSN | INSN_LSR,
140                   InsnLSR,
141                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
142     rasKeywordAdd("ADDC", INSNF_INSN | INSN_ADDC,
143                   InsnADDC,
144                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
145     rasKeywordAdd("SUBC", INSNF_INSN | INSN_SUBC,
146                   InsnSUBC,
147                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
148
149     rasKeywordAdd("MULU", INSNF_INSN | INSN_MULU,
150                   InsnMULU,
151                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
152     rasKeywordAdd("MULS", INSNF_INSN | INSN_MULS,
153                   InsnMULS,
154                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
155     rasKeywordAdd("DIVU", INSNF_INSN | INSN_DIVU,
156                   InsnDIVU,
157                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
158     rasKeywordAdd("DIVS", INSNF_INSN | INSN_DIVS,
159                   InsnDIVS,
160                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
161     rasKeywordAdd("MODU", INSNF_INSN | INSN_MODU,
162                   InsnMODU,
163                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
164     rasKeywordAdd("MODS", INSNF_INSN | INSN_MODS,
165                   InsnMODS,
166                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
167
168     rasKeywordAdd("INC", INSNF_INSN | INSN_INC,
169                   InsnINC,
170                   CHF_READ1 | CHF_WRITELST);
171     rasKeywordAdd("DEC", INSNF_INSN | INSN_DEC,
172                   InsnDEC,
173                   CHF_READ1 | CHF_WRITELST);
174
175     rasKeywordAdd("CMP_EQ", INSNF_INSN | INSN_CMP_EQ,
176                   InsnCMP,
177                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
178     rasKeywordAdd("CMP_NE", INSNF_INSN | INSN_CMP_NE,
179                   InsnCMP,
180                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
181     rasKeywordAdd("CMP_UGT", INSNF_INSN | INSN_CMP_UGT,
182                   InsnCMP,
183                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
184     rasKeywordAdd("CMP_UGE", INSNF_INSN | INSN_CMP_UGE,
185                   InsnCMP,
186                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
187     rasKeywordAdd("CMP_ULT", INSNF_INSN | INSN_CMP_ULT,
188                   InsnCMP,
189                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
190     rasKeywordAdd("CMP_ULE", INSNF_INSN | INSN_CMP_ULE,
191                   InsnCMP,
192                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
193     rasKeywordAdd("CMP_SGT", INSNF_INSN | INSN_CMP_SGT,
194                   InsnCMP,
195                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
196     rasKeywordAdd("CMP_SGE", INSNF_INSN | INSN_CMP_SGE,
197                   InsnCMP,
198                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
199     rasKeywordAdd("CMP_SLT", INSNF_INSN | INSN_CMP_SLT,
200                   InsnCMP,
201                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
202     rasKeywordAdd("CMP_SLE", INSNF_INSN | INSN_CMP_SLE,
203                   InsnCMP,
204                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
205
206     rasKeywordAdd("MOVEA", INSNF_INSN | INSN_MOVEA,
207                   InsnMOVEA,
208                   CHF_READ1 | CHF_WRITELST);
209     rasKeywordAdd("ADDA", INSNF_INSN | INSN_ADDA,
210                   InsnADDA,
211                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
212     rasKeywordAdd("SUBA", INSNF_INSN | INSN_SUBA,
213                   InsnSUBA,
214                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
215     rasKeywordAdd("ADDAU", INSNF_INSN | INSN_ADDAU,
216                   InsnADDAU,
217                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
218     rasKeywordAdd("SUBAU", INSNF_INSN | INSN_SUBAU,
219                   InsnSUBAU,
220                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
221     rasKeywordAdd("SUBAA", INSNF_INSN | INSN_SUBAA,
222                   InsnSUBAA,
223                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
224     rasKeywordAdd("LEA", INSNF_INSN | INSN_LEA,
225                   InsnLEA,
226                   CHF_READ1 | CHF_LEA1 | CHF_WRITELST);
227
228     /*
229      * For now set the LEA* flags on BCOPY and BZERO because our object-life
230      * handling can't deal with inner-ranges.
231      */
232     rasKeywordAdd("BCOPY", INSNF_INSN | INSN_BCOPY,
233                   InsnBCOPY,
234                   CHF_READ1 | CHF_READ2 | CHF_WRITE3 |
235                   CHF_LEA2 | CHF_LEA3);
236     rasKeywordAdd("BZERO", INSNF_INSN | INSN_BZERO,
237                   InsnBZERO,
238                   CHF_READ1 | CHF_WRITE2 | CHF_LEA2);
239
240
241     rasKeywordAdd("CMPTYPE", INSNF_INSN | INSN_CMPTYPE,
242                   InsnCMPTYPE,
243                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
244
245     rasKeywordAdd("CMPA_EQ", INSNF_INSN | INSN_CMPA_EQ,
246                   InsnCMPA,
247                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
248     rasKeywordAdd("CMPA_NE", INSNF_INSN | INSN_CMPA_NE,
249                   InsnCMPA,
250                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
251     rasKeywordAdd("CMPA_UGT", INSNF_INSN | INSN_CMPA_UGT,
252                   InsnCMPA,
253                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
254     rasKeywordAdd("CMPA_UGE", INSNF_INSN | INSN_CMPA_UGE,
255                   InsnCMPA,
256                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
257     rasKeywordAdd("CMPA_ULT", INSNF_INSN | INSN_CMPA_ULT,
258                   InsnCMPA,
259                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
260     rasKeywordAdd("CMPA_ULE", INSNF_INSN | INSN_CMPA_ULE,
261                   InsnCMPA,
262                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
263     rasKeywordAdd("CMPA_SGT", INSNF_INSN | INSN_CMPA_SGT,
264                   InsnCMPA,
265                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
266     rasKeywordAdd("CMPA_SGE", INSNF_INSN | INSN_CMPA_SGE,
267                   InsnCMPA,
268                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
269     rasKeywordAdd("CMPA_SLT", INSNF_INSN | INSN_CMPA_SLT,
270                   InsnCMPA,
271                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
272     rasKeywordAdd("CMPA_SLE", INSNF_INSN | INSN_CMPA_SLE,
273                   InsnCMPA,
274                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
275
276     rasKeywordAdd("CASTU", INSNF_INSN | INSN_CASTU,
277                   InsnCASTU,
278                   CHF_READ1 | CHF_WRITE2);
279     rasKeywordAdd("CASTS", INSNF_INSN | INSN_CASTS,
280                   InsnCASTS,
281                   CHF_READ1 | CHF_WRITE2);
282     rasKeywordAdd("CASTP", INSNF_INSN | INSN_CASTP,
283                   InsnCASTP,
284                   CHF_READ1 | CHF_WRITE2);
285
286     rasKeywordAdd("BCHECK", INSNF_INSN | INSN_BCHECK,
287                   InsnBCHECK,
288                   CHF_READ1 | CHF_READ2);
289
290     rasKeywordAdd("PGET", INSNF_INSN | INSN_PGET,
291                   InsnPGET,
292                   CHF_READ1);
293     rasKeywordAdd("PGETH", INSNF_INSN | INSN_PGETH,
294                   InsnPGETH,
295                   CHF_READ1);
296     rasKeywordAdd("PPUT", INSNF_INSN | INSN_PPUT,
297                   InsnPPUT,
298                   CHF_READ1);
299     rasKeywordAdd("PPUTH", INSNF_INSN | INSN_PPUTH,
300                   InsnPPUTH,
301                   CHF_READ1);
302     rasKeywordAdd("PREF", INSNF_INSN | INSN_PREF,
303                   InsnPREF,
304                   CHF_READ1);
305     rasKeywordAdd("PREL", INSNF_INSN | INSN_PREL,
306                   InsnPREL,
307                   CHF_READ1);
308     rasKeywordAdd("PLOCK", INSNF_INSN | INSN_PLOCK,
309                   InsnPLOCK,
310                   CHF_READ1);
311     rasKeywordAdd("PLOCKH", INSNF_INSN | INSN_PLOCKH,
312                   InsnPLOCKH,
313                   CHF_READ1);
314     rasKeywordAdd("PUNLOCK", INSNF_INSN | INSN_PUNLOCK,
315                   InsnPUNLOCK,
316                   CHF_READ1);
317     rasKeywordAdd("PUNLOCKH", INSNF_INSN | INSN_PUNLOCKH,
318                   InsnPUNLOCKH,
319                   CHF_READ1);
320     rasKeywordAdd("PUNLOCKH", INSNF_INSN | INSN_PUNLOCKH,
321                   InsnPUNLOCKH,
322                   CHF_READ1);
323
324     rasKeywordAdd("IGET", INSNF_INSN | INSN_IGET,
325                   InsnIGET,
326                   CHF_READ1);
327     rasKeywordAdd("IGETH", INSNF_INSN | INSN_IGETH,
328                   InsnIGETH,
329                   CHF_READ1);
330     rasKeywordAdd("IPUT", INSNF_INSN | INSN_IPUT,
331                   InsnIPUT,
332                   CHF_READ1);
333     rasKeywordAdd("IPUTH", INSNF_INSN | INSN_IPUTH,
334                   InsnIPUTH,
335                   CHF_READ1);
336     rasKeywordAdd("IREF", INSNF_INSN | INSN_IREF,
337                   InsnIREF,
338                   CHF_READ1);
339     rasKeywordAdd("IREL", INSNF_INSN | INSN_IREL,
340                   InsnIREL,
341                   CHF_READ1);
342     rasKeywordAdd("ILOCK", INSNF_INSN | INSN_ILOCK,
343                   InsnILOCK,
344                   CHF_READ1);
345     rasKeywordAdd("ILOCKH", INSNF_INSN | INSN_ILOCKH,
346                   InsnILOCKH,
347                   CHF_READ1);
348     rasKeywordAdd("IUNLOCK", INSNF_INSN | INSN_IUNLOCK,
349                   InsnIUNLOCK,
350                   CHF_READ1);
351     rasKeywordAdd("IUNLOCKH", INSNF_INSN | INSN_IUNLOCKH,
352                   InsnIUNLOCKH,
353                   CHF_READ1);
354     rasKeywordAdd("IUNLOCKH", INSNF_INSN | INSN_IUNLOCKH,
355                   InsnIUNLOCKH,
356                   CHF_READ1);
357
358     rasKeywordAdd("LVALLOC", INSNF_INSN | INSN_LVALLOC,
359                   InsnLVALLOC,
360                   CHF_READ1 | CHF_READ2 | CHF_WRITE3 | CHF_NODROP3);
361
362     rasKeywordAdd("BND_TRAP", INSNF_INSN | INSN_BND_TRAP,
363                   InsnBNDTRAP, 0);
364     rasKeywordAdd("CALL", INSNF_INSN | INSN_CALL,
365                   InsnCALL,
366                   CHF_READ1 | CHF_LEA1 |
367                   CHF_READ2 | CHF_LEA2 |
368                   CHF_READ3 | CHF_LEA3 | CHF_WRITE3 | CHF_NODROP3 |
369                   CHF_READ4);
370     rasKeywordAdd("TCALL", INSNF_INSN | INSN_TCALL,
371                   InsnTCALL,
372                   CHF_READ1 | CHF_LEA1 |
373                   CHF_READ2 | CHF_LEA2 |
374                   CHF_READ3 | CHF_LEA3 | CHF_WRITE3 | CHF_NODROP3 |
375                   CHF_READ4);
376     rasKeywordAdd("LCALL", INSNF_INSN | INSN_LCALL,
377                   InsnLCALL,
378                   CHF_READ1 | CHF_LEA1 |
379                   CHF_READ2 | CHF_LEA2 |
380                   CHF_READ3 | CHF_LEA3 | CHF_WRITE3 | CHF_NODROP3 |
381                   CHF_READ4);
382     rasKeywordAdd("QCALL", INSNF_INSN | INSN_QCALL,
383                   InsnQCALL,
384                   CHF_READ1 | CHF_LEA1 |
385                   CHF_READ2 | CHF_LEA2 |
386                   CHF_READ3 | CHF_LEA3 | CHF_WRITE3 | CHF_NODROP3 |
387                   CHF_READ4);
388     rasKeywordAdd("RCALL", INSNF_INSN | INSN_RCALL,
389                   InsnRCALL,
390                   CHF_READ1 | CHF_LEA1 |
391                   CHF_READ2 | CHF_LEA2 |
392                   CHF_READ3 | CHF_LEA3 | CHF_WRITE3 | CHF_NODROP3 |
393                   CHF_READ4);
394
395     rasKeywordAdd("RET", INSNF_INSN | INSN_RET,
396                   InsnRET, 0);
397     rasKeywordAdd("DET", INSNF_INSN | INSN_DET,
398                   InsnDET, 0);
399     rasKeywordAdd("LINK", INSNF_INSN | INSN_LINK,
400                   InsnLINK, 0);
401     rasKeywordAdd("TSCHED", INSNF_INSN | INSN_TSCHED,
402                   InsnTSCHED, 0);
403
404     rasKeywordAdd("JMP", INSNF_INSN | INSN_JMP,
405                   InsnJMP, 0);
406     rasKeywordAdd("TEST_EQ", INSNF_INSN | INSN_TEST_EQ,
407                   InsnTEST,
408                   CHF_READ1 | CHF_WRITE2);
409     rasKeywordAdd("TEST_NE", INSNF_INSN | INSN_TEST_NE,
410                   InsnTEST,
411                   CHF_READ1 | CHF_WRITE2);
412
413     rasKeywordAdd("FMOVE", INSNF_INSN | INSN_FMOVE,
414                   InsnFMOVE,
415                   CHF_FLOAT1 | CHF_FLOATLST |
416                   CHF_READ1 | CHF_WRITELST);
417     rasKeywordAdd("FADD", INSNF_INSN | INSN_FADD,
418                   InsnFADD,
419                   CHF_FLOAT1 | CHF_FLOAT2 | CHF_FLOATLST |
420                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
421     rasKeywordAdd("FSUB", INSNF_INSN | INSN_FSUB,
422                   InsnFSUB,
423                   CHF_FLOAT1 | CHF_FLOAT2 | CHF_FLOATLST |
424                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
425     rasKeywordAdd("FMUL", INSNF_INSN | INSN_FMUL,
426                   InsnFMUL,
427                   CHF_FLOAT1 | CHF_FLOAT2 | CHF_FLOATLST |
428                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
429     rasKeywordAdd("FDIV", INSNF_INSN | INSN_FDIV,
430                   InsnFDIV,
431                   CHF_FLOAT1 | CHF_FLOAT2 | CHF_FLOATLST |
432                   CHF_READ1 | CHF_READ2 | CHF_WRITELST);
433
434     rasKeywordAdd("FINC", INSNF_INSN | INSN_FINC,
435                   InsnFINC,
436                   CHF_FLOAT1 | CHF_FLOATLST |
437                   CHF_READ1 | CHF_WRITELST);
438     rasKeywordAdd("FDEC", INSNF_INSN | INSN_FDEC,
439                   InsnFDEC,
440                   CHF_FLOAT1 | CHF_FLOATLST |
441                   CHF_READ1 | CHF_WRITELST);
442     rasKeywordAdd("FNEG", INSNF_INSN | INSN_FNEG,
443                   InsnFNEG,
444                   CHF_FLOAT1 | CHF_FLOATLST |
445                   CHF_READ1 | CHF_WRITELST);
446     rasKeywordAdd("FPOS", INSNF_INSN | INSN_FPOS,
447                   InsnFPOS,
448                   CHF_FLOAT1 | CHF_FLOATLST |
449                   CHF_READ1 | CHF_WRITELST);
450
451     /*
452      * NOTE: arg2 is a boolean destination, so FLOAT is only on arg1.
453      */
454     rasKeywordAdd("FNOT", INSNF_INSN | INSN_FNOT,
455                   InsnFNOT,
456                   CHF_FLOAT1 | CHF_READ1 | CHF_WRITELST);
457
458     rasKeywordAdd("UITOF", INSNF_INSN | INSN_UITOF,
459                   InsnUITOF,
460                   CHF_FLOAT2 |
461                   CHF_READ1 | CHF_WRITE2);
462     rasKeywordAdd("SITOF", INSNF_INSN | INSN_SITOF,
463                   InsnSITOF,
464                   CHF_FLOAT2 |
465                   CHF_READ1 | CHF_WRITE2);
466     rasKeywordAdd("FTOUI", INSNF_INSN | INSN_FTOUI,
467                   InsnFTOUI,
468                   CHF_FLOAT1 |
469                   CHF_READ1 | CHF_WRITE2);
470     rasKeywordAdd("FTOSI", INSNF_INSN | INSN_FTOSI,
471                   InsnFTOSI,
472                   CHF_FLOAT1 |
473                   CHF_READ1 | CHF_WRITE2);
474     rasKeywordAdd("CASTF", INSNF_INSN | INSN_CASTF,
475                   InsnCASTF,
476                   CHF_FLOAT1 | CHF_FLOAT2 |
477                   CHF_READ1 | CHF_WRITE2);
478
479     rasKeywordAdd("FCMP_UEQ", INSNF_INSN | INSN_FCMP_UEQ,
480                   InsnFCMP,
481                   CHF_FLOAT1 | CHF_FLOAT2 |
482                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
483     rasKeywordAdd("FCMP_UGT", INSNF_INSN | INSN_FCMP_UGT,
484                   InsnFCMP,
485                   CHF_FLOAT1 | CHF_FLOAT2 |
486                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
487     rasKeywordAdd("FCMP_UGE", INSNF_INSN | INSN_FCMP_UGE,
488                   InsnFCMP,
489                   CHF_FLOAT1 | CHF_FLOAT2 |
490                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
491     rasKeywordAdd("FCMP_ULT", INSNF_INSN | INSN_FCMP_ULT,
492                   InsnFCMP,
493                   CHF_FLOAT1 | CHF_FLOAT2 |
494                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
495     rasKeywordAdd("FCMP_ULE", INSNF_INSN | INSN_FCMP_ULE,
496                   InsnFCMP,
497                   CHF_FLOAT1 | CHF_FLOAT2 |
498                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
499     rasKeywordAdd("FCMP_UNE", INSNF_INSN | INSN_FCMP_UNE,
500                   InsnFCMP,
501                   CHF_FLOAT1 | CHF_FLOAT2 |
502                   CHF_READ1 | CHF_READ2 | CHF_WRITE3);
503 }
504
505 void
506 RasSymReinit(void)
507 {
508     size_t  i;
509
510     for (i = 0; i < SHSIZE; ++i) {
511         rsym_t **symp;
512         rsym_t *sym;
513
514         symp = &RasSymHash[i];
515         while ((sym = *symp) != NULL) {
516             if (sym->tok == 0 && sym->id[0] != '@') {
517                 *symp = sym->next;
518                 zfree(sym, sizeof(*sym) + sym->bytes + 1);
519                 continue;
520             }
521             symp = &sym->next;
522         }
523     }
524 }
525
526 rsym_t *
527 RasGetSymbol(const uint8_t *ptr, size_t bytes)
528 {
529     rsym_t **symp;
530     rsym_t *sym;
531     int     hv;
532
533     hv = symhash(ptr, bytes);
534     symp = &RasSymHash[hv & SHMASK];
535     for (sym = *symp; sym; sym = sym->next) {
536         if (sym->hv == hv &&
537             sym->bytes == bytes &&
538             bcmp(ptr, sym->id, bytes) == 0) {
539             return sym;
540         }
541     }
542     sym = zalloc(sizeof(*sym) + bytes + 1);
543     sym->id = (char *)(sym + 1);
544     bcopy(ptr, sym->id, bytes);
545     sym->id[bytes] = 0;
546     sym->hv = hv;
547     sym->bytes = bytes;
548     sym->next = *symp;
549     *symp = sym;
550
551     return sym;
552 }
553
554 void
555 RasEmitLabel(RASParser *p __unused, rsym_t *sym)
556 {
557     if (sym->id[0] == '@')
558         printf("%s:\n", sym->id + 1);
559     else
560         printf(".%s:\n", sym->id);
561 }