123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- /* ANSI-C code produced by genperf */
- #include <util.h>
- #include <ctype.h>
- #include <libyasm.h>
- #include <libyasm/phash.h>
- #include "modules/arch/x86/x86arch.h"
- enum regtmod_type {
- REG = 1,
- REGGROUP,
- SEGREG,
- TARGETMOD
- };
- struct regtmod_parse_data {
- const char *name;
- unsigned int type:8; /* regtmod_type */
- /* REG: register size
- * SEGREG: prefix encoding
- * Others: 0
- */
- unsigned int size_prefix:8;
- /* REG: register index
- * REGGROUP: register group type
- * SEGREG: register encoding
- * TARGETMOD: target modifier
- */
- unsigned int data:8;
- /* REG: required bits setting
- * SEGREG: BITS in which the segment is ignored
- * Others: 0
- */
- unsigned int bits:8;
- };
- static const struct regtmod_parse_data *
- regtmod_find(const char *key, size_t len)
- {
- static const struct regtmod_parse_data pd[152] = {
- {"st6", REG, X86_FPUREG, 6, 0},
- {"ymm1", REG, X86_YMMREG, 1, 0},
- {"rsp", REG, X86_REG64, 4, 64},
- {"r10", REG, X86_REG64, 10, 64},
- {"bp", REG, X86_REG16, 5, 0},
- {"r10b", REG, X86_REG8, 10, 64},
- {"mm2", REG, X86_MMXREG, 2, 0},
- {"rdi", REG, X86_REG64, 7, 64},
- {"ymm12", REG, X86_YMMREG, 12, 64},
- {"r8", REG, X86_REG64, 8, 64},
- {"gs", SEGREG, 0x65, 0x05, 0},
- {"r10d", REG, X86_REG32, 10, 64},
- {"rsi", REG, X86_REG64, 6, 64},
- {"eax", REG, X86_REG32, 0, 0},
- {"mm3", REG, X86_MMXREG, 3, 0},
- {"tr6", REG, X86_TRREG, 6, 0},
- {"tr0", REG, X86_TRREG, 0, 0},
- {"ah", REG, X86_REG8, 4, 0},
- {"xmm6", REG, X86_XMMREG, 6, 0},
- {"dr6", REG, X86_DRREG, 6, 0},
- {"esp", REG, X86_REG32, 4, 0},
- {"bpl", REG, X86_REG8X, 5, 64},
- {"tr5", REG, X86_TRREG, 5, 0},
- {"ax", REG, X86_REG16, 0, 0},
- {"sp", REG, X86_REG16, 4, 0},
- {"r15b", REG, X86_REG8, 15, 64},
- {"xmm14", REG, X86_XMMREG, 14, 64},
- {"xmm12", REG, X86_XMMREG, 12, 64},
- {"r11", REG, X86_REG64, 11, 64},
- {"xmm", REGGROUP, 0, X86_XMMREG, 0},
- {"ymm2", REG, X86_YMMREG, 2, 0},
- {"ebp", REG, X86_REG32, 5, 0},
- {"xmm8", REG, X86_XMMREG, 8, 64},
- {"r12d", REG, X86_REG32, 12, 64},
- {"ymm4", REG, X86_YMMREG, 4, 0},
- {"ymm3", REG, X86_YMMREG, 3, 0},
- {"rax", REG, X86_REG64, 0, 64},
- {"xmm3", REG, X86_XMMREG, 3, 0},
- {"xmm0", REG, X86_XMMREG, 0, 0},
- {"dr7", REG, X86_DRREG, 7, 0},
- {"r14w", REG, X86_REG16, 14, 64},
- {"mm1", REG, X86_MMXREG, 1, 0},
- {"bl", REG, X86_REG8, 3, 0},
- {"r9w", REG, X86_REG16, 9, 64},
- {"ymm13", REG, X86_YMMREG, 13, 64},
- {"r9b", REG, X86_REG8, 9, 64},
- {"ymm8", REG, X86_YMMREG, 8, 64},
- {"dx", REG, X86_REG16, 2, 0},
- {"r12", REG, X86_REG64, 12, 64},
- {"r12w", REG, X86_REG16, 12, 64},
- {"r9", REG, X86_REG64, 9, 64},
- {"r15w", REG, X86_REG16, 15, 64},
- {"sil", REG, X86_REG8X, 6, 64},
- {"r10w", REG, X86_REG16, 10, 64},
- {"ymm6", REG, X86_YMMREG, 6, 0},
- {"ss", SEGREG, 0x36, 0x02, 64},
- {"tr4", REG, X86_TRREG, 4, 0},
- {"cr3", REG, X86_CRREG, 3, 0},
- {"r11w", REG, X86_REG16, 11, 64},
- {"xmm4", REG, X86_XMMREG, 4, 0},
- {"st0", REG, X86_FPUREG, 0, 0},
- {"dil", REG, X86_REG8X, 7, 64},
- {"tr3", REG, X86_TRREG, 3, 0},
- {"r13d", REG, X86_REG32, 13, 64},
- {"r8w", REG, X86_REG16, 8, 64},
- {"xmm13", REG, X86_XMMREG, 13, 64},
- {"st3", REG, X86_FPUREG, 3, 0},
- {"xmm15", REG, X86_XMMREG, 15, 64},
- {"xmm10", REG, X86_XMMREG, 10, 64},
- {"es", SEGREG, 0x26, 0x00, 64},
- {"cr8", REG, X86_CRREG, 8, 64},
- {"xmm7", REG, X86_XMMREG, 7, 0},
- {"spl", REG, X86_REG8X, 4, 64},
- {"r15", REG, X86_REG64, 15, 64},
- {"cr4", REG, X86_CRREG, 4, 0},
- {"fs", SEGREG, 0x64, 0x04, 0},
- {"rcx", REG, X86_REG64, 1, 64},
- {"mm0", REG, X86_MMXREG, 0, 0},
- {"mm", REGGROUP, 0, X86_MMXREG, 0},
- {"tr1", REG, X86_TRREG, 1, 0},
- {"short", TARGETMOD, 0, X86_SHORT, 0},
- {"st4", REG, X86_FPUREG, 4, 0},
- {"cr0", REG, X86_CRREG, 0, 0},
- {"xmm11", REG, X86_XMMREG, 11, 64},
- {"mm4", REG, X86_MMXREG, 4, 0},
- {"bh", REG, X86_REG8, 7, 0},
- {"r15d", REG, X86_REG32, 15, 64},
- {"dr2", REG, X86_DRREG, 2, 0},
- {"r8d", REG, X86_REG32, 8, 64},
- {"ymm7", REG, X86_YMMREG, 7, 0},
- {"xmm9", REG, X86_XMMREG, 9, 64},
- {"r12b", REG, X86_REG8, 12, 64},
- {"st2", REG, X86_FPUREG, 2, 0},
- {"ymm9", REG, X86_YMMREG, 9, 64},
- {"st7", REG, X86_FPUREG, 7, 0},
- {"bx", REG, X86_REG16, 3, 0},
- {"ymm11", REG, X86_YMMREG, 11, 64},
- {"ymm5", REG, X86_YMMREG, 5, 0},
- {"ymm15", REG, X86_YMMREG, 15, 64},
- {"rbp", REG, X86_REG64, 5, 64},
- {"r13", REG, X86_REG64, 13, 64},
- {"mm5", REG, X86_MMXREG, 5, 0},
- {"si", REG, X86_REG16, 6, 0},
- {"dl", REG, X86_REG8, 2, 0},
- {"di", REG, X86_REG16, 7, 0},
- {"cr2", REG, X86_CRREG, 2, 0},
- {"r14d", REG, X86_REG32, 14, 64},
- {"ymm14", REG, X86_YMMREG, 14, 64},
- {"tr7", REG, X86_TRREG, 7, 0},
- {"ds", SEGREG, 0x3e, 0x03, 64},
- {"cx", REG, X86_REG16, 1, 0},
- {"st", REGGROUP, 0, X86_FPUREG, 0},
- {"edi", REG, X86_REG32, 7, 0},
- {"al", REG, X86_REG8, 0, 0},
- {"mm7", REG, X86_MMXREG, 7, 0},
- {"ebx", REG, X86_REG32, 3, 0},
- {"xmm2", REG, X86_XMMREG, 2, 0},
- {"st5", REG, X86_FPUREG, 5, 0},
- {"rip", REG, X86_RIP, 0, 64},
- {"rbx", REG, X86_REG64, 3, 64},
- {"to", TARGETMOD, 0, X86_TO, 0},
- {"r11d", REG, X86_REG32, 11, 64},
- {"dr5", REG, X86_DRREG, 5, 0},
- {"dr1", REG, X86_DRREG, 1, 0},
- {"near", TARGETMOD, 0, X86_NEAR, 0},
- {"r14", REG, X86_REG64, 14, 64},
- {"dh", REG, X86_REG8, 6, 0},
- {"cl", REG, X86_REG8, 1, 0},
- {"dr4", REG, X86_DRREG, 4, 0},
- {"ymm10", REG, X86_YMMREG, 10, 64},
- {"dr3", REG, X86_DRREG, 3, 0},
- {"xmm5", REG, X86_XMMREG, 5, 0},
- {"mm6", REG, X86_MMXREG, 6, 0},
- {"r13w", REG, X86_REG16, 13, 64},
- {"far", TARGETMOD, 0, X86_FAR, 0},
- {"ymm0", REG, X86_YMMREG, 0, 0},
- {"ymm", REGGROUP, 0, X86_YMMREG, 0},
- {"ch", REG, X86_REG8, 5, 0},
- {"xmm1", REG, X86_XMMREG, 1, 0},
- {"esi", REG, X86_REG32, 6, 0},
- {"r14b", REG, X86_REG8, 14, 64},
- {"st1", REG, X86_FPUREG, 1, 0},
- {"r8b", REG, X86_REG8, 8, 64},
- {"r11b", REG, X86_REG8, 11, 64},
- {"r13b", REG, X86_REG8, 13, 64},
- {"ecx", REG, X86_REG32, 1, 0},
- {"tr2", REG, X86_TRREG, 2, 0},
- {"rdx", REG, X86_REG64, 2, 64},
- {"r9d", REG, X86_REG32, 9, 64},
- {"cs", SEGREG, 0x2e, 0x01, 0},
- {"dr0", REG, X86_DRREG, 0, 0},
- {"edx", REG, X86_REG32, 2, 0}
- };
- static const unsigned char tab[] = {
- 0,0,125,22,0,0,85,0,85,168,0,0,0,7,113,0,
- 0,0,0,22,183,0,0,11,42,55,0,0,82,0,88,235,
- 0,0,0,0,0,0,183,85,0,0,145,113,220,125,22,0,
- 88,183,0,7,0,0,0,7,0,125,113,87,131,116,7,0,
- 113,7,0,113,0,87,87,7,7,7,113,40,85,125,113,85,
- 0,0,22,235,0,131,125,113,0,22,0,220,0,220,0,120,
- 116,0,124,184,0,0,0,183,92,125,0,92,125,0,0,177,
- 7,0,0,7,0,45,0,214,180,113,211,163,142,0,88,173,
- };
- const struct regtmod_parse_data *ret;
- unsigned long rsl, val = phash_lookup(key, len, 0x9e3779b9UL);
- rsl = ((val>>25)^tab[val&0x7f]);
- if (rsl >= 152) return NULL;
- ret = &pd[rsl];
- if (strcmp(key, ret->name) != 0) return NULL;
- return ret;
- }
- yasm_arch_regtmod
- yasm_x86__parse_check_regtmod(yasm_arch *arch, const char *id, size_t id_len,
- uintptr_t *data)
- {
- yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
- /*@null@*/ const struct regtmod_parse_data *pdata;
- size_t i;
- static char lcaseid[8];
- unsigned int bits;
- yasm_arch_regtmod type;
- if (id_len > 7)
- return YASM_ARCH_NOTREGTMOD;
- for (i=0; i<id_len; i++)
- lcaseid[i] = tolower(id[i]);
- lcaseid[id_len] = '\0';
- pdata = regtmod_find(lcaseid, id_len);
- if (!pdata)
- return YASM_ARCH_NOTREGTMOD;
- type = (yasm_arch_regtmod)pdata->type;
- bits = pdata->bits;
- if (type == YASM_ARCH_REG && bits != 0 && arch_x86->mode_bits != bits) {
- yasm_warn_set(YASM_WARN_GENERAL,
- N_("`%s' is a register in %u-bit mode"), id, bits);
- return YASM_ARCH_NOTREGTMOD;
- }
- if (type == YASM_ARCH_SEGREG && bits != 0 && arch_x86->mode_bits == bits) {
- yasm_warn_set(YASM_WARN_GENERAL,
- N_("`%s' segment register ignored in %u-bit mode"), id,
- bits);
- }
- if (type == YASM_ARCH_SEGREG)
- *data = (pdata->size_prefix<<8) | pdata->data;
- else
- *data = pdata->size_prefix | pdata->data;
- return type;
- }
|