xref: /openbmc/linux/arch/x86/include/asm/inat.h (revision d30c7b82)
11a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2eb13296cSMasami Hiramatsu #ifndef _ASM_X86_INAT_H
3eb13296cSMasami Hiramatsu #define _ASM_X86_INAT_H
4eb13296cSMasami Hiramatsu /*
5eb13296cSMasami Hiramatsu  * x86 instruction attributes
6eb13296cSMasami Hiramatsu  *
7eb13296cSMasami Hiramatsu  * Written by Masami Hiramatsu <mhiramat@redhat.com>
8eb13296cSMasami Hiramatsu  */
9*d30c7b82SBorislav Petkov #include <asm/inat_types.h> /* __ignore_sync_check__ */
10eb13296cSMasami Hiramatsu 
11eb13296cSMasami Hiramatsu /*
12eb13296cSMasami Hiramatsu  * Internal bits. Don't use bitmasks directly, because these bits are
13eb13296cSMasami Hiramatsu  * unstable. You should use checking functions.
14eb13296cSMasami Hiramatsu  */
15eb13296cSMasami Hiramatsu 
16eb13296cSMasami Hiramatsu #define INAT_OPCODE_TABLE_SIZE 256
17eb13296cSMasami Hiramatsu #define INAT_GROUP_TABLE_SIZE 8
18eb13296cSMasami Hiramatsu 
1904d46c1bSMasami Hiramatsu /* Legacy last prefixes */
20eb13296cSMasami Hiramatsu #define INAT_PFX_OPNDSZ	1	/* 0x66 */ /* LPFX1 */
21e0e492e9SMasami Hiramatsu #define INAT_PFX_REPE	2	/* 0xF3 */ /* LPFX2 */
22e0e492e9SMasami Hiramatsu #define INAT_PFX_REPNE	3	/* 0xF2 */ /* LPFX3 */
2304d46c1bSMasami Hiramatsu /* Other Legacy prefixes */
24eb13296cSMasami Hiramatsu #define INAT_PFX_LOCK	4	/* 0xF0 */
25eb13296cSMasami Hiramatsu #define INAT_PFX_CS	5	/* 0x2E */
26eb13296cSMasami Hiramatsu #define INAT_PFX_DS	6	/* 0x3E */
27eb13296cSMasami Hiramatsu #define INAT_PFX_ES	7	/* 0x26 */
28eb13296cSMasami Hiramatsu #define INAT_PFX_FS	8	/* 0x64 */
29eb13296cSMasami Hiramatsu #define INAT_PFX_GS	9	/* 0x65 */
30eb13296cSMasami Hiramatsu #define INAT_PFX_SS	10	/* 0x36 */
31eb13296cSMasami Hiramatsu #define INAT_PFX_ADDRSZ	11	/* 0x67 */
3204d46c1bSMasami Hiramatsu /* x86-64 REX prefix */
3304d46c1bSMasami Hiramatsu #define INAT_PFX_REX	12	/* 0x4X */
34e0e492e9SMasami Hiramatsu /* AVX VEX prefixes */
35e0e492e9SMasami Hiramatsu #define INAT_PFX_VEX2	13	/* 2-bytes VEX prefix */
36e0e492e9SMasami Hiramatsu #define INAT_PFX_VEX3	14	/* 3-bytes VEX prefix */
3725af37f4SAdrian Hunter #define INAT_PFX_EVEX	15	/* EVEX prefix */
38eb13296cSMasami Hiramatsu 
3904d46c1bSMasami Hiramatsu #define INAT_LSTPFX_MAX	3
4004d46c1bSMasami Hiramatsu #define INAT_LGCPFX_MAX	11
41eb13296cSMasami Hiramatsu 
42eb13296cSMasami Hiramatsu /* Immediate size */
43eb13296cSMasami Hiramatsu #define INAT_IMM_BYTE		1
44eb13296cSMasami Hiramatsu #define INAT_IMM_WORD		2
45eb13296cSMasami Hiramatsu #define INAT_IMM_DWORD		3
46eb13296cSMasami Hiramatsu #define INAT_IMM_QWORD		4
47eb13296cSMasami Hiramatsu #define INAT_IMM_PTR		5
48eb13296cSMasami Hiramatsu #define INAT_IMM_VWORD32	6
49eb13296cSMasami Hiramatsu #define INAT_IMM_VWORD		7
50eb13296cSMasami Hiramatsu 
51eb13296cSMasami Hiramatsu /* Legacy prefix */
52eb13296cSMasami Hiramatsu #define INAT_PFX_OFFS	0
53eb13296cSMasami Hiramatsu #define INAT_PFX_BITS	4
54eb13296cSMasami Hiramatsu #define INAT_PFX_MAX    ((1 << INAT_PFX_BITS) - 1)
55eb13296cSMasami Hiramatsu #define INAT_PFX_MASK	(INAT_PFX_MAX << INAT_PFX_OFFS)
56eb13296cSMasami Hiramatsu /* Escape opcodes */
57eb13296cSMasami Hiramatsu #define INAT_ESC_OFFS	(INAT_PFX_OFFS + INAT_PFX_BITS)
58eb13296cSMasami Hiramatsu #define INAT_ESC_BITS	2
59eb13296cSMasami Hiramatsu #define INAT_ESC_MAX	((1 << INAT_ESC_BITS) - 1)
60eb13296cSMasami Hiramatsu #define INAT_ESC_MASK	(INAT_ESC_MAX << INAT_ESC_OFFS)
61eb13296cSMasami Hiramatsu /* Group opcodes (1-16) */
62eb13296cSMasami Hiramatsu #define INAT_GRP_OFFS	(INAT_ESC_OFFS + INAT_ESC_BITS)
63eb13296cSMasami Hiramatsu #define INAT_GRP_BITS	5
64eb13296cSMasami Hiramatsu #define INAT_GRP_MAX	((1 << INAT_GRP_BITS) - 1)
65eb13296cSMasami Hiramatsu #define INAT_GRP_MASK	(INAT_GRP_MAX << INAT_GRP_OFFS)
66eb13296cSMasami Hiramatsu /* Immediates */
67eb13296cSMasami Hiramatsu #define INAT_IMM_OFFS	(INAT_GRP_OFFS + INAT_GRP_BITS)
68eb13296cSMasami Hiramatsu #define INAT_IMM_BITS	3
69eb13296cSMasami Hiramatsu #define INAT_IMM_MASK	(((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS)
70eb13296cSMasami Hiramatsu /* Flags */
71eb13296cSMasami Hiramatsu #define INAT_FLAG_OFFS	(INAT_IMM_OFFS + INAT_IMM_BITS)
7204d46c1bSMasami Hiramatsu #define INAT_MODRM	(1 << (INAT_FLAG_OFFS))
7304d46c1bSMasami Hiramatsu #define INAT_FORCE64	(1 << (INAT_FLAG_OFFS + 1))
7404d46c1bSMasami Hiramatsu #define INAT_SCNDIMM	(1 << (INAT_FLAG_OFFS + 2))
7504d46c1bSMasami Hiramatsu #define INAT_MOFFSET	(1 << (INAT_FLAG_OFFS + 3))
7604d46c1bSMasami Hiramatsu #define INAT_VARIANT	(1 << (INAT_FLAG_OFFS + 4))
77e0e492e9SMasami Hiramatsu #define INAT_VEXOK	(1 << (INAT_FLAG_OFFS + 5))
78e0e492e9SMasami Hiramatsu #define INAT_VEXONLY	(1 << (INAT_FLAG_OFFS + 6))
7925af37f4SAdrian Hunter #define INAT_EVEXONLY	(1 << (INAT_FLAG_OFFS + 7))
80eb13296cSMasami Hiramatsu /* Attribute making macros for attribute tables */
81eb13296cSMasami Hiramatsu #define INAT_MAKE_PREFIX(pfx)	(pfx << INAT_PFX_OFFS)
82eb13296cSMasami Hiramatsu #define INAT_MAKE_ESCAPE(esc)	(esc << INAT_ESC_OFFS)
83eb13296cSMasami Hiramatsu #define INAT_MAKE_GROUP(grp)	((grp << INAT_GRP_OFFS) | INAT_MODRM)
84eb13296cSMasami Hiramatsu #define INAT_MAKE_IMM(imm)	(imm << INAT_IMM_OFFS)
85eb13296cSMasami Hiramatsu 
8632d0b953SRicardo Neri /* Identifiers for segment registers */
8732d0b953SRicardo Neri #define INAT_SEG_REG_IGNORE	0
8832d0b953SRicardo Neri #define INAT_SEG_REG_DEFAULT	1
8932d0b953SRicardo Neri #define INAT_SEG_REG_CS		2
9032d0b953SRicardo Neri #define INAT_SEG_REG_SS		3
9132d0b953SRicardo Neri #define INAT_SEG_REG_DS		4
9232d0b953SRicardo Neri #define INAT_SEG_REG_ES		5
9332d0b953SRicardo Neri #define INAT_SEG_REG_FS		6
9432d0b953SRicardo Neri #define INAT_SEG_REG_GS		7
9532d0b953SRicardo Neri 
96eb13296cSMasami Hiramatsu /* Attribute search APIs */
97eb13296cSMasami Hiramatsu extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
98f8d98f10SMasami Hiramatsu extern int inat_get_last_prefix_id(insn_byte_t last_pfx);
99eb13296cSMasami Hiramatsu extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode,
100f8d98f10SMasami Hiramatsu 					     int lpfx_id,
101eb13296cSMasami Hiramatsu 					     insn_attr_t esc_attr);
102eb13296cSMasami Hiramatsu extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm,
103f8d98f10SMasami Hiramatsu 					    int lpfx_id,
104eb13296cSMasami Hiramatsu 					    insn_attr_t esc_attr);
105e0e492e9SMasami Hiramatsu extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode,
106e0e492e9SMasami Hiramatsu 					  insn_byte_t vex_m,
107e0e492e9SMasami Hiramatsu 					  insn_byte_t vex_pp);
108eb13296cSMasami Hiramatsu 
109eb13296cSMasami Hiramatsu /* Attribute checking functions */
inat_is_legacy_prefix(insn_attr_t attr)11004d46c1bSMasami Hiramatsu static inline int inat_is_legacy_prefix(insn_attr_t attr)
111eb13296cSMasami Hiramatsu {
11204d46c1bSMasami Hiramatsu 	attr &= INAT_PFX_MASK;
11304d46c1bSMasami Hiramatsu 	return attr && attr <= INAT_LGCPFX_MAX;
114eb13296cSMasami Hiramatsu }
115eb13296cSMasami Hiramatsu 
inat_is_address_size_prefix(insn_attr_t attr)116eb13296cSMasami Hiramatsu static inline int inat_is_address_size_prefix(insn_attr_t attr)
117eb13296cSMasami Hiramatsu {
118eb13296cSMasami Hiramatsu 	return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ;
119eb13296cSMasami Hiramatsu }
120eb13296cSMasami Hiramatsu 
inat_is_operand_size_prefix(insn_attr_t attr)121eb13296cSMasami Hiramatsu static inline int inat_is_operand_size_prefix(insn_attr_t attr)
122eb13296cSMasami Hiramatsu {
123eb13296cSMasami Hiramatsu 	return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ;
124eb13296cSMasami Hiramatsu }
125eb13296cSMasami Hiramatsu 
inat_is_rex_prefix(insn_attr_t attr)12604d46c1bSMasami Hiramatsu static inline int inat_is_rex_prefix(insn_attr_t attr)
12704d46c1bSMasami Hiramatsu {
12804d46c1bSMasami Hiramatsu 	return (attr & INAT_PFX_MASK) == INAT_PFX_REX;
12904d46c1bSMasami Hiramatsu }
13004d46c1bSMasami Hiramatsu 
inat_last_prefix_id(insn_attr_t attr)131eb13296cSMasami Hiramatsu static inline int inat_last_prefix_id(insn_attr_t attr)
132eb13296cSMasami Hiramatsu {
13304d46c1bSMasami Hiramatsu 	if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX)
134eb13296cSMasami Hiramatsu 		return 0;
135eb13296cSMasami Hiramatsu 	else
136eb13296cSMasami Hiramatsu 		return attr & INAT_PFX_MASK;
137eb13296cSMasami Hiramatsu }
138eb13296cSMasami Hiramatsu 
inat_is_vex_prefix(insn_attr_t attr)139e0e492e9SMasami Hiramatsu static inline int inat_is_vex_prefix(insn_attr_t attr)
140e0e492e9SMasami Hiramatsu {
141e0e492e9SMasami Hiramatsu 	attr &= INAT_PFX_MASK;
14225af37f4SAdrian Hunter 	return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
14325af37f4SAdrian Hunter 	       attr == INAT_PFX_EVEX;
14425af37f4SAdrian Hunter }
14525af37f4SAdrian Hunter 
inat_is_evex_prefix(insn_attr_t attr)14625af37f4SAdrian Hunter static inline int inat_is_evex_prefix(insn_attr_t attr)
14725af37f4SAdrian Hunter {
14825af37f4SAdrian Hunter 	return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
149e0e492e9SMasami Hiramatsu }
150e0e492e9SMasami Hiramatsu 
inat_is_vex3_prefix(insn_attr_t attr)151e0e492e9SMasami Hiramatsu static inline int inat_is_vex3_prefix(insn_attr_t attr)
152e0e492e9SMasami Hiramatsu {
153e0e492e9SMasami Hiramatsu 	return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
154e0e492e9SMasami Hiramatsu }
155e0e492e9SMasami Hiramatsu 
inat_is_escape(insn_attr_t attr)156eb13296cSMasami Hiramatsu static inline int inat_is_escape(insn_attr_t attr)
157eb13296cSMasami Hiramatsu {
158eb13296cSMasami Hiramatsu 	return attr & INAT_ESC_MASK;
159eb13296cSMasami Hiramatsu }
160eb13296cSMasami Hiramatsu 
inat_escape_id(insn_attr_t attr)161eb13296cSMasami Hiramatsu static inline int inat_escape_id(insn_attr_t attr)
162eb13296cSMasami Hiramatsu {
163eb13296cSMasami Hiramatsu 	return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS;
164eb13296cSMasami Hiramatsu }
165eb13296cSMasami Hiramatsu 
inat_is_group(insn_attr_t attr)166eb13296cSMasami Hiramatsu static inline int inat_is_group(insn_attr_t attr)
167eb13296cSMasami Hiramatsu {
168eb13296cSMasami Hiramatsu 	return attr & INAT_GRP_MASK;
169eb13296cSMasami Hiramatsu }
170eb13296cSMasami Hiramatsu 
inat_group_id(insn_attr_t attr)171eb13296cSMasami Hiramatsu static inline int inat_group_id(insn_attr_t attr)
172eb13296cSMasami Hiramatsu {
173eb13296cSMasami Hiramatsu 	return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS;
174eb13296cSMasami Hiramatsu }
175eb13296cSMasami Hiramatsu 
inat_group_common_attribute(insn_attr_t attr)176eb13296cSMasami Hiramatsu static inline int inat_group_common_attribute(insn_attr_t attr)
177eb13296cSMasami Hiramatsu {
178eb13296cSMasami Hiramatsu 	return attr & ~INAT_GRP_MASK;
179eb13296cSMasami Hiramatsu }
180eb13296cSMasami Hiramatsu 
inat_has_immediate(insn_attr_t attr)181eb13296cSMasami Hiramatsu static inline int inat_has_immediate(insn_attr_t attr)
182eb13296cSMasami Hiramatsu {
183eb13296cSMasami Hiramatsu 	return attr & INAT_IMM_MASK;
184eb13296cSMasami Hiramatsu }
185eb13296cSMasami Hiramatsu 
inat_immediate_size(insn_attr_t attr)186eb13296cSMasami Hiramatsu static inline int inat_immediate_size(insn_attr_t attr)
187eb13296cSMasami Hiramatsu {
188eb13296cSMasami Hiramatsu 	return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS;
189eb13296cSMasami Hiramatsu }
190eb13296cSMasami Hiramatsu 
inat_has_modrm(insn_attr_t attr)191eb13296cSMasami Hiramatsu static inline int inat_has_modrm(insn_attr_t attr)
192eb13296cSMasami Hiramatsu {
193eb13296cSMasami Hiramatsu 	return attr & INAT_MODRM;
194eb13296cSMasami Hiramatsu }
195eb13296cSMasami Hiramatsu 
inat_is_force64(insn_attr_t attr)196eb13296cSMasami Hiramatsu static inline int inat_is_force64(insn_attr_t attr)
197eb13296cSMasami Hiramatsu {
198eb13296cSMasami Hiramatsu 	return attr & INAT_FORCE64;
199eb13296cSMasami Hiramatsu }
200eb13296cSMasami Hiramatsu 
inat_has_second_immediate(insn_attr_t attr)201eb13296cSMasami Hiramatsu static inline int inat_has_second_immediate(insn_attr_t attr)
202eb13296cSMasami Hiramatsu {
203eb13296cSMasami Hiramatsu 	return attr & INAT_SCNDIMM;
204eb13296cSMasami Hiramatsu }
205eb13296cSMasami Hiramatsu 
inat_has_moffset(insn_attr_t attr)206eb13296cSMasami Hiramatsu static inline int inat_has_moffset(insn_attr_t attr)
207eb13296cSMasami Hiramatsu {
208eb13296cSMasami Hiramatsu 	return attr & INAT_MOFFSET;
209eb13296cSMasami Hiramatsu }
210eb13296cSMasami Hiramatsu 
inat_has_variant(insn_attr_t attr)211eb13296cSMasami Hiramatsu static inline int inat_has_variant(insn_attr_t attr)
212eb13296cSMasami Hiramatsu {
213eb13296cSMasami Hiramatsu 	return attr & INAT_VARIANT;
214eb13296cSMasami Hiramatsu }
215eb13296cSMasami Hiramatsu 
inat_accept_vex(insn_attr_t attr)216e0e492e9SMasami Hiramatsu static inline int inat_accept_vex(insn_attr_t attr)
217e0e492e9SMasami Hiramatsu {
218e0e492e9SMasami Hiramatsu 	return attr & INAT_VEXOK;
219e0e492e9SMasami Hiramatsu }
220e0e492e9SMasami Hiramatsu 
inat_must_vex(insn_attr_t attr)221e0e492e9SMasami Hiramatsu static inline int inat_must_vex(insn_attr_t attr)
222e0e492e9SMasami Hiramatsu {
22325af37f4SAdrian Hunter 	return attr & (INAT_VEXONLY | INAT_EVEXONLY);
22425af37f4SAdrian Hunter }
22525af37f4SAdrian Hunter 
inat_must_evex(insn_attr_t attr)22625af37f4SAdrian Hunter static inline int inat_must_evex(insn_attr_t attr)
22725af37f4SAdrian Hunter {
22825af37f4SAdrian Hunter 	return attr & INAT_EVEXONLY;
229e0e492e9SMasami Hiramatsu }
230eb13296cSMasami Hiramatsu #endif
231