diff options
Diffstat (limited to 'modules/arch/x86/x86regtmod.gperf')
-rw-r--r-- | modules/arch/x86/x86regtmod.gperf | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/modules/arch/x86/x86regtmod.gperf b/modules/arch/x86/x86regtmod.gperf new file mode 100644 index 00000000..a5763432 --- /dev/null +++ b/modules/arch/x86/x86regtmod.gperf @@ -0,0 +1,280 @@ +# +# x86 register and target modifier recognition +# +# Copyright (C) 2002-2007 Peter Johnson +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +%{ +#include <util.h> +RCSID("$Id$"); + +#include <ctype.h> +#include <libyasm.h> +#include <libyasm/phash.h> + +#include "modules/arch/x86/x86arch.h" + +enum regtmod_type { + REG = 1, + REGGROUP, + SEGREG, + TARGETMOD +}; +%} +%ignore-case +%language=ANSI-C +%compare-strncmp +%readonly-tables +%enum +%struct-type +%define hash-function-name regtmod_hash +%define lookup-function-name regtmod_find +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; +}; +%% +# +# control, debug, and test registers +# +cr0, REG, X86_CRREG, 0, 0 +cr2, REG, X86_CRREG, 2, 0 +cr3, REG, X86_CRREG, 3, 0 +cr4, REG, X86_CRREG, 4, 0 +cr8, REG, X86_CRREG, 8, 64 +# +dr0, REG, X86_DRREG, 0, 0 +dr1, REG, X86_DRREG, 1, 0 +dr2, REG, X86_DRREG, 2, 0 +dr3, REG, X86_DRREG, 3, 0 +dr4, REG, X86_DRREG, 4, 0 +dr5, REG, X86_DRREG, 5, 0 +dr6, REG, X86_DRREG, 6, 0 +dr7, REG, X86_DRREG, 7, 0 +# +tr0, REG, X86_TRREG, 0, 0 +tr1, REG, X86_TRREG, 1, 0 +tr2, REG, X86_TRREG, 2, 0 +tr3, REG, X86_TRREG, 3, 0 +tr4, REG, X86_TRREG, 4, 0 +tr5, REG, X86_TRREG, 5, 0 +tr6, REG, X86_TRREG, 6, 0 +tr7, REG, X86_TRREG, 7, 0 +# +# floating point, MMX, and SSE/SSE2 registers +# +st0, REG, X86_FPUREG, 0, 0 +st1, REG, X86_FPUREG, 1, 0 +st2, REG, X86_FPUREG, 2, 0 +st3, REG, X86_FPUREG, 3, 0 +st4, REG, X86_FPUREG, 4, 0 +st5, REG, X86_FPUREG, 5, 0 +st6, REG, X86_FPUREG, 6, 0 +st7, REG, X86_FPUREG, 7, 0 +# +mm0, REG, X86_MMXREG, 0, 0 +mm1, REG, X86_MMXREG, 1, 0 +mm2, REG, X86_MMXREG, 2, 0 +mm3, REG, X86_MMXREG, 3, 0 +mm4, REG, X86_MMXREG, 4, 0 +mm5, REG, X86_MMXREG, 5, 0 +mm6, REG, X86_MMXREG, 6, 0 +mm7, REG, X86_MMXREG, 7, 0 +# +xmm0, REG, X86_XMMREG, 0, 0 +xmm1, REG, X86_XMMREG, 1, 0 +xmm2, REG, X86_XMMREG, 2, 0 +xmm3, REG, X86_XMMREG, 3, 0 +xmm4, REG, X86_XMMREG, 4, 0 +xmm5, REG, X86_XMMREG, 5, 0 +xmm6, REG, X86_XMMREG, 6, 0 +xmm7, REG, X86_XMMREG, 7, 0 +xmm8, REG, X86_XMMREG, 8, 64 +xmm9, REG, X86_XMMREG, 9, 64 +xmm10, REG, X86_XMMREG, 10, 64 +xmm11, REG, X86_XMMREG, 11, 64 +xmm12, REG, X86_XMMREG, 12, 64 +xmm13, REG, X86_XMMREG, 13, 64 +xmm14, REG, X86_XMMREG, 14, 64 +xmm15, REG, X86_XMMREG, 15, 64 +# +# integer registers +# +rax, REG, X86_REG64, 0, 64 +rcx, REG, X86_REG64, 1, 64 +rdx, REG, X86_REG64, 2, 64 +rbx, REG, X86_REG64, 3, 64 +rsp, REG, X86_REG64, 4, 64 +rbp, REG, X86_REG64, 5, 64 +rsi, REG, X86_REG64, 6, 64 +rdi, REG, X86_REG64, 7, 64 +r8, REG, X86_REG64, 8, 64 +r9, REG, X86_REG64, 9, 64 +r10, REG, X86_REG64, 10, 64 +r11, REG, X86_REG64, 11, 64 +r12, REG, X86_REG64, 12, 64 +r13, REG, X86_REG64, 13, 64 +r14, REG, X86_REG64, 14, 64 +r15, REG, X86_REG64, 15, 64 +# +eax, REG, X86_REG32, 0, 0 +ecx, REG, X86_REG32, 1, 0 +edx, REG, X86_REG32, 2, 0 +ebx, REG, X86_REG32, 3, 0 +esp, REG, X86_REG32, 4, 0 +ebp, REG, X86_REG32, 5, 0 +esi, REG, X86_REG32, 6, 0 +edi, REG, X86_REG32, 7, 0 +r8d, REG, X86_REG32, 8, 64 +r9d, REG, X86_REG32, 9, 64 +r10d, REG, X86_REG32, 10, 64 +r11d, REG, X86_REG32, 11, 64 +r12d, REG, X86_REG32, 12, 64 +r13d, REG, X86_REG32, 13, 64 +r14d, REG, X86_REG32, 14, 64 +r15d, REG, X86_REG32, 15, 64 +# +ax, REG, X86_REG16, 0, 0 +cx, REG, X86_REG16, 1, 0 +dx, REG, X86_REG16, 2, 0 +bx, REG, X86_REG16, 3, 0 +sp, REG, X86_REG16, 4, 0 +bp, REG, X86_REG16, 5, 0 +si, REG, X86_REG16, 6, 0 +di, REG, X86_REG16, 7, 0 +r8w, REG, X86_REG16, 8, 64 +r9w, REG, X86_REG16, 9, 64 +r10w, REG, X86_REG16, 10, 64 +r11w, REG, X86_REG16, 11, 64 +r12w, REG, X86_REG16, 12, 64 +r13w, REG, X86_REG16, 13, 64 +r14w, REG, X86_REG16, 14, 64 +r15w, REG, X86_REG16, 15, 64 +# +al, REG, X86_REG8, 0, 0 +cl, REG, X86_REG8, 1, 0 +dl, REG, X86_REG8, 2, 0 +bl, REG, X86_REG8, 3, 0 +ah, REG, X86_REG8, 4, 0 +ch, REG, X86_REG8, 5, 0 +dh, REG, X86_REG8, 6, 0 +bh, REG, X86_REG8, 7, 0 +r8b, REG, X86_REG8, 8, 64 +r9b, REG, X86_REG8, 9, 64 +r10b, REG, X86_REG8, 10, 64 +r11b, REG, X86_REG8, 11, 64 +r12b, REG, X86_REG8, 12, 64 +r13b, REG, X86_REG8, 13, 64 +r14b, REG, X86_REG8, 14, 64 +r15b, REG, X86_REG8, 15, 64 +# +spl, REG, X86_REG8X, 4, 64 +bpl, REG, X86_REG8X, 5, 64 +sil, REG, X86_REG8X, 6, 64 +dil, REG, X86_REG8X, 7, 64 +# +rip, REG, X86_RIP, 0, 64 +# +# floating point, MMX, and SSE/SSE2 registers +# +st, REGGROUP, 0, X86_FPUREG, 0 +mm, REGGROUP, 0, X86_MMXREG, 0 +xmm, REGGROUP, 0, X86_XMMREG, 0 +# +# segment registers +# +es, SEGREG, 0x26, 0x00, 64 +cs, SEGREG, 0x2e, 0x01, 0 +ss, SEGREG, 0x36, 0x02, 64 +ds, SEGREG, 0x3e, 0x03, 64 +fs, SEGREG, 0x64, 0x04, 0 +gs, SEGREG, 0x65, 0x05, 0 +# +# target modifiers +# +near, TARGETMOD, 0, X86_NEAR, 0 +short, TARGETMOD, 0, X86_SHORT, 0 +far, TARGETMOD, 0, X86_FAR, 0 +to, TARGETMOD, 0, X86_TO, 0 +%% + +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; +} |