11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2eb13296cSMasami Hiramatsu /*
3eb13296cSMasami Hiramatsu * x86 instruction attribute tables
4eb13296cSMasami Hiramatsu *
5eb13296cSMasami Hiramatsu * Written by Masami Hiramatsu <mhiramat@redhat.com>
6eb13296cSMasami Hiramatsu */
7*d30c7b82SBorislav Petkov #include <asm/insn.h> /* __ignore_sync_check__ */
8eb13296cSMasami Hiramatsu
9eb13296cSMasami Hiramatsu /* Attribute tables are generated from opcode map */
10eb13296cSMasami Hiramatsu #include "inat-tables.c"
11eb13296cSMasami Hiramatsu
12eb13296cSMasami Hiramatsu /* Attribute search APIs */
inat_get_opcode_attribute(insn_byte_t opcode)13eb13296cSMasami Hiramatsu insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
14eb13296cSMasami Hiramatsu {
15eb13296cSMasami Hiramatsu return inat_primary_table[opcode];
16eb13296cSMasami Hiramatsu }
17eb13296cSMasami Hiramatsu
inat_get_last_prefix_id(insn_byte_t last_pfx)18f8d98f10SMasami Hiramatsu int inat_get_last_prefix_id(insn_byte_t last_pfx)
19f8d98f10SMasami Hiramatsu {
20f8d98f10SMasami Hiramatsu insn_attr_t lpfx_attr;
21f8d98f10SMasami Hiramatsu
22f8d98f10SMasami Hiramatsu lpfx_attr = inat_get_opcode_attribute(last_pfx);
23f8d98f10SMasami Hiramatsu return inat_last_prefix_id(lpfx_attr);
24f8d98f10SMasami Hiramatsu }
25f8d98f10SMasami Hiramatsu
inat_get_escape_attribute(insn_byte_t opcode,int lpfx_id,insn_attr_t esc_attr)26f8d98f10SMasami Hiramatsu insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id,
27eb13296cSMasami Hiramatsu insn_attr_t esc_attr)
28eb13296cSMasami Hiramatsu {
29eb13296cSMasami Hiramatsu const insn_attr_t *table;
30f8d98f10SMasami Hiramatsu int n;
31eb13296cSMasami Hiramatsu
32eb13296cSMasami Hiramatsu n = inat_escape_id(esc_attr);
33f8d98f10SMasami Hiramatsu
34eb13296cSMasami Hiramatsu table = inat_escape_tables[n][0];
35eb13296cSMasami Hiramatsu if (!table)
36eb13296cSMasami Hiramatsu return 0;
37f8d98f10SMasami Hiramatsu if (inat_has_variant(table[opcode]) && lpfx_id) {
38f8d98f10SMasami Hiramatsu table = inat_escape_tables[n][lpfx_id];
39eb13296cSMasami Hiramatsu if (!table)
40eb13296cSMasami Hiramatsu return 0;
41eb13296cSMasami Hiramatsu }
42eb13296cSMasami Hiramatsu return table[opcode];
43eb13296cSMasami Hiramatsu }
44eb13296cSMasami Hiramatsu
inat_get_group_attribute(insn_byte_t modrm,int lpfx_id,insn_attr_t grp_attr)45f8d98f10SMasami Hiramatsu insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id,
46eb13296cSMasami Hiramatsu insn_attr_t grp_attr)
47eb13296cSMasami Hiramatsu {
48eb13296cSMasami Hiramatsu const insn_attr_t *table;
49f8d98f10SMasami Hiramatsu int n;
50eb13296cSMasami Hiramatsu
51eb13296cSMasami Hiramatsu n = inat_group_id(grp_attr);
52f8d98f10SMasami Hiramatsu
53eb13296cSMasami Hiramatsu table = inat_group_tables[n][0];
54eb13296cSMasami Hiramatsu if (!table)
55eb13296cSMasami Hiramatsu return inat_group_common_attribute(grp_attr);
56f8d98f10SMasami Hiramatsu if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) {
57f8d98f10SMasami Hiramatsu table = inat_group_tables[n][lpfx_id];
58eb13296cSMasami Hiramatsu if (!table)
59eb13296cSMasami Hiramatsu return inat_group_common_attribute(grp_attr);
60eb13296cSMasami Hiramatsu }
61eb13296cSMasami Hiramatsu return table[X86_MODRM_REG(modrm)] |
62eb13296cSMasami Hiramatsu inat_group_common_attribute(grp_attr);
63eb13296cSMasami Hiramatsu }
64eb13296cSMasami Hiramatsu
inat_get_avx_attribute(insn_byte_t opcode,insn_byte_t vex_m,insn_byte_t vex_p)65e0e492e9SMasami Hiramatsu insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m,
66e0e492e9SMasami Hiramatsu insn_byte_t vex_p)
67e0e492e9SMasami Hiramatsu {
68e0e492e9SMasami Hiramatsu const insn_attr_t *table;
69e0e492e9SMasami Hiramatsu if (vex_m > X86_VEX_M_MAX || vex_p > INAT_LSTPFX_MAX)
70e0e492e9SMasami Hiramatsu return 0;
71130b78b2SMasami Hiramatsu /* At first, this checks the master table */
72130b78b2SMasami Hiramatsu table = inat_avx_tables[vex_m][0];
73130b78b2SMasami Hiramatsu if (!table)
74130b78b2SMasami Hiramatsu return 0;
75130b78b2SMasami Hiramatsu if (!inat_is_group(table[opcode]) && vex_p) {
76130b78b2SMasami Hiramatsu /* If this is not a group, get attribute directly */
77e0e492e9SMasami Hiramatsu table = inat_avx_tables[vex_m][vex_p];
78e0e492e9SMasami Hiramatsu if (!table)
79e0e492e9SMasami Hiramatsu return 0;
80130b78b2SMasami Hiramatsu }
81e0e492e9SMasami Hiramatsu return table[opcode];
82e0e492e9SMasami Hiramatsu }
83e0e492e9SMasami Hiramatsu
84