4 * (c)Copyright 2016, Matthew Dillon, All Rights Reserved. See the COPYRIGHT
5 * file at the base of the distribution.
11 * Minimum ~8 bits, maximum ~16 bits for hash to work well
14 #define SHSIZE (1 << SHBITS)
15 #define SHMASK (SHSIZE - 1)
17 static rsym_t *RasSymHash[SHSIZE];
20 symhash(const uint8_t *ptr, size_t bytes)
25 for (i = 0; i < bytes; ++i)
26 hv = (hv << 5) ^ ptr[i] ^ (hv >> 23);
28 hv ^= (hv & 0xFFFF) >> SHBITS;
35 rasKeywordAdd(const char *str, rastoken_t tok,
36 void (*func) (RASParser *, rinsn_t *),
41 sym = RasGetSymbol((const uint8_t *)str, strlen(str));
44 sym->characterize = characterize;
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);
72 * Data layout pseudoops
74 rasKeywordAdd("zero", RAS_TOK_ZERO, PsopZERO, 0);
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);
87 rasKeywordAdd("float", RAS_TOK_FLOAT, PsopLAYOUT, 0);
88 rasKeywordAdd("double", RAS_TOK_DOUBLE, PsopLAYOUT, 0);
89 rasKeywordAdd("ldouble", RAS_TOK_LDOUBLE, PsopLAYOUT, 0);
92 * Constants and specials
94 rasKeywordAdd("NULL", RAS_TOK_NULL, NULL, 0);
95 rasKeywordAdd("CACHE", RAS_TOK_CACHE, NULL, 0);
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.
103 rasKeywordAdd("MOVE", INSNF_INSN | INSN_MOVE,
105 CHF_READ1 | CHF_WRITELST);
106 rasKeywordAdd("ADD", INSNF_INSN | INSN_ADD,
108 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
109 rasKeywordAdd("SUB", INSNF_INSN | INSN_SUB,
111 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
112 rasKeywordAdd("AND", INSNF_INSN | INSN_AND,
114 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
115 rasKeywordAdd("OR", INSNF_INSN | INSN_OR,
117 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
118 rasKeywordAdd("XOR", INSNF_INSN | INSN_XOR,
120 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
121 rasKeywordAdd("NOT", INSNF_INSN | INSN_NOT,
123 CHF_READ1 | CHF_WRITELST);
124 rasKeywordAdd("COM", INSNF_INSN | INSN_COM,
126 CHF_READ1 | CHF_WRITELST);
127 rasKeywordAdd("NEG", INSNF_INSN | INSN_NEG,
129 CHF_READ1 | CHF_WRITELST);
130 rasKeywordAdd("POS", INSNF_INSN | INSN_POS,
132 CHF_READ1 | CHF_WRITELST);
133 rasKeywordAdd("ASL", INSNF_INSN | INSN_ASL,
135 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
136 rasKeywordAdd("ASR", INSNF_INSN | INSN_ASR,
138 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
139 rasKeywordAdd("LSR", INSNF_INSN | INSN_LSR,
141 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
142 rasKeywordAdd("ADDC", INSNF_INSN | INSN_ADDC,
144 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
145 rasKeywordAdd("SUBC", INSNF_INSN | INSN_SUBC,
147 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
149 rasKeywordAdd("MULU", INSNF_INSN | INSN_MULU,
151 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
152 rasKeywordAdd("MULS", INSNF_INSN | INSN_MULS,
154 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
155 rasKeywordAdd("DIVU", INSNF_INSN | INSN_DIVU,
157 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
158 rasKeywordAdd("DIVS", INSNF_INSN | INSN_DIVS,
160 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
161 rasKeywordAdd("MODU", INSNF_INSN | INSN_MODU,
163 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
164 rasKeywordAdd("MODS", INSNF_INSN | INSN_MODS,
166 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
168 rasKeywordAdd("INC", INSNF_INSN | INSN_INC,
170 CHF_READ1 | CHF_WRITELST);
171 rasKeywordAdd("DEC", INSNF_INSN | INSN_DEC,
173 CHF_READ1 | CHF_WRITELST);
175 rasKeywordAdd("CMP_EQ", INSNF_INSN | INSN_CMP_EQ,
177 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
178 rasKeywordAdd("CMP_NE", INSNF_INSN | INSN_CMP_NE,
180 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
181 rasKeywordAdd("CMP_UGT", INSNF_INSN | INSN_CMP_UGT,
183 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
184 rasKeywordAdd("CMP_UGE", INSNF_INSN | INSN_CMP_UGE,
186 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
187 rasKeywordAdd("CMP_ULT", INSNF_INSN | INSN_CMP_ULT,
189 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
190 rasKeywordAdd("CMP_ULE", INSNF_INSN | INSN_CMP_ULE,
192 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
193 rasKeywordAdd("CMP_SGT", INSNF_INSN | INSN_CMP_SGT,
195 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
196 rasKeywordAdd("CMP_SGE", INSNF_INSN | INSN_CMP_SGE,
198 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
199 rasKeywordAdd("CMP_SLT", INSNF_INSN | INSN_CMP_SLT,
201 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
202 rasKeywordAdd("CMP_SLE", INSNF_INSN | INSN_CMP_SLE,
204 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
206 rasKeywordAdd("MOVEA", INSNF_INSN | INSN_MOVEA,
208 CHF_READ1 | CHF_WRITELST);
209 rasKeywordAdd("ADDA", INSNF_INSN | INSN_ADDA,
211 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
212 rasKeywordAdd("SUBA", INSNF_INSN | INSN_SUBA,
214 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
215 rasKeywordAdd("ADDAU", INSNF_INSN | INSN_ADDAU,
217 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
218 rasKeywordAdd("SUBAU", INSNF_INSN | INSN_SUBAU,
220 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
221 rasKeywordAdd("SUBAA", INSNF_INSN | INSN_SUBAA,
223 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
224 rasKeywordAdd("LEA", INSNF_INSN | INSN_LEA,
226 CHF_READ1 | CHF_LEA1 | CHF_WRITELST);
229 * For now set the LEA* flags on BCOPY and BZERO because our object-life
230 * handling can't deal with inner-ranges.
232 rasKeywordAdd("BCOPY", INSNF_INSN | INSN_BCOPY,
234 CHF_READ1 | CHF_READ2 | CHF_WRITE3 |
235 CHF_LEA2 | CHF_LEA3);
236 rasKeywordAdd("BZERO", INSNF_INSN | INSN_BZERO,
238 CHF_READ1 | CHF_WRITE2 | CHF_LEA2);
241 rasKeywordAdd("CMPTYPE", INSNF_INSN | INSN_CMPTYPE,
243 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
245 rasKeywordAdd("CMPA_EQ", INSNF_INSN | INSN_CMPA_EQ,
247 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
248 rasKeywordAdd("CMPA_NE", INSNF_INSN | INSN_CMPA_NE,
250 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
251 rasKeywordAdd("CMPA_UGT", INSNF_INSN | INSN_CMPA_UGT,
253 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
254 rasKeywordAdd("CMPA_UGE", INSNF_INSN | INSN_CMPA_UGE,
256 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
257 rasKeywordAdd("CMPA_ULT", INSNF_INSN | INSN_CMPA_ULT,
259 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
260 rasKeywordAdd("CMPA_ULE", INSNF_INSN | INSN_CMPA_ULE,
262 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
263 rasKeywordAdd("CMPA_SGT", INSNF_INSN | INSN_CMPA_SGT,
265 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
266 rasKeywordAdd("CMPA_SGE", INSNF_INSN | INSN_CMPA_SGE,
268 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
269 rasKeywordAdd("CMPA_SLT", INSNF_INSN | INSN_CMPA_SLT,
271 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
272 rasKeywordAdd("CMPA_SLE", INSNF_INSN | INSN_CMPA_SLE,
274 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
276 rasKeywordAdd("CASTU", INSNF_INSN | INSN_CASTU,
278 CHF_READ1 | CHF_WRITE2);
279 rasKeywordAdd("CASTS", INSNF_INSN | INSN_CASTS,
281 CHF_READ1 | CHF_WRITE2);
282 rasKeywordAdd("CASTP", INSNF_INSN | INSN_CASTP,
284 CHF_READ1 | CHF_WRITE2);
286 rasKeywordAdd("BCHECK", INSNF_INSN | INSN_BCHECK,
288 CHF_READ1 | CHF_READ2);
290 rasKeywordAdd("PGET", INSNF_INSN | INSN_PGET,
293 rasKeywordAdd("PGETH", INSNF_INSN | INSN_PGETH,
296 rasKeywordAdd("PPUT", INSNF_INSN | INSN_PPUT,
299 rasKeywordAdd("PPUTH", INSNF_INSN | INSN_PPUTH,
302 rasKeywordAdd("PREF", INSNF_INSN | INSN_PREF,
305 rasKeywordAdd("PREL", INSNF_INSN | INSN_PREL,
308 rasKeywordAdd("PLOCK", INSNF_INSN | INSN_PLOCK,
311 rasKeywordAdd("PLOCKH", INSNF_INSN | INSN_PLOCKH,
314 rasKeywordAdd("PUNLOCK", INSNF_INSN | INSN_PUNLOCK,
317 rasKeywordAdd("PUNLOCKH", INSNF_INSN | INSN_PUNLOCKH,
320 rasKeywordAdd("PUNLOCKH", INSNF_INSN | INSN_PUNLOCKH,
324 rasKeywordAdd("IGET", INSNF_INSN | INSN_IGET,
327 rasKeywordAdd("IGETH", INSNF_INSN | INSN_IGETH,
330 rasKeywordAdd("IPUT", INSNF_INSN | INSN_IPUT,
333 rasKeywordAdd("IPUTH", INSNF_INSN | INSN_IPUTH,
336 rasKeywordAdd("IREF", INSNF_INSN | INSN_IREF,
339 rasKeywordAdd("IREL", INSNF_INSN | INSN_IREL,
342 rasKeywordAdd("ILOCK", INSNF_INSN | INSN_ILOCK,
345 rasKeywordAdd("ILOCKH", INSNF_INSN | INSN_ILOCKH,
348 rasKeywordAdd("IUNLOCK", INSNF_INSN | INSN_IUNLOCK,
351 rasKeywordAdd("IUNLOCKH", INSNF_INSN | INSN_IUNLOCKH,
354 rasKeywordAdd("IUNLOCKH", INSNF_INSN | INSN_IUNLOCKH,
358 rasKeywordAdd("LVALLOC", INSNF_INSN | INSN_LVALLOC,
360 CHF_READ1 | CHF_READ2 | CHF_WRITE3 | CHF_NODROP3);
362 rasKeywordAdd("BND_TRAP", INSNF_INSN | INSN_BND_TRAP,
364 rasKeywordAdd("CALL", INSNF_INSN | INSN_CALL,
366 CHF_READ1 | CHF_LEA1 |
367 CHF_READ2 | CHF_LEA2 |
368 CHF_READ3 | CHF_LEA3 | CHF_WRITE3 | CHF_NODROP3 |
370 rasKeywordAdd("TCALL", INSNF_INSN | INSN_TCALL,
372 CHF_READ1 | CHF_LEA1 |
373 CHF_READ2 | CHF_LEA2 |
374 CHF_READ3 | CHF_LEA3 | CHF_WRITE3 | CHF_NODROP3 |
376 rasKeywordAdd("LCALL", INSNF_INSN | INSN_LCALL,
378 CHF_READ1 | CHF_LEA1 |
379 CHF_READ2 | CHF_LEA2 |
380 CHF_READ3 | CHF_LEA3 | CHF_WRITE3 | CHF_NODROP3 |
382 rasKeywordAdd("QCALL", INSNF_INSN | INSN_QCALL,
384 CHF_READ1 | CHF_LEA1 |
385 CHF_READ2 | CHF_LEA2 |
386 CHF_READ3 | CHF_LEA3 | CHF_WRITE3 | CHF_NODROP3 |
388 rasKeywordAdd("RCALL", INSNF_INSN | INSN_RCALL,
390 CHF_READ1 | CHF_LEA1 |
391 CHF_READ2 | CHF_LEA2 |
392 CHF_READ3 | CHF_LEA3 | CHF_WRITE3 | CHF_NODROP3 |
395 rasKeywordAdd("RET", INSNF_INSN | INSN_RET,
397 rasKeywordAdd("DET", INSNF_INSN | INSN_DET,
399 rasKeywordAdd("LINK", INSNF_INSN | INSN_LINK,
401 rasKeywordAdd("TSCHED", INSNF_INSN | INSN_TSCHED,
404 rasKeywordAdd("JMP", INSNF_INSN | INSN_JMP,
406 rasKeywordAdd("TEST_EQ", INSNF_INSN | INSN_TEST_EQ,
408 CHF_READ1 | CHF_WRITE2);
409 rasKeywordAdd("TEST_NE", INSNF_INSN | INSN_TEST_NE,
411 CHF_READ1 | CHF_WRITE2);
413 rasKeywordAdd("FMOVE", INSNF_INSN | INSN_FMOVE,
415 CHF_FLOAT1 | CHF_FLOATLST |
416 CHF_READ1 | CHF_WRITELST);
417 rasKeywordAdd("FADD", INSNF_INSN | INSN_FADD,
419 CHF_FLOAT1 | CHF_FLOAT2 | CHF_FLOATLST |
420 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
421 rasKeywordAdd("FSUB", INSNF_INSN | INSN_FSUB,
423 CHF_FLOAT1 | CHF_FLOAT2 | CHF_FLOATLST |
424 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
425 rasKeywordAdd("FMUL", INSNF_INSN | INSN_FMUL,
427 CHF_FLOAT1 | CHF_FLOAT2 | CHF_FLOATLST |
428 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
429 rasKeywordAdd("FDIV", INSNF_INSN | INSN_FDIV,
431 CHF_FLOAT1 | CHF_FLOAT2 | CHF_FLOATLST |
432 CHF_READ1 | CHF_READ2 | CHF_WRITELST);
434 rasKeywordAdd("FINC", INSNF_INSN | INSN_FINC,
436 CHF_FLOAT1 | CHF_FLOATLST |
437 CHF_READ1 | CHF_WRITELST);
438 rasKeywordAdd("FDEC", INSNF_INSN | INSN_FDEC,
440 CHF_FLOAT1 | CHF_FLOATLST |
441 CHF_READ1 | CHF_WRITELST);
442 rasKeywordAdd("FNEG", INSNF_INSN | INSN_FNEG,
444 CHF_FLOAT1 | CHF_FLOATLST |
445 CHF_READ1 | CHF_WRITELST);
446 rasKeywordAdd("FPOS", INSNF_INSN | INSN_FPOS,
448 CHF_FLOAT1 | CHF_FLOATLST |
449 CHF_READ1 | CHF_WRITELST);
452 * NOTE: arg2 is a boolean destination, so FLOAT is only on arg1.
454 rasKeywordAdd("FNOT", INSNF_INSN | INSN_FNOT,
456 CHF_FLOAT1 | CHF_READ1 | CHF_WRITELST);
458 rasKeywordAdd("UITOF", INSNF_INSN | INSN_UITOF,
461 CHF_READ1 | CHF_WRITE2);
462 rasKeywordAdd("SITOF", INSNF_INSN | INSN_SITOF,
465 CHF_READ1 | CHF_WRITE2);
466 rasKeywordAdd("FTOUI", INSNF_INSN | INSN_FTOUI,
469 CHF_READ1 | CHF_WRITE2);
470 rasKeywordAdd("FTOSI", INSNF_INSN | INSN_FTOSI,
473 CHF_READ1 | CHF_WRITE2);
474 rasKeywordAdd("CASTF", INSNF_INSN | INSN_CASTF,
476 CHF_FLOAT1 | CHF_FLOAT2 |
477 CHF_READ1 | CHF_WRITE2);
479 rasKeywordAdd("FCMP_UEQ", INSNF_INSN | INSN_FCMP_UEQ,
481 CHF_FLOAT1 | CHF_FLOAT2 |
482 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
483 rasKeywordAdd("FCMP_UGT", INSNF_INSN | INSN_FCMP_UGT,
485 CHF_FLOAT1 | CHF_FLOAT2 |
486 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
487 rasKeywordAdd("FCMP_UGE", INSNF_INSN | INSN_FCMP_UGE,
489 CHF_FLOAT1 | CHF_FLOAT2 |
490 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
491 rasKeywordAdd("FCMP_ULT", INSNF_INSN | INSN_FCMP_ULT,
493 CHF_FLOAT1 | CHF_FLOAT2 |
494 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
495 rasKeywordAdd("FCMP_ULE", INSNF_INSN | INSN_FCMP_ULE,
497 CHF_FLOAT1 | CHF_FLOAT2 |
498 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
499 rasKeywordAdd("FCMP_UNE", INSNF_INSN | INSN_FCMP_UNE,
501 CHF_FLOAT1 | CHF_FLOAT2 |
502 CHF_READ1 | CHF_READ2 | CHF_WRITE3);
510 for (i = 0; i < SHSIZE; ++i) {
514 symp = &RasSymHash[i];
515 while ((sym = *symp) != NULL) {
516 if (sym->tok == 0 && sym->id[0] != '@') {
518 zfree(sym, sizeof(*sym) + sym->bytes + 1);
527 RasGetSymbol(const uint8_t *ptr, size_t bytes)
533 hv = symhash(ptr, bytes);
534 symp = &RasSymHash[hv & SHMASK];
535 for (sym = *symp; sym; sym = sym->next) {
537 sym->bytes == bytes &&
538 bcmp(ptr, sym->id, bytes) == 0) {
542 sym = zalloc(sizeof(*sym) + bytes + 1);
543 sym->id = (char *)(sym + 1);
544 bcopy(ptr, sym->id, bytes);
555 RasEmitLabel(RASParser *p __unused, rsym_t *sym)
557 if (sym->id[0] == '@')
558 printf("%s:\n", sym->id + 1);
560 printf(".%s:\n", sym->id);