Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * Copyright (c) 2022, the SerenityOS developers.
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <AK/StringBuilder.h>
9#include <LibX86/Instruction.h>
10#include <LibX86/Interpreter.h>
11
12#if defined(AK_COMPILER_GCC)
13# pragma GCC optimize("O3")
14#endif
15
16namespace X86 {
17
18InstructionDescriptor s_table[3][256];
19InstructionDescriptor s_0f_table[3][256];
20InstructionDescriptor s_sse_table_np[256];
21InstructionDescriptor s_sse_table_66[256];
22InstructionDescriptor s_sse_table_f3[256];
23InstructionDescriptor s_sse_table_f2[256];
24
25static bool opcode_has_register_index(u8 op)
26{
27 if (op >= 0x40 && op <= 0x5F)
28 return true;
29 if (op >= 0x90 && op <= 0x97)
30 return true;
31 if (op >= 0xB0 && op <= 0xBF)
32 return true;
33 return false;
34}
35
36static void build_in_table(InstructionDescriptor* table, u8 op, char const* mnemonic, InstructionFormat format, InstructionHandler handler, IsLockPrefixAllowed lock_prefix_allowed)
37{
38 InstructionDescriptor& d = table[op];
39
40 d.handler = handler;
41 d.mnemonic = mnemonic;
42 d.format = format;
43 d.lock_prefix_allowed = lock_prefix_allowed;
44
45 if ((format > __BeginFormatsWithRMByte && format < __EndFormatsWithRMByte) || format == MultibyteWithSlash)
46 d.has_rm = true;
47 else
48 d.opcode_has_register_index = opcode_has_register_index(op);
49
50 switch (format) {
51 case OP_RM8_imm8:
52 case OP_RM16_imm8:
53 case OP_RM32_imm8:
54 case OP_reg16_RM16_imm8:
55 case OP_reg32_RM32_imm8:
56 case OP_AL_imm8:
57 case OP_imm8:
58 case OP_reg8_imm8:
59 case OP_AX_imm8:
60 case OP_EAX_imm8:
61 case OP_short_imm8:
62 case OP_imm8_AL:
63 case OP_imm8_AX:
64 case OP_imm8_EAX:
65 case OP_RM16_reg16_imm8:
66 case OP_RM32_reg32_imm8:
67 case OP_mm1_imm8:
68 case OP_mm1_mm2m64_imm8:
69 case OP_reg_mm1_imm8:
70 case OP_mm1_r32m16_imm8:
71 case OP_xmm1_imm8:
72 case OP_xmm1_xmm2m32_imm8:
73 case OP_xmm1_xmm2m128_imm8:
74 case OP_reg_xmm1_imm8:
75 case OP_xmm1_r32m16_imm8:
76 d.imm1_bytes = 1;
77 break;
78 case OP_reg16_RM16_imm16:
79 case OP_AX_imm16:
80 case OP_imm16:
81 case OP_relimm16:
82 case OP_reg16_imm16:
83 case OP_RM16_imm16:
84 d.imm1_bytes = 2;
85 break;
86 case OP_RM32_imm32:
87 case OP_reg32_RM32_imm32:
88 case OP_reg32_imm32:
89 case OP_EAX_imm32:
90 case OP_imm32:
91 case OP_relimm32:
92 d.imm1_bytes = 4;
93 break;
94 case OP_regW_immW:
95 d.imm1_bytes = CurrentOperandSize;
96 break;
97 case OP_imm16_imm8:
98 d.imm1_bytes = 2;
99 d.imm2_bytes = 1;
100 break;
101 case OP_imm16_imm16:
102 d.imm1_bytes = 2;
103 d.imm2_bytes = 2;
104 break;
105 case OP_imm16_imm32:
106 d.imm1_bytes = 2;
107 d.imm2_bytes = 4;
108 break;
109 case OP_moff8_AL:
110 case OP_moff16_AX:
111 case OP_moff32_EAX:
112 case OP_AL_moff8:
113 case OP_AX_moff16:
114 case OP_EAX_moff32:
115 case OP_NEAR_imm:
116 d.imm1_bytes = CurrentAddressSize;
117 break;
118 // default:
119 case InvalidFormat:
120 case MultibyteWithSlash:
121 case InstructionPrefix:
122 case __BeginFormatsWithRMByte:
123 case OP_RM16_reg16:
124 case OP_reg8_RM8:
125 case OP_reg16_RM16:
126 case OP_RM16_seg:
127 case OP_RM32_seg:
128 case OP_RM8:
129 case OP_RM16:
130 case OP_RM32:
131 case OP_FPU:
132 case OP_FPU_reg:
133 case OP_FPU_mem:
134 case OP_FPU_AX16:
135 case OP_FPU_RM16:
136 case OP_FPU_RM32:
137 case OP_FPU_RM64:
138 case OP_FPU_M80:
139 case OP_RM8_reg8:
140 case OP_RM32_reg32:
141 case OP_reg32_RM32:
142 case OP_reg16_mem16:
143 case OP_reg32_mem32:
144 case OP_seg_RM16:
145 case OP_seg_RM32:
146 case OP_RM8_1:
147 case OP_RM16_1:
148 case OP_RM32_1:
149 case OP_FAR_mem16:
150 case OP_FAR_mem32:
151 case OP_RM8_CL:
152 case OP_RM16_CL:
153 case OP_RM32_CL:
154 case OP_reg32_CR:
155 case OP_CR_reg32:
156 case OP_reg16_RM8:
157 case OP_reg32_RM8:
158 case OP_reg:
159 case OP_m64:
160 case OP_mm1_rm32:
161 case OP_rm32_mm2:
162 case OP_mm1_mm2m64:
163 case OP_mm1_mm2m32:
164 case OP_mm1m64_mm2:
165 case OP_reg_mm1:
166 case __SSE:
167 case OP_xmm1_xmm2m32:
168 case OP_xmm1_xmm2m64:
169 case OP_xmm1_xmm2m128:
170 case OP_xmm1m32_xmm2:
171 case OP_xmm1m64_xmm2:
172 case OP_xmm1m128_xmm2:
173 case OP_reg_xmm1:
174 case OP_xmm1_rm32:
175 case OP_xmm1_m64:
176 case OP_m64_xmm2:
177 case OP_rm8_xmm2m32:
178 case OP_r32_xmm2m64:
179 case OP_rm32_xmm2:
180 case OP_xmm1_mm2m64:
181 case OP_xmm_mm:
182 case OP_mm_xmm:
183 case OP_mm1m64_xmm2:
184 case OP_mm1_xmm2m64:
185 case OP_mm1_xmm2m128:
186 case OP_r32_xmm2m32:
187 case __EndFormatsWithRMByte:
188 case OP_CS:
189 case OP_DS:
190 case OP_ES:
191 case OP_SS:
192 case OP_FS:
193 case OP_GS:
194 case OP:
195 case OP_reg16:
196 case OP_AX_reg16:
197 case OP_EAX_reg32:
198 case OP_3:
199 case OP_AL_DX:
200 case OP_AX_DX:
201 case OP_EAX_DX:
202 case OP_DX_AL:
203 case OP_DX_AX:
204 case OP_DX_EAX:
205 case OP_reg8_CL:
206 case OP_reg32:
207 case OP_reg32_RM16:
208 case OP_reg32_DR:
209 case OP_DR_reg32:
210 case OP_RM16_reg16_CL:
211 case OP_RM32_reg32_CL:
212 break;
213 }
214}
215
216static void build_slash(InstructionDescriptor* table, u8 op, u8 slash, char const* mnemonic, InstructionFormat format, InstructionHandler handler, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed)
217{
218 InstructionDescriptor& d = table[op];
219 VERIFY(d.handler == nullptr);
220 d.format = MultibyteWithSlash;
221 d.has_rm = true;
222 if (!d.slashes)
223 d.slashes = new InstructionDescriptor[8];
224
225 build_in_table(d.slashes, slash, mnemonic, format, handler, lock_prefix_allowed);
226}
227
228static void build_slash_rm(InstructionDescriptor* table, u8 op, u8 slash, u8 rm, char const* mnemonic, InstructionFormat format, InstructionHandler handler)
229{
230 VERIFY((rm & 0xc0) == 0xc0);
231 VERIFY(((rm >> 3) & 7) == slash);
232
233 InstructionDescriptor& d0 = table[op];
234 VERIFY(d0.format == MultibyteWithSlash);
235 InstructionDescriptor& d = d0.slashes[slash];
236
237 if (!d.slashes) {
238 // Slash/RM instructions are not always dense, so make them all default to the slash instruction.
239 d.slashes = new InstructionDescriptor[8];
240 for (int i = 0; i < 8; ++i) {
241 d.slashes[i] = d;
242 d.slashes[i].slashes = nullptr;
243 }
244 }
245
246 build_in_table(d.slashes, rm & 7, mnemonic, format, handler, LockPrefixNotAllowed);
247}
248
249template<auto table>
250static void build_base(u8 op, char const* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed)
251{
252 build_in_table(table[to_underlying(OperandSize::Size16)], op, mnemonic, format, impl, lock_prefix_allowed);
253 build_in_table(table[to_underlying(OperandSize::Size32)], op, mnemonic, format, impl, lock_prefix_allowed);
254 build_in_table(table[to_underlying(OperandSize::Size64)], op, mnemonic, format, impl, lock_prefix_allowed);
255}
256
257template<auto table>
258static void build_base(u8 op, char const* mnemonic, InstructionFormat format16, InstructionHandler impl16, InstructionFormat format32, InstructionHandler impl32, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed)
259{
260 build_in_table(table[to_underlying(OperandSize::Size16)], op, mnemonic, format16, impl16, lock_prefix_allowed);
261 build_in_table(table[to_underlying(OperandSize::Size32)], op, mnemonic, format32, impl32, lock_prefix_allowed);
262 build_in_table(table[to_underlying(OperandSize::Size64)], op, mnemonic, format32, impl32, lock_prefix_allowed);
263}
264
265template<auto table>
266static void build_base(u8 op, char const* mnemonic16, InstructionFormat format16, InstructionHandler impl16, char const* mnemonic32, InstructionFormat format32, InstructionHandler impl32, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed)
267{
268 build_in_table(table[to_underlying(OperandSize::Size16)], op, mnemonic16, format16, impl16, lock_prefix_allowed);
269 build_in_table(table[to_underlying(OperandSize::Size32)], op, mnemonic32, format32, impl32, lock_prefix_allowed);
270 build_in_table(table[to_underlying(OperandSize::Size64)], op, mnemonic32, format32, impl32, lock_prefix_allowed);
271}
272
273template<auto table>
274static void build_slash_base(u8 op, u8 slash, char const* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed)
275{
276 build_slash(table[to_underlying(OperandSize::Size16)], op, slash, mnemonic, format, impl, lock_prefix_allowed);
277 build_slash(table[to_underlying(OperandSize::Size32)], op, slash, mnemonic, format, impl, lock_prefix_allowed);
278 build_slash(table[to_underlying(OperandSize::Size64)], op, slash, mnemonic, format, impl, lock_prefix_allowed);
279}
280
281template<auto table>
282static void build_slash_base(u8 op, u8 slash, char const* mnemonic, InstructionFormat format16, InstructionHandler impl16, InstructionFormat format32, InstructionHandler impl32, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed)
283{
284 build_slash(table[to_underlying(OperandSize::Size16)], op, slash, mnemonic, format16, impl16, lock_prefix_allowed);
285 build_slash(table[to_underlying(OperandSize::Size32)], op, slash, mnemonic, format32, impl32, lock_prefix_allowed);
286 build_slash(table[to_underlying(OperandSize::Size64)], op, slash, mnemonic, format32, impl32, lock_prefix_allowed);
287}
288
289template<typename... Args>
290static void build(Args... args)
291{
292 build_base<s_table>(args...);
293}
294
295template<typename... Args>
296static void build_0f(Args... args)
297{
298 build_base<s_0f_table>(args...);
299}
300
301template<typename... Args>
302static void build_slash(Args... args)
303{
304 build_slash_base<s_table>(args...);
305}
306
307template<typename... Args>
308static void build_0f_slash(Args... args)
309{
310 build_slash_base<s_0f_table>(args...);
311}
312
313static void build_slash_rm(u8 op, u8 slash, u8 rm, char const* mnemonic, InstructionFormat format, InstructionHandler impl)
314{
315 build_slash_rm(s_table[to_underlying(OperandSize::Size16)], op, slash, rm, mnemonic, format, impl);
316 build_slash_rm(s_table[to_underlying(OperandSize::Size32)], op, slash, rm, mnemonic, format, impl);
317 build_slash_rm(s_table[to_underlying(OperandSize::Size64)], op, slash, rm, mnemonic, format, impl);
318}
319
320static void build_slash_reg(u8 op, u8 slash, char const* mnemonic, InstructionFormat format, InstructionHandler impl)
321{
322 for (int i = 0; i < 8; ++i)
323 build_slash_rm(op, slash, 0xc0 | (slash << 3) | i, mnemonic, format, impl);
324}
325
326static void build_sse_np(u8 op, char const* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed)
327{
328 if (s_0f_table[to_underlying(OperandSize::Size32)][op].format == InvalidFormat) {
329 build_0f(op, mnemonic, format, impl, lock_prefix_allowed);
330 build_in_table(s_sse_table_np, op, mnemonic, format, impl, lock_prefix_allowed);
331 return;
332 }
333 if (s_0f_table[to_underlying(OperandSize::Size32)][op].format != __SSE)
334 build_0f(op, "__SSE_temp", __SSE, nullptr, lock_prefix_allowed);
335
336 VERIFY(s_0f_table[to_underlying(OperandSize::Size32)][op].format == __SSE);
337 build_in_table(s_sse_table_np, op, mnemonic, format, impl, lock_prefix_allowed);
338}
339
340static void build_sse_66(u8 op, char const* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed)
341{
342 if (s_0f_table[to_underlying(OperandSize::Size32)][op].format != __SSE)
343 build_0f(op, "__SSE_temp", __SSE, nullptr, lock_prefix_allowed);
344 VERIFY(s_0f_table[to_underlying(AddressSize::Size32)][op].format == __SSE);
345 build_in_table(s_sse_table_66, op, mnemonic, format, impl, lock_prefix_allowed);
346}
347
348static void build_sse_f3(u8 op, char const* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed)
349{
350 if (s_0f_table[to_underlying(OperandSize::Size32)][op].format != __SSE)
351 build_0f(op, "__SSE_temp", __SSE, nullptr, lock_prefix_allowed);
352 VERIFY(s_0f_table[to_underlying(OperandSize::Size32)][op].format == __SSE);
353 build_in_table(s_sse_table_f3, op, mnemonic, format, impl, lock_prefix_allowed);
354}
355
356static void build_sse_f2(u8 op, char const* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed)
357{
358 if (s_0f_table[to_underlying(OperandSize::Size32)][op].format != __SSE)
359 build_0f(op, "__SSE_temp", __SSE, nullptr, lock_prefix_allowed);
360 VERIFY(s_0f_table[to_underlying(OperandSize::Size32)][op].format == __SSE);
361 VERIFY(s_sse_table_f2[op].format == InvalidFormat);
362
363 build_in_table(s_sse_table_f2, op, mnemonic, format, impl, lock_prefix_allowed);
364}
365
366static void build_sse_np_slash(u8 op, u8 slash, char const* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed)
367{
368 if (s_0f_table[to_underlying(OperandSize::Size32)][op].format != __SSE)
369 build_0f(op, "__SSE_temp", __SSE, nullptr, lock_prefix_allowed);
370
371 VERIFY(s_0f_table[to_underlying(OperandSize::Size32)][op].format == __SSE);
372 build_slash(s_sse_table_np, op, slash, mnemonic, format, impl, lock_prefix_allowed);
373}
374
375static void build_sse_66_slash(u8 op, u8 slash, char const* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed)
376{
377 if (s_0f_table[to_underlying(OperandSize::Size32)][op].format != __SSE)
378 build_0f(op, "__SSE_temp", __SSE, nullptr, lock_prefix_allowed);
379 VERIFY(s_0f_table[to_underlying(OperandSize::Size32)][op].format == __SSE);
380 build_slash(s_sse_table_66, op, slash, mnemonic, format, impl, lock_prefix_allowed);
381}
382
383[[gnu::constructor]] static void build_opcode_tables()
384{
385 build(0x00, "ADD", OP_RM8_reg8, &Interpreter::ADD_RM8_reg8, LockPrefixAllowed);
386 build(0x01, "ADD", OP_RM16_reg16, &Interpreter::ADD_RM16_reg16, OP_RM32_reg32, &Interpreter::ADD_RM32_reg32, LockPrefixAllowed);
387 build(0x02, "ADD", OP_reg8_RM8, &Interpreter::ADD_reg8_RM8, LockPrefixAllowed);
388 build(0x03, "ADD", OP_reg16_RM16, &Interpreter::ADD_reg16_RM16, OP_reg32_RM32, &Interpreter::ADD_reg32_RM32, LockPrefixAllowed);
389 build(0x04, "ADD", OP_AL_imm8, &Interpreter::ADD_AL_imm8);
390 build(0x05, "ADD", OP_AX_imm16, &Interpreter::ADD_AX_imm16, OP_EAX_imm32, &Interpreter::ADD_EAX_imm32);
391 build(0x06, "PUSH", OP_ES, &Interpreter::PUSH_ES);
392 build(0x07, "POP", OP_ES, &Interpreter::POP_ES);
393 build(0x08, "OR", OP_RM8_reg8, &Interpreter::OR_RM8_reg8, LockPrefixAllowed);
394 build(0x09, "OR", OP_RM16_reg16, &Interpreter::OR_RM16_reg16, OP_RM32_reg32, &Interpreter::OR_RM32_reg32, LockPrefixAllowed);
395 build(0x0A, "OR", OP_reg8_RM8, &Interpreter::OR_reg8_RM8, LockPrefixAllowed);
396 build(0x0B, "OR", OP_reg16_RM16, &Interpreter::OR_reg16_RM16, OP_reg32_RM32, &Interpreter::OR_reg32_RM32, LockPrefixAllowed);
397 build(0x0C, "OR", OP_AL_imm8, &Interpreter::OR_AL_imm8);
398 build(0x0D, "OR", OP_AX_imm16, &Interpreter::OR_AX_imm16, OP_EAX_imm32, &Interpreter::OR_EAX_imm32);
399 build(0x0E, "PUSH", OP_CS, &Interpreter::PUSH_CS);
400
401 build(0x10, "ADC", OP_RM8_reg8, &Interpreter::ADC_RM8_reg8, LockPrefixAllowed);
402 build(0x11, "ADC", OP_RM16_reg16, &Interpreter::ADC_RM16_reg16, OP_RM32_reg32, &Interpreter::ADC_RM32_reg32, LockPrefixAllowed);
403 build(0x12, "ADC", OP_reg8_RM8, &Interpreter::ADC_reg8_RM8, LockPrefixAllowed);
404 build(0x13, "ADC", OP_reg16_RM16, &Interpreter::ADC_reg16_RM16, OP_reg32_RM32, &Interpreter::ADC_reg32_RM32, LockPrefixAllowed);
405 build(0x14, "ADC", OP_AL_imm8, &Interpreter::ADC_AL_imm8);
406 build(0x15, "ADC", OP_AX_imm16, &Interpreter::ADC_AX_imm16, OP_EAX_imm32, &Interpreter::ADC_EAX_imm32);
407 build(0x16, "PUSH", OP_SS, &Interpreter::PUSH_SS);
408 build(0x17, "POP", OP_SS, &Interpreter::POP_SS);
409 build(0x18, "SBB", OP_RM8_reg8, &Interpreter::SBB_RM8_reg8, LockPrefixAllowed);
410 build(0x19, "SBB", OP_RM16_reg16, &Interpreter::SBB_RM16_reg16, OP_RM32_reg32, &Interpreter::SBB_RM32_reg32, LockPrefixAllowed);
411 build(0x1A, "SBB", OP_reg8_RM8, &Interpreter::SBB_reg8_RM8, LockPrefixAllowed);
412 build(0x1B, "SBB", OP_reg16_RM16, &Interpreter::SBB_reg16_RM16, OP_reg32_RM32, &Interpreter::SBB_reg32_RM32, LockPrefixAllowed);
413 build(0x1C, "SBB", OP_AL_imm8, &Interpreter::SBB_AL_imm8);
414 build(0x1D, "SBB", OP_AX_imm16, &Interpreter::SBB_AX_imm16, OP_EAX_imm32, &Interpreter::SBB_EAX_imm32);
415 build(0x1E, "PUSH", OP_DS, &Interpreter::PUSH_DS);
416 build(0x1F, "POP", OP_DS, &Interpreter::POP_DS);
417
418 build(0x20, "AND", OP_RM8_reg8, &Interpreter::AND_RM8_reg8, LockPrefixAllowed);
419 build(0x21, "AND", OP_RM16_reg16, &Interpreter::AND_RM16_reg16, OP_RM32_reg32, &Interpreter::AND_RM32_reg32, LockPrefixAllowed);
420 build(0x22, "AND", OP_reg8_RM8, &Interpreter::AND_reg8_RM8, LockPrefixAllowed);
421 build(0x23, "AND", OP_reg16_RM16, &Interpreter::AND_reg16_RM16, OP_reg32_RM32, &Interpreter::AND_reg32_RM32, LockPrefixAllowed);
422 build(0x24, "AND", OP_AL_imm8, &Interpreter::AND_AL_imm8);
423 build(0x25, "AND", OP_AX_imm16, &Interpreter::AND_AX_imm16, OP_EAX_imm32, &Interpreter::AND_EAX_imm32);
424 build(0x27, "DAA", OP, &Interpreter::DAA);
425 build(0x28, "SUB", OP_RM8_reg8, &Interpreter::SUB_RM8_reg8, LockPrefixAllowed);
426 build(0x29, "SUB", OP_RM16_reg16, &Interpreter::SUB_RM16_reg16, OP_RM32_reg32, &Interpreter::SUB_RM32_reg32, LockPrefixAllowed);
427 build(0x2A, "SUB", OP_reg8_RM8, &Interpreter::SUB_reg8_RM8, LockPrefixAllowed);
428 build(0x2B, "SUB", OP_reg16_RM16, &Interpreter::SUB_reg16_RM16, OP_reg32_RM32, &Interpreter::SUB_reg32_RM32, LockPrefixAllowed);
429 build(0x2C, "SUB", OP_AL_imm8, &Interpreter::SUB_AL_imm8);
430 build(0x2D, "SUB", OP_AX_imm16, &Interpreter::SUB_AX_imm16, OP_EAX_imm32, &Interpreter::SUB_EAX_imm32);
431 build(0x2F, "DAS", OP, &Interpreter::DAS);
432
433 build(0x30, "XOR", OP_RM8_reg8, &Interpreter::XOR_RM8_reg8, LockPrefixAllowed);
434 build(0x31, "XOR", OP_RM16_reg16, &Interpreter::XOR_RM16_reg16, OP_RM32_reg32, &Interpreter::XOR_RM32_reg32, LockPrefixAllowed);
435 build(0x32, "XOR", OP_reg8_RM8, &Interpreter::XOR_reg8_RM8, LockPrefixAllowed);
436 build(0x33, "XOR", OP_reg16_RM16, &Interpreter::XOR_reg16_RM16, OP_reg32_RM32, &Interpreter::XOR_reg32_RM32, LockPrefixAllowed);
437 build(0x34, "XOR", OP_AL_imm8, &Interpreter::XOR_AL_imm8);
438 build(0x35, "XOR", OP_AX_imm16, &Interpreter::XOR_AX_imm16, OP_EAX_imm32, &Interpreter::XOR_EAX_imm32);
439 build(0x37, "AAA", OP, &Interpreter::AAA);
440 build(0x38, "CMP", OP_RM8_reg8, &Interpreter::CMP_RM8_reg8, LockPrefixAllowed);
441 build(0x39, "CMP", OP_RM16_reg16, &Interpreter::CMP_RM16_reg16, OP_RM32_reg32, &Interpreter::CMP_RM32_reg32, LockPrefixAllowed);
442 build(0x3A, "CMP", OP_reg8_RM8, &Interpreter::CMP_reg8_RM8, LockPrefixAllowed);
443 build(0x3B, "CMP", OP_reg16_RM16, &Interpreter::CMP_reg16_RM16, OP_reg32_RM32, &Interpreter::CMP_reg32_RM32, LockPrefixAllowed);
444 build(0x3C, "CMP", OP_AL_imm8, &Interpreter::CMP_AL_imm8);
445 build(0x3D, "CMP", OP_AX_imm16, &Interpreter::CMP_AX_imm16, OP_EAX_imm32, &Interpreter::CMP_EAX_imm32);
446 build(0x3F, "AAS", OP, &Interpreter::AAS);
447
448 for (u8 i = 0; i <= 7; ++i)
449 build(0x40 + i, "INC", OP_reg16, &Interpreter::INC_reg16, OP_reg32, &Interpreter::INC_reg32);
450
451 for (u8 i = 0; i <= 7; ++i)
452 build(0x48 + i, "DEC", OP_reg16, &Interpreter::DEC_reg16, OP_reg32, &Interpreter::DEC_reg32);
453
454 for (u8 i = 0; i <= 7; ++i)
455 build(0x50 + i, "PUSH", OP_reg16, &Interpreter::PUSH_reg16, OP_reg32, &Interpreter::PUSH_reg32);
456
457 for (u8 i = 0; i <= 7; ++i)
458 build(0x58 + i, "POP", OP_reg16, &Interpreter::POP_reg16, OP_reg32, &Interpreter::POP_reg32);
459
460 build(0x60, "PUSHAW", OP, &Interpreter::PUSHA, "PUSHAD", OP, &Interpreter::PUSHAD);
461 build(0x61, "POPAW", OP, &Interpreter::POPA, "POPAD", OP, &Interpreter::POPAD);
462 build(0x62, "BOUND", OP_reg16_RM16, &Interpreter::BOUND, "BOUND", OP_reg32_RM32, &Interpreter::BOUND);
463 build(0x63, "ARPL", OP_RM16_reg16, &Interpreter::ARPL);
464
465 build(0x68, "PUSH", OP_imm16, &Interpreter::PUSH_imm16, OP_imm32, &Interpreter::PUSH_imm32);
466 build(0x69, "IMUL", OP_reg16_RM16_imm16, &Interpreter::IMUL_reg16_RM16_imm16, OP_reg32_RM32_imm32, &Interpreter::IMUL_reg32_RM32_imm32);
467 build(0x6A, "PUSH", OP_imm8, &Interpreter::PUSH_imm8);
468 build(0x6B, "IMUL", OP_reg16_RM16_imm8, &Interpreter::IMUL_reg16_RM16_imm8, OP_reg32_RM32_imm8, &Interpreter::IMUL_reg32_RM32_imm8);
469 build(0x6C, "INSB", OP, &Interpreter::INSB);
470 build(0x6D, "INSW", OP, &Interpreter::INSW, "INSD", OP, &Interpreter::INSD);
471 build(0x6E, "OUTSB", OP, &Interpreter::OUTSB);
472 build(0x6F, "OUTSW", OP, &Interpreter::OUTSW, "OUTSD", OP, &Interpreter::OUTSD);
473
474 build(0x70, "JO", OP_short_imm8, &Interpreter::Jcc_imm8);
475 build(0x71, "JNO", OP_short_imm8, &Interpreter::Jcc_imm8);
476 build(0x72, "JC", OP_short_imm8, &Interpreter::Jcc_imm8);
477 build(0x73, "JNC", OP_short_imm8, &Interpreter::Jcc_imm8);
478 build(0x74, "JZ", OP_short_imm8, &Interpreter::Jcc_imm8);
479 build(0x75, "JNZ", OP_short_imm8, &Interpreter::Jcc_imm8);
480 build(0x76, "JNA", OP_short_imm8, &Interpreter::Jcc_imm8);
481 build(0x77, "JA", OP_short_imm8, &Interpreter::Jcc_imm8);
482 build(0x78, "JS", OP_short_imm8, &Interpreter::Jcc_imm8);
483 build(0x79, "JNS", OP_short_imm8, &Interpreter::Jcc_imm8);
484 build(0x7A, "JP", OP_short_imm8, &Interpreter::Jcc_imm8);
485 build(0x7B, "JNP", OP_short_imm8, &Interpreter::Jcc_imm8);
486 build(0x7C, "JL", OP_short_imm8, &Interpreter::Jcc_imm8);
487 build(0x7D, "JNL", OP_short_imm8, &Interpreter::Jcc_imm8);
488 build(0x7E, "JNG", OP_short_imm8, &Interpreter::Jcc_imm8);
489 build(0x7F, "JG", OP_short_imm8, &Interpreter::Jcc_imm8);
490
491 build(0x84, "TEST", OP_RM8_reg8, &Interpreter::TEST_RM8_reg8);
492 build(0x85, "TEST", OP_RM16_reg16, &Interpreter::TEST_RM16_reg16, OP_RM32_reg32, &Interpreter::TEST_RM32_reg32);
493 build(0x86, "XCHG", OP_reg8_RM8, &Interpreter::XCHG_reg8_RM8, LockPrefixAllowed);
494 build(0x87, "XCHG", OP_reg16_RM16, &Interpreter::XCHG_reg16_RM16, OP_reg32_RM32, &Interpreter::XCHG_reg32_RM32, LockPrefixAllowed);
495 build(0x88, "MOV", OP_RM8_reg8, &Interpreter::MOV_RM8_reg8);
496 build(0x89, "MOV", OP_RM16_reg16, &Interpreter::MOV_RM16_reg16, OP_RM32_reg32, &Interpreter::MOV_RM32_reg32);
497 build(0x8A, "MOV", OP_reg8_RM8, &Interpreter::MOV_reg8_RM8);
498 build(0x8B, "MOV", OP_reg16_RM16, &Interpreter::MOV_reg16_RM16, OP_reg32_RM32, &Interpreter::MOV_reg32_RM32);
499 build(0x8C, "MOV", OP_RM16_seg, &Interpreter::MOV_RM16_seg);
500 build(0x8D, "LEA", OP_reg16_mem16, &Interpreter::LEA_reg16_mem16, OP_reg32_mem32, &Interpreter::LEA_reg32_mem32);
501 build(0x8E, "MOV", OP_seg_RM16, &Interpreter::MOV_seg_RM16, OP_seg_RM32, &Interpreter::MOV_seg_RM32);
502
503 build(0x90, "NOP", OP, &Interpreter::NOP);
504
505 for (u8 i = 0; i <= 6; ++i)
506 build(0x91 + i, "XCHG", OP_AX_reg16, &Interpreter::XCHG_AX_reg16, OP_EAX_reg32, &Interpreter::XCHG_EAX_reg32);
507
508 build(0x98, "CBW", OP, &Interpreter::CBW, "CWDE", OP, &Interpreter::CWDE);
509 build(0x99, "CWD", OP, &Interpreter::CWD, "CDQ", OP, &Interpreter::CDQ);
510 build(0x9A, "CALL", OP_imm16_imm16, &Interpreter::CALL_imm16_imm16, OP_imm16_imm32, &Interpreter::CALL_imm16_imm32);
511 build(0x9B, "WAIT", OP, &Interpreter::WAIT);
512 build(0x9C, "PUSHFW", OP, &Interpreter::PUSHF, "PUSHFD", OP, &Interpreter::PUSHFD);
513 build(0x9D, "POPFW", OP, &Interpreter::POPF, "POPFD", OP, &Interpreter::POPFD);
514 build(0x9E, "SAHF", OP, &Interpreter::SAHF);
515 build(0x9F, "LAHF", OP, &Interpreter::LAHF);
516
517 build(0xA0, "MOV", OP_AL_moff8, &Interpreter::MOV_AL_moff8);
518 build(0xA1, "MOV", OP_AX_moff16, &Interpreter::MOV_AX_moff16, OP_EAX_moff32, &Interpreter::MOV_EAX_moff32);
519 build(0xA2, "MOV", OP_moff8_AL, &Interpreter::MOV_moff8_AL);
520 build(0xA3, "MOV", OP_moff16_AX, &Interpreter::MOV_moff16_AX, OP_moff32_EAX, &Interpreter::MOV_moff32_EAX);
521 build(0xA4, "MOVSB", OP, &Interpreter::MOVSB);
522 build(0xA5, "MOVSW", OP, &Interpreter::MOVSW, "MOVSD", OP, &Interpreter::MOVSD);
523 build(0xA6, "CMPSB", OP, &Interpreter::CMPSB);
524 build(0xA7, "CMPSW", OP, &Interpreter::CMPSW, "CMPSD", OP, &Interpreter::CMPSD);
525 build(0xA8, "TEST", OP_AL_imm8, &Interpreter::TEST_AL_imm8);
526 build(0xA9, "TEST", OP_AX_imm16, &Interpreter::TEST_AX_imm16, OP_EAX_imm32, &Interpreter::TEST_EAX_imm32);
527 build(0xAA, "STOSB", OP, &Interpreter::STOSB);
528 build(0xAB, "STOSW", OP, &Interpreter::STOSW, "STOSD", OP, &Interpreter::STOSD);
529 build(0xAC, "LODSB", OP, &Interpreter::LODSB);
530 build(0xAD, "LODSW", OP, &Interpreter::LODSW, "LODSD", OP, &Interpreter::LODSD);
531 build(0xAE, "SCASB", OP, &Interpreter::SCASB);
532 build(0xAF, "SCASW", OP, &Interpreter::SCASW, "SCASD", OP, &Interpreter::SCASD);
533
534 for (u8 i = 0xb0; i <= 0xb7; ++i)
535 build(i, "MOV", OP_reg8_imm8, &Interpreter::MOV_reg8_imm8);
536
537 for (u8 i = 0xb8; i <= 0xbf; ++i)
538 build(i, "MOV", OP_reg16_imm16, &Interpreter::MOV_reg16_imm16, OP_reg32_imm32, &Interpreter::MOV_reg32_imm32);
539
540 build(0xC2, "RET", OP_imm16, &Interpreter::RET_imm16);
541 build(0xC3, "RET", OP, &Interpreter::RET);
542 build(0xC4, "LES", OP_reg16_mem16, &Interpreter::LES_reg16_mem16, OP_reg32_mem32, &Interpreter::LES_reg32_mem32);
543 build(0xC5, "LDS", OP_reg16_mem16, &Interpreter::LDS_reg16_mem16, OP_reg32_mem32, &Interpreter::LDS_reg32_mem32);
544 build(0xC6, "MOV", OP_RM8_imm8, &Interpreter::MOV_RM8_imm8);
545 build(0xC7, "MOV", OP_RM16_imm16, &Interpreter::MOV_RM16_imm16, OP_RM32_imm32, &Interpreter::MOV_RM32_imm32);
546 build(0xC8, "ENTER", OP_imm16_imm8, &Interpreter::ENTER16, OP_imm16_imm8, &Interpreter::ENTER32);
547 build(0xC9, "LEAVE", OP, &Interpreter::LEAVE16, OP, &Interpreter::LEAVE32);
548 build(0xCA, "RETF", OP_imm16, &Interpreter::RETF_imm16);
549 build(0xCB, "RETF", OP, &Interpreter::RETF);
550 build(0xCC, "INT3", OP_3, &Interpreter::INT3);
551 build(0xCD, "INT", OP_imm8, &Interpreter::INT_imm8);
552 build(0xCE, "INTO", OP, &Interpreter::INTO);
553 build(0xCF, "IRET", OP, &Interpreter::IRET);
554
555 build(0xD4, "AAM", OP_imm8, &Interpreter::AAM);
556 build(0xD5, "AAD", OP_imm8, &Interpreter::AAD);
557 build(0xD6, "SALC", OP, &Interpreter::SALC);
558 build(0xD7, "XLAT", OP, &Interpreter::XLAT);
559
560 // D8-DF == FPU
561 build_slash(0xD8, 0, "FADD", OP_FPU_RM32, &Interpreter::FADD_RM32);
562 build_slash(0xD8, 1, "FMUL", OP_FPU_RM32, &Interpreter::FMUL_RM32);
563 build_slash(0xD8, 2, "FCOM", OP_FPU_RM32, &Interpreter::FCOM_RM32);
564 // FIXME: D8/2 D1 (...but isn't this what D8/2 does naturally, with D1 just being normal R/M?)
565 build_slash(0xD8, 3, "FCOMP", OP_FPU_RM32, &Interpreter::FCOMP_RM32);
566 // FIXME: D8/3 D9 (...but isn't this what D8/3 does naturally, with D9 just being normal R/M?)
567 build_slash(0xD8, 4, "FSUB", OP_FPU_RM32, &Interpreter::FSUB_RM32);
568 build_slash(0xD8, 5, "FSUBR", OP_FPU_RM32, &Interpreter::FSUBR_RM32);
569 build_slash(0xD8, 6, "FDIV", OP_FPU_RM32, &Interpreter::FDIV_RM32);
570 build_slash(0xD8, 7, "FDIVR", OP_FPU_RM32, &Interpreter::FDIVR_RM32);
571
572 build_slash(0xD9, 0, "FLD", OP_FPU_RM32, &Interpreter::FLD_RM32);
573 build_slash(0xD9, 1, "FXCH", OP_FPU_reg, &Interpreter::FXCH);
574 // FIXME: D9/1 C9 (...but isn't this what D9/1 does naturally, with C9 just being normal R/M?)
575 build_slash(0xD9, 2, "FST", OP_FPU_RM32, &Interpreter::FST_RM32);
576 build_slash_rm(0xD9, 2, 0xD0, "FNOP", OP_FPU, &Interpreter::FNOP);
577 build_slash(0xD9, 3, "FSTP", OP_FPU_RM32, &Interpreter::FSTP_RM32);
578 build_slash(0xD9, 4, "FLDENV", OP_FPU_RM32, &Interpreter::FLDENV);
579 build_slash_rm(0xD9, 4, 0xE0, "FCHS", OP_FPU, &Interpreter::FCHS);
580 build_slash_rm(0xD9, 4, 0xE1, "FABS", OP_FPU, &Interpreter::FABS);
581 build_slash_rm(0xD9, 4, 0xE2, "FTST", OP_FPU, &Interpreter::FTST);
582 build_slash_rm(0xD9, 4, 0xE3, "FXAM", OP_FPU, &Interpreter::FXAM);
583 build_slash(0xD9, 5, "FLDCW", OP_FPU_RM16, &Interpreter::FLDCW);
584 build_slash_rm(0xD9, 5, 0xE8, "FLD1", OP_FPU, &Interpreter::FLD1);
585 build_slash_rm(0xD9, 5, 0xE9, "FLDL2T", OP_FPU, &Interpreter::FLDL2T);
586 build_slash_rm(0xD9, 5, 0xEA, "FLDL2E", OP_FPU, &Interpreter::FLDL2E);
587 build_slash_rm(0xD9, 5, 0xEB, "FLDPI", OP_FPU, &Interpreter::FLDPI);
588 build_slash_rm(0xD9, 5, 0xEC, "FLDLG2", OP_FPU, &Interpreter::FLDLG2);
589 build_slash_rm(0xD9, 5, 0xED, "FLDLN2", OP_FPU, &Interpreter::FLDLN2);
590 build_slash_rm(0xD9, 5, 0xEE, "FLDZ", OP_FPU, &Interpreter::FLDZ);
591 build_slash(0xD9, 6, "FNSTENV", OP_FPU_RM32, &Interpreter::FNSTENV);
592 // FIXME: Extraordinary prefix 0x9B + 0xD9/6: FSTENV
593 build_slash_rm(0xD9, 6, 0xF0, "F2XM1", OP_FPU, &Interpreter::F2XM1);
594 build_slash_rm(0xD9, 6, 0xF1, "FYL2X", OP_FPU, &Interpreter::FYL2X);
595 build_slash_rm(0xD9, 6, 0xF2, "FPTAN", OP_FPU, &Interpreter::FPTAN);
596 build_slash_rm(0xD9, 6, 0xF3, "FPATAN", OP_FPU, &Interpreter::FPATAN);
597 build_slash_rm(0xD9, 6, 0xF4, "FXTRACT", OP_FPU, &Interpreter::FXTRACT);
598 build_slash_rm(0xD9, 6, 0xF5, "FPREM1", OP_FPU, &Interpreter::FPREM1);
599 build_slash_rm(0xD9, 6, 0xF6, "FDECSTP", OP_FPU, &Interpreter::FDECSTP);
600 build_slash_rm(0xD9, 6, 0xF7, "FINCSTP", OP_FPU, &Interpreter::FINCSTP);
601 build_slash(0xD9, 7, "FNSTCW", OP_FPU_RM16, &Interpreter::FNSTCW);
602 // FIXME: Extraordinary prefix 0x9B + 0xD9/7: FSTCW
603 build_slash_rm(0xD9, 7, 0xF8, "FPREM", OP_FPU, &Interpreter::FPREM);
604 build_slash_rm(0xD9, 7, 0xF9, "FYL2XP1", OP_FPU, &Interpreter::FYL2XP1);
605 build_slash_rm(0xD9, 7, 0xFA, "FSQRT", OP_FPU, &Interpreter::FSQRT);
606 build_slash_rm(0xD9, 7, 0xFB, "FSINCOS", OP_FPU, &Interpreter::FSINCOS);
607 build_slash_rm(0xD9, 7, 0xFC, "FRNDINT", OP_FPU, &Interpreter::FRNDINT);
608 build_slash_rm(0xD9, 7, 0xFD, "FSCALE", OP_FPU, &Interpreter::FSCALE);
609 build_slash_rm(0xD9, 7, 0xFE, "FSIN", OP_FPU, &Interpreter::FSIN);
610 build_slash_rm(0xD9, 7, 0xFF, "FCOS", OP_FPU, &Interpreter::FCOS);
611
612 build_slash(0xDA, 0, "FIADD", OP_FPU_RM32, &Interpreter::FIADD_RM32);
613 build_slash_reg(0xDA, 0, "FCMOVB", OP_FPU_reg, &Interpreter::FCMOVB);
614 build_slash(0xDA, 1, "FIMUL", OP_FPU_RM32, &Interpreter::FIMUL_RM32);
615 build_slash_reg(0xDA, 1, "FCMOVE", OP_FPU_reg, &Interpreter::FCMOVE);
616 build_slash(0xDA, 2, "FICOM", OP_FPU_RM32, &Interpreter::FICOM_RM32);
617 build_slash_reg(0xDA, 2, "FCMOVBE", OP_FPU_reg, &Interpreter::FCMOVBE);
618 build_slash(0xDA, 3, "FICOMP", OP_FPU_RM32, &Interpreter::FICOMP_RM32);
619 build_slash_reg(0xDA, 3, "FCMOVU", OP_FPU_reg, &Interpreter::FCMOVU);
620 build_slash(0xDA, 4, "FISUB", OP_FPU_RM32, &Interpreter::FISUB_RM32);
621 build_slash(0xDA, 5, "FISUBR", OP_FPU_RM32, &Interpreter::FISUBR_RM32);
622 build_slash_rm(0xDA, 5, 0xE9, "FUCOMPP", OP_FPU, &Interpreter::FUCOMPP);
623 build_slash(0xDA, 6, "FIDIV", OP_FPU_RM32, &Interpreter::FIDIV_RM32);
624 build_slash(0xDA, 7, "FIDIVR", OP_FPU_RM32, &Interpreter::FIDIVR_RM32);
625
626 build_slash(0xDB, 0, "FILD", OP_FPU_RM32, &Interpreter::FILD_RM32);
627 build_slash_reg(0xDB, 0, "FCMOVNB", OP_FPU_reg, &Interpreter::FCMOVNB);
628 build_slash(0xDB, 1, "FISTTP", OP_FPU_RM32, &Interpreter::FISTTP_RM32);
629 build_slash_reg(0xDB, 1, "FCMOVNE", OP_FPU_reg, &Interpreter::FCMOVNE);
630 build_slash(0xDB, 2, "FIST", OP_FPU_RM32, &Interpreter::FIST_RM32);
631 build_slash_reg(0xDB, 2, "FCMOVNBE", OP_FPU_reg, &Interpreter::FCMOVNBE);
632 build_slash(0xDB, 3, "FISTP", OP_FPU_RM32, &Interpreter::FISTP_RM32);
633 build_slash_reg(0xDB, 3, "FCMOVNU", OP_FPU_reg, &Interpreter::FCMOVNU);
634 build_slash(0xDB, 4, "FUNASSIGNED", OP_FPU, &Interpreter::ESCAPE);
635 build_slash_rm(0xDB, 4, 0xE0, "FNENI", OP_FPU_reg, &Interpreter::FNENI);
636 build_slash_rm(0xDB, 4, 0xE1, "FNDISI", OP_FPU_reg, &Interpreter::FNDISI);
637 build_slash_rm(0xDB, 4, 0xE2, "FNCLEX", OP_FPU_reg, &Interpreter::FNCLEX);
638 // FIXME: Extraordinary prefix 0x9B + 0xDB/4: FCLEX
639 build_slash_rm(0xDB, 4, 0xE3, "FNINIT", OP_FPU_reg, &Interpreter::FNINIT);
640 // FIXME: Extraordinary prefix 0x9B + 0xDB/4: FINIT
641 build_slash_rm(0xDB, 4, 0xE4, "FNSETPM", OP_FPU_reg, &Interpreter::FNSETPM);
642 build_slash(0xDB, 5, "FLD", OP_FPU_M80, &Interpreter::FLD_RM80);
643 build_slash_reg(0xDB, 5, "FUCOMI", OP_FPU_reg, &Interpreter::FUCOMI);
644 build_slash(0xDB, 6, "FCOMI", OP_FPU_reg, &Interpreter::FCOMI);
645 build_slash(0xDB, 7, "FSTP", OP_FPU_M80, &Interpreter::FSTP_RM80);
646
647 build_slash(0xDC, 0, "FADD", OP_FPU_RM64, &Interpreter::FADD_RM64);
648 build_slash(0xDC, 1, "FMUL", OP_FPU_RM64, &Interpreter::FMUL_RM64);
649 build_slash(0xDC, 2, "FCOM", OP_FPU_RM64, &Interpreter::FCOM_RM64);
650 build_slash(0xDC, 3, "FCOMP", OP_FPU_RM64, &Interpreter::FCOMP_RM64);
651 build_slash(0xDC, 4, "FSUB", OP_FPU_RM64, &Interpreter::FSUB_RM64);
652 build_slash(0xDC, 5, "FSUBR", OP_FPU_RM64, &Interpreter::FSUBR_RM64);
653 build_slash(0xDC, 6, "FDIV", OP_FPU_RM64, &Interpreter::FDIV_RM64);
654 build_slash(0xDC, 7, "FDIVR", OP_FPU_RM64, &Interpreter::FDIVR_RM64);
655
656 build_slash(0xDD, 0, "FLD", OP_FPU_RM64, &Interpreter::FLD_RM64);
657 build_slash_reg(0xDD, 0, "FFREE", OP_FPU_reg, &Interpreter::FFREE);
658 build_slash(0xDD, 1, "FISTTP", OP_FPU_RM64, &Interpreter::FISTTP_RM64);
659 build_slash_reg(0xDD, 1, "FXCH4", OP_FPU_reg, &Interpreter::FXCH);
660 build_slash(0xDD, 2, "FST", OP_FPU_RM64, &Interpreter::FST_RM64);
661 build_slash(0xDD, 3, "FSTP", OP_FPU_RM64, &Interpreter::FSTP_RM64);
662 build_slash(0xDD, 4, "FRSTOR", OP_FPU_mem, &Interpreter::FRSTOR);
663 build_slash_reg(0xDD, 4, "FUCOM", OP_FPU_reg, &Interpreter::FUCOM);
664 // FIXME: DD/4 E1 (...but isn't this what DD/4 does naturally, with E1 just being normal R/M?)
665 build_slash(0xDD, 5, "FUCOMP", OP_FPU_reg, &Interpreter::FUCOMP);
666 // FIXME: DD/5 E9 (...but isn't this what DD/5 does naturally, with E9 just being normal R/M?)
667 build_slash(0xDD, 6, "FNSAVE", OP_FPU_mem, &Interpreter::FNSAVE);
668 // FIXME: Extraordinary prefix 0x9B + 0xDD/6: FSAVE
669 build_slash(0xDD, 7, "FNSTSW", OP_FPU_RM16, &Interpreter::FNSTSW);
670 // FIXME: Extraordinary prefix 0x9B + 0xDD/7: FSTSW
671
672 build_slash(0xDE, 0, "FIADD", OP_FPU_RM16, &Interpreter::FIADD_RM16);
673 build_slash_reg(0xDE, 0, "FADDP", OP_FPU_reg, &Interpreter::FADDP);
674 // FIXME: DE/0 C1 (...but isn't this what DE/0 does naturally, with C1 just being normal R/M?)
675 build_slash(0xDE, 1, "FIMUL", OP_FPU_RM16, &Interpreter::FIMUL_RM16);
676 build_slash_reg(0xDE, 1, "FMULP", OP_FPU_reg, &Interpreter::FMULP);
677 // FIXME: DE/1 C9 (...but isn't this what DE/1 does naturally, with C9 just being normal R/M?)
678 build_slash(0xDE, 2, "FICOM", OP_FPU_RM16, &Interpreter::FICOM_RM16);
679 build_slash_reg(0xDE, 2, "FCOMP5", OP_FPU_reg, &Interpreter::FCOMP_RM32);
680 build_slash(0xDE, 3, "FICOMP", OP_FPU_RM16, &Interpreter::FICOMP_RM16);
681 build_slash_reg(0xDE, 3, "FCOMPP", OP_FPU_reg, &Interpreter::FCOMPP);
682 build_slash(0xDE, 4, "FISUB", OP_FPU_RM16, &Interpreter::FISUB_RM16);
683 build_slash_reg(0xDE, 4, "FSUBRP", OP_FPU_reg, &Interpreter::FSUBRP);
684 // FIXME: DE/4 E1 (...but isn't this what DE/4 does naturally, with E1 just being normal R/M?)
685 build_slash(0xDE, 5, "FISUBR", OP_FPU_RM16, &Interpreter::FISUBR_RM16);
686 build_slash_reg(0xDE, 5, "FSUBP", OP_FPU_reg, &Interpreter::FSUBP);
687 // FIXME: DE/5 E9 (...but isn't this what DE/5 does naturally, with E9 just being normal R/M?)
688 build_slash(0xDE, 6, "FIDIV", OP_FPU_RM16, &Interpreter::FIDIV_RM16);
689 build_slash_reg(0xDE, 6, "FDIVRP", OP_FPU_reg, &Interpreter::FDIVRP);
690 // FIXME: DE/6 F1 (...but isn't this what DE/6 does naturally, with F1 just being normal R/M?)
691 build_slash(0xDE, 7, "FIDIVR", OP_FPU_RM16, &Interpreter::FIDIVR_RM16);
692 build_slash_reg(0xDE, 7, "FDIVP", OP_FPU_reg, &Interpreter::FDIVP);
693 // FIXME: DE/7 F9 (...but isn't this what DE/7 does naturally, with F9 just being normal R/M?)
694
695 build_slash(0xDF, 0, "FILD", OP_FPU_RM32, &Interpreter::FILD_RM16);
696 build_slash_reg(0xDF, 0, "FFREEP", OP_FPU_reg, &Interpreter::FFREEP);
697 build_slash(0xDF, 1, "FISTTP", OP_FPU_RM32, &Interpreter::FISTTP_RM16);
698 build_slash_reg(0xDF, 1, "FXCH7", OP_FPU_reg, &Interpreter::FXCH);
699 build_slash(0xDF, 2, "FIST", OP_FPU_RM32, &Interpreter::FIST_RM16);
700 build_slash_reg(0xDF, 2, "FSTP8", OP_FPU_reg, &Interpreter::FSTP_RM32);
701 build_slash(0xDF, 3, "FISTP", OP_FPU_RM32, &Interpreter::FISTP_RM16);
702 build_slash_reg(0xDF, 3, "FSTP9", OP_FPU_reg, &Interpreter::FSTP_RM32);
703 build_slash(0xDF, 4, "FBLD", OP_FPU_M80, &Interpreter::FBLD_M80);
704 build_slash_reg(0xDF, 4, "FNSTSW", OP_FPU_AX16, &Interpreter::FNSTSW_AX);
705 // FIXME: Extraordinary prefix 0x9B + 0xDF/e: FSTSW_AX
706 build_slash(0xDF, 5, "FILD", OP_FPU_RM64, &Interpreter::FILD_RM64);
707 build_slash_reg(0xDF, 5, "FUCOMIP", OP_FPU_reg, &Interpreter::FUCOMIP);
708 build_slash(0xDF, 6, "FBSTP", OP_FPU_M80, &Interpreter::FBSTP_M80);
709 build_slash_reg(0xDF, 6, "FCOMIP", OP_FPU_reg, &Interpreter::FCOMIP);
710 build_slash(0xDF, 7, "FISTP", OP_FPU_RM64, &Interpreter::FISTP_RM64);
711
712 build(0xE0, "LOOPNZ", OP_imm8, &Interpreter::LOOPNZ_imm8);
713 build(0xE1, "LOOPZ", OP_imm8, &Interpreter::LOOPZ_imm8);
714 build(0xE2, "LOOP", OP_imm8, &Interpreter::LOOP_imm8);
715 build(0xE3, "JCXZ", OP_imm8, &Interpreter::JCXZ_imm8);
716 build(0xE4, "IN", OP_AL_imm8, &Interpreter::IN_AL_imm8);
717 build(0xE5, "IN", OP_AX_imm8, &Interpreter::IN_AX_imm8, OP_EAX_imm8, &Interpreter::IN_EAX_imm8);
718 build(0xE6, "OUT", OP_imm8_AL, &Interpreter::OUT_imm8_AL);
719 build(0xE7, "OUT", OP_imm8_AX, &Interpreter::OUT_imm8_AX, OP_imm8_EAX, &Interpreter::OUT_imm8_EAX);
720 build(0xE8, "CALL", OP_relimm16, &Interpreter::CALL_imm16, OP_relimm32, &Interpreter::CALL_imm32);
721 build(0xE9, "JMP", OP_relimm16, &Interpreter::JMP_imm16, OP_relimm32, &Interpreter::JMP_imm32);
722 build(0xEA, "JMP", OP_imm16_imm16, &Interpreter::JMP_imm16_imm16, OP_imm16_imm32, &Interpreter::JMP_imm16_imm32);
723 build(0xEB, "JMP", OP_short_imm8, &Interpreter::JMP_short_imm8);
724 build(0xEC, "IN", OP_AL_DX, &Interpreter::IN_AL_DX);
725 build(0xED, "IN", OP_AX_DX, &Interpreter::IN_AX_DX, OP_EAX_DX, &Interpreter::IN_EAX_DX);
726 build(0xEE, "OUT", OP_DX_AL, &Interpreter::OUT_DX_AL);
727 build(0xEF, "OUT", OP_DX_AX, &Interpreter::OUT_DX_AX, OP_DX_EAX, &Interpreter::OUT_DX_EAX);
728
729 build(0xF1, "INT1", OP, &Interpreter::INT1);
730
731 build(0xF4, "HLT", OP, &Interpreter::HLT);
732 build(0xF5, "CMC", OP, &Interpreter::CMC);
733
734 build(0xF8, "CLC", OP, &Interpreter::CLC);
735 build(0xF9, "STC", OP, &Interpreter::STC);
736 build(0xFA, "CLI", OP, &Interpreter::CLI);
737 build(0xFB, "STI", OP, &Interpreter::STI);
738 build(0xFC, "CLD", OP, &Interpreter::CLD);
739 build(0xFD, "STD", OP, &Interpreter::STD);
740
741 build_slash(0x80, 0, "ADD", OP_RM8_imm8, &Interpreter::ADD_RM8_imm8, LockPrefixAllowed);
742 build_slash(0x80, 1, "OR", OP_RM8_imm8, &Interpreter::OR_RM8_imm8, LockPrefixAllowed);
743 build_slash(0x80, 2, "ADC", OP_RM8_imm8, &Interpreter::ADC_RM8_imm8, LockPrefixAllowed);
744 build_slash(0x80, 3, "SBB", OP_RM8_imm8, &Interpreter::SBB_RM8_imm8, LockPrefixAllowed);
745 build_slash(0x80, 4, "AND", OP_RM8_imm8, &Interpreter::AND_RM8_imm8, LockPrefixAllowed);
746 build_slash(0x80, 5, "SUB", OP_RM8_imm8, &Interpreter::SUB_RM8_imm8, LockPrefixAllowed);
747 build_slash(0x80, 6, "XOR", OP_RM8_imm8, &Interpreter::XOR_RM8_imm8, LockPrefixAllowed);
748 build_slash(0x80, 7, "CMP", OP_RM8_imm8, &Interpreter::CMP_RM8_imm8);
749
750 build_slash(0x81, 0, "ADD", OP_RM16_imm16, &Interpreter::ADD_RM16_imm16, OP_RM32_imm32, &Interpreter::ADD_RM32_imm32, LockPrefixAllowed);
751 build_slash(0x81, 1, "OR", OP_RM16_imm16, &Interpreter::OR_RM16_imm16, OP_RM32_imm32, &Interpreter::OR_RM32_imm32, LockPrefixAllowed);
752 build_slash(0x81, 2, "ADC", OP_RM16_imm16, &Interpreter::ADC_RM16_imm16, OP_RM32_imm32, &Interpreter::ADC_RM32_imm32, LockPrefixAllowed);
753 build_slash(0x81, 3, "SBB", OP_RM16_imm16, &Interpreter::SBB_RM16_imm16, OP_RM32_imm32, &Interpreter::SBB_RM32_imm32, LockPrefixAllowed);
754 build_slash(0x81, 4, "AND", OP_RM16_imm16, &Interpreter::AND_RM16_imm16, OP_RM32_imm32, &Interpreter::AND_RM32_imm32, LockPrefixAllowed);
755 build_slash(0x81, 5, "SUB", OP_RM16_imm16, &Interpreter::SUB_RM16_imm16, OP_RM32_imm32, &Interpreter::SUB_RM32_imm32, LockPrefixAllowed);
756 build_slash(0x81, 6, "XOR", OP_RM16_imm16, &Interpreter::XOR_RM16_imm16, OP_RM32_imm32, &Interpreter::XOR_RM32_imm32, LockPrefixAllowed);
757 build_slash(0x81, 7, "CMP", OP_RM16_imm16, &Interpreter::CMP_RM16_imm16, OP_RM32_imm32, &Interpreter::CMP_RM32_imm32);
758
759 build_slash(0x83, 0, "ADD", OP_RM16_imm8, &Interpreter::ADD_RM16_imm8, OP_RM32_imm8, &Interpreter::ADD_RM32_imm8, LockPrefixAllowed);
760 build_slash(0x83, 1, "OR", OP_RM16_imm8, &Interpreter::OR_RM16_imm8, OP_RM32_imm8, &Interpreter::OR_RM32_imm8, LockPrefixAllowed);
761 build_slash(0x83, 2, "ADC", OP_RM16_imm8, &Interpreter::ADC_RM16_imm8, OP_RM32_imm8, &Interpreter::ADC_RM32_imm8, LockPrefixAllowed);
762 build_slash(0x83, 3, "SBB", OP_RM16_imm8, &Interpreter::SBB_RM16_imm8, OP_RM32_imm8, &Interpreter::SBB_RM32_imm8, LockPrefixAllowed);
763 build_slash(0x83, 4, "AND", OP_RM16_imm8, &Interpreter::AND_RM16_imm8, OP_RM32_imm8, &Interpreter::AND_RM32_imm8, LockPrefixAllowed);
764 build_slash(0x83, 5, "SUB", OP_RM16_imm8, &Interpreter::SUB_RM16_imm8, OP_RM32_imm8, &Interpreter::SUB_RM32_imm8, LockPrefixAllowed);
765 build_slash(0x83, 6, "XOR", OP_RM16_imm8, &Interpreter::XOR_RM16_imm8, OP_RM32_imm8, &Interpreter::XOR_RM32_imm8, LockPrefixAllowed);
766 build_slash(0x83, 7, "CMP", OP_RM16_imm8, &Interpreter::CMP_RM16_imm8, OP_RM32_imm8, &Interpreter::CMP_RM32_imm8);
767
768 build_slash(0x8F, 0, "POP", OP_RM16, &Interpreter::POP_RM16, OP_RM32, &Interpreter::POP_RM32);
769
770 build_slash(0xC0, 0, "ROL", OP_RM8_imm8, &Interpreter::ROL_RM8_imm8);
771 build_slash(0xC0, 1, "ROR", OP_RM8_imm8, &Interpreter::ROR_RM8_imm8);
772 build_slash(0xC0, 2, "RCL", OP_RM8_imm8, &Interpreter::RCL_RM8_imm8);
773 build_slash(0xC0, 3, "RCR", OP_RM8_imm8, &Interpreter::RCR_RM8_imm8);
774 build_slash(0xC0, 4, "SHL", OP_RM8_imm8, &Interpreter::SHL_RM8_imm8);
775 build_slash(0xC0, 5, "SHR", OP_RM8_imm8, &Interpreter::SHR_RM8_imm8);
776 build_slash(0xC0, 6, "SHL", OP_RM8_imm8, &Interpreter::SHL_RM8_imm8); // Undocumented
777 build_slash(0xC0, 7, "SAR", OP_RM8_imm8, &Interpreter::SAR_RM8_imm8);
778
779 build_slash(0xC1, 0, "ROL", OP_RM16_imm8, &Interpreter::ROL_RM16_imm8, OP_RM32_imm8, &Interpreter::ROL_RM32_imm8);
780 build_slash(0xC1, 1, "ROR", OP_RM16_imm8, &Interpreter::ROR_RM16_imm8, OP_RM32_imm8, &Interpreter::ROR_RM32_imm8);
781 build_slash(0xC1, 2, "RCL", OP_RM16_imm8, &Interpreter::RCL_RM16_imm8, OP_RM32_imm8, &Interpreter::RCL_RM32_imm8);
782 build_slash(0xC1, 3, "RCR", OP_RM16_imm8, &Interpreter::RCR_RM16_imm8, OP_RM32_imm8, &Interpreter::RCR_RM32_imm8);
783 build_slash(0xC1, 4, "SHL", OP_RM16_imm8, &Interpreter::SHL_RM16_imm8, OP_RM32_imm8, &Interpreter::SHL_RM32_imm8);
784 build_slash(0xC1, 5, "SHR", OP_RM16_imm8, &Interpreter::SHR_RM16_imm8, OP_RM32_imm8, &Interpreter::SHR_RM32_imm8);
785 build_slash(0xC1, 6, "SHL", OP_RM16_imm8, &Interpreter::SHL_RM16_imm8, OP_RM32_imm8, &Interpreter::SHL_RM32_imm8); // Undocumented
786 build_slash(0xC1, 7, "SAR", OP_RM16_imm8, &Interpreter::SAR_RM16_imm8, OP_RM32_imm8, &Interpreter::SAR_RM32_imm8);
787
788 build_slash(0xD0, 0, "ROL", OP_RM8_1, &Interpreter::ROL_RM8_1);
789 build_slash(0xD0, 1, "ROR", OP_RM8_1, &Interpreter::ROR_RM8_1);
790 build_slash(0xD0, 2, "RCL", OP_RM8_1, &Interpreter::RCL_RM8_1);
791 build_slash(0xD0, 3, "RCR", OP_RM8_1, &Interpreter::RCR_RM8_1);
792 build_slash(0xD0, 4, "SHL", OP_RM8_1, &Interpreter::SHL_RM8_1);
793 build_slash(0xD0, 5, "SHR", OP_RM8_1, &Interpreter::SHR_RM8_1);
794 build_slash(0xD0, 6, "SHL", OP_RM8_1, &Interpreter::SHL_RM8_1); // Undocumented
795 build_slash(0xD0, 7, "SAR", OP_RM8_1, &Interpreter::SAR_RM8_1);
796
797 build_slash(0xD1, 0, "ROL", OP_RM16_1, &Interpreter::ROL_RM16_1, OP_RM32_1, &Interpreter::ROL_RM32_1);
798 build_slash(0xD1, 1, "ROR", OP_RM16_1, &Interpreter::ROR_RM16_1, OP_RM32_1, &Interpreter::ROR_RM32_1);
799 build_slash(0xD1, 2, "RCL", OP_RM16_1, &Interpreter::RCL_RM16_1, OP_RM32_1, &Interpreter::RCL_RM32_1);
800 build_slash(0xD1, 3, "RCR", OP_RM16_1, &Interpreter::RCR_RM16_1, OP_RM32_1, &Interpreter::RCR_RM32_1);
801 build_slash(0xD1, 4, "SHL", OP_RM16_1, &Interpreter::SHL_RM16_1, OP_RM32_1, &Interpreter::SHL_RM32_1);
802 build_slash(0xD1, 5, "SHR", OP_RM16_1, &Interpreter::SHR_RM16_1, OP_RM32_1, &Interpreter::SHR_RM32_1);
803 build_slash(0xD1, 6, "SHL", OP_RM16_1, &Interpreter::SHL_RM16_1, OP_RM32_1, &Interpreter::SHL_RM32_1); // Undocumented
804 build_slash(0xD1, 7, "SAR", OP_RM16_1, &Interpreter::SAR_RM16_1, OP_RM32_1, &Interpreter::SAR_RM32_1);
805
806 build_slash(0xD2, 0, "ROL", OP_RM8_CL, &Interpreter::ROL_RM8_CL);
807 build_slash(0xD2, 1, "ROR", OP_RM8_CL, &Interpreter::ROR_RM8_CL);
808 build_slash(0xD2, 2, "RCL", OP_RM8_CL, &Interpreter::RCL_RM8_CL);
809 build_slash(0xD2, 3, "RCR", OP_RM8_CL, &Interpreter::RCR_RM8_CL);
810 build_slash(0xD2, 4, "SHL", OP_RM8_CL, &Interpreter::SHL_RM8_CL);
811 build_slash(0xD2, 5, "SHR", OP_RM8_CL, &Interpreter::SHR_RM8_CL);
812 build_slash(0xD2, 6, "SHL", OP_RM8_CL, &Interpreter::SHL_RM8_CL); // Undocumented
813 build_slash(0xD2, 7, "SAR", OP_RM8_CL, &Interpreter::SAR_RM8_CL);
814
815 build_slash(0xD3, 0, "ROL", OP_RM16_CL, &Interpreter::ROL_RM16_CL, OP_RM32_CL, &Interpreter::ROL_RM32_CL);
816 build_slash(0xD3, 1, "ROR", OP_RM16_CL, &Interpreter::ROR_RM16_CL, OP_RM32_CL, &Interpreter::ROR_RM32_CL);
817 build_slash(0xD3, 2, "RCL", OP_RM16_CL, &Interpreter::RCL_RM16_CL, OP_RM32_CL, &Interpreter::RCL_RM32_CL);
818 build_slash(0xD3, 3, "RCR", OP_RM16_CL, &Interpreter::RCR_RM16_CL, OP_RM32_CL, &Interpreter::RCR_RM32_CL);
819 build_slash(0xD3, 4, "SHL", OP_RM16_CL, &Interpreter::SHL_RM16_CL, OP_RM32_CL, &Interpreter::SHL_RM32_CL);
820 build_slash(0xD3, 5, "SHR", OP_RM16_CL, &Interpreter::SHR_RM16_CL, OP_RM32_CL, &Interpreter::SHR_RM32_CL);
821 build_slash(0xD3, 6, "SHL", OP_RM16_CL, &Interpreter::SHL_RM16_CL, OP_RM32_CL, &Interpreter::SHL_RM32_CL); // Undocumented
822 build_slash(0xD3, 7, "SAR", OP_RM16_CL, &Interpreter::SAR_RM16_CL, OP_RM32_CL, &Interpreter::SAR_RM32_CL);
823
824 build_slash(0xF6, 0, "TEST", OP_RM8_imm8, &Interpreter::TEST_RM8_imm8);
825 build_slash(0xF6, 1, "TEST", OP_RM8_imm8, &Interpreter::TEST_RM8_imm8); // Undocumented
826 build_slash(0xF6, 2, "NOT", OP_RM8, &Interpreter::NOT_RM8, LockPrefixAllowed);
827 build_slash(0xF6, 3, "NEG", OP_RM8, &Interpreter::NEG_RM8, LockPrefixAllowed);
828 build_slash(0xF6, 4, "MUL", OP_RM8, &Interpreter::MUL_RM8);
829 build_slash(0xF6, 5, "IMUL", OP_RM8, &Interpreter::IMUL_RM8);
830 build_slash(0xF6, 6, "DIV", OP_RM8, &Interpreter::DIV_RM8);
831 build_slash(0xF6, 7, "IDIV", OP_RM8, &Interpreter::IDIV_RM8);
832
833 build_slash(0xF7, 0, "TEST", OP_RM16_imm16, &Interpreter::TEST_RM16_imm16, OP_RM32_imm32, &Interpreter::TEST_RM32_imm32);
834 build_slash(0xF7, 1, "TEST", OP_RM16_imm16, &Interpreter::TEST_RM16_imm16, OP_RM32_imm32, &Interpreter::TEST_RM32_imm32); // Undocumented
835 build_slash(0xF7, 2, "NOT", OP_RM16, &Interpreter::NOT_RM16, OP_RM32, &Interpreter::NOT_RM32, LockPrefixAllowed);
836 build_slash(0xF7, 3, "NEG", OP_RM16, &Interpreter::NEG_RM16, OP_RM32, &Interpreter::NEG_RM32, LockPrefixAllowed);
837 build_slash(0xF7, 4, "MUL", OP_RM16, &Interpreter::MUL_RM16, OP_RM32, &Interpreter::MUL_RM32);
838 build_slash(0xF7, 5, "IMUL", OP_RM16, &Interpreter::IMUL_RM16, OP_RM32, &Interpreter::IMUL_RM32);
839 build_slash(0xF7, 6, "DIV", OP_RM16, &Interpreter::DIV_RM16, OP_RM32, &Interpreter::DIV_RM32);
840 build_slash(0xF7, 7, "IDIV", OP_RM16, &Interpreter::IDIV_RM16, OP_RM32, &Interpreter::IDIV_RM32);
841
842 build_slash(0xFE, 0, "INC", OP_RM8, &Interpreter::INC_RM8, LockPrefixAllowed);
843 build_slash(0xFE, 1, "DEC", OP_RM8, &Interpreter::DEC_RM8, LockPrefixAllowed);
844
845 build_slash(0xFF, 0, "INC", OP_RM16, &Interpreter::INC_RM16, OP_RM32, &Interpreter::INC_RM32, LockPrefixAllowed);
846 build_slash(0xFF, 1, "DEC", OP_RM16, &Interpreter::DEC_RM16, OP_RM32, &Interpreter::DEC_RM32, LockPrefixAllowed);
847 build_slash(0xFF, 2, "CALL", OP_RM16, &Interpreter::CALL_RM16, OP_RM32, &Interpreter::CALL_RM32);
848 build_slash(0xFF, 3, "CALL", OP_FAR_mem16, &Interpreter::CALL_FAR_mem16, OP_FAR_mem32, &Interpreter::CALL_FAR_mem32);
849 build_slash(0xFF, 4, "JMP", OP_RM16, &Interpreter::JMP_RM16, OP_RM32, &Interpreter::JMP_RM32);
850 build_slash(0xFF, 5, "JMP", OP_FAR_mem16, &Interpreter::JMP_FAR_mem16, OP_FAR_mem32, &Interpreter::JMP_FAR_mem32);
851 build_slash(0xFF, 6, "PUSH", OP_RM16, &Interpreter::PUSH_RM16, OP_RM32, &Interpreter::PUSH_RM32);
852
853 // Instructions starting with 0x0F are multi-byte opcodes.
854 build_0f_slash(0x00, 0, "SLDT", OP_RM16, &Interpreter::SLDT_RM16);
855 build_0f_slash(0x00, 1, "STR", OP_RM16, &Interpreter::STR_RM16);
856 build_0f_slash(0x00, 2, "LLDT", OP_RM16, &Interpreter::LLDT_RM16);
857 build_0f_slash(0x00, 3, "LTR", OP_RM16, &Interpreter::LTR_RM16);
858 build_0f_slash(0x00, 4, "VERR", OP_RM16, &Interpreter::VERR_RM16);
859 build_0f_slash(0x00, 5, "VERW", OP_RM16, &Interpreter::VERW_RM16);
860
861 build_0f_slash(0x01, 0, "SGDT", OP_RM16, &Interpreter::SGDT);
862 build_0f_slash(0x01, 1, "SIDT", OP_RM16, &Interpreter::SIDT);
863 build_0f_slash(0x01, 2, "LGDT", OP_RM16, &Interpreter::LGDT);
864 build_0f_slash(0x01, 3, "LIDT", OP_RM16, &Interpreter::LIDT);
865 build_0f_slash(0x01, 4, "SMSW", OP_RM16, &Interpreter::SMSW_RM16);
866 build_0f_slash(0x01, 6, "LMSW", OP_RM16, &Interpreter::LMSW_RM16);
867 build_0f_slash(0x01, 7, "INVLPG", OP_RM32, &Interpreter::INVLPG);
868
869 build_0f_slash(0x18, 0, "PREFETCHTNTA", OP_RM8, &Interpreter::PREFETCHTNTA);
870 build_0f_slash(0x18, 1, "PREFETCHT0", OP_RM8, &Interpreter::PREFETCHT0);
871 build_0f_slash(0x18, 2, "PREFETCHT1", OP_RM8, &Interpreter::PREFETCHT1);
872 build_0f_slash(0x18, 3, "PREFETCHT2", OP_RM8, &Interpreter::PREFETCHT2);
873
874 build_0f_slash(0x1f, 0, "NOP", OP_RM32, &Interpreter::NOP);
875
876 // FIXME: Technically NoPrefix (sse_np_slash?)
877 build_0f_slash(0xAE, 2, "LDMXCSR", OP_RM32, &Interpreter::LDMXCSR);
878 build_0f_slash(0xAE, 3, "STMXCSR", OP_RM32, &Interpreter::STMXCSR);
879 // FIXME: SFENCE: NP 0F AE F8
880
881 build_0f_slash(0xBA, 4, "BT", OP_RM16_imm8, &Interpreter::BT_RM16_imm8, OP_RM32_imm8, &Interpreter::BT_RM32_imm8, LockPrefixAllowed);
882 build_0f_slash(0xBA, 5, "BTS", OP_RM16_imm8, &Interpreter::BTS_RM16_imm8, OP_RM32_imm8, &Interpreter::BTS_RM32_imm8, LockPrefixAllowed);
883 build_0f_slash(0xBA, 6, "BTR", OP_RM16_imm8, &Interpreter::BTR_RM16_imm8, OP_RM32_imm8, &Interpreter::BTR_RM32_imm8, LockPrefixAllowed);
884 build_0f_slash(0xBA, 7, "BTC", OP_RM16_imm8, &Interpreter::BTC_RM16_imm8, OP_RM32_imm8, &Interpreter::BTC_RM32_imm8, LockPrefixAllowed);
885
886 build_0f(0x02, "LAR", OP_reg16_RM16, &Interpreter::LAR_reg16_RM16, OP_reg32_RM32, &Interpreter::LAR_reg32_RM32);
887 build_0f(0x03, "LSL", OP_reg16_RM16, &Interpreter::LSL_reg16_RM16, OP_reg32_RM32, &Interpreter::LSL_reg32_RM32);
888 build_0f(0x06, "CLTS", OP, &Interpreter::CLTS);
889 build_0f(0x09, "WBINVD", OP, &Interpreter::WBINVD);
890 build_0f(0x0B, "UD2", OP, &Interpreter::UD2);
891
892 build_sse_np(0x10, "MOVUPS", OP_xmm1_xmm2m128, &Interpreter::MOVUPS_xmm1_xmm2m128);
893 build_sse_66(0x10, "MOVUPD", OP_xmm1_xmm2m128, &Interpreter::MOVUPD_xmm1_xmm2m128);
894 build_sse_f3(0x10, "MOVSS", OP_xmm1_xmm2m32, &Interpreter::MOVSS_xmm1_xmm2m32);
895 build_sse_f2(0x10, "MOVSD", OP_xmm1_xmm2m32, &Interpreter::MOVSD_xmm1_xmm2m32);
896 build_sse_np(0x11, "MOVUPS", OP_xmm1m128_xmm2, &Interpreter::MOVUPS_xmm1m128_xmm2);
897 build_sse_66(0x11, "MOVUPD", OP_xmm1m128_xmm2, &Interpreter::MOVUPD_xmm1m128_xmm2);
898 build_sse_f3(0x11, "MOVSS", OP_xmm1m32_xmm2, &Interpreter::MOVSS_xmm1m32_xmm2);
899 build_sse_f2(0x11, "MOVSD", OP_xmm1m32_xmm2, &Interpreter::MOVSD_xmm1m32_xmm2);
900 build_sse_np(0x12, "MOVLPS", OP_xmm1_xmm2m64, &Interpreter::MOVLPS_xmm1_xmm2m64); // FIXME: This mnemonic is MOVHLPS when providing xmm2
901 build_sse_66(0x12, "MOVLPD", OP_xmm1_m64, &Interpreter::MOVLPD_xmm1_m64);
902 build_sse_np(0x13, "MOVLPS", OP_m64_xmm2, &Interpreter::MOVLPS_m64_xmm2);
903 build_sse_66(0x13, "MOVLPD", OP_m64_xmm2, &Interpreter::MOVLPD_m64_xmm2);
904 build_sse_np(0x14, "UNPCKLPS", OP_xmm1_xmm2m128, &Interpreter::UNPCKLPS_xmm1_xmm2m128);
905 build_sse_66(0x14, "UNPCKLPD", OP_xmm1_xmm2m128, &Interpreter::UNPCKLPD_xmm1_xmm2m128);
906 build_sse_np(0x15, "UNPCKHPS", OP_xmm1_xmm2m128, &Interpreter::UNPCKHPS_xmm1_xmm2m128);
907 build_sse_66(0x15, "UNPCKHPD", OP_xmm1_xmm2m128, &Interpreter::UNPCKHPD_xmm1_xmm2m128);
908 build_sse_np(0x16, "MOVHPS", OP_xmm1_xmm2m64, &Interpreter::MOVHPS_xmm1_xmm2m64); // FIXME: This mnemonic is MOVLHPS when providing xmm2
909 build_sse_66(0x16, "MOVHPD", OP_xmm1_xmm2m64, &Interpreter::MOVHPD_xmm1_xmm2m64); // FIXME: This mnemonic is MOVLHPS when providing xmm2
910 build_sse_np(0x17, "MOVHPS", OP_m64_xmm2, &Interpreter::MOVHPS_m64_xmm2);
911
912 build_0f(0x20, "MOV", OP_reg32_CR, &Interpreter::MOV_reg32_CR);
913 build_0f(0x21, "MOV", OP_reg32_DR, &Interpreter::MOV_reg32_DR);
914 build_0f(0x22, "MOV", OP_CR_reg32, &Interpreter::MOV_CR_reg32);
915 build_0f(0x23, "MOV", OP_DR_reg32, &Interpreter::MOV_DR_reg32);
916
917 build_sse_np(0x28, "MOVAPS", OP_xmm1_xmm2m128, &Interpreter::MOVAPS_xmm1_xmm2m128);
918 build_sse_66(0x28, "MOVAPD", OP_xmm1_xmm2m128, &Interpreter::MOVAPD_xmm1_xmm2m128);
919 build_sse_np(0x29, "MOVAPS", OP_xmm1m128_xmm2, &Interpreter::MOVAPS_xmm1m128_xmm2);
920 build_sse_66(0x29, "MOVAPD", OP_xmm1m128_xmm2, &Interpreter::MOVAPD_xmm1m128_xmm2);
921
922 build_sse_np(0x2A, "CVTPI2PS", OP_xmm1_mm2m64, &Interpreter::CVTPI2PS_xmm1_mm2m64);
923 build_sse_66(0x2A, "CVTPI2PD", OP_xmm1_mm2m64, &Interpreter::CVTPI2PD_xmm1_mm2m64);
924 build_sse_f3(0x2A, "CVTSI2SS", OP_xmm1_rm32, &Interpreter::CVTSI2SS_xmm1_rm32);
925 build_sse_f2(0x2A, "CVTSI2SD", OP_xmm1_rm32, &Interpreter::CVTSI2SD_xmm1_rm32);
926 build_sse_np(0x2B, "MOVNTPS", OP_xmm1m128_xmm2, &Interpreter::MOVNTPS_xmm1m128_xmm2);
927 build_sse_np(0x2C, "CVTTPS2PI", OP_mm1_xmm2m64, &Interpreter::CVTTPS2PI_mm1_xmm2m64);
928 build_sse_66(0x2C, "CVTTPD2PI", OP_mm1_xmm2m128, &Interpreter::CVTTPD2PI_mm1_xmm2m128);
929 build_sse_f3(0x2C, "CVTTSS2SI", OP_r32_xmm2m32, &Interpreter::CVTTSS2SI_r32_xmm2m32);
930 build_sse_f2(0x2C, "CVTTSD2SI", OP_r32_xmm2m64, &Interpreter::CVTTSS2SI_r32_xmm2m64);
931 build_sse_np(0x2D, "CVTPS2PI", OP_mm1_xmm2m64, &Interpreter::CVTPS2PI_xmm1_mm2m64);
932 build_sse_66(0x2D, "CVTPD2PI", OP_mm1_xmm2m128, &Interpreter::CVTPD2PI_xmm1_mm2m128);
933 build_sse_f3(0x2D, "CVTSS2SI", OP_r32_xmm2m32, &Interpreter::CVTSS2SI_r32_xmm2m32);
934 build_sse_f2(0x2D, "CVTSD2SI", OP_r32_xmm2m64, &Interpreter::CVTSD2SI_xmm1_rm64);
935 build_sse_np(0x2E, "UCOMISS", OP_xmm1_xmm2m32, &Interpreter::UCOMISS_xmm1_xmm2m32);
936 build_sse_66(0x2E, "UCOMISD", OP_xmm1_xmm2m64, &Interpreter::UCOMISD_xmm1_xmm2m64);
937 build_sse_np(0x2F, "COMISS", OP_xmm1_xmm2m32, &Interpreter::COMISS_xmm1_xmm2m32);
938 build_sse_66(0x2F, "COMISD", OP_xmm1_xmm2m64, &Interpreter::COMISD_xmm1_xmm2m64);
939
940 build_0f(0x31, "RDTSC", OP, &Interpreter::RDTSC);
941
942 build_0f(0x40, "CMOVO", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
943 build_0f(0x41, "CMOVNO", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
944 build_0f(0x42, "CMOVC", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
945 build_0f(0x43, "CMOVNC", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
946 build_0f(0x44, "CMOVZ", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
947 build_0f(0x45, "CMOVNZ", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
948 build_0f(0x46, "CMOVNA", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
949 build_0f(0x47, "CMOVA", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
950 build_0f(0x48, "CMOVS", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
951 build_0f(0x49, "CMOVNS", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
952 build_0f(0x4A, "CMOVP", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
953 build_0f(0x4B, "CMOVNP", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
954 build_0f(0x4C, "CMOVL", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
955 build_0f(0x4D, "CMOVNL", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
956 build_0f(0x4E, "CMOVNG", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
957 build_0f(0x4F, "CMOVG", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32);
958
959 build_sse_np(0x50, "MOVMSKPS", OP_reg_xmm1, &Interpreter::MOVMSKPS_reg_xmm);
960 build_sse_66(0x50, "MOVMSKPD", OP_reg_xmm1, &Interpreter::MOVMSKPD_reg_xmm);
961 build_sse_np(0x51, "SQRTPS", OP_xmm1_xmm2m128, &Interpreter::SQRTPS_xmm1_xmm2m128);
962 build_sse_66(0x51, "SQRTPD", OP_xmm1_xmm2m128, &Interpreter::SQRTPD_xmm1_xmm2m128);
963 build_sse_f3(0x51, "SQRTSS", OP_xmm1_xmm2m32, &Interpreter::SQRTSS_xmm1_xmm2m32);
964 build_sse_f2(0x51, "SQRTSD", OP_xmm1_xmm2m32, &Interpreter::SQRTSD_xmm1_xmm2m32);
965 build_sse_np(0x52, "RSQRTPS", OP_xmm1_xmm2m128, &Interpreter::RSQRTPS_xmm1_xmm2m128);
966 build_sse_f3(0x52, "RSQRTSS", OP_xmm1_xmm2m32, &Interpreter::RSQRTSS_xmm1_xmm2m32);
967 build_sse_np(0x53, "RCPPS", OP_xmm1_xmm2m128, &Interpreter::RCPPS_xmm1_xmm2m128);
968 build_sse_f3(0x53, "RCPSS", OP_xmm1_xmm2m32, &Interpreter::RCPSS_xmm1_xmm2m32);
969 build_sse_np(0x54, "ANDPS", OP_xmm1_xmm2m128, &Interpreter::ANDPS_xmm1_xmm2m128);
970 build_sse_66(0x54, "ANDPD", OP_xmm1_xmm2m128, &Interpreter::ANDPD_xmm1_xmm2m128);
971 build_sse_np(0x55, "ANDNPS", OP_xmm1_xmm2m128, &Interpreter::ANDNPS_xmm1_xmm2m128);
972 build_sse_66(0x55, "ANDNPD", OP_xmm1_xmm2m128, &Interpreter::ANDNPD_xmm1_xmm2m128);
973 build_sse_np(0x56, "ORPS", OP_xmm1_xmm2m128, &Interpreter::ORPS_xmm1_xmm2m128);
974 build_sse_66(0x56, "ORPD", OP_xmm1_xmm2m128, &Interpreter::ORPD_xmm1_xmm2m128);
975 build_sse_np(0x57, "XORPS", OP_xmm1_xmm2m128, &Interpreter::XORPS_xmm1_xmm2m128);
976 build_sse_66(0x57, "XORPD", OP_xmm1_xmm2m128, &Interpreter::XORPD_xmm1_xmm2m128);
977
978 build_sse_np(0x58, "ADDPS", OP_xmm1_xmm2m128, &Interpreter::ADDPS_xmm1_xmm2m128);
979 build_sse_66(0x58, "ADDPD", OP_xmm1_xmm2m128, &Interpreter::ADDPD_xmm1_xmm2m128);
980 build_sse_f3(0x58, "ADDSS", OP_xmm1_xmm2m32, &Interpreter::ADDSS_xmm1_xmm2m32);
981 build_sse_f2(0x58, "ADDSD", OP_xmm1_xmm2m32, &Interpreter::ADDSD_xmm1_xmm2m32);
982 build_sse_np(0x59, "MULPS", OP_xmm1_xmm2m128, &Interpreter::MULPS_xmm1_xmm2m128);
983 build_sse_66(0x59, "MULPD", OP_xmm1_xmm2m128, &Interpreter::MULPD_xmm1_xmm2m128);
984 build_sse_f3(0x59, "MULSS", OP_xmm1_xmm2m32, &Interpreter::MULSS_xmm1_xmm2m32);
985 build_sse_f2(0x59, "MULSD", OP_xmm1_xmm2m32, &Interpreter::MULSD_xmm1_xmm2m32);
986 build_sse_np(0x5A, "CVTPS2PD", OP_xmm1_xmm2m64, &Interpreter::CVTPS2PD_xmm1_xmm2m64);
987 build_sse_66(0x5A, "CVTPD2PS", OP_xmm1_xmm2m128, &Interpreter::CVTPD2PS_xmm1_xmm2m128);
988 build_sse_f3(0x5A, "CVTSS2SD", OP_xmm1_xmm2m32, &Interpreter::CVTSS2SD_xmm1_xmm2m32);
989 build_sse_f2(0x5A, "CVTSD2SS", OP_xmm1_xmm2m64, &Interpreter::CVTSD2SS_xmm1_xmm2m64);
990 build_sse_np(0x5B, "CVTDQ2PS", OP_xmm1_xmm2m128, &Interpreter::CVTDQ2PS_xmm1_xmm2m128);
991 build_sse_66(0x5B, "CVTPS2DQ", OP_xmm1_xmm2m128, &Interpreter::CVTPS2DQ_xmm1_xmm2m128);
992 build_sse_f3(0x5B, "CVTTPS2DQ", OP_xmm1_xmm2m128, &Interpreter::CVTTPS2DQ_xmm1_xmm2m128);
993
994 build_sse_np(0x5C, "SUBPS", OP_xmm1_xmm2m128, &Interpreter::SUBPS_xmm1_xmm2m128);
995 build_sse_66(0x5C, "SUBPD", OP_xmm1_xmm2m128, &Interpreter::SUBPD_xmm1_xmm2m128);
996 build_sse_f3(0x5C, "SUBSS", OP_xmm1_xmm2m32, &Interpreter::SUBSS_xmm1_xmm2m32);
997 build_sse_f2(0x5C, "SUBSD", OP_xmm1_xmm2m32, &Interpreter::SUBSD_xmm1_xmm2m32);
998 build_sse_np(0x5D, "MINPS", OP_xmm1_xmm2m128, &Interpreter::MINPS_xmm1_xmm2m128);
999 build_sse_66(0x5D, "MINPD", OP_xmm1_xmm2m128, &Interpreter::MINPD_xmm1_xmm2m128);
1000 build_sse_f3(0x5D, "MINSS", OP_xmm1_xmm2m32, &Interpreter::MINSS_xmm1_xmm2m32);
1001 build_sse_f2(0x5D, "MINSD", OP_xmm1_xmm2m32, &Interpreter::MINSD_xmm1_xmm2m32);
1002 build_sse_np(0x5E, "DIVPS", OP_xmm1_xmm2m128, &Interpreter::DIVPS_xmm1_xmm2m128);
1003 build_sse_66(0x5E, "DIVPD", OP_xmm1_xmm2m128, &Interpreter::DIVPD_xmm1_xmm2m128);
1004 build_sse_f3(0x5E, "DIVSS", OP_xmm1_xmm2m32, &Interpreter::DIVSS_xmm1_xmm2m32);
1005 build_sse_f2(0x5E, "DIVSD", OP_xmm1_xmm2m32, &Interpreter::DIVSD_xmm1_xmm2m32);
1006 build_sse_np(0x5F, "MAXPS", OP_xmm1_xmm2m128, &Interpreter::MAXPS_xmm1_xmm2m128);
1007 build_sse_66(0x5F, "MAXPD", OP_xmm1_xmm2m128, &Interpreter::MAXPD_xmm1_xmm2m128);
1008 build_sse_f3(0x5F, "MAXSS", OP_xmm1_xmm2m32, &Interpreter::MAXSS_xmm1_xmm2m32);
1009 build_sse_f2(0x5F, "MAXSD", OP_xmm1_xmm2m32, &Interpreter::MAXSD_xmm1_xmm2m32);
1010
1011 build_0f(0x60, "PUNPCKLBW", OP_mm1_mm2m32, &Interpreter::PUNPCKLBW_mm1_mm2m32);
1012 build_0f(0x61, "PUNPCKLWD", OP_mm1_mm2m32, &Interpreter::PUNPCKLWD_mm1_mm2m32);
1013 build_0f(0x62, "PUNPCKLDQ", OP_mm1_mm2m32, &Interpreter::PUNPCKLDQ_mm1_mm2m32);
1014 build_0f(0x63, "PACKSSWB", OP_mm1_mm2m64, &Interpreter::PACKSSWB_mm1_mm2m64);
1015 build_0f(0x64, "PCMPGTB", OP_mm1_mm2m64, &Interpreter::PCMPGTB_mm1_mm2m64);
1016 build_0f(0x65, "PCMPGTW", OP_mm1_mm2m64, &Interpreter::PCMPGTW_mm1_mm2m64);
1017 build_0f(0x66, "PCMPGTD", OP_mm1_mm2m64, &Interpreter::PCMPGTD_mm1_mm2m64);
1018 build_0f(0x67, "PACKUSWB", OP_mm1_mm2m64, &Interpreter::PACKUSWB_mm1_mm2m64);
1019 build_0f(0x68, "PUNPCKHBW", OP_mm1_mm2m64, &Interpreter::PUNPCKHBW_mm1_mm2m64);
1020 build_0f(0x69, "PUNPCKHWD", OP_mm1_mm2m64, &Interpreter::PUNPCKHWD_mm1_mm2m64);
1021 build_0f(0x6A, "PUNPCKHDQ", OP_mm1_mm2m64, &Interpreter::PUNPCKHDQ_mm1_mm2m64);
1022 build_0f(0x6B, "PACKSSDW", OP_mm1_mm2m64, &Interpreter::PACKSSDW_mm1_mm2m64);
1023 build_sse_66(0x6C, "PUNPCKLQDQ", OP_xmm1_xmm2m128, &Interpreter::PUNPCKLQDQ_xmm1_xmm2m128);
1024 build_sse_66(0x6D, "PUNPCKHQDQ", OP_xmm1_xmm2m128, &Interpreter::PUNPCKHQDQ_xmm1_xmm2m128);
1025 build_0f(0x6E, "MOVD", OP_mm1_rm32, &Interpreter::MOVD_mm1_rm32); // FIXME: REX.W -> MOVQ
1026 build_sse_np(0x6F, "MOVQ", OP_mm1_mm2m64, &Interpreter::MOVQ_mm1_mm2m64);
1027 build_sse_66(0x6F, "MOVDQA", OP_xmm1_xmm2m128, &Interpreter::MOVDQA_xmm1_xmm2m128);
1028 build_sse_f3(0x6F, "MOVDQU", OP_xmm1_xmm2m128, &Interpreter::MOVDQU_xmm1_xmm2m128);
1029
1030 build_sse_np(0x70, "PSHUFW", OP_mm1_mm2m64_imm8, &Interpreter::PSHUFW_mm1_mm2m64_imm8);
1031 build_sse_66(0x70, "PSHUFD", OP_xmm1_xmm2m128_imm8, &Interpreter::PSHUFD_xmm1_xmm2m128_imm8);
1032 build_sse_f3(0x70, "PSHUFHW", OP_xmm1_xmm2m128_imm8, &Interpreter::PSHUFHW_xmm1_xmm2m128_imm8);
1033 build_sse_f2(0x70, "PSHUFLW", OP_xmm1_xmm2m128_imm8, &Interpreter::PSHUFLW_xmm1_xmm2m128_imm8);
1034 build_0f_slash(0x71, 2, "PSRLW", OP_mm1_imm8, &Interpreter::PSRLW_mm1_imm8);
1035 build_0f_slash(0x71, 4, "PSRAW", OP_mm1_imm8, &Interpreter::PSRAW_mm1_imm8);
1036 build_0f_slash(0x71, 6, "PSLLW", OP_mm1_imm8, &Interpreter::PSLLD_mm1_imm8);
1037
1038 build_0f_slash(0x72, 2, "PSRLD", OP_mm1_imm8, &Interpreter::PSRLD_mm1_imm8);
1039 build_0f_slash(0x72, 4, "PSRAD", OP_mm1_imm8, &Interpreter::PSRAD_mm1_imm8);
1040 build_0f_slash(0x72, 6, "PSLLW", OP_mm1_imm8, &Interpreter::PSLLW_mm1_imm8);
1041
1042 build_sse_np_slash(0x73, 2, "PSRLQ", OP_mm1_imm8, &Interpreter::PSRLQ_mm1_imm8);
1043 build_sse_66_slash(0x73, 2, "PSRLQ", OP_xmm1_imm8, &Interpreter::PSRLQ_xmm1_imm8);
1044 build_sse_66_slash(0x73, 3, "PSRLDQ", OP_xmm1_imm8, &Interpreter::PSRLDQ_xmm1_imm8);
1045 build_sse_np_slash(0x73, 6, "PSLLQ", OP_mm1_imm8, &Interpreter::PSLLQ_mm1_imm8);
1046 build_sse_66_slash(0x73, 6, "PSLLQ", OP_xmm1_imm8, &Interpreter::PSLLQ_xmm1_imm8);
1047 build_sse_66_slash(0x73, 7, "PSLLDQ", OP_xmm1_imm8, &Interpreter::PSLLDQ_xmm1_imm8);
1048
1049 build_0f(0x74, "PCMPEQB", OP_mm1_mm2m64, &Interpreter::PCMPEQB_mm1_mm2m64);
1050 build_0f(0x75, "PCMPEQW", OP_mm1_mm2m64, &Interpreter::PCMPEQW_mm1_mm2m64);
1051 build_0f(0x76, "PCMPEQD", OP_mm1_mm2m64, &Interpreter::PCMPEQD_mm1_mm2m64);
1052 build_0f(0x77, "EMMS", OP, &Interpreter::EMMS); // Technically NP
1053 build_sse_np(0x7E, "MOVD", OP_rm32_mm2, &Interpreter::MOVD_rm32_mm2); // FIXME: REW.W -> MOVQ
1054 build_sse_66(0x7E, "MOVD", OP_rm32_xmm2, &Interpreter::MOVD_rm32_xmm2); // FIXME: REW.W -> MOVQ
1055 build_sse_f3(0x7E, "MOVQ", OP_xmm1_xmm2m128, &Interpreter::MOVQ_xmm1_xmm2m128);
1056 build_sse_np(0x7F, "MOVQ", OP_mm1m64_mm2, &Interpreter::MOVQ_mm1m64_mm2);
1057 build_sse_66(0x7F, "MOVDQA", OP_xmm1m128_xmm2, &Interpreter::MOVDQA_xmm1m128_xmm2);
1058 build_sse_f3(0x7F, "MOVDQU", OP_xmm1m128_xmm2, &Interpreter::MOVDQU_xmm1m128_xmm2);
1059
1060 build_0f(0x80, "JO", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1061 build_0f(0x81, "JNO", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1062 build_0f(0x82, "JC", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1063 build_0f(0x83, "JNC", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1064 build_0f(0x84, "JZ", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1065 build_0f(0x85, "JNZ", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1066 build_0f(0x86, "JNA", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1067 build_0f(0x87, "JA", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1068 build_0f(0x88, "JS", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1069 build_0f(0x89, "JNS", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1070 build_0f(0x8A, "JP", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1071 build_0f(0x8B, "JNP", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1072 build_0f(0x8C, "JL", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1073 build_0f(0x8D, "JNL", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1074 build_0f(0x8E, "JNG", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1075 build_0f(0x8F, "JG", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm);
1076
1077 build_0f(0x90, "SETO", OP_RM8, &Interpreter::SETcc_RM8);
1078 build_0f(0x91, "SETNO", OP_RM8, &Interpreter::SETcc_RM8);
1079 build_0f(0x92, "SETC", OP_RM8, &Interpreter::SETcc_RM8);
1080 build_0f(0x93, "SETNC", OP_RM8, &Interpreter::SETcc_RM8);
1081 build_0f(0x94, "SETZ", OP_RM8, &Interpreter::SETcc_RM8);
1082 build_0f(0x95, "SETNZ", OP_RM8, &Interpreter::SETcc_RM8);
1083 build_0f(0x96, "SETNA", OP_RM8, &Interpreter::SETcc_RM8);
1084 build_0f(0x97, "SETA", OP_RM8, &Interpreter::SETcc_RM8);
1085 build_0f(0x98, "SETS", OP_RM8, &Interpreter::SETcc_RM8);
1086 build_0f(0x99, "SETNS", OP_RM8, &Interpreter::SETcc_RM8);
1087 build_0f(0x9A, "SETP", OP_RM8, &Interpreter::SETcc_RM8);
1088 build_0f(0x9B, "SETNP", OP_RM8, &Interpreter::SETcc_RM8);
1089 build_0f(0x9C, "SETL", OP_RM8, &Interpreter::SETcc_RM8);
1090 build_0f(0x9D, "SETNL", OP_RM8, &Interpreter::SETcc_RM8);
1091 build_0f(0x9E, "SETNG", OP_RM8, &Interpreter::SETcc_RM8);
1092 build_0f(0x9F, "SETG", OP_RM8, &Interpreter::SETcc_RM8);
1093
1094 build_0f(0xA0, "PUSH", OP_FS, &Interpreter::PUSH_FS);
1095 build_0f(0xA1, "POP", OP_FS, &Interpreter::POP_FS);
1096 build_0f(0xA2, "CPUID", OP, &Interpreter::CPUID);
1097 build_0f(0xA3, "BT", OP_RM16_reg16, &Interpreter::BT_RM16_reg16, OP_RM32_reg32, &Interpreter::BT_RM32_reg32);
1098 build_0f(0xA4, "SHLD", OP_RM16_reg16_imm8, &Interpreter::SHLD_RM16_reg16_imm8, OP_RM32_reg32_imm8, &Interpreter::SHLD_RM32_reg32_imm8);
1099 build_0f(0xA5, "SHLD", OP_RM16_reg16_CL, &Interpreter::SHLD_RM16_reg16_CL, OP_RM32_reg32_CL, &Interpreter::SHLD_RM32_reg32_CL);
1100 build_0f(0xA8, "PUSH", OP_GS, &Interpreter::PUSH_GS);
1101 build_0f(0xA9, "POP", OP_GS, &Interpreter::POP_GS);
1102 build_0f(0xAB, "BTS", OP_RM16_reg16, &Interpreter::BTS_RM16_reg16, OP_RM32_reg32, &Interpreter::BTS_RM32_reg32);
1103 build_0f(0xAC, "SHRD", OP_RM16_reg16_imm8, &Interpreter::SHRD_RM16_reg16_imm8, OP_RM32_reg32_imm8, &Interpreter::SHRD_RM32_reg32_imm8);
1104 build_0f(0xAD, "SHRD", OP_RM16_reg16_CL, &Interpreter::SHRD_RM16_reg16_CL, OP_RM32_reg32_CL, &Interpreter::SHRD_RM32_reg32_CL);
1105 build_0f(0xAF, "IMUL", OP_reg16_RM16, &Interpreter::IMUL_reg16_RM16, OP_reg32_RM32, &Interpreter::IMUL_reg32_RM32);
1106 build_0f(0xB0, "CMPXCHG", OP_RM8_reg8, &Interpreter::CMPXCHG_RM8_reg8, LockPrefixAllowed);
1107 build_0f(0xB1, "CMPXCHG", OP_RM16_reg16, &Interpreter::CMPXCHG_RM16_reg16, OP_RM32_reg32, &Interpreter::CMPXCHG_RM32_reg32, LockPrefixAllowed);
1108 build_0f(0xB2, "LSS", OP_reg16_mem16, &Interpreter::LSS_reg16_mem16, OP_reg32_mem32, &Interpreter::LSS_reg32_mem32);
1109 build_0f(0xB3, "BTR", OP_RM16_reg16, &Interpreter::BTR_RM16_reg16, OP_RM32_reg32, &Interpreter::BTR_RM32_reg32);
1110 build_0f(0xB4, "LFS", OP_reg16_mem16, &Interpreter::LFS_reg16_mem16, OP_reg32_mem32, &Interpreter::LFS_reg32_mem32);
1111 build_0f(0xB5, "LGS", OP_reg16_mem16, &Interpreter::LGS_reg16_mem16, OP_reg32_mem32, &Interpreter::LGS_reg32_mem32);
1112 build_0f(0xB6, "MOVZX", OP_reg16_RM8, &Interpreter::MOVZX_reg16_RM8, OP_reg32_RM8, &Interpreter::MOVZX_reg32_RM8);
1113 build_0f(0xB7, "0xB7", OP, nullptr, "MOVZX", OP_reg32_RM16, &Interpreter::MOVZX_reg32_RM16);
1114 build_0f(0xB9, "UD1", OP, &Interpreter::UD1);
1115 build_0f(0xBB, "BTC", OP_RM16_reg16, &Interpreter::BTC_RM16_reg16, OP_RM32_reg32, &Interpreter::BTC_RM32_reg32);
1116 build_0f(0xBC, "BSF", OP_reg16_RM16, &Interpreter::BSF_reg16_RM16, OP_reg32_RM32, &Interpreter::BSF_reg32_RM32);
1117 build_0f(0xBD, "BSR", OP_reg16_RM16, &Interpreter::BSR_reg16_RM16, OP_reg32_RM32, &Interpreter::BSR_reg32_RM32);
1118 build_0f(0xBE, "MOVSX", OP_reg16_RM8, &Interpreter::MOVSX_reg16_RM8, OP_reg32_RM8, &Interpreter::MOVSX_reg32_RM8);
1119 build_0f(0xBF, "0xBF", OP, nullptr, "MOVSX", OP_reg32_RM16, &Interpreter::MOVSX_reg32_RM16);
1120 build_0f(0xC0, "XADD", OP_RM8_reg8, &Interpreter::XADD_RM8_reg8, LockPrefixAllowed);
1121 build_0f(0xC1, "XADD", OP_RM16_reg16, &Interpreter::XADD_RM16_reg16, OP_RM32_reg32, &Interpreter::XADD_RM32_reg32, LockPrefixAllowed);
1122 build_sse_np(0xC2, "CMPPS", OP_xmm1_xmm2m128_imm8, &Interpreter::CMPPS_xmm1_xmm2m128_imm8);
1123 build_sse_66(0xC2, "CMPPD", OP_xmm1_xmm2m128_imm8, &Interpreter::CMPPD_xmm1_xmm2m128_imm8);
1124 build_sse_f3(0xC2, "CMPSS", OP_xmm1_xmm2m32_imm8, &Interpreter::CMPSS_xmm1_xmm2m32_imm8);
1125 build_sse_f2(0xC2, "CMPSD", OP_xmm1_xmm2m32_imm8, &Interpreter::CMPSD_xmm1_xmm2m32_imm8);
1126
1127 build_sse_np(0xC4, "PINSRW", OP_mm1_r32m16_imm8, &Interpreter::PINSRW_mm1_r32m16_imm8);
1128 build_sse_66(0xC4, "PINSRW", OP_xmm1_r32m16_imm8, &Interpreter::PINSRW_xmm1_r32m16_imm8);
1129 build_sse_np(0xC5, "PEXTRW", OP_reg_mm1_imm8, &Interpreter::PEXTRW_reg_mm1_imm8);
1130 build_sse_66(0xC5, "PEXTRW", OP_reg_xmm1_imm8, &Interpreter::PEXTRW_reg_xmm1_imm8);
1131 build_sse_np(0xC6, "SHUFPS", OP_xmm1_xmm2m128_imm8, &Interpreter::SHUFPS_xmm1_xmm2m128_imm8);
1132 build_sse_66(0xC6, "SHUFPD", OP_xmm1_xmm2m128_imm8, &Interpreter::SHUFPD_xmm1_xmm2m128_imm8);
1133
1134 build_0f_slash(0xC7, 1, "CMPXCHG8B", OP_m64, &Interpreter::CMPXCHG8B_m64);
1135 // FIXME: NP 0f c7 /2 XRSTORS[64] mem
1136 // FIXME: NP 0F C7 / 4 XSAVEC mem
1137 // FIXME: NP 0F C7 /5 XSAVES mem
1138 // FIXME: VMPTRLD, VMPTRST, VMCLR, VMXON
1139 // This is technically NFx prefixed
1140 // FIXME: f3 0f c7 /7 RDPID
1141 build_0f_slash(0xC7, 6, "RDRAND", OP_reg, &Interpreter::RDRAND_reg);
1142 build_0f_slash(0xC7, 7, "RDSEED", OP_reg, &Interpreter::RDSEED_reg);
1143
1144 for (u8 i = 0xc8; i <= 0xcf; ++i)
1145 build_0f(i, "BSWAP", OP_reg32, &Interpreter::BSWAP_reg32);
1146
1147 build_0f(0xD1, "PSRLW", OP_mm1_mm2m64, &Interpreter::PSRLW_mm1_mm2m64);
1148 build_0f(0xD2, "PSRLD", OP_mm1_mm2m64, &Interpreter::PSRLD_mm1_mm2m64);
1149 build_0f(0xD3, "PSRLQ", OP_mm1_mm2m64, &Interpreter::PSRLQ_mm1_mm2m64);
1150 build_0f(0xD4, "PADDQ", OP_mm1_mm2m64, &Interpreter::PADDQ_mm1_mm2m64);
1151 build_0f(0xD5, "PMULLW", OP_mm1_mm2m64, &Interpreter::PMULLW_mm1_mm2m64);
1152
1153 build_sse_66(0xD6, "MOVQ", OP_xmm1m128_xmm2, &Interpreter::MOVQ_xmm1m128_xmm2);
1154 build_sse_f3(0xD6, "MOVQ2DQ", OP_xmm_mm, &Interpreter::MOVQ2DQ_xmm_mm);
1155 build_sse_f2(0xD6, "MOVDQ2Q", OP_mm_xmm, &Interpreter::MOVDQ2Q_mm_xmm);
1156 build_sse_np(0xD7, "PMOVMSKB", OP_reg_mm1, &Interpreter::PMOVMSKB_reg_mm1);
1157 build_sse_66(0xD7, "PMOVMSKB", OP_reg_xmm1, &Interpreter::PMOVMSKB_reg_xmm1);
1158
1159 build_0f(0xDB, "PAND", OP_mm1_mm2m64, &Interpreter::PAND_mm1_mm2m64);
1160 build_0f(0xD8, "PSUBUSB", OP_mm1_mm2m64, &Interpreter::PSUBUSB_mm1_mm2m64);
1161 build_0f(0xD9, "PSUBUSW", OP_mm1_mm2m64, &Interpreter::PSUBUSW_mm1_mm2m64);
1162
1163 build_sse_np(0xDA, "PMINUB", OP_mm1_mm2m64, &Interpreter::PMINUB_mm1_mm2m64);
1164 build_sse_66(0xDA, "PMINUB", OP_xmm1_xmm2m128, &Interpreter::PMINUB_xmm1_xmm2m128);
1165
1166 build_0f(0xDC, "PADDUSB", OP_mm1_mm2m64, &Interpreter::PADDUSB_mm1_mm2m64);
1167 build_0f(0xDD, "PADDUSW", OP_mm1_mm2m64, &Interpreter::PADDUSW_mm1_mm2m64);
1168 build_sse_np(0xDE, "PMAXUB", OP_mm1_mm2m64, &Interpreter::PMAXUB_mm1_mm2m64);
1169 build_sse_66(0xDE, "PMAXUB", OP_xmm1_xmm2m128, &Interpreter::PMAXUB_xmm1_xmm2m128);
1170 build_0f(0xDF, "PANDN", OP_mm1_mm2m64, &Interpreter::PANDN_mm1_mm2m64);
1171
1172 build_sse_np(0xE0, "PAVGB", OP_mm1_mm2m64, &Interpreter::PAVGB_mm1_mm2m64);
1173 build_sse_66(0xE0, "PAVGB", OP_xmm1_xmm2m128, &Interpreter::PAVGB_xmm1_xmm2m128);
1174 build_sse_np(0xE3, "PAVGW", OP_mm1_mm2m64, &Interpreter::PAVGW_mm1_mm2m64);
1175 build_sse_66(0xE3, "PAVGW", OP_xmm1_xmm2m128, &Interpreter::PAVGW_xmm1_xmm2m128);
1176 build_sse_np(0xE4, "PMULHUW ", OP_mm1_mm2m64, &Interpreter::PMULHUW_mm1_mm2m64);
1177 build_sse_66(0xE4, "PMULHUW ", OP_xmm1_xmm2m64, &Interpreter::PMULHUW_xmm1_xmm2m64);
1178 build_0f(0xE5, "PMULHW", OP_mm1_mm2m64, &Interpreter::PMULHW_mm1_mm2m64);
1179
1180 build_sse_66(0xE6, "CVTTPD2DQ", OP_xmm1_xmm2m128, &Interpreter::CVTTPD2DQ_xmm1_xmm2m128);
1181 build_sse_f2(0xE6, "CVTPD2DQ", OP_xmm1_xmm2m128, &Interpreter::CVTPD2DQ_xmm1_xmm2m128);
1182 build_sse_f3(0xE6, "CVTDQ2PD", OP_xmm1_xmm2m64, &Interpreter::CVTDQ2PD_xmm1_xmm2m64);
1183 build_sse_np(0xE7, "MOVNTQ", OP_mm1m64_mm2, &Interpreter::MOVNTQ_m64_mm1);
1184
1185 build_sse_np(0xEA, "PMINSB", OP_mm1_mm2m64, &Interpreter::PMINSB_mm1_mm2m64);
1186 build_sse_66(0xEA, "PMINSB", OP_xmm1_xmm2m128, &Interpreter::PMINSB_xmm1_xmm2m128);
1187 build_0f(0xEB, "POR", OP_mm1_mm2m64, &Interpreter::POR_mm1_mm2m64);
1188 build_0f(0xE1, "PSRAW", OP_mm1_mm2m64, &Interpreter::PSRAW_mm1_mm2m64);
1189 build_0f(0xE2, "PSRAD", OP_mm1_mm2m64, &Interpreter::PSRAD_mm1_mm2m64);
1190 build_0f(0xE8, "PSUBSB", OP_mm1_mm2m64, &Interpreter::PSUBSB_mm1_mm2m64);
1191 build_0f(0xE9, "PSUBSW", OP_mm1_mm2m64, &Interpreter::PSUBSW_mm1_mm2m64);
1192 build_0f(0xEC, "PADDSB", OP_mm1_mm2m64, &Interpreter::PADDSB_mm1_mm2m64);
1193 build_0f(0xED, "PADDSW", OP_mm1_mm2m64, &Interpreter::PADDSW_mm1_mm2m64);
1194 build_sse_np(0xEE, "PMAXSB", OP_mm1_mm2m64, &Interpreter::PMAXSB_mm1_mm2m64);
1195 build_sse_66(0xEE, "PMAXSB", OP_xmm1_xmm2m128, &Interpreter::PMAXSB_xmm1_xmm2m128);
1196 build_0f(0xEF, "PXOR", OP_mm1_mm2m64, &Interpreter::PXOR_mm1_mm2m64);
1197
1198 build_0f(0xF1, "PSLLW", OP_mm1_mm2m64, &Interpreter::PSLLW_mm1_mm2m64);
1199 build_0f(0xF2, "PSLLD", OP_mm1_mm2m64, &Interpreter::PSLLD_mm1_mm2m64);
1200 build_0f(0xF3, "PSLLQ", OP_mm1_mm2m64, &Interpreter::PSLLQ_mm1_mm2m64);
1201 build_sse_np(0xF4, "PMULUDQ", OP_mm1_mm2m64, &Interpreter::PMULUDQ_mm1_mm2m64);
1202 build_sse_66(0xF4, "PMULUDQ", OP_xmm1_xmm2m128, &Interpreter::PMULUDQ_mm1_mm2m128);
1203 build_0f(0xF5, "PMADDWD", OP_mm1_mm2m64, &Interpreter::PMADDWD_mm1_mm2m64);
1204 build_sse_np(0xF6, "PSADBW", OP_mm1_mm2m64, &Interpreter::PSADBB_mm1_mm2m64);
1205 build_sse_66(0xF6, "PSADBW", OP_xmm1_xmm2m128, &Interpreter::PSADBB_xmm1_xmm2m128);
1206 build_sse_np(0xF7, "MASKMOVQ", OP_mm1_mm2m64, &Interpreter::MASKMOVQ_mm1_mm2m64);
1207 build_0f(0xF8, "PSUBB", OP_mm1_mm2m64, &Interpreter::PSUBB_mm1_mm2m64);
1208 build_0f(0xF9, "PSUBW", OP_mm1_mm2m64, &Interpreter::PSUBW_mm1_mm2m64);
1209 build_0f(0xFA, "PSUBD", OP_mm1_mm2m64, &Interpreter::PSUBD_mm1_mm2m64);
1210 build_0f(0xFB, "PSUBQ", OP_mm1_mm2m64, &Interpreter::PSUBQ_mm1_mm2m64);
1211 build_0f(0xFC, "PADDB", OP_mm1_mm2m64, &Interpreter::PADDB_mm1_mm2m64);
1212 build_0f(0xFD, "PADDW", OP_mm1_mm2m64, &Interpreter::PADDW_mm1_mm2m64);
1213 build_0f(0xFE, "PADDD", OP_mm1_mm2m64, &Interpreter::PADDD_mm1_mm2m64);
1214 build_0f(0xFF, "UD0", OP, &Interpreter::UD0);
1215
1216 // Changes between 32-bit and 64-bit. These are marked with i64/d64/f64 in the Intel manual's opcode tables
1217 auto* table64 = s_table[to_underlying(OperandSize::Size64)];
1218 table64[0x06] = {}; // PUSH ES
1219 table64[0x07] = {}; // POP ES
1220 table64[0x16] = {}; // PUSH SS
1221 table64[0x17] = {}; // POP SS
1222 table64[0x27] = {}; // DAA
1223 table64[0x37] = {}; // AAA
1224 for (u8 rex = 0x40; rex < 0x50; rex++)
1225 table64[rex] = {}; // INC/DEC, replaced by REX prefixes
1226 for (u8 pushPop = 0x50; pushPop < 0x60; pushPop++)
1227 table64[pushPop].long_mode_default_64 = true; // PUSH/POP general register
1228 for (u8 i = 0x60; i < 0x68; i++)
1229 table64[i] = {}; // PUSHA{D}, POPA{D}, BOUND
1230 // ARPL replaced by MOVSXD
1231 build_in_table(table64, 0x63, "MOVSXD", OP_RM32_reg32, nullptr, LockPrefixNotAllowed);
1232 table64[0x68].long_mode_default_64 = true; // PUSH
1233 table64[0x6A].long_mode_default_64 = true; // PUSH
1234 for (u8 jmp = 0x70; jmp < 0x80; jmp++)
1235 table64[jmp].long_mode_force_64 = true; // Jcc
1236 table64[0x9A] = {}; // far CALL
1237 table64[0x9C].long_mode_default_64 = true; // PUSHF/D/Q
1238 table64[0x9D].long_mode_default_64 = true; // POPF/D/Q
1239 build_in_table(table64, 0xB8, "MOV", OP_regW_immW, &Interpreter::MOV_reg32_imm32, LockPrefixNotAllowed);
1240 table64[0xC2].long_mode_force_64 = true; // near RET
1241 table64[0xC3].long_mode_force_64 = true; // near RET
1242 table64[0xC4] = {}; // LES
1243 table64[0xC5] = {}; // LDS
1244 table64[0xC9].long_mode_default_64 = true; // LEAVE
1245 table64[0xCE].long_mode_default_64 = true; // INTO
1246 table64[0xD4] = {}; // AAM
1247 table64[0xD5] = {}; // AAD
1248 for (u8 i = 0; i < 4; i++) {
1249 table64[0xE0 | i].long_mode_force_64 = true; // LOOPN[EZ], LOOP[EZ], LOOP, JrCXZ
1250 table64[0xE8 | i].long_mode_force_64 = true; // near CALL, {near,far,short} JMP
1251 }
1252
1253 auto* table64_0f = s_0f_table[to_underlying(OperandSize::Size64)];
1254 build_in_table(table64_0f, 0x05, "SYSCALL", OP, nullptr, LockPrefixNotAllowed);
1255 build_in_table(table64_0f, 0x07, "SYSRET", OP, nullptr, LockPrefixNotAllowed);
1256 for (u8 i = 0x80; i < 0x90; i++)
1257 table64_0f[i].long_mode_force_64 = true; // Jcc
1258 table64_0f[0xA0].long_mode_default_64 = true; // PUSH FS
1259 table64_0f[0xA1].long_mode_default_64 = true; // POP FS
1260 table64_0f[0xA8].long_mode_default_64 = true; // PUSH GS
1261 table64_0f[0xA9].long_mode_default_64 = true; // POP GS
1262}
1263
1264static StringView register_name(RegisterIndex8);
1265static StringView register_name(RegisterIndex16);
1266static StringView register_name(RegisterIndex32);
1267static StringView register_name(RegisterIndex64);
1268static StringView register_name(FpuRegisterIndex);
1269static StringView register_name(SegmentRegister);
1270static StringView register_name(MMXRegisterIndex);
1271static StringView register_name(XMMRegisterIndex);
1272
1273StringView Instruction::reg8_name() const
1274{
1275 return register_name(static_cast<RegisterIndex8>(register_index()));
1276}
1277
1278StringView Instruction::reg16_name() const
1279{
1280 return register_name(static_cast<RegisterIndex16>(register_index()));
1281}
1282
1283StringView Instruction::reg32_name() const
1284{
1285 return register_name(static_cast<RegisterIndex32>(register_index()));
1286}
1287
1288StringView Instruction::reg64_name() const
1289{
1290 return register_name(static_cast<RegisterIndex64>(register_index()));
1291}
1292
1293DeprecatedString MemoryOrRegisterReference::to_deprecated_string_o8(Instruction const& insn) const
1294{
1295 if (is_register())
1296 return register_name(reg8());
1297 return DeprecatedString::formatted("[{}]", to_deprecated_string(insn));
1298}
1299
1300DeprecatedString MemoryOrRegisterReference::to_deprecated_string_o16(Instruction const& insn) const
1301{
1302 if (is_register())
1303 return register_name(reg16());
1304 return DeprecatedString::formatted("[{}]", to_deprecated_string(insn));
1305}
1306
1307DeprecatedString MemoryOrRegisterReference::to_deprecated_string_o32(Instruction const& insn) const
1308{
1309 if (is_register())
1310 return register_name(reg32());
1311 return DeprecatedString::formatted("[{}]", to_deprecated_string(insn));
1312}
1313
1314DeprecatedString MemoryOrRegisterReference::to_deprecated_string_o64(Instruction const& insn) const
1315{
1316 if (is_register())
1317 return register_name(reg64());
1318 return DeprecatedString::formatted("[{}]", to_deprecated_string(insn));
1319}
1320
1321DeprecatedString MemoryOrRegisterReference::to_deprecated_string_fpu_reg() const
1322{
1323 VERIFY(is_register());
1324 return register_name(reg_fpu());
1325}
1326
1327DeprecatedString MemoryOrRegisterReference::to_deprecated_string_fpu_mem(Instruction const& insn) const
1328{
1329 VERIFY(!is_register());
1330 return DeprecatedString::formatted("[{}]", to_deprecated_string(insn));
1331}
1332
1333DeprecatedString MemoryOrRegisterReference::to_deprecated_string_fpu_ax16() const
1334{
1335 VERIFY(is_register());
1336 return register_name(reg16());
1337}
1338
1339DeprecatedString MemoryOrRegisterReference::to_deprecated_string_fpu16(Instruction const& insn) const
1340{
1341 if (is_register())
1342 return register_name(reg_fpu());
1343 return DeprecatedString::formatted("word ptr [{}]", to_deprecated_string(insn));
1344}
1345
1346DeprecatedString MemoryOrRegisterReference::to_deprecated_string_fpu32(Instruction const& insn) const
1347{
1348 if (is_register())
1349 return register_name(reg_fpu());
1350 return DeprecatedString::formatted("dword ptr [{}]", to_deprecated_string(insn));
1351}
1352
1353DeprecatedString MemoryOrRegisterReference::to_deprecated_string_fpu64(Instruction const& insn) const
1354{
1355 if (is_register())
1356 return register_name(reg_fpu());
1357 return DeprecatedString::formatted("qword ptr [{}]", to_deprecated_string(insn));
1358}
1359
1360DeprecatedString MemoryOrRegisterReference::to_deprecated_string_fpu80(Instruction const& insn) const
1361{
1362 VERIFY(!is_register());
1363 return DeprecatedString::formatted("tbyte ptr [{}]", to_deprecated_string(insn));
1364}
1365DeprecatedString MemoryOrRegisterReference::to_deprecated_string_mm(Instruction const& insn) const
1366{
1367 if (is_register())
1368 return register_name(static_cast<MMXRegisterIndex>(m_register_index));
1369 return DeprecatedString::formatted("[{}]", to_deprecated_string(insn));
1370}
1371DeprecatedString MemoryOrRegisterReference::to_deprecated_string_xmm(Instruction const& insn) const
1372{
1373 if (is_register())
1374 return register_name(static_cast<XMMRegisterIndex>(m_register_index));
1375 return DeprecatedString::formatted("[{}]", to_deprecated_string(insn));
1376}
1377
1378DeprecatedString MemoryOrRegisterReference::to_deprecated_string(Instruction const& insn) const
1379{
1380 switch (insn.address_size()) {
1381 case AddressSize::Size64:
1382 return to_deprecated_string_a64();
1383 case AddressSize::Size32:
1384 return insn.mode() == ProcessorMode::Long ? to_deprecated_string_a64() : to_deprecated_string_a32();
1385 case AddressSize::Size16:
1386 return to_deprecated_string_a16();
1387 }
1388 VERIFY_NOT_REACHED();
1389}
1390
1391DeprecatedString MemoryOrRegisterReference::to_deprecated_string_a16() const
1392{
1393 DeprecatedString base;
1394 bool hasDisplacement = false;
1395
1396 switch (rm()) {
1397 case 0:
1398 base = "bx+si";
1399 break;
1400 case 1:
1401 base = "bx+di";
1402 break;
1403 case 2:
1404 base = "bp+si";
1405 break;
1406 case 3:
1407 base = "bp+di";
1408 break;
1409 case 4:
1410 base = "si";
1411 break;
1412 case 5:
1413 base = "di";
1414 break;
1415 case 7:
1416 base = "bx";
1417 break;
1418 case 6:
1419 if (mod() == 0)
1420 base = DeprecatedString::formatted("{:#04x}", m_displacement16);
1421 else
1422 base = "bp";
1423 break;
1424 }
1425
1426 switch (mod()) {
1427 case 0b01:
1428 case 0b10:
1429 hasDisplacement = true;
1430 }
1431
1432 if (!hasDisplacement)
1433 return base;
1434
1435 return DeprecatedString::formatted("{}{:+#x}", base, (i16)m_displacement16);
1436}
1437
1438DeprecatedString MemoryOrRegisterReference::sib_to_deprecated_string(ProcessorMode mode) const
1439{
1440 DeprecatedString scale;
1441 DeprecatedString index;
1442 DeprecatedString base;
1443 switch (m_sib_scale) {
1444 case 0:;
1445 break;
1446 case 1:
1447 scale = "*2";
1448 break;
1449 case 2:
1450 scale = "*4";
1451 break;
1452 case 3:
1453 scale = "*8";
1454 break;
1455 }
1456 if (m_sib_index != 4)
1457 index = mode == ProcessorMode::Long ? register_name(RegisterIndex64(m_sib_index)) : register_name(RegisterIndex32(m_sib_index));
1458 if (m_sib_base == 5) {
1459 switch (m_reg) {
1460 case 1:
1461 case 2:
1462 base = mode == ProcessorMode::Long ? "rbp" : "ebp";
1463 break;
1464 }
1465 } else {
1466 base = mode == ProcessorMode::Long ? register_name(RegisterIndex64(m_sib_base)) : register_name(RegisterIndex32(m_sib_base));
1467 }
1468 StringBuilder builder;
1469 if (base.is_empty()) {
1470 builder.append(index);
1471 builder.append(scale);
1472 } else {
1473 builder.append(base);
1474 if (!base.is_empty() && !index.is_empty())
1475 builder.append('+');
1476 builder.append(index);
1477 builder.append(scale);
1478 }
1479 return builder.to_deprecated_string();
1480}
1481
1482DeprecatedString MemoryOrRegisterReference::to_deprecated_string_a64() const
1483{
1484 if (is_register())
1485 return register_name(static_cast<RegisterIndex64>(m_register_index));
1486
1487 bool has_displacement = false;
1488 switch (mod()) {
1489 case 0b00:
1490 has_displacement = m_rm == 5;
1491 break;
1492 case 0b01:
1493 case 0b10:
1494 has_displacement = true;
1495 }
1496 if (m_has_sib && m_sib_base == 5)
1497 has_displacement = true;
1498
1499 DeprecatedString base;
1500 switch (m_rm) {
1501 case 5:
1502 if (mod() == 0)
1503 base = "rip";
1504 else
1505 base = "rbp";
1506 break;
1507 case 4:
1508 base = sib_to_deprecated_string(ProcessorMode::Long);
1509 break;
1510 default:
1511 base = register_name(RegisterIndex64(m_rm));
1512 }
1513
1514 if (!has_displacement)
1515 return base;
1516
1517 return DeprecatedString::formatted("{}{:+#x}", base, (i32)m_displacement32);
1518}
1519
1520DeprecatedString MemoryOrRegisterReference::to_deprecated_string_a32() const
1521{
1522 if (is_register())
1523 return register_name(static_cast<RegisterIndex32>(m_register_index));
1524
1525 bool has_displacement = false;
1526 switch (mod()) {
1527 case 0b01:
1528 case 0b10:
1529 has_displacement = true;
1530 }
1531 if (m_has_sib && m_sib_base == 5)
1532 has_displacement = true;
1533
1534 DeprecatedString base;
1535 switch (m_rm) {
1536 case 5:
1537 if (mod() == 0)
1538 base = DeprecatedString::formatted("{:x}", m_displacement32);
1539 else
1540 base = "ebp";
1541 break;
1542 case 4:
1543 base = sib_to_deprecated_string(ProcessorMode::Protected);
1544 break;
1545 default:
1546 base = register_name(RegisterIndex32(m_rm));
1547 }
1548
1549 if (!has_displacement)
1550 return base;
1551
1552 return DeprecatedString::formatted("{}{:+#x}", base, (i32)m_displacement32);
1553}
1554
1555static DeprecatedString relative_address(u32 origin, bool x32, i8 imm)
1556{
1557 if (x32)
1558 return DeprecatedString::formatted("{:x}", origin + imm);
1559 u16 w = origin & 0xffff;
1560 return DeprecatedString::formatted("{:x}", w + imm);
1561}
1562
1563static DeprecatedString relative_address(u32 origin, bool x32, i32 imm)
1564{
1565 if (x32)
1566 return DeprecatedString::formatted("{:x}", origin + imm);
1567 u16 w = origin & 0xffff;
1568 i16 si = imm;
1569 return DeprecatedString::formatted("{:x}", w + si);
1570}
1571
1572DeprecatedString Instruction::to_deprecated_string(u32 origin, SymbolProvider const* symbol_provider, bool x32) const
1573{
1574 StringBuilder builder;
1575 if (has_segment_prefix())
1576 builder.appendff("{}: ", register_name(segment_prefix().value()));
1577 if (has_address_size_override_prefix()) {
1578 switch (m_address_size) {
1579 case AddressSize::Size16:
1580 builder.append("a16"sv);
1581 break;
1582 case AddressSize::Size32:
1583 builder.append("a32"sv);
1584 break;
1585 case AddressSize::Size64:
1586 builder.append("a64"sv);
1587 break;
1588 }
1589 }
1590 if (has_operand_size_override_prefix()) {
1591 switch (m_operand_size) {
1592 case OperandSize::Size16:
1593 builder.append("o16"sv);
1594 break;
1595 case OperandSize::Size32:
1596 builder.append("o32"sv);
1597 break;
1598 case OperandSize::Size64:
1599 builder.append("o64"sv);
1600 break;
1601 }
1602 }
1603 if (has_lock_prefix())
1604 builder.append("lock "sv);
1605 // Note: SSE instructions use these to toggle between packed and single data
1606 if (has_rep_prefix() && !(m_descriptor->format > __SSE && m_descriptor->format < __EndFormatsWithRMByte))
1607 builder.append(m_rep_prefix == Prefix::REPNZ ? "repnz "sv : "repz "sv);
1608 to_deprecated_string_internal(builder, origin, symbol_provider, x32);
1609 return builder.to_deprecated_string();
1610}
1611
1612void Instruction::to_deprecated_string_internal(StringBuilder& builder, u32 origin, SymbolProvider const* symbol_provider, bool x32) const
1613{
1614 if (!m_descriptor) {
1615 builder.appendff("db {:02x}", m_op);
1616 return;
1617 }
1618
1619 DeprecatedString mnemonic = DeprecatedString(m_descriptor->mnemonic).to_lowercase();
1620
1621 auto append_mnemonic = [&] { builder.append(mnemonic); };
1622
1623 auto append_mnemonic_space = [&] { builder.appendff("{: <6} ", mnemonic); };
1624
1625 auto formatted_address = [&](FlatPtr origin, bool x32, auto offset) {
1626 builder.append(relative_address(origin, x32, offset));
1627 if (symbol_provider) {
1628 u32 symbol_offset = 0;
1629 auto symbol = symbol_provider->symbolicate(origin + offset, &symbol_offset);
1630 builder.append(" <"sv);
1631 builder.append(symbol);
1632 if (symbol_offset)
1633 builder.appendff("+{:#x}", symbol_offset);
1634 builder.append('>');
1635 }
1636 };
1637
1638 auto append_rm8 = [&] { builder.append(m_modrm.to_deprecated_string_o8(*this)); };
1639 auto append_rm16 = [&] { builder.append(m_modrm.to_deprecated_string_o16(*this)); };
1640 auto append_rm32 = [&] {
1641 if (m_operand_size == OperandSize::Size64)
1642 builder.append(m_modrm.to_deprecated_string_o64(*this));
1643 else
1644 builder.append(m_modrm.to_deprecated_string_o32(*this));
1645 };
1646 auto append_rm64 = [&] { builder.append(m_modrm.to_deprecated_string_o64(*this)); };
1647 auto append_fpu_reg = [&] { builder.append(m_modrm.to_deprecated_string_fpu_reg()); };
1648 auto append_fpu_mem = [&] { builder.append(m_modrm.to_deprecated_string_fpu_mem(*this)); };
1649 auto append_fpu_ax16 = [&] { builder.append(m_modrm.to_deprecated_string_fpu_ax16()); };
1650 auto append_fpu_rm16 = [&] { builder.append(m_modrm.to_deprecated_string_fpu16(*this)); };
1651 auto append_fpu_rm32 = [&] { builder.append(m_modrm.to_deprecated_string_fpu32(*this)); };
1652 auto append_fpu_rm64 = [&] { builder.append(m_modrm.to_deprecated_string_fpu64(*this)); };
1653 auto append_fpu_rm80 = [&] { builder.append(m_modrm.to_deprecated_string_fpu80(*this)); };
1654 auto append_imm8 = [&] { builder.appendff("{:#02x}", imm8()); };
1655 auto append_imm8_2 = [&] { builder.appendff("{:#02x}", imm8_2()); };
1656 auto append_imm16 = [&] { builder.appendff("{:#04x}", imm16()); };
1657 auto append_imm16_1 = [&] { builder.appendff("{:#04x}", imm16_1()); };
1658 auto append_imm16_2 = [&] { builder.appendff("{:#04x}", imm16_2()); };
1659 auto append_imm32 = [&] { builder.appendff("{:#08x}", imm32()); };
1660 auto append_imm32_2 = [&] { builder.appendff("{:#08x}", imm32_2()); };
1661 auto append_imm64 = [&] { builder.appendff("{:#016x}", imm64()); };
1662 auto append_immW = [&] {
1663 if (m_operand_size == OperandSize::Size64)
1664 append_imm64();
1665 else
1666 append_imm32();
1667 };
1668 auto append_reg8 = [&] { builder.append(reg8_name()); };
1669 auto append_reg16 = [&] { builder.append(reg16_name()); };
1670 auto append_reg32 = [&] {
1671 if (m_operand_size == OperandSize::Size64)
1672 builder.append(reg64_name());
1673 else
1674 builder.append(reg32_name());
1675 };
1676 auto append_seg = [&] { builder.append(register_name(segment_register())); };
1677 auto append_creg = [&] { builder.appendff("cr{}", register_index()); };
1678 auto append_dreg = [&] { builder.appendff("dr{}", register_index()); };
1679 auto append_relative_addr = [&] {
1680 switch (m_address_size) {
1681 case AddressSize::Size16:
1682 formatted_address(origin + 4, x32, i32(imm16()));
1683 break;
1684 case AddressSize::Size32:
1685 formatted_address(origin + 6, x32, i32(imm32()));
1686 break;
1687 default:
1688 VERIFY_NOT_REACHED();
1689 }
1690 };
1691 auto append_relative_imm8 = [&] { formatted_address(origin + 2, x32, i8(imm8())); };
1692 auto append_relative_imm16 = [&] { formatted_address(origin + 3, x32, i16(imm16())); };
1693 auto append_relative_imm32 = [&] { formatted_address(origin + 5, x32, i32(imm32())); };
1694
1695 auto append_mm = [&] { builder.appendff("mm{}", register_index()); };
1696 auto append_mmrm32 = [&] { builder.append(m_modrm.to_deprecated_string_mm(*this)); };
1697 auto append_mmrm64 = [&] { builder.append(m_modrm.to_deprecated_string_mm(*this)); };
1698 auto append_xmm = [&] { builder.appendff("xmm{}", register_index()); };
1699 auto append_xmmrm32 = [&] { builder.append(m_modrm.to_deprecated_string_xmm(*this)); };
1700 auto append_xmmrm64 = [&] { builder.append(m_modrm.to_deprecated_string_xmm(*this)); };
1701 auto append_xmmrm128 = [&] { builder.append(m_modrm.to_deprecated_string_xmm(*this)); };
1702
1703 auto append_mm_or_xmm = [&] {
1704 if (has_operand_size_override_prefix())
1705 append_xmm();
1706 else
1707 append_mm();
1708 };
1709
1710 auto append_mm_or_xmm_or_mem = [&] {
1711 // FIXME: The sizes here dont fully match what is meant, but it does
1712 // not really matter...
1713 if (has_operand_size_override_prefix())
1714 append_xmmrm128();
1715 else
1716 append_mmrm64();
1717 };
1718
1719 auto append = [&](auto content) { builder.append(content); };
1720 auto append_moff = [&] {
1721 builder.append('[');
1722 if (m_address_size == AddressSize::Size64) {
1723 append_imm64();
1724 } else if (m_address_size == AddressSize::Size32) {
1725 append_imm32();
1726 } else if (m_address_size == AddressSize::Size16) {
1727 append_imm16();
1728 } else {
1729 VERIFY_NOT_REACHED();
1730 }
1731 builder.append(']');
1732 };
1733
1734 switch (m_descriptor->format) {
1735 case OP_RM8_imm8:
1736 append_mnemonic_space();
1737 append_rm8();
1738 append(',');
1739 append_imm8();
1740 break;
1741 case OP_RM16_imm8:
1742 append_mnemonic_space();
1743 append_rm16();
1744 append(',');
1745 append_imm8();
1746 break;
1747 case OP_RM32_imm8:
1748 append_mnemonic_space();
1749 append_rm32();
1750 append(',');
1751 append_imm8();
1752 break;
1753 case OP_reg16_RM16_imm8:
1754 append_mnemonic_space();
1755 append_reg16();
1756 append(',');
1757 append_rm16();
1758 append(',');
1759 append_imm8();
1760 break;
1761 case OP_reg32_RM32_imm8:
1762 append_mnemonic_space();
1763 append_reg32();
1764 append(',');
1765 append_rm32();
1766 append(',');
1767 append_imm8();
1768 break;
1769 case OP_AL_imm8:
1770 append_mnemonic_space();
1771 append("al,"sv);
1772 append_imm8();
1773 break;
1774 case OP_imm8:
1775 append_mnemonic_space();
1776 append_imm8();
1777 break;
1778 case OP_reg8_imm8:
1779 append_mnemonic_space();
1780 append_reg8();
1781 append(',');
1782 append_imm8();
1783 break;
1784 case OP_AX_imm8:
1785 append_mnemonic_space();
1786 append("ax,"sv);
1787 append_imm8();
1788 break;
1789 case OP_EAX_imm8:
1790 append_mnemonic_space();
1791 append("eax,"sv);
1792 append_imm8();
1793 break;
1794 case OP_imm8_AL:
1795 append_mnemonic_space();
1796 append_imm8();
1797 append(",al"sv);
1798 break;
1799 case OP_imm8_AX:
1800 append_mnemonic_space();
1801 append_imm8();
1802 append(",ax"sv);
1803 break;
1804 case OP_imm8_EAX:
1805 append_mnemonic_space();
1806 append_imm8();
1807 append(",eax"sv);
1808 break;
1809 case OP_AX_imm16:
1810 append_mnemonic_space();
1811 append("ax,"sv);
1812 append_imm16();
1813 break;
1814 case OP_imm16:
1815 append_mnemonic_space();
1816 append_imm16();
1817 break;
1818 case OP_reg16_imm16:
1819 append_mnemonic_space();
1820 append_reg16();
1821 append(',');
1822 append_imm16();
1823 break;
1824 case OP_reg16_RM16_imm16:
1825 append_mnemonic_space();
1826 append_reg16();
1827 append(',');
1828 append_rm16();
1829 append(',');
1830 append_imm16();
1831 break;
1832 case OP_reg32_RM32_imm32:
1833 append_mnemonic_space();
1834 append_reg32();
1835 append(',');
1836 append_rm32();
1837 append(',');
1838 append_imm32();
1839 break;
1840 case OP_imm32:
1841 append_mnemonic_space();
1842 append_imm32();
1843 break;
1844 case OP_EAX_imm32:
1845 append_mnemonic_space();
1846 append("eax,"sv);
1847 append_imm32();
1848 break;
1849 case OP_CS:
1850 append_mnemonic_space();
1851 append("cs"sv);
1852 break;
1853 case OP_DS:
1854 append_mnemonic_space();
1855 append("ds"sv);
1856 break;
1857 case OP_ES:
1858 append_mnemonic_space();
1859 append("es"sv);
1860 break;
1861 case OP_SS:
1862 append_mnemonic_space();
1863 append("ss"sv);
1864 break;
1865 case OP_FS:
1866 append_mnemonic_space();
1867 append("fs"sv);
1868 break;
1869 case OP_GS:
1870 append_mnemonic_space();
1871 append("gs"sv);
1872 break;
1873 case OP:
1874 append_mnemonic();
1875 break;
1876 case OP_reg32:
1877 append_mnemonic_space();
1878 append_reg32();
1879 break;
1880 case OP_imm16_imm8:
1881 append_mnemonic_space();
1882 append_imm16_1();
1883 append(',');
1884 append_imm8_2();
1885 break;
1886 case OP_moff8_AL:
1887 append_mnemonic_space();
1888 append_moff();
1889 append(",al"sv);
1890 break;
1891 case OP_moff16_AX:
1892 append_mnemonic_space();
1893 append_moff();
1894 append(",ax"sv);
1895 break;
1896 case OP_moff32_EAX:
1897 append_mnemonic_space();
1898 append_moff();
1899 append(",eax"sv);
1900 break;
1901 case OP_AL_moff8:
1902 append_mnemonic_space();
1903 append("al,"sv);
1904 append_moff();
1905 break;
1906 case OP_AX_moff16:
1907 append_mnemonic_space();
1908 append("ax,"sv);
1909 append_moff();
1910 break;
1911 case OP_EAX_moff32:
1912 append_mnemonic_space();
1913 append("eax,"sv);
1914 append_moff();
1915 break;
1916 case OP_imm16_imm16:
1917 append_mnemonic_space();
1918 append_imm16_1();
1919 append(":"sv);
1920 append_imm16_2();
1921 break;
1922 case OP_imm16_imm32:
1923 append_mnemonic_space();
1924 append_imm16_1();
1925 append(":"sv);
1926 append_imm32_2();
1927 break;
1928 case OP_reg32_imm32:
1929 append_mnemonic_space();
1930 append_reg32();
1931 append(',');
1932 append_imm32();
1933 break;
1934 case OP_regW_immW:
1935 append_mnemonic_space();
1936 append_reg32();
1937 append(", "sv);
1938 append_immW();
1939 break;
1940 case OP_RM8_1:
1941 append_mnemonic_space();
1942 append_rm8();
1943 append(",0x01"sv);
1944 break;
1945 case OP_RM16_1:
1946 append_mnemonic_space();
1947 append_rm16();
1948 append(",0x01"sv);
1949 break;
1950 case OP_RM32_1:
1951 append_mnemonic_space();
1952 append_rm32();
1953 append(",0x01"sv);
1954 break;
1955 case OP_RM8_CL:
1956 append_mnemonic_space();
1957 append_rm8();
1958 append(",cl"sv);
1959 break;
1960 case OP_RM16_CL:
1961 append_mnemonic_space();
1962 append_rm16();
1963 append(",cl"sv);
1964 break;
1965 case OP_RM32_CL:
1966 append_mnemonic_space();
1967 append_rm32();
1968 append(",cl"sv);
1969 break;
1970 case OP_reg16:
1971 append_mnemonic_space();
1972 append_reg16();
1973 break;
1974 case OP_AX_reg16:
1975 append_mnemonic_space();
1976 append("ax,"sv);
1977 append_reg16();
1978 break;
1979 case OP_EAX_reg32:
1980 append_mnemonic_space();
1981 append("eax,"sv);
1982 append_reg32();
1983 break;
1984 case OP_3:
1985 append_mnemonic_space();
1986 append("0x03"sv);
1987 break;
1988 case OP_AL_DX:
1989 append_mnemonic_space();
1990 append("al,dx"sv);
1991 break;
1992 case OP_AX_DX:
1993 append_mnemonic_space();
1994 append("ax,dx"sv);
1995 break;
1996 case OP_EAX_DX:
1997 append_mnemonic_space();
1998 append("eax,dx"sv);
1999 break;
2000 case OP_DX_AL:
2001 append_mnemonic_space();
2002 append("dx,al"sv);
2003 break;
2004 case OP_DX_AX:
2005 append_mnemonic_space();
2006 append("dx,ax"sv);
2007 break;
2008 case OP_DX_EAX:
2009 append_mnemonic_space();
2010 append("dx,eax"sv);
2011 break;
2012 case OP_reg8_CL:
2013 append_mnemonic_space();
2014 append_reg8();
2015 append(",cl"sv);
2016 break;
2017 case OP_RM8:
2018 append_mnemonic_space();
2019 append_rm8();
2020 break;
2021 case OP_RM16:
2022 append_mnemonic_space();
2023 append_rm16();
2024 break;
2025 case OP_RM32:
2026 append_mnemonic_space();
2027 append_rm32();
2028 break;
2029 case OP_FPU:
2030 append_mnemonic_space();
2031 break;
2032 case OP_FPU_reg:
2033 append_mnemonic_space();
2034 append_fpu_reg();
2035 break;
2036 case OP_FPU_mem:
2037 append_mnemonic_space();
2038 append_fpu_mem();
2039 break;
2040 case OP_FPU_AX16:
2041 append_mnemonic_space();
2042 append_fpu_ax16();
2043 break;
2044 case OP_FPU_RM16:
2045 append_mnemonic_space();
2046 append_fpu_rm16();
2047 break;
2048 case OP_FPU_RM32:
2049 append_mnemonic_space();
2050 append_fpu_rm32();
2051 break;
2052 case OP_FPU_RM64:
2053 append_mnemonic_space();
2054 append_fpu_rm64();
2055 break;
2056 case OP_FPU_M80:
2057 append_mnemonic_space();
2058 append_fpu_rm80();
2059 break;
2060 case OP_RM8_reg8:
2061 append_mnemonic_space();
2062 append_rm8();
2063 append(',');
2064 append_reg8();
2065 break;
2066 case OP_RM16_reg16:
2067 append_mnemonic_space();
2068 append_rm16();
2069 append(',');
2070 append_reg16();
2071 break;
2072 case OP_RM32_reg32:
2073 append_mnemonic_space();
2074 append_rm32();
2075 append(',');
2076 append_reg32();
2077 break;
2078 case OP_reg8_RM8:
2079 append_mnemonic_space();
2080 append_reg8();
2081 append(',');
2082 append_rm8();
2083 break;
2084 case OP_reg16_RM16:
2085 append_mnemonic_space();
2086 append_reg16();
2087 append(',');
2088 append_rm16();
2089 break;
2090 case OP_reg32_RM32:
2091 append_mnemonic_space();
2092 append_reg32();
2093 append(',');
2094 append_rm32();
2095 break;
2096 case OP_reg32_RM16:
2097 append_mnemonic_space();
2098 append_reg32();
2099 append(',');
2100 append_rm16();
2101 break;
2102 case OP_reg16_RM8:
2103 append_mnemonic_space();
2104 append_reg16();
2105 append(',');
2106 append_rm8();
2107 break;
2108 case OP_reg32_RM8:
2109 append_mnemonic_space();
2110 append_reg32();
2111 append(',');
2112 append_rm8();
2113 break;
2114 case OP_RM16_imm16:
2115 append_mnemonic_space();
2116 append_rm16();
2117 append(',');
2118 append_imm16();
2119 break;
2120 case OP_RM32_imm32:
2121 append_mnemonic_space();
2122 append_rm32();
2123 append(',');
2124 append_imm32();
2125 break;
2126 case OP_RM16_seg:
2127 append_mnemonic_space();
2128 append_rm16();
2129 append(',');
2130 append_seg();
2131 break;
2132 case OP_RM32_seg:
2133 append_mnemonic_space();
2134 append_rm32();
2135 append(',');
2136 append_seg();
2137 break;
2138 case OP_seg_RM16:
2139 append_mnemonic_space();
2140 append_seg();
2141 append(',');
2142 append_rm16();
2143 break;
2144 case OP_seg_RM32:
2145 append_mnemonic_space();
2146 append_seg();
2147 append(',');
2148 append_rm32();
2149 break;
2150 case OP_reg16_mem16:
2151 append_mnemonic_space();
2152 append_reg16();
2153 append(',');
2154 append_rm16();
2155 break;
2156 case OP_reg32_mem32:
2157 append_mnemonic_space();
2158 append_reg32();
2159 append(',');
2160 append_rm32();
2161 break;
2162 case OP_FAR_mem16:
2163 append_mnemonic_space();
2164 append("far "sv);
2165 append_rm16();
2166 break;
2167 case OP_FAR_mem32:
2168 append_mnemonic_space();
2169 append("far "sv);
2170 append_rm32();
2171 break;
2172 case OP_reg32_CR:
2173 append_mnemonic_space();
2174 builder.append(register_name(static_cast<RegisterIndex32>(modrm().rm())));
2175 append(',');
2176 append_creg();
2177 break;
2178 case OP_CR_reg32:
2179 append_mnemonic_space();
2180 append_creg();
2181 append(',');
2182 builder.append(register_name(static_cast<RegisterIndex32>(modrm().rm())));
2183 break;
2184 case OP_reg32_DR:
2185 append_mnemonic_space();
2186 builder.append(register_name(static_cast<RegisterIndex32>(modrm().rm())));
2187 append(',');
2188 append_dreg();
2189 break;
2190 case OP_DR_reg32:
2191 append_mnemonic_space();
2192 append_dreg();
2193 append(',');
2194 builder.append(register_name(static_cast<RegisterIndex32>(modrm().rm())));
2195 break;
2196 case OP_short_imm8:
2197 append_mnemonic_space();
2198 append("short "sv);
2199 append_relative_imm8();
2200 break;
2201 case OP_relimm16:
2202 append_mnemonic_space();
2203 append_relative_imm16();
2204 break;
2205 case OP_relimm32:
2206 append_mnemonic_space();
2207 append_relative_imm32();
2208 break;
2209 case OP_NEAR_imm:
2210 append_mnemonic_space();
2211 append("near "sv);
2212 append_relative_addr();
2213 break;
2214 case OP_RM16_reg16_imm8:
2215 append_mnemonic_space();
2216 append_rm16();
2217 append(',');
2218 append_reg16();
2219 append(',');
2220 append_imm8();
2221 break;
2222 case OP_RM32_reg32_imm8:
2223 append_mnemonic_space();
2224 append_rm32();
2225 append(',');
2226 append_reg32();
2227 append(',');
2228 append_imm8();
2229 break;
2230 case OP_RM16_reg16_CL:
2231 append_mnemonic_space();
2232 append_rm16();
2233 append(',');
2234 append_reg16();
2235 append(", cl"sv);
2236 break;
2237 case OP_RM32_reg32_CL:
2238 append_mnemonic_space();
2239 append_rm32();
2240 append(',');
2241 append_reg32();
2242 append(",cl"sv);
2243 break;
2244 case OP_reg:
2245 append_mnemonic_space();
2246 if (m_operand_size == OperandSize::Size32)
2247 append_reg32();
2248 else
2249 append_reg16();
2250 break;
2251 case OP_m64:
2252 append_mnemonic_space();
2253 append_rm64();
2254 break;
2255 case OP_mm1_imm8:
2256 append_mnemonic_space();
2257 append_mm_or_xmm();
2258 append(',');
2259 append_imm8();
2260 break;
2261 case OP_mm1_mm2m32:
2262 append_mnemonic_space();
2263 append_mm_or_xmm();
2264 append(',');
2265 append_mm_or_xmm_or_mem();
2266 break;
2267 case OP_mm1_rm32:
2268 append_mnemonic_space();
2269 append_mm_or_xmm();
2270 append(',');
2271 append_rm32();
2272 break;
2273 case OP_rm32_mm2:
2274 append_mnemonic_space();
2275 append_rm32();
2276 append(',');
2277 append_mm_or_xmm();
2278 break;
2279 case OP_mm1_mm2m64:
2280 append_mnemonic_space();
2281 append_mm_or_xmm();
2282 append(',');
2283 append_mm_or_xmm_or_mem();
2284 break;
2285 case OP_mm1m64_mm2:
2286 append_mnemonic_space();
2287 append_mm_or_xmm_or_mem();
2288 append(',');
2289 append_mm_or_xmm();
2290 break;
2291 case OP_mm1_mm2m64_imm8:
2292 append_mnemonic_space();
2293 append_mm_or_xmm();
2294 append(',');
2295 append_mm_or_xmm_or_mem();
2296 append(',');
2297 append_imm8();
2298 break;
2299 case OP_reg_mm1:
2300 append_mnemonic_space();
2301 append_rm32();
2302 append(',');
2303 append_mm_or_xmm();
2304 break;
2305 case OP_reg_mm1_imm8:
2306 append_mnemonic_space();
2307 append_reg32();
2308 append(',');
2309 append_mm_or_xmm_or_mem();
2310 append(',');
2311 append_imm8();
2312 break;
2313 case OP_mm1_r32m16_imm8:
2314 append_mnemonic_space();
2315 append_mm_or_xmm();
2316 append_rm32(); // FIXME: r32m16
2317 append(',');
2318 append_imm8();
2319 break;
2320 case __SSE:
2321 break;
2322 case OP_xmm_mm:
2323 append_mnemonic_space();
2324 append_xmm();
2325 append(',');
2326 append_mmrm32(); // FIXME: No Memory
2327 break;
2328 case OP_mm1_xmm2m128:
2329 case OP_mm_xmm:
2330 append_mnemonic_space();
2331 append_mm();
2332 append(',');
2333 append_xmmrm32(); // FIXME: No Memory
2334 break;
2335 case OP_xmm1_imm8:
2336 append_mnemonic_space();
2337 append_xmm();
2338 append(',');
2339 append_imm8();
2340 break;
2341 case OP_xmm1_xmm2m32:
2342 append_mnemonic_space();
2343 append_xmm();
2344 append(',');
2345 append_xmmrm32();
2346 break;
2347 case OP_xmm1_xmm2m64:
2348 append_mnemonic_space();
2349 append_xmm();
2350 append(',');
2351 append_xmmrm64();
2352 break;
2353 case OP_xmm1_xmm2m128:
2354 append_mnemonic_space();
2355 append_xmm();
2356 append(',');
2357 append_xmmrm128();
2358 break;
2359 case OP_xmm1_xmm2m32_imm8:
2360 append_mnemonic_space();
2361 append_xmm();
2362 append(',');
2363 append_xmmrm32();
2364 append(',');
2365 append_imm8();
2366 break;
2367 case OP_xmm1_xmm2m128_imm8:
2368 append_mnemonic_space();
2369 append_xmm();
2370 append(',');
2371 append_xmmrm32();
2372 append(',');
2373 append_imm8();
2374 break;
2375 case OP_xmm1m32_xmm2:
2376 append_mnemonic_space();
2377 append_xmmrm32();
2378 append(',');
2379 append_xmm();
2380 break;
2381 case OP_xmm1m64_xmm2:
2382 append_mnemonic_space();
2383 append_xmmrm64();
2384 append(',');
2385 append_xmm();
2386 break;
2387 case OP_xmm1m128_xmm2:
2388 append_mnemonic_space();
2389 append_xmmrm128();
2390 append(',');
2391 append_xmm();
2392 break;
2393 case OP_reg_xmm1:
2394 case OP_r32_xmm2m64:
2395 append_mnemonic_space();
2396 append_reg32();
2397 append(',');
2398 append_xmmrm128(); // second entry in the rm byte
2399 break;
2400 case OP_rm32_xmm2:
2401 append_mnemonic_space();
2402 append_rm32();
2403 append(',');
2404 append_xmm();
2405 break;
2406 case OP_reg_xmm1_imm8:
2407 append_mnemonic_space();
2408 append_reg32();
2409 append(',');
2410 append_xmmrm128(); // second entry in the rm byte
2411 append(',');
2412 append_imm8();
2413 break;
2414 case OP_xmm1_rm32:
2415 append_mnemonic_space();
2416 append_xmm();
2417 append(',');
2418 append_rm32(); // second entry in the rm byte
2419 break;
2420 case OP_xmm1_m64:
2421 append_mnemonic_space();
2422 append_xmm();
2423 append(',');
2424 append_rm64(); // second entry in the rm byte
2425 break;
2426
2427 case OP_m64_xmm2:
2428 append_mnemonic_space();
2429 append_rm64(); // second entry in the rm byte
2430 append(',');
2431 append_xmm();
2432 break;
2433 case OP_rm8_xmm2m32:
2434 append_mnemonic_space();
2435 append_rm8();
2436 append(',');
2437 append_xmmrm32();
2438 break;
2439 case OP_xmm1_mm2m64:
2440 append_mnemonic_space();
2441 append_xmm();
2442 append(',');
2443 append_mmrm64();
2444 break;
2445 case OP_mm1m64_xmm2:
2446 append_mnemonic_space();
2447 append_mmrm64();
2448 append(',');
2449 append_xmm();
2450 break;
2451 case OP_mm1_xmm2m64:
2452 append_mnemonic_space();
2453 append_mm();
2454 append(',');
2455 append_xmmrm64();
2456 break;
2457 case OP_r32_xmm2m32:
2458 append_mnemonic_space();
2459 append_reg32();
2460 append(',');
2461 append_xmmrm32();
2462 break;
2463 case OP_xmm1_r32m16_imm8:
2464 append_mnemonic_space();
2465 append_xmm();
2466 append(',');
2467 append_rm32(); // FIXME: r32m16
2468 append(',');
2469 append_imm8();
2470 break;
2471 case InstructionPrefix:
2472 append_mnemonic();
2473 break;
2474 case InvalidFormat:
2475 case MultibyteWithSlash:
2476 case __BeginFormatsWithRMByte:
2477 case __EndFormatsWithRMByte:
2478 builder.append(DeprecatedString::formatted("(!{})", mnemonic));
2479 break;
2480 }
2481}
2482
2483DeprecatedString Instruction::mnemonic() const
2484{
2485 if (!m_descriptor) {
2486 VERIFY_NOT_REACHED();
2487 }
2488 return m_descriptor->mnemonic;
2489}
2490
2491StringView register_name(SegmentRegister index)
2492{
2493 static constexpr StringView names[] = { "es"sv, "cs"sv, "ss"sv, "ds"sv, "fs"sv, "gs"sv, "segr6"sv, "segr7"sv };
2494 return names[(int)index & 7];
2495}
2496
2497StringView register_name(RegisterIndex8 register_index)
2498{
2499 static constexpr StringView names[] = { "al"sv, "cl"sv, "dl"sv, "bl"sv, "ah"sv, "ch"sv, "dh"sv, "bh"sv, "r8b"sv, "r9b"sv, "r10b"sv, "r11b"sv, "r12b"sv, "r13b"sv, "r14b"sv, "r15b"sv };
2500 return names[register_index & 15];
2501}
2502
2503StringView register_name(RegisterIndex16 register_index)
2504{
2505 static constexpr StringView names[] = { "ax"sv, "cx"sv, "dx"sv, "bx"sv, "sp"sv, "bp"sv, "si"sv, "di"sv, "r8w"sv, "r9w"sv, "r10w"sv, "r11w"sv, "r12w"sv, "r13w"sv, "r14w"sv, "r15w"sv };
2506 return names[register_index & 15];
2507}
2508
2509StringView register_name(RegisterIndex32 register_index)
2510{
2511 static constexpr StringView names[] = { "eax"sv, "ecx"sv, "edx"sv, "ebx"sv, "esp"sv, "ebp"sv, "esi"sv, "edi"sv, "r8d"sv, "r9d"sv, "r10d"sv, "r11d"sv, "r12d"sv, "r13d"sv, "r14d"sv, "r15d"sv };
2512 return names[register_index & 15];
2513}
2514
2515StringView register_name(RegisterIndex64 register_index)
2516{
2517 static constexpr StringView names[] = { "rax"sv, "rcx"sv, "rdx"sv, "rbx"sv, "rsp"sv, "rbp"sv, "rsi"sv, "rdi"sv, "r8"sv, "r9"sv, "r10"sv, "r11"sv, "r12"sv, "r13"sv, "r14"sv, "r15"sv };
2518 return names[register_index & 15];
2519}
2520
2521StringView register_name(FpuRegisterIndex register_index)
2522{
2523 static constexpr StringView names[] = { "st0"sv, "st1"sv, "st2"sv, "st3"sv, "st4"sv, "st5"sv, "st6"sv, "st7"sv };
2524 return names[register_index & 7];
2525}
2526
2527StringView register_name(MMXRegisterIndex register_index)
2528{
2529 static constexpr StringView names[] = { "mm0"sv, "mm1"sv, "mm2"sv, "mm3"sv, "mm4"sv, "mm5"sv, "mm6"sv, "mm7"sv };
2530 return names[register_index & 7];
2531}
2532
2533StringView register_name(XMMRegisterIndex register_index)
2534{
2535 static constexpr StringView names[] = { "xmm0"sv, "xmm1"sv, "xmm2"sv, "xmm3"sv, "xmm4"sv, "xmm5"sv, "xmm6"sv, "xmm7"sv, "xmm8"sv, "xmm9"sv, "xmm10"sv, "xmm11"sv, "xmm12"sv, "xmm13"sv, "xmm14"sv, "xmm15"sv };
2536 return names[register_index & 15];
2537}
2538
2539}