xref: /openbmc/linux/arch/x86/include/asm/inst.h (revision e7bae9bb)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Generate .byte code for some instructions not supported by old
4  * binutils.
5  */
6 #ifndef X86_ASM_INST_H
7 #define X86_ASM_INST_H
8 
9 #ifdef __ASSEMBLY__
10 
11 #define REG_NUM_INVALID		100
12 
13 #define REG_TYPE_R32		0
14 #define REG_TYPE_R64		1
15 #define REG_TYPE_INVALID	100
16 
17 	.macro R32_NUM opd r32
18 	\opd = REG_NUM_INVALID
19 	.ifc \r32,%eax
20 	\opd = 0
21 	.endif
22 	.ifc \r32,%ecx
23 	\opd = 1
24 	.endif
25 	.ifc \r32,%edx
26 	\opd = 2
27 	.endif
28 	.ifc \r32,%ebx
29 	\opd = 3
30 	.endif
31 	.ifc \r32,%esp
32 	\opd = 4
33 	.endif
34 	.ifc \r32,%ebp
35 	\opd = 5
36 	.endif
37 	.ifc \r32,%esi
38 	\opd = 6
39 	.endif
40 	.ifc \r32,%edi
41 	\opd = 7
42 	.endif
43 #ifdef CONFIG_X86_64
44 	.ifc \r32,%r8d
45 	\opd = 8
46 	.endif
47 	.ifc \r32,%r9d
48 	\opd = 9
49 	.endif
50 	.ifc \r32,%r10d
51 	\opd = 10
52 	.endif
53 	.ifc \r32,%r11d
54 	\opd = 11
55 	.endif
56 	.ifc \r32,%r12d
57 	\opd = 12
58 	.endif
59 	.ifc \r32,%r13d
60 	\opd = 13
61 	.endif
62 	.ifc \r32,%r14d
63 	\opd = 14
64 	.endif
65 	.ifc \r32,%r15d
66 	\opd = 15
67 	.endif
68 #endif
69 	.endm
70 
71 	.macro R64_NUM opd r64
72 	\opd = REG_NUM_INVALID
73 #ifdef CONFIG_X86_64
74 	.ifc \r64,%rax
75 	\opd = 0
76 	.endif
77 	.ifc \r64,%rcx
78 	\opd = 1
79 	.endif
80 	.ifc \r64,%rdx
81 	\opd = 2
82 	.endif
83 	.ifc \r64,%rbx
84 	\opd = 3
85 	.endif
86 	.ifc \r64,%rsp
87 	\opd = 4
88 	.endif
89 	.ifc \r64,%rbp
90 	\opd = 5
91 	.endif
92 	.ifc \r64,%rsi
93 	\opd = 6
94 	.endif
95 	.ifc \r64,%rdi
96 	\opd = 7
97 	.endif
98 	.ifc \r64,%r8
99 	\opd = 8
100 	.endif
101 	.ifc \r64,%r9
102 	\opd = 9
103 	.endif
104 	.ifc \r64,%r10
105 	\opd = 10
106 	.endif
107 	.ifc \r64,%r11
108 	\opd = 11
109 	.endif
110 	.ifc \r64,%r12
111 	\opd = 12
112 	.endif
113 	.ifc \r64,%r13
114 	\opd = 13
115 	.endif
116 	.ifc \r64,%r14
117 	\opd = 14
118 	.endif
119 	.ifc \r64,%r15
120 	\opd = 15
121 	.endif
122 #endif
123 	.endm
124 
125 	.macro REG_TYPE type reg
126 	R32_NUM reg_type_r32 \reg
127 	R64_NUM reg_type_r64 \reg
128 	.if reg_type_r64 <> REG_NUM_INVALID
129 	\type = REG_TYPE_R64
130 	.elseif reg_type_r32 <> REG_NUM_INVALID
131 	\type = REG_TYPE_R32
132 	.else
133 	\type = REG_TYPE_INVALID
134 	.endif
135 	.endm
136 
137 	.macro PFX_REX opd1 opd2 W=0
138 	.if ((\opd1 | \opd2) & 8) || \W
139 	.byte 0x40 | ((\opd1 & 8) >> 3) | ((\opd2 & 8) >> 1) | (\W << 3)
140 	.endif
141 	.endm
142 
143 	.macro MODRM mod opd1 opd2
144 	.byte \mod | (\opd1 & 7) | ((\opd2 & 7) << 3)
145 	.endm
146 
147 .macro RDPID opd
148 	REG_TYPE rdpid_opd_type \opd
149 	.if rdpid_opd_type == REG_TYPE_R64
150 	R64_NUM rdpid_opd \opd
151 	.else
152 	R32_NUM rdpid_opd \opd
153 	.endif
154 	.byte 0xf3
155 	.if rdpid_opd > 7
156 	PFX_REX rdpid_opd 0
157 	.endif
158 	.byte 0x0f, 0xc7
159 	MODRM 0xc0 rdpid_opd 0x7
160 .endm
161 #endif
162 
163 #endif
164