@aptre/v86 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +22 -0
  2. package/LICENSE.MIT +22 -0
  3. package/Readme.md +237 -0
  4. package/dist/v86.browser.js +26666 -0
  5. package/dist/v86.browser.js.map +7 -0
  6. package/dist/v86.js +26632 -0
  7. package/dist/v86.js.map +7 -0
  8. package/gen/generate_analyzer.ts +512 -0
  9. package/gen/generate_interpreter.ts +522 -0
  10. package/gen/generate_jit.ts +624 -0
  11. package/gen/rust_ast.ts +107 -0
  12. package/gen/util.ts +35 -0
  13. package/gen/x86_table.ts +1836 -0
  14. package/lib/9p.ts +1547 -0
  15. package/lib/filesystem.ts +1879 -0
  16. package/lib/marshall.ts +168 -0
  17. package/lib/softfloat/softfloat.c +32501 -0
  18. package/lib/zstd/zstddeclib.c +13520 -0
  19. package/package.json +75 -0
  20. package/src/acpi.ts +267 -0
  21. package/src/browser/dummy_screen.ts +106 -0
  22. package/src/browser/fake_network.ts +1771 -0
  23. package/src/browser/fetch_network.ts +361 -0
  24. package/src/browser/filestorage.ts +124 -0
  25. package/src/browser/inbrowser_network.ts +57 -0
  26. package/src/browser/keyboard.ts +564 -0
  27. package/src/browser/main.ts +3415 -0
  28. package/src/browser/mouse.ts +255 -0
  29. package/src/browser/network.ts +142 -0
  30. package/src/browser/print_stats.ts +336 -0
  31. package/src/browser/screen.ts +978 -0
  32. package/src/browser/serial.ts +316 -0
  33. package/src/browser/speaker.ts +1223 -0
  34. package/src/browser/starter.ts +1688 -0
  35. package/src/browser/wisp_network.ts +332 -0
  36. package/src/browser/worker_bus.ts +64 -0
  37. package/src/buffer.ts +652 -0
  38. package/src/bus.ts +78 -0
  39. package/src/const.ts +128 -0
  40. package/src/cpu.ts +2891 -0
  41. package/src/dma.ts +474 -0
  42. package/src/elf.ts +251 -0
  43. package/src/floppy.ts +1778 -0
  44. package/src/ide.ts +3455 -0
  45. package/src/io.ts +504 -0
  46. package/src/iso9660.ts +317 -0
  47. package/src/kernel.ts +250 -0
  48. package/src/lib.ts +645 -0
  49. package/src/log.ts +149 -0
  50. package/src/main.ts +199 -0
  51. package/src/ne2k.ts +1589 -0
  52. package/src/pci.ts +815 -0
  53. package/src/pit.ts +406 -0
  54. package/src/ps2.ts +820 -0
  55. package/src/rtc.ts +537 -0
  56. package/src/rust/analysis.rs +101 -0
  57. package/src/rust/codegen.rs +2660 -0
  58. package/src/rust/config.rs +3 -0
  59. package/src/rust/control_flow.rs +425 -0
  60. package/src/rust/cpu/apic.rs +658 -0
  61. package/src/rust/cpu/arith.rs +1207 -0
  62. package/src/rust/cpu/call_indirect.rs +2 -0
  63. package/src/rust/cpu/cpu.rs +4501 -0
  64. package/src/rust/cpu/fpu.rs +923 -0
  65. package/src/rust/cpu/global_pointers.rs +112 -0
  66. package/src/rust/cpu/instructions.rs +2486 -0
  67. package/src/rust/cpu/instructions_0f.rs +5261 -0
  68. package/src/rust/cpu/ioapic.rs +316 -0
  69. package/src/rust/cpu/memory.rs +351 -0
  70. package/src/rust/cpu/misc_instr.rs +613 -0
  71. package/src/rust/cpu/mod.rs +16 -0
  72. package/src/rust/cpu/modrm.rs +133 -0
  73. package/src/rust/cpu/pic.rs +402 -0
  74. package/src/rust/cpu/sse_instr.rs +361 -0
  75. package/src/rust/cpu/string.rs +701 -0
  76. package/src/rust/cpu/vga.rs +175 -0
  77. package/src/rust/cpu_context.rs +69 -0
  78. package/src/rust/dbg.rs +98 -0
  79. package/src/rust/gen/analyzer.rs +3807 -0
  80. package/src/rust/gen/analyzer0f.rs +3992 -0
  81. package/src/rust/gen/interpreter.rs +4447 -0
  82. package/src/rust/gen/interpreter0f.rs +5404 -0
  83. package/src/rust/gen/jit.rs +5080 -0
  84. package/src/rust/gen/jit0f.rs +5547 -0
  85. package/src/rust/gen/mod.rs +14 -0
  86. package/src/rust/jit.rs +2443 -0
  87. package/src/rust/jit_instructions.rs +7881 -0
  88. package/src/rust/js_api.rs +6 -0
  89. package/src/rust/leb.rs +46 -0
  90. package/src/rust/lib.rs +29 -0
  91. package/src/rust/modrm.rs +330 -0
  92. package/src/rust/opstats.rs +249 -0
  93. package/src/rust/page.rs +15 -0
  94. package/src/rust/paging.rs +25 -0
  95. package/src/rust/prefix.rs +15 -0
  96. package/src/rust/profiler.rs +155 -0
  97. package/src/rust/regs.rs +38 -0
  98. package/src/rust/softfloat.rs +286 -0
  99. package/src/rust/state_flags.rs +27 -0
  100. package/src/rust/wasmgen/mod.rs +2 -0
  101. package/src/rust/wasmgen/wasm_builder.rs +1047 -0
  102. package/src/rust/wasmgen/wasm_opcodes.rs +221 -0
  103. package/src/rust/zstd.rs +105 -0
  104. package/src/sb16.ts +1928 -0
  105. package/src/state.ts +359 -0
  106. package/src/uart.ts +472 -0
  107. package/src/vga.ts +2791 -0
  108. package/src/virtio.ts +1756 -0
  109. package/src/virtio_balloon.ts +273 -0
  110. package/src/virtio_console.ts +372 -0
  111. package/src/virtio_net.ts +326 -0
@@ -0,0 +1,1836 @@
1
+ // http://ref.x86asm.net/coder32.html
2
+
3
+ export interface X86Encoding {
4
+ opcode: number
5
+ os?: number
6
+ e?: number
7
+ fixed_g?: number
8
+ custom?: number
9
+ custom_modrm_resolve?: number
10
+ custom_sti?: number
11
+ prefix?: number
12
+ block_boundary?: number
13
+ no_block_boundary_in_interpreted?: number
14
+ no_next_instruction?: number
15
+ absolute_jump?: number
16
+ jump_offset_imm?: number
17
+ conditional_jump?: number
18
+ imm8?: number
19
+ imm8s?: number
20
+ imm16?: number
21
+ imm1632?: number
22
+ imm32?: number
23
+ immaddr?: number
24
+ extra_imm8?: number
25
+ extra_imm16?: number
26
+ mask_flags?: number
27
+ skip?: number
28
+ skip_mem?: number
29
+ skip_reg?: number
30
+ is_string?: number
31
+ is_fpu?: number
32
+ task_switch_test?: number
33
+ sse?: number
34
+ reg_ud?: number
35
+ mem_ud?: number
36
+ ignore_mod?: number
37
+ }
38
+
39
+ const zf = 1 << 6
40
+ const of = 1 << 11
41
+ const cf = 1 << 0
42
+ const af = 1 << 4
43
+ const pf = 1 << 2
44
+ const sf = 1 << 7
45
+
46
+ // Test intel-specific behaviour
47
+ // Setting this to true can make some tests fail
48
+ const TESTS_ASSUME_INTEL = false
49
+
50
+ // === Types of instructions
51
+ //
52
+ // create entry | check for compiled code | instruction
53
+ // -------------+-------------------------+-----------------------------------------------------------
54
+ // 1 | optional | pop ds (may change cpu state)
55
+ // | | trigger_ud, div (exception that doesn't generate conditional return from BB)
56
+ // | | port io, popf, sti (may call interrupt or continue at next instruction)
57
+ // | | hlt
58
+ // -------------+-------------------------+-----------------------------------------------------------
59
+ // 1 | 1 | call [eax], jmp [eax], int, iret, ret, jmpf, callf, sysenter, sysexit
60
+ // | | Special case: normal instruction with fallthough to next page
61
+ // | | Special case: after execution of compiled code
62
+ // | | -> may create redundant entry points depending on last instruction?
63
+ // -------------+-------------------------+-----------------------------------------------------------
64
+ // 1 | 0 | rep movs, rep lods, rep stos, rep cmps, rep scas
65
+ // | | -> Executed as follows:
66
+ // | | - Upto including the first call in compiled mode
67
+ // | | - Back to main loop and repeated in interpreted mode (as entry point is after instruction, not on)
68
+ // | | - When finished entry pointer *after* instruction is hit and execution continues in compiled mode
69
+ // -------------+-------------------------+-----------------------------------------------------------
70
+ // 0 | optional | jmp foo, jnz foo
71
+ // | | (foo is in the same page as the instruction)
72
+ // -------------+-------------------------+-----------------------------------------------------------
73
+ // 1 | 1 | call foo
74
+ // | | (foo is in the same page as the instruction)
75
+ // | | -> The entry point is not created for jumps within
76
+ // | | this page, but speculatively for calls from
77
+ // | | other pages to the function in this page
78
+ // -------------+-------------------------+-----------------------------------------------------------
79
+ // 1 | 1 | call foo, jmp foo, jnz foo
80
+ // | | (foo is in a different page than the instruction)
81
+
82
+ // e: a modrm byte follows the operand
83
+ // os: the instruction behaves differently depending on the operand size
84
+ // fixed_g: the reg field of the modrm byte selects an instruction
85
+ // skip: skip automatically generated tests (nasmtests)
86
+ // mask_flags: flags bits to mask in generated tests
87
+ // prefix: is a prefix instruction
88
+ // imm8, imm8s, imm16, imm1632, immaddr, extra_imm8, extra_imm16: one or two immediate bytes follows the instruction
89
+ // custom: will callback jit to generate custom code
90
+ // block_boundary: may change eip in a way not handled by the jit
91
+ // no_next_instruction: jit will stop analysing after instruction (e.g., unconditional jump, ret)
92
+ const encodings: X86Encoding[] = [
93
+ { opcode: 0x06, os: 1, custom: 1 },
94
+ { opcode: 0x07, os: 1, skip: 1, block_boundary: 1 }, // pop es: block_boundary since it uses non-raising cpu exceptions
95
+ { opcode: 0x0e, os: 1, custom: 1 },
96
+ { opcode: 0x0f, os: 1, prefix: 1 },
97
+ { opcode: 0x16, os: 1, custom: 1 },
98
+ { opcode: 0x17, block_boundary: 1, os: 1, skip: 1 }, // pop ss
99
+ { opcode: 0x1e, os: 1, custom: 1 },
100
+ { opcode: 0x1f, block_boundary: 1, os: 1, skip: 1 }, // pop ds
101
+ { opcode: 0x26, prefix: 1 },
102
+ { opcode: 0x27, mask_flags: of },
103
+ { opcode: 0x2e, prefix: 1 },
104
+ { opcode: 0x2f, mask_flags: of },
105
+ { opcode: 0x36, prefix: 1 },
106
+ { opcode: 0x37, mask_flags: of | sf | pf | zf },
107
+ { opcode: 0x3e, prefix: 1 },
108
+ { opcode: 0x3f, mask_flags: of | sf | pf | zf },
109
+
110
+ { opcode: 0x60, os: 1, block_boundary: 1 }, // pusha
111
+ { opcode: 0x61, os: 1, block_boundary: 1 }, // popa
112
+ { opcode: 0x62, e: 1, skip: 1 },
113
+ { opcode: 0x63, e: 1, block_boundary: 1 }, // arpl
114
+ { opcode: 0x64, prefix: 1 },
115
+ { opcode: 0x65, prefix: 1 },
116
+ { opcode: 0x66, prefix: 1 },
117
+ { opcode: 0x67, prefix: 1 },
118
+
119
+ { opcode: 0x68, custom: 1, os: 1, imm1632: 1 },
120
+ {
121
+ opcode: 0x69,
122
+ os: 1,
123
+ e: 1,
124
+ custom: 1,
125
+ imm1632: 1,
126
+ mask_flags: TESTS_ASSUME_INTEL ? af : sf | zf | af | pf,
127
+ },
128
+ { opcode: 0x6a, custom: 1, os: 1, imm8s: 1 },
129
+ {
130
+ opcode: 0x6b,
131
+ os: 1,
132
+ e: 1,
133
+ custom: 1,
134
+ imm8s: 1,
135
+ mask_flags: TESTS_ASSUME_INTEL ? af : sf | zf | af | pf,
136
+ },
137
+
138
+ { opcode: 0x6c, block_boundary: 1, custom: 1, is_string: 1, skip: 1 }, // ins
139
+ { opcode: 0xf26c, block_boundary: 1, custom: 1, is_string: 1, skip: 1 },
140
+ { opcode: 0xf36c, block_boundary: 1, custom: 1, is_string: 1, skip: 1 },
141
+ {
142
+ opcode: 0x6d,
143
+ block_boundary: 1,
144
+ custom: 1,
145
+ is_string: 1,
146
+ os: 1,
147
+ skip: 1,
148
+ },
149
+ {
150
+ opcode: 0xf26d,
151
+ block_boundary: 1,
152
+ custom: 1,
153
+ is_string: 1,
154
+ os: 1,
155
+ skip: 1,
156
+ },
157
+ {
158
+ opcode: 0xf36d,
159
+ block_boundary: 1,
160
+ custom: 1,
161
+ is_string: 1,
162
+ os: 1,
163
+ skip: 1,
164
+ },
165
+
166
+ { opcode: 0x6e, block_boundary: 1, custom: 1, is_string: 1, skip: 1 }, // outs
167
+ { opcode: 0xf26e, block_boundary: 1, custom: 1, is_string: 1, skip: 1 },
168
+ { opcode: 0xf36e, block_boundary: 1, custom: 1, is_string: 1, skip: 1 },
169
+ {
170
+ opcode: 0x6f,
171
+ block_boundary: 1,
172
+ custom: 1,
173
+ is_string: 1,
174
+ os: 1,
175
+ skip: 1,
176
+ },
177
+ {
178
+ opcode: 0xf26f,
179
+ block_boundary: 1,
180
+ custom: 1,
181
+ is_string: 1,
182
+ os: 1,
183
+ skip: 1,
184
+ },
185
+ {
186
+ opcode: 0xf36f,
187
+ block_boundary: 1,
188
+ custom: 1,
189
+ is_string: 1,
190
+ os: 1,
191
+ skip: 1,
192
+ },
193
+
194
+ { opcode: 0x84, custom: 1, e: 1 },
195
+ { opcode: 0x85, custom: 1, e: 1, os: 1 },
196
+ { opcode: 0x86, custom: 1, e: 1 },
197
+ { opcode: 0x87, custom: 1, os: 1, e: 1 },
198
+ { opcode: 0x88, custom: 1, e: 1 },
199
+ { opcode: 0x89, custom: 1, os: 1, e: 1 },
200
+ { opcode: 0x8a, custom: 1, e: 1 },
201
+ { opcode: 0x8b, custom: 1, os: 1, e: 1 },
202
+
203
+ { opcode: 0x8c, os: 1, e: 1, custom: 1, skip: 1 }, // mov reg, sreg
204
+ {
205
+ opcode: 0x8d,
206
+ reg_ud: 1,
207
+ os: 1,
208
+ e: 1,
209
+ custom_modrm_resolve: 1,
210
+ custom: 1,
211
+ }, // lea
212
+ { opcode: 0x8e, block_boundary: 1, e: 1, skip: 1 }, // mov sreg
213
+ {
214
+ opcode: 0x8f,
215
+ os: 1,
216
+ e: 1,
217
+ fixed_g: 0,
218
+ custom_modrm_resolve: 1,
219
+ custom: 1,
220
+ block_boundary: 1,
221
+ }, // pop r/m
222
+
223
+ { opcode: 0x90, custom: 1 },
224
+ { opcode: 0x91, custom: 1, os: 1 },
225
+ { opcode: 0x92, custom: 1, os: 1 },
226
+ { opcode: 0x93, custom: 1, os: 1 },
227
+ { opcode: 0x94, custom: 1, os: 1 },
228
+ { opcode: 0x95, custom: 1, os: 1 },
229
+ { opcode: 0x96, custom: 1, os: 1 },
230
+ { opcode: 0x97, custom: 1, os: 1 },
231
+
232
+ { opcode: 0x98, os: 1, custom: 1 },
233
+ { opcode: 0x99, os: 1, custom: 1 },
234
+ {
235
+ opcode: 0x9a,
236
+ os: 1,
237
+ imm1632: 1,
238
+ extra_imm16: 1,
239
+ skip: 1,
240
+ block_boundary: 1,
241
+ }, // callf
242
+ { opcode: 0x9b, block_boundary: 1, skip: 1 }, // fwait: block_boundary since it uses non-raising cpu exceptions
243
+ { opcode: 0x9c, os: 1, custom: 1, skip: 1 }, // pushf
244
+ { opcode: 0x9d, os: 1, custom: 1, skip: 1 }, // popf
245
+ { opcode: 0x9e, custom: 1 },
246
+ { opcode: 0x9f, custom: 1 },
247
+
248
+ { opcode: 0xa0, custom: 1, immaddr: 1 },
249
+ { opcode: 0xa1, custom: 1, os: 1, immaddr: 1 },
250
+ { opcode: 0xa2, custom: 1, immaddr: 1 },
251
+ { opcode: 0xa3, custom: 1, os: 1, immaddr: 1 },
252
+
253
+ // string instructions aren't jumps, but they modify eip due to how they're implemented
254
+ { opcode: 0xa4, block_boundary: 0, custom: 1, is_string: 1 },
255
+ { opcode: 0xf2a4, block_boundary: 1, custom: 1, is_string: 1 },
256
+ { opcode: 0xf3a4, block_boundary: 1, custom: 1, is_string: 1 },
257
+ { opcode: 0xa5, block_boundary: 0, custom: 1, is_string: 1, os: 1 },
258
+ { opcode: 0xf2a5, block_boundary: 1, custom: 1, is_string: 1, os: 1 },
259
+ { opcode: 0xf3a5, block_boundary: 1, custom: 1, is_string: 1, os: 1 },
260
+
261
+ { opcode: 0xa6, block_boundary: 1, custom: 1, is_string: 1 },
262
+ { opcode: 0xf2a6, block_boundary: 1, custom: 1, is_string: 1 },
263
+ { opcode: 0xf3a6, block_boundary: 1, custom: 1, is_string: 1 },
264
+ { opcode: 0xa7, block_boundary: 1, custom: 1, is_string: 1, os: 1 },
265
+ { opcode: 0xf2a7, block_boundary: 1, custom: 1, is_string: 1, os: 1 },
266
+ { opcode: 0xf3a7, block_boundary: 1, custom: 1, is_string: 1, os: 1 },
267
+
268
+ { opcode: 0xa8, custom: 1, imm8: 1 },
269
+ { opcode: 0xa9, custom: 1, os: 1, imm1632: 1 },
270
+
271
+ { opcode: 0xaa, block_boundary: 0, custom: 1, is_string: 1 },
272
+ { opcode: 0xf2aa, block_boundary: 1, custom: 1, is_string: 1 },
273
+ { opcode: 0xf3aa, block_boundary: 1, custom: 1, is_string: 1 },
274
+ { opcode: 0xab, block_boundary: 0, custom: 1, is_string: 1, os: 1 },
275
+ { opcode: 0xf2ab, block_boundary: 1, custom: 1, is_string: 1, os: 1 },
276
+ { opcode: 0xf3ab, block_boundary: 1, custom: 1, is_string: 1, os: 1 },
277
+
278
+ { opcode: 0xac, block_boundary: 0, custom: 1, is_string: 1 },
279
+ { opcode: 0xf2ac, block_boundary: 1, custom: 1, is_string: 1 },
280
+ { opcode: 0xf3ac, block_boundary: 1, custom: 1, is_string: 1 },
281
+ { opcode: 0xad, block_boundary: 0, custom: 1, is_string: 1, os: 1 },
282
+ { opcode: 0xf2ad, block_boundary: 1, custom: 1, is_string: 1, os: 1 },
283
+ { opcode: 0xf3ad, block_boundary: 1, custom: 1, is_string: 1, os: 1 },
284
+
285
+ { opcode: 0xae, block_boundary: 0, custom: 1, is_string: 1 },
286
+ { opcode: 0xf2ae, block_boundary: 1, custom: 1, is_string: 1 },
287
+ { opcode: 0xf3ae, block_boundary: 1, custom: 1, is_string: 1 },
288
+ { opcode: 0xaf, block_boundary: 0, custom: 1, is_string: 1, os: 1 },
289
+ { opcode: 0xf2af, block_boundary: 1, custom: 1, is_string: 1, os: 1 },
290
+ { opcode: 0xf3af, block_boundary: 1, custom: 1, is_string: 1, os: 1 },
291
+
292
+ {
293
+ opcode: 0xc2,
294
+ custom: 1,
295
+ block_boundary: 1,
296
+ no_next_instruction: 1,
297
+ os: 1,
298
+ absolute_jump: 1,
299
+ imm16: 1,
300
+ skip: 1,
301
+ }, // ret
302
+ {
303
+ opcode: 0xc3,
304
+ custom: 1,
305
+ block_boundary: 1,
306
+ no_next_instruction: 1,
307
+ os: 1,
308
+ absolute_jump: 1,
309
+ skip: 1,
310
+ },
311
+
312
+ { opcode: 0xc4, block_boundary: 1, os: 1, e: 1, skip: 1 }, // les
313
+ { opcode: 0xc5, block_boundary: 1, os: 1, e: 1, skip: 1 }, // lds
314
+
315
+ { opcode: 0xc6, custom: 1, e: 1, fixed_g: 0, imm8: 1 },
316
+ { opcode: 0xc7, custom: 1, os: 1, e: 1, fixed_g: 0, imm1632: 1 },
317
+
318
+ // XXX: Temporary block boundary
319
+ { opcode: 0xc8, os: 1, imm16: 1, extra_imm8: 1, block_boundary: 1 }, // enter
320
+ { opcode: 0xc9, custom: 1, os: 1, skip: 1 }, // leave
321
+
322
+ {
323
+ opcode: 0xca,
324
+ block_boundary: 1,
325
+ no_next_instruction: 1,
326
+ os: 1,
327
+ imm16: 1,
328
+ skip: 1,
329
+ }, // retf
330
+ { opcode: 0xcb, block_boundary: 1, no_next_instruction: 1, os: 1, skip: 1 },
331
+ { opcode: 0xcc, block_boundary: 1, skip: 1 }, // int
332
+ { opcode: 0xcd, block_boundary: 1, skip: 1, imm8: 1 },
333
+ { opcode: 0xce, block_boundary: 1, skip: 1 },
334
+ { opcode: 0xcf, block_boundary: 1, no_next_instruction: 1, os: 1, skip: 1 }, // iret
335
+
336
+ { opcode: 0xd4, imm8: 1, block_boundary: 1 }, // aam, may trigger #de
337
+ { opcode: 0xd5, imm8: 1, mask_flags: of | cf | af },
338
+ { opcode: 0xd6 },
339
+
340
+ { opcode: 0xd7, skip: 1, custom: 1 },
341
+
342
+ {
343
+ opcode: 0xd8,
344
+ e: 1,
345
+ fixed_g: 0,
346
+ custom: 1,
347
+ is_fpu: 1,
348
+ task_switch_test: 1,
349
+ },
350
+ {
351
+ opcode: 0xd8,
352
+ e: 1,
353
+ fixed_g: 1,
354
+ custom: 1,
355
+ is_fpu: 1,
356
+ task_switch_test: 1,
357
+ },
358
+ {
359
+ opcode: 0xd8,
360
+ e: 1,
361
+ fixed_g: 2,
362
+ custom: 1,
363
+ is_fpu: 1,
364
+ task_switch_test: 1,
365
+ },
366
+ {
367
+ opcode: 0xd8,
368
+ e: 1,
369
+ fixed_g: 3,
370
+ custom: 1,
371
+ is_fpu: 1,
372
+ task_switch_test: 1,
373
+ },
374
+ {
375
+ opcode: 0xd8,
376
+ e: 1,
377
+ fixed_g: 4,
378
+ custom: 1,
379
+ is_fpu: 1,
380
+ task_switch_test: 1,
381
+ },
382
+ {
383
+ opcode: 0xd8,
384
+ e: 1,
385
+ fixed_g: 5,
386
+ custom: 1,
387
+ is_fpu: 1,
388
+ task_switch_test: 1,
389
+ },
390
+ {
391
+ opcode: 0xd8,
392
+ e: 1,
393
+ fixed_g: 6,
394
+ custom: 1,
395
+ is_fpu: 1,
396
+ task_switch_test: 1,
397
+ },
398
+ {
399
+ opcode: 0xd8,
400
+ e: 1,
401
+ fixed_g: 7,
402
+ custom: 1,
403
+ is_fpu: 1,
404
+ task_switch_test: 1,
405
+ },
406
+
407
+ {
408
+ opcode: 0xd9,
409
+ e: 1,
410
+ fixed_g: 0,
411
+ custom: 1,
412
+ is_fpu: 1,
413
+ task_switch_test: 1,
414
+ os: 1,
415
+ },
416
+ {
417
+ opcode: 0xd9,
418
+ e: 1,
419
+ fixed_g: 1,
420
+ custom: 1,
421
+ is_fpu: 1,
422
+ task_switch_test: 1,
423
+ os: 1,
424
+ },
425
+ {
426
+ opcode: 0xd9,
427
+ e: 1,
428
+ fixed_g: 2,
429
+ custom: 1,
430
+ is_fpu: 1,
431
+ task_switch_test: 1,
432
+ os: 1,
433
+ },
434
+ {
435
+ opcode: 0xd9,
436
+ e: 1,
437
+ fixed_g: 3,
438
+ custom: 1,
439
+ is_fpu: 1,
440
+ task_switch_test: 1,
441
+ os: 1,
442
+ },
443
+ {
444
+ opcode: 0xd9,
445
+ e: 1,
446
+ fixed_g: 4,
447
+ custom: 1,
448
+ is_fpu: 1,
449
+ task_switch_test: 1,
450
+ os: 1,
451
+ skip_mem: 1,
452
+ }, // fldenv (mem)
453
+ {
454
+ opcode: 0xd9,
455
+ e: 1,
456
+ fixed_g: 5,
457
+ custom: 1,
458
+ is_fpu: 1,
459
+ task_switch_test: 1,
460
+ os: 1,
461
+ },
462
+ {
463
+ opcode: 0xd9,
464
+ e: 1,
465
+ fixed_g: 6,
466
+ custom: 1,
467
+ is_fpu: 1,
468
+ task_switch_test: 1,
469
+ os: 1,
470
+ skip: 1,
471
+ }, // fstenv (mem), fprem (reg)
472
+ {
473
+ opcode: 0xd9,
474
+ e: 1,
475
+ fixed_g: 7,
476
+ custom: 1,
477
+ is_fpu: 1,
478
+ task_switch_test: 1,
479
+ os: 1,
480
+ skip_reg: 1,
481
+ }, // fprem, fyl2xp1 (precision issues)
482
+
483
+ {
484
+ opcode: 0xda,
485
+ e: 1,
486
+ fixed_g: 0,
487
+ custom: 1,
488
+ is_fpu: 1,
489
+ task_switch_test: 1,
490
+ },
491
+ {
492
+ opcode: 0xda,
493
+ e: 1,
494
+ fixed_g: 1,
495
+ custom: 1,
496
+ is_fpu: 1,
497
+ task_switch_test: 1,
498
+ },
499
+ {
500
+ opcode: 0xda,
501
+ e: 1,
502
+ fixed_g: 2,
503
+ custom: 1,
504
+ is_fpu: 1,
505
+ task_switch_test: 1,
506
+ },
507
+ {
508
+ opcode: 0xda,
509
+ e: 1,
510
+ fixed_g: 3,
511
+ custom: 1,
512
+ is_fpu: 1,
513
+ task_switch_test: 1,
514
+ },
515
+ {
516
+ opcode: 0xda,
517
+ e: 1,
518
+ fixed_g: 4,
519
+ custom: 1,
520
+ is_fpu: 1,
521
+ task_switch_test: 1,
522
+ },
523
+ {
524
+ opcode: 0xda,
525
+ e: 1,
526
+ fixed_g: 5,
527
+ custom: 1,
528
+ is_fpu: 1,
529
+ task_switch_test: 1,
530
+ },
531
+ {
532
+ opcode: 0xda,
533
+ e: 1,
534
+ fixed_g: 6,
535
+ custom: 1,
536
+ is_fpu: 1,
537
+ task_switch_test: 1,
538
+ },
539
+ {
540
+ opcode: 0xda,
541
+ e: 1,
542
+ fixed_g: 7,
543
+ custom: 1,
544
+ is_fpu: 1,
545
+ task_switch_test: 1,
546
+ },
547
+
548
+ {
549
+ opcode: 0xdb,
550
+ e: 1,
551
+ fixed_g: 0,
552
+ custom: 1,
553
+ is_fpu: 1,
554
+ task_switch_test: 1,
555
+ },
556
+ {
557
+ opcode: 0xdb,
558
+ e: 1,
559
+ fixed_g: 1,
560
+ custom: 1,
561
+ is_fpu: 1,
562
+ task_switch_test: 1,
563
+ }, // fisttp (sse3)
564
+ {
565
+ opcode: 0xdb,
566
+ e: 1,
567
+ fixed_g: 2,
568
+ custom: 1,
569
+ is_fpu: 1,
570
+ task_switch_test: 1,
571
+ },
572
+ {
573
+ opcode: 0xdb,
574
+ e: 1,
575
+ fixed_g: 3,
576
+ custom: 1,
577
+ is_fpu: 1,
578
+ task_switch_test: 1,
579
+ },
580
+ {
581
+ opcode: 0xdb,
582
+ e: 1,
583
+ fixed_g: 4,
584
+ custom: 0,
585
+ is_fpu: 1,
586
+ task_switch_test: 1,
587
+ },
588
+ {
589
+ opcode: 0xdb,
590
+ e: 1,
591
+ fixed_g: 5,
592
+ custom: 1,
593
+ is_fpu: 1,
594
+ task_switch_test: 1,
595
+ },
596
+ {
597
+ opcode: 0xdb,
598
+ e: 1,
599
+ fixed_g: 6,
600
+ custom: 1,
601
+ is_fpu: 1,
602
+ task_switch_test: 1,
603
+ },
604
+ {
605
+ opcode: 0xdb,
606
+ e: 1,
607
+ fixed_g: 7,
608
+ custom: 0,
609
+ is_fpu: 1,
610
+ task_switch_test: 1,
611
+ },
612
+
613
+ {
614
+ opcode: 0xdc,
615
+ e: 1,
616
+ fixed_g: 0,
617
+ custom: 1,
618
+ is_fpu: 1,
619
+ task_switch_test: 1,
620
+ },
621
+ {
622
+ opcode: 0xdc,
623
+ e: 1,
624
+ fixed_g: 1,
625
+ custom: 1,
626
+ is_fpu: 1,
627
+ task_switch_test: 1,
628
+ },
629
+ {
630
+ opcode: 0xdc,
631
+ e: 1,
632
+ fixed_g: 2,
633
+ custom: 1,
634
+ is_fpu: 1,
635
+ task_switch_test: 1,
636
+ },
637
+ {
638
+ opcode: 0xdc,
639
+ e: 1,
640
+ fixed_g: 3,
641
+ custom: 1,
642
+ is_fpu: 1,
643
+ task_switch_test: 1,
644
+ },
645
+ {
646
+ opcode: 0xdc,
647
+ e: 1,
648
+ fixed_g: 4,
649
+ custom: 1,
650
+ is_fpu: 1,
651
+ task_switch_test: 1,
652
+ },
653
+ {
654
+ opcode: 0xdc,
655
+ e: 1,
656
+ fixed_g: 5,
657
+ custom: 1,
658
+ is_fpu: 1,
659
+ task_switch_test: 1,
660
+ },
661
+ {
662
+ opcode: 0xdc,
663
+ e: 1,
664
+ fixed_g: 6,
665
+ custom: 1,
666
+ is_fpu: 1,
667
+ task_switch_test: 1,
668
+ },
669
+ {
670
+ opcode: 0xdc,
671
+ e: 1,
672
+ fixed_g: 7,
673
+ custom: 1,
674
+ is_fpu: 1,
675
+ task_switch_test: 1,
676
+ },
677
+
678
+ {
679
+ opcode: 0xdd,
680
+ e: 1,
681
+ fixed_g: 0,
682
+ custom: 1,
683
+ is_fpu: 1,
684
+ task_switch_test: 1,
685
+ os: 1,
686
+ },
687
+ {
688
+ opcode: 0xdd,
689
+ e: 1,
690
+ fixed_g: 1,
691
+ custom: 1,
692
+ is_fpu: 1,
693
+ task_switch_test: 1,
694
+ os: 1,
695
+ }, // fisttp (sse3)
696
+ {
697
+ opcode: 0xdd,
698
+ e: 1,
699
+ fixed_g: 2,
700
+ custom: 1,
701
+ is_fpu: 1,
702
+ task_switch_test: 1,
703
+ os: 1,
704
+ },
705
+ {
706
+ opcode: 0xdd,
707
+ e: 1,
708
+ fixed_g: 3,
709
+ custom: 1,
710
+ is_fpu: 1,
711
+ task_switch_test: 1,
712
+ os: 1,
713
+ },
714
+ {
715
+ opcode: 0xdd,
716
+ e: 1,
717
+ fixed_g: 4,
718
+ custom: 0,
719
+ is_fpu: 1,
720
+ task_switch_test: 1,
721
+ os: 1,
722
+ skip_mem: 1,
723
+ }, // frstor
724
+ {
725
+ opcode: 0xdd,
726
+ e: 1,
727
+ fixed_g: 5,
728
+ custom: 1,
729
+ is_fpu: 1,
730
+ task_switch_test: 1,
731
+ os: 1,
732
+ },
733
+ {
734
+ opcode: 0xdd,
735
+ e: 1,
736
+ fixed_g: 6,
737
+ custom: 0,
738
+ is_fpu: 1,
739
+ task_switch_test: 1,
740
+ os: 1,
741
+ skip_mem: 1,
742
+ }, // fsave
743
+ {
744
+ opcode: 0xdd,
745
+ e: 1,
746
+ fixed_g: 7,
747
+ custom: 0,
748
+ is_fpu: 1,
749
+ task_switch_test: 1,
750
+ os: 1,
751
+ skip_mem: 1,
752
+ }, // fstsw (denormal flag)
753
+
754
+ {
755
+ opcode: 0xde,
756
+ e: 1,
757
+ fixed_g: 0,
758
+ custom: 1,
759
+ is_fpu: 1,
760
+ task_switch_test: 1,
761
+ },
762
+ {
763
+ opcode: 0xde,
764
+ e: 1,
765
+ fixed_g: 1,
766
+ custom: 1,
767
+ is_fpu: 1,
768
+ task_switch_test: 1,
769
+ },
770
+ {
771
+ opcode: 0xde,
772
+ e: 1,
773
+ fixed_g: 2,
774
+ custom: 1,
775
+ is_fpu: 1,
776
+ task_switch_test: 1,
777
+ },
778
+ {
779
+ opcode: 0xde,
780
+ e: 1,
781
+ fixed_g: 3,
782
+ custom: 1,
783
+ is_fpu: 1,
784
+ task_switch_test: 1,
785
+ },
786
+ {
787
+ opcode: 0xde,
788
+ e: 1,
789
+ fixed_g: 4,
790
+ custom: 1,
791
+ is_fpu: 1,
792
+ task_switch_test: 1,
793
+ },
794
+ {
795
+ opcode: 0xde,
796
+ e: 1,
797
+ fixed_g: 5,
798
+ custom: 1,
799
+ is_fpu: 1,
800
+ task_switch_test: 1,
801
+ },
802
+ {
803
+ opcode: 0xde,
804
+ e: 1,
805
+ fixed_g: 6,
806
+ custom: 1,
807
+ is_fpu: 1,
808
+ task_switch_test: 1,
809
+ },
810
+ {
811
+ opcode: 0xde,
812
+ e: 1,
813
+ fixed_g: 7,
814
+ custom: 1,
815
+ is_fpu: 1,
816
+ task_switch_test: 1,
817
+ },
818
+
819
+ {
820
+ opcode: 0xdf,
821
+ e: 1,
822
+ fixed_g: 0,
823
+ custom: 0,
824
+ is_fpu: 1,
825
+ task_switch_test: 1,
826
+ },
827
+ {
828
+ opcode: 0xdf,
829
+ e: 1,
830
+ fixed_g: 1,
831
+ custom: 1,
832
+ is_fpu: 1,
833
+ task_switch_test: 1,
834
+ }, // fisttp (sse3)
835
+ {
836
+ opcode: 0xdf,
837
+ e: 1,
838
+ fixed_g: 2,
839
+ custom: 1,
840
+ is_fpu: 1,
841
+ task_switch_test: 1,
842
+ },
843
+ {
844
+ opcode: 0xdf,
845
+ e: 1,
846
+ fixed_g: 3,
847
+ custom: 1,
848
+ is_fpu: 1,
849
+ task_switch_test: 1,
850
+ },
851
+ {
852
+ opcode: 0xdf,
853
+ e: 1,
854
+ fixed_g: 4,
855
+ custom: 1,
856
+ is_fpu: 1,
857
+ task_switch_test: 1,
858
+ skip: 1,
859
+ }, // unimplemented: Binary Coded Decimals / fsts (denormal flag)
860
+ {
861
+ opcode: 0xdf,
862
+ e: 1,
863
+ fixed_g: 5,
864
+ custom: 1,
865
+ is_fpu: 1,
866
+ task_switch_test: 1,
867
+ },
868
+ {
869
+ opcode: 0xdf,
870
+ e: 1,
871
+ fixed_g: 6,
872
+ custom: 1,
873
+ is_fpu: 1,
874
+ task_switch_test: 1,
875
+ },
876
+ {
877
+ opcode: 0xdf,
878
+ e: 1,
879
+ fixed_g: 7,
880
+ custom: 1,
881
+ is_fpu: 1,
882
+ task_switch_test: 1,
883
+ },
884
+
885
+ // loop, jcxz, etc.
886
+ {
887
+ opcode: 0xe0,
888
+ os: 1,
889
+ imm8s: 1,
890
+ no_block_boundary_in_interpreted: 1,
891
+ skip: 1,
892
+ block_boundary: 1,
893
+ jump_offset_imm: 1,
894
+ custom: 1,
895
+ conditional_jump: 1,
896
+ },
897
+ {
898
+ opcode: 0xe1,
899
+ os: 1,
900
+ imm8s: 1,
901
+ no_block_boundary_in_interpreted: 1,
902
+ skip: 1,
903
+ block_boundary: 1,
904
+ jump_offset_imm: 1,
905
+ custom: 1,
906
+ conditional_jump: 1,
907
+ },
908
+ {
909
+ opcode: 0xe2,
910
+ os: 1,
911
+ imm8s: 1,
912
+ no_block_boundary_in_interpreted: 1,
913
+ skip: 1,
914
+ block_boundary: 1,
915
+ jump_offset_imm: 1,
916
+ custom: 1,
917
+ conditional_jump: 1,
918
+ },
919
+ {
920
+ opcode: 0xe3,
921
+ os: 1,
922
+ imm8s: 1,
923
+ no_block_boundary_in_interpreted: 1,
924
+ skip: 1,
925
+ block_boundary: 1,
926
+ jump_offset_imm: 1,
927
+ custom: 1,
928
+ conditional_jump: 1,
929
+ },
930
+
931
+ // port functions aren't jumps, but they may modify eip due to how they are implemented
932
+ { opcode: 0xe4, block_boundary: 1, imm8: 1, skip: 1 }, // in
933
+ { opcode: 0xe5, block_boundary: 1, os: 1, imm8: 1, skip: 1 },
934
+ { opcode: 0xe6, block_boundary: 1, imm8: 1, skip: 1 }, // out
935
+ { opcode: 0xe7, block_boundary: 1, os: 1, imm8: 1, skip: 1 },
936
+
937
+ {
938
+ opcode: 0xe8,
939
+ block_boundary: 1,
940
+ jump_offset_imm: 1,
941
+ os: 1,
942
+ imm1632: 1,
943
+ custom: 1,
944
+ skip: 1,
945
+ }, // call
946
+ {
947
+ opcode: 0xe9,
948
+ block_boundary: 1,
949
+ no_block_boundary_in_interpreted: 1,
950
+ jump_offset_imm: 1,
951
+ no_next_instruction: 1,
952
+ os: 1,
953
+ imm1632: 1,
954
+ custom: 1,
955
+ skip: 1,
956
+ },
957
+ {
958
+ opcode: 0xea,
959
+ block_boundary: 1,
960
+ no_next_instruction: 1,
961
+ os: 1,
962
+ imm1632: 1,
963
+ extra_imm16: 1,
964
+ skip: 1,
965
+ }, // jmpf
966
+ {
967
+ opcode: 0xeb,
968
+ block_boundary: 1,
969
+ no_block_boundary_in_interpreted: 1,
970
+ jump_offset_imm: 1,
971
+ no_next_instruction: 1,
972
+ os: 1,
973
+ imm8s: 1,
974
+ custom: 1,
975
+ skip: 1,
976
+ },
977
+
978
+ { opcode: 0xec, block_boundary: 1, skip: 1 }, // in
979
+ { opcode: 0xed, block_boundary: 1, os: 1, skip: 1 },
980
+ { opcode: 0xee, block_boundary: 1, skip: 1 }, // out
981
+ { opcode: 0xef, block_boundary: 1, os: 1, skip: 1 },
982
+
983
+ { opcode: 0xf0, prefix: 1 },
984
+ { opcode: 0xf1, skip: 1 },
985
+ { opcode: 0xf2, prefix: 1 },
986
+ { opcode: 0xf3, prefix: 1 },
987
+ { opcode: 0xf4, block_boundary: 1, no_next_instruction: 1, skip: 1 }, // hlt
988
+ { opcode: 0xf5 },
989
+
990
+ { opcode: 0xf6, e: 1, fixed_g: 0, imm8: 1, custom: 1 },
991
+ { opcode: 0xf6, e: 1, fixed_g: 1, imm8: 1, custom: 1 },
992
+ { opcode: 0xf6, e: 1, fixed_g: 2, custom: 1 },
993
+ { opcode: 0xf6, e: 1, fixed_g: 3, custom: 1 },
994
+ {
995
+ opcode: 0xf6,
996
+ e: 1,
997
+ fixed_g: 4,
998
+ mask_flags: TESTS_ASSUME_INTEL ? af | zf : sf | zf | af | pf,
999
+ },
1000
+ {
1001
+ opcode: 0xf6,
1002
+ e: 1,
1003
+ fixed_g: 5,
1004
+ mask_flags: TESTS_ASSUME_INTEL ? af | zf : sf | zf | af | pf,
1005
+ },
1006
+ // div/idiv: Not a block boundary, but doesn't use control flow exceptions
1007
+ {
1008
+ opcode: 0xf6,
1009
+ e: 1,
1010
+ fixed_g: 6,
1011
+ mask_flags: TESTS_ASSUME_INTEL ? 0 : sf | zf | af | pf,
1012
+ block_boundary: 1,
1013
+ },
1014
+ {
1015
+ opcode: 0xf6,
1016
+ e: 1,
1017
+ fixed_g: 7,
1018
+ mask_flags: TESTS_ASSUME_INTEL ? 0 : sf | zf | af | pf,
1019
+ block_boundary: 1,
1020
+ },
1021
+
1022
+ { opcode: 0xf7, os: 1, e: 1, fixed_g: 0, imm1632: 1, custom: 1 },
1023
+ { opcode: 0xf7, os: 1, e: 1, fixed_g: 1, imm1632: 1, custom: 1 },
1024
+ { opcode: 0xf7, os: 1, e: 1, fixed_g: 2, custom: 1 },
1025
+ { opcode: 0xf7, os: 1, e: 1, fixed_g: 3, custom: 1 },
1026
+ {
1027
+ opcode: 0xf7,
1028
+ os: 1,
1029
+ e: 1,
1030
+ fixed_g: 4,
1031
+ mask_flags: TESTS_ASSUME_INTEL ? af | zf : sf | zf | af | pf,
1032
+ custom: 1,
1033
+ },
1034
+ {
1035
+ opcode: 0xf7,
1036
+ os: 1,
1037
+ e: 1,
1038
+ fixed_g: 5,
1039
+ mask_flags: TESTS_ASSUME_INTEL ? af | zf : sf | zf | af | pf,
1040
+ custom: 1,
1041
+ },
1042
+ {
1043
+ opcode: 0xf7,
1044
+ os: 1,
1045
+ e: 1,
1046
+ fixed_g: 6,
1047
+ mask_flags: TESTS_ASSUME_INTEL ? 0 : sf | zf | af | pf,
1048
+ custom: 1,
1049
+ },
1050
+ {
1051
+ opcode: 0xf7,
1052
+ os: 1,
1053
+ e: 1,
1054
+ fixed_g: 7,
1055
+ mask_flags: TESTS_ASSUME_INTEL ? 0 : sf | zf | af | pf,
1056
+ custom: 1,
1057
+ },
1058
+
1059
+ { opcode: 0xf8, custom: 1 },
1060
+ { opcode: 0xf9, custom: 1 },
1061
+ { opcode: 0xfa, custom: 1, skip: 1 },
1062
+ // STI: Note: Has special handling in jit in order to call handle_irqs safely
1063
+ { opcode: 0xfb, custom: 1, custom_sti: 1, skip: 1 },
1064
+ { opcode: 0xfc, custom: 1 },
1065
+ { opcode: 0xfd, custom: 1 },
1066
+
1067
+ { opcode: 0xfe, e: 1, fixed_g: 0, custom: 1 },
1068
+ { opcode: 0xfe, e: 1, fixed_g: 1, custom: 1 },
1069
+ { opcode: 0xff, os: 1, e: 1, fixed_g: 0, custom: 1 },
1070
+ { opcode: 0xff, os: 1, e: 1, fixed_g: 1, custom: 1 },
1071
+ {
1072
+ opcode: 0xff,
1073
+ os: 1,
1074
+ e: 1,
1075
+ fixed_g: 2,
1076
+ custom: 1,
1077
+ block_boundary: 1,
1078
+ absolute_jump: 1,
1079
+ skip: 1,
1080
+ },
1081
+ { opcode: 0xff, os: 1, e: 1, fixed_g: 3, block_boundary: 1, skip: 1 },
1082
+ {
1083
+ opcode: 0xff,
1084
+ os: 1,
1085
+ e: 1,
1086
+ fixed_g: 4,
1087
+ custom: 1,
1088
+ block_boundary: 1,
1089
+ absolute_jump: 1,
1090
+ no_next_instruction: 1,
1091
+ skip: 1,
1092
+ },
1093
+ {
1094
+ opcode: 0xff,
1095
+ os: 1,
1096
+ e: 1,
1097
+ fixed_g: 5,
1098
+ block_boundary: 1,
1099
+ no_next_instruction: 1,
1100
+ skip: 1,
1101
+ },
1102
+ { opcode: 0xff, custom: 1, os: 1, e: 1, fixed_g: 6 },
1103
+
1104
+ { opcode: 0x0f00, fixed_g: 0, e: 1, skip: 1, block_boundary: 1, os: 1 }, // sldt, ...
1105
+ { opcode: 0x0f00, fixed_g: 1, e: 1, skip: 1, block_boundary: 1, os: 1 },
1106
+ { opcode: 0x0f00, fixed_g: 2, e: 1, skip: 1, block_boundary: 1, os: 1 },
1107
+ { opcode: 0x0f00, fixed_g: 3, e: 1, skip: 1, block_boundary: 1, os: 1 },
1108
+ { opcode: 0x0f00, fixed_g: 4, e: 1, skip: 1, block_boundary: 1, os: 1 },
1109
+ { opcode: 0x0f00, fixed_g: 5, e: 1, skip: 1, block_boundary: 1, os: 1 },
1110
+
1111
+ { opcode: 0x0f01, fixed_g: 0, e: 1, skip: 1, block_boundary: 1, os: 1 }, // sgdt, ...
1112
+ { opcode: 0x0f01, fixed_g: 1, e: 1, skip: 1, block_boundary: 1, os: 1 },
1113
+ { opcode: 0x0f01, fixed_g: 2, e: 1, skip: 1, block_boundary: 1, os: 1 },
1114
+ { opcode: 0x0f01, fixed_g: 3, e: 1, skip: 1, block_boundary: 1, os: 1 },
1115
+ { opcode: 0x0f01, fixed_g: 4, e: 1, skip: 1, block_boundary: 1, os: 1 },
1116
+ { opcode: 0x0f01, fixed_g: 6, e: 1, skip: 1, block_boundary: 1, os: 1 },
1117
+ { opcode: 0x0f01, fixed_g: 7, e: 1, skip: 1, block_boundary: 1, os: 1 },
1118
+
1119
+ { opcode: 0x0f02, os: 1, e: 1, skip: 1, block_boundary: 1 }, // lar
1120
+ { opcode: 0x0f03, os: 1, e: 1, skip: 1, block_boundary: 1 }, // lsl
1121
+ { opcode: 0x0f04, skip: 1, block_boundary: 1 },
1122
+ { opcode: 0x0f05, skip: 1, block_boundary: 1 },
1123
+ { opcode: 0x0f06, skip: 1, block_boundary: 1 }, // clts
1124
+ { opcode: 0x0f07, skip: 1, block_boundary: 1 },
1125
+ { opcode: 0x0f08, skip: 1, block_boundary: 1 },
1126
+ { opcode: 0x0f09, skip: 1, block_boundary: 1 }, // wbinvd
1127
+ { opcode: 0x0f0a, skip: 1, block_boundary: 1 },
1128
+ // ud2
1129
+ // Technically has a next instruction, but Linux uses this for assertions
1130
+ // and embeds the assertion message after this instruction, which is likely
1131
+ // the most common use case of ud2
1132
+ {
1133
+ opcode: 0x0f0b,
1134
+ skip: 1,
1135
+ block_boundary: 1,
1136
+ custom: 1,
1137
+ no_next_instruction: 1,
1138
+ },
1139
+ { opcode: 0x0f0c, skip: 1, block_boundary: 1 },
1140
+ { opcode: 0x0f0d, skip: 1, block_boundary: 1 },
1141
+ { opcode: 0x0f0e, skip: 1, block_boundary: 1 },
1142
+ { opcode: 0x0f0f, skip: 1, block_boundary: 1 },
1143
+
1144
+ { opcode: 0x0f18, e: 1, custom: 1 },
1145
+ { opcode: 0x0f19, custom: 1, e: 1 },
1146
+ { opcode: 0x0f1a, skip: 1, block_boundary: 1 },
1147
+ { opcode: 0x0f1b, skip: 1, block_boundary: 1 },
1148
+ { opcode: 0x0f1c, custom: 1, e: 1 },
1149
+ { opcode: 0x0f1d, custom: 1, e: 1 },
1150
+ { opcode: 0x0f1e, custom: 1, e: 1 },
1151
+ { opcode: 0x0f1f, custom: 1, e: 1 },
1152
+
1153
+ { opcode: 0x0f20, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1 }, // mov reg, creg
1154
+ { opcode: 0x0f21, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1 }, // mov reg, dreg
1155
+ { opcode: 0x0f22, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1 }, // mov creg, reg
1156
+ { opcode: 0x0f23, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1 }, // mov dreg, reg
1157
+ { opcode: 0x0f24, skip: 1, block_boundary: 1 },
1158
+ { opcode: 0x0f25, skip: 1, block_boundary: 1 },
1159
+ { opcode: 0x0f26, skip: 1, block_boundary: 1 },
1160
+ { opcode: 0x0f27, skip: 1, block_boundary: 1 },
1161
+
1162
+ { opcode: 0x0f30, skip: 1, block_boundary: 1 }, // wrmsr
1163
+ { opcode: 0x0f31, skip: 1, custom: 1 }, // rdtsc
1164
+ { opcode: 0x0f32, skip: 1, block_boundary: 1 }, // rdmsr
1165
+ { opcode: 0x0f33, skip: 1, block_boundary: 1 }, // rdpmc
1166
+ { opcode: 0x0f34, skip: 1, block_boundary: 1, no_next_instruction: 1 }, // sysenter
1167
+ { opcode: 0x0f35, skip: 1, block_boundary: 1, no_next_instruction: 1 }, // sysexit
1168
+
1169
+ { opcode: 0x0f36, skip: 1, block_boundary: 1 }, // ud
1170
+ { opcode: 0x0f37, skip: 1, block_boundary: 1 }, // getsec
1171
+
1172
+ // ssse3+
1173
+ { opcode: 0x0f38, skip: 1, block_boundary: 1 },
1174
+ { opcode: 0x0f39, skip: 1, block_boundary: 1 },
1175
+ { opcode: 0x0f3a, skip: 1, block_boundary: 1 },
1176
+ { opcode: 0x0f3b, skip: 1, block_boundary: 1 },
1177
+ { opcode: 0x0f3c, skip: 1, block_boundary: 1 },
1178
+ { opcode: 0x0f3d, skip: 1, block_boundary: 1 },
1179
+ { opcode: 0x0f3e, skip: 1, block_boundary: 1 },
1180
+ { opcode: 0x0f3f, skip: 1, block_boundary: 1 },
1181
+
1182
+ { opcode: 0x0fa0, os: 1, custom: 1 },
1183
+ { opcode: 0x0fa1, os: 1, block_boundary: 1, skip: 1 }, // pop fs: block_boundary since it uses non-raising cpu exceptions
1184
+
1185
+ { opcode: 0x0fa2, skip: 1 },
1186
+
1187
+ { opcode: 0x0fa8, os: 1, custom: 1 },
1188
+ { opcode: 0x0fa9, os: 1, block_boundary: 1, skip: 1 }, // pop gs
1189
+
1190
+ { opcode: 0x0fa3, os: 1, e: 1, custom: 1, skip_mem: 1 }, // bt (can also index memory, but not supported by test right now)
1191
+ { opcode: 0x0fab, os: 1, e: 1, custom: 1, skip_mem: 1 },
1192
+ { opcode: 0x0fb3, os: 1, e: 1, custom: 1, skip_mem: 1 },
1193
+ { opcode: 0x0fbb, os: 1, e: 1, custom: 1, skip_mem: 1 },
1194
+
1195
+ { opcode: 0x0fba, os: 1, e: 1, fixed_g: 4, imm8: 1, custom: 1 }, // bt
1196
+ { opcode: 0x0fba, os: 1, e: 1, fixed_g: 5, imm8: 1, custom: 1 },
1197
+ { opcode: 0x0fba, os: 1, e: 1, fixed_g: 6, imm8: 1, custom: 1 },
1198
+ { opcode: 0x0fba, os: 1, e: 1, fixed_g: 7, imm8: 1, custom: 1 },
1199
+
1200
+ {
1201
+ opcode: 0x0fbc,
1202
+ os: 1,
1203
+ e: 1,
1204
+ mask_flags: of | sf | af | pf | cf,
1205
+ custom: 1,
1206
+ }, // bsf
1207
+ {
1208
+ opcode: 0x0fbd,
1209
+ os: 1,
1210
+ e: 1,
1211
+ mask_flags: of | sf | af | pf | cf,
1212
+ custom: 1,
1213
+ },
1214
+
1215
+ // note: overflow flag only undefined if shift is > 1
1216
+ { opcode: 0x0fa4, os: 1, e: 1, custom: 1, imm8: 1, mask_flags: af | of }, // shld
1217
+ { opcode: 0x0fa5, os: 1, e: 1, custom: 1, mask_flags: af | of },
1218
+ { opcode: 0x0fac, os: 1, e: 1, custom: 1, imm8: 1, mask_flags: af | of },
1219
+ { opcode: 0x0fad, os: 1, e: 1, custom: 1, mask_flags: af | of },
1220
+
1221
+ { opcode: 0x0fa6, skip: 1, block_boundary: 1 }, // ud
1222
+ { opcode: 0x0fa7, skip: 1, block_boundary: 1 }, // ud
1223
+
1224
+ { opcode: 0x0faa, skip: 1 },
1225
+
1226
+ {
1227
+ opcode: 0x0fae,
1228
+ e: 1,
1229
+ fixed_g: 0,
1230
+ reg_ud: 1,
1231
+ task_switch_test: 1,
1232
+ skip: 1,
1233
+ block_boundary: 1,
1234
+ }, // fxsave
1235
+ {
1236
+ opcode: 0x0fae,
1237
+ e: 1,
1238
+ fixed_g: 1,
1239
+ reg_ud: 1,
1240
+ task_switch_test: 1,
1241
+ skip: 1,
1242
+ block_boundary: 1,
1243
+ }, // fxrstor
1244
+ {
1245
+ opcode: 0x0fae,
1246
+ e: 1,
1247
+ fixed_g: 2,
1248
+ reg_ud: 1,
1249
+ sse: 1,
1250
+ skip: 1,
1251
+ block_boundary: 1,
1252
+ }, // ldmxcsr
1253
+ {
1254
+ opcode: 0x0fae,
1255
+ e: 1,
1256
+ fixed_g: 3,
1257
+ reg_ud: 1,
1258
+ sse: 1,
1259
+ skip: 1,
1260
+ block_boundary: 1,
1261
+ }, // stmxcsr
1262
+
1263
+ { opcode: 0x0fae, e: 1, fixed_g: 4, reg_ud: 1, skip: 1, block_boundary: 1 }, // xsave (mem, not implemented)
1264
+ { opcode: 0x0fae, e: 1, fixed_g: 5, skip: 1, custom: 1 }, // lfence (reg, only 0), xrstor (mem, not implemented)
1265
+ { opcode: 0x0fae, e: 1, fixed_g: 6, skip: 1, block_boundary: 1 }, // mfence (reg, only 0), xsaveopt (mem, not implemented)
1266
+ { opcode: 0x0fae, e: 1, fixed_g: 7, skip: 1, block_boundary: 1 }, // sfence (reg, only 0), clflush (mem)
1267
+
1268
+ {
1269
+ opcode: 0x0faf,
1270
+ os: 1,
1271
+ e: 1,
1272
+ mask_flags: TESTS_ASSUME_INTEL ? af | zf : sf | zf | af | pf,
1273
+ custom: 1,
1274
+ }, // imul
1275
+
1276
+ { opcode: 0x0fb0, e: 1 }, // cmxchg
1277
+ { opcode: 0x0fb1, os: 1, e: 1, custom: 1 },
1278
+ { opcode: 0x0fc7, e: 1, fixed_g: 1, os: 1, reg_ud: 1, custom: 1 }, // cmpxchg8b (memory)
1279
+ { opcode: 0x0fc7, e: 1, fixed_g: 6, os: 1, mem_ud: 1, skip: 1 }, // rdrand
1280
+
1281
+ { opcode: 0x0fb2, block_boundary: 1, os: 1, e: 1, skip: 1 }, // lss
1282
+ { opcode: 0x0fb4, block_boundary: 1, os: 1, e: 1, skip: 1 }, // lfs
1283
+ { opcode: 0x0fb5, block_boundary: 1, os: 1, e: 1, skip: 1 }, // lgs
1284
+
1285
+ { opcode: 0x0fb6, os: 1, e: 1, custom: 1 }, // movzx
1286
+ { opcode: 0x0fb7, os: 1, e: 1, custom: 1 },
1287
+
1288
+ { opcode: 0xf30fb8, os: 1, e: 1, custom: 1 }, // popcnt
1289
+ { opcode: 0x0fb8, os: 1, e: 1, block_boundary: 1 }, // ud
1290
+
1291
+ { opcode: 0x0fb9, block_boundary: 1 }, // ud2
1292
+
1293
+ { opcode: 0x0fbe, os: 1, e: 1, custom: 1 }, // movsx
1294
+ { opcode: 0x0fbf, os: 1, e: 1, custom: 1 },
1295
+
1296
+ { opcode: 0x0fc0, e: 1 }, // xadd
1297
+ { opcode: 0x0fc1, os: 1, e: 1, custom: 1 },
1298
+
1299
+ { opcode: 0x0fc8, custom: 1 }, // bswap
1300
+ { opcode: 0x0fc9, custom: 1 },
1301
+ { opcode: 0x0fca, custom: 1 },
1302
+ { opcode: 0x0fcb, custom: 1 },
1303
+ { opcode: 0x0fcc, custom: 1 },
1304
+ { opcode: 0x0fcd, custom: 1 },
1305
+ { opcode: 0x0fce, custom: 1 },
1306
+ { opcode: 0x0fcf, custom: 1 },
1307
+
1308
+ // mmx, sse
1309
+
1310
+ { sse: 1, opcode: 0x0f10, e: 1, custom: 1 },
1311
+ { sse: 1, opcode: 0xf30f10, e: 1, custom: 1 },
1312
+ { sse: 1, opcode: 0x660f10, e: 1, custom: 1 },
1313
+ { sse: 1, opcode: 0xf20f10, e: 1, custom: 1 },
1314
+ { sse: 1, opcode: 0x0f11, e: 1, custom: 1 },
1315
+ { sse: 1, opcode: 0xf30f11, e: 1, custom: 1 },
1316
+ { sse: 1, opcode: 0x660f11, e: 1, custom: 1 },
1317
+ { sse: 1, opcode: 0xf20f11, e: 1, custom: 1 },
1318
+ { sse: 1, opcode: 0x0f12, e: 1, custom: 1 },
1319
+ { sse: 1, opcode: 0x660f12, reg_ud: 1, e: 1, custom: 1 },
1320
+ { sse: 1, opcode: 0xf20f12, e: 1, custom: 1 }, // sse3
1321
+ { sse: 1, opcode: 0xf30f12, e: 1, custom: 1 }, // sse3
1322
+ { sse: 1, opcode: 0x0f13, reg_ud: 1, e: 1, custom: 1 },
1323
+ { sse: 1, opcode: 0x660f13, reg_ud: 1, e: 1, custom: 1 },
1324
+ { sse: 1, opcode: 0x0f14, e: 1, custom: 1 },
1325
+ { sse: 1, opcode: 0x660f14, e: 1, custom: 1 },
1326
+ { sse: 1, opcode: 0x0f15, e: 1, custom: 1 },
1327
+ { sse: 1, opcode: 0x660f15, e: 1, custom: 1 },
1328
+ { sse: 1, opcode: 0x0f16, e: 1, custom: 1 },
1329
+ { sse: 1, opcode: 0x660f16, reg_ud: 1, e: 1, custom: 1 },
1330
+ { sse: 1, opcode: 0xf30f16, e: 1, custom: 1 }, // sse3
1331
+ { sse: 1, opcode: 0x0f17, reg_ud: 1, e: 1, custom: 1 },
1332
+ { sse: 1, opcode: 0x660f17, reg_ud: 1, e: 1, custom: 1 },
1333
+
1334
+ { sse: 1, opcode: 0x0f28, e: 1, custom: 1 },
1335
+ { sse: 1, opcode: 0x660f28, e: 1, custom: 1 },
1336
+ { sse: 1, opcode: 0x0f29, e: 1, custom: 1 },
1337
+ { sse: 1, opcode: 0x660f29, e: 1, custom: 1 },
1338
+ { sse: 1, opcode: 0x0f2a, e: 1, custom: 1 },
1339
+ { sse: 1, opcode: 0x660f2a, e: 1, custom: 1 },
1340
+ { sse: 1, opcode: 0xf20f2a, e: 1, custom: 1 },
1341
+ { sse: 1, opcode: 0xf30f2a, e: 1, custom: 1 },
1342
+ { sse: 1, opcode: 0x0f2b, reg_ud: 1, e: 1, custom: 1 },
1343
+ { sse: 1, opcode: 0x660f2b, reg_ud: 1, e: 1, custom: 1 },
1344
+
1345
+ { sse: 1, opcode: 0x0f2c, e: 1 },
1346
+ { sse: 1, opcode: 0x660f2c, e: 1 },
1347
+ { sse: 1, opcode: 0xf20f2c, e: 1, custom: 1 },
1348
+ { sse: 1, opcode: 0xf30f2c, e: 1, custom: 1 },
1349
+ { sse: 1, opcode: 0x0f2d, e: 1 },
1350
+ { sse: 1, opcode: 0x660f2d, e: 1 },
1351
+ { sse: 1, opcode: 0xf20f2d, e: 1, custom: 1 },
1352
+ { sse: 1, opcode: 0xf30f2d, e: 1, custom: 1 },
1353
+
1354
+ { sse: 1, opcode: 0x0f2e, e: 1, custom: 1 },
1355
+ { sse: 1, opcode: 0x660f2e, e: 1, custom: 1 },
1356
+ { sse: 1, opcode: 0x0f2f, e: 1, custom: 1 },
1357
+ { sse: 1, opcode: 0x660f2f, e: 1, custom: 1 },
1358
+
1359
+ { sse: 1, opcode: 0x0f50, mem_ud: 1, e: 1 },
1360
+ { sse: 1, opcode: 0x660f50, mem_ud: 1, e: 1 },
1361
+ { sse: 1, opcode: 0x0f51, e: 1, custom: 1 },
1362
+ { sse: 1, opcode: 0x660f51, e: 1, custom: 1 },
1363
+ { sse: 1, opcode: 0xf20f51, e: 1, custom: 1 },
1364
+ { sse: 1, opcode: 0xf30f51, e: 1, custom: 1 },
1365
+
1366
+ // approximation of 1/sqrt(x). Skipped because our approximation doesn't match intel's
1367
+ { sse: 1, opcode: 0x0f52, e: 1, skip: 1, custom: 1 },
1368
+ { sse: 1, opcode: 0xf30f52, e: 1, skip: 1, custom: 1 },
1369
+
1370
+ // reciprocal: approximation of 1/x. Skipped because our approximation doesn't match intel's
1371
+ { sse: 1, opcode: 0x0f53, e: 1, skip: 1, custom: 1 },
1372
+ { sse: 1, opcode: 0xf30f53, e: 1, skip: 1, custom: 1 },
1373
+
1374
+ { sse: 1, opcode: 0x0f54, e: 1, custom: 1 },
1375
+ { sse: 1, opcode: 0x660f54, e: 1, custom: 1 },
1376
+ { sse: 1, opcode: 0x0f55, e: 1, custom: 1 },
1377
+ { sse: 1, opcode: 0x660f55, e: 1, custom: 1 },
1378
+ { sse: 1, opcode: 0x0f56, e: 1, custom: 1 },
1379
+ { sse: 1, opcode: 0x660f56, e: 1, custom: 1 },
1380
+ { sse: 1, opcode: 0x0f57, e: 1, custom: 1 },
1381
+ { sse: 1, opcode: 0x660f57, e: 1, custom: 1 },
1382
+
1383
+ { sse: 1, opcode: 0x0f58, e: 1, custom: 1 },
1384
+ { sse: 1, opcode: 0x660f58, e: 1, custom: 1 },
1385
+ { sse: 1, opcode: 0xf20f58, e: 1, custom: 1 },
1386
+ { sse: 1, opcode: 0xf30f58, e: 1, custom: 1 },
1387
+ { sse: 1, opcode: 0x0f59, e: 1, custom: 1 },
1388
+ { sse: 1, opcode: 0x660f59, e: 1, custom: 1 },
1389
+ { sse: 1, opcode: 0xf20f59, e: 1, custom: 1 },
1390
+ { sse: 1, opcode: 0xf30f59, e: 1, custom: 1 },
1391
+
1392
+ { sse: 1, opcode: 0x0f5a, e: 1, custom: 1 },
1393
+ { sse: 1, opcode: 0x660f5a, e: 1, custom: 1 },
1394
+ { sse: 1, opcode: 0xf20f5a, e: 1, custom: 1 },
1395
+ { sse: 1, opcode: 0xf30f5a, e: 1, custom: 1 },
1396
+ { sse: 1, opcode: 0x0f5b, e: 1, custom: 1 },
1397
+ { sse: 1, opcode: 0x660f5b, e: 1, custom: 1 },
1398
+ // no F2 variant
1399
+ { sse: 1, opcode: 0xf30f5b, e: 1, custom: 1 },
1400
+
1401
+ { sse: 1, opcode: 0x0f5c, e: 1, custom: 1 },
1402
+ { sse: 1, opcode: 0x660f5c, e: 1, custom: 1 },
1403
+ { sse: 1, opcode: 0xf20f5c, e: 1, custom: 1 },
1404
+ { sse: 1, opcode: 0xf30f5c, e: 1, custom: 1 },
1405
+ { sse: 1, opcode: 0x0f5d, e: 1, custom: 1 },
1406
+ { sse: 1, opcode: 0x660f5d, e: 1, custom: 1 },
1407
+ { sse: 1, opcode: 0xf20f5d, e: 1, custom: 1 },
1408
+ { sse: 1, opcode: 0xf30f5d, e: 1, custom: 1 },
1409
+
1410
+ { sse: 1, opcode: 0x0f5e, e: 1, custom: 1 },
1411
+ { sse: 1, opcode: 0x660f5e, e: 1, custom: 1 },
1412
+ { sse: 1, opcode: 0xf20f5e, e: 1, custom: 1 },
1413
+ { sse: 1, opcode: 0xf30f5e, e: 1, custom: 1 },
1414
+ { sse: 1, opcode: 0x0f5f, e: 1, custom: 1 },
1415
+ { sse: 1, opcode: 0x660f5f, e: 1, custom: 1 },
1416
+ { sse: 1, opcode: 0xf20f5f, e: 1, custom: 1 },
1417
+ { sse: 1, opcode: 0xf30f5f, e: 1, custom: 1 },
1418
+
1419
+ { sse: 1, opcode: 0x660f60, e: 1, custom: 1 },
1420
+ { sse: 1, opcode: 0x0f60, e: 1, custom: 1 },
1421
+ { sse: 1, opcode: 0x660f61, e: 1, custom: 1 },
1422
+ { sse: 1, opcode: 0x0f61, e: 1, custom: 1 },
1423
+ { sse: 1, opcode: 0x660f62, e: 1, custom: 1 },
1424
+ { sse: 1, opcode: 0x0f62, e: 1, custom: 1 },
1425
+ { sse: 1, opcode: 0x660f63, e: 1, custom: 1 },
1426
+ { sse: 1, opcode: 0x0f63, e: 1, custom: 1 },
1427
+ { sse: 1, opcode: 0x660f64, e: 1, custom: 1 },
1428
+ { sse: 1, opcode: 0x0f64, e: 1, custom: 1 },
1429
+ { sse: 1, opcode: 0x660f65, e: 1, custom: 1 },
1430
+ { sse: 1, opcode: 0x0f65, e: 1, custom: 1 },
1431
+ { sse: 1, opcode: 0x660f66, e: 1, custom: 1 },
1432
+ { sse: 1, opcode: 0x0f66, e: 1, custom: 1 },
1433
+ { sse: 1, opcode: 0x660f67, e: 1, custom: 1 },
1434
+ { sse: 1, opcode: 0x0f67, e: 1, custom: 1 },
1435
+
1436
+ { sse: 1, opcode: 0x660f68, e: 1, custom: 1 },
1437
+ { sse: 1, opcode: 0x0f68, e: 1, custom: 1 },
1438
+ { sse: 1, opcode: 0x660f69, e: 1, custom: 1 },
1439
+ { sse: 1, opcode: 0x0f69, e: 1, custom: 1 },
1440
+ { sse: 1, opcode: 0x660f6a, e: 1, custom: 1 },
1441
+ { sse: 1, opcode: 0x0f6a, e: 1, custom: 1 },
1442
+ { sse: 1, opcode: 0x660f6b, e: 1, custom: 1 },
1443
+ { sse: 1, opcode: 0x0f6b, e: 1, custom: 1 },
1444
+ { sse: 1, opcode: 0x660f6c, e: 1, custom: 1 },
1445
+ { sse: 1, opcode: 0x0f6c, e: 1, block_boundary: 1 }, // ud
1446
+ { sse: 1, opcode: 0x660f6d, e: 1, custom: 1 },
1447
+ { sse: 1, opcode: 0x0f6d, e: 1, block_boundary: 1 }, // ud
1448
+ { sse: 1, opcode: 0x660f6e, e: 1, custom: 1 },
1449
+ { sse: 1, opcode: 0x0f6e, e: 1, custom: 1 },
1450
+ { sse: 1, opcode: 0xf30f6f, e: 1, custom: 1 },
1451
+ { sse: 1, opcode: 0x660f6f, e: 1, custom: 1 },
1452
+ { sse: 1, opcode: 0x0f6f, e: 1, custom: 1 },
1453
+
1454
+ { sse: 1, opcode: 0x0f70, e: 1, imm8: 1, custom: 1 },
1455
+ { sse: 1, opcode: 0x660f70, e: 1, imm8: 1, custom: 1 },
1456
+ { sse: 1, opcode: 0xf20f70, e: 1, imm8: 1, custom: 1 },
1457
+ { sse: 1, opcode: 0xf30f70, e: 1, imm8: 1, custom: 1 },
1458
+
1459
+ { sse: 1, opcode: 0x0f71, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, custom: 1 },
1460
+ {
1461
+ sse: 1,
1462
+ opcode: 0x660f71,
1463
+ e: 1,
1464
+ fixed_g: 2,
1465
+ imm8: 1,
1466
+ mem_ud: 1,
1467
+ custom: 1,
1468
+ },
1469
+ { sse: 1, opcode: 0x0f71, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1, custom: 1 },
1470
+ {
1471
+ sse: 1,
1472
+ opcode: 0x660f71,
1473
+ e: 1,
1474
+ fixed_g: 4,
1475
+ imm8: 1,
1476
+ mem_ud: 1,
1477
+ custom: 1,
1478
+ },
1479
+ { sse: 1, opcode: 0x0f71, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, custom: 1 },
1480
+ {
1481
+ sse: 1,
1482
+ opcode: 0x660f71,
1483
+ e: 1,
1484
+ fixed_g: 6,
1485
+ imm8: 1,
1486
+ mem_ud: 1,
1487
+ custom: 1,
1488
+ },
1489
+
1490
+ { sse: 1, opcode: 0x0f72, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, custom: 1 },
1491
+ {
1492
+ sse: 1,
1493
+ opcode: 0x660f72,
1494
+ e: 1,
1495
+ fixed_g: 2,
1496
+ imm8: 1,
1497
+ mem_ud: 1,
1498
+ custom: 1,
1499
+ },
1500
+ { sse: 1, opcode: 0x0f72, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1, custom: 1 },
1501
+ {
1502
+ sse: 1,
1503
+ opcode: 0x660f72,
1504
+ e: 1,
1505
+ fixed_g: 4,
1506
+ imm8: 1,
1507
+ mem_ud: 1,
1508
+ custom: 1,
1509
+ },
1510
+ { sse: 1, opcode: 0x0f72, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, custom: 1 },
1511
+ {
1512
+ sse: 1,
1513
+ opcode: 0x660f72,
1514
+ e: 1,
1515
+ fixed_g: 6,
1516
+ imm8: 1,
1517
+ mem_ud: 1,
1518
+ custom: 1,
1519
+ },
1520
+
1521
+ { sse: 1, opcode: 0x0f73, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, custom: 1 },
1522
+ {
1523
+ sse: 1,
1524
+ opcode: 0x660f73,
1525
+ e: 1,
1526
+ fixed_g: 2,
1527
+ imm8: 1,
1528
+ mem_ud: 1,
1529
+ custom: 1,
1530
+ },
1531
+ {
1532
+ sse: 1,
1533
+ opcode: 0x660f73,
1534
+ e: 1,
1535
+ fixed_g: 3,
1536
+ imm8: 1,
1537
+ mem_ud: 1,
1538
+ custom: 1,
1539
+ },
1540
+ { sse: 1, opcode: 0x0f73, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, custom: 1 },
1541
+ {
1542
+ sse: 1,
1543
+ opcode: 0x660f73,
1544
+ e: 1,
1545
+ fixed_g: 6,
1546
+ imm8: 1,
1547
+ mem_ud: 1,
1548
+ custom: 1,
1549
+ },
1550
+ {
1551
+ sse: 1,
1552
+ opcode: 0x660f73,
1553
+ e: 1,
1554
+ fixed_g: 7,
1555
+ imm8: 1,
1556
+ mem_ud: 1,
1557
+ custom: 1,
1558
+ },
1559
+
1560
+ { sse: 1, opcode: 0x0f74, e: 1, custom: 1 },
1561
+ { sse: 1, opcode: 0x660f74, e: 1, custom: 1 },
1562
+ { sse: 1, opcode: 0x0f75, e: 1, custom: 1 },
1563
+ { sse: 1, opcode: 0x660f75, e: 1, custom: 1 },
1564
+ { sse: 1, opcode: 0x0f76, e: 1, custom: 1 },
1565
+ { sse: 1, opcode: 0x660f76, e: 1, custom: 1 },
1566
+ { sse: 1, opcode: 0x0f77, skip: 1 }, // emms (skip as it breaks gdb printing of float registers)
1567
+
1568
+ // vmx instructions
1569
+ { opcode: 0x0f78, skip: 1, block_boundary: 1 },
1570
+ { opcode: 0x0f79, skip: 1, block_boundary: 1 },
1571
+
1572
+ { opcode: 0x0f7a, skip: 1, block_boundary: 1 }, // ud
1573
+ { opcode: 0x0f7b, skip: 1, block_boundary: 1 }, // ud
1574
+
1575
+ { sse: 1, opcode: 0x660f7c, e: 1, custom: 1 }, // sse3
1576
+ { sse: 1, opcode: 0xf20f7c, e: 1, custom: 1 }, // sse3
1577
+ { sse: 1, opcode: 0x660f7d, e: 1, custom: 1 }, // sse3
1578
+ { sse: 1, opcode: 0xf20f7d, e: 1, custom: 1 }, // sse3
1579
+
1580
+ { opcode: 0x0f7c, skip: 1, block_boundary: 1 }, // ud
1581
+ { opcode: 0x0f7d, skip: 1, block_boundary: 1 }, // ud
1582
+
1583
+ { sse: 1, opcode: 0x0f7e, e: 1, custom: 1 },
1584
+ { sse: 1, opcode: 0x660f7e, e: 1, custom: 1 },
1585
+ { sse: 1, opcode: 0xf30f7e, e: 1, custom: 1 },
1586
+ { sse: 1, opcode: 0x0f7f, e: 1, custom: 1 },
1587
+ { sse: 1, opcode: 0x660f7f, e: 1, custom: 1 },
1588
+ { sse: 1, opcode: 0xf30f7f, e: 1, custom: 1 },
1589
+
1590
+ { sse: 1, opcode: 0x0fc2, e: 1, imm8: 1, custom: 1 },
1591
+ { sse: 1, opcode: 0x660fc2, e: 1, imm8: 1, custom: 1 },
1592
+ { sse: 1, opcode: 0xf20fc2, e: 1, imm8: 1, custom: 1 },
1593
+ { sse: 1, opcode: 0xf30fc2, e: 1, imm8: 1, custom: 1 },
1594
+
1595
+ { opcode: 0x0fc3, e: 1, custom: 1, reg_ud: 1 }, // movnti: Uses normal registers, hence not marked as sse
1596
+
1597
+ { sse: 1, opcode: 0x0fc4, e: 1, imm8: 1, custom: 1 },
1598
+ { sse: 1, opcode: 0x660fc4, e: 1, imm8: 1, custom: 1 },
1599
+ { sse: 1, opcode: 0x0fc5, e: 1, mem_ud: 1, imm8: 1, custom: 1 },
1600
+ { sse: 1, opcode: 0x660fc5, e: 1, mem_ud: 1, imm8: 1, custom: 1 },
1601
+
1602
+ { sse: 1, opcode: 0x0fc6, e: 1, imm8: 1, custom: 1 },
1603
+ { sse: 1, opcode: 0x660fc6, e: 1, imm8: 1, custom: 1 },
1604
+
1605
+ { sse: 1, opcode: 0x0fd0, skip: 1, block_boundary: 1 }, // sse3
1606
+
1607
+ { sse: 1, opcode: 0x0fd1, e: 1, custom: 1 },
1608
+ { sse: 1, opcode: 0x660fd1, e: 1, custom: 1 },
1609
+ { sse: 1, opcode: 0x0fd2, e: 1, custom: 1 },
1610
+ { sse: 1, opcode: 0x660fd2, e: 1, custom: 1 },
1611
+ { sse: 1, opcode: 0x0fd3, e: 1, custom: 1 },
1612
+ { sse: 1, opcode: 0x660fd3, e: 1, custom: 1 },
1613
+ { sse: 1, opcode: 0x0fd4, e: 1, custom: 1 },
1614
+ { sse: 1, opcode: 0x660fd4, e: 1, custom: 1 },
1615
+ { sse: 1, opcode: 0x0fd5, e: 1, custom: 1 },
1616
+ { sse: 1, opcode: 0x660fd5, e: 1, custom: 1 },
1617
+
1618
+ { sse: 1, opcode: 0x660fd6, e: 1, custom: 1 },
1619
+ { sse: 1, opcode: 0xf20fd6, mem_ud: 1, e: 1 },
1620
+ { sse: 1, opcode: 0xf30fd6, mem_ud: 1, e: 1 },
1621
+ { sse: 1, opcode: 0x0fd6, e: 1, block_boundary: 1 }, // ud
1622
+
1623
+ { sse: 1, opcode: 0x0fd7, e: 1, mem_ud: 1, custom: 1 },
1624
+ { sse: 1, opcode: 0x660fd7, e: 1, mem_ud: 1, custom: 1 },
1625
+
1626
+ { sse: 1, opcode: 0x0fd8, e: 1, custom: 1 },
1627
+ { sse: 1, opcode: 0x660fd8, e: 1, custom: 1 },
1628
+ { sse: 1, opcode: 0x0fd9, e: 1, custom: 1 },
1629
+ { sse: 1, opcode: 0x660fd9, e: 1, custom: 1 },
1630
+ { sse: 1, opcode: 0x0fda, e: 1, custom: 1 },
1631
+ { sse: 1, opcode: 0x660fda, e: 1, custom: 1 },
1632
+ { sse: 1, opcode: 0x0fdb, e: 1, custom: 1 },
1633
+ { sse: 1, opcode: 0x660fdb, e: 1, custom: 1 },
1634
+ { sse: 1, opcode: 0x0fdc, e: 1, custom: 1 },
1635
+ { sse: 1, opcode: 0x660fdc, e: 1, custom: 1 },
1636
+ { sse: 1, opcode: 0x0fdd, e: 1, custom: 1 },
1637
+ { sse: 1, opcode: 0x660fdd, e: 1, custom: 1 },
1638
+ { sse: 1, opcode: 0x0fde, e: 1, custom: 1 },
1639
+ { sse: 1, opcode: 0x660fde, e: 1, custom: 1 },
1640
+ { sse: 1, opcode: 0x0fdf, e: 1, custom: 1 },
1641
+ { sse: 1, opcode: 0x660fdf, e: 1, custom: 1 },
1642
+
1643
+ { sse: 1, opcode: 0x0fe0, e: 1, custom: 1 },
1644
+ { sse: 1, opcode: 0x660fe0, e: 1, custom: 1 },
1645
+ { sse: 1, opcode: 0x0fe1, e: 1, custom: 1 },
1646
+ { sse: 1, opcode: 0x660fe1, e: 1, custom: 1 },
1647
+ { sse: 1, opcode: 0x0fe2, e: 1, custom: 1 },
1648
+ { sse: 1, opcode: 0x660fe2, e: 1, custom: 1 },
1649
+ { sse: 1, opcode: 0x0fe3, e: 1, custom: 1 },
1650
+ { sse: 1, opcode: 0x660fe3, e: 1, custom: 1 },
1651
+ { sse: 1, opcode: 0x0fe4, e: 1, custom: 1 },
1652
+ { sse: 1, opcode: 0x660fe4, e: 1, custom: 1 },
1653
+ { sse: 1, opcode: 0x0fe5, e: 1, custom: 1 },
1654
+ { sse: 1, opcode: 0x660fe5, e: 1, custom: 1 },
1655
+
1656
+ { sse: 1, opcode: 0x660fe6, e: 1, custom: 1 },
1657
+ { sse: 1, opcode: 0xf20fe6, e: 1, custom: 1 },
1658
+ { sse: 1, opcode: 0xf30fe6, e: 1, custom: 1 },
1659
+ { sse: 1, opcode: 0x0fe6, e: 1, block_boundary: 1 }, // ud
1660
+ { sse: 1, opcode: 0x0fe7, e: 1, reg_ud: 1 },
1661
+ { sse: 1, opcode: 0x660fe7, e: 1, reg_ud: 1, custom: 1 },
1662
+
1663
+ { sse: 1, opcode: 0x0fe8, e: 1, custom: 1 },
1664
+ { sse: 1, opcode: 0x660fe8, e: 1, custom: 1 },
1665
+ { sse: 1, opcode: 0x0fe9, e: 1, custom: 1 },
1666
+ { sse: 1, opcode: 0x660fe9, e: 1, custom: 1 },
1667
+ { sse: 1, opcode: 0x0fea, e: 1, custom: 1 },
1668
+ { sse: 1, opcode: 0x660fea, e: 1, custom: 1 },
1669
+ { sse: 1, opcode: 0x0feb, e: 1, custom: 1 },
1670
+ { sse: 1, opcode: 0x660feb, e: 1, custom: 1 },
1671
+ { sse: 1, opcode: 0x0fec, e: 1, custom: 1 },
1672
+ { sse: 1, opcode: 0x660fec, e: 1, custom: 1 },
1673
+ { sse: 1, opcode: 0x0fed, e: 1, custom: 1 },
1674
+ { sse: 1, opcode: 0x660fed, e: 1, custom: 1 },
1675
+ { sse: 1, opcode: 0x0fee, e: 1, custom: 1 },
1676
+ { sse: 1, opcode: 0x660fee, e: 1, custom: 1 },
1677
+ { sse: 1, opcode: 0x0fef, e: 1, custom: 1 },
1678
+ { sse: 1, opcode: 0x660fef, e: 1, custom: 1 },
1679
+
1680
+ { sse: 1, opcode: 0x0ff0, skip: 1, block_boundary: 1 }, // sse3
1681
+
1682
+ { sse: 1, opcode: 0x0ff1, e: 1, custom: 1 },
1683
+ { sse: 1, opcode: 0x660ff1, e: 1, custom: 1 },
1684
+ { sse: 1, opcode: 0x0ff2, e: 1, custom: 1 },
1685
+ { sse: 1, opcode: 0x660ff2, e: 1, custom: 1 },
1686
+ { sse: 1, opcode: 0x0ff3, e: 1, custom: 1 },
1687
+ { sse: 1, opcode: 0x660ff3, e: 1, custom: 1 },
1688
+ { sse: 1, opcode: 0x0ff4, e: 1, custom: 1 },
1689
+ { sse: 1, opcode: 0x660ff4, e: 1, custom: 1 },
1690
+ { sse: 1, opcode: 0x0ff5, e: 1, custom: 1 },
1691
+ { sse: 1, opcode: 0x660ff5, e: 1, custom: 1 },
1692
+ { sse: 1, opcode: 0x0ff6, e: 1, custom: 1 },
1693
+ { sse: 1, opcode: 0x660ff6, e: 1, custom: 1 },
1694
+ // maskmovq (0FF7), maskmovdqu (660FF7) tested manually
1695
+ // Generated tests don't setup EDI as required (yet)
1696
+ { sse: 1, opcode: 0x0ff7, mem_ud: 1, e: 1, custom: 1, skip: 1 },
1697
+ { sse: 1, opcode: 0x660ff7, mem_ud: 1, e: 1, custom: 1, skip: 1 },
1698
+
1699
+ { sse: 1, opcode: 0x0ff8, e: 1, custom: 1 },
1700
+ { sse: 1, opcode: 0x660ff8, e: 1, custom: 1 },
1701
+ { sse: 1, opcode: 0x0ff9, e: 1, custom: 1 },
1702
+ { sse: 1, opcode: 0x660ff9, e: 1, custom: 1 },
1703
+ { sse: 1, opcode: 0x0ffa, e: 1, custom: 1 },
1704
+ { sse: 1, opcode: 0x660ffa, e: 1, custom: 1 },
1705
+ { sse: 1, opcode: 0x0ffb, e: 1, custom: 1 },
1706
+ { sse: 1, opcode: 0x660ffb, e: 1, custom: 1 },
1707
+ { sse: 1, opcode: 0x0ffc, e: 1, custom: 1 },
1708
+ { sse: 1, opcode: 0x660ffc, e: 1, custom: 1 },
1709
+ { sse: 1, opcode: 0x0ffd, e: 1, custom: 1 },
1710
+ { sse: 1, opcode: 0x660ffd, e: 1, custom: 1 },
1711
+ { sse: 1, opcode: 0x0ffe, e: 1, custom: 1 },
1712
+ { sse: 1, opcode: 0x660ffe, e: 1, custom: 1 },
1713
+
1714
+ { opcode: 0x0fff, block_boundary: 1 }, // ud
1715
+ ]
1716
+
1717
+ for (let i = 0; i < 8; i++) {
1718
+ encodings.push.apply(encodings, [
1719
+ { opcode: 0x00 | (i << 3), custom: 1, e: 1 },
1720
+ { opcode: 0x01 | (i << 3), custom: 1, os: 1, e: 1 },
1721
+ { opcode: 0x02 | (i << 3), custom: 1, e: 1 },
1722
+ { opcode: 0x03 | (i << 3), custom: 1, os: 1, e: 1 },
1723
+ { opcode: 0x04 | (i << 3), custom: 1, imm8: 1 },
1724
+ { opcode: 0x05 | (i << 3), custom: 1, os: 1, imm1632: 1 },
1725
+
1726
+ { opcode: 0x40 | i, os: 1, custom: 1 },
1727
+ { opcode: 0x48 | i, os: 1, custom: 1 },
1728
+
1729
+ { opcode: 0x50 | i, custom: 1, os: 1 },
1730
+ { opcode: 0x58 | i, custom: 1, os: 1 },
1731
+
1732
+ {
1733
+ opcode: 0x70 | i,
1734
+ block_boundary: 1,
1735
+ no_block_boundary_in_interpreted: 1,
1736
+ jump_offset_imm: 1,
1737
+ conditional_jump: 1,
1738
+ os: 1,
1739
+ imm8s: 1,
1740
+ custom: 1,
1741
+ skip: 1,
1742
+ },
1743
+ {
1744
+ opcode: 0x78 | i,
1745
+ block_boundary: 1,
1746
+ no_block_boundary_in_interpreted: 1,
1747
+ jump_offset_imm: 1,
1748
+ conditional_jump: 1,
1749
+ os: 1,
1750
+ imm8s: 1,
1751
+ custom: 1,
1752
+ skip: 1,
1753
+ },
1754
+
1755
+ { opcode: 0x80, e: 1, fixed_g: i, imm8: 1, custom: 1 },
1756
+ { opcode: 0x81, os: 1, e: 1, fixed_g: i, imm1632: 1, custom: 1 },
1757
+ { opcode: 0x82, e: 1, fixed_g: i, imm8: 1, custom: 1 },
1758
+ { opcode: 0x83, os: 1, e: 1, fixed_g: i, imm8s: 1, custom: 1 },
1759
+
1760
+ { opcode: 0xb0 | i, custom: 1, imm8: 1 },
1761
+ { opcode: 0xb8 | i, custom: 1, os: 1, imm1632: 1 },
1762
+
1763
+ // note: overflow flag only undefined if shift is > 1
1764
+ // note: the adjust flag is undefined for shifts > 0 and unaffected by rotates
1765
+ {
1766
+ opcode: 0xc0,
1767
+ e: 1,
1768
+ fixed_g: i,
1769
+ imm8: 1,
1770
+ mask_flags: of | af,
1771
+ custom: 1,
1772
+ },
1773
+ {
1774
+ opcode: 0xc1,
1775
+ os: 1,
1776
+ e: 1,
1777
+ fixed_g: i,
1778
+ imm8: 1,
1779
+ mask_flags: of | af,
1780
+ custom: 1,
1781
+ },
1782
+ { opcode: 0xd0, e: 1, fixed_g: i, mask_flags: af, custom: 1 },
1783
+ { opcode: 0xd1, os: 1, e: 1, fixed_g: i, mask_flags: af, custom: 1 },
1784
+ { opcode: 0xd2, e: 1, fixed_g: i, mask_flags: of | af, custom: 1 },
1785
+ {
1786
+ opcode: 0xd3,
1787
+ os: 1,
1788
+ e: 1,
1789
+ fixed_g: i,
1790
+ mask_flags: of | af,
1791
+ custom: 1,
1792
+ },
1793
+
1794
+ { opcode: 0x0f40 | i, e: 1, os: 1, custom: 1 },
1795
+ { opcode: 0x0f48 | i, e: 1, os: 1, custom: 1 },
1796
+
1797
+ {
1798
+ opcode: 0x0f80 | i,
1799
+ block_boundary: 1,
1800
+ no_block_boundary_in_interpreted: 1,
1801
+ jump_offset_imm: 1,
1802
+ conditional_jump: 1,
1803
+ imm1632: 1,
1804
+ os: 1,
1805
+ custom: 1,
1806
+ skip: 1,
1807
+ },
1808
+ {
1809
+ opcode: 0x0f88 | i,
1810
+ block_boundary: 1,
1811
+ no_block_boundary_in_interpreted: 1,
1812
+ jump_offset_imm: 1,
1813
+ conditional_jump: 1,
1814
+ imm1632: 1,
1815
+ os: 1,
1816
+ custom: 1,
1817
+ skip: 1,
1818
+ },
1819
+
1820
+ { opcode: 0x0f90 | i, e: 1, custom: 1 },
1821
+ { opcode: 0x0f98 | i, e: 1, custom: 1 },
1822
+ ])
1823
+ }
1824
+
1825
+ encodings.sort((e1: X86Encoding, e2: X86Encoding): number => {
1826
+ const o1 =
1827
+ (e1.opcode & 0xff00) === 0x0f00 ? e1.opcode & 0xffff : e1.opcode & 0xff
1828
+ const o2 =
1829
+ (e2.opcode & 0xff00) === 0x0f00 ? e2.opcode & 0xffff : e2.opcode & 0xff
1830
+ return o1 - o2 || (e1.fixed_g ?? 0) - (e2.fixed_g ?? 0)
1831
+ })
1832
+
1833
+ const result: readonly Readonly<X86Encoding>[] = Object.freeze(
1834
+ encodings.map((entry) => Object.freeze(entry)),
1835
+ )
1836
+ export default result