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 | */ |
---|
23 | |
---|
24 | #ifndef __XEN__ |
---|
25 | #include <stddef.h> |
---|
26 | #include <stdint.h> |
---|
27 | #include <public/xen.h> |
---|
28 | #else |
---|
29 | #include <xen/config.h> |
---|
30 | #include <xen/types.h> |
---|
31 | #include <xen/lib.h> |
---|
32 | #include <asm/regs.h> |
---|
33 | #undef cmpxchg |
---|
34 | #endif |
---|
35 | #include <asm-x86/x86_emulate.h> |
---|
36 | |
---|
37 | /* Operand sizes: 8-bit operands or specified/overridden size. */ |
---|
38 | #define ByteOp (1<<0) /* 8-bit operands. */ |
---|
39 | /* Destination operand type. */ |
---|
40 | #define DstBitBase (0<<1) /* Memory operand, bit string. */ |
---|
41 | #define ImplicitOps (1<<1) /* Implicit in opcode. No generic decode. */ |
---|
42 | #define DstReg (2<<1) /* Register operand. */ |
---|
43 | #define DstMem (3<<1) /* Memory operand. */ |
---|
44 | #define DstMask (3<<1) |
---|
45 | /* Source operand type. */ |
---|
46 | #define SrcNone (0<<3) /* No source operand. */ |
---|
47 | #define SrcImplicit (0<<3) /* Source operand is implicit in the opcode. */ |
---|
48 | #define SrcReg (1<<3) /* Register operand. */ |
---|
49 | #define SrcMem (2<<3) /* Memory operand. */ |
---|
50 | #define SrcMem16 (3<<3) /* Memory operand (16-bit). */ |
---|
51 | #define SrcImm (4<<3) /* Immediate operand. */ |
---|
52 | #define SrcImmByte (5<<3) /* 8-bit sign-extended immediate operand. */ |
---|
53 | #define SrcMask (7<<3) |
---|
54 | /* Generic ModRM decode. */ |
---|
55 | #define ModRM (1<<6) |
---|
56 | /* Destination is only written; never read. */ |
---|
57 | #define Mov (1<<7) |
---|
58 | |
---|
59 | static uint8_t opcode_table[256] = { |
---|
60 | /* 0x00 - 0x07 */ |
---|
61 | ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, |
---|
62 | ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, |
---|
63 | ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, |
---|
64 | /* 0x08 - 0x0F */ |
---|
65 | ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, |
---|
66 | ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, |
---|
67 | ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, |
---|
68 | /* 0x10 - 0x17 */ |
---|
69 | ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, |
---|
70 | ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, |
---|
71 | ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, |
---|
72 | /* 0x18 - 0x1F */ |
---|
73 | ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, |
---|
74 | ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, |
---|
75 | ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, |
---|
76 | /* 0x20 - 0x27 */ |
---|
77 | ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, |
---|
78 | ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, |
---|
79 | ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps, |
---|
80 | /* 0x28 - 0x2F */ |
---|
81 | ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, |
---|
82 | ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, |
---|
83 | ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps, |
---|
84 | /* 0x30 - 0x37 */ |
---|
85 | ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, |
---|
86 | ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, |
---|
87 | ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps, |
---|
88 | /* 0x38 - 0x3F */ |
---|
89 | ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, |
---|
90 | ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, |
---|
91 | ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps, |
---|
92 | /* 0x40 - 0x4F */ |
---|
93 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
94 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
95 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
96 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
97 | /* 0x50 - 0x5F */ |
---|
98 | ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, |
---|
99 | ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, |
---|
100 | ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, |
---|
101 | ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, |
---|
102 | /* 0x60 - 0x67 */ |
---|
103 | ImplicitOps, ImplicitOps, DstReg|SrcMem|ModRM, DstReg|SrcMem16|ModRM|Mov, |
---|
104 | 0, 0, 0, 0, |
---|
105 | /* 0x68 - 0x6F */ |
---|
106 | ImplicitOps|Mov, DstMem|SrcImm|ModRM|Mov, |
---|
107 | ImplicitOps|Mov, DstMem|SrcImmByte|ModRM|Mov, |
---|
108 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
109 | /* 0x70 - 0x77 */ |
---|
110 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
111 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
112 | /* 0x78 - 0x7F */ |
---|
113 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
114 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
115 | /* 0x80 - 0x87 */ |
---|
116 | ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM, |
---|
117 | ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, |
---|
118 | ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, |
---|
119 | ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, |
---|
120 | /* 0x88 - 0x8F */ |
---|
121 | ByteOp|DstMem|SrcReg|ModRM|Mov, DstMem|SrcReg|ModRM|Mov, |
---|
122 | ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, |
---|
123 | 0, DstReg|SrcNone|ModRM, 0, DstMem|SrcNone|ModRM|Mov, |
---|
124 | /* 0x90 - 0x97 */ |
---|
125 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
126 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
127 | /* 0x98 - 0x9F */ |
---|
128 | ImplicitOps, ImplicitOps, 0, 0, 0, 0, ImplicitOps, ImplicitOps, |
---|
129 | /* 0xA0 - 0xA7 */ |
---|
130 | ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, |
---|
131 | ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, |
---|
132 | ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, 0, 0, |
---|
133 | /* 0xA8 - 0xAF */ |
---|
134 | ByteOp|DstReg|SrcImm, DstReg|SrcImm, |
---|
135 | ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, |
---|
136 | ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, 0, 0, |
---|
137 | /* 0xB0 - 0xB7 */ |
---|
138 | ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov, |
---|
139 | ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov, |
---|
140 | ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov, |
---|
141 | ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov, |
---|
142 | /* 0xB8 - 0xBF */ |
---|
143 | DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, |
---|
144 | DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, |
---|
145 | /* 0xC0 - 0xC7 */ |
---|
146 | ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, |
---|
147 | ImplicitOps, ImplicitOps, |
---|
148 | 0, 0, ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov, |
---|
149 | /* 0xC8 - 0xCF */ |
---|
150 | 0, 0, 0, 0, 0, 0, 0, 0, |
---|
151 | /* 0xD0 - 0xD7 */ |
---|
152 | ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, |
---|
153 | ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, |
---|
154 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
155 | /* 0xD8 - 0xDF */ |
---|
156 | 0, 0, 0, 0, 0, 0, 0, 0, |
---|
157 | /* 0xE0 - 0xE7 */ |
---|
158 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
159 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
160 | /* 0xE8 - 0xEF */ |
---|
161 | ImplicitOps, ImplicitOps, 0, ImplicitOps, |
---|
162 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
163 | /* 0xF0 - 0xF7 */ |
---|
164 | 0, 0, 0, 0, |
---|
165 | 0, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM, |
---|
166 | /* 0xF8 - 0xFF */ |
---|
167 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
168 | ImplicitOps, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM |
---|
169 | }; |
---|
170 | |
---|
171 | static uint8_t twobyte_table[256] = { |
---|
172 | /* 0x00 - 0x07 */ |
---|
173 | 0, 0, 0, 0, 0, ImplicitOps, 0, 0, |
---|
174 | /* 0x08 - 0x0F */ |
---|
175 | ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps|ModRM, 0, 0, |
---|
176 | /* 0x10 - 0x17 */ |
---|
177 | 0, 0, 0, 0, 0, 0, 0, 0, |
---|
178 | /* 0x18 - 0x1F */ |
---|
179 | ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, |
---|
180 | ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, |
---|
181 | /* 0x20 - 0x27 */ |
---|
182 | ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, ImplicitOps|ModRM, |
---|
183 | 0, 0, 0, 0, |
---|
184 | /* 0x28 - 0x2F */ |
---|
185 | 0, 0, 0, 0, 0, 0, 0, 0, |
---|
186 | /* 0x30 - 0x37 */ |
---|
187 | ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, 0, |
---|
188 | /* 0x38 - 0x3F */ |
---|
189 | 0, 0, 0, 0, 0, 0, 0, 0, |
---|
190 | /* 0x40 - 0x47 */ |
---|
191 | DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, |
---|
192 | DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, |
---|
193 | DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, |
---|
194 | DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, |
---|
195 | /* 0x48 - 0x4F */ |
---|
196 | DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, |
---|
197 | DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, |
---|
198 | DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, |
---|
199 | DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, |
---|
200 | /* 0x50 - 0x5F */ |
---|
201 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
202 | /* 0x60 - 0x6F */ |
---|
203 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
204 | /* 0x70 - 0x7F */ |
---|
205 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
206 | /* 0x80 - 0x87 */ |
---|
207 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
208 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
209 | /* 0x88 - 0x8F */ |
---|
210 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
211 | ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, |
---|
212 | /* 0x90 - 0x97 */ |
---|
213 | ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, |
---|
214 | ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, |
---|
215 | ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, |
---|
216 | ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, |
---|
217 | /* 0x98 - 0x9F */ |
---|
218 | ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, |
---|
219 | ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, |
---|
220 | ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, |
---|
221 | ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, |
---|
222 | /* 0xA0 - 0xA7 */ |
---|
223 | 0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, 0, |
---|
224 | /* 0xA8 - 0xAF */ |
---|
225 | 0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, DstReg|SrcMem|ModRM, |
---|
226 | /* 0xB0 - 0xB7 */ |
---|
227 | ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, |
---|
228 | 0, DstBitBase|SrcReg|ModRM, |
---|
229 | 0, 0, 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 | }; |
---|
247 | |
---|
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; |
---|
252 | unsigned long val, orig_val; |
---|
253 | union { |
---|
254 | /* OP_REG: Pointer to register field. */ |
---|
255 | unsigned long *reg; |
---|
256 | /* OP_MEM: Segment and offset. */ |
---|
257 | struct { |
---|
258 | enum x86_segment seg; |
---|
259 | unsigned long off; |
---|
260 | } mem; |
---|
261 | }; |
---|
262 | }; |
---|
263 | |
---|
264 | /* EFLAGS bit definitions. */ |
---|
265 | #define EFLG_OF (1<<11) |
---|
266 | #define EFLG_DF (1<<10) |
---|
267 | #define EFLG_IF (1<<9) |
---|
268 | #define EFLG_SF (1<<7) |
---|
269 | #define EFLG_ZF (1<<6) |
---|
270 | #define EFLG_AF (1<<4) |
---|
271 | #define EFLG_PF (1<<2) |
---|
272 | #define EFLG_CF (1<<0) |
---|
273 | |
---|
274 | /* Exception definitions. */ |
---|
275 | #define EXC_DE 0 |
---|
276 | #define EXC_BR 5 |
---|
277 | #define EXC_UD 6 |
---|
278 | #define EXC_GP 13 |
---|
279 | |
---|
280 | /* |
---|
281 | * Instruction emulation: |
---|
282 | * Most instructions are emulated directly via a fragment of inline assembly |
---|
283 | * code. This allows us to save/restore EFLAGS and thus very easily pick up |
---|
284 | * any modified flags. |
---|
285 | */ |
---|
286 | |
---|
287 | #if defined(__x86_64__) |
---|
288 | #define _LO32 "k" /* force 32-bit operand */ |
---|
289 | #define _STK "%%rsp" /* stack pointer */ |
---|
290 | #elif defined(__i386__) |
---|
291 | #define _LO32 "" /* force 32-bit operand */ |
---|
292 | #define _STK "%%esp" /* stack pointer */ |
---|
293 | #endif |
---|
294 | |
---|
295 | /* |
---|
296 | * These EFLAGS bits are restored from saved value during emulation, and |
---|
297 | * any changes are written back to the saved value after emulation. |
---|
298 | */ |
---|
299 | #define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF) |
---|
300 | |
---|
301 | /* Before executing instruction: restore necessary bits in EFLAGS. */ |
---|
302 | #define _PRE_EFLAGS(_sav, _msk, _tmp) \ |
---|
303 | /* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); */\ |
---|
304 | "push %"_sav"; " \ |
---|
305 | "movl %"_msk",%"_LO32 _tmp"; " \ |
---|
306 | "andl %"_LO32 _tmp",("_STK"); " \ |
---|
307 | "pushf; " \ |
---|
308 | "notl %"_LO32 _tmp"; " \ |
---|
309 | "andl %"_LO32 _tmp",("_STK"); " \ |
---|
310 | "pop %"_tmp"; " \ |
---|
311 | "orl %"_LO32 _tmp",("_STK"); " \ |
---|
312 | "popf; " \ |
---|
313 | /* _sav &= ~msk; */ \ |
---|
314 | "movl %"_msk",%"_LO32 _tmp"; " \ |
---|
315 | "notl %"_LO32 _tmp"; " \ |
---|
316 | "andl %"_LO32 _tmp",%"_sav"; " |
---|
317 | |
---|
318 | /* After executing instruction: write-back necessary bits in EFLAGS. */ |
---|
319 | #define _POST_EFLAGS(_sav, _msk, _tmp) \ |
---|
320 | /* _sav |= EFLAGS & _msk; */ \ |
---|
321 | "pushf; " \ |
---|
322 | "pop %"_tmp"; " \ |
---|
323 | "andl %"_msk",%"_LO32 _tmp"; " \ |
---|
324 | "orl %"_LO32 _tmp",%"_sav"; " |
---|
325 | |
---|
326 | /* Raw emulation: instruction has two explicit operands. */ |
---|
327 | #define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy)\ |
---|
328 | do{ unsigned long _tmp; \ |
---|
329 | switch ( (_dst).bytes ) \ |
---|
330 | { \ |
---|
331 | case 2: \ |
---|
332 | __asm__ __volatile__ ( \ |
---|
333 | _PRE_EFLAGS("0","4","2") \ |
---|
334 | _op"w %"_wx"3,%1; " \ |
---|
335 | _POST_EFLAGS("0","4","2") \ |
---|
336 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ |
---|
337 | : _wy ((_src).val), "i" (EFLAGS_MASK), \ |
---|
338 | "m" (_eflags), "m" ((_dst).val) ); \ |
---|
339 | break; \ |
---|
340 | case 4: \ |
---|
341 | __asm__ __volatile__ ( \ |
---|
342 | _PRE_EFLAGS("0","4","2") \ |
---|
343 | _op"l %"_lx"3,%1; " \ |
---|
344 | _POST_EFLAGS("0","4","2") \ |
---|
345 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ |
---|
346 | : _ly ((_src).val), "i" (EFLAGS_MASK), \ |
---|
347 | "m" (_eflags), "m" ((_dst).val) ); \ |
---|
348 | break; \ |
---|
349 | case 8: \ |
---|
350 | __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy); \ |
---|
351 | break; \ |
---|
352 | } \ |
---|
353 | } while (0) |
---|
354 | #define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy)\ |
---|
355 | do{ unsigned long _tmp; \ |
---|
356 | switch ( (_dst).bytes ) \ |
---|
357 | { \ |
---|
358 | case 1: \ |
---|
359 | __asm__ __volatile__ ( \ |
---|
360 | _PRE_EFLAGS("0","4","2") \ |
---|
361 | _op"b %"_bx"3,%1; " \ |
---|
362 | _POST_EFLAGS("0","4","2") \ |
---|
363 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ |
---|
364 | : _by ((_src).val), "i" (EFLAGS_MASK), \ |
---|
365 | "m" (_eflags), "m" ((_dst).val) ); \ |
---|
366 | break; \ |
---|
367 | default: \ |
---|
368 | __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy);\ |
---|
369 | break; \ |
---|
370 | } \ |
---|
371 | } while (0) |
---|
372 | /* Source operand is byte-sized and may be restricted to just %cl. */ |
---|
373 | #define emulate_2op_SrcB(_op, _src, _dst, _eflags) \ |
---|
374 | __emulate_2op(_op, _src, _dst, _eflags, \ |
---|
375 | "b", "c", "b", "c", "b", "c", "b", "c") |
---|
376 | /* Source operand is byte, word, long or quad sized. */ |
---|
377 | #define emulate_2op_SrcV(_op, _src, _dst, _eflags) \ |
---|
378 | __emulate_2op(_op, _src, _dst, _eflags, \ |
---|
379 | "b", "q", "w", "r", _LO32, "r", "", "r") |
---|
380 | /* Source operand is word, long or quad sized. */ |
---|
381 | #define emulate_2op_SrcV_nobyte(_op, _src, _dst, _eflags) \ |
---|
382 | __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ |
---|
383 | "w", "r", _LO32, "r", "", "r") |
---|
384 | |
---|
385 | /* Instruction has only one explicit operand (no source operand). */ |
---|
386 | #define emulate_1op(_op,_dst,_eflags) \ |
---|
387 | do{ unsigned long _tmp; \ |
---|
388 | switch ( (_dst).bytes ) \ |
---|
389 | { \ |
---|
390 | case 1: \ |
---|
391 | __asm__ __volatile__ ( \ |
---|
392 | _PRE_EFLAGS("0","3","2") \ |
---|
393 | _op"b %1; " \ |
---|
394 | _POST_EFLAGS("0","3","2") \ |
---|
395 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ |
---|
396 | : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) ); \ |
---|
397 | break; \ |
---|
398 | case 2: \ |
---|
399 | __asm__ __volatile__ ( \ |
---|
400 | _PRE_EFLAGS("0","3","2") \ |
---|
401 | _op"w %1; " \ |
---|
402 | _POST_EFLAGS("0","3","2") \ |
---|
403 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ |
---|
404 | : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) ); \ |
---|
405 | break; \ |
---|
406 | case 4: \ |
---|
407 | __asm__ __volatile__ ( \ |
---|
408 | _PRE_EFLAGS("0","3","2") \ |
---|
409 | _op"l %1; " \ |
---|
410 | _POST_EFLAGS("0","3","2") \ |
---|
411 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ |
---|
412 | : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) ); \ |
---|
413 | break; \ |
---|
414 | case 8: \ |
---|
415 | __emulate_1op_8byte(_op, _dst, _eflags); \ |
---|
416 | break; \ |
---|
417 | } \ |
---|
418 | } while (0) |
---|
419 | |
---|
420 | /* Emulate an instruction with quadword operands (x86/64 only). */ |
---|
421 | #if defined(__x86_64__) |
---|
422 | #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) \ |
---|
423 | do{ __asm__ __volatile__ ( \ |
---|
424 | _PRE_EFLAGS("0","4","2") \ |
---|
425 | _op"q %"_qx"3,%1; " \ |
---|
426 | _POST_EFLAGS("0","4","2") \ |
---|
427 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ |
---|
428 | : _qy ((_src).val), "i" (EFLAGS_MASK), \ |
---|
429 | "m" (_eflags), "m" ((_dst).val) ); \ |
---|
430 | } while (0) |
---|
431 | #define __emulate_1op_8byte(_op, _dst, _eflags) \ |
---|
432 | do{ __asm__ __volatile__ ( \ |
---|
433 | _PRE_EFLAGS("0","3","2") \ |
---|
434 | _op"q %1; " \ |
---|
435 | _POST_EFLAGS("0","3","2") \ |
---|
436 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ |
---|
437 | : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) ); \ |
---|
438 | } while (0) |
---|
439 | #elif defined(__i386__) |
---|
440 | #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) |
---|
441 | #define __emulate_1op_8byte(_op, _dst, _eflags) |
---|
442 | #endif /* __i386__ */ |
---|
443 | |
---|
444 | /* Fetch next part of the instruction being emulated. */ |
---|
445 | #define insn_fetch_bytes(_size) \ |
---|
446 | ({ unsigned long _x, _eip = _regs.eip; \ |
---|
447 | if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \ |
---|
448 | _regs.eip += (_size); /* real hardware doesn't truncate */ \ |
---|
449 | generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) > 15, \ |
---|
450 | EXC_GP); \ |
---|
451 | rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt); \ |
---|
452 | if ( rc ) goto done; \ |
---|
453 | _x; \ |
---|
454 | }) |
---|
455 | #define insn_fetch_type(_type) ((_type)insn_fetch_bytes(sizeof(_type))) |
---|
456 | |
---|
457 | #define _truncate_ea(ea, byte_width) \ |
---|
458 | ({ unsigned long __ea = (ea); \ |
---|
459 | unsigned int _width = (byte_width); \ |
---|
460 | ((_width == sizeof(unsigned long)) ? __ea : \ |
---|
461 | (__ea & ((1UL << (_width << 3)) - 1))); \ |
---|
462 | }) |
---|
463 | #define truncate_ea(ea) _truncate_ea((ea), ad_bytes) |
---|
464 | |
---|
465 | #define mode_64bit() (def_ad_bytes == 8) |
---|
466 | |
---|
467 | #define fail_if(p) \ |
---|
468 | do { \ |
---|
469 | rc = (p) ? X86EMUL_UNHANDLEABLE : X86EMUL_OKAY; \ |
---|
470 | if ( rc ) goto done; \ |
---|
471 | } while (0) |
---|
472 | |
---|
473 | /* In future we will be able to generate arbitrary exceptions. */ |
---|
474 | #define generate_exception_if(p, e) fail_if(p) |
---|
475 | |
---|
476 | /* To be done... */ |
---|
477 | #define mode_ring0() (0) |
---|
478 | #define mode_iopl() (0) |
---|
479 | |
---|
480 | /* Given byte has even parity (even number of 1s)? */ |
---|
481 | static int even_parity(uint8_t v) |
---|
482 | { |
---|
483 | __asm__ ( "test %%al,%%al; setp %%al" |
---|
484 | : "=a" (v) : "0" (v) ); |
---|
485 | return v; |
---|
486 | } |
---|
487 | |
---|
488 | /* Update address held in a register, based on addressing mode. */ |
---|
489 | #define _register_address_increment(reg, inc, byte_width) \ |
---|
490 | do { \ |
---|
491 | int _inc = (inc); /* signed type ensures sign extension to long */ \ |
---|
492 | unsigned int _width = (byte_width); \ |
---|
493 | if ( _width == sizeof(unsigned long) ) \ |
---|
494 | (reg) += _inc; \ |
---|
495 | else if ( mode_64bit() ) \ |
---|
496 | (reg) = ((reg) + _inc) & ((1UL << (_width << 3)) - 1); \ |
---|
497 | else \ |
---|
498 | (reg) = ((reg) & ~((1UL << (_width << 3)) - 1)) | \ |
---|
499 | (((reg) + _inc) & ((1UL << (_width << 3)) - 1)); \ |
---|
500 | } while (0) |
---|
501 | #define register_address_increment(reg, inc) \ |
---|
502 | _register_address_increment((reg), (inc), ad_bytes) |
---|
503 | |
---|
504 | #define sp_pre_dec(dec) ({ \ |
---|
505 | _register_address_increment(_regs.esp, -(dec), ctxt->sp_size/8); \ |
---|
506 | _truncate_ea(_regs.esp, ctxt->sp_size/8); \ |
---|
507 | }) |
---|
508 | #define sp_post_inc(inc) ({ \ |
---|
509 | unsigned long __esp = _truncate_ea(_regs.esp, ctxt->sp_size/8); \ |
---|
510 | _register_address_increment(_regs.esp, (inc), ctxt->sp_size/8); \ |
---|
511 | __esp; \ |
---|
512 | }) |
---|
513 | |
---|
514 | #define jmp_rel(rel) \ |
---|
515 | do { \ |
---|
516 | _regs.eip += (int)(rel); \ |
---|
517 | if ( !mode_64bit() ) \ |
---|
518 | _regs.eip = ((op_bytes == 2) \ |
---|
519 | ? (uint16_t)_regs.eip : (uint32_t)_regs.eip); \ |
---|
520 | } while (0) |
---|
521 | |
---|
522 | static int __handle_rep_prefix( |
---|
523 | struct cpu_user_regs *int_regs, |
---|
524 | struct cpu_user_regs *ext_regs, |
---|
525 | int ad_bytes) |
---|
526 | { |
---|
527 | unsigned long ecx = ((ad_bytes == 2) ? (uint16_t)int_regs->ecx : |
---|
528 | (ad_bytes == 4) ? (uint32_t)int_regs->ecx : |
---|
529 | int_regs->ecx); |
---|
530 | |
---|
531 | if ( ecx-- == 0 ) |
---|
532 | { |
---|
533 | ext_regs->eip = int_regs->eip; |
---|
534 | return 1; |
---|
535 | } |
---|
536 | |
---|
537 | if ( ad_bytes == 2 ) |
---|
538 | *(uint16_t *)&int_regs->ecx = ecx; |
---|
539 | else if ( ad_bytes == 4 ) |
---|
540 | int_regs->ecx = (uint32_t)ecx; |
---|
541 | else |
---|
542 | int_regs->ecx = ecx; |
---|
543 | int_regs->eip = ext_regs->eip; |
---|
544 | return 0; |
---|
545 | } |
---|
546 | |
---|
547 | #define handle_rep_prefix() \ |
---|
548 | do { \ |
---|
549 | if ( rep_prefix && __handle_rep_prefix(&_regs, ctxt->regs, ad_bytes) ) \ |
---|
550 | goto done; \ |
---|
551 | } while (0) |
---|
552 | |
---|
553 | /* |
---|
554 | * Unsigned multiplication with double-word result. |
---|
555 | * IN: Multiplicand=m[0], Multiplier=m[1] |
---|
556 | * OUT: Return CF/OF (overflow status); Result=m[1]:m[0] |
---|
557 | */ |
---|
558 | static int mul_dbl(unsigned long m[2]) |
---|
559 | { |
---|
560 | int rc; |
---|
561 | asm ( "mul %4; seto %b2" |
---|
562 | : "=a" (m[0]), "=d" (m[1]), "=q" (rc) |
---|
563 | : "0" (m[0]), "1" (m[1]), "2" (0) ); |
---|
564 | return rc; |
---|
565 | } |
---|
566 | |
---|
567 | /* |
---|
568 | * Signed multiplication with double-word result. |
---|
569 | * IN: Multiplicand=m[0], Multiplier=m[1] |
---|
570 | * OUT: Return CF/OF (overflow status); Result=m[1]:m[0] |
---|
571 | */ |
---|
572 | static int imul_dbl(unsigned long m[2]) |
---|
573 | { |
---|
574 | int rc; |
---|
575 | asm ( "imul %4; seto %b2" |
---|
576 | : "=a" (m[0]), "=d" (m[1]), "=q" (rc) |
---|
577 | : "0" (m[0]), "1" (m[1]), "2" (0) ); |
---|
578 | return rc; |
---|
579 | } |
---|
580 | |
---|
581 | /* |
---|
582 | * Unsigned division of double-word dividend. |
---|
583 | * IN: Dividend=u[1]:u[0], Divisor=v |
---|
584 | * OUT: Return 1: #DE |
---|
585 | * Return 0: Quotient=u[0], Remainder=u[1] |
---|
586 | */ |
---|
587 | static int div_dbl(unsigned long u[2], unsigned long v) |
---|
588 | { |
---|
589 | if ( (v == 0) || (u[1] > v) || ((u[1] == v) && (u[0] != 0)) ) |
---|
590 | return 1; |
---|
591 | asm ( "div %4" |
---|
592 | : "=a" (u[0]), "=d" (u[1]) |
---|
593 | : "0" (u[0]), "1" (u[1]), "r" (v) ); |
---|
594 | return 0; |
---|
595 | } |
---|
596 | |
---|
597 | /* |
---|
598 | * Signed division of double-word dividend. |
---|
599 | * IN: Dividend=u[1]:u[0], Divisor=v |
---|
600 | * OUT: Return 1: #DE |
---|
601 | * Return 0: Quotient=u[0], Remainder=u[1] |
---|
602 | * NB. We don't use idiv directly as it's moderately hard to work out |
---|
603 | * ahead of time whether it will #DE, which we cannot allow to happen. |
---|
604 | */ |
---|
605 | static int idiv_dbl(unsigned long u[2], unsigned long v) |
---|
606 | { |
---|
607 | int negu = (long)u[1] < 0, negv = (long)v < 0; |
---|
608 | |
---|
609 | /* u = abs(u) */ |
---|
610 | if ( negu ) |
---|
611 | { |
---|
612 | u[1] = ~u[1]; |
---|
613 | if ( (u[0] = -u[0]) == 0 ) |
---|
614 | u[1]++; |
---|
615 | } |
---|
616 | |
---|
617 | /* abs(u) / abs(v) */ |
---|
618 | if ( div_dbl(u, negv ? -v : v) ) |
---|
619 | return 1; |
---|
620 | |
---|
621 | /* Remainder has same sign as dividend. It cannot overflow. */ |
---|
622 | if ( negu ) |
---|
623 | u[1] = -u[1]; |
---|
624 | |
---|
625 | /* Quotient is overflowed if sign bit is set. */ |
---|
626 | if ( negu ^ negv ) |
---|
627 | { |
---|
628 | if ( (long)u[0] >= 0 ) |
---|
629 | u[0] = -u[0]; |
---|
630 | else if ( (u[0] << 1) != 0 ) /* == 0x80...0 is okay */ |
---|
631 | return 1; |
---|
632 | } |
---|
633 | else if ( (long)u[0] < 0 ) |
---|
634 | return 1; |
---|
635 | |
---|
636 | return 0; |
---|
637 | } |
---|
638 | |
---|
639 | static int |
---|
640 | test_cc( |
---|
641 | unsigned int condition, unsigned int flags) |
---|
642 | { |
---|
643 | int rc = 0; |
---|
644 | |
---|
645 | switch ( (condition & 15) >> 1 ) |
---|
646 | { |
---|
647 | case 0: /* o */ |
---|
648 | rc |= (flags & EFLG_OF); |
---|
649 | break; |
---|
650 | case 1: /* b/c/nae */ |
---|
651 | rc |= (flags & EFLG_CF); |
---|
652 | break; |
---|
653 | case 2: /* z/e */ |
---|
654 | rc |= (flags & EFLG_ZF); |
---|
655 | break; |
---|
656 | case 3: /* be/na */ |
---|
657 | rc |= (flags & (EFLG_CF|EFLG_ZF)); |
---|
658 | break; |
---|
659 | case 4: /* s */ |
---|
660 | rc |= (flags & EFLG_SF); |
---|
661 | break; |
---|
662 | case 5: /* p/pe */ |
---|
663 | rc |= (flags & EFLG_PF); |
---|
664 | break; |
---|
665 | case 7: /* le/ng */ |
---|
666 | rc |= (flags & EFLG_ZF); |
---|
667 | /* fall through */ |
---|
668 | case 6: /* l/nge */ |
---|
669 | rc |= (!(flags & EFLG_SF) != !(flags & EFLG_OF)); |
---|
670 | break; |
---|
671 | } |
---|
672 | |
---|
673 | /* Odd condition identifiers (lsb == 1) have inverted sense. */ |
---|
674 | return (!!rc ^ (condition & 1)); |
---|
675 | } |
---|
676 | |
---|
677 | void * |
---|
678 | decode_register( |
---|
679 | uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs) |
---|
680 | { |
---|
681 | void *p; |
---|
682 | |
---|
683 | switch ( modrm_reg ) |
---|
684 | { |
---|
685 | case 0: p = ®s->eax; break; |
---|
686 | case 1: p = ®s->ecx; break; |
---|
687 | case 2: p = ®s->edx; break; |
---|
688 | case 3: p = ®s->ebx; break; |
---|
689 | case 4: p = (highbyte_regs ? |
---|
690 | ((unsigned char *)®s->eax + 1) : |
---|
691 | (unsigned char *)®s->esp); break; |
---|
692 | case 5: p = (highbyte_regs ? |
---|
693 | ((unsigned char *)®s->ecx + 1) : |
---|
694 | (unsigned char *)®s->ebp); break; |
---|
695 | case 6: p = (highbyte_regs ? |
---|
696 | ((unsigned char *)®s->edx + 1) : |
---|
697 | (unsigned char *)®s->esi); break; |
---|
698 | case 7: p = (highbyte_regs ? |
---|
699 | ((unsigned char *)®s->ebx + 1) : |
---|
700 | (unsigned char *)®s->edi); break; |
---|
701 | #if defined(__x86_64__) |
---|
702 | case 8: p = ®s->r8; break; |
---|
703 | case 9: p = ®s->r9; break; |
---|
704 | case 10: p = ®s->r10; break; |
---|
705 | case 11: p = ®s->r11; break; |
---|
706 | case 12: p = ®s->r12; break; |
---|
707 | case 13: p = ®s->r13; break; |
---|
708 | case 14: p = ®s->r14; break; |
---|
709 | case 15: p = ®s->r15; break; |
---|
710 | #endif |
---|
711 | default: p = NULL; break; |
---|
712 | } |
---|
713 | |
---|
714 | return p; |
---|
715 | } |
---|
716 | |
---|
717 | int |
---|
718 | x86_emulate( |
---|
719 | struct x86_emulate_ctxt *ctxt, |
---|
720 | struct x86_emulate_ops *ops) |
---|
721 | { |
---|
722 | /* Shadow copy of register state. Committed on successful emulation. */ |
---|
723 | struct cpu_user_regs _regs = *ctxt->regs; |
---|
724 | |
---|
725 | uint8_t b, d, sib, sib_index, sib_base, twobyte = 0, rex_prefix = 0; |
---|
726 | uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; |
---|
727 | unsigned int op_bytes, def_op_bytes, ad_bytes, def_ad_bytes; |
---|
728 | unsigned int lock_prefix = 0, rep_prefix = 0; |
---|
729 | int override_seg = -1, rc = X86EMUL_OKAY; |
---|
730 | struct operand src, dst; |
---|
731 | |
---|
732 | /* Data operand effective address (usually computed from ModRM). */ |
---|
733 | struct operand ea; |
---|
734 | |
---|
735 | /* Default is a memory operand relative to segment DS. */ |
---|
736 | ea.type = OP_MEM; |
---|
737 | ea.mem.seg = x86_seg_ds; |
---|
738 | ea.mem.off = 0; |
---|
739 | |
---|
740 | op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->addr_size/8; |
---|
741 | if ( op_bytes == 8 ) |
---|
742 | { |
---|
743 | op_bytes = def_op_bytes = 4; |
---|
744 | #ifndef __x86_64__ |
---|
745 | return X86EMUL_UNHANDLEABLE; |
---|
746 | #endif |
---|
747 | } |
---|
748 | |
---|
749 | /* Prefix bytes. */ |
---|
750 | for ( ; ; ) |
---|
751 | { |
---|
752 | switch ( b = insn_fetch_type(uint8_t) ) |
---|
753 | { |
---|
754 | case 0x66: /* operand-size override */ |
---|
755 | op_bytes = def_op_bytes ^ 6; |
---|
756 | break; |
---|
757 | case 0x67: /* address-size override */ |
---|
758 | ad_bytes = def_ad_bytes ^ (mode_64bit() ? 12 : 6); |
---|
759 | break; |
---|
760 | case 0x2e: /* CS override */ |
---|
761 | override_seg = x86_seg_cs; |
---|
762 | break; |
---|
763 | case 0x3e: /* DS override */ |
---|
764 | override_seg = x86_seg_ds; |
---|
765 | break; |
---|
766 | case 0x26: /* ES override */ |
---|
767 | override_seg = x86_seg_es; |
---|
768 | break; |
---|
769 | case 0x64: /* FS override */ |
---|
770 | override_seg = x86_seg_fs; |
---|
771 | break; |
---|
772 | case 0x65: /* GS override */ |
---|
773 | override_seg = x86_seg_gs; |
---|
774 | break; |
---|
775 | case 0x36: /* SS override */ |
---|
776 | override_seg = x86_seg_ss; |
---|
777 | break; |
---|
778 | case 0xf0: /* LOCK */ |
---|
779 | lock_prefix = 1; |
---|
780 | break; |
---|
781 | case 0xf2: /* REPNE/REPNZ */ |
---|
782 | case 0xf3: /* REP/REPE/REPZ */ |
---|
783 | rep_prefix = 1; |
---|
784 | break; |
---|
785 | case 0x40 ... 0x4f: /* REX */ |
---|
786 | if ( !mode_64bit() ) |
---|
787 | goto done_prefixes; |
---|
788 | rex_prefix = b; |
---|
789 | continue; |
---|
790 | default: |
---|
791 | goto done_prefixes; |
---|
792 | } |
---|
793 | |
---|
794 | /* Any legacy prefix after a REX prefix nullifies its effect. */ |
---|
795 | rex_prefix = 0; |
---|
796 | } |
---|
797 | done_prefixes: |
---|
798 | |
---|
799 | if ( rex_prefix & 8 ) /* REX.W */ |
---|
800 | op_bytes = 8; |
---|
801 | |
---|
802 | /* Opcode byte(s). */ |
---|
803 | d = opcode_table[b]; |
---|
804 | if ( d == 0 ) |
---|
805 | { |
---|
806 | /* Two-byte opcode? */ |
---|
807 | if ( b == 0x0f ) |
---|
808 | { |
---|
809 | twobyte = 1; |
---|
810 | b = insn_fetch_type(uint8_t); |
---|
811 | d = twobyte_table[b]; |
---|
812 | } |
---|
813 | |
---|
814 | /* Unrecognised? */ |
---|
815 | if ( d == 0 ) |
---|
816 | goto cannot_emulate; |
---|
817 | } |
---|
818 | |
---|
819 | /* Lock prefix is allowed only on RMW instructions. */ |
---|
820 | generate_exception_if((d & Mov) && lock_prefix, EXC_GP); |
---|
821 | |
---|
822 | /* ModRM and SIB bytes. */ |
---|
823 | if ( d & ModRM ) |
---|
824 | { |
---|
825 | modrm = insn_fetch_type(uint8_t); |
---|
826 | modrm_mod = (modrm & 0xc0) >> 6; |
---|
827 | modrm_reg = ((rex_prefix & 4) << 1) | ((modrm & 0x38) >> 3); |
---|
828 | modrm_rm = modrm & 0x07; |
---|
829 | |
---|
830 | if ( modrm_mod == 3 ) |
---|
831 | { |
---|
832 | modrm_rm |= (rex_prefix & 1) << 3; |
---|
833 | ea.type = OP_REG; |
---|
834 | ea.reg = decode_register( |
---|
835 | modrm_rm, &_regs, (d & ByteOp) && (rex_prefix == 0)); |
---|
836 | } |
---|
837 | else if ( ad_bytes == 2 ) |
---|
838 | { |
---|
839 | /* 16-bit ModR/M decode. */ |
---|
840 | switch ( modrm_rm ) |
---|
841 | { |
---|
842 | case 0: |
---|
843 | ea.mem.off = _regs.ebx + _regs.esi; |
---|
844 | break; |
---|
845 | case 1: |
---|
846 | ea.mem.off = _regs.ebx + _regs.edi; |
---|
847 | break; |
---|
848 | case 2: |
---|
849 | ea.mem.seg = x86_seg_ss; |
---|
850 | ea.mem.off = _regs.ebp + _regs.esi; |
---|
851 | break; |
---|
852 | case 3: |
---|
853 | ea.mem.seg = x86_seg_ss; |
---|
854 | ea.mem.off = _regs.ebp + _regs.edi; |
---|
855 | break; |
---|
856 | case 4: |
---|
857 | ea.mem.off = _regs.esi; |
---|
858 | break; |
---|
859 | case 5: |
---|
860 | ea.mem.off = _regs.edi; |
---|
861 | break; |
---|
862 | case 6: |
---|
863 | if ( modrm_mod == 0 ) |
---|
864 | break; |
---|
865 | ea.mem.seg = x86_seg_ss; |
---|
866 | ea.mem.off = _regs.ebp; |
---|
867 | break; |
---|
868 | case 7: |
---|
869 | ea.mem.off = _regs.ebx; |
---|
870 | break; |
---|
871 | } |
---|
872 | switch ( modrm_mod ) |
---|
873 | { |
---|
874 | case 0: |
---|
875 | if ( modrm_rm == 6 ) |
---|
876 | ea.mem.off = insn_fetch_type(int16_t); |
---|
877 | break; |
---|
878 | case 1: |
---|
879 | ea.mem.off += insn_fetch_type(int8_t); |
---|
880 | break; |
---|
881 | case 2: |
---|
882 | ea.mem.off += insn_fetch_type(int16_t); |
---|
883 | break; |
---|
884 | } |
---|
885 | ea.mem.off = truncate_ea(ea.mem.off); |
---|
886 | } |
---|
887 | else |
---|
888 | { |
---|
889 | /* 32/64-bit ModR/M decode. */ |
---|
890 | if ( modrm_rm == 4 ) |
---|
891 | { |
---|
892 | sib = insn_fetch_type(uint8_t); |
---|
893 | sib_index = ((sib >> 3) & 7) | ((rex_prefix << 2) & 8); |
---|
894 | sib_base = (sib & 7) | ((rex_prefix << 3) & 8); |
---|
895 | if ( sib_index != 4 ) |
---|
896 | ea.mem.off = *(long*)decode_register(sib_index, &_regs, 0); |
---|
897 | ea.mem.off <<= (sib >> 6) & 3; |
---|
898 | if ( (modrm_mod == 0) && ((sib_base & 7) == 5) ) |
---|
899 | ea.mem.off += insn_fetch_type(int32_t); |
---|
900 | else if ( sib_base == 4 ) |
---|
901 | { |
---|
902 | ea.mem.seg = x86_seg_ss; |
---|
903 | ea.mem.off += _regs.esp; |
---|
904 | if ( !twobyte && (b == 0x8f) ) |
---|
905 | /* POP <rm> computes its EA post increment. */ |
---|
906 | ea.mem.off += ((mode_64bit() && (op_bytes == 4)) |
---|
907 | ? 8 : op_bytes); |
---|
908 | } |
---|
909 | else if ( sib_base == 5 ) |
---|
910 | { |
---|
911 | ea.mem.seg = x86_seg_ss; |
---|
912 | ea.mem.off += _regs.ebp; |
---|
913 | } |
---|
914 | else |
---|
915 | ea.mem.off += *(long*)decode_register(sib_base, &_regs, 0); |
---|
916 | } |
---|
917 | else |
---|
918 | { |
---|
919 | modrm_rm |= (rex_prefix & 1) << 3; |
---|
920 | ea.mem.off = *(long *)decode_register(modrm_rm, &_regs, 0); |
---|
921 | if ( (modrm_rm == 5) && (modrm_mod != 0) ) |
---|
922 | ea.mem.seg = x86_seg_ss; |
---|
923 | } |
---|
924 | switch ( modrm_mod ) |
---|
925 | { |
---|
926 | case 0: |
---|
927 | if ( (modrm_rm & 7) != 5 ) |
---|
928 | break; |
---|
929 | ea.mem.off = insn_fetch_type(int32_t); |
---|
930 | if ( !mode_64bit() ) |
---|
931 | break; |
---|
932 | /* Relative to RIP of next instruction. Argh! */ |
---|
933 | ea.mem.off += _regs.eip; |
---|
934 | if ( (d & SrcMask) == SrcImm ) |
---|
935 | ea.mem.off += (d & ByteOp) ? 1 : |
---|
936 | ((op_bytes == 8) ? 4 : op_bytes); |
---|
937 | else if ( (d & SrcMask) == SrcImmByte ) |
---|
938 | ea.mem.off += 1; |
---|
939 | else if ( ((b == 0xf6) || (b == 0xf7)) && |
---|
940 | ((modrm_reg & 7) <= 1) ) |
---|
941 | /* Special case in Grp3: test has immediate operand. */ |
---|
942 | ea.mem.off += (d & ByteOp) ? 1 |
---|
943 | : ((op_bytes == 8) ? 4 : op_bytes); |
---|
944 | break; |
---|
945 | case 1: |
---|
946 | ea.mem.off += insn_fetch_type(int8_t); |
---|
947 | break; |
---|
948 | case 2: |
---|
949 | ea.mem.off += insn_fetch_type(int32_t); |
---|
950 | break; |
---|
951 | } |
---|
952 | ea.mem.off = truncate_ea(ea.mem.off); |
---|
953 | } |
---|
954 | } |
---|
955 | |
---|
956 | if ( override_seg != -1 ) |
---|
957 | ea.mem.seg = override_seg; |
---|
958 | |
---|
959 | /* Special instructions do their own operand decoding. */ |
---|
960 | if ( (d & DstMask) == ImplicitOps ) |
---|
961 | goto special_insn; |
---|
962 | |
---|
963 | /* Decode and fetch the source operand: register, memory or immediate. */ |
---|
964 | switch ( d & SrcMask ) |
---|
965 | { |
---|
966 | case SrcNone: |
---|
967 | break; |
---|
968 | case SrcReg: |
---|
969 | src.type = OP_REG; |
---|
970 | if ( d & ByteOp ) |
---|
971 | { |
---|
972 | src.reg = decode_register(modrm_reg, &_regs, (rex_prefix == 0)); |
---|
973 | src.val = *(uint8_t *)src.reg; |
---|
974 | src.bytes = 1; |
---|
975 | } |
---|
976 | else |
---|
977 | { |
---|
978 | src.reg = decode_register(modrm_reg, &_regs, 0); |
---|
979 | switch ( (src.bytes = op_bytes) ) |
---|
980 | { |
---|
981 | case 2: src.val = *(uint16_t *)src.reg; break; |
---|
982 | case 4: src.val = *(uint32_t *)src.reg; break; |
---|
983 | case 8: src.val = *(uint64_t *)src.reg; break; |
---|
984 | } |
---|
985 | } |
---|
986 | break; |
---|
987 | case SrcMem16: |
---|
988 | ea.bytes = 2; |
---|
989 | goto srcmem_common; |
---|
990 | case SrcMem: |
---|
991 | ea.bytes = (d & ByteOp) ? 1 : op_bytes; |
---|
992 | srcmem_common: |
---|
993 | src = ea; |
---|
994 | if ( src.type == OP_REG ) |
---|
995 | { |
---|
996 | switch ( src.bytes ) |
---|
997 | { |
---|
998 | case 1: src.val = *(uint8_t *)src.reg; break; |
---|
999 | case 2: src.val = *(uint16_t *)src.reg; break; |
---|
1000 | case 4: src.val = *(uint32_t *)src.reg; break; |
---|
1001 | case 8: src.val = *(uint64_t *)src.reg; break; |
---|
1002 | } |
---|
1003 | } |
---|
1004 | else if ( (rc = ops->read(src.mem.seg, src.mem.off, |
---|
1005 | &src.val, src.bytes, ctxt)) ) |
---|
1006 | goto done; |
---|
1007 | break; |
---|
1008 | case SrcImm: |
---|
1009 | src.type = OP_IMM; |
---|
1010 | src.bytes = (d & ByteOp) ? 1 : op_bytes; |
---|
1011 | if ( src.bytes == 8 ) src.bytes = 4; |
---|
1012 | /* NB. Immediates are sign-extended as necessary. */ |
---|
1013 | switch ( src.bytes ) |
---|
1014 | { |
---|
1015 | case 1: src.val = insn_fetch_type(int8_t); break; |
---|
1016 | case 2: src.val = insn_fetch_type(int16_t); break; |
---|
1017 | case 4: src.val = insn_fetch_type(int32_t); break; |
---|
1018 | } |
---|
1019 | break; |
---|
1020 | case SrcImmByte: |
---|
1021 | src.type = OP_IMM; |
---|
1022 | src.bytes = 1; |
---|
1023 | src.val = insn_fetch_type(int8_t); |
---|
1024 | break; |
---|
1025 | } |
---|
1026 | |
---|
1027 | /* Decode and fetch the destination operand: register or memory. */ |
---|
1028 | switch ( d & DstMask ) |
---|
1029 | { |
---|
1030 | case DstReg: |
---|
1031 | dst.type = OP_REG; |
---|
1032 | if ( d & ByteOp ) |
---|
1033 | { |
---|
1034 | dst.reg = decode_register(modrm_reg, &_regs, (rex_prefix == 0)); |
---|
1035 | dst.val = *(uint8_t *)dst.reg; |
---|
1036 | dst.bytes = 1; |
---|
1037 | } |
---|
1038 | else |
---|
1039 | { |
---|
1040 | dst.reg = decode_register(modrm_reg, &_regs, 0); |
---|
1041 | switch ( (dst.bytes = op_bytes) ) |
---|
1042 | { |
---|
1043 | case 2: dst.val = *(uint16_t *)dst.reg; break; |
---|
1044 | case 4: dst.val = *(uint32_t *)dst.reg; break; |
---|
1045 | case 8: dst.val = *(uint64_t *)dst.reg; break; |
---|
1046 | } |
---|
1047 | } |
---|
1048 | break; |
---|
1049 | case DstBitBase: |
---|
1050 | if ( ((d & SrcMask) == SrcImmByte) || (ea.type == OP_REG) ) |
---|
1051 | { |
---|
1052 | src.val &= (op_bytes << 3) - 1; |
---|
1053 | } |
---|
1054 | else |
---|
1055 | { |
---|
1056 | /* |
---|
1057 | * EA += BitOffset DIV op_bytes*8 |
---|
1058 | * BitOffset = BitOffset MOD op_bytes*8 |
---|
1059 | * DIV truncates towards negative infinity. |
---|
1060 | * MOD always produces a positive result. |
---|
1061 | */ |
---|
1062 | if ( op_bytes == 2 ) |
---|
1063 | src.val = (int16_t)src.val; |
---|
1064 | else if ( op_bytes == 4 ) |
---|
1065 | src.val = (int32_t)src.val; |
---|
1066 | if ( (long)src.val < 0 ) |
---|
1067 | { |
---|
1068 | unsigned long byte_offset; |
---|
1069 | byte_offset = op_bytes + (((-src.val-1) >> 3) & ~(op_bytes-1)); |
---|
1070 | ea.mem.off -= byte_offset; |
---|
1071 | src.val = (byte_offset << 3) + src.val; |
---|
1072 | } |
---|
1073 | else |
---|
1074 | { |
---|
1075 | ea.mem.off += (src.val >> 3) & ~(op_bytes - 1); |
---|
1076 | src.val &= (op_bytes << 3) - 1; |
---|
1077 | } |
---|
1078 | } |
---|
1079 | /* Becomes a normal DstMem operation from here on. */ |
---|
1080 | d = (d & ~DstMask) | DstMem; |
---|
1081 | case DstMem: |
---|
1082 | ea.bytes = (d & ByteOp) ? 1 : op_bytes; |
---|
1083 | dst = ea; |
---|
1084 | if ( dst.type == OP_REG ) |
---|
1085 | { |
---|
1086 | switch ( dst.bytes ) |
---|
1087 | { |
---|
1088 | case 1: dst.val = *(uint8_t *)dst.reg; break; |
---|
1089 | case 2: dst.val = *(uint16_t *)dst.reg; break; |
---|
1090 | case 4: dst.val = *(uint32_t *)dst.reg; break; |
---|
1091 | case 8: dst.val = *(uint64_t *)dst.reg; break; |
---|
1092 | } |
---|
1093 | } |
---|
1094 | else if ( !(d & Mov) ) /* optimisation - avoid slow emulated read */ |
---|
1095 | { |
---|
1096 | if ( (rc = ops->read(dst.mem.seg, dst.mem.off, |
---|
1097 | &dst.val, dst.bytes, ctxt)) ) |
---|
1098 | goto done; |
---|
1099 | dst.orig_val = dst.val; |
---|
1100 | } |
---|
1101 | break; |
---|
1102 | } |
---|
1103 | |
---|
1104 | /* LOCK prefix allowed only on instructions with memory destination. */ |
---|
1105 | generate_exception_if(lock_prefix && (dst.type != OP_MEM), EXC_GP); |
---|
1106 | |
---|
1107 | if ( twobyte ) |
---|
1108 | goto twobyte_insn; |
---|
1109 | |
---|
1110 | switch ( b ) |
---|
1111 | { |
---|
1112 | case 0x04 ... 0x05: /* add imm,%%eax */ |
---|
1113 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1114 | dst.val = _regs.eax; |
---|
1115 | case 0x00 ... 0x03: add: /* add */ |
---|
1116 | emulate_2op_SrcV("add", src, dst, _regs.eflags); |
---|
1117 | break; |
---|
1118 | |
---|
1119 | case 0x0c ... 0x0d: /* or imm,%%eax */ |
---|
1120 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1121 | dst.val = _regs.eax; |
---|
1122 | case 0x08 ... 0x0b: or: /* or */ |
---|
1123 | emulate_2op_SrcV("or", src, dst, _regs.eflags); |
---|
1124 | break; |
---|
1125 | |
---|
1126 | case 0x14 ... 0x15: /* adc imm,%%eax */ |
---|
1127 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1128 | dst.val = _regs.eax; |
---|
1129 | case 0x10 ... 0x13: adc: /* adc */ |
---|
1130 | emulate_2op_SrcV("adc", src, dst, _regs.eflags); |
---|
1131 | break; |
---|
1132 | |
---|
1133 | case 0x1c ... 0x1d: /* sbb imm,%%eax */ |
---|
1134 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1135 | dst.val = _regs.eax; |
---|
1136 | case 0x18 ... 0x1b: sbb: /* sbb */ |
---|
1137 | emulate_2op_SrcV("sbb", src, dst, _regs.eflags); |
---|
1138 | break; |
---|
1139 | |
---|
1140 | case 0x24 ... 0x25: /* and imm,%%eax */ |
---|
1141 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1142 | dst.val = _regs.eax; |
---|
1143 | case 0x20 ... 0x23: and: /* and */ |
---|
1144 | emulate_2op_SrcV("and", src, dst, _regs.eflags); |
---|
1145 | break; |
---|
1146 | |
---|
1147 | case 0x2c ... 0x2d: /* sub imm,%%eax */ |
---|
1148 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1149 | dst.val = _regs.eax; |
---|
1150 | case 0x28 ... 0x2b: sub: /* sub */ |
---|
1151 | emulate_2op_SrcV("sub", src, dst, _regs.eflags); |
---|
1152 | break; |
---|
1153 | |
---|
1154 | case 0x34 ... 0x35: /* xor imm,%%eax */ |
---|
1155 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1156 | dst.val = _regs.eax; |
---|
1157 | case 0x30 ... 0x33: xor: /* xor */ |
---|
1158 | emulate_2op_SrcV("xor", src, dst, _regs.eflags); |
---|
1159 | break; |
---|
1160 | |
---|
1161 | case 0x3c ... 0x3d: /* cmp imm,%%eax */ |
---|
1162 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1163 | dst.val = _regs.eax; |
---|
1164 | case 0x38 ... 0x3b: cmp: /* cmp */ |
---|
1165 | emulate_2op_SrcV("cmp", src, dst, _regs.eflags); |
---|
1166 | break; |
---|
1167 | |
---|
1168 | case 0x62: /* bound */ { |
---|
1169 | unsigned long src_val2; |
---|
1170 | int lb, ub, idx; |
---|
1171 | generate_exception_if(mode_64bit() || (src.type != OP_MEM), EXC_UD); |
---|
1172 | if ( (rc = ops->read(src.mem.seg, src.mem.off + op_bytes, |
---|
1173 | &src_val2, op_bytes, ctxt)) ) |
---|
1174 | goto done; |
---|
1175 | ub = (op_bytes == 2) ? (int16_t)src_val2 : (int32_t)src_val2; |
---|
1176 | lb = (op_bytes == 2) ? (int16_t)src.val : (int32_t)src.val; |
---|
1177 | idx = (op_bytes == 2) ? (int16_t)dst.val : (int32_t)dst.val; |
---|
1178 | generate_exception_if((idx < lb) || (idx > ub), EXC_BR); |
---|
1179 | dst.type = OP_NONE; |
---|
1180 | break; |
---|
1181 | } |
---|
1182 | |
---|
1183 | case 0x63: /* movsxd (x86/64) / arpl (x86/32) */ |
---|
1184 | if ( mode_64bit() ) |
---|
1185 | { |
---|
1186 | /* movsxd */ |
---|
1187 | if ( src.type == OP_REG ) |
---|
1188 | src.val = *(int32_t *)src.reg; |
---|
1189 | else if ( (rc = ops->read(src.mem.seg, src.mem.off, |
---|
1190 | &src.val, 4, ctxt)) ) |
---|
1191 | goto done; |
---|
1192 | dst.val = (int32_t)src.val; |
---|
1193 | } |
---|
1194 | else |
---|
1195 | { |
---|
1196 | /* arpl */ |
---|
1197 | uint16_t src_val = dst.val; |
---|
1198 | dst = src; |
---|
1199 | _regs.eflags &= ~EFLG_ZF; |
---|
1200 | _regs.eflags |= ((src_val & 3) > (dst.val & 3)) ? EFLG_ZF : 0; |
---|
1201 | if ( _regs.eflags & EFLG_ZF ) |
---|
1202 | dst.val = (dst.val & ~3) | (src_val & 3); |
---|
1203 | else |
---|
1204 | dst.type = OP_NONE; |
---|
1205 | } |
---|
1206 | break; |
---|
1207 | |
---|
1208 | case 0x69: /* imul imm16/32 */ |
---|
1209 | case 0x6b: /* imul imm8 */ { |
---|
1210 | unsigned long reg = *(long *)decode_register(modrm_reg, &_regs, 0); |
---|
1211 | _regs.eflags &= ~(EFLG_OF|EFLG_CF); |
---|
1212 | switch ( dst.bytes ) |
---|
1213 | { |
---|
1214 | case 2: |
---|
1215 | dst.val = ((uint32_t)(int16_t)src.val * |
---|
1216 | (uint32_t)(int16_t)reg); |
---|
1217 | if ( (int16_t)dst.val != (uint32_t)dst.val ) |
---|
1218 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
1219 | break; |
---|
1220 | #ifdef __x86_64__ |
---|
1221 | case 4: |
---|
1222 | dst.val = ((uint64_t)(int32_t)src.val * |
---|
1223 | (uint64_t)(int32_t)reg); |
---|
1224 | if ( (int32_t)dst.val != dst.val ) |
---|
1225 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
1226 | break; |
---|
1227 | #endif |
---|
1228 | default: { |
---|
1229 | unsigned long m[2] = { src.val, reg }; |
---|
1230 | if ( imul_dbl(m) ) |
---|
1231 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
1232 | dst.val = m[0]; |
---|
1233 | break; |
---|
1234 | } |
---|
1235 | } |
---|
1236 | dst.type = OP_REG; |
---|
1237 | dst.reg = decode_register(modrm_reg, &_regs, 0); |
---|
1238 | break; |
---|
1239 | } |
---|
1240 | |
---|
1241 | case 0x82: /* Grp1 (x86/32 only) */ |
---|
1242 | generate_exception_if(mode_64bit(), EXC_UD); |
---|
1243 | case 0x80: case 0x81: case 0x83: /* Grp1 */ |
---|
1244 | switch ( modrm_reg & 7 ) |
---|
1245 | { |
---|
1246 | case 0: goto add; |
---|
1247 | case 1: goto or; |
---|
1248 | case 2: goto adc; |
---|
1249 | case 3: goto sbb; |
---|
1250 | case 4: goto and; |
---|
1251 | case 5: goto sub; |
---|
1252 | case 6: goto xor; |
---|
1253 | case 7: goto cmp; |
---|
1254 | } |
---|
1255 | break; |
---|
1256 | |
---|
1257 | case 0xa8 ... 0xa9: /* test imm,%%eax */ |
---|
1258 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1259 | dst.val = _regs.eax; |
---|
1260 | case 0x84 ... 0x85: test: /* test */ |
---|
1261 | emulate_2op_SrcV("test", src, dst, _regs.eflags); |
---|
1262 | break; |
---|
1263 | |
---|
1264 | case 0x86 ... 0x87: xchg: /* xchg */ |
---|
1265 | /* Write back the register source. */ |
---|
1266 | switch ( dst.bytes ) |
---|
1267 | { |
---|
1268 | case 1: *(uint8_t *)src.reg = (uint8_t)dst.val; break; |
---|
1269 | case 2: *(uint16_t *)src.reg = (uint16_t)dst.val; break; |
---|
1270 | case 4: *src.reg = (uint32_t)dst.val; break; /* 64b reg: zero-extend */ |
---|
1271 | case 8: *src.reg = dst.val; break; |
---|
1272 | } |
---|
1273 | /* Write back the memory destination with implicit LOCK prefix. */ |
---|
1274 | dst.val = src.val; |
---|
1275 | lock_prefix = 1; |
---|
1276 | break; |
---|
1277 | |
---|
1278 | case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ |
---|
1279 | generate_exception_if((modrm_reg & 7) != 0, EXC_UD); |
---|
1280 | case 0x88 ... 0x8b: /* mov */ |
---|
1281 | dst.val = src.val; |
---|
1282 | break; |
---|
1283 | |
---|
1284 | case 0x8d: /* lea */ |
---|
1285 | dst.val = ea.mem.off; |
---|
1286 | break; |
---|
1287 | |
---|
1288 | case 0x8f: /* pop (sole member of Grp1a) */ |
---|
1289 | generate_exception_if((modrm_reg & 7) != 0, EXC_UD); |
---|
1290 | /* 64-bit mode: POP defaults to a 64-bit operand. */ |
---|
1291 | if ( mode_64bit() && (dst.bytes == 4) ) |
---|
1292 | dst.bytes = 8; |
---|
1293 | if ( (rc = ops->read(x86_seg_ss, sp_post_inc(dst.bytes), |
---|
1294 | &dst.val, dst.bytes, ctxt)) != 0 ) |
---|
1295 | goto done; |
---|
1296 | break; |
---|
1297 | |
---|
1298 | case 0xb0 ... 0xb7: /* mov imm8,r8 */ |
---|
1299 | dst.reg = decode_register( |
---|
1300 | (b & 7) | ((rex_prefix & 1) << 3), &_regs, (rex_prefix == 0)); |
---|
1301 | dst.val = src.val; |
---|
1302 | break; |
---|
1303 | |
---|
1304 | case 0xb8 ... 0xbf: /* mov imm{16,32,64},r{16,32,64} */ |
---|
1305 | if ( dst.bytes == 8 ) /* Fetch more bytes to obtain imm64 */ |
---|
1306 | src.val = ((uint32_t)src.val | |
---|
1307 | ((uint64_t)insn_fetch_type(uint32_t) << 32)); |
---|
1308 | dst.reg = decode_register( |
---|
1309 | (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); |
---|
1310 | dst.val = src.val; |
---|
1311 | break; |
---|
1312 | |
---|
1313 | case 0xc0 ... 0xc1: grp2: /* Grp2 */ |
---|
1314 | switch ( modrm_reg & 7 ) |
---|
1315 | { |
---|
1316 | case 0: /* rol */ |
---|
1317 | emulate_2op_SrcB("rol", src, dst, _regs.eflags); |
---|
1318 | break; |
---|
1319 | case 1: /* ror */ |
---|
1320 | emulate_2op_SrcB("ror", src, dst, _regs.eflags); |
---|
1321 | break; |
---|
1322 | case 2: /* rcl */ |
---|
1323 | emulate_2op_SrcB("rcl", src, dst, _regs.eflags); |
---|
1324 | break; |
---|
1325 | case 3: /* rcr */ |
---|
1326 | emulate_2op_SrcB("rcr", src, dst, _regs.eflags); |
---|
1327 | break; |
---|
1328 | case 4: /* sal/shl */ |
---|
1329 | case 6: /* sal/shl */ |
---|
1330 | emulate_2op_SrcB("sal", src, dst, _regs.eflags); |
---|
1331 | break; |
---|
1332 | case 5: /* shr */ |
---|
1333 | emulate_2op_SrcB("shr", src, dst, _regs.eflags); |
---|
1334 | break; |
---|
1335 | case 7: /* sar */ |
---|
1336 | emulate_2op_SrcB("sar", src, dst, _regs.eflags); |
---|
1337 | break; |
---|
1338 | } |
---|
1339 | break; |
---|
1340 | |
---|
1341 | case 0xd0 ... 0xd1: /* Grp2 */ |
---|
1342 | src.val = 1; |
---|
1343 | goto grp2; |
---|
1344 | |
---|
1345 | case 0xd2 ... 0xd3: /* Grp2 */ |
---|
1346 | src.val = _regs.ecx; |
---|
1347 | goto grp2; |
---|
1348 | |
---|
1349 | case 0xf6 ... 0xf7: /* Grp3 */ |
---|
1350 | switch ( modrm_reg & 7 ) |
---|
1351 | { |
---|
1352 | case 0 ... 1: /* test */ |
---|
1353 | /* Special case in Grp3: test has an immediate source operand. */ |
---|
1354 | src.type = OP_IMM; |
---|
1355 | src.bytes = (d & ByteOp) ? 1 : op_bytes; |
---|
1356 | if ( src.bytes == 8 ) src.bytes = 4; |
---|
1357 | switch ( src.bytes ) |
---|
1358 | { |
---|
1359 | case 1: src.val = insn_fetch_type(int8_t); break; |
---|
1360 | case 2: src.val = insn_fetch_type(int16_t); break; |
---|
1361 | case 4: src.val = insn_fetch_type(int32_t); break; |
---|
1362 | } |
---|
1363 | goto test; |
---|
1364 | case 2: /* not */ |
---|
1365 | dst.val = ~dst.val; |
---|
1366 | break; |
---|
1367 | case 3: /* neg */ |
---|
1368 | emulate_1op("neg", dst, _regs.eflags); |
---|
1369 | break; |
---|
1370 | case 4: /* mul */ |
---|
1371 | src = dst; |
---|
1372 | dst.type = OP_REG; |
---|
1373 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1374 | dst.val = *dst.reg; |
---|
1375 | _regs.eflags &= ~(EFLG_OF|EFLG_CF); |
---|
1376 | switch ( src.bytes ) |
---|
1377 | { |
---|
1378 | case 1: |
---|
1379 | dst.val *= src.val; |
---|
1380 | if ( (uint8_t)dst.val != (uint16_t)dst.val ) |
---|
1381 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
1382 | break; |
---|
1383 | case 2: |
---|
1384 | dst.val *= src.val; |
---|
1385 | if ( (uint16_t)dst.val != (uint32_t)dst.val ) |
---|
1386 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
1387 | *(uint16_t *)&_regs.edx = dst.val >> 16; |
---|
1388 | break; |
---|
1389 | #ifdef __x86_64__ |
---|
1390 | case 4: |
---|
1391 | dst.val *= src.val; |
---|
1392 | if ( (uint32_t)dst.val != dst.val ) |
---|
1393 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
1394 | _regs.edx = (uint32_t)(dst.val >> 32); |
---|
1395 | break; |
---|
1396 | #endif |
---|
1397 | default: { |
---|
1398 | unsigned long m[2] = { src.val, dst.val }; |
---|
1399 | if ( mul_dbl(m) ) |
---|
1400 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
1401 | _regs.edx = m[1]; |
---|
1402 | dst.val = m[0]; |
---|
1403 | break; |
---|
1404 | } |
---|
1405 | } |
---|
1406 | break; |
---|
1407 | case 5: /* imul */ |
---|
1408 | src = dst; |
---|
1409 | dst.type = OP_REG; |
---|
1410 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1411 | dst.val = *dst.reg; |
---|
1412 | _regs.eflags &= ~(EFLG_OF|EFLG_CF); |
---|
1413 | switch ( src.bytes ) |
---|
1414 | { |
---|
1415 | case 1: |
---|
1416 | dst.val = ((uint16_t)(int8_t)src.val * |
---|
1417 | (uint16_t)(int8_t)dst.val); |
---|
1418 | if ( (int8_t)dst.val != (uint16_t)dst.val ) |
---|
1419 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
1420 | break; |
---|
1421 | case 2: |
---|
1422 | dst.val = ((uint32_t)(int16_t)src.val * |
---|
1423 | (uint32_t)(int16_t)dst.val); |
---|
1424 | if ( (int16_t)dst.val != (uint32_t)dst.val ) |
---|
1425 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
1426 | *(uint16_t *)&_regs.edx = dst.val >> 16; |
---|
1427 | break; |
---|
1428 | #ifdef __x86_64__ |
---|
1429 | case 4: |
---|
1430 | dst.val = ((uint64_t)(int32_t)src.val * |
---|
1431 | (uint64_t)(int32_t)dst.val); |
---|
1432 | if ( (int32_t)dst.val != dst.val ) |
---|
1433 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
1434 | _regs.edx = (uint32_t)(dst.val >> 32); |
---|
1435 | break; |
---|
1436 | #endif |
---|
1437 | default: { |
---|
1438 | unsigned long m[2] = { src.val, dst.val }; |
---|
1439 | if ( imul_dbl(m) ) |
---|
1440 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
1441 | _regs.edx = m[1]; |
---|
1442 | dst.val = m[0]; |
---|
1443 | break; |
---|
1444 | } |
---|
1445 | } |
---|
1446 | break; |
---|
1447 | case 6: /* div */ { |
---|
1448 | unsigned long u[2], v; |
---|
1449 | src = dst; |
---|
1450 | dst.type = OP_REG; |
---|
1451 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1452 | switch ( src.bytes ) |
---|
1453 | { |
---|
1454 | case 1: |
---|
1455 | u[0] = (uint16_t)_regs.eax; |
---|
1456 | u[1] = 0; |
---|
1457 | v = (uint8_t)src.val; |
---|
1458 | generate_exception_if( |
---|
1459 | div_dbl(u, v) || ((uint8_t)u[0] != (uint16_t)u[0]), |
---|
1460 | EXC_DE); |
---|
1461 | dst.val = (uint8_t)u[0]; |
---|
1462 | ((uint8_t *)&_regs.eax)[1] = u[1]; |
---|
1463 | break; |
---|
1464 | case 2: |
---|
1465 | u[0] = ((uint32_t)_regs.edx << 16) | (uint16_t)_regs.eax; |
---|
1466 | u[1] = 0; |
---|
1467 | v = (uint16_t)src.val; |
---|
1468 | generate_exception_if( |
---|
1469 | div_dbl(u, v) || ((uint16_t)u[0] != (uint32_t)u[0]), |
---|
1470 | EXC_DE); |
---|
1471 | dst.val = (uint16_t)u[0]; |
---|
1472 | *(uint16_t *)&_regs.edx = u[1]; |
---|
1473 | break; |
---|
1474 | #ifdef __x86_64__ |
---|
1475 | case 4: |
---|
1476 | u[0] = (_regs.edx << 32) | (uint32_t)_regs.eax; |
---|
1477 | u[1] = 0; |
---|
1478 | v = (uint32_t)src.val; |
---|
1479 | generate_exception_if( |
---|
1480 | div_dbl(u, v) || ((uint32_t)u[0] != u[0]), |
---|
1481 | EXC_DE); |
---|
1482 | dst.val = (uint32_t)u[0]; |
---|
1483 | _regs.edx = (uint32_t)u[1]; |
---|
1484 | break; |
---|
1485 | #endif |
---|
1486 | default: |
---|
1487 | u[0] = _regs.eax; |
---|
1488 | u[1] = _regs.edx; |
---|
1489 | v = src.val; |
---|
1490 | generate_exception_if(div_dbl(u, v), EXC_DE); |
---|
1491 | dst.val = u[0]; |
---|
1492 | _regs.edx = u[1]; |
---|
1493 | break; |
---|
1494 | } |
---|
1495 | break; |
---|
1496 | } |
---|
1497 | case 7: /* idiv */ { |
---|
1498 | unsigned long u[2], v; |
---|
1499 | src = dst; |
---|
1500 | dst.type = OP_REG; |
---|
1501 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1502 | switch ( src.bytes ) |
---|
1503 | { |
---|
1504 | case 1: |
---|
1505 | u[0] = (int16_t)_regs.eax; |
---|
1506 | u[1] = ((long)u[0] < 0) ? ~0UL : 0UL; |
---|
1507 | v = (int8_t)src.val; |
---|
1508 | generate_exception_if( |
---|
1509 | idiv_dbl(u, v) || ((int8_t)u[0] != (int16_t)u[0]), |
---|
1510 | EXC_DE); |
---|
1511 | dst.val = (int8_t)u[0]; |
---|
1512 | ((int8_t *)&_regs.eax)[1] = u[1]; |
---|
1513 | break; |
---|
1514 | case 2: |
---|
1515 | u[0] = (int32_t)((_regs.edx << 16) | (uint16_t)_regs.eax); |
---|
1516 | u[1] = ((long)u[0] < 0) ? ~0UL : 0UL; |
---|
1517 | v = (int16_t)src.val; |
---|
1518 | generate_exception_if( |
---|
1519 | idiv_dbl(u, v) || ((int16_t)u[0] != (int32_t)u[0]), |
---|
1520 | EXC_DE); |
---|
1521 | dst.val = (int16_t)u[0]; |
---|
1522 | *(int16_t *)&_regs.edx = u[1]; |
---|
1523 | break; |
---|
1524 | #ifdef __x86_64__ |
---|
1525 | case 4: |
---|
1526 | u[0] = (_regs.edx << 32) | (uint32_t)_regs.eax; |
---|
1527 | u[1] = ((long)u[0] < 0) ? ~0UL : 0UL; |
---|
1528 | v = (int32_t)src.val; |
---|
1529 | generate_exception_if( |
---|
1530 | idiv_dbl(u, v) || ((int32_t)u[0] != u[0]), |
---|
1531 | EXC_DE); |
---|
1532 | dst.val = (int32_t)u[0]; |
---|
1533 | _regs.edx = (uint32_t)u[1]; |
---|
1534 | break; |
---|
1535 | #endif |
---|
1536 | default: |
---|
1537 | u[0] = _regs.eax; |
---|
1538 | u[1] = _regs.edx; |
---|
1539 | v = src.val; |
---|
1540 | generate_exception_if(idiv_dbl(u, v), EXC_DE); |
---|
1541 | dst.val = u[0]; |
---|
1542 | _regs.edx = u[1]; |
---|
1543 | break; |
---|
1544 | } |
---|
1545 | break; |
---|
1546 | } |
---|
1547 | default: |
---|
1548 | goto cannot_emulate; |
---|
1549 | } |
---|
1550 | break; |
---|
1551 | |
---|
1552 | case 0xfe: /* Grp4 */ |
---|
1553 | generate_exception_if((modrm_reg & 7) >= 2, EXC_UD); |
---|
1554 | case 0xff: /* Grp5 */ |
---|
1555 | switch ( modrm_reg & 7 ) |
---|
1556 | { |
---|
1557 | case 0: /* inc */ |
---|
1558 | emulate_1op("inc", dst, _regs.eflags); |
---|
1559 | break; |
---|
1560 | case 1: /* dec */ |
---|
1561 | emulate_1op("dec", dst, _regs.eflags); |
---|
1562 | break; |
---|
1563 | case 2: /* call (near) */ |
---|
1564 | case 4: /* jmp (near) */ |
---|
1565 | if ( ((op_bytes = dst.bytes) != 8) && mode_64bit() ) |
---|
1566 | { |
---|
1567 | dst.bytes = op_bytes = 8; |
---|
1568 | if ( dst.type == OP_REG ) |
---|
1569 | dst.val = *dst.reg; |
---|
1570 | else if ( (rc = ops->read(dst.mem.seg, dst.mem.off, |
---|
1571 | &dst.val, 8, ctxt)) != 0 ) |
---|
1572 | goto done; |
---|
1573 | } |
---|
1574 | src.val = _regs.eip; |
---|
1575 | _regs.eip = dst.val; |
---|
1576 | if ( (modrm_reg & 7) == 2 ) |
---|
1577 | goto push; /* call */ |
---|
1578 | break; |
---|
1579 | case 6: /* push */ |
---|
1580 | /* 64-bit mode: PUSH defaults to a 64-bit operand. */ |
---|
1581 | if ( mode_64bit() && (dst.bytes == 4) ) |
---|
1582 | { |
---|
1583 | dst.bytes = 8; |
---|
1584 | if ( dst.type == OP_REG ) |
---|
1585 | dst.val = *dst.reg; |
---|
1586 | else if ( (rc = ops->read(dst.mem.seg, dst.mem.off, |
---|
1587 | &dst.val, 8, ctxt)) != 0 ) |
---|
1588 | goto done; |
---|
1589 | } |
---|
1590 | if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes), |
---|
1591 | dst.val, dst.bytes, ctxt)) != 0 ) |
---|
1592 | goto done; |
---|
1593 | dst.type = OP_NONE; |
---|
1594 | break; |
---|
1595 | case 7: |
---|
1596 | generate_exception_if(1, EXC_UD); |
---|
1597 | default: |
---|
1598 | goto cannot_emulate; |
---|
1599 | } |
---|
1600 | break; |
---|
1601 | } |
---|
1602 | |
---|
1603 | writeback: |
---|
1604 | switch ( dst.type ) |
---|
1605 | { |
---|
1606 | case OP_REG: |
---|
1607 | /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */ |
---|
1608 | switch ( dst.bytes ) |
---|
1609 | { |
---|
1610 | case 1: *(uint8_t *)dst.reg = (uint8_t)dst.val; break; |
---|
1611 | case 2: *(uint16_t *)dst.reg = (uint16_t)dst.val; break; |
---|
1612 | case 4: *dst.reg = (uint32_t)dst.val; break; /* 64b: zero-ext */ |
---|
1613 | case 8: *dst.reg = dst.val; break; |
---|
1614 | } |
---|
1615 | break; |
---|
1616 | case OP_MEM: |
---|
1617 | if ( !(d & Mov) && (dst.orig_val == dst.val) ) |
---|
1618 | /* nothing to do */; |
---|
1619 | else if ( lock_prefix ) |
---|
1620 | rc = ops->cmpxchg( |
---|
1621 | dst.mem.seg, dst.mem.off, dst.orig_val, |
---|
1622 | dst.val, dst.bytes, ctxt); |
---|
1623 | else |
---|
1624 | rc = ops->write( |
---|
1625 | dst.mem.seg, dst.mem.off, dst.val, dst.bytes, ctxt); |
---|
1626 | if ( rc != 0 ) |
---|
1627 | goto done; |
---|
1628 | default: |
---|
1629 | break; |
---|
1630 | } |
---|
1631 | |
---|
1632 | /* Commit shadow register state. */ |
---|
1633 | *ctxt->regs = _regs; |
---|
1634 | |
---|
1635 | done: |
---|
1636 | return rc; |
---|
1637 | |
---|
1638 | special_insn: |
---|
1639 | dst.type = OP_NONE; |
---|
1640 | |
---|
1641 | /* |
---|
1642 | * The only implicit-operands instructions allowed a LOCK prefix are |
---|
1643 | * CMPXCHG{8,16}B, MOV CRn, MOV DRn. |
---|
1644 | */ |
---|
1645 | generate_exception_if(lock_prefix && |
---|
1646 | ((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */ |
---|
1647 | (b != 0xc7), /* CMPXCHG{8,16}B */ |
---|
1648 | EXC_GP); |
---|
1649 | |
---|
1650 | if ( twobyte ) |
---|
1651 | goto twobyte_special_insn; |
---|
1652 | |
---|
1653 | switch ( b ) |
---|
1654 | { |
---|
1655 | case 0x27: /* daa */ { |
---|
1656 | uint8_t al = _regs.eax; |
---|
1657 | unsigned long eflags = _regs.eflags; |
---|
1658 | generate_exception_if(mode_64bit(), EXC_UD); |
---|
1659 | _regs.eflags &= ~(EFLG_CF|EFLG_AF); |
---|
1660 | if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) ) |
---|
1661 | { |
---|
1662 | *(uint8_t *)&_regs.eax += 6; |
---|
1663 | _regs.eflags |= EFLG_AF; |
---|
1664 | } |
---|
1665 | if ( (al > 0x99) || (eflags & EFLG_CF) ) |
---|
1666 | { |
---|
1667 | *(uint8_t *)&_regs.eax += 0x60; |
---|
1668 | _regs.eflags |= EFLG_CF; |
---|
1669 | } |
---|
1670 | _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF); |
---|
1671 | _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0; |
---|
1672 | _regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0; |
---|
1673 | _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0; |
---|
1674 | break; |
---|
1675 | } |
---|
1676 | |
---|
1677 | case 0x2f: /* das */ { |
---|
1678 | uint8_t al = _regs.eax; |
---|
1679 | unsigned long eflags = _regs.eflags; |
---|
1680 | generate_exception_if(mode_64bit(), EXC_UD); |
---|
1681 | _regs.eflags &= ~(EFLG_CF|EFLG_AF); |
---|
1682 | if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) ) |
---|
1683 | { |
---|
1684 | _regs.eflags |= EFLG_AF; |
---|
1685 | if ( (al < 6) || (eflags & EFLG_CF) ) |
---|
1686 | _regs.eflags |= EFLG_CF; |
---|
1687 | *(uint8_t *)&_regs.eax -= 6; |
---|
1688 | } |
---|
1689 | if ( (al > 0x99) || (eflags & EFLG_CF) ) |
---|
1690 | { |
---|
1691 | *(uint8_t *)&_regs.eax -= 0x60; |
---|
1692 | _regs.eflags |= EFLG_CF; |
---|
1693 | } |
---|
1694 | _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF); |
---|
1695 | _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0; |
---|
1696 | _regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0; |
---|
1697 | _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0; |
---|
1698 | break; |
---|
1699 | } |
---|
1700 | |
---|
1701 | case 0x37: /* aaa */ |
---|
1702 | case 0x3f: /* aas */ |
---|
1703 | generate_exception_if(mode_64bit(), EXC_UD); |
---|
1704 | _regs.eflags &= ~EFLG_CF; |
---|
1705 | if ( ((uint8_t)_regs.eax > 9) || (_regs.eflags & EFLG_AF) ) |
---|
1706 | { |
---|
1707 | ((uint8_t *)&_regs.eax)[0] += (b == 0x37) ? 6 : -6; |
---|
1708 | ((uint8_t *)&_regs.eax)[1] += (b == 0x37) ? 1 : -1; |
---|
1709 | _regs.eflags |= EFLG_CF | EFLG_AF; |
---|
1710 | } |
---|
1711 | ((uint8_t *)&_regs.eax)[0] &= 0x0f; |
---|
1712 | break; |
---|
1713 | |
---|
1714 | case 0x40 ... 0x4f: /* inc/dec reg */ |
---|
1715 | dst.type = OP_REG; |
---|
1716 | dst.reg = decode_register(b & 7, &_regs, 0); |
---|
1717 | dst.bytes = op_bytes; |
---|
1718 | dst.val = *dst.reg; |
---|
1719 | if ( b & 8 ) |
---|
1720 | emulate_1op("dec", dst, _regs.eflags); |
---|
1721 | else |
---|
1722 | emulate_1op("inc", dst, _regs.eflags); |
---|
1723 | break; |
---|
1724 | |
---|
1725 | case 0x50 ... 0x57: /* push reg */ |
---|
1726 | src.val = *(unsigned long *)decode_register( |
---|
1727 | (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); |
---|
1728 | goto push; |
---|
1729 | |
---|
1730 | case 0x58 ... 0x5f: /* pop reg */ |
---|
1731 | dst.type = OP_REG; |
---|
1732 | dst.reg = decode_register( |
---|
1733 | (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); |
---|
1734 | dst.bytes = op_bytes; |
---|
1735 | if ( mode_64bit() && (dst.bytes == 4) ) |
---|
1736 | dst.bytes = 8; |
---|
1737 | if ( (rc = ops->read(x86_seg_ss, sp_post_inc(dst.bytes), |
---|
1738 | &dst.val, dst.bytes, ctxt)) != 0 ) |
---|
1739 | goto done; |
---|
1740 | break; |
---|
1741 | |
---|
1742 | case 0x60: /* pusha */ { |
---|
1743 | int i; |
---|
1744 | unsigned long regs[] = { |
---|
1745 | _regs.eax, _regs.ecx, _regs.edx, _regs.ebx, |
---|
1746 | _regs.esp, _regs.ebp, _regs.esi, _regs.edi }; |
---|
1747 | generate_exception_if(mode_64bit(), EXC_UD); |
---|
1748 | for ( i = 0; i < 8; i++ ) |
---|
1749 | if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), |
---|
1750 | regs[i], op_bytes, ctxt)) != 0 ) |
---|
1751 | goto done; |
---|
1752 | break; |
---|
1753 | } |
---|
1754 | |
---|
1755 | case 0x61: /* popa */ { |
---|
1756 | int i; |
---|
1757 | unsigned long dummy_esp, *regs[] = { |
---|
1758 | (unsigned long *)&_regs.edi, (unsigned long *)&_regs.esi, |
---|
1759 | (unsigned long *)&_regs.ebp, (unsigned long *)&dummy_esp, |
---|
1760 | (unsigned long *)&_regs.ebx, (unsigned long *)&_regs.edx, |
---|
1761 | (unsigned long *)&_regs.ecx, (unsigned long *)&_regs.eax }; |
---|
1762 | generate_exception_if(mode_64bit(), EXC_UD); |
---|
1763 | for ( i = 0; i < 8; i++ ) |
---|
1764 | if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes), |
---|
1765 | regs[i], op_bytes, ctxt)) != 0 ) |
---|
1766 | goto done; |
---|
1767 | break; |
---|
1768 | } |
---|
1769 | |
---|
1770 | case 0x68: /* push imm{16,32,64} */ |
---|
1771 | src.val = ((op_bytes == 2) |
---|
1772 | ? (int32_t)insn_fetch_type(int16_t) |
---|
1773 | : insn_fetch_type(int32_t)); |
---|
1774 | goto push; |
---|
1775 | |
---|
1776 | case 0x6a: /* push imm8 */ |
---|
1777 | src.val = insn_fetch_type(int8_t); |
---|
1778 | push: |
---|
1779 | d |= Mov; /* force writeback */ |
---|
1780 | dst.type = OP_MEM; |
---|
1781 | dst.bytes = op_bytes; |
---|
1782 | if ( mode_64bit() && (dst.bytes == 4) ) |
---|
1783 | dst.bytes = 8; |
---|
1784 | dst.val = src.val; |
---|
1785 | dst.mem.seg = x86_seg_ss; |
---|
1786 | dst.mem.off = sp_pre_dec(dst.bytes); |
---|
1787 | break; |
---|
1788 | |
---|
1789 | case 0x6c ... 0x6d: /* ins %dx,%es:%edi */ |
---|
1790 | handle_rep_prefix(); |
---|
1791 | generate_exception_if(!mode_iopl(), EXC_GP); |
---|
1792 | dst.type = OP_MEM; |
---|
1793 | dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes; |
---|
1794 | dst.mem.seg = x86_seg_es; |
---|
1795 | dst.mem.off = truncate_ea(_regs.edi); |
---|
1796 | fail_if(ops->read_io == NULL); |
---|
1797 | if ( (rc = ops->read_io((uint16_t)_regs.edx, dst.bytes, |
---|
1798 | &dst.val, ctxt)) != 0 ) |
---|
1799 | goto done; |
---|
1800 | register_address_increment( |
---|
1801 | _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); |
---|
1802 | break; |
---|
1803 | |
---|
1804 | case 0x6e ... 0x6f: /* outs %esi,%dx */ |
---|
1805 | handle_rep_prefix(); |
---|
1806 | generate_exception_if(!mode_iopl(), EXC_GP); |
---|
1807 | dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes; |
---|
1808 | if ( (rc = ops->read(ea.mem.seg, truncate_ea(_regs.esi), |
---|
1809 | &dst.val, dst.bytes, ctxt)) != 0 ) |
---|
1810 | goto done; |
---|
1811 | fail_if(ops->write_io == NULL); |
---|
1812 | if ( (rc = ops->write_io((uint16_t)_regs.edx, dst.bytes, |
---|
1813 | dst.val, ctxt)) != 0 ) |
---|
1814 | goto done; |
---|
1815 | register_address_increment( |
---|
1816 | _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); |
---|
1817 | break; |
---|
1818 | |
---|
1819 | case 0x70 ... 0x7f: /* jcc (short) */ { |
---|
1820 | int rel = insn_fetch_type(int8_t); |
---|
1821 | if ( test_cc(b, _regs.eflags) ) |
---|
1822 | jmp_rel(rel); |
---|
1823 | break; |
---|
1824 | } |
---|
1825 | |
---|
1826 | case 0x90: /* nop / xchg %%r8,%%rax */ |
---|
1827 | if ( !(rex_prefix & 1) ) |
---|
1828 | break; /* nop */ |
---|
1829 | |
---|
1830 | case 0x91 ... 0x97: /* xchg reg,%%rax */ |
---|
1831 | src.type = dst.type = OP_REG; |
---|
1832 | src.bytes = dst.bytes = op_bytes; |
---|
1833 | src.reg = (unsigned long *)&_regs.eax; |
---|
1834 | src.val = *src.reg; |
---|
1835 | dst.reg = decode_register( |
---|
1836 | (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); |
---|
1837 | dst.val = *dst.reg; |
---|
1838 | goto xchg; |
---|
1839 | |
---|
1840 | case 0x98: /* cbw/cwde/cdqe */ |
---|
1841 | switch ( op_bytes ) |
---|
1842 | { |
---|
1843 | case 2: *(int16_t *)&_regs.eax = (int8_t)_regs.eax; break; /* cbw */ |
---|
1844 | case 4: _regs.eax = (uint32_t)(int16_t)_regs.eax; break; /* cwde */ |
---|
1845 | case 8: _regs.eax = (int32_t)_regs.eax; break; /* cdqe */ |
---|
1846 | } |
---|
1847 | break; |
---|
1848 | |
---|
1849 | case 0x99: /* cwd/cdq/cqo */ |
---|
1850 | switch ( op_bytes ) |
---|
1851 | { |
---|
1852 | case 2: |
---|
1853 | *(int16_t *)&_regs.edx = ((int16_t)_regs.eax < 0) ? -1 : 0; |
---|
1854 | break; |
---|
1855 | case 4: |
---|
1856 | _regs.edx = (uint32_t)(((int32_t)_regs.eax < 0) ? -1 : 0); |
---|
1857 | break; |
---|
1858 | case 8: |
---|
1859 | _regs.edx = (_regs.eax < 0) ? -1 : 0; |
---|
1860 | break; |
---|
1861 | } |
---|
1862 | break; |
---|
1863 | |
---|
1864 | case 0x9e: /* sahf */ |
---|
1865 | *(uint8_t *)_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02; |
---|
1866 | break; |
---|
1867 | |
---|
1868 | case 0x9f: /* lahf */ |
---|
1869 | ((uint8_t *)&_regs.eax)[1] = (_regs.eflags & 0xd7) | 0x02; |
---|
1870 | break; |
---|
1871 | |
---|
1872 | case 0xa0 ... 0xa1: /* mov mem.offs,{%al,%ax,%eax,%rax} */ |
---|
1873 | /* Source EA is not encoded via ModRM. */ |
---|
1874 | dst.type = OP_REG; |
---|
1875 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1876 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; |
---|
1877 | if ( (rc = ops->read(ea.mem.seg, insn_fetch_bytes(ad_bytes), |
---|
1878 | &dst.val, dst.bytes, ctxt)) != 0 ) |
---|
1879 | goto done; |
---|
1880 | break; |
---|
1881 | |
---|
1882 | case 0xa2 ... 0xa3: /* mov {%al,%ax,%eax,%rax},mem.offs */ |
---|
1883 | /* Destination EA is not encoded via ModRM. */ |
---|
1884 | dst.type = OP_MEM; |
---|
1885 | dst.mem.seg = ea.mem.seg; |
---|
1886 | dst.mem.off = insn_fetch_bytes(ad_bytes); |
---|
1887 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; |
---|
1888 | dst.val = (unsigned long)_regs.eax; |
---|
1889 | break; |
---|
1890 | |
---|
1891 | case 0xa4 ... 0xa5: /* movs */ |
---|
1892 | handle_rep_prefix(); |
---|
1893 | dst.type = OP_MEM; |
---|
1894 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; |
---|
1895 | dst.mem.seg = x86_seg_es; |
---|
1896 | dst.mem.off = truncate_ea(_regs.edi); |
---|
1897 | if ( (rc = ops->read(ea.mem.seg, truncate_ea(_regs.esi), |
---|
1898 | &dst.val, dst.bytes, ctxt)) != 0 ) |
---|
1899 | goto done; |
---|
1900 | register_address_increment( |
---|
1901 | _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); |
---|
1902 | register_address_increment( |
---|
1903 | _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); |
---|
1904 | break; |
---|
1905 | |
---|
1906 | case 0xaa ... 0xab: /* stos */ |
---|
1907 | handle_rep_prefix(); |
---|
1908 | dst.type = OP_MEM; |
---|
1909 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; |
---|
1910 | dst.mem.seg = x86_seg_es; |
---|
1911 | dst.mem.off = truncate_ea(_regs.edi); |
---|
1912 | dst.val = _regs.eax; |
---|
1913 | register_address_increment( |
---|
1914 | _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); |
---|
1915 | break; |
---|
1916 | |
---|
1917 | case 0xac ... 0xad: /* lods */ |
---|
1918 | handle_rep_prefix(); |
---|
1919 | dst.type = OP_REG; |
---|
1920 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; |
---|
1921 | dst.reg = (unsigned long *)&_regs.eax; |
---|
1922 | if ( (rc = ops->read(ea.mem.seg, truncate_ea(_regs.esi), |
---|
1923 | &dst.val, dst.bytes, ctxt)) != 0 ) |
---|
1924 | goto done; |
---|
1925 | register_address_increment( |
---|
1926 | _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); |
---|
1927 | break; |
---|
1928 | |
---|
1929 | case 0xc2: /* ret imm16 (near) */ |
---|
1930 | case 0xc3: /* ret (near) */ { |
---|
1931 | int offset = (b == 0xc2) ? insn_fetch_type(uint16_t) : 0; |
---|
1932 | op_bytes = mode_64bit() ? 8 : op_bytes; |
---|
1933 | if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes + offset), |
---|
1934 | &dst.val, op_bytes, ctxt)) != 0 ) |
---|
1935 | goto done; |
---|
1936 | _regs.eip = dst.val; |
---|
1937 | break; |
---|
1938 | } |
---|
1939 | |
---|
1940 | case 0xd4: /* aam */ { |
---|
1941 | unsigned int base = insn_fetch_type(uint8_t); |
---|
1942 | uint8_t al = _regs.eax; |
---|
1943 | generate_exception_if(mode_64bit(), EXC_UD); |
---|
1944 | generate_exception_if(base == 0, EXC_DE); |
---|
1945 | *(uint16_t *)&_regs.eax = ((al / base) << 8) | (al % base); |
---|
1946 | _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF); |
---|
1947 | _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0; |
---|
1948 | _regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0; |
---|
1949 | _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0; |
---|
1950 | break; |
---|
1951 | } |
---|
1952 | |
---|
1953 | case 0xd5: /* aad */ { |
---|
1954 | unsigned int base = insn_fetch_type(uint8_t); |
---|
1955 | uint16_t ax = _regs.eax; |
---|
1956 | generate_exception_if(mode_64bit(), EXC_UD); |
---|
1957 | *(uint16_t *)&_regs.eax = (uint8_t)(ax + ((ax >> 8) * base)); |
---|
1958 | _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF); |
---|
1959 | _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0; |
---|
1960 | _regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0; |
---|
1961 | _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0; |
---|
1962 | break; |
---|
1963 | } |
---|
1964 | |
---|
1965 | case 0xd6: /* salc */ |
---|
1966 | generate_exception_if(mode_64bit(), EXC_UD); |
---|
1967 | *(uint8_t *)&_regs.eax = (_regs.eflags & EFLG_CF) ? 0xff : 0x00; |
---|
1968 | break; |
---|
1969 | |
---|
1970 | case 0xd7: /* xlat */ { |
---|
1971 | unsigned long al = (uint8_t)_regs.eax; |
---|
1972 | if ( (rc = ops->read(ea.mem.seg, truncate_ea(_regs.ebx + al), |
---|
1973 | &al, 1, ctxt)) != 0 ) |
---|
1974 | goto done; |
---|
1975 | *(uint8_t *)&_regs.eax = al; |
---|
1976 | break; |
---|
1977 | } |
---|
1978 | |
---|
1979 | case 0xe0 ... 0xe2: /* loop{,z,nz} */ { |
---|
1980 | int rel = insn_fetch_type(int8_t); |
---|
1981 | int do_jmp = !(_regs.eflags & EFLG_ZF); /* loopnz */ |
---|
1982 | if ( b == 0xe1 ) |
---|
1983 | do_jmp = !do_jmp; /* loopz */ |
---|
1984 | else if ( b == 0xe2 ) |
---|
1985 | do_jmp = 1; /* loop */ |
---|
1986 | switch ( ad_bytes ) |
---|
1987 | { |
---|
1988 | case 2: |
---|
1989 | do_jmp &= --(*(uint16_t *)&_regs.ecx) != 0; |
---|
1990 | break; |
---|
1991 | case 4: |
---|
1992 | do_jmp &= --(*(uint32_t *)&_regs.ecx) != 0; |
---|
1993 | _regs.ecx = (uint32_t)_regs.ecx; /* zero extend in x86/64 mode */ |
---|
1994 | break; |
---|
1995 | default: /* case 8: */ |
---|
1996 | do_jmp &= --_regs.ecx != 0; |
---|
1997 | break; |
---|
1998 | } |
---|
1999 | if ( do_jmp ) |
---|
2000 | jmp_rel(rel); |
---|
2001 | break; |
---|
2002 | } |
---|
2003 | |
---|
2004 | case 0xe3: /* jcxz/jecxz (short) */ { |
---|
2005 | int rel = insn_fetch_type(int8_t); |
---|
2006 | if ( (ad_bytes == 2) ? !(uint16_t)_regs.ecx : |
---|
2007 | (ad_bytes == 4) ? !(uint32_t)_regs.ecx : !_regs.ecx ) |
---|
2008 | jmp_rel(rel); |
---|
2009 | break; |
---|
2010 | } |
---|
2011 | |
---|
2012 | case 0xe4: /* in imm8,%al */ |
---|
2013 | case 0xe5: /* in imm8,%eax */ |
---|
2014 | case 0xe6: /* out %al,imm8 */ |
---|
2015 | case 0xe7: /* out %eax,imm8 */ |
---|
2016 | case 0xec: /* in %dx,%al */ |
---|
2017 | case 0xed: /* in %dx,%eax */ |
---|
2018 | case 0xee: /* out %al,%dx */ |
---|
2019 | case 0xef: /* out %eax,%dx */ { |
---|
2020 | unsigned int port = ((b < 0xe8) |
---|
2021 | ? insn_fetch_type(uint8_t) |
---|
2022 | : (uint16_t)_regs.edx); |
---|
2023 | generate_exception_if(!mode_iopl(), EXC_GP); |
---|
2024 | op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes; |
---|
2025 | if ( b & 2 ) |
---|
2026 | { |
---|
2027 | /* out */ |
---|
2028 | fail_if(ops->write_io == NULL); |
---|
2029 | rc = ops->write_io(port, op_bytes, _regs.eax, ctxt); |
---|
2030 | |
---|
2031 | } |
---|
2032 | else |
---|
2033 | { |
---|
2034 | /* in */ |
---|
2035 | dst.type = OP_REG; |
---|
2036 | dst.bytes = op_bytes; |
---|
2037 | dst.reg = (unsigned long *)&_regs.eax; |
---|
2038 | fail_if(ops->read_io == NULL); |
---|
2039 | rc = ops->read_io(port, dst.bytes, &dst.val, ctxt); |
---|
2040 | } |
---|
2041 | if ( rc != 0 ) |
---|
2042 | goto done; |
---|
2043 | break; |
---|
2044 | } |
---|
2045 | |
---|
2046 | case 0xe8: /* call (near) */ { |
---|
2047 | int rel = (((op_bytes == 2) && !mode_64bit()) |
---|
2048 | ? (int32_t)insn_fetch_type(int16_t) |
---|
2049 | : insn_fetch_type(int32_t)); |
---|
2050 | op_bytes = mode_64bit() ? 8 : op_bytes; |
---|
2051 | src.val = _regs.eip; |
---|
2052 | jmp_rel(rel); |
---|
2053 | goto push; |
---|
2054 | } |
---|
2055 | |
---|
2056 | case 0xe9: /* jmp (near) */ { |
---|
2057 | int rel = (((op_bytes == 2) && !mode_64bit()) |
---|
2058 | ? (int32_t)insn_fetch_type(int16_t) |
---|
2059 | : insn_fetch_type(int32_t)); |
---|
2060 | jmp_rel(rel); |
---|
2061 | break; |
---|
2062 | } |
---|
2063 | |
---|
2064 | case 0xeb: /* jmp (short) */ |
---|
2065 | jmp_rel(insn_fetch_type(int8_t)); |
---|
2066 | break; |
---|
2067 | |
---|
2068 | case 0xf5: /* cmc */ |
---|
2069 | _regs.eflags ^= EFLG_CF; |
---|
2070 | break; |
---|
2071 | |
---|
2072 | case 0xf8: /* clc */ |
---|
2073 | _regs.eflags &= ~EFLG_CF; |
---|
2074 | break; |
---|
2075 | |
---|
2076 | case 0xf9: /* stc */ |
---|
2077 | _regs.eflags |= EFLG_CF; |
---|
2078 | break; |
---|
2079 | |
---|
2080 | case 0xfa: /* cli */ |
---|
2081 | generate_exception_if(!mode_iopl(), EXC_GP); |
---|
2082 | fail_if(ops->write_rflags == NULL); |
---|
2083 | if ( (rc = ops->write_rflags(_regs.eflags & ~EFLG_IF, ctxt)) != 0 ) |
---|
2084 | goto done; |
---|
2085 | break; |
---|
2086 | |
---|
2087 | case 0xfb: /* sti */ |
---|
2088 | generate_exception_if(!mode_iopl(), EXC_GP); |
---|
2089 | fail_if(ops->write_rflags == NULL); |
---|
2090 | if ( (rc = ops->write_rflags(_regs.eflags | EFLG_IF, ctxt)) != 0 ) |
---|
2091 | goto done; |
---|
2092 | break; |
---|
2093 | |
---|
2094 | case 0xfc: /* cld */ |
---|
2095 | _regs.eflags &= ~EFLG_DF; |
---|
2096 | break; |
---|
2097 | |
---|
2098 | case 0xfd: /* std */ |
---|
2099 | _regs.eflags |= EFLG_DF; |
---|
2100 | break; |
---|
2101 | } |
---|
2102 | goto writeback; |
---|
2103 | |
---|
2104 | twobyte_insn: |
---|
2105 | switch ( b ) |
---|
2106 | { |
---|
2107 | case 0x40 ... 0x4f: /* cmovcc */ |
---|
2108 | dst.val = src.val; |
---|
2109 | if ( !test_cc(b, _regs.eflags) ) |
---|
2110 | dst.type = OP_NONE; |
---|
2111 | break; |
---|
2112 | |
---|
2113 | case 0x90 ... 0x9f: /* setcc */ |
---|
2114 | dst.val = test_cc(b, _regs.eflags); |
---|
2115 | break; |
---|
2116 | |
---|
2117 | case 0xb0 ... 0xb1: /* cmpxchg */ |
---|
2118 | /* Save real source value, then compare EAX against destination. */ |
---|
2119 | src.orig_val = src.val; |
---|
2120 | src.val = _regs.eax; |
---|
2121 | emulate_2op_SrcV("cmp", src, dst, _regs.eflags); |
---|
2122 | /* Always write back. The question is: where to? */ |
---|
2123 | d |= Mov; |
---|
2124 | if ( _regs.eflags & EFLG_ZF ) |
---|
2125 | { |
---|
2126 | /* Success: write back to memory. */ |
---|
2127 | dst.val = src.orig_val; |
---|
2128 | } |
---|
2129 | else |
---|
2130 | { |
---|
2131 | /* Failure: write the value we saw to EAX. */ |
---|
2132 | dst.type = OP_REG; |
---|
2133 | dst.reg = (unsigned long *)&_regs.eax; |
---|
2134 | } |
---|
2135 | break; |
---|
2136 | |
---|
2137 | case 0xa3: bt: /* bt */ |
---|
2138 | emulate_2op_SrcV_nobyte("bt", src, dst, _regs.eflags); |
---|
2139 | break; |
---|
2140 | |
---|
2141 | case 0xb3: btr: /* btr */ |
---|
2142 | emulate_2op_SrcV_nobyte("btr", src, dst, _regs.eflags); |
---|
2143 | break; |
---|
2144 | |
---|
2145 | case 0xab: bts: /* bts */ |
---|
2146 | emulate_2op_SrcV_nobyte("bts", src, dst, _regs.eflags); |
---|
2147 | break; |
---|
2148 | |
---|
2149 | case 0xaf: /* imul */ |
---|
2150 | _regs.eflags &= ~(EFLG_OF|EFLG_CF); |
---|
2151 | switch ( dst.bytes ) |
---|
2152 | { |
---|
2153 | case 2: |
---|
2154 | dst.val = ((uint32_t)(int16_t)src.val * |
---|
2155 | (uint32_t)(int16_t)dst.val); |
---|
2156 | if ( (int16_t)dst.val != (uint32_t)dst.val ) |
---|
2157 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
2158 | break; |
---|
2159 | #ifdef __x86_64__ |
---|
2160 | case 4: |
---|
2161 | dst.val = ((uint64_t)(int32_t)src.val * |
---|
2162 | (uint64_t)(int32_t)dst.val); |
---|
2163 | if ( (int32_t)dst.val != dst.val ) |
---|
2164 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
2165 | break; |
---|
2166 | #endif |
---|
2167 | default: { |
---|
2168 | unsigned long m[2] = { src.val, dst.val }; |
---|
2169 | if ( imul_dbl(m) ) |
---|
2170 | _regs.eflags |= EFLG_OF|EFLG_CF; |
---|
2171 | dst.val = m[0]; |
---|
2172 | break; |
---|
2173 | } |
---|
2174 | } |
---|
2175 | break; |
---|
2176 | |
---|
2177 | case 0xb6: /* movzx rm8,r{16,32,64} */ |
---|
2178 | /* Recompute DstReg as we may have decoded AH/BH/CH/DH. */ |
---|
2179 | dst.reg = decode_register(modrm_reg, &_regs, 0); |
---|
2180 | dst.bytes = op_bytes; |
---|
2181 | dst.val = (uint8_t)src.val; |
---|
2182 | break; |
---|
2183 | |
---|
2184 | case 0xbc: /* bsf */ { |
---|
2185 | int zf; |
---|
2186 | asm ( "bsf %2,%0; setz %b1" |
---|
2187 | : "=r" (dst.val), "=q" (zf) |
---|
2188 | : "r" (src.val), "1" (0) ); |
---|
2189 | _regs.eflags &= ~EFLG_ZF; |
---|
2190 | _regs.eflags |= zf ? EFLG_ZF : 0; |
---|
2191 | break; |
---|
2192 | } |
---|
2193 | |
---|
2194 | case 0xbd: /* bsr */ { |
---|
2195 | int zf; |
---|
2196 | asm ( "bsr %2,%0; setz %b1" |
---|
2197 | : "=r" (dst.val), "=q" (zf) |
---|
2198 | : "r" (src.val), "1" (0) ); |
---|
2199 | _regs.eflags &= ~EFLG_ZF; |
---|
2200 | _regs.eflags |= zf ? EFLG_ZF : 0; |
---|
2201 | break; |
---|
2202 | } |
---|
2203 | |
---|
2204 | case 0xb7: /* movzx rm16,r{16,32,64} */ |
---|
2205 | dst.val = (uint16_t)src.val; |
---|
2206 | break; |
---|
2207 | |
---|
2208 | case 0xbb: btc: /* btc */ |
---|
2209 | emulate_2op_SrcV_nobyte("btc", src, dst, _regs.eflags); |
---|
2210 | break; |
---|
2211 | |
---|
2212 | case 0xba: /* Grp8 */ |
---|
2213 | switch ( modrm_reg & 7 ) |
---|
2214 | { |
---|
2215 | case 4: goto bt; |
---|
2216 | case 5: goto bts; |
---|
2217 | case 6: goto btr; |
---|
2218 | case 7: goto btc; |
---|
2219 | default: generate_exception_if(1, EXC_UD); |
---|
2220 | } |
---|
2221 | break; |
---|
2222 | |
---|
2223 | case 0xbe: /* movsx rm8,r{16,32,64} */ |
---|
2224 | /* Recompute DstReg as we may have decoded AH/BH/CH/DH. */ |
---|
2225 | dst.reg = decode_register(modrm_reg, &_regs, 0); |
---|
2226 | dst.bytes = op_bytes; |
---|
2227 | dst.val = (int8_t)src.val; |
---|
2228 | break; |
---|
2229 | |
---|
2230 | case 0xbf: /* movsx rm16,r{16,32,64} */ |
---|
2231 | dst.val = (int16_t)src.val; |
---|
2232 | break; |
---|
2233 | |
---|
2234 | case 0xc0 ... 0xc1: /* xadd */ |
---|
2235 | /* Write back the register source. */ |
---|
2236 | switch ( dst.bytes ) |
---|
2237 | { |
---|
2238 | case 1: *(uint8_t *)src.reg = (uint8_t)dst.val; break; |
---|
2239 | case 2: *(uint16_t *)src.reg = (uint16_t)dst.val; break; |
---|
2240 | case 4: *src.reg = (uint32_t)dst.val; break; /* 64b reg: zero-extend */ |
---|
2241 | case 8: *src.reg = dst.val; break; |
---|
2242 | } |
---|
2243 | goto add; |
---|
2244 | } |
---|
2245 | goto writeback; |
---|
2246 | |
---|
2247 | twobyte_special_insn: |
---|
2248 | switch ( b ) |
---|
2249 | { |
---|
2250 | case 0x06: /* clts */ |
---|
2251 | generate_exception_if(!mode_ring0(), EXC_GP); |
---|
2252 | fail_if((ops->read_cr == NULL) || (ops->write_cr == NULL)); |
---|
2253 | if ( (rc = ops->read_cr(0, &dst.val, ctxt)) || |
---|
2254 | (rc = ops->write_cr(0, dst.val&~8, ctxt)) ) |
---|
2255 | goto done; |
---|
2256 | break; |
---|
2257 | |
---|
2258 | case 0x08: /* invd */ |
---|
2259 | case 0x09: /* wbinvd */ |
---|
2260 | generate_exception_if(!mode_ring0(), EXC_GP); |
---|
2261 | fail_if(ops->wbinvd == NULL); |
---|
2262 | if ( (rc = ops->wbinvd(ctxt)) != 0 ) |
---|
2263 | goto done; |
---|
2264 | break; |
---|
2265 | |
---|
2266 | case 0x0d: /* GrpP (prefetch) */ |
---|
2267 | case 0x18: /* Grp16 (prefetch/nop) */ |
---|
2268 | case 0x19 ... 0x1f: /* nop (amd-defined) */ |
---|
2269 | break; |
---|
2270 | |
---|
2271 | case 0x20: /* mov cr,reg */ |
---|
2272 | case 0x21: /* mov dr,reg */ |
---|
2273 | case 0x22: /* mov reg,cr */ |
---|
2274 | case 0x23: /* mov reg,dr */ |
---|
2275 | generate_exception_if(!mode_ring0(), EXC_GP); |
---|
2276 | modrm_rm |= (rex_prefix & 1) << 3; |
---|
2277 | modrm_reg |= lock_prefix << 3; |
---|
2278 | if ( b & 2 ) |
---|
2279 | { |
---|
2280 | /* Write to CR/DR. */ |
---|
2281 | src.val = *(unsigned long *)decode_register(modrm_rm, &_regs, 0); |
---|
2282 | if ( !mode_64bit() ) |
---|
2283 | src.val = (uint32_t)src.val; |
---|
2284 | rc = ((b & 1) |
---|
2285 | ? (ops->write_dr |
---|
2286 | ? ops->write_dr(modrm_reg, src.val, ctxt) |
---|
2287 | : X86EMUL_UNHANDLEABLE) |
---|
2288 | : (ops->write_cr |
---|
2289 | ? ops->write_dr(modrm_reg, src.val, ctxt) |
---|
2290 | : X86EMUL_UNHANDLEABLE)); |
---|
2291 | } |
---|
2292 | else |
---|
2293 | { |
---|
2294 | /* Read from CR/DR. */ |
---|
2295 | dst.type = OP_REG; |
---|
2296 | dst.bytes = mode_64bit() ? 8 : 4; |
---|
2297 | dst.reg = decode_register(modrm_rm, &_regs, 0); |
---|
2298 | rc = ((b & 1) |
---|
2299 | ? (ops->read_dr |
---|
2300 | ? ops->read_dr(modrm_reg, &dst.val, ctxt) |
---|
2301 | : X86EMUL_UNHANDLEABLE) |
---|
2302 | : (ops->read_cr |
---|
2303 | ? ops->read_dr(modrm_reg, &dst.val, ctxt) |
---|
2304 | : X86EMUL_UNHANDLEABLE)); |
---|
2305 | } |
---|
2306 | if ( rc != 0 ) |
---|
2307 | goto done; |
---|
2308 | break; |
---|
2309 | |
---|
2310 | case 0x30: /* wrmsr */ { |
---|
2311 | uint64_t val = ((uint64_t)_regs.edx << 32) | (uint32_t)_regs.eax; |
---|
2312 | generate_exception_if(!mode_ring0(), EXC_GP); |
---|
2313 | fail_if(ops->write_msr == NULL); |
---|
2314 | if ( (rc = ops->write_msr((uint32_t)_regs.ecx, val, ctxt)) != 0 ) |
---|
2315 | goto done; |
---|
2316 | break; |
---|
2317 | } |
---|
2318 | |
---|
2319 | case 0x32: /* rdmsr */ { |
---|
2320 | uint64_t val; |
---|
2321 | generate_exception_if(!mode_ring0(), EXC_GP); |
---|
2322 | fail_if(ops->read_msr == NULL); |
---|
2323 | if ( (rc = ops->read_msr((uint32_t)_regs.ecx, &val, ctxt)) != 0 ) |
---|
2324 | goto done; |
---|
2325 | _regs.edx = (uint32_t)(val >> 32); |
---|
2326 | _regs.eax = (uint32_t)(val >> 0); |
---|
2327 | break; |
---|
2328 | } |
---|
2329 | |
---|
2330 | case 0x80 ... 0x8f: /* jcc (near) */ { |
---|
2331 | int rel = (((op_bytes == 2) && !mode_64bit()) |
---|
2332 | ? (int32_t)insn_fetch_type(int16_t) |
---|
2333 | : insn_fetch_type(int32_t)); |
---|
2334 | if ( test_cc(b, _regs.eflags) ) |
---|
2335 | jmp_rel(rel); |
---|
2336 | break; |
---|
2337 | } |
---|
2338 | |
---|
2339 | case 0xc7: /* Grp9 (cmpxchg8b) */ |
---|
2340 | #if defined(__i386__) |
---|
2341 | { |
---|
2342 | unsigned long old_lo, old_hi; |
---|
2343 | generate_exception_if((modrm_reg & 7) != 1, EXC_UD); |
---|
2344 | if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0, &old_lo, 4, ctxt)) || |
---|
2345 | (rc = ops->read(ea.mem.seg, ea.mem.off+4, &old_hi, 4, ctxt)) ) |
---|
2346 | goto done; |
---|
2347 | if ( (old_lo != _regs.eax) || (old_hi != _regs.edx) ) |
---|
2348 | { |
---|
2349 | _regs.eax = old_lo; |
---|
2350 | _regs.edx = old_hi; |
---|
2351 | _regs.eflags &= ~EFLG_ZF; |
---|
2352 | } |
---|
2353 | else if ( ops->cmpxchg8b == NULL ) |
---|
2354 | { |
---|
2355 | rc = X86EMUL_UNHANDLEABLE; |
---|
2356 | goto done; |
---|
2357 | } |
---|
2358 | else |
---|
2359 | { |
---|
2360 | if ( (rc = ops->cmpxchg8b(ea.mem.seg, ea.mem.off, old_lo, old_hi, |
---|
2361 | _regs.ebx, _regs.ecx, ctxt)) != 0 ) |
---|
2362 | goto done; |
---|
2363 | _regs.eflags |= EFLG_ZF; |
---|
2364 | } |
---|
2365 | break; |
---|
2366 | } |
---|
2367 | #elif defined(__x86_64__) |
---|
2368 | { |
---|
2369 | unsigned long old, new; |
---|
2370 | generate_exception_if((modrm_reg & 7) != 1, EXC_UD); |
---|
2371 | if ( (rc = ops->read(ea.mem.seg, ea.mem.off, &old, 8, ctxt)) != 0 ) |
---|
2372 | goto done; |
---|
2373 | if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) || |
---|
2374 | ((uint32_t)(old>>32) != (uint32_t)_regs.edx) ) |
---|
2375 | { |
---|
2376 | _regs.eax = (uint32_t)(old>>0); |
---|
2377 | _regs.edx = (uint32_t)(old>>32); |
---|
2378 | _regs.eflags &= ~EFLG_ZF; |
---|
2379 | } |
---|
2380 | else |
---|
2381 | { |
---|
2382 | new = (_regs.ecx<<32)|(uint32_t)_regs.ebx; |
---|
2383 | if ( (rc = ops->cmpxchg(ea.mem.seg, ea.mem.off, old, |
---|
2384 | new, 8, ctxt)) != 0 ) |
---|
2385 | goto done; |
---|
2386 | _regs.eflags |= EFLG_ZF; |
---|
2387 | } |
---|
2388 | break; |
---|
2389 | } |
---|
2390 | #endif |
---|
2391 | |
---|
2392 | case 0xc8 ... 0xcf: /* bswap */ |
---|
2393 | dst.type = OP_REG; |
---|
2394 | dst.reg = decode_register( |
---|
2395 | (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); |
---|
2396 | switch ( dst.bytes = op_bytes ) |
---|
2397 | { |
---|
2398 | default: /* case 2: */ |
---|
2399 | /* Undefined behaviour. Writes zero on all tested CPUs. */ |
---|
2400 | dst.val = 0; |
---|
2401 | break; |
---|
2402 | case 4: |
---|
2403 | #ifdef __x86_64__ |
---|
2404 | __asm__ ( "bswap %k0" : "=r" (dst.val) : "0" (*dst.reg) ); |
---|
2405 | break; |
---|
2406 | case 8: |
---|
2407 | #endif |
---|
2408 | __asm__ ( "bswap %0" : "=r" (dst.val) : "0" (*dst.reg) ); |
---|
2409 | break; |
---|
2410 | } |
---|
2411 | break; |
---|
2412 | } |
---|
2413 | goto writeback; |
---|
2414 | |
---|
2415 | cannot_emulate: |
---|
2416 | #if 0 |
---|
2417 | gdprintk(XENLOG_DEBUG, "Instr:"); |
---|
2418 | for ( ea.mem.off = ctxt->regs->eip; ea.mem.off < _regs.eip; ea.mem.off++ ) |
---|
2419 | { |
---|
2420 | unsigned long x; |
---|
2421 | ops->insn_fetch(x86_seg_cs, ea.mem.off, &x, 1, ctxt); |
---|
2422 | printk(" %02x", (uint8_t)x); |
---|
2423 | } |
---|
2424 | printk("\n"); |
---|
2425 | #endif |
---|
2426 | return X86EMUL_UNHANDLEABLE; |
---|
2427 | } |
---|