SandboXP

Форк
0
/
x86_table.js 
976 строк · 52.0 Кб
1
"use strict";
2

3
const { hex } = require("./util");
4

5
// http://ref.x86asm.net/coder32.html
6

7
const zf = 1 << 6;
8
const of = 1 << 11;
9
const cf = 1 << 0;
10
const af = 1 << 4;
11
const pf = 1 << 2;
12
const sf = 1 << 7;
13

14
// === Types of instructions
15
//
16
// create entry | check for compiled code | instruction
17
// -------------+-------------------------+-----------------------------------------------------------
18
//      1       |        optional         | pop ds (may change cpu state)
19
//              |                         | trigger_ud, div (exception that doesn't generate conditional return from BB)
20
//              |                         | port io, popf, sti (may call interrupt or continue at next instruction)
21
//              |                         | hlt
22
// -------------+-------------------------+-----------------------------------------------------------
23
//      1       |            1            | call [eax], jmp [eax], int, iret, ret, jmpf, callf, sysenter, sysexit
24
//              |                         | Special case: normal instruction with fallthough to next page
25
//              |                         | Special case: after execution of compiled code
26
//              |                         | -> may create redundant entry points depending on last instruction?
27
// -------------+-------------------------+-----------------------------------------------------------
28
//      1       |            0            | rep movs, rep lods, rep stos, rep cmps, rep scas
29
//              |                         | -> Executed as follows:
30
//              |                         |   - Upto including the first call in compiled mode
31
//              |                         |   - Back to main loop and repeated in interpreted mode (as entry point is after instruction, not on)
32
//              |                         |   - When finished entry pointer *after* instruction is hit and execution continues in compiled mode
33
// -------------+-------------------------+-----------------------------------------------------------
34
//      0       |        optional         | jmp foo, jnz foo
35
//              |                         | (foo is in the same page as the instruction)
36
// -------------+-------------------------+-----------------------------------------------------------
37
//      1       |            1            | call foo
38
//              |                         | (foo is in the same page as the instruction)
39
//              |                         | -> The entry point is not created for jumps within
40
//              |                         |    this page, but speculatively for calls from
41
//              |                         |    other pages to the function in this page
42
// -------------+-------------------------+-----------------------------------------------------------
43
//      1       |            1            | call foo, jmp foo, jnz foo
44
//              |                         | (foo is in a different page than the instruction)
45

46

47
// e: a modrm byte follows the operand
48
// os: the instruction behaves differently depending on the operand size
49
// fixed_g: the reg field of the modrm byte selects an instruction
50
// skip: skip automatically generated tests (nasmtests)
51
// mask_flags: flags bits to mask in generated tests
52
// prefix: is a prefix instruction
53
// imm8, imm8s, imm16, imm1632, immaddr, extra_imm8, extra_imm16: one or two immediate bytes follows the instruction
54
// custom: will callback jit to generate custom code
55
// block_boundary: may change eip in a way not handled by the jit
56
// no_next_instruction: jit will stop analysing after instruction (e.g., unconditional jump, ret)
57
const encodings = [
58
    { opcode: 0x00, custom: 1, e: 1, },
59
    { opcode: 0x01, custom: 1, os: 1, e: 1, },
60
    { opcode: 0x02, custom: 1, e: 1, },
61
    { opcode: 0x03, custom: 1, os: 1, e: 1, },
62

63
    { opcode: 0x08, custom: 1, e: 1, },
64
    { opcode: 0x09, custom: 1, os: 1, e: 1, },
65
    { opcode: 0x0A, custom: 1, e: 1, },
66
    { opcode: 0x0B, custom: 1, os: 1, e: 1, },
67

68
    { opcode: 0x10, custom: 1, e: 1, },
69
    { opcode: 0x11, custom: 1, os: 1, e: 1, },
70
    { opcode: 0x12, custom: 1, e: 1, },
71
    { opcode: 0x13, custom: 1, os: 1, e: 1, },
72

73
    { opcode: 0x18, custom: 1, e: 1, },
74
    { opcode: 0x19, custom: 1, os: 1, e: 1, },
75
    { opcode: 0x1A, custom: 1, e: 1, },
76
    { opcode: 0x1B, custom: 1, os: 1, e: 1, },
77

78
    { opcode: 0x20, custom: 1, e: 1, },
79
    { opcode: 0x21, custom: 1, os: 1, e: 1, },
80
    { opcode: 0x22, custom: 1, e: 1, },
81
    { opcode: 0x23, custom: 1, os: 1, e: 1, },
82

83
    { opcode: 0x28, custom: 1, e: 1, },
84
    { opcode: 0x29, custom: 1, os: 1, e: 1, },
85
    { opcode: 0x2A, custom: 1, e: 1, },
86
    { opcode: 0x2B, custom: 1, os: 1, e: 1, },
87

88
    { opcode: 0x30, custom: 1, e: 1, },
89
    { opcode: 0x31, custom: 1, os: 1, e: 1, },
90
    { opcode: 0x32, custom: 1, e: 1, },
91
    { opcode: 0x33, custom: 1, os: 1, e: 1, },
92

93
    { opcode: 0x38, custom: 1, e: 1, },
94
    { opcode: 0x39, custom: 1, os: 1, e: 1, },
95
    { opcode: 0x3A, custom: 1, e: 1, },
96
    { opcode: 0x3B, custom: 1, os: 1, e: 1, },
97

98
    { opcode: 0x06, os: 1, custom: 1 },
99
    { opcode: 0x07, os: 1, skip: 1, block_boundary: 1, }, // pop es: block_boundary since it uses non-raising cpu exceptions
100
    { opcode: 0x0E, os: 1, custom: 1 },
101
    { opcode: 0x0F, os: 1, prefix: 1, },
102
    { opcode: 0x16, os: 1, custom: 1 },
103
    { opcode: 0x17, block_boundary: 1, os: 1, skip: 1, }, // pop ss
104
    { opcode: 0x1E, os: 1, custom: 1 },
105
    { opcode: 0x1F, block_boundary: 1, os: 1, skip: 1, }, // pop ds
106
    { opcode: 0x26, prefix: 1, },
107
    { opcode: 0x27, mask_flags: of, },
108
    { opcode: 0x2E, prefix: 1, },
109
    { opcode: 0x2F, mask_flags: of, },
110
    { opcode: 0x36, prefix: 1, },
111
    { opcode: 0x37, mask_flags: of | sf | pf | zf, },
112
    { opcode: 0x3E, prefix: 1, },
113
    { opcode: 0x3F, mask_flags: of | sf | pf | zf, },
114

115
    { opcode: 0x40, os: 1, custom: 1 },
116
    { opcode: 0x41, os: 1, custom: 1 },
117
    { opcode: 0x42, os: 1, custom: 1 },
118
    { opcode: 0x43, os: 1, custom: 1 },
119
    { opcode: 0x44, os: 1, custom: 1 },
120
    { opcode: 0x45, os: 1, custom: 1 },
121
    { opcode: 0x46, os: 1, custom: 1 },
122
    { opcode: 0x47, os: 1, custom: 1 },
123

124
    { opcode: 0x48, os: 1, custom: 1 },
125
    { opcode: 0x49, os: 1, custom: 1 },
126
    { opcode: 0x4A, os: 1, custom: 1 },
127
    { opcode: 0x4B, os: 1, custom: 1 },
128
    { opcode: 0x4C, os: 1, custom: 1 },
129
    { opcode: 0x4D, os: 1, custom: 1 },
130
    { opcode: 0x4E, os: 1, custom: 1 },
131
    { opcode: 0x4F, os: 1, custom: 1 },
132

133
    { opcode: 0x50, custom: 1, os: 1 },
134
    { opcode: 0x51, custom: 1, os: 1 },
135
    { opcode: 0x52, custom: 1, os: 1 },
136
    { opcode: 0x53, custom: 1, os: 1 },
137
    { opcode: 0x54, custom: 1, os: 1 },
138
    { opcode: 0x55, custom: 1, os: 1 },
139
    { opcode: 0x56, custom: 1, os: 1 },
140
    { opcode: 0x57, custom: 1, os: 1 },
141

142
    { opcode: 0x58, custom: 1, os: 1, },
143
    { opcode: 0x59, custom: 1, os: 1, },
144
    { opcode: 0x5A, custom: 1, os: 1, },
145
    { opcode: 0x5B, custom: 1, os: 1, },
146
    { opcode: 0x5C, custom: 1, os: 1, },
147
    { opcode: 0x5D, custom: 1, os: 1, },
148
    { opcode: 0x5E, custom: 1, os: 1, },
149
    { opcode: 0x5F, custom: 1, os: 1, },
150

151
    { opcode: 0x60, os: 1, block_boundary: 1 }, // pusha
152
    { opcode: 0x61, os: 1, block_boundary: 1 }, // popa
153
    { opcode: 0x62, e: 1, skip: 1, },
154
    { opcode: 0x63, e: 1, block_boundary: 1, }, // arpl
155
    { opcode: 0x64, prefix: 1, },
156
    { opcode: 0x65, prefix: 1, },
157
    { opcode: 0x66, prefix: 1, },
158
    { opcode: 0x67, prefix: 1, },
159

160
    { opcode: 0x68, custom: 1, os: 1, imm1632: 1 },
161
    { opcode: 0x69, os: 1, e: 1, custom: 1, imm1632: 1, mask_flags: af, }, // zf?
162
    { opcode: 0x6A, custom: 1, os: 1, imm8s: 1 },
163
    { opcode: 0x6B, os: 1, e: 1, custom: 1, imm8s: 1, mask_flags: af, }, // zf?
164

165
    { opcode: 0x6C, block_boundary: 1, custom: 1, is_string: 1, skip: 1, },          // ins
166
    { opcode: 0xF26C, block_boundary: 1, custom: 1, is_string: 1, skip: 1, },
167
    { opcode: 0xF36C, block_boundary: 1, custom: 1, is_string: 1, skip: 1, },
168
    { opcode: 0x6D, block_boundary: 1, custom: 1, is_string: 1, os: 1, skip: 1, },
169
    { opcode: 0xF26D, block_boundary: 1, custom: 1, is_string: 1, os: 1, skip: 1, },
170
    { opcode: 0xF36D, block_boundary: 1, custom: 1, is_string: 1, os: 1, skip: 1, },
171

172
    { opcode: 0x6E, block_boundary: 1, custom: 1, is_string: 1, skip: 1, },          // outs
173
    { opcode: 0xF26E, block_boundary: 1, custom: 1, is_string: 1, skip: 1, },
174
    { opcode: 0xF36E, block_boundary: 1, custom: 1, is_string: 1, skip: 1, },
175
    { opcode: 0x6F, block_boundary: 1, custom: 1, is_string: 1, os: 1, skip: 1, },
176
    { opcode: 0xF26F, block_boundary: 1, custom: 1, is_string: 1, os: 1, skip: 1, },
177
    { opcode: 0xF36F, block_boundary: 1, custom: 1, is_string: 1, os: 1, skip: 1, },
178

179
    { opcode: 0x84, custom: 1, e: 1, },
180
    { opcode: 0x85, custom: 1, e: 1, os: 1, },
181
    { opcode: 0x86, custom: 1, e: 1, },
182
    { opcode: 0x87, custom: 1, os: 1, e: 1, },
183
    { opcode: 0x88, custom: 1, e: 1, },
184
    { opcode: 0x89, custom: 1, os: 1, e: 1, },
185
    { opcode: 0x8A, custom: 1, e: 1, },
186
    { opcode: 0x8B, custom: 1, os: 1, e: 1, },
187

188
    { opcode: 0x8C, os: 1, e: 1, custom: 1 }, // mov reg, sreg
189
    { opcode: 0x8D, reg_ud: 1, os: 1, e: 1, custom_modrm_resolve: 1, custom: 1, }, // lea
190
    { opcode: 0x8E, block_boundary: 1, e: 1, skip: 1, }, // mov sreg
191
    { opcode: 0x8F, os: 1, e: 1, fixed_g: 0, custom_modrm_resolve: 1, custom: 1, block_boundary: 1, }, // pop r/m
192

193
    { opcode: 0x90, custom: 1, },
194
    { opcode: 0x91, custom: 1, os: 1, },
195
    { opcode: 0x92, custom: 1, os: 1, },
196
    { opcode: 0x93, custom: 1, os: 1, },
197
    { opcode: 0x94, custom: 1, os: 1, },
198
    { opcode: 0x95, custom: 1, os: 1, },
199
    { opcode: 0x96, custom: 1, os: 1, },
200
    { opcode: 0x97, custom: 1, os: 1, },
201

202
    { opcode: 0x98, os: 1, custom: 1 },
203
    { opcode: 0x99, os: 1, custom: 1 },
204
    { opcode: 0x9A, os: 1, imm1632: 1, extra_imm16: 1, skip: 1, block_boundary: 1, }, // callf
205
    { opcode: 0x9B, block_boundary: 1, skip: 1, }, // fwait: block_boundary since it uses non-raising cpu exceptions
206
    { opcode: 0x9C, os: 1, custom: 1 },
207
    { opcode: 0x9D, os: 1, skip: 1, custom: 1, },
208
    { opcode: 0x9E, custom: 1 },
209
    { opcode: 0x9F, custom: 1 },
210

211
    { opcode: 0xA0, custom: 1, immaddr: 1 },
212
    { opcode: 0xA1, custom: 1, os: 1, immaddr: 1 },
213
    { opcode: 0xA2, custom: 1, immaddr: 1 },
214
    { opcode: 0xA3, custom: 1, os: 1, immaddr: 1 },
215

216
    // string instructions aren't jumps, but they modify eip due to how they're implemented
217
    { opcode: 0xA4, block_boundary: 0, custom: 1, is_string: 1, },
218
    { opcode: 0xF2A4, block_boundary: 1, custom: 1, is_string: 1, },
219
    { opcode: 0xF3A4, block_boundary: 1, custom: 1, is_string: 1, },
220
    { opcode: 0xA5, block_boundary: 0, custom: 1, is_string: 1, os: 1, },
221
    { opcode: 0xF2A5, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
222
    { opcode: 0xF3A5, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
223

224
    { opcode: 0xA6, block_boundary: 1, custom: 1, is_string: 1, },
225
    { opcode: 0xF2A6, block_boundary: 1, custom: 1, is_string: 1, },
226
    { opcode: 0xF3A6, block_boundary: 1, custom: 1, is_string: 1, },
227
    { opcode: 0xA7, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
228
    { opcode: 0xF2A7, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
229
    { opcode: 0xF3A7, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
230

231
    { opcode: 0xA8, custom: 1, imm8: 1, },
232
    { opcode: 0xA9, custom: 1, os: 1, imm1632: 1, },
233

234
    { opcode: 0xAA, block_boundary: 0, custom: 1, is_string: 1, },
235
    { opcode: 0xF2AA, block_boundary: 1, custom: 1, is_string: 1, },
236
    { opcode: 0xF3AA, block_boundary: 1, custom: 1, is_string: 1, },
237
    { opcode: 0xAB, block_boundary: 0, custom: 1, is_string: 1, os: 1, },
238
    { opcode: 0xF2AB, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
239
    { opcode: 0xF3AB, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
240

241
    { opcode: 0xAC, block_boundary: 0, custom: 1, is_string: 1, },
242
    { opcode: 0xF2AC, block_boundary: 1, custom: 1, is_string: 1, },
243
    { opcode: 0xF3AC, block_boundary: 1, custom: 1, is_string: 1, },
244
    { opcode: 0xAD, block_boundary: 0, custom: 1, is_string: 1, os: 1, },
245
    { opcode: 0xF2AD, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
246
    { opcode: 0xF3AD, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
247

248
    { opcode: 0xAE, block_boundary: 0, custom: 1, is_string: 1, },
249
    { opcode: 0xF2AE, block_boundary: 1, custom: 1, is_string: 1, },
250
    { opcode: 0xF3AE, block_boundary: 1, custom: 1, is_string: 1, },
251
    { opcode: 0xAF, block_boundary: 0, custom: 1, is_string: 1, os: 1, },
252
    { opcode: 0xF2AF, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
253
    { opcode: 0xF3AF, block_boundary: 1, custom: 1, is_string: 1, os: 1, },
254

255
    { opcode: 0xC2, custom: 1, block_boundary: 1, no_next_instruction: 1, os: 1, absolute_jump: 1, imm16: 1, skip: 1, }, // ret
256
    { opcode: 0xC3, custom: 1, block_boundary: 1, no_next_instruction: 1, os: 1, absolute_jump: 1, skip: 1, },
257

258
    { opcode: 0xC4, block_boundary: 1, os: 1, e: 1, skip: 1, }, // les
259
    { opcode: 0xC5, block_boundary: 1, os: 1, e: 1, skip: 1, }, // lds
260

261
    { opcode: 0xC6, custom: 1, e: 1, fixed_g: 0, imm8: 1 },
262
    { opcode: 0xC7, custom: 1, os: 1, e: 1, fixed_g: 0, imm1632: 1 },
263

264
    // XXX: Temporary block boundary
265
    { opcode: 0xC8, os: 1, imm16: 1, extra_imm8: 1, block_boundary: 1, }, // enter
266
    { opcode: 0xC9, custom: 1, os: 1, skip: 1 }, // leave
267

268
    { opcode: 0xCA, block_boundary: 1, no_next_instruction: 1, os: 1, imm16: 1, skip: 1, }, // retf
269
    { opcode: 0xCB, block_boundary: 1, no_next_instruction: 1, os: 1, skip: 1, },
270
    { opcode: 0xCC, block_boundary: 1, skip: 1, }, // int
271
    { opcode: 0xCD, block_boundary: 1, skip: 1, imm8: 1, },
272
    { opcode: 0xCE, block_boundary: 1, skip: 1, },
273
    { opcode: 0xCF, block_boundary: 1, no_next_instruction: 1, os: 1, skip: 1, }, // iret
274

275
    { opcode: 0xD4, imm8: 1, block_boundary: 1, }, // aam, may trigger #de
276
    { opcode: 0xD5, imm8: 1, mask_flags: of | cf | af, },
277
    { opcode: 0xD6, },
278

279
    { opcode: 0xD7, skip: 1, custom: 1, },
280

281
    { opcode: 0xD8, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, },
282
    { opcode: 0xD8, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, },
283
    { opcode: 0xD8, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, },
284
    { opcode: 0xD8, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, },
285
    { opcode: 0xD8, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, },
286
    { opcode: 0xD8, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, },
287
    { opcode: 0xD8, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, },
288
    { opcode: 0xD8, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, },
289

290
    { opcode: 0xD9, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, },
291
    { opcode: 0xD9, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, },
292
    { opcode: 0xD9, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, },
293
    { opcode: 0xD9, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, },
294
    { opcode: 0xD9, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1, }, // fldenv (mem)
295
    { opcode: 0xD9, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, },
296
    { opcode: 0xD9, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, skip: 1, }, // fstenv (mem), fprem (reg)
297
    { opcode: 0xD9, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, skip_reg: 1, }, // fprem, fyl2xp1 (precision issues)
298

299
    { opcode: 0xDA, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, },
300
    { opcode: 0xDA, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, },
301
    { opcode: 0xDA, e: 1, fixed_g: 2, custom: 0, is_fpu: 1, task_switch_test: 1, },
302
    { opcode: 0xDA, e: 1, fixed_g: 3, custom: 0, is_fpu: 1, task_switch_test: 1, },
303
    { opcode: 0xDA, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, },
304
    { opcode: 0xDA, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, },
305
    { opcode: 0xDA, e: 1, fixed_g: 6, custom: 0, is_fpu: 1, task_switch_test: 1, },
306
    { opcode: 0xDA, e: 1, fixed_g: 7, custom: 0, is_fpu: 1, task_switch_test: 1, },
307

308
    { opcode: 0xDB, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, },
309
    { opcode: 0xDB, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, skip_mem: 1, }, // unimplemented: fisttp (sse3)
310
    { opcode: 0xDB, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, },
311
    { opcode: 0xDB, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, },
312
    { opcode: 0xDB, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, },
313
    { opcode: 0xDB, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, },
314
    { opcode: 0xDB, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, },
315
    { opcode: 0xDB, e: 1, fixed_g: 7, custom: 0, is_fpu: 1, task_switch_test: 1, },
316

317
    { opcode: 0xDC, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, },
318
    { opcode: 0xDC, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, },
319
    { opcode: 0xDC, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, },
320
    { opcode: 0xDC, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, },
321
    { opcode: 0xDC, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, },
322
    { opcode: 0xDC, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, },
323
    { opcode: 0xDC, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, },
324
    { opcode: 0xDC, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, },
325

326
    { opcode: 0xDD, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, },
327
    { opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1, }, // unimplemented: fisttp (sse3)
328
    { opcode: 0xDD, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, },
329
    { opcode: 0xDD, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, },
330
    { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1 }, // frstor
331
    { opcode: 0xDD, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, },
332
    { opcode: 0xDD, e: 1, fixed_g: 6, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1 }, // fsave
333
    { opcode: 0xDD, e: 1, fixed_g: 7, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, },
334

335
    { opcode: 0xDE, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, },
336
    { opcode: 0xDE, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, },
337
    { opcode: 0xDE, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, },
338
    { opcode: 0xDE, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, },
339
    { opcode: 0xDE, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, },
340
    { opcode: 0xDE, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, },
341
    { opcode: 0xDE, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, },
342
    { opcode: 0xDE, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, },
343

344
    { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1 },
345
    { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, skip_mem: 1 }, // unimplemented: fisttp (sse3)
346
    { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1 },
347
    { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1 },
348
    { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, skip_mem: 1 }, // unimplemented: Binary Coded Decimals
349
    { opcode: 0xDF, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, },
350
    { opcode: 0xDF, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, skip_mem: 1 }, // unimplemented: Binary Coded Decimals
351
    { opcode: 0xDF, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, },
352

353
    // loop, jcxz, etc.
354
    { opcode: 0xE0, os: 1, imm8s: 1, no_block_boundary_in_interpreted: 1, skip: 1, block_boundary: 1, jump_offset_imm: 1, custom: 1, conditional_jump: 1, },
355
    { opcode: 0xE1, os: 1, imm8s: 1, no_block_boundary_in_interpreted: 1, skip: 1, block_boundary: 1, jump_offset_imm: 1, custom: 1, conditional_jump: 1, },
356
    { opcode: 0xE2, os: 1, imm8s: 1, no_block_boundary_in_interpreted: 1, skip: 1, block_boundary: 1, jump_offset_imm: 1, custom: 1, conditional_jump: 1, },
357
    { opcode: 0xE3, os: 1, imm8s: 1, no_block_boundary_in_interpreted: 1, skip: 1, block_boundary: 1, jump_offset_imm: 1, custom: 1, conditional_jump: 1, },
358

359
    // port functions aren't jumps, but they may modify eip due to how they are implemented
360
    { opcode: 0xE4, block_boundary: 1, imm8: 1, skip: 1, }, // in
361
    { opcode: 0xE5, block_boundary: 1, os: 1, imm8: 1, skip: 1, },
362
    { opcode: 0xE6, block_boundary: 1, imm8: 1, skip: 1, }, // out
363
    { opcode: 0xE7, block_boundary: 1, os: 1, imm8: 1, skip: 1, },
364

365
    { opcode: 0xE8, block_boundary: 1, jump_offset_imm: 1, os: 1, imm1632: 1, custom: 1, skip: 1, }, // call
366
    { opcode: 0xE9, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, no_next_instruction: 1, os: 1, imm1632: 1, custom: 1, skip: 1, },
367
    { opcode: 0xEA, block_boundary: 1, no_next_instruction: 1, os: 1, imm1632: 1, extra_imm16: 1, skip: 1, }, // jmpf
368
    { opcode: 0xEB, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, no_next_instruction: 1, os: 1, imm8s: 1, custom: 1, skip: 1, },
369

370
    { opcode: 0xEC, block_boundary: 1, skip: 1, }, // in
371
    { opcode: 0xED, block_boundary: 1, os: 1, skip: 1, },
372
    { opcode: 0xEE, block_boundary: 1, skip: 1, }, // out
373
    { opcode: 0xEF, block_boundary: 1, os: 1, skip: 1, },
374

375
    { opcode: 0xF0, prefix: 1, },
376
    { opcode: 0xF1, skip: 1, },
377
    { opcode: 0xF2, prefix: 1, },
378
    { opcode: 0xF3, prefix: 1, },
379
    { opcode: 0xF4, block_boundary: 1, no_next_instruction: 1, skip: 1, }, // hlt
380
    { opcode: 0xF5, },
381

382
    { opcode: 0xF6, e: 1, fixed_g: 0, imm8: 1, custom: 1 },
383
    { opcode: 0xF6, e: 1, fixed_g: 1, imm8: 1, custom: 1 },
384
    { opcode: 0xF6, e: 1, fixed_g: 2, custom: 1 },
385
    { opcode: 0xF6, e: 1, fixed_g: 3, custom: 1 },
386
    { opcode: 0xF6, e: 1, fixed_g: 4, mask_flags: af | zf, },
387
    { opcode: 0xF6, e: 1, fixed_g: 5, mask_flags: af | zf, },
388
    { opcode: 0xF6, e: 1, fixed_g: 6, block_boundary: 1, }, // div/idiv: Not a block boundary, but doesn't use control flow exceptions
389
    { opcode: 0xF6, e: 1, fixed_g: 7, block_boundary: 1, },
390

391
    { opcode: 0xF7, os: 1, e: 1, fixed_g: 0, imm1632: 1, custom: 1 },
392
    { opcode: 0xF7, os: 1, e: 1, fixed_g: 1, imm1632: 1, custom: 1 },
393
    { opcode: 0xF7, os: 1, e: 1, fixed_g: 2, custom: 1 },
394
    { opcode: 0xF7, os: 1, e: 1, fixed_g: 3, custom: 1 },
395
    { opcode: 0xF7, os: 1, e: 1, fixed_g: 4, mask_flags: zf | af, custom: 1 },
396
    { opcode: 0xF7, os: 1, e: 1, fixed_g: 5, mask_flags: zf | af, custom: 1 },
397
    { opcode: 0xF7, os: 1, e: 1, fixed_g: 6, custom: 1 },
398
    { opcode: 0xF7, os: 1, e: 1, fixed_g: 7, custom: 1 },
399

400
    { opcode: 0xF8, custom: 1 },
401
    { opcode: 0xF9, custom: 1 },
402
    { opcode: 0xFA, custom: 1, skip: 1 },
403
    // STI: Note: Has special handling in jit in order to call handle_irqs safely
404
    { opcode: 0xFB, custom: 1, custom_sti: 1, skip: 1, },
405
    { opcode: 0xFC, custom: 1, },
406
    { opcode: 0xFD, custom: 1, },
407

408
    { opcode: 0xFE, e: 1, fixed_g: 0, custom: 1 },
409
    { opcode: 0xFE, e: 1, fixed_g: 1, custom: 1 },
410
    { opcode: 0xFF, os: 1, e: 1, fixed_g: 0, custom: 1, },
411
    { opcode: 0xFF, os: 1, e: 1, fixed_g: 1, custom: 1, },
412
    { opcode: 0xFF, os: 1, e: 1, fixed_g: 2, custom: 1, block_boundary: 1, absolute_jump: 1, skip: 1, },
413
    { opcode: 0xFF, os: 1, e: 1, fixed_g: 3, block_boundary: 1, skip: 1, },
414
    { opcode: 0xFF, os: 1, e: 1, fixed_g: 4, custom: 1, block_boundary: 1, absolute_jump: 1, no_next_instruction: 1, skip: 1, },
415
    { opcode: 0xFF, os: 1, e: 1, fixed_g: 5, block_boundary: 1, no_next_instruction: 1, skip: 1, },
416
    { opcode: 0xFF, custom: 1, os: 1, e: 1, fixed_g: 6, },
417

418
    { opcode: 0x0F00, fixed_g: 0, e: 1, skip: 1, block_boundary: 1, os: 1, }, // sldt, ...
419
    { opcode: 0x0F00, fixed_g: 1, e: 1, skip: 1, block_boundary: 1, os: 1, },
420
    { opcode: 0x0F00, fixed_g: 2, e: 1, skip: 1, block_boundary: 1, os: 1, },
421
    { opcode: 0x0F00, fixed_g: 3, e: 1, skip: 1, block_boundary: 1, os: 1, },
422
    { opcode: 0x0F00, fixed_g: 4, e: 1, skip: 1, block_boundary: 1, os: 1, },
423
    { opcode: 0x0F00, fixed_g: 5, e: 1, skip: 1, block_boundary: 1, os: 1, },
424

425
    { opcode: 0x0F01, fixed_g: 0, e: 1, skip: 1, block_boundary: 1, os: 1, }, // sgdt, ...
426
    { opcode: 0x0F01, fixed_g: 1, e: 1, skip: 1, block_boundary: 1, os: 1, },
427
    { opcode: 0x0F01, fixed_g: 2, e: 1, skip: 1, block_boundary: 1, os: 1, },
428
    { opcode: 0x0F01, fixed_g: 3, e: 1, skip: 1, block_boundary: 1, os: 1, },
429
    { opcode: 0x0F01, fixed_g: 4, e: 1, skip: 1, block_boundary: 1, os: 1, },
430
    { opcode: 0x0F01, fixed_g: 6, e: 1, skip: 1, block_boundary: 1, os: 1, },
431
    { opcode: 0x0F01, fixed_g: 7, e: 1, skip: 1, block_boundary: 1, os: 1, },
432

433
    { opcode: 0x0F02, os: 1, e: 1, skip: 1, block_boundary: 1, }, // lar
434
    { opcode: 0x0F03, os: 1, e: 1, skip: 1, block_boundary: 1, }, // lsl
435
    { opcode: 0x0F04, skip: 1, block_boundary: 1, },
436
    { opcode: 0x0F05, skip: 1, block_boundary: 1, },
437
    { opcode: 0x0F06, skip: 1, block_boundary: 1, }, // clts
438
    { opcode: 0x0F07, skip: 1, block_boundary: 1, },
439
    { opcode: 0x0F08, skip: 1, block_boundary: 1, },
440
    { opcode: 0x0F09, skip: 1, block_boundary: 1, }, // wbinvd
441
    { opcode: 0x0F0A, skip: 1, block_boundary: 1, },
442
    // ud2
443
    // Technically has a next instruction, but Linux uses this for assertions
444
    // and embeds the assertion message after this instruction, which is likely
445
    // the most common use case of ud2
446
    { opcode: 0x0F0B, skip: 1, block_boundary: 1, no_next_instruction: 1, },
447
    { opcode: 0x0F0C, skip: 1, block_boundary: 1, },
448
    { opcode: 0x0F0D, skip: 1, block_boundary: 1, },
449
    { opcode: 0x0F0E, skip: 1, block_boundary: 1, },
450
    { opcode: 0x0F0F, skip: 1, block_boundary: 1, },
451

452
    { opcode: 0x0F18, e: 1, custom: 1 },
453
    { opcode: 0x0F19, custom: 1, e: 1, },
454
    { opcode: 0x0F1A, skip: 1, block_boundary: 1, },
455
    { opcode: 0x0F1B, skip: 1, block_boundary: 1, },
456
    { opcode: 0x0F1C, custom: 1, e: 1, },
457
    { opcode: 0x0F1D, custom: 1, e: 1, },
458
    { opcode: 0x0F1E, custom: 1, e: 1, },
459
    { opcode: 0x0F1F, custom: 1, e: 1, },
460

461
    { opcode: 0x0F20, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1, }, // mov reg, creg
462
    { opcode: 0x0F21, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1, }, // mov reg, dreg
463
    { opcode: 0x0F22, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1, }, // mov creg, reg
464
    { opcode: 0x0F23, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1, }, // mov dreg, reg
465
    { opcode: 0x0F24, skip: 1, block_boundary: 1, },
466
    { opcode: 0x0F25, skip: 1, block_boundary: 1, },
467
    { opcode: 0x0F26, skip: 1, block_boundary: 1, },
468
    { opcode: 0x0F27, skip: 1, block_boundary: 1, },
469

470
    { opcode: 0x0F30, skip: 1, block_boundary: 1, }, // wrmsr
471
    { opcode: 0x0F31, skip: 1, custom: 1, }, // rdtsc
472
    { opcode: 0x0F32, skip: 1, block_boundary: 1, }, // rdmsr
473
    { opcode: 0x0F33, skip: 1, block_boundary: 1, }, // rdpmc
474
    { opcode: 0x0F34, skip: 1, block_boundary: 1, no_next_instruction: 1, }, // sysenter
475
    { opcode: 0x0F35, skip: 1, block_boundary: 1, no_next_instruction: 1, }, // sysexit
476

477
    { opcode: 0x0F36, skip: 1, block_boundary: 1, }, // ud
478
    { opcode: 0x0F37, skip: 1, block_boundary: 1, }, // getsec
479

480
    // sse3+
481
    { opcode: 0x0F38, skip: 1, block_boundary: 1, },
482
    { opcode: 0x0F39, skip: 1, block_boundary: 1, },
483
    { opcode: 0x0F3A, skip: 1, block_boundary: 1, },
484
    { opcode: 0x0F3B, skip: 1, block_boundary: 1, },
485
    { opcode: 0x0F3C, skip: 1, block_boundary: 1, },
486
    { opcode: 0x0F3D, skip: 1, block_boundary: 1, },
487
    { opcode: 0x0F3E, skip: 1, block_boundary: 1, },
488
    { opcode: 0x0F3F, skip: 1, block_boundary: 1, },
489

490
    { opcode: 0x0F40, e: 1, os: 1, custom: 1, },
491
    { opcode: 0x0F41, e: 1, os: 1, custom: 1, },
492
    { opcode: 0x0F42, e: 1, os: 1, custom: 1, },
493
    { opcode: 0x0F43, e: 1, os: 1, custom: 1, },
494
    { opcode: 0x0F44, e: 1, os: 1, custom: 1, },
495
    { opcode: 0x0F45, e: 1, os: 1, custom: 1, },
496
    { opcode: 0x0F46, e: 1, os: 1, custom: 1, },
497
    { opcode: 0x0F47, e: 1, os: 1, custom: 1, },
498
    { opcode: 0x0F48, e: 1, os: 1, custom: 1, },
499
    { opcode: 0x0F49, e: 1, os: 1, custom: 1, },
500
    { opcode: 0x0F4A, e: 1, os: 1, custom: 1, },
501
    { opcode: 0x0F4B, e: 1, os: 1, custom: 1, },
502
    { opcode: 0x0F4C, e: 1, os: 1, custom: 1, },
503
    { opcode: 0x0F4D, e: 1, os: 1, custom: 1, },
504
    { opcode: 0x0F4E, e: 1, os: 1, custom: 1, },
505
    { opcode: 0x0F4F, e: 1, os: 1, custom: 1, },
506

507
    { opcode: 0x0F80, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
508
    { opcode: 0x0F81, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
509
    { opcode: 0x0F82, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
510
    { opcode: 0x0F83, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
511
    { opcode: 0x0F84, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
512
    { opcode: 0x0F85, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
513
    { opcode: 0x0F86, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
514
    { opcode: 0x0F87, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
515
    { opcode: 0x0F88, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
516
    { opcode: 0x0F89, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
517
    { opcode: 0x0F8A, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
518
    { opcode: 0x0F8B, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
519
    { opcode: 0x0F8C, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
520
    { opcode: 0x0F8D, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
521
    { opcode: 0x0F8E, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
522
    { opcode: 0x0F8F, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, imm1632: 1, os: 1, custom: 1, skip: 1, },
523

524
    { opcode: 0x0F90, e: 1, custom: 1, },
525
    { opcode: 0x0F91, e: 1, custom: 1, },
526
    { opcode: 0x0F92, e: 1, custom: 1, },
527
    { opcode: 0x0F93, e: 1, custom: 1, },
528
    { opcode: 0x0F94, e: 1, custom: 1, },
529
    { opcode: 0x0F95, e: 1, custom: 1, },
530
    { opcode: 0x0F96, e: 1, custom: 1, },
531
    { opcode: 0x0F97, e: 1, custom: 1, },
532
    { opcode: 0x0F98, e: 1, custom: 1, },
533
    { opcode: 0x0F99, e: 1, custom: 1, },
534
    { opcode: 0x0F9A, e: 1, custom: 1, },
535
    { opcode: 0x0F9B, e: 1, custom: 1, },
536
    { opcode: 0x0F9C, e: 1, custom: 1, },
537
    { opcode: 0x0F9D, e: 1, custom: 1, },
538
    { opcode: 0x0F9E, e: 1, custom: 1, },
539
    { opcode: 0x0F9F, e: 1, custom: 1, },
540

541
    { opcode: 0x0FA0, os: 1, custom: 1, },
542
    { opcode: 0x0FA1, os: 1, block_boundary: 1, skip: 1, }, // pop fs: block_boundary since it uses non-raising cpu exceptions
543

544
    { opcode: 0x0FA2, skip: 1, },
545

546
    { opcode: 0x0FA8, os: 1, custom: 1, },
547
    { opcode: 0x0FA9, os: 1, block_boundary: 1, skip: 1, }, // pop gs
548

549
    { opcode: 0x0FA3, os: 1, e: 1, custom: 1, skip_mem: 1 }, // bt (can also index memory, but not supported by test right now)
550
    { opcode: 0x0FAB, os: 1, e: 1, custom: 1, skip_mem: 1 },
551
    { opcode: 0x0FB3, os: 1, e: 1, custom: 1, skip_mem: 1 },
552
    { opcode: 0x0FBB, os: 1, e: 1, custom: 1, skip_mem: 1 },
553

554
    { opcode: 0x0FBA, os: 1, e: 1, fixed_g: 4, imm8: 1, custom: 1 }, // bt
555
    { opcode: 0x0FBA, os: 1, e: 1, fixed_g: 5, imm8: 1, custom: 1 },
556
    { opcode: 0x0FBA, os: 1, e: 1, fixed_g: 6, imm8: 1, custom: 1 },
557
    { opcode: 0x0FBA, os: 1, e: 1, fixed_g: 7, imm8: 1, custom: 1 },
558

559
    { opcode: 0x0FBC, os: 1, e: 1, mask_flags: af, custom: 1 }, // bsf
560
    { opcode: 0x0FBD, os: 1, e: 1, mask_flags: af, custom: 1 },
561

562
    // note: overflow flag only undefined if shift is > 1
563
    { opcode: 0x0FA4, os: 1, e: 1, custom: 1, imm8: 1, mask_flags: af | of, }, // shld
564
    { opcode: 0x0FA5, os: 1, e: 1, custom: 1, mask_flags: af | of, },
565
    { opcode: 0x0FAC, os: 1, e: 1, custom: 1, imm8: 1, mask_flags: af | of, },
566
    { opcode: 0x0FAD, os: 1, e: 1, custom: 1, mask_flags: af | of, },
567

568
    { opcode: 0x0FA6, skip: 1, block_boundary: 1, }, // ud
569
    { opcode: 0x0FA7, skip: 1, block_boundary: 1, }, // ud
570

571
    { opcode: 0x0FAA, skip: 1 },
572

573
    { opcode: 0x0FAE, e: 1, fixed_g: 0, reg_ud: 1, task_switch_test: 1, skip: 1, block_boundary: 1, }, // fxsave
574
    { opcode: 0x0FAE, e: 1, fixed_g: 1, reg_ud: 1, task_switch_test: 1, skip: 1, block_boundary: 1, }, // fxrstor
575
    { opcode: 0x0FAE, e: 1, fixed_g: 2, reg_ud: 1, sse: 1, skip: 1, block_boundary: 1, }, // ldmxcsr
576
    { opcode: 0x0FAE, e: 1, fixed_g: 3, reg_ud: 1, sse: 1, skip: 1, block_boundary: 1, }, // stmxcsr
577

578
    { opcode: 0x0FAE, e: 1, fixed_g: 4, reg_ud: 1, skip: 1, block_boundary: 1, }, // xsave (mem, not implemented)
579
    { opcode: 0x0FAE, e: 1, fixed_g: 5, skip: 1, custom: 1 }, // lfence (reg, only 0), xrstor (mem, not implemented)
580
    { opcode: 0x0FAE, e: 1, fixed_g: 6, skip: 1, block_boundary: 1, }, // mfence (reg, only 0), xsaveopt (mem, not implemented)
581
    { opcode: 0x0FAE, e: 1, fixed_g: 7, skip: 1, block_boundary: 1, }, // sfence (reg, only 0), clflush (mem)
582

583
    { opcode: 0x0FAF, os: 1, e: 1, mask_flags: af | zf, custom: 1, }, // imul
584

585
    { opcode: 0x0FB0, e: 1 }, // cmxchg
586
    { opcode: 0x0FB1, os: 1, e: 1, custom: 1 },
587
    { opcode: 0x0FC7, e: 1, fixed_g: 1, os: 1, reg_ud: 1, custom: 1 }, // cmpxchg8b (memory)
588
    { opcode: 0x0FC7, e: 1, fixed_g: 6, os: 1, mem_ud: 1, skip: 1, }, // rdrand
589

590
    { opcode: 0x0FB2, block_boundary: 1, os: 1, e: 1, skip: 1, }, // lss
591
    { opcode: 0x0FB4, block_boundary: 1, os: 1, e: 1, skip: 1, }, // lfs
592
    { opcode: 0x0FB5, block_boundary: 1, os: 1, e: 1, skip: 1, }, // lgs
593

594
    { opcode: 0x0FB6, os: 1, e: 1, custom: 1 }, // movzx
595
    { opcode: 0x0FB7, os: 1, e: 1, custom: 1 },
596

597
    { opcode: 0xF30FB8, os: 1, e: 1, custom: 1 }, // popcnt
598
    { opcode: 0x0FB8, os: 1, e: 1, block_boundary: 1, }, // ud
599

600
    { opcode: 0x0FB9, block_boundary: 1, }, // ud2
601

602
    { opcode: 0x0FBE, os: 1, e: 1, custom: 1 }, // movsx
603
    { opcode: 0x0FBF, os: 1, e: 1, custom: 1 },
604

605
    { opcode: 0x0FC0, e: 1, }, // xadd
606
    { opcode: 0x0FC1, os: 1, e: 1, custom: 1 },
607

608
    { opcode: 0x0FC8, custom: 1 }, // bswap
609
    { opcode: 0x0FC9, custom: 1 },
610
    { opcode: 0x0FCA, custom: 1 },
611
    { opcode: 0x0FCB, custom: 1 },
612
    { opcode: 0x0FCC, custom: 1 },
613
    { opcode: 0x0FCD, custom: 1 },
614
    { opcode: 0x0FCE, custom: 1 },
615
    { opcode: 0x0FCF, custom: 1 },
616

617

618
    // mmx, sse
619
    // - skipped or missing are sse3+
620

621
    { sse: 1, opcode: 0x0F10, e: 1, custom: 1 },
622
    { sse: 1, opcode: 0xF30F10, e: 1, custom: 1 },
623
    { sse: 1, opcode: 0x660F10, e: 1, custom: 1 },
624
    { sse: 1, opcode: 0xF20F10, e: 1, custom: 1 },
625
    { sse: 1, opcode: 0x0F11, e: 1, custom: 1 },
626
    { sse: 1, opcode: 0xF30F11, e: 1, custom: 1 },
627
    { sse: 1, opcode: 0x660F11, e: 1, custom: 1 },
628
    { sse: 1, opcode: 0xF20F11, e: 1, custom: 1 },
629
    { sse: 1, opcode: 0x0F12, e: 1, custom: 1 },
630
    { sse: 1, opcode: 0x660F12, reg_ud: 1, e: 1, custom: 1 },
631
    { sse: 1, opcode: 0xF20F12, e: 1, skip: 1, block_boundary: 1, }, // sse3
632
    { sse: 1, opcode: 0xF30F12, e: 1, skip: 1, block_boundary: 1, }, // sse3
633
    { sse: 1, opcode: 0x0F13, reg_ud: 1, e: 1, custom: 1 },
634
    { sse: 1, opcode: 0x660F13, reg_ud: 1, e: 1, custom: 1 },
635
    { sse: 1, opcode: 0x0F14, e: 1, custom: 1 },
636
    { sse: 1, opcode: 0x660F14, e: 1, custom: 1 },
637
    { sse: 1, opcode: 0x0F15, e: 1, custom: 1 },
638
    { sse: 1, opcode: 0x660F15, e: 1, custom: 1 },
639
    { sse: 1, opcode: 0x0F16, e: 1 },
640
    { sse: 1, opcode: 0x660F16, reg_ud: 1, e: 1 },
641
    { sse: 1, opcode: 0xF30F16, skip: 1, e: 1, block_boundary: 1, }, // sse3
642
    { sse: 1, opcode: 0x0F17, reg_ud: 1, e: 1 },
643
    { sse: 1, opcode: 0x660F17, reg_ud: 1, e: 1 },
644

645
    { sse: 1, opcode: 0x0F28, e: 1, custom: 1 },
646
    { sse: 1, opcode: 0x660F28, e: 1, custom: 1 },
647
    { sse: 1, opcode: 0x0F29, e: 1, custom: 1 },
648
    { sse: 1, opcode: 0x660F29, e: 1, custom: 1 },
649
    { sse: 1, opcode: 0x0F2A, e: 1, custom: 1 },
650
    { sse: 1, opcode: 0x660F2A, e: 1, custom: 1 },
651
    { sse: 1, opcode: 0xF20F2A, e: 1, custom: 1 },
652
    { sse: 1, opcode: 0xF30F2A, e: 1, custom: 1 },
653
    { sse: 1, opcode: 0x0F2B, reg_ud: 1, e: 1, custom: 1 },
654
    { sse: 1, opcode: 0x660F2B, reg_ud: 1, e: 1, custom: 1 },
655

656
    { sse: 1, opcode: 0x0F2C, e: 1, },
657
    { sse: 1, opcode: 0x660F2C, e: 1, },
658
    { sse: 1, opcode: 0xF20F2C, e: 1, custom: 1 },
659
    { sse: 1, opcode: 0xF30F2C, e: 1, custom: 1 },
660
    { sse: 1, opcode: 0x0F2D, e: 1, },
661
    { sse: 1, opcode: 0x660F2D, e: 1, },
662
    { sse: 1, opcode: 0xF20F2D, e: 1, custom: 1 },
663
    { sse: 1, opcode: 0xF30F2D, e: 1, custom: 1 },
664

665
    { sse: 1, opcode: 0x0F2E, e: 1, custom: 1 },
666
    { sse: 1, opcode: 0x660F2E, e: 1, custom: 1 },
667
    { sse: 1, opcode: 0x0F2F, e: 1, custom: 1 },
668
    { sse: 1, opcode: 0x660F2F, e: 1, custom: 1 },
669

670
    { sse: 1, opcode: 0x0F50, mem_ud: 1, e: 1 },
671
    { sse: 1, opcode: 0x660F50, mem_ud: 1, e: 1 },
672
    { sse: 1, opcode: 0x0F51, e: 1, custom: 1 },
673
    { sse: 1, opcode: 0x660F51, e: 1, custom: 1 },
674
    { sse: 1, opcode: 0xF20F51, e: 1, custom: 1 },
675
    { sse: 1, opcode: 0xF30F51, e: 1, custom: 1 },
676

677
    // approximation of 1/sqrt(x). Skipped because our approximation doesn't match intel's
678
    { sse: 1, opcode: 0x0F52, e: 1, skip: 1, custom: 1 },
679
    { sse: 1, opcode: 0xF30F52, e: 1, skip: 1, custom: 1 },
680

681
    // reciprocal: approximation of 1/x. Skipped because our approximation doesn't match intel's
682
    { sse: 1, opcode: 0x0F53, e: 1, skip: 1, custom: 1 },
683
    { sse: 1, opcode: 0xF30F53, e: 1, skip: 1, custom: 1 },
684

685
    { sse: 1, opcode: 0x0F54, e: 1, custom: 1 },
686
    { sse: 1, opcode: 0x660F54, e: 1, custom: 1 },
687
    { sse: 1, opcode: 0x0F55, e: 1, custom: 1 },
688
    { sse: 1, opcode: 0x660F55, e: 1, custom: 1 },
689
    { sse: 1, opcode: 0x0F56, e: 1, custom: 1 },
690
    { sse: 1, opcode: 0x660F56, e: 1, custom: 1 },
691
    { sse: 1, opcode: 0x0F57, e: 1, custom: 1 },
692
    { sse: 1, opcode: 0x660F57, e: 1, custom: 1 },
693

694
    { sse: 1, opcode: 0x0F58, e: 1, custom: 1 },
695
    { sse: 1, opcode: 0x660F58, e: 1, custom: 1 },
696
    { sse: 1, opcode: 0xF20F58, e: 1, custom: 1 },
697
    { sse: 1, opcode: 0xF30F58, e: 1, custom: 1 },
698
    { sse: 1, opcode: 0x0F59, e: 1, custom: 1 },
699
    { sse: 1, opcode: 0x660F59, e: 1, custom: 1 },
700
    { sse: 1, opcode: 0xF20F59, e: 1, custom: 1 },
701
    { sse: 1, opcode: 0xF30F59, e: 1, custom: 1 },
702

703
    { sse: 1, opcode: 0x0F5A, e: 1, custom: 1 },
704
    { sse: 1, opcode: 0x660F5A, e: 1, custom: 1 },
705
    { sse: 1, opcode: 0xF20F5A, e: 1, custom: 1 },
706
    { sse: 1, opcode: 0xF30F5A, e: 1, custom: 1 },
707
    { sse: 1, opcode: 0x0F5B, e: 1, custom: 1 },
708
    { sse: 1, opcode: 0x660F5B, e: 1, custom: 1 },
709
    // no F2 variant
710
    { sse: 1, opcode: 0xF30F5B, e: 1, custom: 1 },
711

712
    { sse: 1, opcode: 0x0F5C, e: 1, custom: 1 },
713
    { sse: 1, opcode: 0x660F5C, e: 1, custom: 1 },
714
    { sse: 1, opcode: 0xF20F5C, e: 1, custom: 1 },
715
    { sse: 1, opcode: 0xF30F5C, e: 1, custom: 1 },
716
    { sse: 1, opcode: 0x0F5D, e: 1, custom: 1 },
717
    { sse: 1, opcode: 0x660F5D, e: 1, custom: 1 },
718
    { sse: 1, opcode: 0xF20F5D, e: 1, custom: 1 },
719
    { sse: 1, opcode: 0xF30F5D, e: 1, custom: 1 },
720

721
    { sse: 1, opcode: 0x0F5E, e: 1, custom: 1 },
722
    { sse: 1, opcode: 0x660F5E, e: 1, custom: 1 },
723
    { sse: 1, opcode: 0xF20F5E, e: 1, custom: 1 },
724
    { sse: 1, opcode: 0xF30F5E, e: 1, custom: 1 },
725
    { sse: 1, opcode: 0x0F5F, e: 1, custom: 1 },
726
    { sse: 1, opcode: 0x660F5F, e: 1, custom: 1 },
727
    { sse: 1, opcode: 0xF20F5F, e: 1, custom: 1 },
728
    { sse: 1, opcode: 0xF30F5F, e: 1, custom: 1 },
729

730
    { sse: 1, opcode: 0x660F60, e: 1, custom: 1 },
731
    { sse: 1, opcode: 0x0F60, e: 1, custom: 1 },
732
    { sse: 1, opcode: 0x660F61, e: 1, custom: 1 },
733
    { sse: 1, opcode: 0x0F61, e: 1, custom: 1 },
734
    { sse: 1, opcode: 0x660F62, e: 1, custom: 1 },
735
    { sse: 1, opcode: 0x0F62, e: 1, custom: 1 },
736
    { sse: 1, opcode: 0x660F63, e: 1, custom: 1 },
737
    { sse: 1, opcode: 0x0F63, e: 1, custom: 1 },
738
    { sse: 1, opcode: 0x660F64, e: 1, custom: 1 },
739
    { sse: 1, opcode: 0x0F64, e: 1, custom: 1 },
740
    { sse: 1, opcode: 0x660F65, e: 1, custom: 1 },
741
    { sse: 1, opcode: 0x0F65, e: 1, custom: 1 },
742
    { sse: 1, opcode: 0x660F66, e: 1, custom: 1 },
743
    { sse: 1, opcode: 0x0F66, e: 1, custom: 1 },
744
    { sse: 1, opcode: 0x660F67, e: 1, custom: 1 },
745
    { sse: 1, opcode: 0x0F67, e: 1, custom: 1 },
746

747
    { sse: 1, opcode: 0x660F68, e: 1, custom: 1 },
748
    { sse: 1, opcode: 0x0F68, e: 1, custom: 1 },
749
    { sse: 1, opcode: 0x660F69, e: 1, custom: 1 },
750
    { sse: 1, opcode: 0x0F69, e: 1, custom: 1 },
751
    { sse: 1, opcode: 0x660F6A, e: 1, custom: 1 },
752
    { sse: 1, opcode: 0x0F6A, e: 1, custom: 1 },
753
    { sse: 1, opcode: 0x660F6B, e: 1, custom: 1 },
754
    { sse: 1, opcode: 0x0F6B, e: 1, custom: 1 },
755
    { sse: 1, opcode: 0x660F6C, e: 1, custom: 1 },
756
    { sse: 1, opcode: 0x0F6C, e: 1, block_boundary: 1, }, // ud
757
    { sse: 1, opcode: 0x660F6D, e: 1, custom: 1 },
758
    { sse: 1, opcode: 0x0F6D, e: 1, block_boundary: 1, }, // ud
759
    { sse: 1, opcode: 0x660F6E, e: 1, custom: 1 },
760
    { sse: 1, opcode: 0x0F6E, e: 1, custom: 1 },
761
    { sse: 1, opcode: 0xF30F6F, e: 1, custom: 1 },
762
    { sse: 1, opcode: 0x660F6F, e: 1, custom: 1 },
763
    { sse: 1, opcode: 0x0F6F, e: 1, custom: 1 },
764

765
    { sse: 1, opcode: 0x0F70, e: 1, imm8: 1, custom: 1 },
766
    { sse: 1, opcode: 0x660F70, e: 1, imm8: 1, custom: 1 },
767
    { sse: 1, opcode: 0xF20F70, e: 1, imm8: 1, custom: 1 },
768
    { sse: 1, opcode: 0xF30F70, e: 1, imm8: 1, custom: 1 },
769

770
    { sse: 1, opcode: 0x0F71, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, custom: 1 },
771
    { sse: 1, opcode: 0x660F71, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, custom: 1 },
772
    { sse: 1, opcode: 0x0F71, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1, custom: 1 },
773
    { sse: 1, opcode: 0x660F71, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1, custom: 1 },
774
    { sse: 1, opcode: 0x0F71, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, custom: 1 },
775
    { sse: 1, opcode: 0x660F71, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, custom: 1 },
776

777
    { sse: 1, opcode: 0x0F72, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, custom: 1 },
778
    { sse: 1, opcode: 0x660F72, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, custom: 1 },
779
    { sse: 1, opcode: 0x0F72, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1, custom: 1 },
780
    { sse: 1, opcode: 0x660F72, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1, custom: 1 },
781
    { sse: 1, opcode: 0x0F72, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, custom: 1 },
782
    { sse: 1, opcode: 0x660F72, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, custom: 1 },
783

784
    { sse: 1, opcode: 0x0F73, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, custom: 1 },
785
    { sse: 1, opcode: 0x660F73, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, custom: 1 },
786
    { sse: 1, opcode: 0x660F73, e: 1, fixed_g: 3, imm8: 1, mem_ud: 1, custom: 1 },
787
    { sse: 1, opcode: 0x0F73, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, custom: 1 },
788
    { sse: 1, opcode: 0x660F73, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, custom: 1 },
789
    { sse: 1, opcode: 0x660F73, e: 1, fixed_g: 7, imm8: 1, mem_ud: 1, custom: 1 },
790

791
    { sse: 1, opcode: 0x0F74, e: 1, custom: 1 },
792
    { sse: 1, opcode: 0x660F74, e: 1, custom: 1 },
793
    { sse: 1, opcode: 0x0F75, e: 1, custom: 1 },
794
    { sse: 1, opcode: 0x660F75, e: 1, custom: 1 },
795
    { sse: 1, opcode: 0x0F76, e: 1, custom: 1 },
796
    { sse: 1, opcode: 0x660F76, e: 1, custom: 1 },
797
    { sse: 1, opcode: 0x0F77, skip: 1 }, // emms (skip as it breaks gdb printing of float registers)
798

799
    // vmx instructions
800
    { opcode: 0x0F78, skip: 1, block_boundary: 1, },
801
    { opcode: 0x0F79, skip: 1, block_boundary: 1, },
802

803
    { opcode: 0x0F7A, skip: 1, block_boundary: 1, }, // ud
804
    { opcode: 0x0F7B, skip: 1, block_boundary: 1, }, // ud
805
    { sse: 1, opcode: 0x0F7C, skip: 1, block_boundary: 1, }, // sse3
806
    { sse: 1, opcode: 0x0F7D, skip: 1, block_boundary: 1, }, // sse3
807

808
    { sse: 1, opcode: 0x0F7E, e: 1, custom: 1 },
809
    { sse: 1, opcode: 0x660F7E, e: 1, custom: 1 },
810
    { sse: 1, opcode: 0xF30F7E, e: 1, custom: 1 },
811
    { sse: 1, opcode: 0x0F7F, e: 1, custom: 1 },
812
    { sse: 1, opcode: 0x660F7F, e: 1, custom: 1 },
813
    { sse: 1, opcode: 0xF30F7F, e: 1, custom: 1 },
814

815
    { sse: 1, opcode: 0x0FC2, e: 1, imm8: 1, custom: 1 },
816
    { sse: 1, opcode: 0x660FC2, e: 1, imm8: 1, custom: 1 },
817
    { sse: 1, opcode: 0xF20FC2, e: 1, imm8: 1, custom: 1 },
818
    { sse: 1, opcode: 0xF30FC2, e: 1, imm8: 1, custom: 1 },
819

820
    { opcode: 0x0FC3, e: 1, custom: 1, reg_ud: 1, }, // movnti: Uses normal registers, hence not marked as sse
821

822
    { sse: 1, opcode: 0x0FC4, e: 1, imm8: 1 },
823
    { sse: 1, opcode: 0x660FC4, e: 1, imm8: 1 },
824
    { sse: 1, opcode: 0x0FC5, e: 1, mem_ud: 1, imm8: 1 },
825
    { sse: 1, opcode: 0x660FC5, e: 1, mem_ud: 1, imm8: 1, },
826

827
    { sse: 1, opcode: 0x0FC6, e: 1, imm8: 1, custom: 1 },
828
    { sse: 1, opcode: 0x660FC6, e: 1, imm8: 1, custom: 1 },
829

830
    { sse: 1, opcode: 0x0FD0, skip: 1, block_boundary: 1, }, // sse3
831

832
    { sse: 1, opcode: 0x0FD1, e: 1, custom: 1 },
833
    { sse: 1, opcode: 0x660FD1, e: 1, custom: 1 },
834
    { sse: 1, opcode: 0x0FD2, e: 1, custom: 1 },
835
    { sse: 1, opcode: 0x660FD2, e: 1, custom: 1 },
836
    { sse: 1, opcode: 0x0FD3, e: 1, custom: 1 },
837
    { sse: 1, opcode: 0x660FD3, e: 1, custom: 1 },
838
    { sse: 1, opcode: 0x0FD4, e: 1, custom: 1 },
839
    { sse: 1, opcode: 0x660FD4, e: 1, custom: 1 },
840
    { sse: 1, opcode: 0x0FD5, e: 1, custom: 1 },
841
    { sse: 1, opcode: 0x660FD5, e: 1, custom: 1 },
842

843
    { sse: 1, opcode: 0x660FD6, e: 1, custom: 1 },
844
    { sse: 1, opcode: 0xF20FD6, mem_ud: 1, e: 1 },
845
    { sse: 1, opcode: 0xF30FD6, mem_ud: 1, e: 1 },
846
    { sse: 1, opcode: 0x0FD6, e: 1, block_boundary: 1, }, // ud
847

848
    { sse: 1, opcode: 0x0FD7, e: 1, mem_ud: 1, custom: 1 },
849
    { sse: 1, opcode: 0x660FD7, e: 1, mem_ud: 1, custom: 1 },
850

851
    { sse: 1, opcode: 0x0FD8, e: 1, custom: 1 },
852
    { sse: 1, opcode: 0x660FD8, e: 1, custom: 1 },
853
    { sse: 1, opcode: 0x0FD9, e: 1, custom: 1 },
854
    { sse: 1, opcode: 0x660FD9, e: 1, custom: 1 },
855
    { sse: 1, opcode: 0x0FDA, e: 1, custom: 1 },
856
    { sse: 1, opcode: 0x660FDA, e: 1, custom: 1 },
857
    { sse: 1, opcode: 0x0FDB, e: 1, custom: 1 },
858
    { sse: 1, opcode: 0x660FDB, e: 1, custom: 1 },
859
    { sse: 1, opcode: 0x0FDC, e: 1, custom: 1 },
860
    { sse: 1, opcode: 0x660FDC, e: 1, custom: 1 },
861
    { sse: 1, opcode: 0x0FDD, e: 1, custom: 1 },
862
    { sse: 1, opcode: 0x660FDD, e: 1, custom: 1 },
863
    { sse: 1, opcode: 0x0FDE, e: 1, custom: 1 },
864
    { sse: 1, opcode: 0x660FDE, e: 1, custom: 1 },
865
    { sse: 1, opcode: 0x0FDF, e: 1, custom: 1 },
866
    { sse: 1, opcode: 0x660FDF, e: 1, custom: 1 },
867

868
    { sse: 1, opcode: 0x0FE0, e: 1, custom: 1 },
869
    { sse: 1, opcode: 0x660FE0, e: 1, custom: 1 },
870
    { sse: 1, opcode: 0x0FE1, e: 1, custom: 1 },
871
    { sse: 1, opcode: 0x660FE1, e: 1, custom: 1 },
872
    { sse: 1, opcode: 0x0FE2, e: 1, custom: 1 },
873
    { sse: 1, opcode: 0x660FE2, e: 1, custom: 1 },
874
    { sse: 1, opcode: 0x0FE3, e: 1, custom: 1 },
875
    { sse: 1, opcode: 0x660FE3, e: 1, custom: 1 },
876
    { sse: 1, opcode: 0x0FE4, e: 1, custom: 1 },
877
    { sse: 1, opcode: 0x660FE4, e: 1, custom: 1 },
878
    { sse: 1, opcode: 0x0FE5, e: 1, custom: 1 },
879
    { sse: 1, opcode: 0x660FE5, e: 1, custom: 1 },
880

881
    { sse: 1, opcode: 0x660FE6, e: 1, custom: 1 },
882
    { sse: 1, opcode: 0xF20FE6, e: 1, custom: 1 },
883
    { sse: 1, opcode: 0xF30FE6, e: 1, custom: 1 },
884
    { sse: 1, opcode: 0x0FE6, e: 1, block_boundary: 1, }, // ud
885
    { sse: 1, opcode: 0x0FE7, e: 1, reg_ud: 1 },
886
    { sse: 1, opcode: 0x660FE7, e: 1, reg_ud: 1, custom: 1 },
887

888
    { sse: 1, opcode: 0x0FE8, e: 1, custom: 1 },
889
    { sse: 1, opcode: 0x660FE8, e: 1, custom: 1 },
890
    { sse: 1, opcode: 0x0FE9, e: 1, custom: 1 },
891
    { sse: 1, opcode: 0x660FE9, e: 1, custom: 1 },
892
    { sse: 1, opcode: 0x0FEA, e: 1, custom: 1 },
893
    { sse: 1, opcode: 0x660FEA, e: 1, custom: 1 },
894
    { sse: 1, opcode: 0x0FEB, e: 1, custom: 1 },
895
    { sse: 1, opcode: 0x660FEB, e: 1, custom: 1 },
896
    { sse: 1, opcode: 0x0FEC, e: 1, custom: 1 },
897
    { sse: 1, opcode: 0x660FEC, e: 1, custom: 1 },
898
    { sse: 1, opcode: 0x0FED, e: 1, custom: 1 },
899
    { sse: 1, opcode: 0x660FED, e: 1, custom: 1 },
900
    { sse: 1, opcode: 0x0FEE, e: 1, custom: 1 },
901
    { sse: 1, opcode: 0x660FEE, e: 1, custom: 1 },
902
    { sse: 1, opcode: 0x0FEF, e: 1, custom: 1 },
903
    { sse: 1, opcode: 0x660FEF, e: 1, custom: 1 },
904

905
    { sse: 1, opcode: 0x0FF0, skip: 1, block_boundary: 1, }, // sse3
906

907
    { sse: 1, opcode: 0x0FF1, e: 1, custom: 1 },
908
    { sse: 1, opcode: 0x660FF1, e: 1, custom: 1 },
909
    { sse: 1, opcode: 0x0FF2, e: 1, custom: 1 },
910
    { sse: 1, opcode: 0x660FF2, e: 1, custom: 1 },
911
    { sse: 1, opcode: 0x0FF3, e: 1, custom: 1 },
912
    { sse: 1, opcode: 0x660FF3, e: 1, custom: 1, },
913
    { sse: 1, opcode: 0x0FF4, e: 1, custom: 1 },
914
    { sse: 1, opcode: 0x660FF4, e: 1, custom: 1 },
915
    { sse: 1, opcode: 0x0FF5, e: 1, custom: 1 },
916
    { sse: 1, opcode: 0x660FF5, e: 1, custom: 1 },
917
    { sse: 1, opcode: 0x0FF6, e: 1, custom: 1 },
918
    { sse: 1, opcode: 0x660FF6, e: 1, custom: 1 },
919
    // maskmovq (0FF7), maskmovdqu (660FF7) tested manually
920
    // Generated tests don't setup EDI as required (yet)
921
    { sse: 1, opcode: 0x0FF7, mem_ud: 1, e: 1, custom: 1, skip: 1, },
922
    { sse: 1, opcode: 0x660FF7, mem_ud: 1, e: 1, custom: 1, skip: 1, },
923

924
    { sse: 1, opcode: 0x0FF8, e: 1, custom: 1 },
925
    { sse: 1, opcode: 0x660FF8, e: 1, custom: 1 },
926
    { sse: 1, opcode: 0x0FF9, e: 1, custom: 1 },
927
    { sse: 1, opcode: 0x660FF9, e: 1, custom: 1 },
928
    { sse: 1, opcode: 0x0FFA, e: 1, custom: 1 },
929
    { sse: 1, opcode: 0x660FFA, e: 1, custom: 1 },
930
    { sse: 1, opcode: 0x0FFB, e: 1, custom: 1 },
931
    { sse: 1, opcode: 0x660FFB, e: 1, custom: 1 },
932
    { sse: 1, opcode: 0x0FFC, e: 1, custom: 1 },
933
    { sse: 1, opcode: 0x660FFC, e: 1, custom: 1 },
934
    { sse: 1, opcode: 0x0FFD, e: 1, custom: 1 },
935
    { sse: 1, opcode: 0x660FFD, e: 1, custom: 1 },
936
    { sse: 1, opcode: 0x0FFE, e: 1, custom: 1 },
937
    { sse: 1, opcode: 0x660FFE, e: 1, custom: 1 },
938

939
    { opcode: 0x0FFF, block_boundary: 1, }, // ud
940
];
941

942
for(let i = 0; i < 8; i++)
943
{
944
    encodings.push.apply(encodings, [
945
        { opcode: 0x04 | i << 3, custom: 1, imm8: 1, },
946
        { opcode: 0x05 | i << 3, custom: 1, os: 1, imm1632: 1, },
947

948
        { opcode: 0x70 | i, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, os: 1, imm8s: 1, custom: 1, skip: 1, },
949
        { opcode: 0x78 | i, block_boundary: 1, no_block_boundary_in_interpreted: 1, jump_offset_imm: 1, conditional_jump: 1, os: 1, imm8s: 1, custom: 1, skip: 1, },
950

951
        { opcode: 0x80, e: 1, fixed_g: i, imm8: 1, custom: 1, },
952
        { opcode: 0x81, os: 1, e: 1, fixed_g: i, imm1632: 1, custom: 1, },
953
        { opcode: 0x82, e: 1, fixed_g: i, imm8: 1, custom: 1, },
954
        { opcode: 0x83, os: 1, e: 1, fixed_g: i, imm8s: 1, custom: 1, },
955

956
        { opcode: 0xB0 | i, custom: 1, imm8: 1, },
957
        { opcode: 0xB8 | i, custom: 1, os: 1, imm1632: 1, },
958

959
        // note: overflow flag only undefined if shift is > 1
960
        // note: the adjust flag is undefined for shifts > 0 and unaffected by rotates
961
        { opcode: 0xC0, e: 1, fixed_g: i, imm8: 1, mask_flags: of | af, custom: 1, },
962
        { opcode: 0xC1, os: 1, e: 1, fixed_g: i, imm8: 1, mask_flags: of | af, custom: 1, },
963
        { opcode: 0xD0, e: 1, fixed_g: i, mask_flags: af, custom: 1 },
964
        { opcode: 0xD1, os: 1, e: 1, fixed_g: i, mask_flags: af, custom: 1, },
965
        { opcode: 0xD2, e: 1, fixed_g: i, mask_flags: of | af, custom: 1 },
966
        { opcode: 0xD3, os: 1, e: 1, fixed_g: i, mask_flags: of | af, custom: 1, },
967
    ]);
968
}
969

970
encodings.sort((e1, e2) => {
971
    let o1 = (e1.opcode & 0xFF00) === 0x0F00 ? e1.opcode & 0xFFFF : e1.opcode & 0xFF;
972
    let o2 = (e2.opcode & 0xFF00) === 0x0F00 ? e2.opcode & 0xFFFF : e2.opcode & 0xFF;
973
    return o1 - o2 || e1.fixed_g - e2.fixed_g;
974
});
975

976
module.exports = Object.freeze(encodings.map(entry => Object.freeze(entry)));
977

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.