x86: Instruction decoder API
Add x86 instruction decoder to arch-specific libraries. This decoder
can decode x86 instructions used in kernel into prefix, opcode, modrm,
sib, displacement and immediates. This can also show the length of
instructions.
This version introduces instruction attributes for decoding
instructions.
The instruction attribute tables are generated from the opcode map file
(x86-opcode-map.txt) by the generator script(gen-insn-attr-x86.awk).
Currently, the opcode maps are based on opcode maps in Intel(R) 64 and
IA-32 Architectures Software Developers Manual Vol.2: Appendix.A,
and consist of below two types of opcode tables.
1-byte/2-bytes/3-bytes opcodes, which has 256 elements, are
written as below;
Table: table-name
Referrer: escaped-name
opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
(or)
opcode: escape # escaped-name
EndTable
Group opcodes, which has 8 elements, are written as below;
GrpTable: GrpXXX
reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
EndTable
These opcode maps include a few SSE and FP opcodes (for setup), because
those opcodes are used in the kernel.
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Signed-off-by: Jim Keniston <jkenisto@us.ibm.com>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Avi Kivity <avi@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Jason Baron <jbaron@redhat.com>
Cc: K.Prasad <prasad@linux.vnet.ibm.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Przemysław Pawełczyk <przemyslaw@pawelczyk.it>
Cc: Roland McGrath <roland@redhat.com>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Vegard Nossum <vegard.nossum@gmail.com>
LKML-Reference: <20090813203413.31965.49709.stgit@localhost.localdomain>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
2009-08-13 20:34:13 +00:00
|
|
|
/*
|
|
|
|
* x86 instruction attribute tables
|
|
|
|
*
|
|
|
|
* Written by Masami Hiramatsu <mhiramat@redhat.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include <asm/insn.h>
|
|
|
|
|
|
|
|
/* Attribute tables are generated from opcode map */
|
|
|
|
#include "inat-tables.c"
|
|
|
|
|
|
|
|
/* Attribute search APIs */
|
|
|
|
insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
|
|
|
|
{
|
|
|
|
return inat_primary_table[opcode];
|
|
|
|
}
|
|
|
|
|
|
|
|
insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, insn_byte_t last_pfx,
|
|
|
|
insn_attr_t esc_attr)
|
|
|
|
{
|
|
|
|
const insn_attr_t *table;
|
|
|
|
insn_attr_t lpfx_attr;
|
|
|
|
int n, m = 0;
|
|
|
|
|
|
|
|
n = inat_escape_id(esc_attr);
|
|
|
|
if (last_pfx) {
|
|
|
|
lpfx_attr = inat_get_opcode_attribute(last_pfx);
|
|
|
|
m = inat_last_prefix_id(lpfx_attr);
|
|
|
|
}
|
|
|
|
table = inat_escape_tables[n][0];
|
|
|
|
if (!table)
|
|
|
|
return 0;
|
|
|
|
if (inat_has_variant(table[opcode]) && m) {
|
|
|
|
table = inat_escape_tables[n][m];
|
|
|
|
if (!table)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return table[opcode];
|
|
|
|
}
|
|
|
|
|
|
|
|
insn_attr_t inat_get_group_attribute(insn_byte_t modrm, insn_byte_t last_pfx,
|
|
|
|
insn_attr_t grp_attr)
|
|
|
|
{
|
|
|
|
const insn_attr_t *table;
|
|
|
|
insn_attr_t lpfx_attr;
|
|
|
|
int n, m = 0;
|
|
|
|
|
|
|
|
n = inat_group_id(grp_attr);
|
|
|
|
if (last_pfx) {
|
|
|
|
lpfx_attr = inat_get_opcode_attribute(last_pfx);
|
|
|
|
m = inat_last_prefix_id(lpfx_attr);
|
|
|
|
}
|
|
|
|
table = inat_group_tables[n][0];
|
|
|
|
if (!table)
|
|
|
|
return inat_group_common_attribute(grp_attr);
|
|
|
|
if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && m) {
|
2009-10-20 16:55:24 +00:00
|
|
|
table = inat_group_tables[n][m];
|
x86: Instruction decoder API
Add x86 instruction decoder to arch-specific libraries. This decoder
can decode x86 instructions used in kernel into prefix, opcode, modrm,
sib, displacement and immediates. This can also show the length of
instructions.
This version introduces instruction attributes for decoding
instructions.
The instruction attribute tables are generated from the opcode map file
(x86-opcode-map.txt) by the generator script(gen-insn-attr-x86.awk).
Currently, the opcode maps are based on opcode maps in Intel(R) 64 and
IA-32 Architectures Software Developers Manual Vol.2: Appendix.A,
and consist of below two types of opcode tables.
1-byte/2-bytes/3-bytes opcodes, which has 256 elements, are
written as below;
Table: table-name
Referrer: escaped-name
opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
(or)
opcode: escape # escaped-name
EndTable
Group opcodes, which has 8 elements, are written as below;
GrpTable: GrpXXX
reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
EndTable
These opcode maps include a few SSE and FP opcodes (for setup), because
those opcodes are used in the kernel.
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Signed-off-by: Jim Keniston <jkenisto@us.ibm.com>
Acked-by: H. Peter Anvin <hpa@zytor.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Avi Kivity <avi@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Jason Baron <jbaron@redhat.com>
Cc: K.Prasad <prasad@linux.vnet.ibm.com>
Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Przemysław Pawełczyk <przemyslaw@pawelczyk.it>
Cc: Roland McGrath <roland@redhat.com>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Vegard Nossum <vegard.nossum@gmail.com>
LKML-Reference: <20090813203413.31965.49709.stgit@localhost.localdomain>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
2009-08-13 20:34:13 +00:00
|
|
|
if (!table)
|
|
|
|
return inat_group_common_attribute(grp_attr);
|
|
|
|
}
|
|
|
|
return table[X86_MODRM_REG(modrm)] |
|
|
|
|
inat_group_common_attribute(grp_attr);
|
|
|
|
}
|
|
|
|
|
2009-10-27 20:42:27 +00:00
|
|
|
insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m,
|
|
|
|
insn_byte_t vex_p)
|
|
|
|
{
|
|
|
|
const insn_attr_t *table;
|
|
|
|
if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX)
|
|
|
|
return 0;
|
|
|
|
table = inat_avx_tables[vex_m][vex_p];
|
|
|
|
if (!table)
|
|
|
|
return 0;
|
|
|
|
return table[opcode];
|
|
|
|
}
|
|
|
|
|