debuggers.hg

view xen/arch/x86/x86_emulate/x86_emulate.c @ 17962:6685c412698f

x86_emulate: (Almost) complete FPU emulation.

Provide emulation for all FPU instructions except fsave/frstore &
fnstenv/fldenv.

While the main purpose of the patch is to avoid current and future
"gotchas" on FPU intructions used by various OS boot-loaders, it is
complete enough to run DOS realmode FPU applications and benchmarks,
but don't expect to set any speed records.

Signed-off-by: Trolle Selander <trolle.selander@eu.citrix.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jul 01 13:27:41 2008 +0100 (2008-07-01)
parents c33a40b4c22b
children 2e4ecfc83460
line source
1 /******************************************************************************
2 * x86_emulate.c
3 *
4 * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
5 *
6 * Copyright (c) 2005-2007 Keir Fraser
7 * Copyright (c) 2005-2007 XenSource Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
24 /* Operand sizes: 8-bit operands or specified/overridden size. */
25 #define ByteOp (1<<0) /* 8-bit operands. */
26 /* Destination operand type. */
27 #define DstBitBase (0<<1) /* Memory operand, bit string. */
28 #define ImplicitOps (1<<1) /* Implicit in opcode. No generic decode. */
29 #define DstReg (2<<1) /* Register operand. */
30 #define DstMem (3<<1) /* Memory operand. */
31 #define DstMask (3<<1)
32 /* Source operand type. */
33 #define SrcNone (0<<3) /* No source operand. */
34 #define SrcImplicit (0<<3) /* Source operand is implicit in the opcode. */
35 #define SrcReg (1<<3) /* Register operand. */
36 #define SrcMem (2<<3) /* Memory operand. */
37 #define SrcMem16 (3<<3) /* Memory operand (16-bit). */
38 #define SrcImm (4<<3) /* Immediate operand. */
39 #define SrcImmByte (5<<3) /* 8-bit sign-extended immediate operand. */
40 #define SrcMask (7<<3)
41 /* Generic ModRM decode. */
42 #define ModRM (1<<6)
43 /* Destination is only written; never read. */
44 #define Mov (1<<7)
46 static uint8_t opcode_table[256] = {
47 /* 0x00 - 0x07 */
48 ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
49 ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
50 ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, ImplicitOps,
51 /* 0x08 - 0x0F */
52 ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
53 ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
54 ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, 0,
55 /* 0x10 - 0x17 */
56 ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
57 ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
58 ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, ImplicitOps,
59 /* 0x18 - 0x1F */
60 ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
61 ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
62 ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, ImplicitOps,
63 /* 0x20 - 0x27 */
64 ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
65 ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
66 ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,
67 /* 0x28 - 0x2F */
68 ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
69 ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
70 ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,
71 /* 0x30 - 0x37 */
72 ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
73 ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
74 ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,
75 /* 0x38 - 0x3F */
76 ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
77 ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
78 ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,
79 /* 0x40 - 0x4F */
80 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
81 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
82 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
83 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
84 /* 0x50 - 0x5F */
85 ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
86 ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
87 ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
88 ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
89 /* 0x60 - 0x67 */
90 ImplicitOps, ImplicitOps, DstReg|SrcMem|ModRM, DstReg|SrcMem16|ModRM|Mov,
91 0, 0, 0, 0,
92 /* 0x68 - 0x6F */
93 ImplicitOps|Mov, DstReg|SrcImm|ModRM|Mov,
94 ImplicitOps|Mov, DstReg|SrcImmByte|ModRM|Mov,
95 ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
96 /* 0x70 - 0x77 */
97 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
98 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
99 /* 0x78 - 0x7F */
100 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
101 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
102 /* 0x80 - 0x87 */
103 ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
104 ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM,
105 ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
106 ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
107 /* 0x88 - 0x8F */
108 ByteOp|DstMem|SrcReg|ModRM|Mov, DstMem|SrcReg|ModRM|Mov,
109 ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
110 DstMem|SrcReg|ModRM|Mov, DstReg|SrcNone|ModRM,
111 DstReg|SrcMem|ModRM|Mov, DstMem|SrcNone|ModRM|Mov,
112 /* 0x90 - 0x97 */
113 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
114 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
115 /* 0x98 - 0x9F */
116 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
117 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
118 /* 0xA0 - 0xA7 */
119 ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
120 ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
121 ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
122 ByteOp|ImplicitOps, ImplicitOps,
123 /* 0xA8 - 0xAF */
124 ByteOp|DstReg|SrcImm, DstReg|SrcImm,
125 ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
126 ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
127 ByteOp|ImplicitOps, ImplicitOps,
128 /* 0xB0 - 0xB7 */
129 ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,
130 ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,
131 ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,
132 ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov,
133 /* 0xB8 - 0xBF */
134 DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov,
135 DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov,
136 /* 0xC0 - 0xC7 */
137 ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM,
138 ImplicitOps, ImplicitOps,
139 DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
140 ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov,
141 /* 0xC8 - 0xCF */
142 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
143 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
144 /* 0xD0 - 0xD7 */
145 ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM,
146 ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM,
147 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
148 /* 0xD8 - 0xDF */
149 ImplicitOps|ModRM|Mov, ImplicitOps|ModRM|Mov,
150 ImplicitOps|ModRM|Mov, ImplicitOps|ModRM|Mov,
151 ImplicitOps|ModRM|Mov, ImplicitOps|ModRM|Mov,
152 ImplicitOps|ModRM|Mov, ImplicitOps|ModRM|Mov,
153 /* 0xE0 - 0xE7 */
154 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
155 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
156 /* 0xE8 - 0xEF */
157 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
158 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
159 /* 0xF0 - 0xF7 */
160 0, ImplicitOps, 0, 0,
161 ImplicitOps, ImplicitOps,
162 ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM,
163 /* 0xF8 - 0xFF */
164 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
165 ImplicitOps, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM
166 };
168 static uint8_t twobyte_table[256] = {
169 /* 0x00 - 0x07 */
170 0, ImplicitOps|ModRM, 0, 0, 0, 0, ImplicitOps, 0,
171 /* 0x08 - 0x0F */
172 ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps|ModRM, 0, 0,
173 /* 0x10 - 0x17 */
174 0, 0, 0, 0, 0, 0, 0, 0,
175 /* 0x18 - 0x1F */
176 ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM,
177 ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM,
178 /* 0x20 - 0x27 */
179 ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM,
180 0, 0, 0, 0,
181 /* 0x28 - 0x2F */
182 0, 0, 0, 0, 0, 0, 0, 0,
183 /* 0x30 - 0x37 */
184 ImplicitOps, ImplicitOps, ImplicitOps, 0, 0, 0, 0, 0,
185 /* 0x38 - 0x3F */
186 0, 0, 0, 0, 0, 0, 0, 0,
187 /* 0x40 - 0x47 */
188 DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
189 DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
190 DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
191 DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
192 /* 0x48 - 0x4F */
193 DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
194 DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
195 DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
196 DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
197 /* 0x50 - 0x5F */
198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
199 /* 0x60 - 0x6F */
200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM,
201 /* 0x70 - 0x7F */
202 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM,
203 /* 0x80 - 0x87 */
204 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
205 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
206 /* 0x88 - 0x8F */
207 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
208 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
209 /* 0x90 - 0x97 */
210 ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
211 ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
212 ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
213 ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
214 /* 0x98 - 0x9F */
215 ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
216 ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
217 ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
218 ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov,
219 /* 0xA0 - 0xA7 */
220 ImplicitOps, ImplicitOps, ImplicitOps, DstBitBase|SrcReg|ModRM,
221 DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0,
222 /* 0xA8 - 0xAF */
223 ImplicitOps, ImplicitOps, 0, DstBitBase|SrcReg|ModRM,
224 DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, DstReg|SrcMem|ModRM,
225 /* 0xB0 - 0xB7 */
226 ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
227 DstReg|SrcMem|ModRM|Mov, DstBitBase|SrcReg|ModRM,
228 DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
229 ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
230 /* 0xB8 - 0xBF */
231 0, 0, DstBitBase|SrcImmByte|ModRM, DstBitBase|SrcReg|ModRM,
232 DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
233 ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
234 /* 0xC0 - 0xC7 */
235 ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0,
236 0, 0, 0, ImplicitOps|ModRM,
237 /* 0xC8 - 0xCF */
238 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
239 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
240 /* 0xD0 - 0xDF */
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
242 /* 0xE0 - 0xEF */
243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
244 /* 0xF0 - 0xFF */
245 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
246 };
248 /* Type, address-of, and value of an instruction's operand. */
249 struct operand {
250 enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;
251 unsigned int bytes;
253 /* Up to 128-byte operand value, addressable as ulong or uint32_t[]. */
254 union {
255 unsigned long val;
256 uint32_t bigval[4];
257 };
259 /* Up to 128-byte operand value, addressable as ulong or uint32_t[]. */
260 union {
261 unsigned long orig_val;
262 uint32_t orig_bigval[4];
263 };
265 union {
266 /* OP_REG: Pointer to register field. */
267 unsigned long *reg;
268 /* OP_MEM: Segment and offset. */
269 struct {
270 enum x86_segment seg;
271 unsigned long off;
272 } mem;
273 };
274 };
276 /* MSRs. */
277 #define MSR_TSC 0x10
279 /* Control register flags. */
280 #define CR0_PE (1<<0)
281 #define CR4_TSD (1<<2)
283 /* EFLAGS bit definitions. */
284 #define EFLG_VIP (1<<20)
285 #define EFLG_VIF (1<<19)
286 #define EFLG_AC (1<<18)
287 #define EFLG_VM (1<<17)
288 #define EFLG_RF (1<<16)
289 #define EFLG_NT (1<<14)
290 #define EFLG_IOPL (3<<12)
291 #define EFLG_OF (1<<11)
292 #define EFLG_DF (1<<10)
293 #define EFLG_IF (1<<9)
294 #define EFLG_TF (1<<8)
295 #define EFLG_SF (1<<7)
296 #define EFLG_ZF (1<<6)
297 #define EFLG_AF (1<<4)
298 #define EFLG_PF (1<<2)
299 #define EFLG_CF (1<<0)
301 /* Exception definitions. */
302 #define EXC_DE 0
303 #define EXC_DB 1
304 #define EXC_BP 3
305 #define EXC_OF 4
306 #define EXC_BR 5
307 #define EXC_UD 6
308 #define EXC_TS 10
309 #define EXC_NP 11
310 #define EXC_SS 12
311 #define EXC_GP 13
312 #define EXC_PF 14
313 #define EXC_MF 16
315 /*
316 * Instruction emulation:
317 * Most instructions are emulated directly via a fragment of inline assembly
318 * code. This allows us to save/restore EFLAGS and thus very easily pick up
319 * any modified flags.
320 */
322 #if defined(__x86_64__)
323 #define _LO32 "k" /* force 32-bit operand */
324 #define _STK "%%rsp" /* stack pointer */
325 #define _BYTES_PER_LONG "8"
326 #elif defined(__i386__)
327 #define _LO32 "" /* force 32-bit operand */
328 #define _STK "%%esp" /* stack pointer */
329 #define _BYTES_PER_LONG "4"
330 #endif
332 /*
333 * These EFLAGS bits are restored from saved value during emulation, and
334 * any changes are written back to the saved value after emulation.
335 */
336 #define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF)
338 /* Before executing instruction: restore necessary bits in EFLAGS. */
339 #define _PRE_EFLAGS(_sav, _msk, _tmp) \
340 /* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \
341 "movl %"_sav",%"_LO32 _tmp"; " \
342 "push %"_tmp"; " \
343 "push %"_tmp"; " \
344 "movl %"_msk",%"_LO32 _tmp"; " \
345 "andl %"_LO32 _tmp",("_STK"); " \
346 "pushf; " \
347 "notl %"_LO32 _tmp"; " \
348 "andl %"_LO32 _tmp",("_STK"); " \
349 "andl %"_LO32 _tmp",2*"_BYTES_PER_LONG"("_STK"); " \
350 "pop %"_tmp"; " \
351 "orl %"_LO32 _tmp",("_STK"); " \
352 "popf; " \
353 "pop %"_sav"; "
355 /* After executing instruction: write-back necessary bits in EFLAGS. */
356 #define _POST_EFLAGS(_sav, _msk, _tmp) \
357 /* _sav |= EFLAGS & _msk; */ \
358 "pushf; " \
359 "pop %"_tmp"; " \
360 "andl %"_msk",%"_LO32 _tmp"; " \
361 "orl %"_LO32 _tmp",%"_sav"; "
363 /* Raw emulation: instruction has two explicit operands. */
364 #define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy)\
365 do{ unsigned long _tmp; \
366 switch ( (_dst).bytes ) \
367 { \
368 case 2: \
369 asm volatile ( \
370 _PRE_EFLAGS("0","4","2") \
371 _op"w %"_wx"3,%1; " \
372 _POST_EFLAGS("0","4","2") \
373 : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
374 : _wy ((_src).val), "i" (EFLAGS_MASK), \
375 "m" (_eflags), "m" ((_dst).val) ); \
376 break; \
377 case 4: \
378 asm volatile ( \
379 _PRE_EFLAGS("0","4","2") \
380 _op"l %"_lx"3,%1; " \
381 _POST_EFLAGS("0","4","2") \
382 : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
383 : _ly ((_src).val), "i" (EFLAGS_MASK), \
384 "m" (_eflags), "m" ((_dst).val) ); \
385 break; \
386 case 8: \
387 __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy); \
388 break; \
389 } \
390 } while (0)
391 #define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy)\
392 do{ unsigned long _tmp; \
393 switch ( (_dst).bytes ) \
394 { \
395 case 1: \
396 asm volatile ( \
397 _PRE_EFLAGS("0","4","2") \
398 _op"b %"_bx"3,%1; " \
399 _POST_EFLAGS("0","4","2") \
400 : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
401 : _by ((_src).val), "i" (EFLAGS_MASK), \
402 "m" (_eflags), "m" ((_dst).val) ); \
403 break; \
404 default: \
405 __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy);\
406 break; \
407 } \
408 } while (0)
409 /* Source operand is byte-sized and may be restricted to just %cl. */
410 #define emulate_2op_SrcB(_op, _src, _dst, _eflags) \
411 __emulate_2op(_op, _src, _dst, _eflags, \
412 "b", "c", "b", "c", "b", "c", "b", "c")
413 /* Source operand is byte, word, long or quad sized. */
414 #define emulate_2op_SrcV(_op, _src, _dst, _eflags) \
415 __emulate_2op(_op, _src, _dst, _eflags, \
416 "b", "q", "w", "r", _LO32, "r", "", "r")
417 /* Source operand is word, long or quad sized. */
418 #define emulate_2op_SrcV_nobyte(_op, _src, _dst, _eflags) \
419 __emulate_2op_nobyte(_op, _src, _dst, _eflags, \
420 "w", "r", _LO32, "r", "", "r")
422 /* Instruction has only one explicit operand (no source operand). */
423 #define emulate_1op(_op,_dst,_eflags) \
424 do{ unsigned long _tmp; \
425 switch ( (_dst).bytes ) \
426 { \
427 case 1: \
428 asm volatile ( \
429 _PRE_EFLAGS("0","3","2") \
430 _op"b %1; " \
431 _POST_EFLAGS("0","3","2") \
432 : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
433 : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) ); \
434 break; \
435 case 2: \
436 asm volatile ( \
437 _PRE_EFLAGS("0","3","2") \
438 _op"w %1; " \
439 _POST_EFLAGS("0","3","2") \
440 : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
441 : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) ); \
442 break; \
443 case 4: \
444 asm volatile ( \
445 _PRE_EFLAGS("0","3","2") \
446 _op"l %1; " \
447 _POST_EFLAGS("0","3","2") \
448 : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
449 : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) ); \
450 break; \
451 case 8: \
452 __emulate_1op_8byte(_op, _dst, _eflags); \
453 break; \
454 } \
455 } while (0)
457 /* Emulate an instruction with quadword operands (x86/64 only). */
458 #if defined(__x86_64__)
459 #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) \
460 do{ asm volatile ( \
461 _PRE_EFLAGS("0","4","2") \
462 _op"q %"_qx"3,%1; " \
463 _POST_EFLAGS("0","4","2") \
464 : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
465 : _qy ((_src).val), "i" (EFLAGS_MASK), \
466 "m" (_eflags), "m" ((_dst).val) ); \
467 } while (0)
468 #define __emulate_1op_8byte(_op, _dst, _eflags) \
469 do{ asm volatile ( \
470 _PRE_EFLAGS("0","3","2") \
471 _op"q %1; " \
472 _POST_EFLAGS("0","3","2") \
473 : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
474 : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) ); \
475 } while (0)
476 #elif defined(__i386__)
477 #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy)
478 #define __emulate_1op_8byte(_op, _dst, _eflags)
479 #endif /* __i386__ */
481 /* Fetch next part of the instruction being emulated. */
482 #define insn_fetch_bytes(_size) \
483 ({ unsigned long _x = 0, _eip = _regs.eip; \
484 if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \
485 _regs.eip += (_size); /* real hardware doesn't truncate */ \
486 generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) > 15, \
487 EXC_GP, 0); \
488 rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt); \
489 if ( rc ) goto done; \
490 _x; \
491 })
492 #define insn_fetch_type(_type) ((_type)insn_fetch_bytes(sizeof(_type)))
494 #define truncate_word(ea, byte_width) \
495 ({ unsigned long __ea = (ea); \
496 unsigned int _width = (byte_width); \
497 ((_width == sizeof(unsigned long)) ? __ea : \
498 (__ea & ((1UL << (_width << 3)) - 1))); \
499 })
500 #define truncate_ea(ea) truncate_word((ea), ad_bytes)
502 #define mode_64bit() (def_ad_bytes == 8)
504 #define fail_if(p) \
505 do { \
506 rc = (p) ? X86EMUL_UNHANDLEABLE : X86EMUL_OKAY; \
507 if ( rc ) goto done; \
508 } while (0)
510 #define generate_exception_if(p, e, ec) \
511 ({ if ( (p) ) { \
512 fail_if(ops->inject_hw_exception == NULL); \
513 rc = ops->inject_hw_exception(e, ec, ctxt) ? : X86EMUL_EXCEPTION; \
514 goto done; \
515 } \
516 })
518 /*
519 * Given byte has even parity (even number of 1s)? SDM Vol. 1 Sec. 3.4.3.1,
520 * "Status Flags": EFLAGS.PF reflects parity of least-sig. byte of result only.
521 */
522 static int even_parity(uint8_t v)
523 {
524 asm ( "test %b0,%b0; setp %b0" : "=a" (v) : "0" (v) );
525 return v;
526 }
528 /* Update address held in a register, based on addressing mode. */
529 #define _register_address_increment(reg, inc, byte_width) \
530 do { \
531 int _inc = (inc); /* signed type ensures sign extension to long */ \
532 unsigned int _width = (byte_width); \
533 if ( _width == sizeof(unsigned long) ) \
534 (reg) += _inc; \
535 else if ( mode_64bit() ) \
536 (reg) = ((reg) + _inc) & ((1UL << (_width << 3)) - 1); \
537 else \
538 (reg) = ((reg) & ~((1UL << (_width << 3)) - 1)) | \
539 (((reg) + _inc) & ((1UL << (_width << 3)) - 1)); \
540 } while (0)
541 #define register_address_increment(reg, inc) \
542 _register_address_increment((reg), (inc), ad_bytes)
544 #define sp_pre_dec(dec) ({ \
545 _register_address_increment(_regs.esp, -(dec), ctxt->sp_size/8); \
546 truncate_word(_regs.esp, ctxt->sp_size/8); \
547 })
548 #define sp_post_inc(inc) ({ \
549 unsigned long __esp = truncate_word(_regs.esp, ctxt->sp_size/8); \
550 _register_address_increment(_regs.esp, (inc), ctxt->sp_size/8); \
551 __esp; \
552 })
554 #define jmp_rel(rel) \
555 do { \
556 int _rel = (int)(rel); \
557 _regs.eip += _rel; \
558 if ( !mode_64bit() ) \
559 _regs.eip = ((op_bytes == 2) \
560 ? (uint16_t)_regs.eip : (uint32_t)_regs.eip); \
561 } while (0)
563 struct fpu_insn_ctxt {
564 uint8_t insn_bytes;
565 uint8_t exn_raised;
566 };
568 static void fpu_handle_exception(void *_fic, struct cpu_user_regs *regs)
569 {
570 struct fpu_insn_ctxt *fic = _fic;
571 fic->exn_raised = 1;
572 regs->eip += fic->insn_bytes;
573 }
575 #define get_fpu(_type, _fic) \
576 do{ (_fic)->exn_raised = 0; \
577 fail_if(ops->get_fpu == NULL); \
578 rc = ops->get_fpu(fpu_handle_exception, _fic, _type, ctxt); \
579 if ( rc ) goto done; \
580 } while (0)
581 #define put_fpu(_fic) \
582 do{ \
583 if ( ops->put_fpu != NULL ) \
584 ops->put_fpu(ctxt); \
585 generate_exception_if((_fic)->exn_raised, EXC_MF, -1); \
586 } while (0)
588 #define emulate_fpu_insn(_op) \
589 do{ struct fpu_insn_ctxt fic; \
590 get_fpu(X86EMUL_FPU_fpu, &fic); \
591 asm volatile ( \
592 "movb $2f-1f,%0 \n" \
593 "1: " _op " \n" \
594 "2: \n" \
595 : "=m" (fic.insn_bytes) : : "memory" ); \
596 put_fpu(&fic); \
597 } while (0)
599 #define emulate_fpu_insn_memdst(_op, _arg) \
600 do{ struct fpu_insn_ctxt fic; \
601 get_fpu(X86EMUL_FPU_fpu, &fic); \
602 asm volatile ( \
603 "movb $2f-1f,%0 \n" \
604 "1: " _op " %1 \n" \
605 "2: \n" \
606 : "=m" (fic.insn_bytes), "=m" (_arg) \
607 : : "memory" ); \
608 put_fpu(&fic); \
609 } while (0)
611 #define emulate_fpu_insn_memsrc(_op, _arg) \
612 do{ struct fpu_insn_ctxt fic; \
613 get_fpu(X86EMUL_FPU_fpu, &fic); \
614 asm volatile ( \
615 "movb $2f-1f,%0 \n" \
616 "1: " _op " %1 \n" \
617 "2: \n" \
618 : "=m" (fic.insn_bytes) \
619 : "m" (_arg) : "memory" ); \
620 put_fpu(&fic); \
621 } while (0)
623 #define emulate_fpu_insn_stub(_bytes...) \
624 do{ uint8_t stub[] = { _bytes, 0xc3 }; \
625 struct fpu_insn_ctxt fic = { .insn_bytes = sizeof(stub)-1 }; \
626 get_fpu(X86EMUL_FPU_fpu, &fic); \
627 (*(void(*)(void))stub)(); \
628 put_fpu(&fic); \
629 } while (0)
631 static unsigned long __get_rep_prefix(
632 struct cpu_user_regs *int_regs,
633 struct cpu_user_regs *ext_regs,
634 int ad_bytes)
635 {
636 unsigned long ecx = ((ad_bytes == 2) ? (uint16_t)int_regs->ecx :
637 (ad_bytes == 4) ? (uint32_t)int_regs->ecx :
638 int_regs->ecx);
640 /* Skip the instruction if no repetitions are required. */
641 if ( ecx == 0 )
642 ext_regs->eip = int_regs->eip;
644 return ecx;
645 }
647 #define get_rep_prefix() ({ \
648 unsigned long max_reps = 1; \
649 if ( rep_prefix ) \
650 max_reps = __get_rep_prefix(&_regs, ctxt->regs, ad_bytes); \
651 if ( max_reps == 0 ) \
652 goto done; \
653 max_reps; \
654 })
656 static void __put_rep_prefix(
657 struct cpu_user_regs *int_regs,
658 struct cpu_user_regs *ext_regs,
659 int ad_bytes,
660 unsigned long reps_completed)
661 {
662 unsigned long ecx = ((ad_bytes == 2) ? (uint16_t)int_regs->ecx :
663 (ad_bytes == 4) ? (uint32_t)int_regs->ecx :
664 int_regs->ecx);
666 /* Reduce counter appropriately, and repeat instruction if non-zero. */
667 ecx -= reps_completed;
668 if ( ecx != 0 )
669 int_regs->eip = ext_regs->eip;
671 if ( ad_bytes == 2 )
672 *(uint16_t *)&int_regs->ecx = ecx;
673 else if ( ad_bytes == 4 )
674 int_regs->ecx = (uint32_t)ecx;
675 else
676 int_regs->ecx = ecx;
677 }
679 #define put_rep_prefix(reps_completed) ({ \
680 if ( rep_prefix ) \
681 __put_rep_prefix(&_regs, ctxt->regs, ad_bytes, reps_completed); \
682 })
684 /* Compatibility function: read guest memory, zero-extend result to a ulong. */
685 static int read_ulong(
686 enum x86_segment seg,
687 unsigned long offset,
688 unsigned long *val,
689 unsigned int bytes,
690 struct x86_emulate_ctxt *ctxt,
691 struct x86_emulate_ops *ops)
692 {
693 *val = 0;
694 return ops->read(seg, offset, val, bytes, ctxt);
695 }
697 /*
698 * Unsigned multiplication with double-word result.
699 * IN: Multiplicand=m[0], Multiplier=m[1]
700 * OUT: Return CF/OF (overflow status); Result=m[1]:m[0]
701 */
702 static int mul_dbl(unsigned long m[2])
703 {
704 int rc;
705 asm ( "mul %4; seto %b2"
706 : "=a" (m[0]), "=d" (m[1]), "=q" (rc)
707 : "0" (m[0]), "1" (m[1]), "2" (0) );
708 return rc;
709 }
711 /*
712 * Signed multiplication with double-word result.
713 * IN: Multiplicand=m[0], Multiplier=m[1]
714 * OUT: Return CF/OF (overflow status); Result=m[1]:m[0]
715 */
716 static int imul_dbl(unsigned long m[2])
717 {
718 int rc;
719 asm ( "imul %4; seto %b2"
720 : "=a" (m[0]), "=d" (m[1]), "=q" (rc)
721 : "0" (m[0]), "1" (m[1]), "2" (0) );
722 return rc;
723 }
725 /*
726 * Unsigned division of double-word dividend.
727 * IN: Dividend=u[1]:u[0], Divisor=v
728 * OUT: Return 1: #DE
729 * Return 0: Quotient=u[0], Remainder=u[1]
730 */
731 static int div_dbl(unsigned long u[2], unsigned long v)
732 {
733 if ( (v == 0) || (u[1] >= v) )
734 return 1;
735 asm ( "div %4"
736 : "=a" (u[0]), "=d" (u[1])
737 : "0" (u[0]), "1" (u[1]), "r" (v) );
738 return 0;
739 }
741 /*
742 * Signed division of double-word dividend.
743 * IN: Dividend=u[1]:u[0], Divisor=v
744 * OUT: Return 1: #DE
745 * Return 0: Quotient=u[0], Remainder=u[1]
746 * NB. We don't use idiv directly as it's moderately hard to work out
747 * ahead of time whether it will #DE, which we cannot allow to happen.
748 */
749 static int idiv_dbl(unsigned long u[2], unsigned long v)
750 {
751 int negu = (long)u[1] < 0, negv = (long)v < 0;
753 /* u = abs(u) */
754 if ( negu )
755 {
756 u[1] = ~u[1];
757 if ( (u[0] = -u[0]) == 0 )
758 u[1]++;
759 }
761 /* abs(u) / abs(v) */
762 if ( div_dbl(u, negv ? -v : v) )
763 return 1;
765 /* Remainder has same sign as dividend. It cannot overflow. */
766 if ( negu )
767 u[1] = -u[1];
769 /* Quotient is overflowed if sign bit is set. */
770 if ( negu ^ negv )
771 {
772 if ( (long)u[0] >= 0 )
773 u[0] = -u[0];
774 else if ( (u[0] << 1) != 0 ) /* == 0x80...0 is okay */
775 return 1;
776 }
777 else if ( (long)u[0] < 0 )
778 return 1;
780 return 0;
781 }
783 static int
784 test_cc(
785 unsigned int condition, unsigned int flags)
786 {
787 int rc = 0;
789 switch ( (condition & 15) >> 1 )
790 {
791 case 0: /* o */
792 rc |= (flags & EFLG_OF);
793 break;
794 case 1: /* b/c/nae */
795 rc |= (flags & EFLG_CF);
796 break;
797 case 2: /* z/e */
798 rc |= (flags & EFLG_ZF);
799 break;
800 case 3: /* be/na */
801 rc |= (flags & (EFLG_CF|EFLG_ZF));
802 break;
803 case 4: /* s */
804 rc |= (flags & EFLG_SF);
805 break;
806 case 5: /* p/pe */
807 rc |= (flags & EFLG_PF);
808 break;
809 case 7: /* le/ng */
810 rc |= (flags & EFLG_ZF);
811 /* fall through */
812 case 6: /* l/nge */
813 rc |= (!(flags & EFLG_SF) != !(flags & EFLG_OF));
814 break;
815 }
817 /* Odd condition identifiers (lsb == 1) have inverted sense. */
818 return (!!rc ^ (condition & 1));
819 }
821 static int
822 get_cpl(
823 struct x86_emulate_ctxt *ctxt,
824 struct x86_emulate_ops *ops)
825 {
826 struct segment_register reg;
828 if ( ctxt->regs->eflags & EFLG_VM )
829 return 3;
831 if ( (ops->read_segment == NULL) ||
832 ops->read_segment(x86_seg_ss, &reg, ctxt) )
833 return -1;
835 return reg.attr.fields.dpl;
836 }
838 static int
839 _mode_iopl(
840 struct x86_emulate_ctxt *ctxt,
841 struct x86_emulate_ops *ops)
842 {
843 int cpl = get_cpl(ctxt, ops);
844 if ( cpl == -1 )
845 return -1;
846 return (cpl <= ((ctxt->regs->eflags >> 12) & 3));
847 }
849 #define mode_ring0() ({ \
850 int _cpl = get_cpl(ctxt, ops); \
851 fail_if(_cpl < 0); \
852 (_cpl == 0); \
853 })
854 #define mode_iopl() ({ \
855 int _iopl = _mode_iopl(ctxt, ops); \
856 fail_if(_iopl < 0); \
857 _iopl; \
858 })
860 static int ioport_access_check(
861 unsigned int first_port,
862 unsigned int bytes,
863 struct x86_emulate_ctxt *ctxt,
864 struct x86_emulate_ops *ops)
865 {
866 unsigned long iobmp;
867 struct segment_register tr;
868 int rc = X86EMUL_OKAY;
870 if ( !(ctxt->regs->eflags & EFLG_VM) && mode_iopl() )
871 return X86EMUL_OKAY;
873 fail_if(ops->read_segment == NULL);
874 if ( (rc = ops->read_segment(x86_seg_tr, &tr, ctxt)) != 0 )
875 return rc;
877 /* Ensure that the TSS is valid and has an io-bitmap-offset field. */
878 if ( !tr.attr.fields.p ||
879 ((tr.attr.fields.type & 0xd) != 0x9) ||
880 (tr.limit < 0x67) )
881 goto raise_exception;
883 if ( (rc = read_ulong(x86_seg_none, tr.base + 0x66,
884 &iobmp, 2, ctxt, ops)) )
885 return rc;
887 /* Ensure TSS includes two bytes including byte containing first port. */
888 iobmp += first_port / 8;
889 if ( tr.limit <= iobmp )
890 goto raise_exception;
892 if ( (rc = read_ulong(x86_seg_none, tr.base + iobmp,
893 &iobmp, 2, ctxt, ops)) )
894 return rc;
895 if ( (iobmp & (((1<<bytes)-1) << (first_port&7))) != 0 )
896 goto raise_exception;
898 done:
899 return rc;
901 raise_exception:
902 fail_if(ops->inject_hw_exception == NULL);
903 return ops->inject_hw_exception(EXC_GP, 0, ctxt) ? : X86EMUL_EXCEPTION;
904 }
906 static int
907 in_realmode(
908 struct x86_emulate_ctxt *ctxt,
909 struct x86_emulate_ops *ops)
910 {
911 unsigned long cr0;
912 int rc;
914 if ( ops->read_cr == NULL )
915 return 0;
917 rc = ops->read_cr(0, &cr0, ctxt);
918 return (!rc && !(cr0 & CR0_PE));
919 }
921 static int
922 in_protmode(
923 struct x86_emulate_ctxt *ctxt,
924 struct x86_emulate_ops *ops)
925 {
926 return !(in_realmode(ctxt, ops) || (ctxt->regs->eflags & EFLG_VM));
927 }
929 static int
930 realmode_load_seg(
931 enum x86_segment seg,
932 uint16_t sel,
933 struct x86_emulate_ctxt *ctxt,
934 struct x86_emulate_ops *ops)
935 {
936 struct segment_register reg;
937 int rc;
939 if ( (rc = ops->read_segment(seg, &reg, ctxt)) != 0 )
940 return rc;
942 reg.sel = sel;
943 reg.base = (uint32_t)sel << 4;
945 return ops->write_segment(seg, &reg, ctxt);
946 }
948 static int
949 protmode_load_seg(
950 enum x86_segment seg,
951 uint16_t sel,
952 struct x86_emulate_ctxt *ctxt,
953 struct x86_emulate_ops *ops)
954 {
955 struct segment_register desctab, ss, segr;
956 struct { uint32_t a, b; } desc;
957 unsigned long val;
958 uint8_t dpl, rpl, cpl;
959 uint32_t new_desc_b;
960 int rc, fault_type = EXC_TS;
962 /* NULL selector? */
963 if ( (sel & 0xfffc) == 0 )
964 {
965 if ( (seg == x86_seg_cs) || (seg == x86_seg_ss) )
966 goto raise_exn;
967 memset(&segr, 0, sizeof(segr));
968 return ops->write_segment(seg, &segr, ctxt);
969 }
971 /* LDT descriptor must be in the GDT. */
972 if ( (seg == x86_seg_ldtr) && (sel & 4) )
973 goto raise_exn;
975 if ( (rc = ops->read_segment(x86_seg_ss, &ss, ctxt)) ||
976 (rc = ops->read_segment((sel & 4) ? x86_seg_ldtr : x86_seg_gdtr,
977 &desctab, ctxt)) )
978 return rc;
980 /* Check against descriptor table limit. */
981 if ( ((sel & 0xfff8) + 7) > desctab.limit )
982 goto raise_exn;
984 do {
985 if ( (rc = read_ulong(x86_seg_none, desctab.base + (sel & 0xfff8),
986 &val, 4, ctxt, ops)) )
987 return rc;
988 desc.a = val;
989 if ( (rc = read_ulong(x86_seg_none, desctab.base + (sel & 0xfff8) + 4,
990 &val, 4, ctxt, ops)) )
991 return rc;
992 desc.b = val;
994 /* Segment present in memory? */
995 if ( !(desc.b & (1u<<15)) )
996 {
997 fault_type = EXC_NP;
998 goto raise_exn;
999 }
1001 /* LDT descriptor is a system segment. All others are code/data. */
1002 if ( (desc.b & (1u<<12)) == ((seg == x86_seg_ldtr) << 12) )
1003 goto raise_exn;
1005 dpl = (desc.b >> 13) & 3;
1006 rpl = sel & 3;
1007 cpl = ss.attr.fields.dpl;
1009 switch ( seg )
1011 case x86_seg_cs:
1012 /* Code segment? */
1013 if ( !(desc.b & (1u<<11)) )
1014 goto raise_exn;
1015 /* Non-conforming segment: check DPL against RPL. */
1016 if ( ((desc.b & (6u<<9)) != (6u<<9)) && (dpl != rpl) )
1017 goto raise_exn;
1018 break;
1019 case x86_seg_ss:
1020 /* Writable data segment? */
1021 if ( (desc.b & (5u<<9)) != (1u<<9) )
1022 goto raise_exn;
1023 if ( (dpl != cpl) || (dpl != rpl) )
1024 goto raise_exn;
1025 break;
1026 case x86_seg_ldtr:
1027 /* LDT system segment? */
1028 if ( (desc.b & (15u<<8)) != (2u<<8) )
1029 goto raise_exn;
1030 goto skip_accessed_flag;
1031 default:
1032 /* Readable code or data segment? */
1033 if ( (desc.b & (5u<<9)) == (4u<<9) )
1034 goto raise_exn;
1035 /* Non-conforming segment: check DPL against RPL and CPL. */
1036 if ( ((desc.b & (6u<<9)) != (6u<<9)) &&
1037 ((dpl < cpl) || (dpl < rpl)) )
1038 goto raise_exn;
1039 break;
1042 /* Ensure Accessed flag is set. */
1043 new_desc_b = desc.b | 0x100;
1044 rc = ((desc.b & 0x100) ? X86EMUL_OKAY :
1045 ops->cmpxchg(
1046 x86_seg_none, desctab.base + (sel & 0xfff8) + 4,
1047 &desc.b, &new_desc_b, 4, ctxt));
1048 } while ( rc == X86EMUL_CMPXCHG_FAILED );
1050 if ( rc )
1051 return rc;
1053 /* Force the Accessed flag in our local copy. */
1054 desc.b |= 0x100;
1056 skip_accessed_flag:
1057 segr.base = (((desc.b << 0) & 0xff000000u) |
1058 ((desc.b << 16) & 0x00ff0000u) |
1059 ((desc.a >> 16) & 0x0000ffffu));
1060 segr.attr.bytes = (((desc.b >> 8) & 0x00ffu) |
1061 ((desc.b >> 12) & 0x0f00u));
1062 segr.limit = (desc.b & 0x000f0000u) | (desc.a & 0x0000ffffu);
1063 if ( segr.attr.fields.g )
1064 segr.limit = (segr.limit << 12) | 0xfffu;
1065 segr.sel = sel;
1066 return ops->write_segment(seg, &segr, ctxt);
1068 raise_exn:
1069 if ( ops->inject_hw_exception == NULL )
1070 return X86EMUL_UNHANDLEABLE;
1071 if ( (rc = ops->inject_hw_exception(fault_type, sel & 0xfffc, ctxt)) )
1072 return rc;
1073 return X86EMUL_EXCEPTION;
1076 static int
1077 load_seg(
1078 enum x86_segment seg,
1079 uint16_t sel,
1080 struct x86_emulate_ctxt *ctxt,
1081 struct x86_emulate_ops *ops)
1083 if ( (ops->read_segment == NULL) ||
1084 (ops->write_segment == NULL) )
1085 return X86EMUL_UNHANDLEABLE;
1087 if ( in_protmode(ctxt, ops) )
1088 return protmode_load_seg(seg, sel, ctxt, ops);
1090 return realmode_load_seg(seg, sel, ctxt, ops);
1093 void *
1094 decode_register(
1095 uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs)
1097 void *p;
1099 switch ( modrm_reg )
1101 case 0: p = &regs->eax; break;
1102 case 1: p = &regs->ecx; break;
1103 case 2: p = &regs->edx; break;
1104 case 3: p = &regs->ebx; break;
1105 case 4: p = (highbyte_regs ?
1106 ((unsigned char *)&regs->eax + 1) :
1107 (unsigned char *)&regs->esp); break;
1108 case 5: p = (highbyte_regs ?
1109 ((unsigned char *)&regs->ecx + 1) :
1110 (unsigned char *)&regs->ebp); break;
1111 case 6: p = (highbyte_regs ?
1112 ((unsigned char *)&regs->edx + 1) :
1113 (unsigned char *)&regs->esi); break;
1114 case 7: p = (highbyte_regs ?
1115 ((unsigned char *)&regs->ebx + 1) :
1116 (unsigned char *)&regs->edi); break;
1117 #if defined(__x86_64__)
1118 case 8: p = &regs->r8; break;
1119 case 9: p = &regs->r9; break;
1120 case 10: p = &regs->r10; break;
1121 case 11: p = &regs->r11; break;
1122 case 12: p = &regs->r12; break;
1123 case 13: p = &regs->r13; break;
1124 case 14: p = &regs->r14; break;
1125 case 15: p = &regs->r15; break;
1126 #endif
1127 default: p = NULL; break;
1130 return p;
1133 #define decode_segment_failed x86_seg_tr
1134 enum x86_segment
1135 decode_segment(
1136 uint8_t modrm_reg)
1138 switch ( modrm_reg )
1140 case 0: return x86_seg_es;
1141 case 1: return x86_seg_cs;
1142 case 2: return x86_seg_ss;
1143 case 3: return x86_seg_ds;
1144 case 4: return x86_seg_fs;
1145 case 5: return x86_seg_gs;
1146 default: break;
1148 return decode_segment_failed;
1151 int
1152 x86_emulate(
1153 struct x86_emulate_ctxt *ctxt,
1154 struct x86_emulate_ops *ops)
1156 /* Shadow copy of register state. Committed on successful emulation. */
1157 struct cpu_user_regs _regs = *ctxt->regs;
1159 uint8_t b, d, sib, sib_index, sib_base, twobyte = 0, rex_prefix = 0;
1160 uint8_t modrm = 0, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
1161 unsigned int op_bytes, def_op_bytes, ad_bytes, def_ad_bytes;
1162 #define REPE_PREFIX 1
1163 #define REPNE_PREFIX 2
1164 unsigned int lock_prefix = 0, rep_prefix = 0;
1165 int override_seg = -1, rc = X86EMUL_OKAY;
1166 struct operand src, dst;
1168 /* Data operand effective address (usually computed from ModRM). */
1169 struct operand ea;
1171 /* Default is a memory operand relative to segment DS. */
1172 ea.type = OP_MEM;
1173 ea.mem.seg = x86_seg_ds;
1174 ea.mem.off = 0;
1176 ctxt->retire.byte = 0;
1178 op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->addr_size/8;
1179 if ( op_bytes == 8 )
1181 op_bytes = def_op_bytes = 4;
1182 #ifndef __x86_64__
1183 return X86EMUL_UNHANDLEABLE;
1184 #endif
1187 /* Prefix bytes. */
1188 for ( ; ; )
1190 switch ( b = insn_fetch_type(uint8_t) )
1192 case 0x66: /* operand-size override */
1193 op_bytes = def_op_bytes ^ 6;
1194 break;
1195 case 0x67: /* address-size override */
1196 ad_bytes = def_ad_bytes ^ (mode_64bit() ? 12 : 6);
1197 break;
1198 case 0x2e: /* CS override */
1199 override_seg = x86_seg_cs;
1200 break;
1201 case 0x3e: /* DS override */
1202 override_seg = x86_seg_ds;
1203 break;
1204 case 0x26: /* ES override */
1205 override_seg = x86_seg_es;
1206 break;
1207 case 0x64: /* FS override */
1208 override_seg = x86_seg_fs;
1209 break;
1210 case 0x65: /* GS override */
1211 override_seg = x86_seg_gs;
1212 break;
1213 case 0x36: /* SS override */
1214 override_seg = x86_seg_ss;
1215 break;
1216 case 0xf0: /* LOCK */
1217 lock_prefix = 1;
1218 break;
1219 case 0xf2: /* REPNE/REPNZ */
1220 rep_prefix = REPNE_PREFIX;
1221 break;
1222 case 0xf3: /* REP/REPE/REPZ */
1223 rep_prefix = REPE_PREFIX;
1224 break;
1225 case 0x40 ... 0x4f: /* REX */
1226 if ( !mode_64bit() )
1227 goto done_prefixes;
1228 rex_prefix = b;
1229 continue;
1230 default:
1231 goto done_prefixes;
1234 /* Any legacy prefix after a REX prefix nullifies its effect. */
1235 rex_prefix = 0;
1237 done_prefixes:
1239 if ( rex_prefix & 8 ) /* REX.W */
1240 op_bytes = 8;
1242 /* Opcode byte(s). */
1243 d = opcode_table[b];
1244 if ( d == 0 )
1246 /* Two-byte opcode? */
1247 if ( b == 0x0f )
1249 twobyte = 1;
1250 b = insn_fetch_type(uint8_t);
1251 d = twobyte_table[b];
1254 /* Unrecognised? */
1255 if ( d == 0 )
1256 goto cannot_emulate;
1259 /* Lock prefix is allowed only on RMW instructions. */
1260 generate_exception_if((d & Mov) && lock_prefix, EXC_GP, 0);
1262 /* ModRM and SIB bytes. */
1263 if ( d & ModRM )
1265 modrm = insn_fetch_type(uint8_t);
1266 modrm_mod = (modrm & 0xc0) >> 6;
1267 modrm_reg = ((rex_prefix & 4) << 1) | ((modrm & 0x38) >> 3);
1268 modrm_rm = modrm & 0x07;
1270 if ( modrm_mod == 3 )
1272 modrm_rm |= (rex_prefix & 1) << 3;
1273 ea.type = OP_REG;
1274 ea.reg = decode_register(
1275 modrm_rm, &_regs, (d & ByteOp) && (rex_prefix == 0));
1277 else if ( ad_bytes == 2 )
1279 /* 16-bit ModR/M decode. */
1280 switch ( modrm_rm )
1282 case 0:
1283 ea.mem.off = _regs.ebx + _regs.esi;
1284 break;
1285 case 1:
1286 ea.mem.off = _regs.ebx + _regs.edi;
1287 break;
1288 case 2:
1289 ea.mem.seg = x86_seg_ss;
1290 ea.mem.off = _regs.ebp + _regs.esi;
1291 break;
1292 case 3:
1293 ea.mem.seg = x86_seg_ss;
1294 ea.mem.off = _regs.ebp + _regs.edi;
1295 break;
1296 case 4:
1297 ea.mem.off = _regs.esi;
1298 break;
1299 case 5:
1300 ea.mem.off = _regs.edi;
1301 break;
1302 case 6:
1303 if ( modrm_mod == 0 )
1304 break;
1305 ea.mem.seg = x86_seg_ss;
1306 ea.mem.off = _regs.ebp;
1307 break;
1308 case 7:
1309 ea.mem.off = _regs.ebx;
1310 break;
1312 switch ( modrm_mod )
1314 case 0:
1315 if ( modrm_rm == 6 )
1316 ea.mem.off = insn_fetch_type(int16_t);
1317 break;
1318 case 1:
1319 ea.mem.off += insn_fetch_type(int8_t);
1320 break;
1321 case 2:
1322 ea.mem.off += insn_fetch_type(int16_t);
1323 break;
1325 ea.mem.off = truncate_ea(ea.mem.off);
1327 else
1329 /* 32/64-bit ModR/M decode. */
1330 if ( modrm_rm == 4 )
1332 sib = insn_fetch_type(uint8_t);
1333 sib_index = ((sib >> 3) & 7) | ((rex_prefix << 2) & 8);
1334 sib_base = (sib & 7) | ((rex_prefix << 3) & 8);
1335 if ( sib_index != 4 )
1336 ea.mem.off = *(long*)decode_register(sib_index, &_regs, 0);
1337 ea.mem.off <<= (sib >> 6) & 3;
1338 if ( (modrm_mod == 0) && ((sib_base & 7) == 5) )
1339 ea.mem.off += insn_fetch_type(int32_t);
1340 else if ( sib_base == 4 )
1342 ea.mem.seg = x86_seg_ss;
1343 ea.mem.off += _regs.esp;
1344 if ( !twobyte && (b == 0x8f) )
1345 /* POP <rm> computes its EA post increment. */
1346 ea.mem.off += ((mode_64bit() && (op_bytes == 4))
1347 ? 8 : op_bytes);
1349 else if ( sib_base == 5 )
1351 ea.mem.seg = x86_seg_ss;
1352 ea.mem.off += _regs.ebp;
1354 else
1355 ea.mem.off += *(long*)decode_register(sib_base, &_regs, 0);
1357 else
1359 modrm_rm |= (rex_prefix & 1) << 3;
1360 ea.mem.off = *(long *)decode_register(modrm_rm, &_regs, 0);
1361 if ( (modrm_rm == 5) && (modrm_mod != 0) )
1362 ea.mem.seg = x86_seg_ss;
1364 switch ( modrm_mod )
1366 case 0:
1367 if ( (modrm_rm & 7) != 5 )
1368 break;
1369 ea.mem.off = insn_fetch_type(int32_t);
1370 if ( !mode_64bit() )
1371 break;
1372 /* Relative to RIP of next instruction. Argh! */
1373 ea.mem.off += _regs.eip;
1374 if ( (d & SrcMask) == SrcImm )
1375 ea.mem.off += (d & ByteOp) ? 1 :
1376 ((op_bytes == 8) ? 4 : op_bytes);
1377 else if ( (d & SrcMask) == SrcImmByte )
1378 ea.mem.off += 1;
1379 else if ( !twobyte && ((b & 0xfe) == 0xf6) &&
1380 ((modrm_reg & 7) <= 1) )
1381 /* Special case in Grp3: test has immediate operand. */
1382 ea.mem.off += (d & ByteOp) ? 1
1383 : ((op_bytes == 8) ? 4 : op_bytes);
1384 else if ( twobyte && ((b & 0xf7) == 0xa4) )
1385 /* SHLD/SHRD with immediate byte third operand. */
1386 ea.mem.off++;
1387 break;
1388 case 1:
1389 ea.mem.off += insn_fetch_type(int8_t);
1390 break;
1391 case 2:
1392 ea.mem.off += insn_fetch_type(int32_t);
1393 break;
1395 ea.mem.off = truncate_ea(ea.mem.off);
1399 if ( override_seg != -1 )
1400 ea.mem.seg = override_seg;
1402 /* Special instructions do their own operand decoding. */
1403 if ( (d & DstMask) == ImplicitOps )
1404 goto special_insn;
1406 /* Decode and fetch the source operand: register, memory or immediate. */
1407 switch ( d & SrcMask )
1409 case SrcNone:
1410 break;
1411 case SrcReg:
1412 src.type = OP_REG;
1413 if ( d & ByteOp )
1415 src.reg = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
1416 src.val = *(uint8_t *)src.reg;
1417 src.bytes = 1;
1419 else
1421 src.reg = decode_register(modrm_reg, &_regs, 0);
1422 switch ( (src.bytes = op_bytes) )
1424 case 2: src.val = *(uint16_t *)src.reg; break;
1425 case 4: src.val = *(uint32_t *)src.reg; break;
1426 case 8: src.val = *(uint64_t *)src.reg; break;
1429 break;
1430 case SrcMem16:
1431 ea.bytes = 2;
1432 goto srcmem_common;
1433 case SrcMem:
1434 ea.bytes = (d & ByteOp) ? 1 : op_bytes;
1435 srcmem_common:
1436 src = ea;
1437 if ( src.type == OP_REG )
1439 switch ( src.bytes )
1441 case 1: src.val = *(uint8_t *)src.reg; break;
1442 case 2: src.val = *(uint16_t *)src.reg; break;
1443 case 4: src.val = *(uint32_t *)src.reg; break;
1444 case 8: src.val = *(uint64_t *)src.reg; break;
1447 else if ( (rc = read_ulong(src.mem.seg, src.mem.off,
1448 &src.val, src.bytes, ctxt, ops)) )
1449 goto done;
1450 break;
1451 case SrcImm:
1452 src.type = OP_IMM;
1453 src.bytes = (d & ByteOp) ? 1 : op_bytes;
1454 if ( src.bytes == 8 ) src.bytes = 4;
1455 /* NB. Immediates are sign-extended as necessary. */
1456 switch ( src.bytes )
1458 case 1: src.val = insn_fetch_type(int8_t); break;
1459 case 2: src.val = insn_fetch_type(int16_t); break;
1460 case 4: src.val = insn_fetch_type(int32_t); break;
1462 break;
1463 case SrcImmByte:
1464 src.type = OP_IMM;
1465 src.bytes = 1;
1466 src.val = insn_fetch_type(int8_t);
1467 break;
1470 /* Decode and fetch the destination operand: register or memory. */
1471 switch ( d & DstMask )
1473 case DstReg:
1474 dst.type = OP_REG;
1475 if ( d & ByteOp )
1477 dst.reg = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
1478 dst.val = *(uint8_t *)dst.reg;
1479 dst.bytes = 1;
1481 else
1483 dst.reg = decode_register(modrm_reg, &_regs, 0);
1484 switch ( (dst.bytes = op_bytes) )
1486 case 2: dst.val = *(uint16_t *)dst.reg; break;
1487 case 4: dst.val = *(uint32_t *)dst.reg; break;
1488 case 8: dst.val = *(uint64_t *)dst.reg; break;
1491 break;
1492 case DstBitBase:
1493 if ( ((d & SrcMask) == SrcImmByte) || (ea.type == OP_REG) )
1495 src.val &= (op_bytes << 3) - 1;
1497 else
1499 /*
1500 * EA += BitOffset DIV op_bytes*8
1501 * BitOffset = BitOffset MOD op_bytes*8
1502 * DIV truncates towards negative infinity.
1503 * MOD always produces a positive result.
1504 */
1505 if ( op_bytes == 2 )
1506 src.val = (int16_t)src.val;
1507 else if ( op_bytes == 4 )
1508 src.val = (int32_t)src.val;
1509 if ( (long)src.val < 0 )
1511 unsigned long byte_offset;
1512 byte_offset = op_bytes + (((-src.val-1) >> 3) & ~(op_bytes-1));
1513 ea.mem.off -= byte_offset;
1514 src.val = (byte_offset << 3) + src.val;
1516 else
1518 ea.mem.off += (src.val >> 3) & ~(op_bytes - 1);
1519 src.val &= (op_bytes << 3) - 1;
1522 /* Becomes a normal DstMem operation from here on. */
1523 d = (d & ~DstMask) | DstMem;
1524 case DstMem:
1525 ea.bytes = (d & ByteOp) ? 1 : op_bytes;
1526 dst = ea;
1527 if ( dst.type == OP_REG )
1529 switch ( dst.bytes )
1531 case 1: dst.val = *(uint8_t *)dst.reg; break;
1532 case 2: dst.val = *(uint16_t *)dst.reg; break;
1533 case 4: dst.val = *(uint32_t *)dst.reg; break;
1534 case 8: dst.val = *(uint64_t *)dst.reg; break;
1537 else if ( !(d & Mov) ) /* optimisation - avoid slow emulated read */
1539 if ( (rc = read_ulong(dst.mem.seg, dst.mem.off,
1540 &dst.val, dst.bytes, ctxt, ops)) )
1541 goto done;
1542 dst.orig_val = dst.val;
1544 break;
1547 /* LOCK prefix allowed only on instructions with memory destination. */
1548 generate_exception_if(lock_prefix && (dst.type != OP_MEM), EXC_GP, 0);
1550 if ( twobyte )
1551 goto twobyte_insn;
1553 switch ( b )
1555 case 0x04 ... 0x05: /* add imm,%%eax */
1556 dst.reg = (unsigned long *)&_regs.eax;
1557 dst.val = _regs.eax;
1558 case 0x00 ... 0x03: add: /* add */
1559 emulate_2op_SrcV("add", src, dst, _regs.eflags);
1560 break;
1562 case 0x0c ... 0x0d: /* or imm,%%eax */
1563 dst.reg = (unsigned long *)&_regs.eax;
1564 dst.val = _regs.eax;
1565 case 0x08 ... 0x0b: or: /* or */
1566 emulate_2op_SrcV("or", src, dst, _regs.eflags);
1567 break;
1569 case 0x14 ... 0x15: /* adc imm,%%eax */
1570 dst.reg = (unsigned long *)&_regs.eax;
1571 dst.val = _regs.eax;
1572 case 0x10 ... 0x13: adc: /* adc */
1573 emulate_2op_SrcV("adc", src, dst, _regs.eflags);
1574 break;
1576 case 0x1c ... 0x1d: /* sbb imm,%%eax */
1577 dst.reg = (unsigned long *)&_regs.eax;
1578 dst.val = _regs.eax;
1579 case 0x18 ... 0x1b: sbb: /* sbb */
1580 emulate_2op_SrcV("sbb", src, dst, _regs.eflags);
1581 break;
1583 case 0x24 ... 0x25: /* and imm,%%eax */
1584 dst.reg = (unsigned long *)&_regs.eax;
1585 dst.val = _regs.eax;
1586 case 0x20 ... 0x23: and: /* and */
1587 emulate_2op_SrcV("and", src, dst, _regs.eflags);
1588 break;
1590 case 0x2c ... 0x2d: /* sub imm,%%eax */
1591 dst.reg = (unsigned long *)&_regs.eax;
1592 dst.val = _regs.eax;
1593 case 0x28 ... 0x2b: sub: /* sub */
1594 emulate_2op_SrcV("sub", src, dst, _regs.eflags);
1595 break;
1597 case 0x34 ... 0x35: /* xor imm,%%eax */
1598 dst.reg = (unsigned long *)&_regs.eax;
1599 dst.val = _regs.eax;
1600 case 0x30 ... 0x33: xor: /* xor */
1601 emulate_2op_SrcV("xor", src, dst, _regs.eflags);
1602 break;
1604 case 0x3c ... 0x3d: /* cmp imm,%%eax */
1605 dst.reg = (unsigned long *)&_regs.eax;
1606 dst.val = _regs.eax;
1607 case 0x38 ... 0x3b: cmp: /* cmp */
1608 emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
1609 break;
1611 case 0x62: /* bound */ {
1612 unsigned long src_val2;
1613 int lb, ub, idx;
1614 generate_exception_if(mode_64bit() || (src.type != OP_MEM),
1615 EXC_UD, -1);
1616 if ( (rc = read_ulong(src.mem.seg, src.mem.off + op_bytes,
1617 &src_val2, op_bytes, ctxt, ops)) )
1618 goto done;
1619 ub = (op_bytes == 2) ? (int16_t)src_val2 : (int32_t)src_val2;
1620 lb = (op_bytes == 2) ? (int16_t)src.val : (int32_t)src.val;
1621 idx = (op_bytes == 2) ? (int16_t)dst.val : (int32_t)dst.val;
1622 generate_exception_if((idx < lb) || (idx > ub), EXC_BR, -1);
1623 dst.type = OP_NONE;
1624 break;
1627 case 0x63: /* movsxd (x86/64) / arpl (x86/32) */
1628 if ( mode_64bit() )
1630 /* movsxd */
1631 if ( src.type == OP_REG )
1632 src.val = *(int32_t *)src.reg;
1633 else if ( (rc = read_ulong(src.mem.seg, src.mem.off,
1634 &src.val, 4, ctxt, ops)) )
1635 goto done;
1636 dst.val = (int32_t)src.val;
1638 else
1640 /* arpl */
1641 uint16_t src_val = dst.val;
1642 dst = src;
1643 _regs.eflags &= ~EFLG_ZF;
1644 _regs.eflags |= ((src_val & 3) > (dst.val & 3)) ? EFLG_ZF : 0;
1645 if ( _regs.eflags & EFLG_ZF )
1646 dst.val = (dst.val & ~3) | (src_val & 3);
1647 else
1648 dst.type = OP_NONE;
1649 generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1);
1651 break;
1653 case 0x69: /* imul imm16/32 */
1654 case 0x6b: /* imul imm8 */ {
1655 unsigned long src1; /* ModR/M source operand */
1656 if ( ea.type == OP_REG )
1657 src1 = *ea.reg;
1658 else if ( (rc = read_ulong(ea.mem.seg, ea.mem.off,
1659 &src1, op_bytes, ctxt, ops)) )
1660 goto done;
1661 _regs.eflags &= ~(EFLG_OF|EFLG_CF);
1662 switch ( dst.bytes )
1664 case 2:
1665 dst.val = ((uint32_t)(int16_t)src.val *
1666 (uint32_t)(int16_t)src1);
1667 if ( (int16_t)dst.val != (uint32_t)dst.val )
1668 _regs.eflags |= EFLG_OF|EFLG_CF;
1669 break;
1670 #ifdef __x86_64__
1671 case 4:
1672 dst.val = ((uint64_t)(int32_t)src.val *
1673 (uint64_t)(int32_t)src1);
1674 if ( (int32_t)dst.val != dst.val )
1675 _regs.eflags |= EFLG_OF|EFLG_CF;
1676 break;
1677 #endif
1678 default: {
1679 unsigned long m[2] = { src.val, src1 };
1680 if ( imul_dbl(m) )
1681 _regs.eflags |= EFLG_OF|EFLG_CF;
1682 dst.val = m[0];
1683 break;
1686 break;
1689 case 0x82: /* Grp1 (x86/32 only) */
1690 generate_exception_if(mode_64bit(), EXC_UD, -1);
1691 case 0x80: case 0x81: case 0x83: /* Grp1 */
1692 switch ( modrm_reg & 7 )
1694 case 0: goto add;
1695 case 1: goto or;
1696 case 2: goto adc;
1697 case 3: goto sbb;
1698 case 4: goto and;
1699 case 5: goto sub;
1700 case 6: goto xor;
1701 case 7: goto cmp;
1703 break;
1705 case 0xa8 ... 0xa9: /* test imm,%%eax */
1706 dst.reg = (unsigned long *)&_regs.eax;
1707 dst.val = _regs.eax;
1708 case 0x84 ... 0x85: test: /* test */
1709 emulate_2op_SrcV("test", src, dst, _regs.eflags);
1710 break;
1712 case 0x86 ... 0x87: xchg: /* xchg */
1713 /* Write back the register source. */
1714 switch ( dst.bytes )
1716 case 1: *(uint8_t *)src.reg = (uint8_t)dst.val; break;
1717 case 2: *(uint16_t *)src.reg = (uint16_t)dst.val; break;
1718 case 4: *src.reg = (uint32_t)dst.val; break; /* 64b reg: zero-extend */
1719 case 8: *src.reg = dst.val; break;
1721 /* Write back the memory destination with implicit LOCK prefix. */
1722 dst.val = src.val;
1723 lock_prefix = 1;
1724 break;
1726 case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
1727 generate_exception_if((modrm_reg & 7) != 0, EXC_UD, -1);
1728 case 0x88 ... 0x8b: /* mov */
1729 dst.val = src.val;
1730 break;
1732 case 0x8c: /* mov Sreg,r/m */ {
1733 struct segment_register reg;
1734 enum x86_segment seg = decode_segment(modrm_reg);
1735 generate_exception_if(seg == decode_segment_failed, EXC_UD, -1);
1736 fail_if(ops->read_segment == NULL);
1737 if ( (rc = ops->read_segment(seg, &reg, ctxt)) != 0 )
1738 goto done;
1739 dst.val = reg.sel;
1740 if ( dst.type == OP_MEM )
1741 dst.bytes = 2;
1742 break;
1745 case 0x8e: /* mov r/m,Sreg */ {
1746 enum x86_segment seg = decode_segment(modrm_reg);
1747 generate_exception_if(seg == decode_segment_failed, EXC_UD, -1);
1748 if ( (rc = load_seg(seg, (uint16_t)src.val, ctxt, ops)) != 0 )
1749 goto done;
1750 if ( seg == x86_seg_ss )
1751 ctxt->retire.flags.mov_ss = 1;
1752 dst.type = OP_NONE;
1753 break;
1756 case 0x8d: /* lea */
1757 dst.val = ea.mem.off;
1758 break;
1760 case 0x8f: /* pop (sole member of Grp1a) */
1761 generate_exception_if((modrm_reg & 7) != 0, EXC_UD, -1);
1762 /* 64-bit mode: POP defaults to a 64-bit operand. */
1763 if ( mode_64bit() && (dst.bytes == 4) )
1764 dst.bytes = 8;
1765 if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(dst.bytes),
1766 &dst.val, dst.bytes, ctxt, ops)) != 0 )
1767 goto done;
1768 break;
1770 case 0xb0 ... 0xb7: /* mov imm8,r8 */
1771 dst.reg = decode_register(
1772 (b & 7) | ((rex_prefix & 1) << 3), &_regs, (rex_prefix == 0));
1773 dst.val = src.val;
1774 break;
1776 case 0xb8 ... 0xbf: /* mov imm{16,32,64},r{16,32,64} */
1777 if ( dst.bytes == 8 ) /* Fetch more bytes to obtain imm64 */
1778 src.val = ((uint32_t)src.val |
1779 ((uint64_t)insn_fetch_type(uint32_t) << 32));
1780 dst.reg = decode_register(
1781 (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0);
1782 dst.val = src.val;
1783 break;
1785 case 0xc0 ... 0xc1: grp2: /* Grp2 */
1786 switch ( modrm_reg & 7 )
1788 case 0: /* rol */
1789 emulate_2op_SrcB("rol", src, dst, _regs.eflags);
1790 break;
1791 case 1: /* ror */
1792 emulate_2op_SrcB("ror", src, dst, _regs.eflags);
1793 break;
1794 case 2: /* rcl */
1795 emulate_2op_SrcB("rcl", src, dst, _regs.eflags);
1796 break;
1797 case 3: /* rcr */
1798 emulate_2op_SrcB("rcr", src, dst, _regs.eflags);
1799 break;
1800 case 4: /* sal/shl */
1801 case 6: /* sal/shl */
1802 emulate_2op_SrcB("sal", src, dst, _regs.eflags);
1803 break;
1804 case 5: /* shr */
1805 emulate_2op_SrcB("shr", src, dst, _regs.eflags);
1806 break;
1807 case 7: /* sar */
1808 emulate_2op_SrcB("sar", src, dst, _regs.eflags);
1809 break;
1811 break;
1813 case 0xc4: /* les */ {
1814 unsigned long sel;
1815 dst.val = x86_seg_es;
1816 les: /* dst.val identifies the segment */
1817 generate_exception_if(src.type != OP_MEM, EXC_UD, -1);
1818 if ( (rc = read_ulong(src.mem.seg, src.mem.off + src.bytes,
1819 &sel, 2, ctxt, ops)) != 0 )
1820 goto done;
1821 if ( (rc = load_seg(dst.val, (uint16_t)sel, ctxt, ops)) != 0 )
1822 goto done;
1823 dst.val = src.val;
1824 break;
1827 case 0xc5: /* lds */
1828 dst.val = x86_seg_ds;
1829 goto les;
1831 case 0xd0 ... 0xd1: /* Grp2 */
1832 src.val = 1;
1833 goto grp2;
1835 case 0xd2 ... 0xd3: /* Grp2 */
1836 src.val = _regs.ecx;
1837 goto grp2;
1839 case 0xf6 ... 0xf7: /* Grp3 */
1840 switch ( modrm_reg & 7 )
1842 case 0 ... 1: /* test */
1843 /* Special case in Grp3: test has an immediate source operand. */
1844 src.type = OP_IMM;
1845 src.bytes = (d & ByteOp) ? 1 : op_bytes;
1846 if ( src.bytes == 8 ) src.bytes = 4;
1847 switch ( src.bytes )
1849 case 1: src.val = insn_fetch_type(int8_t); break;
1850 case 2: src.val = insn_fetch_type(int16_t); break;
1851 case 4: src.val = insn_fetch_type(int32_t); break;
1853 goto test;
1854 case 2: /* not */
1855 dst.val = ~dst.val;
1856 break;
1857 case 3: /* neg */
1858 emulate_1op("neg", dst, _regs.eflags);
1859 break;
1860 case 4: /* mul */
1861 src = dst;
1862 dst.type = OP_REG;
1863 dst.reg = (unsigned long *)&_regs.eax;
1864 dst.val = *dst.reg;
1865 _regs.eflags &= ~(EFLG_OF|EFLG_CF);
1866 switch ( src.bytes )
1868 case 1:
1869 dst.val = (uint8_t)dst.val;
1870 dst.val *= src.val;
1871 if ( (uint8_t)dst.val != (uint16_t)dst.val )
1872 _regs.eflags |= EFLG_OF|EFLG_CF;
1873 dst.bytes = 2;
1874 break;
1875 case 2:
1876 dst.val = (uint16_t)dst.val;
1877 dst.val *= src.val;
1878 if ( (uint16_t)dst.val != (uint32_t)dst.val )
1879 _regs.eflags |= EFLG_OF|EFLG_CF;
1880 *(uint16_t *)&_regs.edx = dst.val >> 16;
1881 break;
1882 #ifdef __x86_64__
1883 case 4:
1884 dst.val = (uint32_t)dst.val;
1885 dst.val *= src.val;
1886 if ( (uint32_t)dst.val != dst.val )
1887 _regs.eflags |= EFLG_OF|EFLG_CF;
1888 _regs.edx = (uint32_t)(dst.val >> 32);
1889 break;
1890 #endif
1891 default: {
1892 unsigned long m[2] = { src.val, dst.val };
1893 if ( mul_dbl(m) )
1894 _regs.eflags |= EFLG_OF|EFLG_CF;
1895 _regs.edx = m[1];
1896 dst.val = m[0];
1897 break;
1900 break;
1901 case 5: /* imul */
1902 src = dst;
1903 dst.type = OP_REG;
1904 dst.reg = (unsigned long *)&_regs.eax;
1905 dst.val = *dst.reg;
1906 _regs.eflags &= ~(EFLG_OF|EFLG_CF);
1907 switch ( src.bytes )
1909 case 1:
1910 dst.val = ((uint16_t)(int8_t)src.val *
1911 (uint16_t)(int8_t)dst.val);
1912 if ( (int8_t)dst.val != (uint16_t)dst.val )
1913 _regs.eflags |= EFLG_OF|EFLG_CF;
1914 dst.bytes = 2;
1915 break;
1916 case 2:
1917 dst.val = ((uint32_t)(int16_t)src.val *
1918 (uint32_t)(int16_t)dst.val);
1919 if ( (int16_t)dst.val != (uint32_t)dst.val )
1920 _regs.eflags |= EFLG_OF|EFLG_CF;
1921 *(uint16_t *)&_regs.edx = dst.val >> 16;
1922 break;
1923 #ifdef __x86_64__
1924 case 4:
1925 dst.val = ((uint64_t)(int32_t)src.val *
1926 (uint64_t)(int32_t)dst.val);
1927 if ( (int32_t)dst.val != dst.val )
1928 _regs.eflags |= EFLG_OF|EFLG_CF;
1929 _regs.edx = (uint32_t)(dst.val >> 32);
1930 break;
1931 #endif
1932 default: {
1933 unsigned long m[2] = { src.val, dst.val };
1934 if ( imul_dbl(m) )
1935 _regs.eflags |= EFLG_OF|EFLG_CF;
1936 _regs.edx = m[1];
1937 dst.val = m[0];
1938 break;
1941 break;
1942 case 6: /* div */ {
1943 unsigned long u[2], v;
1944 src = dst;
1945 dst.type = OP_REG;
1946 dst.reg = (unsigned long *)&_regs.eax;
1947 switch ( src.bytes )
1949 case 1:
1950 u[0] = (uint16_t)_regs.eax;
1951 u[1] = 0;
1952 v = (uint8_t)src.val;
1953 generate_exception_if(
1954 div_dbl(u, v) || ((uint8_t)u[0] != (uint16_t)u[0]),
1955 EXC_DE, -1);
1956 dst.val = (uint8_t)u[0];
1957 ((uint8_t *)&_regs.eax)[1] = u[1];
1958 break;
1959 case 2:
1960 u[0] = ((uint32_t)_regs.edx << 16) | (uint16_t)_regs.eax;
1961 u[1] = 0;
1962 v = (uint16_t)src.val;
1963 generate_exception_if(
1964 div_dbl(u, v) || ((uint16_t)u[0] != (uint32_t)u[0]),
1965 EXC_DE, -1);
1966 dst.val = (uint16_t)u[0];
1967 *(uint16_t *)&_regs.edx = u[1];
1968 break;
1969 #ifdef __x86_64__
1970 case 4:
1971 u[0] = (_regs.edx << 32) | (uint32_t)_regs.eax;
1972 u[1] = 0;
1973 v = (uint32_t)src.val;
1974 generate_exception_if(
1975 div_dbl(u, v) || ((uint32_t)u[0] != u[0]),
1976 EXC_DE, -1);
1977 dst.val = (uint32_t)u[0];
1978 _regs.edx = (uint32_t)u[1];
1979 break;
1980 #endif
1981 default:
1982 u[0] = _regs.eax;
1983 u[1] = _regs.edx;
1984 v = src.val;
1985 generate_exception_if(div_dbl(u, v), EXC_DE, -1);
1986 dst.val = u[0];
1987 _regs.edx = u[1];
1988 break;
1990 break;
1992 case 7: /* idiv */ {
1993 unsigned long u[2], v;
1994 src = dst;
1995 dst.type = OP_REG;
1996 dst.reg = (unsigned long *)&_regs.eax;
1997 switch ( src.bytes )
1999 case 1:
2000 u[0] = (int16_t)_regs.eax;
2001 u[1] = ((long)u[0] < 0) ? ~0UL : 0UL;
2002 v = (int8_t)src.val;
2003 generate_exception_if(
2004 idiv_dbl(u, v) || ((int8_t)u[0] != (int16_t)u[0]),
2005 EXC_DE, -1);
2006 dst.val = (int8_t)u[0];
2007 ((int8_t *)&_regs.eax)[1] = u[1];
2008 break;
2009 case 2:
2010 u[0] = (int32_t)((_regs.edx << 16) | (uint16_t)_regs.eax);
2011 u[1] = ((long)u[0] < 0) ? ~0UL : 0UL;
2012 v = (int16_t)src.val;
2013 generate_exception_if(
2014 idiv_dbl(u, v) || ((int16_t)u[0] != (int32_t)u[0]),
2015 EXC_DE, -1);
2016 dst.val = (int16_t)u[0];
2017 *(int16_t *)&_regs.edx = u[1];
2018 break;
2019 #ifdef __x86_64__
2020 case 4:
2021 u[0] = (_regs.edx << 32) | (uint32_t)_regs.eax;
2022 u[1] = ((long)u[0] < 0) ? ~0UL : 0UL;
2023 v = (int32_t)src.val;
2024 generate_exception_if(
2025 idiv_dbl(u, v) || ((int32_t)u[0] != u[0]),
2026 EXC_DE, -1);
2027 dst.val = (int32_t)u[0];
2028 _regs.edx = (uint32_t)u[1];
2029 break;
2030 #endif
2031 default:
2032 u[0] = _regs.eax;
2033 u[1] = _regs.edx;
2034 v = src.val;
2035 generate_exception_if(idiv_dbl(u, v), EXC_DE, -1);
2036 dst.val = u[0];
2037 _regs.edx = u[1];
2038 break;
2040 break;
2042 default:
2043 goto cannot_emulate;
2045 break;
2047 case 0xfe: /* Grp4 */
2048 generate_exception_if((modrm_reg & 7) >= 2, EXC_UD, -1);
2049 case 0xff: /* Grp5 */
2050 switch ( modrm_reg & 7 )
2052 case 0: /* inc */
2053 emulate_1op("inc", dst, _regs.eflags);
2054 break;
2055 case 1: /* dec */
2056 emulate_1op("dec", dst, _regs.eflags);
2057 break;
2058 case 2: /* call (near) */
2059 case 4: /* jmp (near) */
2060 if ( (dst.bytes != 8) && mode_64bit() )
2062 dst.bytes = op_bytes = 8;
2063 if ( dst.type == OP_REG )
2064 dst.val = *dst.reg;
2065 else if ( (rc = read_ulong(dst.mem.seg, dst.mem.off,
2066 &dst.val, 8, ctxt, ops)) != 0 )
2067 goto done;
2069 src.val = _regs.eip;
2070 _regs.eip = dst.val;
2071 if ( (modrm_reg & 7) == 2 )
2072 goto push; /* call */
2073 dst.type = OP_NONE;
2074 break;
2075 case 3: /* call (far, absolute indirect) */
2076 case 5: /* jmp (far, absolute indirect) */ {
2077 unsigned long sel;
2079 generate_exception_if(dst.type != OP_MEM, EXC_UD, -1);
2081 if ( (rc = read_ulong(dst.mem.seg, dst.mem.off+dst.bytes,
2082 &sel, 2, ctxt, ops)) )
2083 goto done;
2085 if ( (modrm_reg & 7) == 3 ) /* call */
2087 struct segment_register reg;
2088 fail_if(ops->read_segment == NULL);
2089 if ( (rc = ops->read_segment(x86_seg_cs, &reg, ctxt)) ||
2090 (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
2091 &reg.sel, op_bytes, ctxt)) ||
2092 (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
2093 &_regs.eip, op_bytes, ctxt)) )
2094 goto done;
2097 if ( (rc = load_seg(x86_seg_cs, sel, ctxt, ops)) != 0 )
2098 goto done;
2099 _regs.eip = dst.val;
2101 dst.type = OP_NONE;
2102 break;
2104 case 6: /* push */
2105 /* 64-bit mode: PUSH defaults to a 64-bit operand. */
2106 if ( mode_64bit() && (dst.bytes == 4) )
2108 dst.bytes = 8;
2109 if ( dst.type == OP_REG )
2110 dst.val = *dst.reg;
2111 else if ( (rc = read_ulong(dst.mem.seg, dst.mem.off,
2112 &dst.val, 8, ctxt, ops)) != 0 )
2113 goto done;
2115 if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes),
2116 &dst.val, dst.bytes, ctxt)) != 0 )
2117 goto done;
2118 dst.type = OP_NONE;
2119 break;
2120 case 7:
2121 generate_exception_if(1, EXC_UD, -1);
2122 default:
2123 goto cannot_emulate;
2125 break;
2128 writeback:
2129 switch ( dst.type )
2131 case OP_REG:
2132 /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */
2133 switch ( dst.bytes )
2135 case 1: *(uint8_t *)dst.reg = (uint8_t)dst.val; break;
2136 case 2: *(uint16_t *)dst.reg = (uint16_t)dst.val; break;
2137 case 4: *dst.reg = (uint32_t)dst.val; break; /* 64b: zero-ext */
2138 case 8: *dst.reg = dst.val; break;
2140 break;
2141 case OP_MEM:
2142 if ( !(d & Mov) && (dst.orig_val == dst.val) &&
2143 !ctxt->force_writeback )
2144 /* nothing to do */;
2145 else if ( lock_prefix )
2146 rc = ops->cmpxchg(
2147 dst.mem.seg, dst.mem.off, &dst.orig_val,
2148 &dst.val, dst.bytes, ctxt);
2149 else
2150 rc = ops->write(
2151 dst.mem.seg, dst.mem.off, &dst.val, dst.bytes, ctxt);
2152 if ( rc != 0 )
2153 goto done;
2154 default:
2155 break;
2158 /* Inject #DB if single-step tracing was enabled at instruction start. */
2159 if ( (ctxt->regs->eflags & EFLG_TF) && (rc == X86EMUL_OKAY) &&
2160 (ops->inject_hw_exception != NULL) )
2161 rc = ops->inject_hw_exception(EXC_DB, -1, ctxt) ? : X86EMUL_EXCEPTION;
2163 /* Commit shadow register state. */
2164 _regs.eflags &= ~EFLG_RF;
2165 *ctxt->regs = _regs;
2167 done:
2168 return rc;
2170 special_insn:
2171 dst.type = OP_NONE;
2173 /*
2174 * The only implicit-operands instructions allowed a LOCK prefix are
2175 * CMPXCHG{8,16}B, MOV CRn, MOV DRn.
2176 */
2177 generate_exception_if(lock_prefix &&
2178 ((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */
2179 (b != 0xc7), /* CMPXCHG{8,16}B */
2180 EXC_GP, 0);
2182 if ( twobyte )
2183 goto twobyte_special_insn;
2185 switch ( b )
2187 case 0x06: /* push %%es */ {
2188 struct segment_register reg;
2189 src.val = x86_seg_es;
2190 push_seg:
2191 fail_if(ops->read_segment == NULL);
2192 if ( (rc = ops->read_segment(src.val, &reg, ctxt)) != 0 )
2193 return rc;
2194 /* 64-bit mode: PUSH defaults to a 64-bit operand. */
2195 if ( mode_64bit() && (op_bytes == 4) )
2196 op_bytes = 8;
2197 if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
2198 &reg.sel, op_bytes, ctxt)) != 0 )
2199 goto done;
2200 break;
2203 case 0x07: /* pop %%es */
2204 src.val = x86_seg_es;
2205 pop_seg:
2206 fail_if(ops->write_segment == NULL);
2207 /* 64-bit mode: POP defaults to a 64-bit operand. */
2208 if ( mode_64bit() && (op_bytes == 4) )
2209 op_bytes = 8;
2210 if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes),
2211 &dst.val, op_bytes, ctxt, ops)) != 0 )
2212 goto done;
2213 if ( (rc = load_seg(src.val, (uint16_t)dst.val, ctxt, ops)) != 0 )
2214 return rc;
2215 break;
2217 case 0x0e: /* push %%cs */
2218 src.val = x86_seg_cs;
2219 goto push_seg;
2221 case 0x16: /* push %%ss */
2222 src.val = x86_seg_ss;
2223 goto push_seg;
2225 case 0x17: /* pop %%ss */
2226 src.val = x86_seg_ss;
2227 ctxt->retire.flags.mov_ss = 1;
2228 goto pop_seg;
2230 case 0x1e: /* push %%ds */
2231 src.val = x86_seg_ds;
2232 goto push_seg;
2234 case 0x1f: /* pop %%ds */
2235 src.val = x86_seg_ds;
2236 goto pop_seg;
2238 case 0x27: /* daa */ {
2239 uint8_t al = _regs.eax;
2240 unsigned long eflags = _regs.eflags;
2241 generate_exception_if(mode_64bit(), EXC_UD, -1);
2242 _regs.eflags &= ~(EFLG_CF|EFLG_AF);
2243 if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
2245 *(uint8_t *)&_regs.eax += 6;
2246 _regs.eflags |= EFLG_AF;
2248 if ( (al > 0x99) || (eflags & EFLG_CF) )
2250 *(uint8_t *)&_regs.eax += 0x60;
2251 _regs.eflags |= EFLG_CF;
2253 _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
2254 _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
2255 _regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0;
2256 _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0;
2257 break;
2260 case 0x2f: /* das */ {
2261 uint8_t al = _regs.eax;
2262 unsigned long eflags = _regs.eflags;
2263 generate_exception_if(mode_64bit(), EXC_UD, -1);
2264 _regs.eflags &= ~(EFLG_CF|EFLG_AF);
2265 if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
2267 _regs.eflags |= EFLG_AF;
2268 if ( (al < 6) || (eflags & EFLG_CF) )
2269 _regs.eflags |= EFLG_CF;
2270 *(uint8_t *)&_regs.eax -= 6;
2272 if ( (al > 0x99) || (eflags & EFLG_CF) )
2274 *(uint8_t *)&_regs.eax -= 0x60;
2275 _regs.eflags |= EFLG_CF;
2277 _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
2278 _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
2279 _regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0;
2280 _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0;
2281 break;
2284 case 0x37: /* aaa */
2285 case 0x3f: /* aas */
2286 generate_exception_if(mode_64bit(), EXC_UD, -1);
2287 _regs.eflags &= ~EFLG_CF;
2288 if ( ((uint8_t)_regs.eax > 9) || (_regs.eflags & EFLG_AF) )
2290 ((uint8_t *)&_regs.eax)[0] += (b == 0x37) ? 6 : -6;
2291 ((uint8_t *)&_regs.eax)[1] += (b == 0x37) ? 1 : -1;
2292 _regs.eflags |= EFLG_CF | EFLG_AF;
2294 ((uint8_t *)&_regs.eax)[0] &= 0x0f;
2295 break;
2297 case 0x40 ... 0x4f: /* inc/dec reg */
2298 dst.type = OP_REG;
2299 dst.reg = decode_register(b & 7, &_regs, 0);
2300 dst.bytes = op_bytes;
2301 dst.val = *dst.reg;
2302 if ( b & 8 )
2303 emulate_1op("dec", dst, _regs.eflags);
2304 else
2305 emulate_1op("inc", dst, _regs.eflags);
2306 break;
2308 case 0x50 ... 0x57: /* push reg */
2309 src.val = *(unsigned long *)decode_register(
2310 (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0);
2311 goto push;
2313 case 0x58 ... 0x5f: /* pop reg */
2314 dst.type = OP_REG;
2315 dst.reg = decode_register(
2316 (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0);
2317 dst.bytes = op_bytes;
2318 if ( mode_64bit() && (dst.bytes == 4) )
2319 dst.bytes = 8;
2320 if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(dst.bytes),
2321 &dst.val, dst.bytes, ctxt, ops)) != 0 )
2322 goto done;
2323 break;
2325 case 0x60: /* pusha */ {
2326 int i;
2327 unsigned long regs[] = {
2328 _regs.eax, _regs.ecx, _regs.edx, _regs.ebx,
2329 _regs.esp, _regs.ebp, _regs.esi, _regs.edi };
2330 generate_exception_if(mode_64bit(), EXC_UD, -1);
2331 for ( i = 0; i < 8; i++ )
2332 if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
2333 &regs[i], op_bytes, ctxt)) != 0 )
2334 goto done;
2335 break;
2338 case 0x61: /* popa */ {
2339 int i;
2340 unsigned long dummy_esp, *regs[] = {
2341 (unsigned long *)&_regs.edi, (unsigned long *)&_regs.esi,
2342 (unsigned long *)&_regs.ebp, (unsigned long *)&dummy_esp,
2343 (unsigned long *)&_regs.ebx, (unsigned long *)&_regs.edx,
2344 (unsigned long *)&_regs.ecx, (unsigned long *)&_regs.eax };
2345 generate_exception_if(mode_64bit(), EXC_UD, -1);
2346 for ( i = 0; i < 8; i++ )
2348 if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes),
2349 &dst.val, op_bytes, ctxt, ops)) != 0 )
2350 goto done;
2351 switch ( op_bytes )
2353 case 1: *(uint8_t *)regs[i] = (uint8_t)dst.val; break;
2354 case 2: *(uint16_t *)regs[i] = (uint16_t)dst.val; break;
2355 case 4: *regs[i] = (uint32_t)dst.val; break; /* 64b: zero-ext */
2356 case 8: *regs[i] = dst.val; break;
2359 break;
2362 case 0x68: /* push imm{16,32,64} */
2363 src.val = ((op_bytes == 2)
2364 ? (int32_t)insn_fetch_type(int16_t)
2365 : insn_fetch_type(int32_t));
2366 goto push;
2368 case 0x6a: /* push imm8 */
2369 src.val = insn_fetch_type(int8_t);
2370 push:
2371 d |= Mov; /* force writeback */
2372 dst.type = OP_MEM;
2373 dst.bytes = op_bytes;
2374 if ( mode_64bit() && (dst.bytes == 4) )
2375 dst.bytes = 8;
2376 dst.val = src.val;
2377 dst.mem.seg = x86_seg_ss;
2378 dst.mem.off = sp_pre_dec(dst.bytes);
2379 break;
2381 case 0x6c ... 0x6d: /* ins %dx,%es:%edi */ {
2382 unsigned long nr_reps = get_rep_prefix();
2383 unsigned int port = (uint16_t)_regs.edx;
2384 dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
2385 dst.mem.seg = x86_seg_es;
2386 dst.mem.off = truncate_ea(_regs.edi);
2387 if ( (rc = ioport_access_check(port, dst.bytes, ctxt, ops)) != 0 )
2388 goto done;
2389 if ( (nr_reps > 1) && (ops->rep_ins != NULL) &&
2390 ((rc = ops->rep_ins(port, dst.mem.seg, dst.mem.off, dst.bytes,
2391 &nr_reps, ctxt)) != X86EMUL_UNHANDLEABLE) )
2393 if ( rc != 0 )
2394 goto done;
2396 else
2398 fail_if(ops->read_io == NULL);
2399 if ( (rc = ops->read_io(port, dst.bytes, &dst.val, ctxt)) != 0 )
2400 goto done;
2401 dst.type = OP_MEM;
2402 nr_reps = 1;
2404 register_address_increment(
2405 _regs.edi,
2406 nr_reps * ((_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes));
2407 put_rep_prefix(nr_reps);
2408 break;
2411 case 0x6e ... 0x6f: /* outs %esi,%dx */ {
2412 unsigned long nr_reps = get_rep_prefix();
2413 unsigned int port = (uint16_t)_regs.edx;
2414 dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
2415 if ( (rc = ioport_access_check(port, dst.bytes, ctxt, ops)) != 0 )
2416 goto done;
2417 if ( (nr_reps > 1) && (ops->rep_outs != NULL) &&
2418 ((rc = ops->rep_outs(ea.mem.seg, truncate_ea(_regs.esi),
2419 port, dst.bytes,
2420 &nr_reps, ctxt)) != X86EMUL_UNHANDLEABLE) )
2422 if ( rc != 0 )
2423 goto done;
2425 else
2427 if ( (rc = read_ulong(ea.mem.seg, truncate_ea(_regs.esi),
2428 &dst.val, dst.bytes, ctxt, ops)) != 0 )
2429 goto done;
2430 fail_if(ops->write_io == NULL);
2431 if ( (rc = ops->write_io(port, dst.bytes, dst.val, ctxt)) != 0 )
2432 goto done;
2433 nr_reps = 1;
2435 register_address_increment(
2436 _regs.esi,
2437 nr_reps * ((_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes));
2438 put_rep_prefix(nr_reps);
2439 break;
2442 case 0x70 ... 0x7f: /* jcc (short) */ {
2443 int rel = insn_fetch_type(int8_t);
2444 if ( test_cc(b, _regs.eflags) )
2445 jmp_rel(rel);
2446 break;
2449 case 0x90: /* nop / xchg %%r8,%%rax */
2450 if ( !(rex_prefix & 1) )
2451 break; /* nop */
2453 case 0x91 ... 0x97: /* xchg reg,%%rax */
2454 src.type = dst.type = OP_REG;
2455 src.bytes = dst.bytes = op_bytes;
2456 src.reg = (unsigned long *)&_regs.eax;
2457 src.val = *src.reg;
2458 dst.reg = decode_register(
2459 (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0);
2460 dst.val = *dst.reg;
2461 goto xchg;
2463 case 0x98: /* cbw/cwde/cdqe */
2464 switch ( op_bytes )
2466 case 2: *(int16_t *)&_regs.eax = (int8_t)_regs.eax; break; /* cbw */
2467 case 4: _regs.eax = (uint32_t)(int16_t)_regs.eax; break; /* cwde */
2468 case 8: _regs.eax = (int32_t)_regs.eax; break; /* cdqe */
2470 break;
2472 case 0x99: /* cwd/cdq/cqo */
2473 switch ( op_bytes )
2475 case 2:
2476 *(int16_t *)&_regs.edx = ((int16_t)_regs.eax < 0) ? -1 : 0;
2477 break;
2478 case 4:
2479 _regs.edx = (uint32_t)(((int32_t)_regs.eax < 0) ? -1 : 0);
2480 break;
2481 case 8:
2482 _regs.edx = (_regs.eax < 0) ? -1 : 0;
2483 break;
2485 break;
2487 case 0x9a: /* call (far, absolute) */ {
2488 struct segment_register reg;
2489 uint16_t sel;
2490 uint32_t eip;
2492 fail_if(ops->read_segment == NULL);
2493 generate_exception_if(mode_64bit(), EXC_UD, -1);
2495 eip = insn_fetch_bytes(op_bytes);
2496 sel = insn_fetch_type(uint16_t);
2498 if ( (rc = ops->read_segment(x86_seg_cs, &reg, ctxt)) ||
2499 (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
2500 &reg.sel, op_bytes, ctxt)) ||
2501 (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
2502 &_regs.eip, op_bytes, ctxt)) )
2503 goto done;
2505 if ( (rc = load_seg(x86_seg_cs, sel, ctxt, ops)) != 0 )
2506 goto done;
2507 _regs.eip = eip;
2508 break;
2511 case 0x9b: /* wait/fwait */
2512 emulate_fpu_insn("fwait");
2513 break;
2515 case 0x9c: /* pushf */
2516 src.val = _regs.eflags;
2517 goto push;
2519 case 0x9d: /* popf */ {
2520 uint32_t mask = EFLG_VIP | EFLG_VIF | EFLG_VM;
2521 if ( !mode_ring0() )
2522 mask |= EFLG_IOPL;
2523 if ( !mode_iopl() )
2524 mask |= EFLG_IF;
2525 /* 64-bit mode: POP defaults to a 64-bit operand. */
2526 if ( mode_64bit() && (op_bytes == 4) )
2527 op_bytes = 8;
2528 if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes),
2529 &dst.val, op_bytes, ctxt, ops)) != 0 )
2530 goto done;
2531 if ( op_bytes == 2 )
2532 dst.val = (uint16_t)dst.val | (_regs.eflags & 0xffff0000u);
2533 dst.val &= 0x257fd5;
2534 _regs.eflags &= mask;
2535 _regs.eflags |= (uint32_t)(dst.val & ~mask) | 0x02;
2536 break;
2539 case 0x9e: /* sahf */
2540 *(uint8_t *)&_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02;
2541 break;
2543 case 0x9f: /* lahf */
2544 ((uint8_t *)&_regs.eax)[1] = (_regs.eflags & 0xd7) | 0x02;
2545 break;
2547 case 0xa0 ... 0xa1: /* mov mem.offs,{%al,%ax,%eax,%rax} */
2548 /* Source EA is not encoded via ModRM. */
2549 dst.type = OP_REG;
2550 dst.reg = (unsigned long *)&_regs.eax;
2551 dst.bytes = (d & ByteOp) ? 1 : op_bytes;
2552 if ( (rc = read_ulong(ea.mem.seg, insn_fetch_bytes(ad_bytes),
2553 &dst.val, dst.bytes, ctxt, ops)) != 0 )
2554 goto done;
2555 break;
2557 case 0xa2 ... 0xa3: /* mov {%al,%ax,%eax,%rax},mem.offs */
2558 /* Destination EA is not encoded via ModRM. */
2559 dst.type = OP_MEM;
2560 dst.mem.seg = ea.mem.seg;
2561 dst.mem.off = insn_fetch_bytes(ad_bytes);
2562 dst.bytes = (d & ByteOp) ? 1 : op_bytes;
2563 dst.val = (unsigned long)_regs.eax;
2564 break;
2566 case 0xa4 ... 0xa5: /* movs */ {
2567 unsigned long nr_reps = get_rep_prefix();
2568 dst.bytes = (d & ByteOp) ? 1 : op_bytes;
2569 dst.mem.seg = x86_seg_es;
2570 dst.mem.off = truncate_ea(_regs.edi);
2571 if ( (nr_reps > 1) && (ops->rep_movs != NULL) &&
2572 ((rc = ops->rep_movs(ea.mem.seg, truncate_ea(_regs.esi),
2573 dst.mem.seg, dst.mem.off, dst.bytes,
2574 &nr_reps, ctxt)) != X86EMUL_UNHANDLEABLE) )
2576 if ( rc != 0 )
2577 goto done;
2579 else
2581 if ( (rc = read_ulong(ea.mem.seg, truncate_ea(_regs.esi),
2582 &dst.val, dst.bytes, ctxt, ops)) != 0 )
2583 goto done;
2584 dst.type = OP_MEM;
2585 nr_reps = 1;
2587 register_address_increment(
2588 _regs.esi,
2589 nr_reps * ((_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes));
2590 register_address_increment(
2591 _regs.edi,
2592 nr_reps * ((_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes));
2593 put_rep_prefix(nr_reps);
2594 break;
2597 case 0xa6 ... 0xa7: /* cmps */ {
2598 unsigned long next_eip = _regs.eip;
2599 get_rep_prefix();
2600 src.bytes = dst.bytes = (d & ByteOp) ? 1 : op_bytes;
2601 if ( (rc = read_ulong(ea.mem.seg, truncate_ea(_regs.esi),
2602 &dst.val, dst.bytes, ctxt, ops)) ||
2603 (rc = read_ulong(x86_seg_es, truncate_ea(_regs.edi),
2604 &src.val, src.bytes, ctxt, ops)) )
2605 goto done;
2606 register_address_increment(
2607 _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
2608 register_address_increment(
2609 _regs.edi, (_regs.eflags & EFLG_DF) ? -src.bytes : src.bytes);
2610 put_rep_prefix(1);
2611 /* cmp: dst - src ==> src=*%%edi,dst=*%%esi ==> *%%esi - *%%edi */
2612 emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
2613 if ( ((rep_prefix == REPE_PREFIX) && !(_regs.eflags & EFLG_ZF)) ||
2614 ((rep_prefix == REPNE_PREFIX) && (_regs.eflags & EFLG_ZF)) )
2615 _regs.eip = next_eip;
2616 break;
2619 case 0xaa ... 0xab: /* stos */ {
2620 /* unsigned long max_reps = */get_rep_prefix();
2621 dst.type = OP_MEM;
2622 dst.bytes = (d & ByteOp) ? 1 : op_bytes;
2623 dst.mem.seg = x86_seg_es;
2624 dst.mem.off = truncate_ea(_regs.edi);
2625 dst.val = _regs.eax;
2626 register_address_increment(
2627 _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
2628 put_rep_prefix(1);
2629 break;
2632 case 0xac ... 0xad: /* lods */ {
2633 /* unsigned long max_reps = */get_rep_prefix();
2634 dst.type = OP_REG;
2635 dst.bytes = (d & ByteOp) ? 1 : op_bytes;
2636 dst.reg = (unsigned long *)&_regs.eax;
2637 if ( (rc = read_ulong(ea.mem.seg, truncate_ea(_regs.esi),
2638 &dst.val, dst.bytes, ctxt, ops)) != 0 )
2639 goto done;
2640 register_address_increment(
2641 _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes);
2642 put_rep_prefix(1);
2643 break;
2646 case 0xae ... 0xaf: /* scas */ {
2647 unsigned long next_eip = _regs.eip;
2648 get_rep_prefix();
2649 src.bytes = dst.bytes = (d & ByteOp) ? 1 : op_bytes;
2650 dst.val = _regs.eax;
2651 if ( (rc = read_ulong(x86_seg_es, truncate_ea(_regs.edi),
2652 &src.val, src.bytes, ctxt, ops)) != 0 )
2653 goto done;
2654 register_address_increment(
2655 _regs.edi, (_regs.eflags & EFLG_DF) ? -src.bytes : src.bytes);
2656 put_rep_prefix(1);
2657 /* cmp: dst - src ==> src=*%%edi,dst=%%eax ==> %%eax - *%%edi */
2658 emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
2659 if ( ((rep_prefix == REPE_PREFIX) && !(_regs.eflags & EFLG_ZF)) ||
2660 ((rep_prefix == REPNE_PREFIX) && (_regs.eflags & EFLG_ZF)) )
2661 _regs.eip = next_eip;
2662 break;
2665 case 0xc2: /* ret imm16 (near) */
2666 case 0xc3: /* ret (near) */ {
2667 int offset = (b == 0xc2) ? insn_fetch_type(uint16_t) : 0;
2668 op_bytes = mode_64bit() ? 8 : op_bytes;
2669 if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes + offset),
2670 &dst.val, op_bytes, ctxt, ops)) != 0 )
2671 goto done;
2672 _regs.eip = dst.val;
2673 break;
2676 case 0xc8: /* enter imm16,imm8 */ {
2677 uint16_t size = insn_fetch_type(uint16_t);
2678 uint8_t depth = insn_fetch_type(uint8_t) & 31;
2679 int i;
2681 dst.type = OP_REG;
2682 dst.bytes = (mode_64bit() && (op_bytes == 4)) ? 8 : op_bytes;
2683 dst.reg = (unsigned long *)&_regs.ebp;
2684 if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes),
2685 &_regs.ebp, dst.bytes, ctxt)) )
2686 goto done;
2687 dst.val = _regs.esp;
2689 if ( depth > 0 )
2691 for ( i = 1; i < depth; i++ )
2693 unsigned long ebp, temp_data;
2694 ebp = truncate_word(_regs.ebp - i*dst.bytes, ctxt->sp_size/8);
2695 if ( (rc = read_ulong(x86_seg_ss, ebp,
2696 &temp_data, dst.bytes, ctxt, ops)) ||
2697 (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes),
2698 &temp_data, dst.bytes, ctxt)) )
2699 goto done;
2701 if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes),
2702 &dst.val, dst.bytes, ctxt)) )
2703 goto done;
2706 sp_pre_dec(size);
2707 break;
2710 case 0xc9: /* leave */
2711 /* First writeback, to %%esp. */
2712 dst.type = OP_REG;
2713 dst.bytes = (mode_64bit() && (op_bytes == 4)) ? 8 : op_bytes;
2714 dst.reg = (unsigned long *)&_regs.esp;
2715 dst.val = _regs.ebp;
2717 /* Flush first writeback, since there is a second. */
2718 switch ( dst.bytes )
2720 case 1: *(uint8_t *)dst.reg = (uint8_t)dst.val; break;
2721 case 2: *(uint16_t *)dst.reg = (uint16_t)dst.val; break;
2722 case 4: *dst.reg = (uint32_t)dst.val; break; /* 64b: zero-ext */
2723 case 8: *dst.reg = dst.val; break;
2726 /* Second writeback, to %%ebp. */
2727 dst.reg = (unsigned long *)&_regs.ebp;
2728 if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(dst.bytes),
2729 &dst.val, dst.bytes, ctxt, ops)) )
2730 goto done;
2731 break;
2733 case 0xca: /* ret imm16 (far) */
2734 case 0xcb: /* ret (far) */ {
2735 int offset = (b == 0xca) ? insn_fetch_type(uint16_t) : 0;
2736 op_bytes = mode_64bit() ? 8 : op_bytes;
2737 if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes),
2738 &dst.val, op_bytes, ctxt, ops)) ||
2739 (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes + offset),
2740 &src.val, op_bytes, ctxt, ops)) ||
2741 (rc = load_seg(x86_seg_cs, (uint16_t)src.val, ctxt, ops)) )
2742 goto done;
2743 _regs.eip = dst.val;
2744 break;
2747 case 0xcc: /* int3 */
2748 src.val = EXC_BP;
2749 goto swint;
2751 case 0xcd: /* int imm8 */
2752 src.val = insn_fetch_type(uint8_t);
2753 swint:
2754 fail_if(ops->inject_sw_interrupt == NULL);
2755 rc = ops->inject_sw_interrupt(src.val, _regs.eip - ctxt->regs->eip,
2756 ctxt) ? : X86EMUL_EXCEPTION;
2757 goto done;
2759 case 0xce: /* into */
2760 generate_exception_if(mode_64bit(), EXC_UD, -1);
2761 if ( !(_regs.eflags & EFLG_OF) )
2762 break;
2763 src.val = EXC_OF;
2764 goto swint;
2766 case 0xcf: /* iret */ {
2767 unsigned long cs, eip, eflags;
2768 uint32_t mask = EFLG_VIP | EFLG_VIF | EFLG_VM;
2769 if ( !mode_ring0() )
2770 mask |= EFLG_IOPL;
2771 if ( !mode_iopl() )
2772 mask |= EFLG_IF;
2773 fail_if(!in_realmode(ctxt, ops));
2774 if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes),
2775 &eip, op_bytes, ctxt, ops)) ||
2776 (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes),
2777 &cs, op_bytes, ctxt, ops)) ||
2778 (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes),
2779 &eflags, op_bytes, ctxt, ops)) )
2780 goto done;
2781 if ( op_bytes == 2 )
2782 eflags = (uint16_t)eflags | (_regs.eflags & 0xffff0000u);
2783 eflags &= 0x257fd5;
2784 _regs.eflags &= mask;
2785 _regs.eflags |= (uint32_t)(eflags & ~mask) | 0x02;
2786 _regs.eip = eip;
2787 if ( (rc = load_seg(x86_seg_cs, (uint16_t)cs, ctxt, ops)) != 0 )
2788 goto done;
2789 break;
2792 case 0xd4: /* aam */ {
2793 unsigned int base = insn_fetch_type(uint8_t);
2794 uint8_t al = _regs.eax;
2795 generate_exception_if(mode_64bit(), EXC_UD, -1);
2796 generate_exception_if(base == 0, EXC_DE, -1);
2797 *(uint16_t *)&_regs.eax = ((al / base) << 8) | (al % base);
2798 _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
2799 _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
2800 _regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0;
2801 _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0;
2802 break;
2805 case 0xd5: /* aad */ {
2806 unsigned int base = insn_fetch_type(uint8_t);
2807 uint16_t ax = _regs.eax;
2808 generate_exception_if(mode_64bit(), EXC_UD, -1);
2809 *(uint16_t *)&_regs.eax = (uint8_t)(ax + ((ax >> 8) * base));
2810 _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
2811 _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
2812 _regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0;
2813 _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0;
2814 break;
2817 case 0xd6: /* salc */
2818 generate_exception_if(mode_64bit(), EXC_UD, -1);
2819 *(uint8_t *)&_regs.eax = (_regs.eflags & EFLG_CF) ? 0xff : 0x00;
2820 break;
2822 case 0xd7: /* xlat */ {
2823 unsigned long al = (uint8_t)_regs.eax;
2824 if ( (rc = read_ulong(ea.mem.seg, truncate_ea(_regs.ebx + al),
2825 &al, 1, ctxt, ops)) != 0 )
2826 goto done;
2827 *(uint8_t *)&_regs.eax = al;
2828 break;
2831 case 0xd8: /* FPU 0xd8 */
2832 switch ( modrm )
2834 case 0xc0 ... 0xc7: /* fadd %stN,%stN */
2835 case 0xc8 ... 0xcf: /* fmul %stN,%stN */
2836 case 0xd0 ... 0xd7: /* fcom %stN,%stN */
2837 case 0xd8 ... 0xdf: /* fcomp %stN,%stN */
2838 case 0xe0 ... 0xe7: /* fsub %stN,%stN */
2839 case 0xe8 ... 0xef: /* fsubr %stN,%stN */
2840 case 0xf0 ... 0xf7: /* fdiv %stN,%stN */
2841 case 0xf8 ... 0xff: /* fdivr %stN,%stN */
2842 emulate_fpu_insn_stub(0xd8, modrm);
2843 break;
2844 default:
2845 fail_if(modrm >= 0xc0);
2846 ea.bytes = 4;
2847 src = ea;
2848 if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val,
2849 src.bytes, ctxt)) != 0 )
2850 goto done;
2851 switch ( modrm_reg & 7 )
2853 case 0: /* fadd */
2854 emulate_fpu_insn_memsrc("fadds", src.val);
2855 break;
2856 case 1: /* fmul */
2857 emulate_fpu_insn_memsrc("fmuls", src.val);
2858 break;
2859 case 2: /* fcom */
2860 emulate_fpu_insn_memsrc("fcoms", src.val);
2861 break;
2862 case 3: /* fcomp */
2863 emulate_fpu_insn_memsrc("fcomps", src.val);
2864 break;
2865 case 4: /* fsub */
2866 emulate_fpu_insn_memsrc("fsubs", src.val);
2867 break;
2868 case 5: /* fsubr */
2869 emulate_fpu_insn_memsrc("fsubrs", src.val);
2870 break;
2871 case 6: /* fdiv */
2872 emulate_fpu_insn_memsrc("fdivs", src.val);
2873 break;
2874 case 7: /* fdivr */
2875 emulate_fpu_insn_memsrc("fdivrs", src.val);
2876 break;
2877 default:
2878 goto cannot_emulate;
2881 break;
2883 case 0xd9: /* FPU 0xd9 */
2884 switch ( modrm )
2886 case 0xc0 ... 0xc7: /* fld %stN */
2887 case 0xc8 ... 0xcf: /* fxch %stN */
2888 case 0xd0: /* fnop */
2889 case 0xe0: /* fchs */
2890 case 0xe1: /* fabs */
2891 case 0xe4: /* ftst */
2892 case 0xe5: /* fxam */
2893 case 0xe8: /* fld1 */
2894 case 0xe9: /* fldl2t */
2895 case 0xea: /* fldl2e */
2896 case 0xeb: /* fldpi */
2897 case 0xec: /* fldlg2 */
2898 case 0xed: /* fldln2 */
2899 case 0xee: /* fldz */
2900 case 0xf0: /* f2xm1 */
2901 case 0xf1: /* fyl2x */
2902 case 0xf2: /* fptan */
2903 case 0xf3: /* fpatan */
2904 case 0xf4: /* fxtract */
2905 case 0xf5: /* fprem1 */
2906 case 0xf6: /* fdecstp */
2907 case 0xf7: /* fincstp */
2908 case 0xf8: /* fprem */
2909 case 0xf9: /* fyl2xp1 */
2910 case 0xfa: /* fsqrt */
2911 case 0xfb: /* fsincos */
2912 case 0xfc: /* frndint */
2913 case 0xfd: /* fscale */
2914 case 0xfe: /* fsin */
2915 case 0xff: /* fcos */
2916 emulate_fpu_insn_stub(0xd9, modrm);
2917 break;
2918 default:
2919 fail_if(modrm >= 0xc0);
2920 switch ( modrm_reg & 7 )
2922 case 0: /* fld m32fp */
2923 ea.bytes = 4;
2924 src = ea;
2925 if ( (rc = ops->read(ea.mem.seg, ea.mem.off, &src.val,
2926 src.bytes, ctxt)) != 0 )
2927 goto done;
2928 emulate_fpu_insn_memsrc("flds", src.val);
2929 break;
2930 case 2: /* fstp m32fp */
2931 ea.bytes = 4;
2932 dst = ea;
2933 dst.type = OP_MEM;
2934 emulate_fpu_insn_memdst("fsts", dst.val);
2935 break;
2936 case 3: /* fstp m32fp */
2937 ea.bytes = 4;
2938 dst = ea;
2939 dst.type = OP_MEM;
2940 emulate_fpu_insn_memdst("fstps", dst.val);
2941 break;
2942 /* case 4: fldenv - TODO */
2943 case 5: /* fldcw m2byte */
2944 ea.bytes = 2;
2945 src = ea;
2946 if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val,
2947 src.bytes, ctxt)) != 0 )
2948 goto done;
2949 emulate_fpu_insn_memsrc("fldcw", src.val);
2950 break;
2951 /* case 6: fstenv - TODO */
2952 case 7: /* fnstcw m2byte */
2953 ea.bytes = 2;
2954 dst = ea;
2955 dst.type = OP_MEM;
2956 emulate_fpu_insn_memdst("fnstcw", dst.val);
2957 break;
2958 default:
2959 goto cannot_emulate;
2962 break;
2964 case 0xda: /* FPU 0xda */
2965 switch ( modrm )
2967 case 0xc0 ... 0xc7: /* fcmovb %stN */
2968 case 0xc8 ... 0xcf: /* fcmove %stN */
2969 case 0xd0 ... 0xd7: /* fcmovbe %stN */
2970 case 0xd8 ... 0xdf: /* fcmovu %stN */
2971 case 0xe9: /* fucompp */
2972 emulate_fpu_insn_stub(0xda, modrm);
2973 break;
2974 default:
2975 fail_if(modrm >= 0xc0);
2976 ea.bytes = 8;
2977 src = ea;
2978 if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val,
2979 src.bytes, ctxt)) != 0 )
2980 goto done;
2981 switch ( modrm_reg & 7 )
2983 case 0: /* fiadd m64i */
2984 emulate_fpu_insn_memsrc("fiaddl", src.val);
2985 break;
2986 case 1: /* fimul m64i */
2987 emulate_fpu_insn_memsrc("fimul", src.val);
2988 break;
2989 case 2: /* ficom m64i */
2990 emulate_fpu_insn_memsrc("ficoml", src.val);
2991 break;
2992 case 3: /* ficomp m64i */
2993 emulate_fpu_insn_memsrc("ficompl", src.val);
2994 break;
2995 case 4: /* fisub m64i */
2996 emulate_fpu_insn_memsrc("fisubl", src.val);
2997 break;
2998 case 5: /* fisubr m64i */
2999 emulate_fpu_insn_memsrc("fisubrl", src.val);
3000 break;
3001 case 6: /* fidiv m64i */
3002 emulate_fpu_insn_memsrc("fidivl", src.val);
3003 break;
3004 case 7: /* fidivr m64i */
3005 emulate_fpu_insn_memsrc("fidivrl", src.val);
3006 break;
3007 default:
3008 goto cannot_emulate;
3011 break;
3013 case 0xdb: /* FPU 0xdb */
3014 switch ( modrm )
3016 case 0xc0 ... 0xc7: /* fcmovnb %stN */
3017 case 0xc8 ... 0xcf: /* fcmovne %stN */
3018 case 0xd0 ... 0xd7: /* fcmovnbe %stN */
3019 case 0xd8 ... 0xdf: /* fcmovnu %stN */
3020 emulate_fpu_insn_stub(0xdb, modrm);
3021 break;
3022 case 0xe2: /* fnclex */
3023 emulate_fpu_insn("fnclex");
3024 break;
3025 case 0xe3: /* fninit */
3026 emulate_fpu_insn("fninit");
3027 break;
3028 case 0xe4: /* fsetpm - 287 only, ignored by 387 */
3029 break;
3030 case 0xe8 ... 0xef: /* fucomi %stN */
3031 case 0xf0 ... 0xf7: /* fcomi %stN */
3032 emulate_fpu_insn_stub(0xdb, modrm);
3033 break;
3034 default:
3035 fail_if(modrm >= 0xc0);
3036 switch ( modrm_reg & 7 )
3038 case 0: /* fild m32i */
3039 ea.bytes = 4;
3040 src = ea;
3041 if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val,
3042 src.bytes, ctxt)) != 0 )
3043 goto done;
3044 emulate_fpu_insn_memsrc("fildl", src.val);
3045 break;
3046 case 1: /* fisttp m32i */
3047 ea.bytes = 4;
3048 dst = ea;
3049 dst.type = OP_MEM;
3050 emulate_fpu_insn_memdst("fisttpl", dst.val);
3051 break;
3052 case 2: /* fist m32i */
3053 ea.bytes = 4;
3054 dst = ea;
3055 dst.type = OP_MEM;
3056 emulate_fpu_insn_memdst("fistl", dst.val);
3057 break;
3058 case 3: /* fistp m32i */
3059 ea.bytes = 4;
3060 dst = ea;
3061 dst.type = OP_MEM;
3062 emulate_fpu_insn_memdst("fistpl", dst.val);
3063 break;
3064 case 5: /* fld m80fp */
3065 ea.bytes = 10;
3066 src = ea;
3067 if ( (rc = ops->read(src.mem.seg, src.mem.off,
3068 &src.val, src.bytes, ctxt)) != 0 )
3069 goto done;
3070 emulate_fpu_insn_memdst("fldt", src.val);
3071 break;
3072 case 7: /* fstp m80fp */
3073 ea.bytes = 10;
3074 dst.type = OP_MEM;
3075 dst = ea;
3076 emulate_fpu_insn_memdst("fstpt", dst.val);
3077 break;
3078 default:
3079 goto cannot_emulate;
3082 break;
3084 case 0xdc: /* FPU 0xdc */
3085 switch ( modrm )
3087 case 0xc0 ... 0xc7: /* fadd %stN */
3088 case 0xc8 ... 0xcf: /* fmul %stN */
3089 case 0xe0 ... 0xe7: /* fsubr %stN */
3090 case 0xe8 ... 0xef: /* fsub %stN */
3091 case 0xf0 ... 0xf7: /* fdivr %stN */
3092 case 0xf8 ... 0xff: /* fdiv %stN */
3093 emulate_fpu_insn_stub(0xdc, modrm);
3094 break;
3095 default:
3096 fail_if(modrm >= 0xc0);
3097 ea.bytes = 8;
3098 src = ea;
3099 if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val,
3100 src.bytes, ctxt)) != 0 )
3101 goto done;
3102 switch ( modrm_reg & 7 )
3104 case 0: /* fadd m64fp */
3105 emulate_fpu_insn_memsrc("faddl", src.val);
3106 break;
3107 case 1: /* fmul m64fp */
3108 emulate_fpu_insn_memsrc("fmull", src.val);
3109 break;
3110 case 2: /* fcom m64fp */
3111 emulate_fpu_insn_memsrc("fcoml", src.val);
3112 break;
3113 case 3: /* fcomp m64fp */
3114 emulate_fpu_insn_memsrc("fcompl", src.val);
3115 break;
3116 case 4: /* fsub m64fp */
3117 emulate_fpu_insn_memsrc("fsubl", src.val);
3118 break;
3119 case 5: /* fsubr m64fp */
3120 emulate_fpu_insn_memsrc("fsubrl", src.val);
3121 break;
3122 case 6: /* fdiv m64fp */
3123 emulate_fpu_insn_memsrc("fdivl", src.val);
3124 break;
3125 case 7: /* fdivr m64fp */
3126 emulate_fpu_insn_memsrc("fdivrl", src.val);
3127 break;
3130 break;
3132 case 0xdd: /* FPU 0xdd */
3133 switch ( modrm )
3135 case 0xc0 ... 0xc7: /* ffree %stN */
3136 case 0xd0 ... 0xd7: /* fst %stN */
3137 case 0xd8 ... 0xdf: /* fstp %stN */
3138 case 0xe0 ... 0xe7: /* fucom %stN */
3139 case 0xe8 ... 0xef: /* fucomp %stN */
3140 emulate_fpu_insn_stub(0xdd, modrm);
3141 break;
3142 default:
3143 fail_if(modrm >= 0xc0);
3144 switch ( modrm_reg & 7 )
3146 case 0: /* fld m64fp */;
3147 ea.bytes = 8;
3148 src = ea;
3149 if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val,
3150 src.bytes, ctxt)) != 0 )
3151 goto done;
3152 emulate_fpu_insn_memsrc("fldl", src.val);
3153 break;
3154 case 1: /* fisttp m64i */
3155 ea.bytes = 8;
3156 dst = ea;
3157 dst.type = OP_MEM;
3158 emulate_fpu_insn_memdst("fisttpll", dst.val);
3159 break;
3160 case 2: /* fst m64fp */
3161 ea.bytes = 8;
3162 dst = ea;
3163 dst.type = OP_MEM;
3164 emulate_fpu_insn_memsrc("fstl", dst.val);
3165 break;
3166 case 3: /* fstp m64fp */
3167 ea.bytes = 8;
3168 dst = ea;
3169 dst.type = OP_MEM;
3170 emulate_fpu_insn_memdst("fstpl", dst.val);
3171 break;
3172 case 7: /* fnstsw m2byte */
3173 ea.bytes = 2;
3174 dst = ea;
3175 dst.type = OP_MEM;
3176 emulate_fpu_insn_memdst("fnstsw", dst.val);
3177 break;
3178 default:
3179 goto cannot_emulate;
3182 break;
3184 case 0xde: /* FPU 0xde */
3185 switch ( modrm )
3187 case 0xc0 ... 0xc7: /* faddp %stN */
3188 case 0xc8 ... 0xcf: /* fmulp %stN */
3189 case 0xd9: /* fcompp */
3190 case 0xe0 ... 0xe7: /* fsubrp %stN */
3191 case 0xe8 ... 0xef: /* fsubp %stN */
3192 case 0xf0 ... 0xf7: /* fdivrp %stN */
3193 case 0xf8 ... 0xff: /* fdivp %stN */
3194 emulate_fpu_insn_stub(0xde, modrm);
3195 break;
3196 default:
3197 fail_if(modrm >= 0xc0);
3198 ea.bytes = 2;
3199 src = ea;
3200 if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val,
3201 src.bytes, ctxt)) != 0 )
3202 goto done;
3203 switch ( modrm_reg & 7 )
3205 case 0: /* fiadd m16i */
3206 emulate_fpu_insn_memsrc("fiadd", src.val);
3207 break;
3208 case 1: /* fimul m16i */
3209 emulate_fpu_insn_memsrc("fimul", src.val);
3210 break;
3211 case 2: /* ficom m16i */
3212 emulate_fpu_insn_memsrc("ficom", src.val);
3213 break;
3214 case 3: /* ficomp m16i */
3215 emulate_fpu_insn_memsrc("ficomp", src.val);
3216 break;
3217 case 4: /* fisub m16i */
3218 emulate_fpu_insn_memsrc("fisub", src.val);
3219 break;
3220 case 5: /* fisubr m16i */
3221 emulate_fpu_insn_memsrc("fisubr", src.val);
3222 break;
3223 case 6: /* fidiv m16i */
3224 emulate_fpu_insn_memsrc("fidiv", src.val);
3225 break;
3226 case 7: /* fidivr m16i */
3227 emulate_fpu_insn_memsrc("fidivr", src.val);
3228 break;
3229 default:
3230 goto cannot_emulate;
3233 break;
3235 case 0xdf: /* FPU 0xdf */
3236 switch ( modrm )
3238 case 0xe0:
3239 /* fnstsw %ax */
3240 dst.bytes = 2;
3241 dst.type = OP_REG;
3242 dst.reg = (unsigned long *)&_regs.eax;
3243 emulate_fpu_insn_memdst("fnstsw", dst.val);
3244 break;
3245 case 0xf0 ... 0xf7: /* fcomip %stN */
3246 case 0xf8 ... 0xff: /* fucomip %stN */
3247 emulate_fpu_insn_stub(0xdf, modrm);
3248 break;
3249 default:
3250 fail_if(modrm >= 0xc0);
3251 switch ( modrm_reg & 7 )
3253 case 0: /* fild m16i */
3254 ea.bytes = 2;
3255 src = ea;
3256 if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val,
3257 src.bytes, ctxt)) != 0 )
3258 goto done;
3259 emulate_fpu_insn_memsrc("fild", src.val);
3260 break;
3261 case 1: /* fisttp m16i */
3262 ea.bytes = 2;
3263 dst = ea;
3264 dst.type = OP_MEM;
3265 emulate_fpu_insn_memdst("fisttp", dst.val);
3266 break;
3267 case 2: /* fist m16i */
3268 ea.bytes = 2;
3269 dst = ea;
3270 dst.type = OP_MEM;
3271 emulate_fpu_insn_memdst("fist", dst.val);
3272 break;
3273 case 3: /* fistp m16i */
3274 ea.bytes = 2;
3275 dst = ea;
3276 dst.type = OP_MEM;
3277 emulate_fpu_insn_memdst("fistp", dst.val);
3278 break;
3279 case 4: /* fbld m80dec */
3280 ea.bytes = 10;
3281 dst = ea;
3282 if ( (rc = ops->read(src.mem.seg, src.mem.off,
3283 &src.val, src.bytes, ctxt)) != 0 )
3284 goto done;
3285 emulate_fpu_insn_memdst("fbld", src.val);
3286 break;
3287 case 5: /* fild m64i */
3288 ea.bytes = 8;
3289 src = ea;
3290 if ( (rc = ops->read(src.mem.seg, src.mem.off, &src.val,
3291 src.bytes, ctxt)) != 0 )
3292 goto done;
3293 emulate_fpu_insn_memsrc("fildll", src.val);
3294 break;
3295 case 6: /* fbstp packed bcd */
3296 ea.bytes = 10;
3297 dst = ea;
3298 dst.type = OP_MEM;
3299 emulate_fpu_insn_memdst("fbstp", dst.val);
3300 break;
3301 case 7: /* fistp m64i */
3302 ea.bytes = 8;
3303 dst = ea;
3304 dst.type = OP_MEM;
3305 emulate_fpu_insn_memdst("fistpll", dst.val);
3306 break;
3307 default:
3308 goto cannot_emulate;
3311 break;
3313 case 0xe0 ... 0xe2: /* loop{,z,nz} */ {
3314 int rel = insn_fetch_type(int8_t);
3315 int do_jmp = !(_regs.eflags & EFLG_ZF); /* loopnz */
3316 if ( b == 0xe1 )
3317 do_jmp = !do_jmp; /* loopz */
3318 else if ( b == 0xe2 )
3319 do_jmp = 1; /* loop */
3320 switch ( ad_bytes )
3322 case 2:
3323 do_jmp &= --(*(uint16_t *)&_regs.ecx) != 0;
3324 break;
3325 case 4:
3326 do_jmp &= --(*(uint32_t *)&_regs.ecx) != 0;
3327 _regs.ecx = (uint32_t)_regs.ecx; /* zero extend in x86/64 mode */
3328 break;
3329 default: /* case 8: */
3330 do_jmp &= --_regs.ecx != 0;
3331 break;
3333 if ( do_jmp )
3334 jmp_rel(rel);
3335 break;
3338 case 0xe3: /* jcxz/jecxz (short) */ {
3339 int rel = insn_fetch_type(int8_t);
3340 if ( (ad_bytes == 2) ? !(uint16_t)_regs.ecx :
3341 (ad_bytes == 4) ? !(uint32_t)_regs.ecx : !_regs.ecx )
3342 jmp_rel(rel);
3343 break;
3346 case 0xe4: /* in imm8,%al */
3347 case 0xe5: /* in imm8,%eax */
3348 case 0xe6: /* out %al,imm8 */
3349 case 0xe7: /* out %eax,imm8 */
3350 case 0xec: /* in %dx,%al */
3351 case 0xed: /* in %dx,%eax */
3352 case 0xee: /* out %al,%dx */
3353 case 0xef: /* out %eax,%dx */ {
3354 unsigned int port = ((b < 0xe8)
3355 ? insn_fetch_type(uint8_t)
3356 : (uint16_t)_regs.edx);
3357 op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
3358 if ( (rc = ioport_access_check(port, op_bytes, ctxt, ops)) != 0 )
3359 goto done;
3360 if ( b & 2 )
3362 /* out */
3363 fail_if(ops->write_io == NULL);
3364 rc = ops->write_io(port, op_bytes, _regs.eax, ctxt);
3366 else
3368 /* in */
3369 dst.type = OP_REG;
3370 dst.bytes = op_bytes;
3371 dst.reg = (unsigned long *)&_regs.eax;
3372 fail_if(ops->read_io == NULL);
3373 rc = ops->read_io(port, dst.bytes, &dst.val, ctxt);
3375 if ( rc != 0 )
3376 goto done;
3377 break;
3380 case 0xe8: /* call (near) */ {
3381 int rel = (((op_bytes == 2) && !mode_64bit())
3382 ? (int32_t)insn_fetch_type(int16_t)
3383 : insn_fetch_type(int32_t));
3384 op_bytes = mode_64bit() ? 8 : op_bytes;
3385 src.val = _regs.eip;
3386 jmp_rel(rel);
3387 goto push;
3390 case 0xe9: /* jmp (near) */ {
3391 int rel = (((op_bytes == 2) && !mode_64bit())
3392 ? (int32_t)insn_fetch_type(int16_t)
3393 : insn_fetch_type(int32_t));
3394 jmp_rel(rel);
3395 break;
3398 case 0xea: /* jmp (far, absolute) */ {
3399 uint16_t sel;
3400 uint32_t eip;
3401 generate_exception_if(mode_64bit(), EXC_UD, -1);
3402 eip = insn_fetch_bytes(op_bytes);
3403 sel = insn_fetch_type(uint16_t);
3404 if ( (rc = load_seg(x86_seg_cs, sel, ctxt, ops)) != 0 )
3405 goto done;
3406 _regs.eip = eip;
3407 break;
3410 case 0xeb: /* jmp (short) */ {
3411 int rel = insn_fetch_type(int8_t);
3412 jmp_rel(rel);
3413 break;
3416 case 0xf1: /* int1 (icebp) */
3417 src.val = EXC_DB;
3418 goto swint;
3420 case 0xf4: /* hlt */
3421 ctxt->retire.flags.hlt = 1;
3422 break;
3424 case 0xf5: /* cmc */
3425 _regs.eflags ^= EFLG_CF;
3426 break;
3428 case 0xf8: /* clc */
3429 _regs.eflags &= ~EFLG_CF;
3430 break;
3432 case 0xf9: /* stc */
3433 _regs.eflags |= EFLG_CF;
3434 break;
3436 case 0xfa: /* cli */
3437 generate_exception_if(!mode_iopl(), EXC_GP, 0);
3438 _regs.eflags &= ~EFLG_IF;
3439 break;
3441 case 0xfb: /* sti */
3442 generate_exception_if(!mode_iopl(), EXC_GP, 0);
3443 if ( !(_regs.eflags & EFLG_IF) )
3445 _regs.eflags |= EFLG_IF;
3446 ctxt->retire.flags.sti = 1;
3448 break;
3450 case 0xfc: /* cld */
3451 _regs.eflags &= ~EFLG_DF;
3452 break;
3454 case 0xfd: /* std */
3455 _regs.eflags |= EFLG_DF;
3456 break;
3458 goto writeback;
3460 twobyte_insn:
3461 switch ( b )
3463 case 0x40 ... 0x4f: /* cmovcc */
3464 dst.val = src.val;
3465 if ( !test_cc(b, _regs.eflags) )
3466 dst.type = OP_NONE;
3467 break;
3469 case 0x90 ... 0x9f: /* setcc */
3470 dst.val = test_cc(b, _regs.eflags);
3471 break;
3473 case 0xb0 ... 0xb1: /* cmpxchg */
3474 /* Save real source value, then compare EAX against destination. */
3475 src.orig_val = src.val;
3476 src.val = _regs.eax;
3477 emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
3478 if ( _regs.eflags & EFLG_ZF )
3480 /* Success: write back to memory. */
3481 dst.val = src.orig_val;
3483 else
3485 /* Failure: write the value we saw to EAX. */
3486 dst.type = OP_REG;
3487 dst.reg = (unsigned long *)&_regs.eax;
3489 break;
3491 case 0xa3: bt: /* bt */
3492 emulate_2op_SrcV_nobyte("bt", src, dst, _regs.eflags);
3493 dst.type = OP_NONE;
3494 break;
3496 case 0xa4: /* shld imm8,r,r/m */
3497 case 0xa5: /* shld %%cl,r,r/m */
3498 case 0xac: /* shrd imm8,r,r/m */
3499 case 0xad: /* shrd %%cl,r,r/m */ {
3500 uint8_t shift, width = dst.bytes << 3;
3501 shift = (b & 1) ? (uint8_t)_regs.ecx : insn_fetch_type(uint8_t);
3502 if ( (shift &= width - 1) == 0 )
3503 break;
3504 dst.orig_val = truncate_word(dst.val, dst.bytes);
3505 dst.val = ((shift == width) ? src.val :
3506 (b & 8) ?
3507 /* shrd */
3508 ((dst.orig_val >> shift) |
3509 truncate_word(src.val << (width - shift), dst.bytes)) :
3510 /* shld */
3511 ((dst.orig_val << shift) |
3512 ((src.val >> (width - shift)) & ((1ull << shift) - 1))));
3513 dst.val = truncate_word(dst.val, dst.bytes);
3514 _regs.eflags &= ~(EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_PF|EFLG_CF);
3515 if ( (dst.val >> ((b & 8) ? (shift - 1) : (width - shift))) & 1 )
3516 _regs.eflags |= EFLG_CF;
3517 if ( ((dst.val ^ dst.orig_val) >> (width - 1)) & 1 )
3518 _regs.eflags |= EFLG_OF;
3519 _regs.eflags |= ((dst.val >> (width - 1)) & 1) ? EFLG_SF : 0;
3520 _regs.eflags |= (dst.val == 0) ? EFLG_ZF : 0;
3521 _regs.eflags |= even_parity(dst.val) ? EFLG_PF : 0;
3522 break;
3525 case 0xb3: btr: /* btr */
3526 emulate_2op_SrcV_nobyte("btr", src, dst, _regs.eflags);
3527 break;
3529 case 0xab: bts: /* bts */
3530 emulate_2op_SrcV_nobyte("bts", src, dst, _regs.eflags);
3531 break;
3533 case 0xaf: /* imul */
3534 _regs.eflags &= ~(EFLG_OF|EFLG_CF);
3535 switch ( dst.bytes )
3537 case 2:
3538 dst.val = ((uint32_t)(int16_t)src.val *
3539 (uint32_t)(int16_t)dst.val);
3540 if ( (int16_t)dst.val != (uint32_t)dst.val )
3541 _regs.eflags |= EFLG_OF|EFLG_CF;
3542 break;
3543 #ifdef __x86_64__
3544 case 4:
3545 dst.val = ((uint64_t)(int32_t)src.val *
3546 (uint64_t)(int32_t)dst.val);
3547 if ( (int32_t)dst.val != dst.val )
3548 _regs.eflags |= EFLG_OF|EFLG_CF;
3549 break;
3550 #endif
3551 default: {
3552 unsigned long m[2] = { src.val, dst.val };
3553 if ( imul_dbl(m) )
3554 _regs.eflags |= EFLG_OF|EFLG_CF;
3555 dst.val = m[0];
3556 break;
3559 break;
3561 case 0xb2: /* lss */
3562 dst.val = x86_seg_ss;
3563 goto les;
3565 case 0xb4: /* lfs */
3566 dst.val = x86_seg_fs;
3567 goto les;
3569 case 0xb5: /* lgs */
3570 dst.val = x86_seg_gs;
3571 goto les;
3573 case 0xb6: /* movzx rm8,r{16,32,64} */
3574 /* Recompute DstReg as we may have decoded AH/BH/CH/DH. */
3575 dst.reg = decode_register(modrm_reg, &_regs, 0);
3576 dst.bytes = op_bytes;
3577 dst.val = (uint8_t)src.val;
3578 break;
3580 case 0xbc: /* bsf */ {
3581 int zf;
3582 asm ( "bsf %2,%0; setz %b1"
3583 : "=r" (dst.val), "=q" (zf)
3584 : "r" (src.val), "1" (0) );
3585 _regs.eflags &= ~EFLG_ZF;
3586 if ( zf )
3588 _regs.eflags |= EFLG_ZF;
3589 dst.type = OP_NONE;
3591 break;
3594 case 0xbd: /* bsr */ {
3595 int zf;
3596 asm ( "bsr %2,%0; setz %b1"
3597 : "=r" (dst.val), "=q" (zf)
3598 : "r" (src.val), "1" (0) );
3599 _regs.eflags &= ~EFLG_ZF;
3600 if ( zf )
3602 _regs.eflags |= EFLG_ZF;
3603 dst.type = OP_NONE;
3605 break;
3608 case 0xb7: /* movzx rm16,r{16,32,64} */
3609 dst.val = (uint16_t)src.val;
3610 break;
3612 case 0xbb: btc: /* btc */
3613 emulate_2op_SrcV_nobyte("btc", src, dst, _regs.eflags);
3614 break;
3616 case 0xba: /* Grp8 */
3617 switch ( modrm_reg & 7 )
3619 case 4: goto bt;
3620 case 5: goto bts;
3621 case 6: goto btr;
3622 case 7: goto btc;
3623 default: generate_exception_if(1, EXC_UD, -1);
3625 break;
3627 case 0xbe: /* movsx rm8,r{16,32,64} */
3628 /* Recompute DstReg as we may have decoded AH/BH/CH/DH. */
3629 dst.reg = decode_register(modrm_reg, &_regs, 0);
3630 dst.bytes = op_bytes;
3631 dst.val = (int8_t)src.val;
3632 break;
3634 case 0xbf: /* movsx rm16,r{16,32,64} */
3635 dst.val = (int16_t)src.val;
3636 break;
3638 case 0xc0 ... 0xc1: /* xadd */
3639 /* Write back the register source. */
3640 switch ( dst.bytes )
3642 case 1: *(uint8_t *)src.reg = (uint8_t)dst.val; break;
3643 case 2: *(uint16_t *)src.reg = (uint16_t)dst.val; break;
3644 case 4: *src.reg = (uint32_t)dst.val; break; /* 64b reg: zero-extend */
3645 case 8: *src.reg = dst.val; break;
3647 goto add;
3649 goto writeback;
3651 twobyte_special_insn:
3652 switch ( b )
3654 case 0x01: /* Grp7 */ {
3655 struct segment_register reg;
3656 unsigned long base, limit, cr0, cr0w;
3658 if ( modrm == 0xdf ) /* invlpga */
3660 generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1);
3661 generate_exception_if(!mode_ring0(), EXC_GP, 0);
3662 fail_if(ops->invlpg == NULL);
3663 if ( (rc = ops->invlpg(x86_seg_none, truncate_ea(_regs.eax),
3664 ctxt)) )
3665 goto done;
3666 break;
3669 switch ( modrm_reg & 7 )
3671 case 0: /* sgdt */
3672 case 1: /* sidt */
3673 generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
3674 fail_if(ops->read_segment == NULL);
3675 if ( (rc = ops->read_segment((modrm_reg & 1) ?
3676 x86_seg_idtr : x86_seg_gdtr,
3677 &reg, ctxt)) )
3678 goto done;
3679 if ( op_bytes == 2 )
3680 reg.base &= 0xffffff;
3681 if ( (rc = ops->write(ea.mem.seg, ea.mem.off+0,
3682 &reg.limit, 2, ctxt)) ||
3683 (rc = ops->write(ea.mem.seg, ea.mem.off+2,
3684 &reg.base, mode_64bit() ? 8 : 4, ctxt)) )
3685 goto done;
3686 break;
3687 case 2: /* lgdt */
3688 case 3: /* lidt */
3689 generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
3690 fail_if(ops->write_segment == NULL);
3691 memset(&reg, 0, sizeof(reg));
3692 if ( (rc = read_ulong(ea.mem.seg, ea.mem.off+0,
3693 &limit, 2, ctxt, ops)) ||
3694 (rc = read_ulong(ea.mem.seg, ea.mem.off+2,
3695 &base, mode_64bit() ? 8 : 4, ctxt, ops)) )
3696 goto done;
3697 reg.base = base;
3698 reg.limit = limit;
3699 if ( op_bytes == 2 )
3700 reg.base &= 0xffffff;
3701 if ( (rc = ops->write_segment((modrm_reg & 1) ?
3702 x86_seg_idtr : x86_seg_gdtr,
3703 &reg, ctxt)) )
3704 goto done;
3705 break;
3706 case 4: /* smsw */
3707 if ( ea.type == OP_MEM )
3708 ea.bytes = 2;
3709 dst = ea;
3710 fail_if(ops->read_cr == NULL);
3711 if ( (rc = ops->read_cr(0, &dst.val, ctxt)) )
3712 goto done;
3713 d |= Mov; /* force writeback */
3714 break;
3715 case 6: /* lmsw */
3716 fail_if(ops->read_cr == NULL);
3717 fail_if(ops->write_cr == NULL);
3718 if ( (rc = ops->read_cr(0, &cr0, ctxt)) )
3719 goto done;
3720 if ( ea.type == OP_REG )
3721 cr0w = *ea.reg;
3722 else if ( (rc = read_ulong(ea.mem.seg, ea.mem.off,
3723 &cr0w, 2, ctxt, ops)) )
3724 goto done;
3725 /* LMSW can: (1) set bits 0-3; (2) clear bits 1-3. */
3726 cr0 = (cr0 & ~0xe) | (cr0w & 0xf);
3727 if ( (rc = ops->write_cr(0, cr0, ctxt)) )
3728 goto done;
3729 break;
3730 case 7: /* invlpg */
3731 generate_exception_if(!mode_ring0(), EXC_GP, 0);
3732 generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
3733 fail_if(ops->invlpg == NULL);
3734 if ( (rc = ops->invlpg(ea.mem.seg, ea.mem.off, ctxt)) )
3735 goto done;
3736 break;
3737 default:
3738 goto cannot_emulate;
3740 break;
3743 case 0x06: /* clts */
3744 generate_exception_if(!mode_ring0(), EXC_GP, 0);
3745 fail_if((ops->read_cr == NULL) || (ops->write_cr == NULL));
3746 if ( (rc = ops->read_cr(0, &dst.val, ctxt)) ||
3747 (rc = ops->write_cr(0, dst.val&~8, ctxt)) )
3748 goto done;
3749 break;
3751 case 0x08: /* invd */
3752 case 0x09: /* wbinvd */
3753 generate_exception_if(!mode_ring0(), EXC_GP, 0);
3754 fail_if(ops->wbinvd == NULL);
3755 if ( (rc = ops->wbinvd(ctxt)) != 0 )
3756 goto done;
3757 break;
3759 case 0x0d: /* GrpP (prefetch) */
3760 case 0x18: /* Grp16 (prefetch/nop) */
3761 case 0x19 ... 0x1f: /* nop (amd-defined) */
3762 break;
3764 case 0x20: /* mov cr,reg */
3765 case 0x21: /* mov dr,reg */
3766 case 0x22: /* mov reg,cr */
3767 case 0x23: /* mov reg,dr */
3768 generate_exception_if(ea.type != OP_REG, EXC_UD, -1);
3769 generate_exception_if(!mode_ring0(), EXC_GP, 0);
3770 modrm_reg |= lock_prefix << 3;
3771 if ( b & 2 )
3773 /* Write to CR/DR. */
3774 src.val = *(unsigned long *)decode_register(modrm_rm, &_regs, 0);
3775 if ( !mode_64bit() )
3776 src.val = (uint32_t)src.val;
3777 rc = ((b & 1)
3778 ? (ops->write_dr
3779 ? ops->write_dr(modrm_reg, src.val, ctxt)
3780 : X86EMUL_UNHANDLEABLE)
3781 : (ops->write_cr
3782 ? ops->write_cr(modrm_reg, src.val, ctxt)
3783 : X86EMUL_UNHANDLEABLE));
3785 else
3787 /* Read from CR/DR. */
3788 dst.type = OP_REG;
3789 dst.bytes = mode_64bit() ? 8 : 4;
3790 dst.reg = decode_register(modrm_rm, &_regs, 0);
3791 rc = ((b & 1)
3792 ? (ops->read_dr
3793 ? ops->read_dr(modrm_reg, &dst.val, ctxt)
3794 : X86EMUL_UNHANDLEABLE)
3795 : (ops->read_cr
3796 ? ops->read_cr(modrm_reg, &dst.val, ctxt)
3797 : X86EMUL_UNHANDLEABLE));
3799 if ( rc != 0 )
3800 goto done;
3801 break;
3803 case 0x30: /* wrmsr */ {
3804 uint64_t val = ((uint64_t)_regs.edx << 32) | (uint32_t)_regs.eax;
3805 generate_exception_if(!mode_ring0(), EXC_GP, 0);
3806 fail_if(ops->write_msr == NULL);
3807 if ( (rc = ops->write_msr((uint32_t)_regs.ecx, val, ctxt)) != 0 )
3808 goto done;
3809 break;
3812 case 0x31: /* rdtsc */ {
3813 unsigned long cr4;
3814 uint64_t val;
3815 fail_if(ops->read_cr == NULL);
3816 if ( (rc = ops->read_cr(4, &cr4, ctxt)) )
3817 goto done;
3818 generate_exception_if((cr4 & CR4_TSD) && !mode_ring0(), EXC_GP, 0);
3819 fail_if(ops->read_msr == NULL);
3820 if ( (rc = ops->read_msr(MSR_TSC, &val, ctxt)) != 0 )
3821 goto done;
3822 _regs.edx = (uint32_t)(val >> 32);
3823 _regs.eax = (uint32_t)(val >> 0);
3824 break;
3827 case 0x32: /* rdmsr */ {
3828 uint64_t val;
3829 generate_exception_if(!mode_ring0(), EXC_GP, 0);
3830 fail_if(ops->read_msr == NULL);
3831 if ( (rc = ops->read_msr((uint32_t)_regs.ecx, &val, ctxt)) != 0 )
3832 goto done;
3833 _regs.edx = (uint32_t)(val >> 32);
3834 _regs.eax = (uint32_t)(val >> 0);
3835 break;
3838 case 0x6f: /* movq mm/m64,mm */ {
3839 uint8_t stub[] = { 0x0f, 0x6f, modrm, 0xc3 };
3840 struct fpu_insn_ctxt fic = { .insn_bytes = sizeof(stub)-1 };
3841 uint64_t val;
3842 if ( ea.type == OP_MEM )
3844 unsigned long lval, hval;
3845 if ( (rc = read_ulong(ea.mem.seg, ea.mem.off+0,
3846 &lval, 4, ctxt, ops)) ||
3847 (rc = read_ulong(ea.mem.seg, ea.mem.off+4,
3848 &hval, 4, ctxt, ops)) )
3849 goto done;
3850 val = ((uint64_t)hval << 32) | (uint32_t)lval;
3851 stub[2] = modrm & 0x38; /* movq (%eax),%mmN */
3853 get_fpu(X86EMUL_FPU_mmx, &fic);
3854 asm volatile ( "call *%0" : : "r" (stub), "a" (&val) : "memory" );
3855 put_fpu(&fic);
3856 break;
3859 case 0x7f: /* movq mm,mm/m64 */ {
3860 uint8_t stub[] = { 0x0f, 0x7f, modrm, 0xc3 };
3861 struct fpu_insn_ctxt fic = { .insn_bytes = sizeof(stub)-1 };
3862 uint64_t val;
3863 if ( ea.type == OP_MEM )
3864 stub[2] = modrm & 0x38; /* movq %mmN,(%eax) */
3865 get_fpu(X86EMUL_FPU_mmx, &fic);
3866 asm volatile ( "call *%0" : : "r" (stub), "a" (&val) : "memory" );
3867 put_fpu(&fic);
3868 if ( ea.type == OP_MEM )
3870 unsigned long lval = (uint32_t)val, hval = (uint32_t)(val >> 32);
3871 if ( (rc = ops->write(ea.mem.seg, ea.mem.off+0, &lval, 4, ctxt)) ||
3872 (rc = ops->write(ea.mem.seg, ea.mem.off+4, &hval, 4, ctxt)) )
3873 goto done;
3875 break;
3878 case 0x80 ... 0x8f: /* jcc (near) */ {
3879 int rel = (((op_bytes == 2) && !mode_64bit())
3880 ? (int32_t)insn_fetch_type(int16_t)
3881 : insn_fetch_type(int32_t));
3882 if ( test_cc(b, _regs.eflags) )
3883 jmp_rel(rel);
3884 break;
3887 case 0xa0: /* push %%fs */
3888 src.val = x86_seg_fs;
3889 goto push_seg;
3891 case 0xa1: /* pop %%fs */
3892 src.val = x86_seg_fs;
3893 goto pop_seg;
3895 case 0xa2: /* cpuid */ {
3896 unsigned int eax = _regs.eax, ebx = _regs.ebx;
3897 unsigned int ecx = _regs.ecx, edx = _regs.edx;
3898 fail_if(ops->cpuid == NULL);
3899 if ( (rc = ops->cpuid(&eax, &ebx, &ecx, &edx, ctxt)) != 0 )
3900 goto done;
3901 _regs.eax = eax; _regs.ebx = ebx;
3902 _regs.ecx = ecx; _regs.edx = edx;
3903 break;
3906 case 0xa8: /* push %%gs */
3907 src.val = x86_seg_gs;
3908 goto push_seg;
3910 case 0xa9: /* pop %%gs */
3911 src.val = x86_seg_gs;
3912 goto pop_seg;
3914 case 0xc7: /* Grp9 (cmpxchg8b/cmpxchg16b) */ {
3915 unsigned long old[2], exp[2], new[2];
3916 unsigned int i;
3918 generate_exception_if((modrm_reg & 7) != 1, EXC_UD, -1);
3919 generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
3920 op_bytes *= 2;
3922 /* Get actual old value. */
3923 for ( i = 0; i < (op_bytes/sizeof(long)); i++ )
3924 if ( (rc = read_ulong(ea.mem.seg, ea.mem.off + i*sizeof(long),
3925 &old[i], sizeof(long), ctxt, ops)) != 0 )
3926 goto done;
3928 /* Get expected and proposed values. */
3929 if ( op_bytes == 8 )
3931 ((uint32_t *)exp)[0] = _regs.eax; ((uint32_t *)exp)[1] = _regs.edx;
3932 ((uint32_t *)new)[0] = _regs.ebx; ((uint32_t *)new)[1] = _regs.ecx;
3934 else
3936 exp[0] = _regs.eax; exp[1] = _regs.edx;
3937 new[0] = _regs.ebx; new[1] = _regs.ecx;
3940 if ( memcmp(old, exp, op_bytes) )
3942 /* Expected != actual: store actual to rDX:rAX and clear ZF. */
3943 _regs.eax = (op_bytes == 8) ? ((uint32_t *)old)[0] : old[0];
3944 _regs.edx = (op_bytes == 8) ? ((uint32_t *)old)[1] : old[1];
3945 _regs.eflags &= ~EFLG_ZF;
3947 else
3949 /* Expected == actual: attempt atomic cmpxchg and set ZF. */
3950 if ( (rc = ops->cmpxchg(ea.mem.seg, ea.mem.off, old,
3951 new, op_bytes, ctxt)) != 0 )
3952 goto done;
3953 _regs.eflags |= EFLG_ZF;
3955 break;
3958 case 0xc8 ... 0xcf: /* bswap */
3959 dst.type = OP_REG;
3960 dst.reg = decode_register(
3961 (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0);
3962 switch ( dst.bytes = op_bytes )
3964 default: /* case 2: */
3965 /* Undefined behaviour. Writes zero on all tested CPUs. */
3966 dst.val = 0;
3967 break;
3968 case 4:
3969 #ifdef __x86_64__
3970 asm ( "bswap %k0" : "=r" (dst.val) : "0" (*dst.reg) );
3971 break;
3972 case 8:
3973 #endif
3974 asm ( "bswap %0" : "=r" (dst.val) : "0" (*dst.reg) );
3975 break;
3977 break;
3979 goto writeback;
3981 cannot_emulate:
3982 return X86EMUL_UNHANDLEABLE;