299 lines
7.9 KiB
Plaintext
299 lines
7.9 KiB
Plaintext
|
#
|
||
|
# 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: x86regtmod.gperf 2062 2008-04-12 01:34:30Z peter $");
|
||
|
|
||
|
#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
|
||
|
# AVX registers
|
||
|
ymm0, REG, X86_YMMREG, 0, 0
|
||
|
ymm1, REG, X86_YMMREG, 1, 0
|
||
|
ymm2, REG, X86_YMMREG, 2, 0
|
||
|
ymm3, REG, X86_YMMREG, 3, 0
|
||
|
ymm4, REG, X86_YMMREG, 4, 0
|
||
|
ymm5, REG, X86_YMMREG, 5, 0
|
||
|
ymm6, REG, X86_YMMREG, 6, 0
|
||
|
ymm7, REG, X86_YMMREG, 7, 0
|
||
|
ymm8, REG, X86_YMMREG, 8, 64
|
||
|
ymm9, REG, X86_YMMREG, 9, 64
|
||
|
ymm10, REG, X86_YMMREG, 10, 64
|
||
|
ymm11, REG, X86_YMMREG, 11, 64
|
||
|
ymm12, REG, X86_YMMREG, 12, 64
|
||
|
ymm13, REG, X86_YMMREG, 13, 64
|
||
|
ymm14, REG, X86_YMMREG, 14, 64
|
||
|
ymm15, REG, X86_YMMREG, 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
|
||
|
ymm, REGGROUP, 0, X86_YMMREG, 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;
|
||
|
}
|