summaryrefslogtreecommitdiff
path: root/modules/arch/x86/x86regtmod.gperf
diff options
context:
space:
mode:
Diffstat (limited to 'modules/arch/x86/x86regtmod.gperf')
-rw-r--r--modules/arch/x86/x86regtmod.gperf280
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;
+}