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