xref: /OK3568_Linux_fs/kernel/arch/x86/include/asm/inat.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun #ifndef _ASM_X86_INAT_H
3*4882a593Smuzhiyun #define _ASM_X86_INAT_H
4*4882a593Smuzhiyun /*
5*4882a593Smuzhiyun  * x86 instruction attributes
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Written by Masami Hiramatsu <mhiramat@redhat.com>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun #include <asm/inat_types.h> /* __ignore_sync_check__ */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /*
12*4882a593Smuzhiyun  * Internal bits. Don't use bitmasks directly, because these bits are
13*4882a593Smuzhiyun  * unstable. You should use checking functions.
14*4882a593Smuzhiyun  */
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define INAT_OPCODE_TABLE_SIZE 256
17*4882a593Smuzhiyun #define INAT_GROUP_TABLE_SIZE 8
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /* Legacy last prefixes */
20*4882a593Smuzhiyun #define INAT_PFX_OPNDSZ	1	/* 0x66 */ /* LPFX1 */
21*4882a593Smuzhiyun #define INAT_PFX_REPE	2	/* 0xF3 */ /* LPFX2 */
22*4882a593Smuzhiyun #define INAT_PFX_REPNE	3	/* 0xF2 */ /* LPFX3 */
23*4882a593Smuzhiyun /* Other Legacy prefixes */
24*4882a593Smuzhiyun #define INAT_PFX_LOCK	4	/* 0xF0 */
25*4882a593Smuzhiyun #define INAT_PFX_CS	5	/* 0x2E */
26*4882a593Smuzhiyun #define INAT_PFX_DS	6	/* 0x3E */
27*4882a593Smuzhiyun #define INAT_PFX_ES	7	/* 0x26 */
28*4882a593Smuzhiyun #define INAT_PFX_FS	8	/* 0x64 */
29*4882a593Smuzhiyun #define INAT_PFX_GS	9	/* 0x65 */
30*4882a593Smuzhiyun #define INAT_PFX_SS	10	/* 0x36 */
31*4882a593Smuzhiyun #define INAT_PFX_ADDRSZ	11	/* 0x67 */
32*4882a593Smuzhiyun /* x86-64 REX prefix */
33*4882a593Smuzhiyun #define INAT_PFX_REX	12	/* 0x4X */
34*4882a593Smuzhiyun /* AVX VEX prefixes */
35*4882a593Smuzhiyun #define INAT_PFX_VEX2	13	/* 2-bytes VEX prefix */
36*4882a593Smuzhiyun #define INAT_PFX_VEX3	14	/* 3-bytes VEX prefix */
37*4882a593Smuzhiyun #define INAT_PFX_EVEX	15	/* EVEX prefix */
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define INAT_LSTPFX_MAX	3
40*4882a593Smuzhiyun #define INAT_LGCPFX_MAX	11
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /* Immediate size */
43*4882a593Smuzhiyun #define INAT_IMM_BYTE		1
44*4882a593Smuzhiyun #define INAT_IMM_WORD		2
45*4882a593Smuzhiyun #define INAT_IMM_DWORD		3
46*4882a593Smuzhiyun #define INAT_IMM_QWORD		4
47*4882a593Smuzhiyun #define INAT_IMM_PTR		5
48*4882a593Smuzhiyun #define INAT_IMM_VWORD32	6
49*4882a593Smuzhiyun #define INAT_IMM_VWORD		7
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun /* Legacy prefix */
52*4882a593Smuzhiyun #define INAT_PFX_OFFS	0
53*4882a593Smuzhiyun #define INAT_PFX_BITS	4
54*4882a593Smuzhiyun #define INAT_PFX_MAX    ((1 << INAT_PFX_BITS) - 1)
55*4882a593Smuzhiyun #define INAT_PFX_MASK	(INAT_PFX_MAX << INAT_PFX_OFFS)
56*4882a593Smuzhiyun /* Escape opcodes */
57*4882a593Smuzhiyun #define INAT_ESC_OFFS	(INAT_PFX_OFFS + INAT_PFX_BITS)
58*4882a593Smuzhiyun #define INAT_ESC_BITS	2
59*4882a593Smuzhiyun #define INAT_ESC_MAX	((1 << INAT_ESC_BITS) - 1)
60*4882a593Smuzhiyun #define INAT_ESC_MASK	(INAT_ESC_MAX << INAT_ESC_OFFS)
61*4882a593Smuzhiyun /* Group opcodes (1-16) */
62*4882a593Smuzhiyun #define INAT_GRP_OFFS	(INAT_ESC_OFFS + INAT_ESC_BITS)
63*4882a593Smuzhiyun #define INAT_GRP_BITS	5
64*4882a593Smuzhiyun #define INAT_GRP_MAX	((1 << INAT_GRP_BITS) - 1)
65*4882a593Smuzhiyun #define INAT_GRP_MASK	(INAT_GRP_MAX << INAT_GRP_OFFS)
66*4882a593Smuzhiyun /* Immediates */
67*4882a593Smuzhiyun #define INAT_IMM_OFFS	(INAT_GRP_OFFS + INAT_GRP_BITS)
68*4882a593Smuzhiyun #define INAT_IMM_BITS	3
69*4882a593Smuzhiyun #define INAT_IMM_MASK	(((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS)
70*4882a593Smuzhiyun /* Flags */
71*4882a593Smuzhiyun #define INAT_FLAG_OFFS	(INAT_IMM_OFFS + INAT_IMM_BITS)
72*4882a593Smuzhiyun #define INAT_MODRM	(1 << (INAT_FLAG_OFFS))
73*4882a593Smuzhiyun #define INAT_FORCE64	(1 << (INAT_FLAG_OFFS + 1))
74*4882a593Smuzhiyun #define INAT_SCNDIMM	(1 << (INAT_FLAG_OFFS + 2))
75*4882a593Smuzhiyun #define INAT_MOFFSET	(1 << (INAT_FLAG_OFFS + 3))
76*4882a593Smuzhiyun #define INAT_VARIANT	(1 << (INAT_FLAG_OFFS + 4))
77*4882a593Smuzhiyun #define INAT_VEXOK	(1 << (INAT_FLAG_OFFS + 5))
78*4882a593Smuzhiyun #define INAT_VEXONLY	(1 << (INAT_FLAG_OFFS + 6))
79*4882a593Smuzhiyun #define INAT_EVEXONLY	(1 << (INAT_FLAG_OFFS + 7))
80*4882a593Smuzhiyun /* Attribute making macros for attribute tables */
81*4882a593Smuzhiyun #define INAT_MAKE_PREFIX(pfx)	(pfx << INAT_PFX_OFFS)
82*4882a593Smuzhiyun #define INAT_MAKE_ESCAPE(esc)	(esc << INAT_ESC_OFFS)
83*4882a593Smuzhiyun #define INAT_MAKE_GROUP(grp)	((grp << INAT_GRP_OFFS) | INAT_MODRM)
84*4882a593Smuzhiyun #define INAT_MAKE_IMM(imm)	(imm << INAT_IMM_OFFS)
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun /* Identifiers for segment registers */
87*4882a593Smuzhiyun #define INAT_SEG_REG_IGNORE	0
88*4882a593Smuzhiyun #define INAT_SEG_REG_DEFAULT	1
89*4882a593Smuzhiyun #define INAT_SEG_REG_CS		2
90*4882a593Smuzhiyun #define INAT_SEG_REG_SS		3
91*4882a593Smuzhiyun #define INAT_SEG_REG_DS		4
92*4882a593Smuzhiyun #define INAT_SEG_REG_ES		5
93*4882a593Smuzhiyun #define INAT_SEG_REG_FS		6
94*4882a593Smuzhiyun #define INAT_SEG_REG_GS		7
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun /* Attribute search APIs */
97*4882a593Smuzhiyun extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
98*4882a593Smuzhiyun extern int inat_get_last_prefix_id(insn_byte_t last_pfx);
99*4882a593Smuzhiyun extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode,
100*4882a593Smuzhiyun 					     int lpfx_id,
101*4882a593Smuzhiyun 					     insn_attr_t esc_attr);
102*4882a593Smuzhiyun extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm,
103*4882a593Smuzhiyun 					    int lpfx_id,
104*4882a593Smuzhiyun 					    insn_attr_t esc_attr);
105*4882a593Smuzhiyun extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode,
106*4882a593Smuzhiyun 					  insn_byte_t vex_m,
107*4882a593Smuzhiyun 					  insn_byte_t vex_pp);
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun /* Attribute checking functions */
inat_is_legacy_prefix(insn_attr_t attr)110*4882a593Smuzhiyun static inline int inat_is_legacy_prefix(insn_attr_t attr)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun 	attr &= INAT_PFX_MASK;
113*4882a593Smuzhiyun 	return attr && attr <= INAT_LGCPFX_MAX;
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun 
inat_is_address_size_prefix(insn_attr_t attr)116*4882a593Smuzhiyun static inline int inat_is_address_size_prefix(insn_attr_t attr)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun 	return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ;
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun 
inat_is_operand_size_prefix(insn_attr_t attr)121*4882a593Smuzhiyun static inline int inat_is_operand_size_prefix(insn_attr_t attr)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun 	return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun 
inat_is_rex_prefix(insn_attr_t attr)126*4882a593Smuzhiyun static inline int inat_is_rex_prefix(insn_attr_t attr)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun 	return (attr & INAT_PFX_MASK) == INAT_PFX_REX;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun 
inat_last_prefix_id(insn_attr_t attr)131*4882a593Smuzhiyun static inline int inat_last_prefix_id(insn_attr_t attr)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun 	if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX)
134*4882a593Smuzhiyun 		return 0;
135*4882a593Smuzhiyun 	else
136*4882a593Smuzhiyun 		return attr & INAT_PFX_MASK;
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun 
inat_is_vex_prefix(insn_attr_t attr)139*4882a593Smuzhiyun static inline int inat_is_vex_prefix(insn_attr_t attr)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	attr &= INAT_PFX_MASK;
142*4882a593Smuzhiyun 	return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
143*4882a593Smuzhiyun 	       attr == INAT_PFX_EVEX;
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun 
inat_is_evex_prefix(insn_attr_t attr)146*4882a593Smuzhiyun static inline int inat_is_evex_prefix(insn_attr_t attr)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun 	return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun 
inat_is_vex3_prefix(insn_attr_t attr)151*4882a593Smuzhiyun static inline int inat_is_vex3_prefix(insn_attr_t attr)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun 	return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
inat_is_escape(insn_attr_t attr)156*4882a593Smuzhiyun static inline int inat_is_escape(insn_attr_t attr)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun 	return attr & INAT_ESC_MASK;
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun 
inat_escape_id(insn_attr_t attr)161*4882a593Smuzhiyun static inline int inat_escape_id(insn_attr_t attr)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
inat_is_group(insn_attr_t attr)166*4882a593Smuzhiyun static inline int inat_is_group(insn_attr_t attr)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	return attr & INAT_GRP_MASK;
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun 
inat_group_id(insn_attr_t attr)171*4882a593Smuzhiyun static inline int inat_group_id(insn_attr_t attr)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun 	return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS;
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun 
inat_group_common_attribute(insn_attr_t attr)176*4882a593Smuzhiyun static inline int inat_group_common_attribute(insn_attr_t attr)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun 	return attr & ~INAT_GRP_MASK;
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun 
inat_has_immediate(insn_attr_t attr)181*4882a593Smuzhiyun static inline int inat_has_immediate(insn_attr_t attr)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun 	return attr & INAT_IMM_MASK;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun 
inat_immediate_size(insn_attr_t attr)186*4882a593Smuzhiyun static inline int inat_immediate_size(insn_attr_t attr)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun 	return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS;
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun 
inat_has_modrm(insn_attr_t attr)191*4882a593Smuzhiyun static inline int inat_has_modrm(insn_attr_t attr)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun 	return attr & INAT_MODRM;
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun 
inat_is_force64(insn_attr_t attr)196*4882a593Smuzhiyun static inline int inat_is_force64(insn_attr_t attr)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun 	return attr & INAT_FORCE64;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun 
inat_has_second_immediate(insn_attr_t attr)201*4882a593Smuzhiyun static inline int inat_has_second_immediate(insn_attr_t attr)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun 	return attr & INAT_SCNDIMM;
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun 
inat_has_moffset(insn_attr_t attr)206*4882a593Smuzhiyun static inline int inat_has_moffset(insn_attr_t attr)
207*4882a593Smuzhiyun {
208*4882a593Smuzhiyun 	return attr & INAT_MOFFSET;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun 
inat_has_variant(insn_attr_t attr)211*4882a593Smuzhiyun static inline int inat_has_variant(insn_attr_t attr)
212*4882a593Smuzhiyun {
213*4882a593Smuzhiyun 	return attr & INAT_VARIANT;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun 
inat_accept_vex(insn_attr_t attr)216*4882a593Smuzhiyun static inline int inat_accept_vex(insn_attr_t attr)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun 	return attr & INAT_VEXOK;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
inat_must_vex(insn_attr_t attr)221*4882a593Smuzhiyun static inline int inat_must_vex(insn_attr_t attr)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun 	return attr & (INAT_VEXONLY | INAT_EVEXONLY);
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun 
inat_must_evex(insn_attr_t attr)226*4882a593Smuzhiyun static inline int inat_must_evex(insn_attr_t attr)
227*4882a593Smuzhiyun {
228*4882a593Smuzhiyun 	return attr & INAT_EVEXONLY;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun #endif
231