blob: c259877842a89e39da226697680848b13dc14f11 [file] [log] [blame]
#
# 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,v 1.1.1.1 2012/03/29 17:21:00 uid42307 Exp $");
#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;
}