Coverage Report

Created: 2026-09-14 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xen/xen/arch/x86/x86_emulate/decode.c
Line
Count
Source
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
2
/******************************************************************************
3
 * decode.c - helper for x86_emulate.c
4
 *
5
 * Generic x86 (32-bit and 64-bit) instruction decoder.
6
 *
7
 * Copyright (c) 2005-2007 Keir Fraser
8
 * Copyright (c) 2005-2007 XenSource Inc.
9
 */
10
11
#include "private.h"
12
13
#ifdef __XEN__
14
# include <xen/err.h>
15
#else
16
0
# define ERR_PTR(val) NULL
17
#endif
18
19
1.23M
#define evex_encoded() (s->evex.mbs)
20
21
struct x86_emulate_state *
22
x86_decode_insn(
23
    struct x86_emulate_ctxt *ctxt,
24
    int (*insn_fetch)(
25
        unsigned long offset, void *p_data, unsigned int bytes,
26
        struct x86_emulate_ctxt *ctxt))
27
0
{
28
0
    static DEFINE_PER_CPU(struct x86_emulate_state, state);
29
0
    struct x86_emulate_state *s = &this_cpu(state);
30
0
    const struct x86_emulate_ops ops = {
31
0
        .insn_fetch = insn_fetch,
32
0
        .read       = x86emul_unhandleable_rw,
33
0
    };
34
0
    int rc;
35
36
0
    init_context(ctxt);
37
38
0
    rc = x86emul_decode(s, ctxt, &ops);
39
0
    if ( unlikely(rc != X86EMUL_OKAY) )
40
0
        return ERR_PTR(-rc);
41
42
#if defined(__XEN__) && !defined(NDEBUG)
43
    /*
44
     * While we avoid memory allocation (by use of per-CPU data) above,
45
     * nevertheless make sure callers properly release the state structure
46
     * for forward compatibility.
47
     */
48
    if ( s->caller )
49
    {
50
        printk(XENLOG_ERR "Unreleased emulation state acquired by %ps\n",
51
               s->caller);
52
        dump_execution_state();
53
    }
54
    s->caller = __builtin_return_address(0);
55
#endif
56
57
0
    return s;
58
0
}
59
60
static const opcode_desc_t opcode_table[256] = {
61
    /* 0x00 - 0x07 */
62
    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
63
    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
64
    ByteOp|DstEax|SrcImm, DstEax|SrcImm, ImplicitOps|Mov, ImplicitOps|Mov,
65
    /* 0x08 - 0x0F */
66
    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
67
    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
68
    ByteOp|DstEax|SrcImm, DstEax|SrcImm, ImplicitOps|Mov, 0,
69
    /* 0x10 - 0x17 */
70
    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
71
    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
72
    ByteOp|DstEax|SrcImm, DstEax|SrcImm, ImplicitOps|Mov, ImplicitOps|Mov,
73
    /* 0x18 - 0x1F */
74
    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
75
    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
76
    ByteOp|DstEax|SrcImm, DstEax|SrcImm, ImplicitOps|Mov, ImplicitOps|Mov,
77
    /* 0x20 - 0x27 */
78
    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
79
    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
80
    ByteOp|DstEax|SrcImm, DstEax|SrcImm, 0, ImplicitOps,
81
    /* 0x28 - 0x2F */
82
    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
83
    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
84
    ByteOp|DstEax|SrcImm, DstEax|SrcImm, 0, ImplicitOps,
85
    /* 0x30 - 0x37 */
86
    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
87
    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
88
    ByteOp|DstEax|SrcImm, DstEax|SrcImm, 0, ImplicitOps,
89
    /* 0x38 - 0x3F */
90
    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
91
    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
92
    ByteOp|DstEax|SrcImm, DstEax|SrcImm, 0, ImplicitOps,
93
    /* 0x40 - 0x4F */
94
    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
95
    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
96
    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
97
    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
98
    /* 0x50 - 0x5F */
99
    ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
100
    ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
101
    ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
102
    ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
103
    /* 0x60 - 0x67 */
104
    ImplicitOps, ImplicitOps, DstReg|SrcMem|ModRM, DstReg|SrcNone|ModRM|Mov,
105
    0, 0, 0, 0,
106
    /* 0x68 - 0x6F */
107
    DstImplicit|SrcImm|Mov, DstReg|SrcImm|ModRM|Mov,
108
    DstImplicit|SrcImmByte|Mov, DstReg|SrcImmByte|ModRM|Mov,
109
    ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
110
    /* 0x70 - 0x77 */
111
    DstImplicit|SrcImmByte, DstImplicit|SrcImmByte,
112
    DstImplicit|SrcImmByte, DstImplicit|SrcImmByte,
113
    DstImplicit|SrcImmByte, DstImplicit|SrcImmByte,
114
    DstImplicit|SrcImmByte, DstImplicit|SrcImmByte,
115
    /* 0x78 - 0x7F */
116
    DstImplicit|SrcImmByte, DstImplicit|SrcImmByte,
117
    DstImplicit|SrcImmByte, DstImplicit|SrcImmByte,
118
    DstImplicit|SrcImmByte, DstImplicit|SrcImmByte,
119
    DstImplicit|SrcImmByte, DstImplicit|SrcImmByte,
120
    /* 0x80 - 0x87 */
121
    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
122
    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM,
123
    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
124
    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
125
    /* 0x88 - 0x8F */
126
    ByteOp|DstMem|SrcReg|ModRM|Mov, DstMem|SrcReg|ModRM|Mov,
127
    ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
128
    DstMem|SrcReg|ModRM|Mov, DstReg|SrcNone|ModRM,
129
    DstReg|SrcMem16|ModRM|Mov, DstMem|SrcNone|ModRM|Mov,
130
    /* 0x90 - 0x97 */
131
    DstImplicit|SrcEax, DstImplicit|SrcEax,
132
    DstImplicit|SrcEax, DstImplicit|SrcEax,
133
    DstImplicit|SrcEax, DstImplicit|SrcEax,
134
    DstImplicit|SrcEax, DstImplicit|SrcEax,
135
    /* 0x98 - 0x9F */
136
    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
137
    ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps, ImplicitOps,
138
    /* 0xA0 - 0xA7 */
139
    ByteOp|DstEax|SrcMem|Mov, DstEax|SrcMem|Mov,
140
    ByteOp|DstMem|SrcEax|Mov, DstMem|SrcEax|Mov,
141
    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
142
    ByteOp|ImplicitOps, ImplicitOps,
143
    /* 0xA8 - 0xAF */
144
    ByteOp|DstEax|SrcImm, DstEax|SrcImm,
145
    ByteOp|DstImplicit|SrcEax|Mov, DstImplicit|SrcEax|Mov,
146
    ByteOp|DstEax|SrcImplicit|Mov, DstEax|SrcImplicit|Mov,
147
    ByteOp|DstImplicit|SrcEax, DstImplicit|SrcEax,
148
    /* 0xB0 - 0xB7 */
149
    ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,
150
    ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,
151
    ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,
152
    ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,
153
    /* 0xB8 - 0xBF */
154
    DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov,
155
    DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov,
156
    /* 0xC0 - 0xC7 */
157
    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM,
158
    DstImplicit|SrcImm16, ImplicitOps,
159
    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
160
    ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov,
161
    /* 0xC8 - 0xCF */
162
    DstImplicit|SrcImm16, ImplicitOps, DstImplicit|SrcImm16, ImplicitOps,
163
    ImplicitOps, DstImplicit|SrcImmByte, ImplicitOps, ImplicitOps,
164
    /* 0xD0 - 0xD7 */
165
    ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM,
166
    ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM,
167
    DstImplicit|SrcImmByte, DstImplicit|SrcImmByte, ImplicitOps, ImplicitOps,
168
    /* 0xD8 - 0xDF */
169
    ImplicitOps|ModRM, ImplicitOps|ModRM|Mov,
170
    ImplicitOps|ModRM, ImplicitOps|ModRM|Mov,
171
    ImplicitOps|ModRM, ImplicitOps|ModRM|Mov,
172
    DstImplicit|SrcMem16|ModRM, ImplicitOps|ModRM|Mov,
173
    /* 0xE0 - 0xE7 */
174
    DstImplicit|SrcImmByte, DstImplicit|SrcImmByte,
175
    DstImplicit|SrcImmByte, DstImplicit|SrcImmByte,
176
    DstEax|SrcImmByte, DstEax|SrcImmByte,
177
    DstImplicit|SrcImmByte, DstImplicit|SrcImmByte,
178
    /* 0xE8 - 0xEF */
179
    DstImplicit|SrcImm|Mov, DstImplicit|SrcImm,
180
    ImplicitOps, DstImplicit|SrcImmByte,
181
    DstEax|SrcImplicit, DstEax|SrcImplicit, ImplicitOps, ImplicitOps,
182
    /* 0xF0 - 0xF7 */
183
    0, ImplicitOps, 0, 0,
184
    ImplicitOps, ImplicitOps, ByteOp|ModRM, ModRM,
185
    /* 0xF8 - 0xFF */
186
    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
187
    ImplicitOps, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM
188
};
189
190
static const struct twobyte_table {
191
    opcode_desc_t desc;
192
    simd_opsize_t size:4;
193
    disp8scale_t d8s:4;
194
} twobyte_table[256] = {
195
    [0x00] = { ModRM },
196
    [0x01] = { ImplicitOps|ModRM },
197
    [0x02] = { DstReg|SrcMem16|ModRM },
198
    [0x03] = { DstReg|SrcMem16|ModRM },
199
    [0x05] = { ImplicitOps },
200
    [0x06] = { ImplicitOps },
201
    [0x07] = { ImplicitOps },
202
    [0x08] = { ImplicitOps },
203
    [0x09] = { ImplicitOps },
204
    [0x0b] = { ImplicitOps },
205
    [0x0d] = { ImplicitOps|ModRM },
206
    [0x0e] = { ImplicitOps },
207
    [0x0f] = { ModRM|SrcImmByte },
208
    [0x10] = { DstImplicit|SrcMem|ModRM|Mov, simd_any_fp, d8s_vl },
209
    [0x11] = { DstMem|SrcImplicit|ModRM|Mov, simd_any_fp, d8s_vl },
210
    [0x12] = { DstImplicit|SrcMem|ModRM|Mov, simd_other, 3 },
211
    [0x13] = { DstMem|SrcImplicit|ModRM|Mov, simd_other, 3 },
212
    [0x14 ... 0x15] = { DstImplicit|SrcMem|ModRM, simd_packed_fp, d8s_vl },
213
    [0x16] = { DstImplicit|SrcMem|ModRM|Mov, simd_other, 3 },
214
    [0x17] = { DstMem|SrcImplicit|ModRM|Mov, simd_other, 3 },
215
    [0x18 ... 0x1c] = { ImplicitOps|ModRM },
216
    [0x1d] = { ImplicitOps|ModRM, simd_none, d8s_vl },
217
    [0x1e ... 0x1f] = { ImplicitOps|ModRM },
218
    [0x20 ... 0x21] = { DstMem|SrcImplicit|ModRM },
219
    [0x22 ... 0x23] = { DstImplicit|SrcMem|ModRM },
220
    [0x28] = { DstImplicit|SrcMem|ModRM|Mov, simd_packed_fp, d8s_vl },
221
    [0x29] = { DstMem|SrcImplicit|ModRM|Mov, simd_packed_fp, d8s_vl },
222
    [0x2a] = { DstImplicit|SrcMem|ModRM|Mov, simd_other, d8s_dq64 },
223
    [0x2b] = { DstMem|SrcImplicit|ModRM|Mov, simd_any_fp, d8s_vl },
224
    [0x2c ... 0x2d] = { DstImplicit|SrcMem|ModRM|Mov, simd_other },
225
    [0x2e ... 0x2f] = { ImplicitOps|ModRM|TwoOp, simd_none, d8s_dq },
226
    [0x30 ... 0x35] = { ImplicitOps },
227
    [0x37] = { ImplicitOps },
228
    [0x38] = { DstReg|SrcMem|ModRM },
229
    [0x3a] = { DstReg|SrcImmByte|ModRM },
230
    [0x40 ... 0x4f] = { DstReg|SrcMem|ModRM|Mov },
231
    [0x50] = { DstReg|SrcImplicit|ModRM|Mov },
232
    [0x51] = { DstImplicit|SrcMem|ModRM|TwoOp, simd_any_fp, d8s_vl },
233
    [0x52 ... 0x53] = { DstImplicit|SrcMem|ModRM|TwoOp, simd_single_fp },
234
    [0x54 ... 0x57] = { DstImplicit|SrcMem|ModRM, simd_packed_fp, d8s_vl },
235
    [0x58 ... 0x59] = { DstImplicit|SrcMem|ModRM, simd_any_fp, d8s_vl },
236
    [0x5a] = { DstImplicit|SrcMem|ModRM|Mov, simd_any_fp, d8s_vl },
237
    [0x5b] = { DstImplicit|SrcMem|ModRM|Mov, simd_packed_fp, d8s_vl },
238
    [0x5c ... 0x5f] = { DstImplicit|SrcMem|ModRM, simd_any_fp, d8s_vl },
239
    [0x60 ... 0x62] = { DstImplicit|SrcMem|ModRM, simd_other, d8s_vl },
240
    [0x63 ... 0x67] = { DstImplicit|SrcMem|ModRM, simd_packed_int, d8s_vl },
241
    [0x68 ... 0x6a] = { DstImplicit|SrcMem|ModRM, simd_other, d8s_vl },
242
    [0x6b ... 0x6d] = { DstImplicit|SrcMem|ModRM, simd_packed_int, d8s_vl },
243
    [0x6e] = { DstImplicit|SrcMem|ModRM|Mov, simd_none, d8s_dq64 },
244
    [0x6f] = { DstImplicit|SrcMem|ModRM|Mov, simd_packed_int, d8s_vl },
245
    [0x70] = { SrcImmByte|ModRM|TwoOp, simd_other, d8s_vl },
246
    [0x71 ... 0x73] = { DstImplicit|SrcImmByte|ModRM, simd_none, d8s_vl },
247
    [0x74 ... 0x76] = { DstImplicit|SrcMem|ModRM, simd_packed_int, d8s_vl },
248
    [0x77] = { DstImplicit|SrcNone },
249
    [0x78 ... 0x79] = { DstImplicit|SrcMem|ModRM|Mov, simd_other, d8s_vl },
250
    [0x7a] = { DstImplicit|SrcMem|ModRM|Mov, simd_packed_fp, d8s_vl },
251
    [0x7b] = { DstImplicit|SrcMem|ModRM|Mov, simd_other, d8s_dq64 },
252
    [0x7c ... 0x7d] = { DstImplicit|SrcMem|ModRM, simd_other, d8s_vl },
253
    [0x7e] = { DstMem|SrcImplicit|ModRM|Mov, simd_none, d8s_dq64 },
254
    [0x7f] = { DstMem|SrcImplicit|ModRM|Mov, simd_packed_int, d8s_vl },
255
    [0x80 ... 0x8f] = { DstImplicit|SrcImm },
256
    [0x90 ... 0x9f] = { ByteOp|DstMem|SrcNone|ModRM|Mov },
257
    [0xa0 ... 0xa1] = { ImplicitOps|Mov },
258
    [0xa2] = { ImplicitOps },
259
    [0xa3] = { DstBitBase|SrcReg|ModRM },
260
    [0xa4] = { DstMem|SrcImmByte|ModRM },
261
    [0xa5] = { DstMem|SrcReg|ModRM },
262
    [0xa6 ... 0xa7] = { ModRM },
263
    [0xa8 ... 0xa9] = { ImplicitOps|Mov },
264
    [0xaa] = { ImplicitOps },
265
    [0xab] = { DstBitBase|SrcReg|ModRM },
266
    [0xac] = { DstMem|SrcImmByte|ModRM },
267
    [0xad] = { DstMem|SrcReg|ModRM },
268
    [0xae] = { ImplicitOps|ModRM },
269
    [0xaf] = { DstReg|SrcMem|ModRM },
270
    [0xb0] = { ByteOp|DstMem|SrcReg|ModRM },
271
    [0xb1] = { DstMem|SrcReg|ModRM },
272
    [0xb2] = { DstReg|SrcMem|ModRM|Mov },
273
    [0xb3] = { DstBitBase|SrcReg|ModRM },
274
    [0xb4 ... 0xb5] = { DstReg|SrcMem|ModRM|Mov },
275
    [0xb6] = { ByteOp|DstReg|SrcMem|ModRM|Mov },
276
    [0xb7] = { DstReg|SrcMem16|ModRM|Mov },
277
    [0xb8] = { DstReg|SrcMem|ModRM },
278
    [0xb9] = { ModRM },
279
    [0xba] = { DstBitBase|SrcImmByte|ModRM },
280
    [0xbb] = { DstBitBase|SrcReg|ModRM },
281
    [0xbc ... 0xbd] = { DstReg|SrcMem|ModRM },
282
    [0xbe] = { ByteOp|DstReg|SrcMem|ModRM|Mov },
283
    [0xbf] = { DstReg|SrcMem16|ModRM|Mov },
284
    [0xc0] = { ByteOp|DstMem|SrcReg|ModRM },
285
    [0xc1] = { DstMem|SrcReg|ModRM },
286
    [0xc2] = { DstImplicit|SrcImmByte|ModRM, simd_any_fp, d8s_vl },
287
    [0xc3] = { DstMem|SrcReg|ModRM|Mov },
288
    [0xc4] = { DstImplicit|SrcImmByte|ModRM, simd_none, 1 },
289
    [0xc5] = { DstReg|SrcImmByte|ModRM|Mov },
290
    [0xc6] = { DstImplicit|SrcImmByte|ModRM, simd_packed_fp, d8s_vl },
291
    [0xc7] = { ImplicitOps|ModRM },
292
    [0xc8 ... 0xcf] = { ImplicitOps },
293
    [0xd0] = { DstImplicit|SrcMem|ModRM, simd_other },
294
    [0xd1 ... 0xd3] = { DstImplicit|SrcMem|ModRM, simd_128, 4 },
295
    [0xd4 ... 0xd5] = { DstImplicit|SrcMem|ModRM, simd_packed_int, d8s_vl },
296
    [0xd6] = { DstMem|SrcImplicit|ModRM|Mov, simd_other, 3 },
297
    [0xd7] = { DstReg|SrcImplicit|ModRM|Mov },
298
    [0xd8 ... 0xdf] = { DstImplicit|SrcMem|ModRM, simd_packed_int, d8s_vl },
299
    [0xe0] = { DstImplicit|SrcMem|ModRM, simd_packed_int, d8s_vl },
300
    [0xe1 ... 0xe2] = { DstImplicit|SrcMem|ModRM, simd_128, 4 },
301
    [0xe3 ... 0xe5] = { DstImplicit|SrcMem|ModRM, simd_packed_int, d8s_vl },
302
    [0xe6] = { DstImplicit|SrcMem|ModRM|Mov, simd_packed_fp, d8s_vl },
303
    [0xe7] = { DstMem|SrcImplicit|ModRM|Mov, simd_packed_int, d8s_vl },
304
    [0xe8 ... 0xef] = { DstImplicit|SrcMem|ModRM, simd_packed_int, d8s_vl },
305
    [0xf0] = { DstImplicit|SrcMem|ModRM|Mov, simd_other },
306
    [0xf1 ... 0xf3] = { DstImplicit|SrcMem|ModRM, simd_128, 4 },
307
    [0xf4 ... 0xf6] = { DstImplicit|SrcMem|ModRM, simd_packed_int, d8s_vl },
308
    [0xf7] = { DstMem|SrcMem|ModRM|Mov, simd_packed_int },
309
    [0xf8 ... 0xfe] = { DstImplicit|SrcMem|ModRM, simd_packed_int, d8s_vl },
310
    [0xff] = { ModRM }
311
};
312
313
/*
314
 * "two_op" and "four_op" below refer to the number of register operands
315
 * (one of which possibly also allowing to be a memory one). The named
316
 * operand counts do not include any immediate operands.
317
 */
318
static const struct ext0f38_table {
319
    uint8_t simd_size:5;
320
    uint8_t to_mem:1;
321
    uint8_t two_op:1;
322
    uint8_t vsib:1;
323
    disp8scale_t d8s:4;
324
} ext0f38_table[256] = {
325
    [0x00] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
326
    [0x01 ... 0x03] = { .simd_size = simd_packed_int },
327
    [0x04] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
328
    [0x05 ... 0x0a] = { .simd_size = simd_packed_int },
329
    [0x0b] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
330
    [0x0c ... 0x0d] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
331
    [0x0e ... 0x0f] = { .simd_size = simd_packed_fp },
332
    [0x10 ... 0x12] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
333
    [0x13] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_2 },
334
    [0x14 ... 0x16] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
335
    [0x17] = { .simd_size = simd_packed_int, .two_op = 1 },
336
    [0x18] = { .simd_size = simd_scalar_opc, .two_op = 1, .d8s = 2 },
337
    [0x19] = { .simd_size = simd_scalar_opc, .two_op = 1, .d8s = 3 },
338
    [0x1a] = { .simd_size = simd_128, .two_op = 1, .d8s = 4 },
339
    [0x1b] = { .simd_size = simd_256, .two_op = 1, .d8s = d8s_vl_by_2 },
340
    [0x1c ... 0x1f] = { .simd_size = simd_packed_int, .two_op = 1, .d8s = d8s_vl },
341
    [0x20] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_2 },
342
    [0x21] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_4 },
343
    [0x22] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_8 },
344
    [0x23] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_2 },
345
    [0x24] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_4 },
346
    [0x25] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_2 },
347
    [0x26 ... 0x29] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
348
    [0x2a] = { .simd_size = simd_packed_int, .two_op = 1, .d8s = d8s_vl },
349
    [0x2b] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
350
    [0x2c] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
351
    [0x2d] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
352
    [0x2e ... 0x2f] = { .simd_size = simd_packed_fp, .to_mem = 1 },
353
    [0x30] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_2 },
354
    [0x31] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_4 },
355
    [0x32] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_8 },
356
    [0x33] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_2 },
357
    [0x34] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_4 },
358
    [0x35] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl_by_2 },
359
    [0x36 ... 0x3f] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
360
    [0x40] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
361
    [0x41] = { .simd_size = simd_packed_int, .two_op = 1 },
362
    [0x42] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_vl },
363
    [0x43] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
364
    [0x44] = { .simd_size = simd_packed_int, .two_op = 1, .d8s = d8s_vl },
365
    [0x45 ... 0x47] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
366
    [0x4c] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_vl },
367
    [0x4d] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
368
    [0x4e] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_vl },
369
    [0x4f] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
370
    [0x50 ... 0x53] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
371
    [0x54 ... 0x55] = { .simd_size = simd_packed_int, .two_op = 1, .d8s = d8s_vl },
372
    [0x56] = { .simd_size = simd_other, .d8s = d8s_vl },
373
    [0x57] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
374
    [0x58] = { .simd_size = simd_other, .two_op = 1, .d8s = 2 },
375
    [0x59] = { .simd_size = simd_other, .two_op = 1, .d8s = 3 },
376
    [0x5a] = { .simd_size = simd_128, .two_op = 1, .d8s = 4 },
377
    [0x5b] = { .simd_size = simd_256, .two_op = 1, .d8s = d8s_vl_by_2 },
378
    [0x62] = { .simd_size = simd_packed_int, .two_op = 1, .d8s = d8s_bw },
379
    [0x63] = { .simd_size = simd_packed_int, .to_mem = 1, .two_op = 1, .d8s = d8s_bw },
380
    [0x64 ... 0x66] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
381
    [0x68] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
382
    [0x70 ... 0x73] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
383
    [0x75 ... 0x76] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
384
    [0x77] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
385
    [0x78] = { .simd_size = simd_other, .two_op = 1 },
386
    [0x79] = { .simd_size = simd_other, .two_op = 1, .d8s = 1 },
387
    [0x7a ... 0x7c] = { .simd_size = simd_none, .two_op = 1 },
388
    [0x7d ... 0x7e] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
389
    [0x7f] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
390
    [0x80 ... 0x81] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
391
    [0x82] = { .simd_size = simd_other },
392
    [0x83] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
393
    [0x88] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_dq },
394
    [0x89] = { .simd_size = simd_packed_int, .two_op = 1, .d8s = d8s_dq },
395
    [0x8a] = { .simd_size = simd_packed_fp, .to_mem = 1, .two_op = 1, .d8s = d8s_dq },
396
    [0x8b] = { .simd_size = simd_packed_int, .to_mem = 1, .two_op = 1, .d8s = d8s_dq },
397
    [0x8c] = { .simd_size = simd_packed_int },
398
    [0x8d] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
399
    [0x8e] = { .simd_size = simd_packed_int, .to_mem = 1 },
400
    [0x8f] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
401
    [0x90 ... 0x93] = { .simd_size = simd_other, .vsib = 1, .d8s = d8s_dq },
402
    [0x96 ... 0x98] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
403
    [0x99] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
404
    [0x9a] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
405
    [0x9b] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
406
    [0x9c] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
407
    [0x9d] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
408
    [0x9e] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
409
    [0x9f] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
410
    [0xa0 ... 0xa3] = { .simd_size = simd_other, .to_mem = 1, .vsib = 1, .d8s = d8s_dq },
411
    [0xa6 ... 0xa8] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
412
    [0xa9] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
413
    [0xaa] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
414
    [0xab] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
415
    [0xac] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
416
    [0xad] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
417
    [0xae] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
418
    [0xaf] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
419
    [0xb0] = { .simd_size = simd_other, .two_op = 1 },
420
    [0xb1] = { .simd_size = simd_other, .two_op = 1 },
421
    [0xb4 ... 0xb5] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
422
    [0xb6 ... 0xb8] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
423
    [0xb9] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
424
    [0xba] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
425
    [0xbb] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
426
    [0xbc] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
427
    [0xbd] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
428
    [0xbe] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
429
    [0xbf] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
430
    [0xc4] = { .simd_size = simd_packed_int, .two_op = 1, .d8s = d8s_vl },
431
    [0xc8] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_vl },
432
    [0xc9] = { .simd_size = simd_other },
433
    [0xca] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_vl },
434
    [0xcb] = { .simd_size = simd_other, .d8s = d8s_vl },
435
    [0xcc ... 0xcd] = { .simd_size = simd_other, .two_op = 1, .d8s = d8s_vl },
436
    [0xcf] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
437
    [0xd2] = { .simd_size = simd_other },
438
    [0xd3] = { .simd_size = simd_other },
439
    [0xd6] = { .simd_size = simd_other, .d8s = d8s_vl },
440
    [0xd7] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
441
    [0xda] = { .simd_size = simd_other },
442
    [0xdb] = { .simd_size = simd_packed_int, .two_op = 1 },
443
    [0xdc ... 0xdf] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
444
    [0xe0 ... 0xef] = { .to_mem = 1 },
445
    [0xf0] = { .two_op = 1 },
446
    [0xf1] = { .to_mem = 1, .two_op = 1 },
447
    [0xf2 ... 0xf3] = {},
448
    [0xf5 ... 0xf7] = {},
449
    [0xf8] = { .simd_size = simd_other },
450
    [0xf9] = { .to_mem = 1, .two_op = 1 /* Mov */ },
451
};
452
453
static const struct ext0f3a_table {
454
    uint8_t simd_size:5;
455
    uint8_t to_mem:1;
456
    uint8_t two_op:1;
457
    uint8_t four_op:1;
458
    disp8scale_t d8s:4;
459
} ext0f3a_table[256] = {
460
    [0x00] = { .simd_size = simd_packed_int, .two_op = 1, .d8s = d8s_vl },
461
    [0x01] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_vl },
462
    [0x02] = { .simd_size = simd_packed_int },
463
    [0x03] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
464
    [0x04 ... 0x05] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_vl },
465
    [0x06] = { .simd_size = simd_packed_fp },
466
    [0x08 ... 0x09] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_vl },
467
    [0x0a ... 0x0b] = { .simd_size = simd_scalar_opc, .d8s = d8s_dq },
468
    [0x0c ... 0x0d] = { .simd_size = simd_packed_fp },
469
    [0x0e] = { .simd_size = simd_packed_int },
470
    [0x0f] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
471
    [0x14] = { .simd_size = simd_none, .to_mem = 1, .two_op = 1, .d8s = 0 },
472
    [0x15] = { .simd_size = simd_none, .to_mem = 1, .two_op = 1, .d8s = 1 },
473
    [0x16] = { .simd_size = simd_none, .to_mem = 1, .two_op = 1, .d8s = d8s_dq64 },
474
    [0x17] = { .simd_size = simd_none, .to_mem = 1, .two_op = 1, .d8s = 2 },
475
    [0x18] = { .simd_size = simd_128, .d8s = 4 },
476
    [0x19] = { .simd_size = simd_128, .to_mem = 1, .two_op = 1, .d8s = 4 },
477
    [0x1a] = { .simd_size = simd_256, .d8s = d8s_vl_by_2 },
478
    [0x1b] = { .simd_size = simd_256, .to_mem = 1, .two_op = 1, .d8s = d8s_vl_by_2 },
479
    [0x1d] = { .simd_size = simd_other, .to_mem = 1, .two_op = 1, .d8s = d8s_vl_by_2 },
480
    [0x1e ... 0x1f] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
481
    [0x20] = { .simd_size = simd_none, .d8s = 0 },
482
    [0x21] = { .simd_size = simd_other, .d8s = 2 },
483
    [0x22] = { .simd_size = simd_none, .d8s = d8s_dq64 },
484
    [0x23] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
485
    [0x25] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
486
    [0x26] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_vl },
487
    [0x27] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
488
    [0x30 ... 0x33] = { .simd_size = simd_other, .two_op = 1 },
489
    [0x38] = { .simd_size = simd_128, .d8s = 4 },
490
    [0x3a] = { .simd_size = simd_256, .d8s = d8s_vl_by_2 },
491
    [0x39] = { .simd_size = simd_128, .to_mem = 1, .two_op = 1, .d8s = 4 },
492
    [0x3b] = { .simd_size = simd_256, .to_mem = 1, .two_op = 1, .d8s = d8s_vl_by_2 },
493
    [0x3e ... 0x3f] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
494
    [0x40 ... 0x41] = { .simd_size = simd_packed_fp },
495
    [0x42 ... 0x43] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
496
    [0x44] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
497
    [0x46] = { .simd_size = simd_packed_int },
498
    [0x48 ... 0x49] = { .simd_size = simd_packed_fp, .four_op = 1 },
499
    [0x4a ... 0x4b] = { .simd_size = simd_packed_fp, .four_op = 1 },
500
    [0x4c] = { .simd_size = simd_packed_int, .four_op = 1 },
501
    [0x50] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
502
    [0x51] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
503
    [0x54] = { .simd_size = simd_packed_fp, .d8s = d8s_vl },
504
    [0x55] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
505
    [0x56] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_vl },
506
    [0x57] = { .simd_size = simd_scalar_vexw, .d8s = d8s_dq },
507
    [0x5c ... 0x5f] = { .simd_size = simd_packed_fp, .four_op = 1 },
508
    [0x60 ... 0x63] = { .simd_size = simd_packed_int, .two_op = 1 },
509
    [0x66] = { .simd_size = simd_packed_fp, .two_op = 1, .d8s = d8s_vl },
510
    [0x67] = { .simd_size = simd_scalar_vexw, .two_op = 1, .d8s = d8s_dq },
511
    [0x68 ... 0x69] = { .simd_size = simd_packed_fp, .four_op = 1 },
512
    [0x6a ... 0x6b] = { .simd_size = simd_scalar_opc, .four_op = 1 },
513
    [0x6c ... 0x6d] = { .simd_size = simd_packed_fp, .four_op = 1 },
514
    [0x6e ... 0x6f] = { .simd_size = simd_scalar_opc, .four_op = 1 },
515
    [0x70 ... 0x73] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
516
    [0x78 ... 0x79] = { .simd_size = simd_packed_fp, .four_op = 1 },
517
    [0x7a ... 0x7b] = { .simd_size = simd_scalar_opc, .four_op = 1 },
518
    [0x7c ... 0x7d] = { .simd_size = simd_packed_fp, .four_op = 1 },
519
    [0x7e ... 0x7f] = { .simd_size = simd_scalar_opc, .four_op = 1 },
520
    [0xc2] = { .simd_size = simd_any_fp, .d8s = d8s_vl },
521
    [0xcc] = { .simd_size = simd_other },
522
    [0xce ... 0xcf] = { .simd_size = simd_packed_int, .d8s = d8s_vl },
523
    [0xde] = { .simd_size = simd_other },
524
    [0xdf] = { .simd_size = simd_packed_int, .two_op = 1 },
525
    [0xf0] = { .two_op = 1 /* Mov */ },
526
};
527
528
static const opcode_desc_t xop_table[] = {
529
    DstReg|SrcImmByte|ModRM,
530
    DstReg|SrcMem|ModRM,
531
    DstReg|SrcImm|ModRM,
532
};
533
534
static const struct ext8f08_table {
535
    uint8_t simd_size:5;
536
    uint8_t two_op:1;
537
    uint8_t four_op:1;
538
} ext8f08_table[256] = {
539
    [0xa2] = { .simd_size = simd_packed_int, .four_op = 1 },
540
    [0x85 ... 0x87] = { .simd_size = simd_packed_int, .four_op = 1 },
541
    [0x8e ... 0x8f] = { .simd_size = simd_packed_int, .four_op = 1 },
542
    [0x95 ... 0x97] = { .simd_size = simd_packed_int, .four_op = 1 },
543
    [0x9e ... 0x9f] = { .simd_size = simd_packed_int, .four_op = 1 },
544
    [0xa3] = { .simd_size = simd_packed_int, .four_op = 1 },
545
    [0xa6] = { .simd_size = simd_packed_int, .four_op = 1 },
546
    [0xb6] = { .simd_size = simd_packed_int, .four_op = 1 },
547
    [0xc0 ... 0xc3] = { .simd_size = simd_packed_int, .two_op = 1 },
548
    [0xcc ... 0xcf] = { .simd_size = simd_packed_int },
549
    [0xec ... 0xef] = { .simd_size = simd_packed_int },
550
};
551
552
static const struct ext8f09_table {
553
    uint8_t simd_size:5;
554
    uint8_t two_op:1;
555
} ext8f09_table[256] = {
556
    [0x01 ... 0x02] = { .two_op = 1 },
557
    [0x80 ... 0x81] = { .simd_size = simd_packed_fp, .two_op = 1 },
558
    [0x82 ... 0x83] = { .simd_size = simd_scalar_opc, .two_op = 1 },
559
    [0x90 ... 0x9b] = { .simd_size = simd_packed_int },
560
    [0xc1 ... 0xc3] = { .simd_size = simd_packed_int, .two_op = 1 },
561
    [0xc6 ... 0xc7] = { .simd_size = simd_packed_int, .two_op = 1 },
562
    [0xcb] = { .simd_size = simd_packed_int, .two_op = 1 },
563
    [0xd1 ... 0xd3] = { .simd_size = simd_packed_int, .two_op = 1 },
564
    [0xd6 ... 0xd7] = { .simd_size = simd_packed_int, .two_op = 1 },
565
    [0xdb] = { .simd_size = simd_packed_int, .two_op = 1 },
566
    [0xe1 ... 0xe3] = { .simd_size = simd_packed_int, .two_op = 1 },
567
};
568
569
static unsigned int decode_disp8scale(enum disp8scale scale,
570
                                      const struct x86_emulate_state *s)
571
1.22k
{
572
1.22k
    switch ( scale )
573
1.22k
    {
574
3
    case d8s_bw:
575
3
        return s->evex.w;
576
577
1.05k
    default:
578
1.05k
        if ( scale < d8s_vl )
579
271
            return scale;
580
781
        if ( s->evex.brs )
581
302
        {
582
423
    case d8s_dq:
583
423
            return 1 + !s->fp16 + s->evex.w;
584
302
        }
585
479
        break;
586
587
479
    case d8s_dq64:
588
48
        return 1 + !s->fp16 + (s->op_bytes == 8);
589
1.22k
    }
590
591
479
    switch ( s->simd_size )
592
479
    {
593
67
    case simd_any_fp:
594
67
    case simd_single_fp:
595
67
        if ( !(s->evex.pfx & VEX_PREFIX_SCALAR_MASK) )
596
29
            break;
597
        /* fall through */
598
38
    case simd_scalar_opc:
599
40
    case simd_scalar_vexw:
600
40
        return 1 + !s->fp16 + s->evex.w;
601
602
0
    case simd_128:
603
        /* These should have an explicit size specified. */
604
0
        ASSERT_UNREACHABLE();
605
0
        return 4;
606
607
410
    default:
608
410
        break;
609
479
    }
610
611
439
    return 4 + s->evex.lr - (scale - d8s_vl);
612
479
}
613
614
/* Fetch next part of the instruction being emulated. */
615
1.34M
#define insn_fetch_bytes(_size) ({                                    \
616
1.34M
   unsigned long _x = 0, _ip = s->ip;                                 \
617
1.34M
   s->ip += (_size); /* real hardware doesn't truncate */             \
618
1.34M
   generate_exception_if((uint8_t)(s->ip -                            \
619
1.34M
                                   ctxt->regs->r(ip)) > MAX_INST_LEN, \
620
1.34M
                         X86_EXC_GP, 0);                              \
621
1.34M
   rc = ops->insn_fetch(_ip, &_x, _size, ctxt);                       \
622
1.34M
   if ( rc ) goto done;                                               \
623
1.34M
   _x;                                                                \
624
1.33M
})
625
1.34M
#define insn_fetch_type(type) ((type)insn_fetch_bytes(sizeof(type)))
626
627
static int
628
decode_onebyte(struct x86_emulate_state *s,
629
               struct x86_emulate_ctxt *ctxt,
630
               const struct x86_emulate_ops *ops)
631
290k
{
632
290k
    int rc = X86EMUL_OKAY;
633
634
290k
    switch ( ctxt->opcode )
635
290k
    {
636
1.02k
    case 0x06: /* push %%es */
637
1.69k
    case 0x07: /* pop %%es */
638
2.12k
    case 0x0e: /* push %%cs */
639
3.25k
    case 0x16: /* push %%ss */
640
3.74k
    case 0x17: /* pop %%ss */
641
3.98k
    case 0x1e: /* push %%ds */
642
4.50k
    case 0x1f: /* pop %%ds */
643
7.89k
    case 0x27: /* daa */
644
12.4k
    case 0x2f: /* das */
645
13.4k
    case 0x37: /* aaa */
646
15.3k
    case 0x3f: /* aas */
647
16.0k
    case 0x60: /* pusha */
648
16.6k
    case 0x61: /* popa */
649
17.5k
    case 0x62: /* bound */
650
18.0k
    case 0xc4: /* les */
651
18.3k
    case 0xc5: /* lds */
652
19.4k
    case 0xce: /* into */
653
19.9k
    case 0xd4: /* aam */
654
20.2k
    case 0xd5: /* aad */
655
21.3k
    case 0xd6: /* salc / udb */
656
21.3k
        s->not_64bit = true;
657
21.3k
        break;
658
659
123
    case 0x82: /* Grp1 (x86/32 only) */
660
123
        s->not_64bit = true;
661
        /* fall through */
662
2.16k
    case 0x80: case 0x81: case 0x83: /* Grp1 */
663
2.16k
        if ( (s->modrm_reg & 7) == 7 ) /* cmp */
664
74
            s->desc = (s->desc & ByteOp) | DstNone | SrcMem;
665
2.16k
        break;
666
667
540
    case 0x90: /* nop / pause */
668
540
        if ( s->vex.pfx == vex_f3 )
669
196
            ctxt->opcode |= X86EMUL_OPC_F3(0, 0);
670
540
        break;
671
672
640
    case 0x9a: /* call (far, absolute) */
673
796
    case 0xea: /* jmp (far, absolute) */
674
796
        generate_exception_if(mode_64bit(), X86_EXC_UD);
675
676
1.57k
        s->imm1 = insn_fetch_bytes(s->op_bytes);
677
1.57k
        s->imm2 = insn_fetch_type(uint16_t);
678
783
        break;
679
680
283
    case 0xa0: case 0xa1: /* mov mem.offs,{%al,%ax,%eax,%rax} */
681
595
    case 0xa2: case 0xa3: /* mov {%al,%ax,%eax,%rax},mem.offs */
682
        /* Source EA is not encoded via ModRM. */
683
595
        s->ea.type = OP_MEM;
684
595
        s->ea.mem.off = insn_fetch_bytes(s->ad_bytes);
685
572
        break;
686
687
2.11k
    case 0xb8 ... 0xbf: /* mov imm{16,32,64},r{16,32,64} */
688
2.11k
        if ( s->op_bytes == 8 ) /* Fetch more bytes to obtain imm64. */
689
207
            s->imm1 = ((uint32_t)s->imm1 |
690
411
                       ((uint64_t)insn_fetch_type(uint32_t) << 32));
691
2.11k
        break;
692
693
2.11k
    case 0xc8: /* enter imm16,imm8 */
694
1.19k
        s->imm2 = insn_fetch_type(uint8_t);
695
1.19k
        break;
696
697
8.02k
    case 0xf6: case 0xf7: /* Grp3 */
698
8.02k
        if ( !(s->modrm_reg & 6) ) /* test */
699
437
            s->desc = (s->desc & ByteOp) | DstNone | SrcMem;
700
8.02k
        break;
701
702
3.38k
    case 0xff: /* Grp5 */
703
3.38k
        switch ( s->modrm_reg & 7 )
704
3.38k
        {
705
232
        case 2: /* call (near) */
706
986
        case 4: /* jmp (near) */
707
986
            if ( mode_64bit() && (s->op_bytes == 4 || !amd_like(ctxt)) )
708
328
                s->op_bytes = 8;
709
986
            s->desc = DstNone | SrcMem | Mov;
710
986
            break;
711
712
363
        case 3: /* call (far, absolute indirect) */
713
467
        case 5: /* jmp (far, absolute indirect) */
714
            /* REX.W ignored on a vendor-dependent basis. */
715
467
            if ( s->op_bytes == 8 && amd_like(ctxt) )
716
75
                s->op_bytes = 4;
717
467
            s->desc = DstNone | SrcMem | Mov;
718
467
            break;
719
720
593
        case 6: /* push */
721
593
            if ( mode_64bit() && s->op_bytes == 4 )
722
203
                s->op_bytes = 8;
723
593
            s->desc = DstNone | SrcMem | Mov;
724
593
            break;
725
3.38k
        }
726
3.38k
        break;
727
290k
    }
728
729
290k
 done:
730
290k
    return rc;
731
290k
}
732
733
static int
734
decode_twobyte(struct x86_emulate_state *s,
735
               struct x86_emulate_ctxt *ctxt,
736
               const struct x86_emulate_ops *ops)
737
160k
{
738
160k
    int rc = X86EMUL_OKAY;
739
740
160k
    switch ( ctxt->opcode & X86EMUL_OPC_MASK )
741
160k
    {
742
2.35k
    case 0x00: /* Grp6 */
743
2.35k
        switch ( s->modrm_reg & 6 )
744
2.35k
        {
745
874
        case 0:
746
874
            s->desc |= DstMem | SrcImplicit | Mov;
747
874
            break;
748
12
        case 6:
749
12
            if ( !(s->modrm_reg & 1) && mode_64bit() )
750
7
            {
751
1.48k
        case 2: case 4:
752
1.48k
                s->desc |= SrcMem16;
753
1.48k
            }
754
1.48k
            break;
755
2.35k
        }
756
2.35k
        break;
757
758
2.35k
    case 0x78:
759
10
        s->desc = ImplicitOps;
760
10
        s->simd_size = simd_none;
761
10
        switch ( s->vex.pfx )
762
10
        {
763
4
        case vex_66: /* extrq $imm8, $imm8, xmm */
764
8
        case vex_f2: /* insertq $imm8, $imm8, xmm, xmm */
765
13
            s->imm1 = insn_fetch_type(uint8_t);
766
13
            s->imm2 = insn_fetch_type(uint8_t);
767
8
            break;
768
10
        }
769
        /* fall through */
770
4.96k
    case 0x10 ... 0x18:
771
10.9k
    case 0x28 ... 0x2f:
772
31.3k
    case 0x50 ... 0x77:
773
31.6k
    case 0x7a ... 0x7d:
774
32.1k
    case 0x7f:
775
32.9k
    case 0xc2 ... 0xc3:
776
33.3k
    case 0xc5 ... 0xc6:
777
48.5k
    case 0xd0 ... 0xef:
778
53.9k
    case 0xf1 ... 0xfe:
779
53.9k
        ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
780
53.9k
        break;
781
782
456
    case 0x20: case 0x22: /* mov to/from cr */
783
456
        if ( s->lock_prefix && vcpu_has_cr8_legacy() && s->modrm_reg == 0 )
784
1
        {
785
1
            s->modrm_reg = 8;
786
1
            s->lock_prefix = false;
787
1
        }
788
456
        fallthrough;
789
460
    case 0x21: case 0x23: /* mov to/from dr */
790
460
        ASSERT(s->ea.type == OP_REG); /* Early operand adjustment ensures this. */
791
460
        generate_exception_if(s->lock_prefix, X86_EXC_UD);
792
460
        s->op_bytes = mode_64bit() ? 8 : 4;
793
459
        break;
794
795
4
    case 0x79:
796
4
        s->desc = DstReg | SrcMem;
797
4
        s->simd_size = simd_packed_int;
798
4
        ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
799
4
        break;
800
801
340
    case 0x7e:
802
340
        ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
803
340
        if ( s->vex.pfx == vex_f3 ) /* movq xmm/m64,xmm */
804
66
        {
805
261
    case X86EMUL_OPC_VEX_F3(0, 0x7e): /* vmovq xmm/m64,xmm */
806
271
    case X86EMUL_OPC_EVEX_F3(0, 0x7e): /* vmovq xmm/m64,xmm */
807
271
            s->desc = DstImplicit | SrcMem | TwoOp;
808
271
            s->simd_size = simd_other;
809
            /* Avoid the s->desc clobbering of TwoOp below. */
810
271
            return X86EMUL_OKAY;
811
261
        }
812
274
        break;
813
814
274
    case X86EMUL_OPC_VEX(0, 0x90):    /* kmov{w,q} */
815
2
    case X86EMUL_OPC_VEX_66(0, 0x90): /* kmov{b,d} */
816
2
        s->desc = DstReg | SrcMem | Mov;
817
2
        s->simd_size = simd_other;
818
2
        break;
819
820
1
    case X86EMUL_OPC_VEX(0, 0x91):    /* kmov{w,q} */
821
3
    case X86EMUL_OPC_VEX_66(0, 0x91): /* kmov{b,d} */
822
3
        s->desc = DstMem | SrcReg | Mov;
823
3
        s->simd_size = simd_other;
824
3
        break;
825
826
668
    case 0xae:
827
668
        ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
828
        /* fall through */
829
734
    case X86EMUL_OPC_VEX(0, 0xae):
830
734
        switch ( s->modrm_reg & 7 )
831
734
        {
832
111
        case 2: /* {,v}ldmxcsr */
833
111
            s->desc = DstImplicit | SrcMem | Mov;
834
111
            s->op_bytes = 4;
835
111
            break;
836
837
182
        case 3: /* {,v}stmxcsr */
838
182
            s->desc = DstMem | SrcImplicit | Mov;
839
182
            s->op_bytes = 4;
840
182
            break;
841
734
        }
842
734
        break;
843
844
734
    case 0xb2: /* lss */
845
328
    case 0xb4: /* lfs */
846
528
    case 0xb5: /* lgs */
847
        /* REX.W ignored on a vendor-dependent basis. */
848
528
        if ( s->op_bytes == 8 && amd_like(ctxt) )
849
13
            s->op_bytes = 4;
850
528
        break;
851
852
417
    case 0xb8: /* jmpe / popcnt */
853
417
        if ( s->vex.pfx >= vex_f3 )
854
416
            ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
855
417
        break;
856
857
        /* Intentionally not handling here despite being modified by F3:
858
    case 0xbc: bsf / tzcnt
859
    case 0xbd: bsr / lzcnt
860
         * They're being dealt with in the execution phase (if at all).
861
         */
862
863
588
    case 0xc4: /* pinsrw */
864
588
        ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
865
        /* fall through */
866
626
    case X86EMUL_OPC_VEX_66(0, 0xc4): /* vpinsrw */
867
630
    case X86EMUL_OPC_EVEX_66(0, 0xc4): /* vpinsrw */
868
630
        s->desc = DstImplicit | SrcMem16;
869
630
        break;
870
871
69
    case 0xf0:
872
69
        ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
873
69
        if ( s->vex.pfx == vex_f2 ) /* lddqu mem,xmm */
874
67
        {
875
        /* fall through */
876
133
    case X86EMUL_OPC_VEX_F2(0, 0xf0): /* vlddqu mem,{x,y}mm */
877
133
            s->desc = DstImplicit | SrcMem | TwoOp;
878
133
            s->simd_size = simd_other;
879
            /* Avoid the s->desc clobbering of TwoOp below. */
880
133
            return X86EMUL_OKAY;
881
67
        }
882
2
        break;
883
160k
    }
884
885
    /*
886
     * Scalar forms of most VEX-/EVEX-encoded TwoOp instructions have
887
     * three operands.  Those which do really have two operands
888
     * should have exited earlier.
889
     */
890
160k
    if ( s->simd_size && s->vex.opcx &&
891
24.6k
         (s->vex.pfx & VEX_PREFIX_SCALAR_MASK) )
892
6.56k
        s->desc &= ~TwoOp;
893
894
160k
 done:
895
160k
    return rc;
896
160k
}
897
898
static int
899
decode_0f38(struct x86_emulate_state *s,
900
            struct x86_emulate_ctxt *ctxt,
901
            const struct x86_emulate_ops *ops)
902
27.7k
{
903
27.7k
    switch ( ctxt->opcode & X86EMUL_OPC_MASK )
904
27.7k
    {
905
10.1k
    case 0x00 ... 0x89:
906
10.5k
    case 0x8c ... 0xef:
907
10.5k
    case 0xf2 ... 0xf5:
908
10.5k
    case 0xf7 ... 0xf8:
909
10.5k
    case 0xfa ... 0xff:
910
10.5k
        s->op_bytes = 0;
911
        /* fall through */
912
11.4k
    case 0xf6: /* adcx / adox */
913
11.4k
    case 0xf9: /* movdiri */
914
11.4k
        ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
915
11.4k
        break;
916
917
4
    case 0x8a ... 0x8b: /* movrs */
918
4
        s->desc = DstReg | SrcMem | Mov;
919
4
        if ( !(ctxt->opcode & 1) )
920
2
            s->desc |= ByteOp;
921
4
        s->simd_size = simd_none;
922
4
        break;
923
924
198
    case X86EMUL_OPC_VEX_66(0, 0x2d): /* vmaskmovpd */
925
198
        s->simd_size = simd_packed_fp;
926
198
        break;
927
928
2
    case X86EMUL_OPC_EVEX_66(0, 0x7a): /* vpbroadcastb */
929
4
    case X86EMUL_OPC_EVEX_66(0, 0x7b): /* vpbroadcastw */
930
10
    case X86EMUL_OPC_EVEX_66(0, 0x7c): /* vpbroadcast{d,q} */
931
10
        break;
932
933
193
    case 0xf0: /* movbe / crc32 */
934
193
        s->desc |= s->vex.pfx == vex_f2 ? ByteOp : Mov;
935
193
        if ( s->vex.pfx >= vex_f3 )
936
124
            ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
937
193
        break;
938
939
733
    case 0xf1: /* movbe / crc32 */
940
733
        if ( s->vex.pfx == vex_f2 )
941
117
            s->desc = DstReg | SrcMem;
942
733
        if ( s->vex.pfx >= vex_f3 )
943
118
            ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
944
733
        break;
945
946
33
    case X86EMUL_OPC_VEX_66(0, 0xe0) ...
947
33
         X86EMUL_OPC_VEX_66(0, 0xef): /* cmp<cc>xadd */
948
107
    case X86EMUL_OPC_VEX(0, 0xf2):    /* andn */
949
248
    case X86EMUL_OPC_VEX(0, 0xf3):    /* Grp 17 */
950
448
    case X86EMUL_OPC_VEX(0, 0xf5):    /* bzhi */
951
517
    case X86EMUL_OPC_VEX_F3(0, 0xf5): /* pext */
952
595
    case X86EMUL_OPC_VEX_F2(0, 0xf5): /* pdep */
953
859
    case X86EMUL_OPC_VEX_F2(0, 0xf6): /* mulx */
954
1.06k
    case X86EMUL_OPC_VEX(0, 0xf7):    /* bextr */
955
1.19k
    case X86EMUL_OPC_VEX_66(0, 0xf7): /* shlx */
956
1.26k
    case X86EMUL_OPC_VEX_F3(0, 0xf7): /* sarx */
957
2.03k
    case X86EMUL_OPC_VEX_F2(0, 0xf7): /* shrx */
958
2.03k
        break;
959
960
13.1k
    default:
961
13.1k
        s->op_bytes = 0;
962
13.1k
        break;
963
27.7k
    }
964
965
27.7k
    return X86EMUL_OKAY;
966
27.7k
}
967
968
static int
969
decode_0f3a(struct x86_emulate_state *s,
970
            struct x86_emulate_ctxt *ctxt,
971
            const struct x86_emulate_ops *ops)
972
10.5k
{
973
10.5k
    if ( !s->vex.opcx )
974
3.84k
        ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
975
976
10.5k
    switch ( ctxt->opcode & X86EMUL_OPC_MASK )
977
10.5k
    {
978
1.14k
    case X86EMUL_OPC_66(0, 0x14)
979
1.14k
     ... X86EMUL_OPC_66(0, 0x17):     /* pextr*, extractps */
980
1.94k
    case X86EMUL_OPC_VEX_66(0, 0x14)
981
1.94k
     ... X86EMUL_OPC_VEX_66(0, 0x17): /* vpextr*, vextractps */
982
1.95k
    case X86EMUL_OPC_EVEX_66(0, 0x14)
983
1.95k
     ... X86EMUL_OPC_EVEX_66(0, 0x17): /* vpextr*, vextractps */
984
2.11k
    case X86EMUL_OPC_VEX_F2(0, 0xf0): /* rorx */
985
2.11k
        break;
986
987
337
    case X86EMUL_OPC_66(0, 0x20):     /* pinsrb */
988
738
    case X86EMUL_OPC_VEX_66(0, 0x20): /* vpinsrb */
989
740
    case X86EMUL_OPC_EVEX_66(0, 0x20): /* vpinsrb */
990
740
        s->desc = DstImplicit | SrcMem;
991
740
        if ( s->modrm_mod != 3 )
992
390
            s->desc |= ByteOp;
993
740
        break;
994
995
70
    case X86EMUL_OPC_66(0, 0x22):     /* pinsr{d,q} */
996
458
    case X86EMUL_OPC_VEX_66(0, 0x22): /* vpinsr{d,q} */
997
459
    case X86EMUL_OPC_EVEX_66(0, 0x22): /* vpinsr{d,q} */
998
459
        s->desc = DstImplicit | SrcMem;
999
459
        break;
1000
1001
7.22k
    default:
1002
7.22k
        s->op_bytes = 0;
1003
7.22k
        break;
1004
10.5k
    }
1005
1006
10.5k
    return X86EMUL_OKAY;
1007
10.5k
}
1008
1009
646k
#define ad_bytes (s->ad_bytes) /* for truncate_ea() */
1010
1011
int x86emul_decode(struct x86_emulate_state *s,
1012
                   struct x86_emulate_ctxt *ctxt,
1013
                   const struct x86_emulate_ops *ops)
1014
500k
{
1015
500k
    uint8_t b, d;
1016
500k
    unsigned int def_op_bytes, def_ad_bytes, opcode;
1017
500k
    enum x86_segment override_seg = x86_seg_none;
1018
500k
    bool pc_rel = false;
1019
500k
    int rc = X86EMUL_OKAY;
1020
1021
500k
    ASSERT(ops->insn_fetch);
1022
1023
500k
    memset(s, 0, sizeof(*s));
1024
500k
    s->ea.type = OP_NONE;
1025
500k
    s->ea.mem.seg = x86_seg_ds;
1026
500k
    s->ea.reg = PTR_POISON;
1027
500k
    s->ip = ctxt->regs->r(ip);
1028
1029
500k
    s->op_bytes = def_op_bytes = ad_bytes = def_ad_bytes =
1030
500k
        ctxt->addr_size / 8;
1031
500k
    if ( s->op_bytes == 8 )
1032
126k
    {
1033
126k
        s->op_bytes = def_op_bytes = 4;
1034
#ifndef __x86_64__
1035
        return X86EMUL_UNHANDLEABLE;
1036
#endif
1037
126k
    }
1038
1039
    /* Prefix bytes. */
1040
500k
    for ( ; ; )
1041
615k
    {
1042
1.22M
        switch ( b = insn_fetch_type(uint8_t) )
1043
1.22M
        {
1044
44.6k
        case 0x66: /* operand-size override */
1045
44.6k
            s->op_bytes = def_op_bytes ^ 6;
1046
44.6k
            if ( !s->vex.pfx )
1047
40.3k
                s->vex.pfx = vex_66;
1048
44.6k
            break;
1049
5.83k
        case 0x67: /* address-size override */
1050
5.83k
            ad_bytes = def_ad_bytes ^ (mode_64bit() ? 12 : 6);
1051
5.83k
            break;
1052
3.08k
        case 0x26: /* ES override */
1053
4.45k
        case 0x2e: /* CS override */
1054
5.13k
        case 0x36: /* SS override */
1055
5.88k
        case 0x3e: /* DS override, all ignored in 64-bit mode */
1056
5.88k
            if ( !mode_64bit() )
1057
4.15k
                override_seg = (b >> 3) & 3;
1058
5.88k
            break;
1059
1.40k
        case 0x64: /* FS override */
1060
1.40k
            override_seg = x86_seg_fs;
1061
1.40k
            break;
1062
2.14k
        case 0x65: /* GS override */
1063
2.14k
            override_seg = x86_seg_gs;
1064
2.14k
            break;
1065
920
        case 0xf0: /* LOCK */
1066
920
            s->lock_prefix = true;
1067
920
            break;
1068
16.1k
        case 0xf2: /* REPNE/REPNZ */
1069
16.1k
            s->vex.pfx = vex_f2;
1070
16.1k
            break;
1071
13.7k
        case 0xf3: /* REP/REPE/REPZ */
1072
13.7k
            s->vex.pfx = vex_f3;
1073
13.7k
            break;
1074
58.1k
        case 0x40 ... 0x4f: /* REX */
1075
58.1k
            if ( !mode_64bit() )
1076
33.6k
                goto done_prefixes;
1077
24.5k
            s->rex_prefix = b;
1078
24.5k
            continue;
1079
459k
        default:
1080
459k
            goto done_prefixes;
1081
1.22M
        }
1082
1083
        /* Any legacy prefix after a REX prefix nullifies its effect. */
1084
90.6k
        s->rex_prefix = 0;
1085
90.6k
    }
1086
492k
 done_prefixes:
1087
1088
492k
    if ( s->rex_prefix & REX_W )
1089
16.4k
        s->op_bytes = 8;
1090
1091
    /* Opcode byte(s). */
1092
492k
    d = opcode_table[b];
1093
492k
    if ( b == 0x0f )
1094
148k
    {
1095
        /* Two-byte opcode. */
1096
296k
        b = insn_fetch_type(uint8_t);
1097
296k
        d = twobyte_table[b].desc;
1098
296k
        switch ( b )
1099
296k
        {
1100
132k
        default:
1101
132k
            opcode = b | MASK_INSR(0x0f, X86EMUL_OPC_EXT_MASK);
1102
132k
            s->ext = ext_0f;
1103
132k
            s->simd_size = twobyte_table[b].size;
1104
132k
            break;
1105
12.3k
        case 0x38:
1106
12.3k
            b = insn_fetch_type(uint8_t);
1107
12.3k
            opcode = b | MASK_INSR(0x0f38, X86EMUL_OPC_EXT_MASK);
1108
12.3k
            s->ext = ext_0f38;
1109
12.3k
            break;
1110
3.84k
        case 0x3a:
1111
7.68k
            b = insn_fetch_type(uint8_t);
1112
7.68k
            opcode = b | MASK_INSR(0x0f3a, X86EMUL_OPC_EXT_MASK);
1113
7.68k
            s->ext = ext_0f3a;
1114
7.68k
            break;
1115
296k
        }
1116
296k
    }
1117
344k
    else
1118
344k
        opcode = b;
1119
1120
    /* ModRM and SIB bytes. */
1121
492k
    if ( d & ModRM )
1122
321k
    {
1123
640k
        s->modrm = insn_fetch_type(uint8_t);
1124
640k
        s->modrm_mod = (s->modrm & 0xc0) >> 6;
1125
1126
640k
        if ( !s->ext && ((b & ~1) == 0xc4 || (b == 0x8f && (s->modrm & 0x18)) ||
1127
131k
                         b == 0x62) )
1128
53.4k
            switch ( def_ad_bytes )
1129
53.4k
            {
1130
0
            default:
1131
0
                ASSERT_UNREACHABLE(); /* Shouldn't be possible. */
1132
0
                return X86EMUL_UNHANDLEABLE;
1133
1134
24.2k
            case 2:
1135
24.2k
                if ( ctxt->regs->eflags & X86_EFLAGS_VM )
1136
806
                    break;
1137
                /* fall through */
1138
31.5k
            case 4:
1139
31.5k
                if ( s->modrm_mod != 3 || in_realmode(ctxt, ops) )
1140
941
                    break;
1141
                /* fall through */
1142
51.7k
            case 8:
1143
                /* VEX / XOP / EVEX */
1144
51.7k
                generate_exception_if(s->rex_prefix || s->vex.pfx, X86_EXC_UD);
1145
                /*
1146
                 * With operand size override disallowed (see above), op_bytes
1147
                 * should not have changed from its default.
1148
                 */
1149
51.7k
                ASSERT(s->op_bytes == def_op_bytes);
1150
1151
51.7k
                s->vex.raw[0] = s->modrm;
1152
51.7k
                if ( b == 0xc5 )
1153
27.5k
                {
1154
27.5k
                    opcode = X86EMUL_OPC_VEX_;
1155
27.5k
                    s->vex.raw[1] = s->modrm;
1156
27.5k
                    s->vex.opcx = vex_0f;
1157
27.5k
                    s->vex.x = 1;
1158
27.5k
                    s->vex.b = 1;
1159
27.5k
                    s->vex.w = 0;
1160
27.5k
                }
1161
24.1k
                else
1162
24.1k
                {
1163
48.2k
                    s->vex.raw[1] = insn_fetch_type(uint8_t);
1164
48.2k
                    if ( mode_64bit() )
1165
11.1k
                    {
1166
11.1k
                        if ( !s->vex.b )
1167
6.09k
                            s->rex_prefix |= REX_B;
1168
11.1k
                        if ( !s->vex.x )
1169
2.57k
                            s->rex_prefix |= REX_X;
1170
11.1k
                        if ( s->vex.w )
1171
2.53k
                        {
1172
2.53k
                            s->rex_prefix |= REX_W;
1173
2.53k
                            s->op_bytes = 8;
1174
2.53k
                        }
1175
11.1k
                    }
1176
13.0k
                    else
1177
13.0k
                    {
1178
                        /* Operand size fixed at 4 (no override via W bit). */
1179
13.0k
                        s->op_bytes = 4;
1180
13.0k
                        s->vex.b = 1;
1181
13.0k
                    }
1182
48.2k
                    switch ( b )
1183
48.2k
                    {
1184
1.32k
                    case 0x62:
1185
1.32k
                        opcode = X86EMUL_OPC_EVEX_;
1186
1.32k
                        s->evex.raw[0] = s->vex.raw[0];
1187
1.32k
                        s->evex.raw[1] = s->vex.raw[1];
1188
2.64k
                        s->evex.raw[2] = insn_fetch_type(uint8_t);
1189
1190
2.64k
                        generate_exception_if(!s->evex.mbs || s->evex.mbz, X86_EXC_UD);
1191
2.64k
                        generate_exception_if(!s->evex.opmsk && s->evex.z, X86_EXC_UD);
1192
1193
1.31k
                        if ( !mode_64bit() )
1194
51
                            s->evex.R = 1;
1195
1196
1.30k
                        s->vex.opcx = s->evex.opcx;
1197
1.30k
                        break;
1198
22.6k
                    case 0xc4:
1199
22.6k
                        opcode = X86EMUL_OPC_VEX_;
1200
22.6k
                        break;
1201
161
                    default:
1202
161
                        opcode = 0;
1203
161
                        break;
1204
48.2k
                    }
1205
48.2k
                }
1206
51.6k
                if ( !s->vex.r )
1207
8.12k
                    s->rex_prefix |= REX_R;
1208
1209
51.6k
                s->ext = s->vex.opcx;
1210
51.6k
                if ( b != 0x8f )
1211
51.5k
                {
1212
102k
                    b = insn_fetch_type(uint8_t);
1213
102k
                    switch ( s->ext )
1214
102k
                    {
1215
29.0k
                    case vex_0f:
1216
29.0k
                        opcode |= MASK_INSR(0x0f, X86EMUL_OPC_EXT_MASK);
1217
29.0k
                        d = twobyte_table[b].desc;
1218
29.0k
                        s->simd_size = twobyte_table[b].size;
1219
29.0k
                        break;
1220
15.4k
                    case vex_0f38:
1221
15.4k
                        opcode |= MASK_INSR(0x0f38, X86EMUL_OPC_EXT_MASK);
1222
15.4k
                        d = twobyte_table[0x38].desc;
1223
15.4k
                        break;
1224
6.70k
                    case vex_0f3a:
1225
6.70k
                        opcode |= MASK_INSR(0x0f3a, X86EMUL_OPC_EXT_MASK);
1226
6.70k
                        d = twobyte_table[0x3a].desc;
1227
6.70k
                        break;
1228
1229
150
                    case evex_map5:
1230
150
                        if ( !evex_encoded() )
1231
1
                        {
1232
3
                    default:
1233
3
                            rc = X86EMUL_UNRECOGNIZED;
1234
3
                            goto done;
1235
1
                        }
1236
149
                        opcode |= MASK_INSR(5, X86EMUL_OPC_EXT_MASK);
1237
                        /*
1238
                         * Re-use twobyte_table[] here, for the similarity of
1239
                         * the entries valid in map 5.
1240
                         */
1241
149
                        d = twobyte_table[b].desc;
1242
149
                        s->simd_size = twobyte_table[b].size ?: simd_other;
1243
149
                        break;
1244
1245
133
                    case evex_map6:
1246
133
                        if ( !evex_encoded() )
1247
1
                        {
1248
1
                            rc = X86EMUL_UNRECOGNIZED;
1249
1
                            goto done;
1250
1
                        }
1251
132
                        opcode |= MASK_INSR(6, X86EMUL_OPC_EXT_MASK);
1252
                        /*
1253
                         * Re-use twobyte_table[]'s 0x38 entry here, for the
1254
                         * similarity of the 0F38 entries with map 6.
1255
                         */
1256
132
                        d = twobyte_table[0x38].desc;
1257
132
                        break;
1258
102k
                    }
1259
102k
                }
1260
161
                else if ( s->ext < ext_8f08 + ARRAY_SIZE(xop_table) )
1261
157
                {
1262
310
                    b = insn_fetch_type(uint8_t);
1263
310
                    opcode |= MASK_INSR(0x8f08 + s->ext - ext_8f08,
1264
310
                                        X86EMUL_OPC_EXT_MASK);
1265
310
                    d = array_access_nospec(xop_table, s->ext - ext_8f08);
1266
310
                }
1267
4
                else
1268
4
                {
1269
4
                    rc = X86EMUL_UNRECOGNIZED;
1270
4
                    goto done;
1271
4
                }
1272
1273
51.5k
                opcode |= b | MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
1274
1275
51.5k
                if ( !evex_encoded() )
1276
50.2k
                    s->evex.lr = s->vex.l;
1277
1278
51.5k
                if ( !(d & ModRM) )
1279
430
                    break;
1280
1281
102k
                s->modrm = insn_fetch_type(uint8_t);
1282
102k
                s->modrm_mod = (s->modrm & 0xc0) >> 6;
1283
1284
102k
                break;
1285
53.4k
            }
1286
640k
    }
1287
1288
490k
    if ( d & ModRM )
1289
318k
    {
1290
318k
        unsigned int disp8scale = 0;
1291
1292
318k
        d &= ~ModRM;
1293
318k
#undef ModRM /* Only its aliases are valid to use from here on. */
1294
318k
        s->modrm_reg = ((s->rex_prefix & 4) << 1) | ((s->modrm & 0x38) >> 3) |
1295
318k
                       ((evex_encoded() && !s->evex.R) << 4);
1296
318k
        s->modrm_rm  = s->modrm & 0x07;
1297
1298
        /*
1299
         * Early operand adjustments. Only ones affecting further processing
1300
         * prior to the x86_decode_*() calls really belong here. That would
1301
         * normally be only addition/removal of SrcImm/SrcImm16, so their
1302
         * fetching can be taken care of by the common code below.
1303
         */
1304
318k
        switch ( s->ext )
1305
318k
        {
1306
131k
        case ext_none:
1307
131k
            switch ( b )
1308
131k
            {
1309
8.03k
            case 0xf6 ... 0xf7: /* Grp3 */
1310
8.03k
                switch ( s->modrm_reg & 7 )
1311
8.03k
                {
1312
449
                case 0 ... 1: /* test */
1313
449
                    d |= DstMem | SrcImm;
1314
449
                    break;
1315
209
                case 2: /* not */
1316
877
                case 3: /* neg */
1317
877
                    d |= DstMem;
1318
877
                    break;
1319
2.17k
                case 4: /* mul */
1320
4.08k
                case 5: /* imul */
1321
5.03k
                case 6: /* div */
1322
6.71k
                case 7: /* idiv */
1323
                    /*
1324
                     * DstEax isn't really precise for all cases; updates to
1325
                     * rDX get handled in an open coded manner.
1326
                     */
1327
6.71k
                    d |= DstEax | SrcMem;
1328
6.71k
                    break;
1329
8.03k
                }
1330
8.03k
                break;
1331
131k
            }
1332
131k
            break;
1333
1334
148k
        case ext_0f:
1335
148k
            if ( evex_encoded() )
1336
410
                disp8scale = decode_disp8scale(twobyte_table[b].d8s, s);
1337
1338
148k
            switch ( b )
1339
148k
            {
1340
1.18k
            case 0x12: /* vmovsldup / vmovddup */
1341
1.18k
                if ( s->evex.pfx == vex_f2 )
1342
2
                    disp8scale = s->evex.lr ? 4 + s->evex.lr : 3;
1343
                /* fall through */
1344
2.40k
            case 0x16: /* vmovshdup */
1345
2.40k
                if ( s->evex.pfx == vex_f3 )
1346
3
                    disp8scale = 4 + s->evex.lr;
1347
2.40k
                break;
1348
1349
207
            case 0x20: /* mov cr,reg */
1350
210
            case 0x21: /* mov dr,reg */
1351
459
            case 0x22: /* mov reg,cr */
1352
461
            case 0x23: /* mov reg,dr */
1353
                /*
1354
                 * Mov to/from cr/dr ignore the encoding of Mod, and behave as
1355
                 * if they were encoded as reg/reg instructions.  No further
1356
                 * disp/SIB bytes are fetched.
1357
                 */
1358
461
                s->modrm_mod = 3;
1359
461
                break;
1360
1361
17
            case 0x78:
1362
28
            case 0x79:
1363
28
                if ( !s->evex.pfx )
1364
17
                    break;
1365
                /* vcvt{,t}ps2uqq need special casing */
1366
11
                if ( s->evex.pfx == vex_66 )
1367
7
                {
1368
7
                    if ( !s->evex.w && !s->evex.brs )
1369
2
                        --disp8scale;
1370
7
                    break;
1371
7
                }
1372
                /* vcvt{,t}s{s,d}2usi need special casing. */
1373
4
                fallthrough;
1374
1.69k
            case 0x2c: /* vcvtts{s,d}2si need special casing */
1375
3.36k
            case 0x2d: /* vcvts{s,d}2si need special casing */
1376
3.36k
                if ( evex_encoded() )
1377
14
                    disp8scale = 2 + (s->evex.pfx & VEX_PREFIX_DOUBLE_MASK);
1378
3.36k
                break;
1379
1380
1.19k
            case 0x5a: /* vcvtps2pd needs special casing */
1381
1.19k
                if ( disp8scale && !s->evex.pfx && !s->evex.brs )
1382
2
                    --disp8scale;
1383
1.19k
                break;
1384
1385
18
            case 0x7a: /* vcvttps2qq and vcvtudq2pd need special casing */
1386
18
                if ( disp8scale && s->evex.pfx != vex_f2 && !s->evex.w && !s->evex.brs )
1387
3
                    --disp8scale;
1388
18
                break;
1389
1390
10
            case 0x7b: /* vcvtp{s,d}2qq need special casing */
1391
10
                if ( disp8scale && s->evex.pfx == vex_66 )
1392
2
                    disp8scale = (s->evex.brs ? 2 : 3 + s->evex.lr) + s->evex.w;
1393
10
                break;
1394
1395
815
            case 0x7e: /* vmovq xmm/m64,xmm needs special casing */
1396
815
                if ( disp8scale == 2 && s->evex.pfx == vex_f3 )
1397
7
                    disp8scale = 3;
1398
815
                break;
1399
1400
541
            case 0xe6: /* vcvtdq2pd needs special casing */
1401
541
                if ( disp8scale && s->evex.pfx == vex_f3 && !s->evex.w && !s->evex.brs )
1402
2
                    --disp8scale;
1403
541
                break;
1404
148k
            }
1405
148k
            break;
1406
1407
148k
        case ext_0f38:
1408
27.7k
            d = ext0f38_table[b].to_mem ? DstMem | SrcReg
1409
27.7k
                                        : DstReg | SrcMem;
1410
27.7k
            if ( ext0f38_table[b].two_op )
1411
8.43k
                d |= TwoOp;
1412
27.7k
            if ( ext0f38_table[b].vsib )
1413
806
                d |= vSIB;
1414
27.7k
            s->simd_size = ext0f38_table[b].simd_size;
1415
27.7k
            if ( evex_encoded() )
1416
366
            {
1417
                /*
1418
                 * VPMOVUS* are identical to VPMOVS* Disp8-scaling-wise, but
1419
                 * their attributes don't match those of the vex_66 encoded
1420
                 * insns with the same base opcodes. Rather than adding new
1421
                 * columns to the table, handle this here for now.
1422
                 */
1423
366
                if ( s->evex.pfx != vex_f3 || (b & 0xf8) != 0x10 )
1424
359
                    disp8scale = decode_disp8scale(ext0f38_table[b].d8s, s);
1425
7
                else
1426
7
                {
1427
7
                    disp8scale = decode_disp8scale(ext0f38_table[b ^ 0x30].d8s,
1428
7
                                                   s);
1429
7
                    s->simd_size = simd_other;
1430
7
                }
1431
366
            }
1432
27.7k
            break;
1433
1434
10.5k
        case ext_0f3a:
1435
            /*
1436
             * Cannot update d here yet, as the immediate operand still
1437
             * needs fetching.
1438
             */
1439
10.5k
            s->simd_size = ext0f3a_table[b].simd_size;
1440
10.5k
            if ( evex_encoded() )
1441
202
            {
1442
202
                switch ( b )
1443
202
                {
1444
3
                case 0x08: /* vrndscaleph */
1445
10
                case 0x0a: /* vrndscalesh */
1446
13
                case 0x26: /* vfpclassph */
1447
16
                case 0x27: /* vfpclasssh */
1448
19
                case 0x56: /* vgetmantph */
1449
22
                case 0x57: /* vgetmantsh */
1450
25
                case 0x66: /* vreduceph */
1451
28
                case 0x67: /* vreducesh */
1452
28
                    if ( !s->evex.pfx )
1453
14
                        s->fp16 = true;
1454
28
                    break;
1455
1456
6
                case 0xc2: /* vpcmp{p,s}h */
1457
6
                    if ( !(s->evex.pfx & VEX_PREFIX_DOUBLE_MASK) )
1458
5
                        s->fp16 = true;
1459
6
                    break;
1460
202
                }
1461
1462
202
                disp8scale = decode_disp8scale(ext0f3a_table[b].d8s, s);
1463
202
            }
1464
10.5k
            break;
1465
1466
10.5k
        case ext_map5:
1467
115
            switch ( b )
1468
115
            {
1469
72
            default:
1470
72
                if ( !(s->evex.pfx & VEX_PREFIX_DOUBLE_MASK) )
1471
47
                    s->fp16 = true;
1472
72
                break;
1473
1474
3
            case 0x1d: /* vcvtps2phx / vcvtss2sh */
1475
3
                if ( s->evex.pfx & VEX_PREFIX_SCALAR_MASK )
1476
1
                    break;
1477
2
                d = DstReg | SrcMem;
1478
2
                if ( s->evex.pfx & VEX_PREFIX_DOUBLE_MASK )
1479
1
                {
1480
1
                    s->simd_size = simd_packed_fp;
1481
1
                    d |= TwoOp;
1482
1
                }
1483
1
                else
1484
1
                    s->simd_size = simd_scalar_vexw;
1485
2
                break;
1486
1487
1
            case 0x2a: /* vcvtsi2sh */
1488
1
                break;
1489
1490
5
            case 0x2c: case 0x2d: /* vcvt{,t}sh2si */
1491
5
                if ( s->evex.pfx == vex_f3 )
1492
2
                    s->fp16 = true;
1493
5
                break;
1494
1495
5
            case 0x2e: case 0x2f: /* v{,u}comish */
1496
5
                if ( !s->evex.pfx )
1497
2
                    s->fp16 = true;
1498
5
                s->simd_size = simd_none;
1499
5
                break;
1500
1501
4
            case 0x5b: /* vcvt{d,q}q2ph, vcvt{,t}ph2dq */
1502
4
                if ( s->evex.pfx && s->evex.pfx != vex_f2 )
1503
2
                    s->fp16 = true;
1504
4
                break;
1505
1506
2
            case 0x6e: /* vmovw r/m16, xmm */
1507
2
                d = (d & ~SrcMask) | SrcMem16;
1508
                /* fall through */
1509
6
            case 0x7e: /* vmovw xmm, r/m16 */
1510
6
                if ( s->evex.pfx == vex_66 )
1511
3
                    s->fp16 = true;
1512
6
                s->simd_size = simd_none;
1513
6
                break;
1514
1515
7
            case 0x78: case 0x79: /* vcvt{,t}ph2u{d,q}q, vcvt{,t}sh2usi */
1516
7
                if ( s->evex.pfx != vex_f2 )
1517
6
                    s->fp16 = true;
1518
7
                break;
1519
1520
3
            case 0x7a: /* vcvttph2qq, vcvtu{d,q}q2ph */
1521
6
            case 0x7b: /* vcvtph2qq, vcvtusi2sh */
1522
6
                if ( s->evex.pfx == vex_66 )
1523
3
                    s->fp16 = true;
1524
6
                break;
1525
1526
2
            case 0x7c: /* vcvttph2{,u}w */
1527
6
            case 0x7d: /* vcvtph2{,u}w / vcvt{,u}w2ph */
1528
6
                d = DstReg | SrcMem | TwoOp;
1529
6
                s->fp16 = true;
1530
6
                break;
1531
115
            }
1532
1533
            /* Like above re-use twobyte_table[] here. */
1534
115
            disp8scale = decode_disp8scale(twobyte_table[b].d8s, s);
1535
1536
115
            switch ( b )
1537
115
            {
1538
4
            case 0x78:
1539
7
            case 0x79:
1540
                /* vcvt{,t}ph2u{d,q}q need special casing */
1541
7
                if ( s->evex.pfx <= vex_66 )
1542
4
                {
1543
4
                    if ( !s->evex.brs )
1544
1
                        disp8scale -= 1 + (s->evex.pfx == vex_66);
1545
4
                    break;
1546
4
                }
1547
                /* vcvt{,t}sh2usi needs special casing. */
1548
3
                fallthrough;
1549
8
            case 0x2c: case 0x2d: /* vcvt{,t}sh2si need special casing */
1550
8
                disp8scale = 1;
1551
8
                break;
1552
1553
8
            case 0x5a: /* vcvtph2pd needs special casing */
1554
8
                if ( !s->evex.pfx && !s->evex.brs )
1555
1
                    disp8scale -= 2;
1556
8
                break;
1557
1558
4
            case 0x5b: /* vcvt{,t}ph2dq need special casing */
1559
4
                if ( s->evex.pfx && !s->evex.brs )
1560
1
                    --disp8scale;
1561
4
                break;
1562
1563
6
            case 0x7a: case 0x7b: /* vcvt{,t}ph2qq need special casing */
1564
6
                if ( s->evex.pfx == vex_66 && !s->evex.brs )
1565
1
                    disp8scale = s->evex.brs ? 1 : 2 + s->evex.lr;
1566
6
                break;
1567
115
            }
1568
1569
115
            break;
1570
1571
131
        case ext_map6:
1572
            /*
1573
             * Re-use ext0f38_table[] here, for the similarity of the entries
1574
             * valid in map 6.
1575
             */
1576
131
            d = ext0f38_table[b].to_mem ? DstMem | SrcReg
1577
131
                                        : DstReg | SrcMem;
1578
131
            if ( ext0f38_table[b].two_op )
1579
25
                d |= TwoOp;
1580
131
            s->simd_size = ext0f38_table[b].simd_size ?: simd_other;
1581
1582
131
            switch ( b )
1583
131
            {
1584
118
            default:
1585
118
                if ( s->evex.pfx == vex_66 )
1586
64
                    s->fp16 = true;
1587
118
                break;
1588
1589
3
            case 0x13: /* vcvtph2psx / vcvtsh2ss */
1590
3
                if ( s->evex.pfx & VEX_PREFIX_SCALAR_MASK )
1591
1
                    break;
1592
2
                s->fp16 = true;
1593
2
                if ( !(s->evex.pfx & VEX_PREFIX_DOUBLE_MASK) )
1594
1
                {
1595
1
                    s->simd_size = simd_scalar_vexw;
1596
1
                    d &= ~TwoOp;
1597
1
                }
1598
2
                break;
1599
1600
6
            case 0x56: case 0x57: /* vf{,c}maddc{p,s}h */
1601
10
            case 0xd6: case 0xd7: /* vf{,c}mulc{p,s}h */
1602
10
                break;
1603
131
            }
1604
1605
131
            disp8scale = decode_disp8scale(ext0f38_table[b].d8s, s);
1606
131
            break;
1607
1608
82
        case ext_8f09:
1609
82
            if ( ext8f09_table[b].two_op )
1610
32
                d |= TwoOp;
1611
82
            s->simd_size = ext8f09_table[b].simd_size;
1612
82
            break;
1613
1614
54
        case ext_8f08:
1615
71
        case ext_8f0a:
1616
            /*
1617
             * Cannot update d here yet, as the immediate operand still
1618
             * needs fetching.
1619
             */
1620
71
            break;
1621
1622
0
        default:
1623
0
            ASSERT_UNREACHABLE();
1624
0
            return X86EMUL_UNIMPLEMENTED;
1625
318k
        }
1626
1627
318k
        if ( s->modrm_mod == 3 )
1628
179k
        {
1629
179k
            generate_exception_if(d & vSIB, X86_EXC_UD);
1630
179k
            s->modrm_rm |= ((s->rex_prefix & 1) << 3) |
1631
179k
                           ((evex_encoded() && !s->evex.x) << 4);
1632
179k
            s->ea.type = OP_REG;
1633
179k
        }
1634
139k
        else if ( ad_bytes == 2 )
1635
84.6k
        {
1636
            /* 16-bit ModR/M decode. */
1637
84.6k
            generate_exception_if(d & vSIB, X86_EXC_UD);
1638
84.6k
            s->ea.type = OP_MEM;
1639
84.6k
            switch ( s->modrm_rm )
1640
84.6k
            {
1641
30.7k
            case 0:
1642
30.7k
                s->ea.mem.off = ctxt->regs->bx + ctxt->regs->si;
1643
30.7k
                break;
1644
8.99k
            case 1:
1645
8.99k
                s->ea.mem.off = ctxt->regs->bx + ctxt->regs->di;
1646
8.99k
                break;
1647
7.83k
            case 2:
1648
7.83k
                s->ea.mem.seg = x86_seg_ss;
1649
7.83k
                s->ea.mem.off = ctxt->regs->bp + ctxt->regs->si;
1650
7.83k
                break;
1651
7.72k
            case 3:
1652
7.72k
                s->ea.mem.seg = x86_seg_ss;
1653
7.72k
                s->ea.mem.off = ctxt->regs->bp + ctxt->regs->di;
1654
7.72k
                break;
1655
6.09k
            case 4:
1656
6.09k
                s->ea.mem.off = ctxt->regs->si;
1657
6.09k
                break;
1658
7.09k
            case 5:
1659
7.09k
                s->ea.mem.off = ctxt->regs->di;
1660
7.09k
                break;
1661
5.68k
            case 6:
1662
5.68k
                if ( s->modrm_mod == 0 )
1663
1.68k
                    break;
1664
3.99k
                s->ea.mem.seg = x86_seg_ss;
1665
3.99k
                s->ea.mem.off = ctxt->regs->bp;
1666
3.99k
                break;
1667
10.5k
            case 7:
1668
10.5k
                s->ea.mem.off = ctxt->regs->bx;
1669
10.5k
                break;
1670
84.6k
            }
1671
84.6k
            switch ( s->modrm_mod )
1672
84.6k
            {
1673
58.4k
            case 0:
1674
58.4k
                if ( s->modrm_rm == 6 )
1675
1.68k
                    s->ea.mem.off = insn_fetch_type(int16_t);
1676
58.4k
                break;
1677
58.4k
            case 1:
1678
19.5k
                s->ea.mem.off += insn_fetch_type(int8_t) * (1 << disp8scale);
1679
19.5k
                break;
1680
6.66k
            case 2:
1681
13.3k
                s->ea.mem.off += insn_fetch_type(int16_t);
1682
13.3k
                break;
1683
84.6k
            }
1684
84.6k
        }
1685
54.7k
        else
1686
54.7k
        {
1687
            /* 32/64-bit ModR/M decode. */
1688
54.7k
            s->ea.type = OP_MEM;
1689
54.7k
            if ( s->modrm_rm == 4 )
1690
6.15k
            {
1691
12.3k
                uint8_t sib = insn_fetch_type(uint8_t);
1692
12.3k
                uint8_t sib_base = (sib & 7) | ((s->rex_prefix << 3) & 8);
1693
1694
12.3k
                s->sib_index = ((sib >> 3) & 7) | ((s->rex_prefix << 2) & 8);
1695
12.3k
                s->sib_scale = (sib >> 6) & 3;
1696
12.3k
                if ( unlikely(d & vSIB) )
1697
803
                    s->sib_index |= (mode_64bit() && evex_encoded() &&
1698
21
                                     !s->evex.RX) << 4;
1699
5.34k
                else if ( s->sib_index != 4 )
1700
4.61k
                {
1701
4.61k
                    s->ea.mem.off = *decode_gpr(ctxt->regs, s->sib_index);
1702
4.61k
                    s->ea.mem.off <<= s->sib_scale;
1703
4.61k
                }
1704
12.3k
                if ( (s->modrm_mod == 0) && ((sib_base & 7) == 5) )
1705
236
                    s->ea.mem.off += insn_fetch_type(int32_t);
1706
5.91k
                else if ( sib_base == 4 )
1707
2.14k
                {
1708
2.14k
                    s->ea.mem.seg  = x86_seg_ss;
1709
2.14k
                    s->ea.mem.off += ctxt->regs->r(sp);
1710
2.14k
                    if ( !s->ext && (b == 0x8f) )
1711
                        /* POP <rm> computes its EA post increment. */
1712
887
                        s->ea.mem.off += ((mode_64bit() && (s->op_bytes == 4))
1713
887
                                       ? 8 : s->op_bytes);
1714
2.14k
                }
1715
3.76k
                else if ( sib_base == 5 )
1716
295
                {
1717
295
                    s->ea.mem.seg  = x86_seg_ss;
1718
295
                    s->ea.mem.off += ctxt->regs->r(bp);
1719
295
                }
1720
3.47k
                else
1721
3.47k
                    s->ea.mem.off += *decode_gpr(ctxt->regs, sib_base);
1722
12.3k
            }
1723
48.5k
            else
1724
48.5k
            {
1725
48.5k
                generate_exception_if(d & vSIB, X86_EXC_UD);
1726
48.5k
                s->modrm_rm |= (s->rex_prefix & 1) << 3;
1727
48.5k
                s->ea.mem.off = *decode_gpr(ctxt->regs, s->modrm_rm);
1728
48.5k
                if ( (s->modrm_rm == 5) && (s->modrm_mod != 0) )
1729
2.06k
                    s->ea.mem.seg = x86_seg_ss;
1730
48.5k
            }
1731
54.7k
            switch ( s->modrm_mod )
1732
54.7k
            {
1733
39.3k
            case 0:
1734
39.3k
                if ( (s->modrm_rm & 7) != 5 )
1735
38.2k
                    break;
1736
1.07k
                s->ea.mem.off = insn_fetch_type(int32_t);
1737
1.07k
                pc_rel = mode_64bit();
1738
1.07k
                break;
1739
13.6k
            case 1:
1740
13.6k
                s->ea.mem.off += insn_fetch_type(int8_t) * (1 << disp8scale);
1741
13.5k
                break;
1742
1.76k
            case 2:
1743
3.51k
                s->ea.mem.off += insn_fetch_type(int32_t);
1744
3.51k
                break;
1745
54.7k
            }
1746
54.7k
        }
1747
318k
    }
1748
172k
    else
1749
172k
    {
1750
172k
        s->modrm_mod = 0xff;
1751
172k
        s->modrm_reg = s->modrm_rm = s->modrm = 0;
1752
172k
    }
1753
1754
490k
    if ( override_seg != x86_seg_none )
1755
5.64k
        s->ea.mem.seg = override_seg;
1756
1757
    /* Fetch the immediate operand, if present. */
1758
490k
    switch ( d & SrcMask )
1759
490k
    {
1760
0
        unsigned int bytes;
1761
1762
23.3k
    case SrcImm:
1763
23.3k
        if ( !(d & ByteOp) )
1764
12.8k
        {
1765
12.8k
            if ( mode_64bit() && !amd_like(ctxt) &&
1766
0
                 ((s->ext == ext_none && (b | 1) == 0xe9) /* call / jmp */ ||
1767
0
                  (s->ext == ext_0f && (b | 0xf) == 0x8f) /* jcc */ ) )
1768
0
                s->op_bytes = 4;
1769
12.8k
            bytes = s->op_bytes != 8 ? s->op_bytes : 4;
1770
12.8k
        }
1771
10.4k
        else
1772
10.4k
        {
1773
46.4k
    case SrcImmByte:
1774
46.4k
            bytes = 1;
1775
46.4k
        }
1776
        /* NB. Immediates are sign-extended as necessary. */
1777
59.2k
        switch ( bytes )
1778
59.2k
        {
1779
46.4k
        case 1: s->imm1 = insn_fetch_type(int8_t);  break;
1780
7.33k
        case 2: s->imm1 = insn_fetch_type(int16_t); break;
1781
10.9k
        case 4: s->imm1 = insn_fetch_type(int32_t); break;
1782
59.2k
        }
1783
59.0k
        break;
1784
59.0k
    case SrcImm16:
1785
2.88k
        s->imm1 = insn_fetch_type(uint16_t);
1786
2.88k
        break;
1787
490k
    }
1788
1789
490k
    ctxt->opcode = opcode;
1790
490k
    s->desc = d;
1791
1792
490k
    switch ( s->ext )
1793
490k
    {
1794
290k
    case ext_none:
1795
290k
        rc = decode_onebyte(s, ctxt, ops);
1796
290k
        break;
1797
1798
160k
    case ext_0f:
1799
160k
        rc = decode_twobyte(s, ctxt, ops);
1800
160k
        break;
1801
1802
27.7k
    case ext_0f38:
1803
27.7k
        rc = decode_0f38(s, ctxt, ops);
1804
27.7k
        break;
1805
1806
10.5k
    case ext_0f3a:
1807
10.5k
        d = ext0f3a_table[b].to_mem ? DstMem | SrcReg : DstReg | SrcMem;
1808
10.5k
        if ( ext0f3a_table[b].two_op )
1809
5.48k
            d |= TwoOp;
1810
5.05k
        else if ( ext0f3a_table[b].four_op && !mode_64bit() && s->vex.opcx )
1811
512
            s->imm1 &= 0x7f;
1812
10.5k
        s->desc = d;
1813
10.5k
        rc = decode_0f3a(s, ctxt, ops);
1814
10.5k
        break;
1815
1816
53
    case ext_8f08:
1817
53
        d = DstReg | SrcMem;
1818
53
        if ( ext8f08_table[b].two_op )
1819
4
            d |= TwoOp;
1820
49
        else if ( ext8f08_table[b].four_op && !mode_64bit() )
1821
7
            s->imm1 &= 0x7f;
1822
53
        s->desc = d;
1823
53
        s->simd_size = ext8f08_table[b].simd_size;
1824
53
        break;
1825
1826
147
    case ext_map5:
1827
278
    case ext_map6:
1828
360
    case ext_8f09:
1829
376
    case ext_8f0a:
1830
376
        break;
1831
1832
0
    default:
1833
0
        ASSERT_UNREACHABLE();
1834
0
        return X86EMUL_UNIMPLEMENTED;
1835
490k
    }
1836
1837
490k
    if ( s->ea.type == OP_MEM )
1838
139k
    {
1839
139k
        if ( pc_rel )
1840
860
            s->ea.mem.off += s->ip;
1841
1842
139k
        s->ea.mem.off = truncate_ea(s->ea.mem.off);
1843
139k
    }
1844
1845
    /*
1846
     * Simple op_bytes calculations. More complicated cases produce 0
1847
     * and are further handled during execute.
1848
     */
1849
490k
    switch ( s->simd_size )
1850
490k
    {
1851
384k
    case simd_none:
1852
        /*
1853
         * When prefix 66 has a meaning different from operand-size override,
1854
         * operand size defaults to 4 and can't be overridden to 2.
1855
         */
1856
384k
        if ( s->op_bytes == 2 &&
1857
219k
             (ctxt->opcode & X86EMUL_OPC_PFX_MASK) == X86EMUL_OPC_66(0, 0) )
1858
3.88k
            s->op_bytes = 4;
1859
384k
        break;
1860
1861
0
#ifndef X86EMUL_NO_SIMD
1862
43.7k
    case simd_packed_int:
1863
43.7k
        switch ( s->vex.pfx )
1864
43.7k
        {
1865
13.7k
        case vex_np:
1866
13.7k
            if ( !s->vex.opcx )
1867
13.5k
            {
1868
13.5k
                s->op_bytes = 8;
1869
13.5k
                break;
1870
13.5k
            }
1871
            /* fall through */
1872
29.3k
        case vex_66:
1873
29.3k
            s->op_bytes = 16 << s->evex.lr;
1874
29.3k
            break;
1875
722
        default:
1876
722
            s->op_bytes = 0;
1877
722
            break;
1878
43.7k
        }
1879
43.7k
        break;
1880
1881
43.7k
    case simd_single_fp:
1882
1.36k
        if ( s->vex.pfx & VEX_PREFIX_DOUBLE_MASK )
1883
5
        {
1884
5
            s->op_bytes = 0;
1885
5
            break;
1886
13.8k
    case simd_packed_fp:
1887
13.8k
            if ( s->vex.pfx & VEX_PREFIX_SCALAR_MASK )
1888
783
            {
1889
783
                s->op_bytes = 0;
1890
783
                break;
1891
783
            }
1892
13.8k
        }
1893
        /* fall through */
1894
30.2k
    case simd_any_fp:
1895
30.2k
        switch ( s->vex.pfx )
1896
30.2k
        {
1897
23.0k
        default:
1898
23.0k
            s->op_bytes = 16 << s->evex.lr;
1899
23.0k
            break;
1900
3.59k
        case vex_f3:
1901
3.59k
            generate_exception_if(evex_encoded() && s->evex.w, X86_EXC_UD);
1902
3.59k
            s->op_bytes = 4 >> s->fp16;
1903
3.58k
            break;
1904
3.58k
        case vex_f2:
1905
3.58k
            generate_exception_if(evex_encoded() && !s->evex.w, X86_EXC_UD);
1906
3.58k
            s->op_bytes = 8;
1907
3.58k
            break;
1908
30.2k
        }
1909
30.2k
        break;
1910
1911
30.2k
    case simd_scalar_opc:
1912
846
        s->op_bytes = 2 << (!s->fp16 + (ctxt->opcode & 1));
1913
846
        break;
1914
1915
1.60k
    case simd_scalar_vexw:
1916
1.60k
        s->op_bytes = 2 << (!s->fp16 + s->vex.w);
1917
1.60k
        break;
1918
1919
5.28k
    case simd_128:
1920
        /* The special cases here are MMX shift insns. */
1921
5.28k
        s->op_bytes = s->vex.opcx || s->vex.pfx ? 16 : 8;
1922
5.28k
        break;
1923
1924
27
    case simd_256:
1925
27
        s->op_bytes = 32;
1926
27
        break;
1927
0
#endif /* !X86EMUL_NO_SIMD */
1928
1929
22.8k
    default:
1930
22.8k
        s->op_bytes = 0;
1931
22.8k
        break;
1932
490k
    }
1933
1934
500k
 done:
1935
500k
    return rc;
1936
490k
}