]> git.proxmox.com Git - mirror_qemu.git/blob - target/i386/tcg/translate.c
qga: Solaris has net/if_arp.h and netinet/if_ether.h but not ETHER_ADDR_LEN
[mirror_qemu.git] / target / i386 / tcg / translate.c
1 /*
2 * i386 translation
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "qemu/osdep.h"
20
21 #include "qemu/host-utils.h"
22 #include "cpu.h"
23 #include "disas/disas.h"
24 #include "exec/exec-all.h"
25 #include "tcg/tcg-op.h"
26 #include "tcg/tcg-op-gvec.h"
27 #include "exec/cpu_ldst.h"
28 #include "exec/translator.h"
29 #include "fpu/softfloat.h"
30
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
33 #include "helper-tcg.h"
34
35 #include "exec/log.h"
36
37 #define HELPER_H "helper.h"
38 #include "exec/helper-info.c.inc"
39 #undef HELPER_H
40
41
42 #define PREFIX_REPZ 0x01
43 #define PREFIX_REPNZ 0x02
44 #define PREFIX_LOCK 0x04
45 #define PREFIX_DATA 0x08
46 #define PREFIX_ADR 0x10
47 #define PREFIX_VEX 0x20
48 #define PREFIX_REX 0x40
49
50 #ifdef TARGET_X86_64
51 # define ctztl ctz64
52 # define clztl clz64
53 #else
54 # define ctztl ctz32
55 # define clztl clz32
56 #endif
57
58 /* For a switch indexed by MODRM, match all memory operands for a given OP. */
59 #define CASE_MODRM_MEM_OP(OP) \
60 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
61 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
62 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
63
64 #define CASE_MODRM_OP(OP) \
65 case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
66 case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
67 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
68 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
69
70 //#define MACRO_TEST 1
71
72 /* global register indexes */
73 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2;
74 static TCGv cpu_eip;
75 static TCGv_i32 cpu_cc_op;
76 static TCGv cpu_regs[CPU_NB_REGS];
77 static TCGv cpu_seg_base[6];
78 static TCGv_i64 cpu_bndl[4];
79 static TCGv_i64 cpu_bndu[4];
80
81 typedef struct DisasContext {
82 DisasContextBase base;
83
84 target_ulong pc; /* pc = eip + cs_base */
85 target_ulong cs_base; /* base of CS segment */
86 target_ulong pc_save;
87
88 MemOp aflag;
89 MemOp dflag;
90
91 int8_t override; /* -1 if no override, else R_CS, R_DS, etc */
92 uint8_t prefix;
93
94 bool has_modrm;
95 uint8_t modrm;
96
97 #ifndef CONFIG_USER_ONLY
98 uint8_t cpl; /* code priv level */
99 uint8_t iopl; /* i/o priv level */
100 #endif
101 uint8_t vex_l; /* vex vector length */
102 uint8_t vex_v; /* vex vvvv register, without 1's complement. */
103 uint8_t popl_esp_hack; /* for correct popl with esp base handling */
104 uint8_t rip_offset; /* only used in x86_64, but left for simplicity */
105
106 #ifdef TARGET_X86_64
107 uint8_t rex_r;
108 uint8_t rex_x;
109 uint8_t rex_b;
110 #endif
111 bool vex_w; /* used by AVX even on 32-bit processors */
112 bool jmp_opt; /* use direct block chaining for direct jumps */
113 bool repz_opt; /* optimize jumps within repz instructions */
114 bool cc_op_dirty;
115
116 CCOp cc_op; /* current CC operation */
117 int mem_index; /* select memory access functions */
118 uint32_t flags; /* all execution flags */
119 int cpuid_features;
120 int cpuid_ext_features;
121 int cpuid_ext2_features;
122 int cpuid_ext3_features;
123 int cpuid_7_0_ebx_features;
124 int cpuid_7_0_ecx_features;
125 int cpuid_7_1_eax_features;
126 int cpuid_xsave_features;
127
128 /* TCG local temps */
129 TCGv cc_srcT;
130 TCGv A0;
131 TCGv T0;
132 TCGv T1;
133
134 /* TCG local register indexes (only used inside old micro ops) */
135 TCGv tmp0;
136 TCGv tmp4;
137 TCGv_i32 tmp2_i32;
138 TCGv_i32 tmp3_i32;
139 TCGv_i64 tmp1_i64;
140
141 sigjmp_buf jmpbuf;
142 TCGOp *prev_insn_end;
143 } DisasContext;
144
145 #define DISAS_EOB_ONLY DISAS_TARGET_0
146 #define DISAS_EOB_NEXT DISAS_TARGET_1
147 #define DISAS_EOB_INHIBIT_IRQ DISAS_TARGET_2
148 #define DISAS_JUMP DISAS_TARGET_3
149
150 /* The environment in which user-only runs is constrained. */
151 #ifdef CONFIG_USER_ONLY
152 #define PE(S) true
153 #define CPL(S) 3
154 #define IOPL(S) 0
155 #define SVME(S) false
156 #define GUEST(S) false
157 #else
158 #define PE(S) (((S)->flags & HF_PE_MASK) != 0)
159 #define CPL(S) ((S)->cpl)
160 #define IOPL(S) ((S)->iopl)
161 #define SVME(S) (((S)->flags & HF_SVME_MASK) != 0)
162 #define GUEST(S) (((S)->flags & HF_GUEST_MASK) != 0)
163 #endif
164 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
165 #define VM86(S) false
166 #define CODE32(S) true
167 #define SS32(S) true
168 #define ADDSEG(S) false
169 #else
170 #define VM86(S) (((S)->flags & HF_VM_MASK) != 0)
171 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0)
172 #define SS32(S) (((S)->flags & HF_SS32_MASK) != 0)
173 #define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0)
174 #endif
175 #if !defined(TARGET_X86_64)
176 #define CODE64(S) false
177 #elif defined(CONFIG_USER_ONLY)
178 #define CODE64(S) true
179 #else
180 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0)
181 #endif
182 #if defined(CONFIG_USER_ONLY) || defined(TARGET_X86_64)
183 #define LMA(S) (((S)->flags & HF_LMA_MASK) != 0)
184 #else
185 #define LMA(S) false
186 #endif
187
188 #ifdef TARGET_X86_64
189 #define REX_PREFIX(S) (((S)->prefix & PREFIX_REX) != 0)
190 #define REX_W(S) ((S)->vex_w)
191 #define REX_R(S) ((S)->rex_r + 0)
192 #define REX_X(S) ((S)->rex_x + 0)
193 #define REX_B(S) ((S)->rex_b + 0)
194 #else
195 #define REX_PREFIX(S) false
196 #define REX_W(S) false
197 #define REX_R(S) 0
198 #define REX_X(S) 0
199 #define REX_B(S) 0
200 #endif
201
202 /*
203 * Many sysemu-only helpers are not reachable for user-only.
204 * Define stub generators here, so that we need not either sprinkle
205 * ifdefs through the translator, nor provide the helper function.
206 */
207 #define STUB_HELPER(NAME, ...) \
208 static inline void gen_helper_##NAME(__VA_ARGS__) \
209 { qemu_build_not_reached(); }
210
211 #ifdef CONFIG_USER_ONLY
212 STUB_HELPER(clgi, TCGv_env env)
213 STUB_HELPER(flush_page, TCGv_env env, TCGv addr)
214 STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs)
215 STUB_HELPER(inb, TCGv ret, TCGv_env env, TCGv_i32 port)
216 STUB_HELPER(inw, TCGv ret, TCGv_env env, TCGv_i32 port)
217 STUB_HELPER(inl, TCGv ret, TCGv_env env, TCGv_i32 port)
218 STUB_HELPER(monitor, TCGv_env env, TCGv addr)
219 STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs)
220 STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
221 STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
222 STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
223 STUB_HELPER(rdmsr, TCGv_env env)
224 STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg)
225 STUB_HELPER(get_dr, TCGv ret, TCGv_env env, TCGv_i32 reg)
226 STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
227 STUB_HELPER(stgi, TCGv_env env)
228 STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type)
229 STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag)
230 STUB_HELPER(vmmcall, TCGv_env env)
231 STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs)
232 STUB_HELPER(vmsave, TCGv_env env, TCGv_i32 aflag)
233 STUB_HELPER(write_crN, TCGv_env env, TCGv_i32 reg, TCGv val)
234 STUB_HELPER(wrmsr, TCGv_env env)
235 #endif
236
237 static void gen_eob(DisasContext *s);
238 static void gen_jr(DisasContext *s);
239 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num);
240 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num);
241 static void gen_op(DisasContext *s1, int op, MemOp ot, int d);
242 static void gen_exception_gpf(DisasContext *s);
243
244 /* i386 arith/logic operations */
245 enum {
246 OP_ADDL,
247 OP_ORL,
248 OP_ADCL,
249 OP_SBBL,
250 OP_ANDL,
251 OP_SUBL,
252 OP_XORL,
253 OP_CMPL,
254 };
255
256 /* i386 shift ops */
257 enum {
258 OP_ROL,
259 OP_ROR,
260 OP_RCL,
261 OP_RCR,
262 OP_SHL,
263 OP_SHR,
264 OP_SHL1, /* undocumented */
265 OP_SAR = 7,
266 };
267
268 enum {
269 JCC_O,
270 JCC_B,
271 JCC_Z,
272 JCC_BE,
273 JCC_S,
274 JCC_P,
275 JCC_L,
276 JCC_LE,
277 };
278
279 enum {
280 /* I386 int registers */
281 OR_EAX, /* MUST be even numbered */
282 OR_ECX,
283 OR_EDX,
284 OR_EBX,
285 OR_ESP,
286 OR_EBP,
287 OR_ESI,
288 OR_EDI,
289
290 OR_TMP0 = 16, /* temporary operand register */
291 OR_TMP1,
292 OR_A0, /* temporary register used when doing address evaluation */
293 };
294
295 enum {
296 USES_CC_DST = 1,
297 USES_CC_SRC = 2,
298 USES_CC_SRC2 = 4,
299 USES_CC_SRCT = 8,
300 };
301
302 /* Bit set if the global variable is live after setting CC_OP to X. */
303 static const uint8_t cc_op_live[CC_OP_NB] = {
304 [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
305 [CC_OP_EFLAGS] = USES_CC_SRC,
306 [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
307 [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
308 [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
309 [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
310 [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
311 [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
312 [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
313 [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
314 [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
315 [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
316 [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
317 [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
318 [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
319 [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
320 [CC_OP_CLR] = 0,
321 [CC_OP_POPCNT] = USES_CC_SRC,
322 };
323
324 static void set_cc_op(DisasContext *s, CCOp op)
325 {
326 int dead;
327
328 if (s->cc_op == op) {
329 return;
330 }
331
332 /* Discard CC computation that will no longer be used. */
333 dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
334 if (dead & USES_CC_DST) {
335 tcg_gen_discard_tl(cpu_cc_dst);
336 }
337 if (dead & USES_CC_SRC) {
338 tcg_gen_discard_tl(cpu_cc_src);
339 }
340 if (dead & USES_CC_SRC2) {
341 tcg_gen_discard_tl(cpu_cc_src2);
342 }
343 if (dead & USES_CC_SRCT) {
344 tcg_gen_discard_tl(s->cc_srcT);
345 }
346
347 if (op == CC_OP_DYNAMIC) {
348 /* The DYNAMIC setting is translator only, and should never be
349 stored. Thus we always consider it clean. */
350 s->cc_op_dirty = false;
351 } else {
352 /* Discard any computed CC_OP value (see shifts). */
353 if (s->cc_op == CC_OP_DYNAMIC) {
354 tcg_gen_discard_i32(cpu_cc_op);
355 }
356 s->cc_op_dirty = true;
357 }
358 s->cc_op = op;
359 }
360
361 static void gen_update_cc_op(DisasContext *s)
362 {
363 if (s->cc_op_dirty) {
364 tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
365 s->cc_op_dirty = false;
366 }
367 }
368
369 #ifdef TARGET_X86_64
370
371 #define NB_OP_SIZES 4
372
373 #else /* !TARGET_X86_64 */
374
375 #define NB_OP_SIZES 3
376
377 #endif /* !TARGET_X86_64 */
378
379 #if HOST_BIG_ENDIAN
380 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
381 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
382 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
383 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
384 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
385 #else
386 #define REG_B_OFFSET 0
387 #define REG_H_OFFSET 1
388 #define REG_W_OFFSET 0
389 #define REG_L_OFFSET 0
390 #define REG_LH_OFFSET 4
391 #endif
392
393 /* In instruction encodings for byte register accesses the
394 * register number usually indicates "low 8 bits of register N";
395 * however there are some special cases where N 4..7 indicates
396 * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
397 * true for this special case, false otherwise.
398 */
399 static inline bool byte_reg_is_xH(DisasContext *s, int reg)
400 {
401 /* Any time the REX prefix is present, byte registers are uniform */
402 if (reg < 4 || REX_PREFIX(s)) {
403 return false;
404 }
405 return true;
406 }
407
408 /* Select the size of a push/pop operation. */
409 static inline MemOp mo_pushpop(DisasContext *s, MemOp ot)
410 {
411 if (CODE64(s)) {
412 return ot == MO_16 ? MO_16 : MO_64;
413 } else {
414 return ot;
415 }
416 }
417
418 /* Select the size of the stack pointer. */
419 static inline MemOp mo_stacksize(DisasContext *s)
420 {
421 return CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16;
422 }
423
424 /* Select only size 64 else 32. Used for SSE operand sizes. */
425 static inline MemOp mo_64_32(MemOp ot)
426 {
427 #ifdef TARGET_X86_64
428 return ot == MO_64 ? MO_64 : MO_32;
429 #else
430 return MO_32;
431 #endif
432 }
433
434 /* Select size 8 if lsb of B is clear, else OT. Used for decoding
435 byte vs word opcodes. */
436 static inline MemOp mo_b_d(int b, MemOp ot)
437 {
438 return b & 1 ? ot : MO_8;
439 }
440
441 /* Select size 8 if lsb of B is clear, else OT capped at 32.
442 Used for decoding operand size of port opcodes. */
443 static inline MemOp mo_b_d32(int b, MemOp ot)
444 {
445 return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8;
446 }
447
448 /* Compute the result of writing t0 to the OT-sized register REG.
449 *
450 * If DEST is NULL, store the result into the register and return the
451 * register's TCGv.
452 *
453 * If DEST is not NULL, store the result into DEST and return the
454 * register's TCGv.
455 */
456 static TCGv gen_op_deposit_reg_v(DisasContext *s, MemOp ot, int reg, TCGv dest, TCGv t0)
457 {
458 switch(ot) {
459 case MO_8:
460 if (byte_reg_is_xH(s, reg)) {
461 dest = dest ? dest : cpu_regs[reg - 4];
462 tcg_gen_deposit_tl(dest, cpu_regs[reg - 4], t0, 8, 8);
463 return cpu_regs[reg - 4];
464 }
465 dest = dest ? dest : cpu_regs[reg];
466 tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 8);
467 break;
468 case MO_16:
469 dest = dest ? dest : cpu_regs[reg];
470 tcg_gen_deposit_tl(dest, cpu_regs[reg], t0, 0, 16);
471 break;
472 case MO_32:
473 /* For x86_64, this sets the higher half of register to zero.
474 For i386, this is equivalent to a mov. */
475 dest = dest ? dest : cpu_regs[reg];
476 tcg_gen_ext32u_tl(dest, t0);
477 break;
478 #ifdef TARGET_X86_64
479 case MO_64:
480 dest = dest ? dest : cpu_regs[reg];
481 tcg_gen_mov_tl(dest, t0);
482 break;
483 #endif
484 default:
485 g_assert_not_reached();
486 }
487 return cpu_regs[reg];
488 }
489
490 static void gen_op_mov_reg_v(DisasContext *s, MemOp ot, int reg, TCGv t0)
491 {
492 gen_op_deposit_reg_v(s, ot, reg, NULL, t0);
493 }
494
495 static inline
496 void gen_op_mov_v_reg(DisasContext *s, MemOp ot, TCGv t0, int reg)
497 {
498 if (ot == MO_8 && byte_reg_is_xH(s, reg)) {
499 tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8);
500 } else {
501 tcg_gen_mov_tl(t0, cpu_regs[reg]);
502 }
503 }
504
505 static void gen_add_A0_im(DisasContext *s, int val)
506 {
507 tcg_gen_addi_tl(s->A0, s->A0, val);
508 if (!CODE64(s)) {
509 tcg_gen_ext32u_tl(s->A0, s->A0);
510 }
511 }
512
513 static inline void gen_op_jmp_v(DisasContext *s, TCGv dest)
514 {
515 tcg_gen_mov_tl(cpu_eip, dest);
516 s->pc_save = -1;
517 }
518
519 static inline
520 void gen_op_add_reg_im(DisasContext *s, MemOp size, int reg, int32_t val)
521 {
522 tcg_gen_addi_tl(s->tmp0, cpu_regs[reg], val);
523 gen_op_mov_reg_v(s, size, reg, s->tmp0);
524 }
525
526 static inline void gen_op_add_reg(DisasContext *s, MemOp size, int reg, TCGv val)
527 {
528 tcg_gen_add_tl(s->tmp0, cpu_regs[reg], val);
529 gen_op_mov_reg_v(s, size, reg, s->tmp0);
530 }
531
532 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
533 {
534 tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
535 }
536
537 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
538 {
539 tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
540 }
541
542 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
543 {
544 if (d == OR_TMP0) {
545 gen_op_st_v(s, idx, s->T0, s->A0);
546 } else {
547 gen_op_mov_reg_v(s, idx, d, s->T0);
548 }
549 }
550
551 static void gen_update_eip_cur(DisasContext *s)
552 {
553 assert(s->pc_save != -1);
554 if (tb_cflags(s->base.tb) & CF_PCREL) {
555 tcg_gen_addi_tl(cpu_eip, cpu_eip, s->base.pc_next - s->pc_save);
556 } else if (CODE64(s)) {
557 tcg_gen_movi_tl(cpu_eip, s->base.pc_next);
558 } else {
559 tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->base.pc_next - s->cs_base));
560 }
561 s->pc_save = s->base.pc_next;
562 }
563
564 static void gen_update_eip_next(DisasContext *s)
565 {
566 assert(s->pc_save != -1);
567 if (tb_cflags(s->base.tb) & CF_PCREL) {
568 tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save);
569 } else if (CODE64(s)) {
570 tcg_gen_movi_tl(cpu_eip, s->pc);
571 } else {
572 tcg_gen_movi_tl(cpu_eip, (uint32_t)(s->pc - s->cs_base));
573 }
574 s->pc_save = s->pc;
575 }
576
577 static int cur_insn_len(DisasContext *s)
578 {
579 return s->pc - s->base.pc_next;
580 }
581
582 static TCGv_i32 cur_insn_len_i32(DisasContext *s)
583 {
584 return tcg_constant_i32(cur_insn_len(s));
585 }
586
587 static TCGv_i32 eip_next_i32(DisasContext *s)
588 {
589 assert(s->pc_save != -1);
590 /*
591 * This function has two users: lcall_real (always 16-bit mode), and
592 * iret_protected (16, 32, or 64-bit mode). IRET only uses the value
593 * when EFLAGS.NT is set, which is illegal in 64-bit mode, which is
594 * why passing a 32-bit value isn't broken. To avoid using this where
595 * we shouldn't, return -1 in 64-bit mode so that execution goes into
596 * the weeds quickly.
597 */
598 if (CODE64(s)) {
599 return tcg_constant_i32(-1);
600 }
601 if (tb_cflags(s->base.tb) & CF_PCREL) {
602 TCGv_i32 ret = tcg_temp_new_i32();
603 tcg_gen_trunc_tl_i32(ret, cpu_eip);
604 tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save);
605 return ret;
606 } else {
607 return tcg_constant_i32(s->pc - s->cs_base);
608 }
609 }
610
611 static TCGv eip_next_tl(DisasContext *s)
612 {
613 assert(s->pc_save != -1);
614 if (tb_cflags(s->base.tb) & CF_PCREL) {
615 TCGv ret = tcg_temp_new();
616 tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save);
617 return ret;
618 } else if (CODE64(s)) {
619 return tcg_constant_tl(s->pc);
620 } else {
621 return tcg_constant_tl((uint32_t)(s->pc - s->cs_base));
622 }
623 }
624
625 static TCGv eip_cur_tl(DisasContext *s)
626 {
627 assert(s->pc_save != -1);
628 if (tb_cflags(s->base.tb) & CF_PCREL) {
629 TCGv ret = tcg_temp_new();
630 tcg_gen_addi_tl(ret, cpu_eip, s->base.pc_next - s->pc_save);
631 return ret;
632 } else if (CODE64(s)) {
633 return tcg_constant_tl(s->base.pc_next);
634 } else {
635 return tcg_constant_tl((uint32_t)(s->base.pc_next - s->cs_base));
636 }
637 }
638
639 /* Compute SEG:REG into DEST. SEG is selected from the override segment
640 (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
641 indicate no override. */
642 static void gen_lea_v_seg_dest(DisasContext *s, MemOp aflag, TCGv dest, TCGv a0,
643 int def_seg, int ovr_seg)
644 {
645 switch (aflag) {
646 #ifdef TARGET_X86_64
647 case MO_64:
648 if (ovr_seg < 0) {
649 tcg_gen_mov_tl(dest, a0);
650 return;
651 }
652 break;
653 #endif
654 case MO_32:
655 /* 32 bit address */
656 if (ovr_seg < 0 && ADDSEG(s)) {
657 ovr_seg = def_seg;
658 }
659 if (ovr_seg < 0) {
660 tcg_gen_ext32u_tl(dest, a0);
661 return;
662 }
663 break;
664 case MO_16:
665 /* 16 bit address */
666 tcg_gen_ext16u_tl(dest, a0);
667 a0 = dest;
668 if (ovr_seg < 0) {
669 if (ADDSEG(s)) {
670 ovr_seg = def_seg;
671 } else {
672 return;
673 }
674 }
675 break;
676 default:
677 g_assert_not_reached();
678 }
679
680 if (ovr_seg >= 0) {
681 TCGv seg = cpu_seg_base[ovr_seg];
682
683 if (aflag == MO_64) {
684 tcg_gen_add_tl(dest, a0, seg);
685 } else if (CODE64(s)) {
686 tcg_gen_ext32u_tl(dest, a0);
687 tcg_gen_add_tl(dest, dest, seg);
688 } else {
689 tcg_gen_add_tl(dest, a0, seg);
690 tcg_gen_ext32u_tl(dest, dest);
691 }
692 }
693 }
694
695 static void gen_lea_v_seg(DisasContext *s, MemOp aflag, TCGv a0,
696 int def_seg, int ovr_seg)
697 {
698 gen_lea_v_seg_dest(s, aflag, s->A0, a0, def_seg, ovr_seg);
699 }
700
701 static inline void gen_string_movl_A0_ESI(DisasContext *s)
702 {
703 gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override);
704 }
705
706 static inline void gen_string_movl_A0_EDI(DisasContext *s)
707 {
708 gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1);
709 }
710
711 static inline TCGv gen_compute_Dshift(DisasContext *s, MemOp ot)
712 {
713 TCGv dshift = tcg_temp_new();
714 tcg_gen_ld32s_tl(dshift, tcg_env, offsetof(CPUX86State, df));
715 tcg_gen_shli_tl(dshift, dshift, ot);
716 return dshift;
717 };
718
719 static TCGv gen_ext_tl(TCGv dst, TCGv src, MemOp size, bool sign)
720 {
721 if (size == MO_TL) {
722 return src;
723 }
724 if (!dst) {
725 dst = tcg_temp_new();
726 }
727 tcg_gen_ext_tl(dst, src, size | (sign ? MO_SIGN : 0));
728 return dst;
729 }
730
731 static void gen_extu(MemOp ot, TCGv reg)
732 {
733 gen_ext_tl(reg, reg, ot, false);
734 }
735
736 static void gen_exts(MemOp ot, TCGv reg)
737 {
738 gen_ext_tl(reg, reg, ot, true);
739 }
740
741 static void gen_op_j_ecx(DisasContext *s, TCGCond cond, TCGLabel *label1)
742 {
743 TCGv tmp = gen_ext_tl(NULL, cpu_regs[R_ECX], s->aflag, false);
744
745 tcg_gen_brcondi_tl(cond, tmp, 0, label1);
746 }
747
748 static inline void gen_op_jz_ecx(DisasContext *s, TCGLabel *label1)
749 {
750 gen_op_j_ecx(s, TCG_COND_EQ, label1);
751 }
752
753 static inline void gen_op_jnz_ecx(DisasContext *s, TCGLabel *label1)
754 {
755 gen_op_j_ecx(s, TCG_COND_NE, label1);
756 }
757
758 static void gen_helper_in_func(MemOp ot, TCGv v, TCGv_i32 n)
759 {
760 switch (ot) {
761 case MO_8:
762 gen_helper_inb(v, tcg_env, n);
763 break;
764 case MO_16:
765 gen_helper_inw(v, tcg_env, n);
766 break;
767 case MO_32:
768 gen_helper_inl(v, tcg_env, n);
769 break;
770 default:
771 g_assert_not_reached();
772 }
773 }
774
775 static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n)
776 {
777 switch (ot) {
778 case MO_8:
779 gen_helper_outb(tcg_env, v, n);
780 break;
781 case MO_16:
782 gen_helper_outw(tcg_env, v, n);
783 break;
784 case MO_32:
785 gen_helper_outl(tcg_env, v, n);
786 break;
787 default:
788 g_assert_not_reached();
789 }
790 }
791
792 /*
793 * Validate that access to [port, port + 1<<ot) is allowed.
794 * Raise #GP, or VMM exit if not.
795 */
796 static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
797 uint32_t svm_flags)
798 {
799 #ifdef CONFIG_USER_ONLY
800 /*
801 * We do not implement the ioperm(2) syscall, so the TSS check
802 * will always fail.
803 */
804 gen_exception_gpf(s);
805 return false;
806 #else
807 if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) {
808 gen_helper_check_io(tcg_env, port, tcg_constant_i32(1 << ot));
809 }
810 if (GUEST(s)) {
811 gen_update_cc_op(s);
812 gen_update_eip_cur(s);
813 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
814 svm_flags |= SVM_IOIO_REP_MASK;
815 }
816 svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot);
817 gen_helper_svm_check_io(tcg_env, port,
818 tcg_constant_i32(svm_flags),
819 cur_insn_len_i32(s));
820 }
821 return true;
822 #endif
823 }
824
825 static void gen_movs(DisasContext *s, MemOp ot)
826 {
827 TCGv dshift;
828
829 gen_string_movl_A0_ESI(s);
830 gen_op_ld_v(s, ot, s->T0, s->A0);
831 gen_string_movl_A0_EDI(s);
832 gen_op_st_v(s, ot, s->T0, s->A0);
833
834 dshift = gen_compute_Dshift(s, ot);
835 gen_op_add_reg(s, s->aflag, R_ESI, dshift);
836 gen_op_add_reg(s, s->aflag, R_EDI, dshift);
837 }
838
839 static void gen_op_update1_cc(DisasContext *s)
840 {
841 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
842 }
843
844 static void gen_op_update2_cc(DisasContext *s)
845 {
846 tcg_gen_mov_tl(cpu_cc_src, s->T1);
847 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
848 }
849
850 static void gen_op_update3_cc(DisasContext *s, TCGv reg)
851 {
852 tcg_gen_mov_tl(cpu_cc_src2, reg);
853 tcg_gen_mov_tl(cpu_cc_src, s->T1);
854 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
855 }
856
857 static inline void gen_op_testl_T0_T1_cc(DisasContext *s)
858 {
859 tcg_gen_and_tl(cpu_cc_dst, s->T0, s->T1);
860 }
861
862 static void gen_op_update_neg_cc(DisasContext *s)
863 {
864 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
865 tcg_gen_neg_tl(cpu_cc_src, s->T0);
866 tcg_gen_movi_tl(s->cc_srcT, 0);
867 }
868
869 /* compute all eflags to reg */
870 static void gen_mov_eflags(DisasContext *s, TCGv reg)
871 {
872 TCGv dst, src1, src2;
873 TCGv_i32 cc_op;
874 int live, dead;
875
876 if (s->cc_op == CC_OP_EFLAGS) {
877 tcg_gen_mov_tl(reg, cpu_cc_src);
878 return;
879 }
880 if (s->cc_op == CC_OP_CLR) {
881 tcg_gen_movi_tl(reg, CC_Z | CC_P);
882 return;
883 }
884
885 dst = cpu_cc_dst;
886 src1 = cpu_cc_src;
887 src2 = cpu_cc_src2;
888
889 /* Take care to not read values that are not live. */
890 live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
891 dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
892 if (dead) {
893 TCGv zero = tcg_constant_tl(0);
894 if (dead & USES_CC_DST) {
895 dst = zero;
896 }
897 if (dead & USES_CC_SRC) {
898 src1 = zero;
899 }
900 if (dead & USES_CC_SRC2) {
901 src2 = zero;
902 }
903 }
904
905 if (s->cc_op != CC_OP_DYNAMIC) {
906 cc_op = tcg_constant_i32(s->cc_op);
907 } else {
908 cc_op = cpu_cc_op;
909 }
910 gen_helper_cc_compute_all(reg, dst, src1, src2, cc_op);
911 }
912
913 /* compute all eflags to cc_src */
914 static void gen_compute_eflags(DisasContext *s)
915 {
916 gen_mov_eflags(s, cpu_cc_src);
917 set_cc_op(s, CC_OP_EFLAGS);
918 }
919
920 typedef struct CCPrepare {
921 TCGCond cond;
922 TCGv reg;
923 TCGv reg2;
924 target_ulong imm;
925 target_ulong mask;
926 bool use_reg2;
927 bool no_setcond;
928 } CCPrepare;
929
930 /* compute eflags.C to reg */
931 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
932 {
933 TCGv t0, t1;
934 int size, shift;
935
936 switch (s->cc_op) {
937 case CC_OP_SUBB ... CC_OP_SUBQ:
938 /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
939 size = s->cc_op - CC_OP_SUBB;
940 t1 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false);
941 /* If no temporary was used, be careful not to alias t1 and t0. */
942 t0 = t1 == cpu_cc_src ? s->tmp0 : reg;
943 tcg_gen_mov_tl(t0, s->cc_srcT);
944 gen_extu(size, t0);
945 goto add_sub;
946
947 case CC_OP_ADDB ... CC_OP_ADDQ:
948 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
949 size = s->cc_op - CC_OP_ADDB;
950 t1 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false);
951 t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
952 add_sub:
953 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
954 .reg2 = t1, .mask = -1, .use_reg2 = true };
955
956 case CC_OP_LOGICB ... CC_OP_LOGICQ:
957 case CC_OP_CLR:
958 case CC_OP_POPCNT:
959 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
960
961 case CC_OP_INCB ... CC_OP_INCQ:
962 case CC_OP_DECB ... CC_OP_DECQ:
963 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
964 .mask = -1, .no_setcond = true };
965
966 case CC_OP_SHLB ... CC_OP_SHLQ:
967 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
968 size = s->cc_op - CC_OP_SHLB;
969 shift = (8 << size) - 1;
970 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
971 .mask = (target_ulong)1 << shift };
972
973 case CC_OP_MULB ... CC_OP_MULQ:
974 return (CCPrepare) { .cond = TCG_COND_NE,
975 .reg = cpu_cc_src, .mask = -1 };
976
977 case CC_OP_BMILGB ... CC_OP_BMILGQ:
978 size = s->cc_op - CC_OP_BMILGB;
979 t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
980 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
981
982 case CC_OP_ADCX:
983 case CC_OP_ADCOX:
984 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
985 .mask = -1, .no_setcond = true };
986
987 case CC_OP_EFLAGS:
988 case CC_OP_SARB ... CC_OP_SARQ:
989 /* CC_SRC & 1 */
990 return (CCPrepare) { .cond = TCG_COND_NE,
991 .reg = cpu_cc_src, .mask = CC_C };
992
993 default:
994 /* The need to compute only C from CC_OP_DYNAMIC is important
995 in efficiently implementing e.g. INC at the start of a TB. */
996 gen_update_cc_op(s);
997 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
998 cpu_cc_src2, cpu_cc_op);
999 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1000 .mask = -1, .no_setcond = true };
1001 }
1002 }
1003
1004 /* compute eflags.P to reg */
1005 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
1006 {
1007 gen_compute_eflags(s);
1008 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1009 .mask = CC_P };
1010 }
1011
1012 /* compute eflags.S to reg */
1013 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
1014 {
1015 switch (s->cc_op) {
1016 case CC_OP_DYNAMIC:
1017 gen_compute_eflags(s);
1018 /* FALLTHRU */
1019 case CC_OP_EFLAGS:
1020 case CC_OP_ADCX:
1021 case CC_OP_ADOX:
1022 case CC_OP_ADCOX:
1023 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1024 .mask = CC_S };
1025 case CC_OP_CLR:
1026 case CC_OP_POPCNT:
1027 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
1028 default:
1029 {
1030 MemOp size = (s->cc_op - CC_OP_ADDB) & 3;
1031 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
1032 return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
1033 }
1034 }
1035 }
1036
1037 /* compute eflags.O to reg */
1038 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
1039 {
1040 switch (s->cc_op) {
1041 case CC_OP_ADOX:
1042 case CC_OP_ADCOX:
1043 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
1044 .mask = -1, .no_setcond = true };
1045 case CC_OP_CLR:
1046 case CC_OP_POPCNT:
1047 return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
1048 case CC_OP_MULB ... CC_OP_MULQ:
1049 return (CCPrepare) { .cond = TCG_COND_NE,
1050 .reg = cpu_cc_src, .mask = -1 };
1051 default:
1052 gen_compute_eflags(s);
1053 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1054 .mask = CC_O };
1055 }
1056 }
1057
1058 /* compute eflags.Z to reg */
1059 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
1060 {
1061 switch (s->cc_op) {
1062 case CC_OP_DYNAMIC:
1063 gen_compute_eflags(s);
1064 /* FALLTHRU */
1065 case CC_OP_EFLAGS:
1066 case CC_OP_ADCX:
1067 case CC_OP_ADOX:
1068 case CC_OP_ADCOX:
1069 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1070 .mask = CC_Z };
1071 case CC_OP_CLR:
1072 return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
1073 case CC_OP_POPCNT:
1074 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src,
1075 .mask = -1 };
1076 default:
1077 {
1078 MemOp size = (s->cc_op - CC_OP_ADDB) & 3;
1079 TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
1080 return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
1081 }
1082 }
1083 }
1084
1085 /* perform a conditional store into register 'reg' according to jump opcode
1086 value 'b'. In the fast case, T0 is guaranteed not to be used. */
1087 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
1088 {
1089 int inv, jcc_op, cond;
1090 MemOp size;
1091 CCPrepare cc;
1092 TCGv t0;
1093
1094 inv = b & 1;
1095 jcc_op = (b >> 1) & 7;
1096
1097 switch (s->cc_op) {
1098 case CC_OP_SUBB ... CC_OP_SUBQ:
1099 /* We optimize relational operators for the cmp/jcc case. */
1100 size = s->cc_op - CC_OP_SUBB;
1101 switch (jcc_op) {
1102 case JCC_BE:
1103 tcg_gen_mov_tl(s->tmp4, s->cc_srcT);
1104 gen_extu(size, s->tmp4);
1105 t0 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false);
1106 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = s->tmp4,
1107 .reg2 = t0, .mask = -1, .use_reg2 = true };
1108 break;
1109
1110 case JCC_L:
1111 cond = TCG_COND_LT;
1112 goto fast_jcc_l;
1113 case JCC_LE:
1114 cond = TCG_COND_LE;
1115 fast_jcc_l:
1116 tcg_gen_mov_tl(s->tmp4, s->cc_srcT);
1117 gen_exts(size, s->tmp4);
1118 t0 = gen_ext_tl(s->tmp0, cpu_cc_src, size, true);
1119 cc = (CCPrepare) { .cond = cond, .reg = s->tmp4,
1120 .reg2 = t0, .mask = -1, .use_reg2 = true };
1121 break;
1122
1123 default:
1124 goto slow_jcc;
1125 }
1126 break;
1127
1128 default:
1129 slow_jcc:
1130 /* This actually generates good code for JC, JZ and JS. */
1131 switch (jcc_op) {
1132 case JCC_O:
1133 cc = gen_prepare_eflags_o(s, reg);
1134 break;
1135 case JCC_B:
1136 cc = gen_prepare_eflags_c(s, reg);
1137 break;
1138 case JCC_Z:
1139 cc = gen_prepare_eflags_z(s, reg);
1140 break;
1141 case JCC_BE:
1142 gen_compute_eflags(s);
1143 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1144 .mask = CC_Z | CC_C };
1145 break;
1146 case JCC_S:
1147 cc = gen_prepare_eflags_s(s, reg);
1148 break;
1149 case JCC_P:
1150 cc = gen_prepare_eflags_p(s, reg);
1151 break;
1152 case JCC_L:
1153 gen_compute_eflags(s);
1154 if (reg == cpu_cc_src) {
1155 reg = s->tmp0;
1156 }
1157 tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S);
1158 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1159 .mask = CC_O };
1160 break;
1161 default:
1162 case JCC_LE:
1163 gen_compute_eflags(s);
1164 if (reg == cpu_cc_src) {
1165 reg = s->tmp0;
1166 }
1167 tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S);
1168 cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1169 .mask = CC_O | CC_Z };
1170 break;
1171 }
1172 break;
1173 }
1174
1175 if (inv) {
1176 cc.cond = tcg_invert_cond(cc.cond);
1177 }
1178 return cc;
1179 }
1180
1181 static void gen_setcc1(DisasContext *s, int b, TCGv reg)
1182 {
1183 CCPrepare cc = gen_prepare_cc(s, b, reg);
1184
1185 if (cc.no_setcond) {
1186 if (cc.cond == TCG_COND_EQ) {
1187 tcg_gen_xori_tl(reg, cc.reg, 1);
1188 } else {
1189 tcg_gen_mov_tl(reg, cc.reg);
1190 }
1191 return;
1192 }
1193
1194 if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
1195 cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
1196 tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
1197 tcg_gen_andi_tl(reg, reg, 1);
1198 return;
1199 }
1200 if (cc.mask != -1) {
1201 tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1202 cc.reg = reg;
1203 }
1204 if (cc.use_reg2) {
1205 tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1206 } else {
1207 tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1208 }
1209 }
1210
1211 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1212 {
1213 gen_setcc1(s, JCC_B << 1, reg);
1214 }
1215
1216 /* generate a conditional jump to label 'l1' according to jump opcode
1217 value 'b'. In the fast case, T0 is guaranteed not to be used. */
1218 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1)
1219 {
1220 CCPrepare cc = gen_prepare_cc(s, b, s->T0);
1221
1222 if (cc.mask != -1) {
1223 tcg_gen_andi_tl(s->T0, cc.reg, cc.mask);
1224 cc.reg = s->T0;
1225 }
1226 if (cc.use_reg2) {
1227 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1228 } else {
1229 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1230 }
1231 }
1232
1233 /* Generate a conditional jump to label 'l1' according to jump opcode
1234 value 'b'. In the fast case, T0 is guaranteed not to be used.
1235 A translation block must end soon. */
1236 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
1237 {
1238 CCPrepare cc = gen_prepare_cc(s, b, s->T0);
1239
1240 gen_update_cc_op(s);
1241 if (cc.mask != -1) {
1242 tcg_gen_andi_tl(s->T0, cc.reg, cc.mask);
1243 cc.reg = s->T0;
1244 }
1245 set_cc_op(s, CC_OP_DYNAMIC);
1246 if (cc.use_reg2) {
1247 tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1248 } else {
1249 tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1250 }
1251 }
1252
1253 /* XXX: does not work with gdbstub "ice" single step - not a
1254 serious problem */
1255 static TCGLabel *gen_jz_ecx_string(DisasContext *s)
1256 {
1257 TCGLabel *l1 = gen_new_label();
1258 TCGLabel *l2 = gen_new_label();
1259 gen_op_jnz_ecx(s, l1);
1260 gen_set_label(l2);
1261 gen_jmp_rel_csize(s, 0, 1);
1262 gen_set_label(l1);
1263 return l2;
1264 }
1265
1266 static void gen_stos(DisasContext *s, MemOp ot)
1267 {
1268 gen_string_movl_A0_EDI(s);
1269 gen_op_st_v(s, ot, s->T0, s->A0);
1270 gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot));
1271 }
1272
1273 static void gen_lods(DisasContext *s, MemOp ot)
1274 {
1275 gen_string_movl_A0_ESI(s);
1276 gen_op_ld_v(s, ot, s->T0, s->A0);
1277 gen_op_mov_reg_v(s, ot, R_EAX, s->T0);
1278 gen_op_add_reg(s, s->aflag, R_ESI, gen_compute_Dshift(s, ot));
1279 }
1280
1281 static void gen_scas(DisasContext *s, MemOp ot)
1282 {
1283 gen_string_movl_A0_EDI(s);
1284 gen_op_ld_v(s, ot, s->T1, s->A0);
1285 tcg_gen_mov_tl(cpu_cc_src, s->T1);
1286 tcg_gen_mov_tl(s->cc_srcT, s->T0);
1287 tcg_gen_sub_tl(cpu_cc_dst, s->T0, s->T1);
1288 set_cc_op(s, CC_OP_SUBB + ot);
1289
1290 gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot));
1291 }
1292
1293 static void gen_cmps(DisasContext *s, MemOp ot)
1294 {
1295 TCGv dshift;
1296
1297 gen_string_movl_A0_EDI(s);
1298 gen_op_ld_v(s, ot, s->T1, s->A0);
1299 gen_string_movl_A0_ESI(s);
1300 gen_op(s, OP_CMPL, ot, OR_TMP0);
1301
1302 dshift = gen_compute_Dshift(s, ot);
1303 gen_op_add_reg(s, s->aflag, R_ESI, dshift);
1304 gen_op_add_reg(s, s->aflag, R_EDI, dshift);
1305 }
1306
1307 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
1308 {
1309 if (s->flags & HF_IOBPT_MASK) {
1310 #ifdef CONFIG_USER_ONLY
1311 /* user-mode cpu should not be in IOBPT mode */
1312 g_assert_not_reached();
1313 #else
1314 TCGv_i32 t_size = tcg_constant_i32(1 << ot);
1315 TCGv t_next = eip_next_tl(s);
1316 gen_helper_bpt_io(tcg_env, t_port, t_size, t_next);
1317 #endif /* CONFIG_USER_ONLY */
1318 }
1319 }
1320
1321 static void gen_ins(DisasContext *s, MemOp ot)
1322 {
1323 gen_string_movl_A0_EDI(s);
1324 /* Note: we must do this dummy write first to be restartable in
1325 case of page fault. */
1326 tcg_gen_movi_tl(s->T0, 0);
1327 gen_op_st_v(s, ot, s->T0, s->A0);
1328 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
1329 tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff);
1330 gen_helper_in_func(ot, s->T0, s->tmp2_i32);
1331 gen_op_st_v(s, ot, s->T0, s->A0);
1332 gen_op_add_reg(s, s->aflag, R_EDI, gen_compute_Dshift(s, ot));
1333 gen_bpt_io(s, s->tmp2_i32, ot);
1334 }
1335
1336 static void gen_outs(DisasContext *s, MemOp ot)
1337 {
1338 gen_string_movl_A0_ESI(s);
1339 gen_op_ld_v(s, ot, s->T0, s->A0);
1340
1341 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
1342 tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff);
1343 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T0);
1344 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
1345 gen_op_add_reg(s, s->aflag, R_ESI, gen_compute_Dshift(s, ot));
1346 gen_bpt_io(s, s->tmp2_i32, ot);
1347 }
1348
1349 /* Generate jumps to current or next instruction */
1350 static void gen_repz(DisasContext *s, MemOp ot,
1351 void (*fn)(DisasContext *s, MemOp ot))
1352 {
1353 TCGLabel *l2;
1354 gen_update_cc_op(s);
1355 l2 = gen_jz_ecx_string(s);
1356 fn(s, ot);
1357 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
1358 /*
1359 * A loop would cause two single step exceptions if ECX = 1
1360 * before rep string_insn
1361 */
1362 if (s->repz_opt) {
1363 gen_op_jz_ecx(s, l2);
1364 }
1365 gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
1366 }
1367
1368 #define GEN_REPZ(op) \
1369 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot) \
1370 { gen_repz(s, ot, gen_##op); }
1371
1372 static void gen_repz2(DisasContext *s, MemOp ot, int nz,
1373 void (*fn)(DisasContext *s, MemOp ot))
1374 {
1375 TCGLabel *l2;
1376 gen_update_cc_op(s);
1377 l2 = gen_jz_ecx_string(s);
1378 fn(s, ot);
1379 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
1380 gen_update_cc_op(s);
1381 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2);
1382 if (s->repz_opt) {
1383 gen_op_jz_ecx(s, l2);
1384 }
1385 gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
1386 }
1387
1388 #define GEN_REPZ2(op) \
1389 static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, int nz) \
1390 { gen_repz2(s, ot, nz, gen_##op); }
1391
1392 GEN_REPZ(movs)
1393 GEN_REPZ(stos)
1394 GEN_REPZ(lods)
1395 GEN_REPZ(ins)
1396 GEN_REPZ(outs)
1397 GEN_REPZ2(scas)
1398 GEN_REPZ2(cmps)
1399
1400 static void gen_helper_fp_arith_ST0_FT0(int op)
1401 {
1402 switch (op) {
1403 case 0:
1404 gen_helper_fadd_ST0_FT0(tcg_env);
1405 break;
1406 case 1:
1407 gen_helper_fmul_ST0_FT0(tcg_env);
1408 break;
1409 case 2:
1410 gen_helper_fcom_ST0_FT0(tcg_env);
1411 break;
1412 case 3:
1413 gen_helper_fcom_ST0_FT0(tcg_env);
1414 break;
1415 case 4:
1416 gen_helper_fsub_ST0_FT0(tcg_env);
1417 break;
1418 case 5:
1419 gen_helper_fsubr_ST0_FT0(tcg_env);
1420 break;
1421 case 6:
1422 gen_helper_fdiv_ST0_FT0(tcg_env);
1423 break;
1424 case 7:
1425 gen_helper_fdivr_ST0_FT0(tcg_env);
1426 break;
1427 }
1428 }
1429
1430 /* NOTE the exception in "r" op ordering */
1431 static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1432 {
1433 TCGv_i32 tmp = tcg_constant_i32(opreg);
1434 switch (op) {
1435 case 0:
1436 gen_helper_fadd_STN_ST0(tcg_env, tmp);
1437 break;
1438 case 1:
1439 gen_helper_fmul_STN_ST0(tcg_env, tmp);
1440 break;
1441 case 4:
1442 gen_helper_fsubr_STN_ST0(tcg_env, tmp);
1443 break;
1444 case 5:
1445 gen_helper_fsub_STN_ST0(tcg_env, tmp);
1446 break;
1447 case 6:
1448 gen_helper_fdivr_STN_ST0(tcg_env, tmp);
1449 break;
1450 case 7:
1451 gen_helper_fdiv_STN_ST0(tcg_env, tmp);
1452 break;
1453 }
1454 }
1455
1456 static void gen_exception(DisasContext *s, int trapno)
1457 {
1458 gen_update_cc_op(s);
1459 gen_update_eip_cur(s);
1460 gen_helper_raise_exception(tcg_env, tcg_constant_i32(trapno));
1461 s->base.is_jmp = DISAS_NORETURN;
1462 }
1463
1464 /* Generate #UD for the current instruction. The assumption here is that
1465 the instruction is known, but it isn't allowed in the current cpu mode. */
1466 static void gen_illegal_opcode(DisasContext *s)
1467 {
1468 gen_exception(s, EXCP06_ILLOP);
1469 }
1470
1471 /* Generate #GP for the current instruction. */
1472 static void gen_exception_gpf(DisasContext *s)
1473 {
1474 gen_exception(s, EXCP0D_GPF);
1475 }
1476
1477 /* Check for cpl == 0; if not, raise #GP and return false. */
1478 static bool check_cpl0(DisasContext *s)
1479 {
1480 if (CPL(s) == 0) {
1481 return true;
1482 }
1483 gen_exception_gpf(s);
1484 return false;
1485 }
1486
1487 /* If vm86, check for iopl == 3; if not, raise #GP and return false. */
1488 static bool check_vm86_iopl(DisasContext *s)
1489 {
1490 if (!VM86(s) || IOPL(s) == 3) {
1491 return true;
1492 }
1493 gen_exception_gpf(s);
1494 return false;
1495 }
1496
1497 /* Check for iopl allowing access; if not, raise #GP and return false. */
1498 static bool check_iopl(DisasContext *s)
1499 {
1500 if (VM86(s) ? IOPL(s) == 3 : CPL(s) <= IOPL(s)) {
1501 return true;
1502 }
1503 gen_exception_gpf(s);
1504 return false;
1505 }
1506
1507 /* if d == OR_TMP0, it means memory operand (address in A0) */
1508 static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
1509 {
1510 if (d != OR_TMP0) {
1511 if (s1->prefix & PREFIX_LOCK) {
1512 /* Lock prefix when destination is not memory. */
1513 gen_illegal_opcode(s1);
1514 return;
1515 }
1516 gen_op_mov_v_reg(s1, ot, s1->T0, d);
1517 } else if (!(s1->prefix & PREFIX_LOCK)) {
1518 gen_op_ld_v(s1, ot, s1->T0, s1->A0);
1519 }
1520 switch(op) {
1521 case OP_ADCL:
1522 gen_compute_eflags_c(s1, s1->tmp4);
1523 if (s1->prefix & PREFIX_LOCK) {
1524 tcg_gen_add_tl(s1->T0, s1->tmp4, s1->T1);
1525 tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
1526 s1->mem_index, ot | MO_LE);
1527 } else {
1528 tcg_gen_add_tl(s1->T0, s1->T0, s1->T1);
1529 tcg_gen_add_tl(s1->T0, s1->T0, s1->tmp4);
1530 gen_op_st_rm_T0_A0(s1, ot, d);
1531 }
1532 gen_op_update3_cc(s1, s1->tmp4);
1533 set_cc_op(s1, CC_OP_ADCB + ot);
1534 break;
1535 case OP_SBBL:
1536 gen_compute_eflags_c(s1, s1->tmp4);
1537 if (s1->prefix & PREFIX_LOCK) {
1538 tcg_gen_add_tl(s1->T0, s1->T1, s1->tmp4);
1539 tcg_gen_neg_tl(s1->T0, s1->T0);
1540 tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
1541 s1->mem_index, ot | MO_LE);
1542 } else {
1543 tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1);
1544 tcg_gen_sub_tl(s1->T0, s1->T0, s1->tmp4);
1545 gen_op_st_rm_T0_A0(s1, ot, d);
1546 }
1547 gen_op_update3_cc(s1, s1->tmp4);
1548 set_cc_op(s1, CC_OP_SBBB + ot);
1549 break;
1550 case OP_ADDL:
1551 if (s1->prefix & PREFIX_LOCK) {
1552 tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T1,
1553 s1->mem_index, ot | MO_LE);
1554 } else {
1555 tcg_gen_add_tl(s1->T0, s1->T0, s1->T1);
1556 gen_op_st_rm_T0_A0(s1, ot, d);
1557 }
1558 gen_op_update2_cc(s1);
1559 set_cc_op(s1, CC_OP_ADDB + ot);
1560 break;
1561 case OP_SUBL:
1562 if (s1->prefix & PREFIX_LOCK) {
1563 tcg_gen_neg_tl(s1->T0, s1->T1);
1564 tcg_gen_atomic_fetch_add_tl(s1->cc_srcT, s1->A0, s1->T0,
1565 s1->mem_index, ot | MO_LE);
1566 tcg_gen_sub_tl(s1->T0, s1->cc_srcT, s1->T1);
1567 } else {
1568 tcg_gen_mov_tl(s1->cc_srcT, s1->T0);
1569 tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1);
1570 gen_op_st_rm_T0_A0(s1, ot, d);
1571 }
1572 gen_op_update2_cc(s1);
1573 set_cc_op(s1, CC_OP_SUBB + ot);
1574 break;
1575 default:
1576 case OP_ANDL:
1577 if (s1->prefix & PREFIX_LOCK) {
1578 tcg_gen_atomic_and_fetch_tl(s1->T0, s1->A0, s1->T1,
1579 s1->mem_index, ot | MO_LE);
1580 } else {
1581 tcg_gen_and_tl(s1->T0, s1->T0, s1->T1);
1582 gen_op_st_rm_T0_A0(s1, ot, d);
1583 }
1584 gen_op_update1_cc(s1);
1585 set_cc_op(s1, CC_OP_LOGICB + ot);
1586 break;
1587 case OP_ORL:
1588 if (s1->prefix & PREFIX_LOCK) {
1589 tcg_gen_atomic_or_fetch_tl(s1->T0, s1->A0, s1->T1,
1590 s1->mem_index, ot | MO_LE);
1591 } else {
1592 tcg_gen_or_tl(s1->T0, s1->T0, s1->T1);
1593 gen_op_st_rm_T0_A0(s1, ot, d);
1594 }
1595 gen_op_update1_cc(s1);
1596 set_cc_op(s1, CC_OP_LOGICB + ot);
1597 break;
1598 case OP_XORL:
1599 if (s1->prefix & PREFIX_LOCK) {
1600 tcg_gen_atomic_xor_fetch_tl(s1->T0, s1->A0, s1->T1,
1601 s1->mem_index, ot | MO_LE);
1602 } else {
1603 tcg_gen_xor_tl(s1->T0, s1->T0, s1->T1);
1604 gen_op_st_rm_T0_A0(s1, ot, d);
1605 }
1606 gen_op_update1_cc(s1);
1607 set_cc_op(s1, CC_OP_LOGICB + ot);
1608 break;
1609 case OP_CMPL:
1610 tcg_gen_mov_tl(cpu_cc_src, s1->T1);
1611 tcg_gen_mov_tl(s1->cc_srcT, s1->T0);
1612 tcg_gen_sub_tl(cpu_cc_dst, s1->T0, s1->T1);
1613 set_cc_op(s1, CC_OP_SUBB + ot);
1614 break;
1615 }
1616 }
1617
1618 /* if d == OR_TMP0, it means memory operand (address in A0) */
1619 static void gen_inc(DisasContext *s1, MemOp ot, int d, int c)
1620 {
1621 if (s1->prefix & PREFIX_LOCK) {
1622 if (d != OR_TMP0) {
1623 /* Lock prefix when destination is not memory */
1624 gen_illegal_opcode(s1);
1625 return;
1626 }
1627 tcg_gen_movi_tl(s1->T0, c > 0 ? 1 : -1);
1628 tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
1629 s1->mem_index, ot | MO_LE);
1630 } else {
1631 if (d != OR_TMP0) {
1632 gen_op_mov_v_reg(s1, ot, s1->T0, d);
1633 } else {
1634 gen_op_ld_v(s1, ot, s1->T0, s1->A0);
1635 }
1636 tcg_gen_addi_tl(s1->T0, s1->T0, (c > 0 ? 1 : -1));
1637 gen_op_st_rm_T0_A0(s1, ot, d);
1638 }
1639
1640 gen_compute_eflags_c(s1, cpu_cc_src);
1641 tcg_gen_mov_tl(cpu_cc_dst, s1->T0);
1642 set_cc_op(s1, (c > 0 ? CC_OP_INCB : CC_OP_DECB) + ot);
1643 }
1644
1645 static void gen_shift_flags(DisasContext *s, MemOp ot, TCGv result,
1646 TCGv shm1, TCGv count, bool is_right)
1647 {
1648 TCGv_i32 z32, s32, oldop;
1649 TCGv z_tl;
1650
1651 /* Store the results into the CC variables. If we know that the
1652 variable must be dead, store unconditionally. Otherwise we'll
1653 need to not disrupt the current contents. */
1654 z_tl = tcg_constant_tl(0);
1655 if (cc_op_live[s->cc_op] & USES_CC_DST) {
1656 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl,
1657 result, cpu_cc_dst);
1658 } else {
1659 tcg_gen_mov_tl(cpu_cc_dst, result);
1660 }
1661 if (cc_op_live[s->cc_op] & USES_CC_SRC) {
1662 tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl,
1663 shm1, cpu_cc_src);
1664 } else {
1665 tcg_gen_mov_tl(cpu_cc_src, shm1);
1666 }
1667
1668 /* Get the two potential CC_OP values into temporaries. */
1669 tcg_gen_movi_i32(s->tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1670 if (s->cc_op == CC_OP_DYNAMIC) {
1671 oldop = cpu_cc_op;
1672 } else {
1673 tcg_gen_movi_i32(s->tmp3_i32, s->cc_op);
1674 oldop = s->tmp3_i32;
1675 }
1676
1677 /* Conditionally store the CC_OP value. */
1678 z32 = tcg_constant_i32(0);
1679 s32 = tcg_temp_new_i32();
1680 tcg_gen_trunc_tl_i32(s32, count);
1681 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, s->tmp2_i32, oldop);
1682
1683 /* The CC_OP value is no longer predictable. */
1684 set_cc_op(s, CC_OP_DYNAMIC);
1685 }
1686
1687 static void gen_shift_rm_T1(DisasContext *s, MemOp ot, int op1,
1688 int is_right, int is_arith)
1689 {
1690 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1691
1692 /* load */
1693 if (op1 == OR_TMP0) {
1694 gen_op_ld_v(s, ot, s->T0, s->A0);
1695 } else {
1696 gen_op_mov_v_reg(s, ot, s->T0, op1);
1697 }
1698
1699 tcg_gen_andi_tl(s->T1, s->T1, mask);
1700 tcg_gen_subi_tl(s->tmp0, s->T1, 1);
1701
1702 if (is_right) {
1703 if (is_arith) {
1704 gen_exts(ot, s->T0);
1705 tcg_gen_sar_tl(s->tmp0, s->T0, s->tmp0);
1706 tcg_gen_sar_tl(s->T0, s->T0, s->T1);
1707 } else {
1708 gen_extu(ot, s->T0);
1709 tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0);
1710 tcg_gen_shr_tl(s->T0, s->T0, s->T1);
1711 }
1712 } else {
1713 tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0);
1714 tcg_gen_shl_tl(s->T0, s->T0, s->T1);
1715 }
1716
1717 /* store */
1718 gen_op_st_rm_T0_A0(s, ot, op1);
1719
1720 gen_shift_flags(s, ot, s->T0, s->tmp0, s->T1, is_right);
1721 }
1722
1723 static void gen_shift_rm_im(DisasContext *s, MemOp ot, int op1, int op2,
1724 int is_right, int is_arith)
1725 {
1726 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1727
1728 /* load */
1729 if (op1 == OR_TMP0)
1730 gen_op_ld_v(s, ot, s->T0, s->A0);
1731 else
1732 gen_op_mov_v_reg(s, ot, s->T0, op1);
1733
1734 op2 &= mask;
1735 if (op2 != 0) {
1736 if (is_right) {
1737 if (is_arith) {
1738 gen_exts(ot, s->T0);
1739 tcg_gen_sari_tl(s->tmp4, s->T0, op2 - 1);
1740 tcg_gen_sari_tl(s->T0, s->T0, op2);
1741 } else {
1742 gen_extu(ot, s->T0);
1743 tcg_gen_shri_tl(s->tmp4, s->T0, op2 - 1);
1744 tcg_gen_shri_tl(s->T0, s->T0, op2);
1745 }
1746 } else {
1747 tcg_gen_shli_tl(s->tmp4, s->T0, op2 - 1);
1748 tcg_gen_shli_tl(s->T0, s->T0, op2);
1749 }
1750 }
1751
1752 /* store */
1753 gen_op_st_rm_T0_A0(s, ot, op1);
1754
1755 /* update eflags if non zero shift */
1756 if (op2 != 0) {
1757 tcg_gen_mov_tl(cpu_cc_src, s->tmp4);
1758 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
1759 set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1760 }
1761 }
1762
1763 static void gen_rot_rm_T1(DisasContext *s, MemOp ot, int op1, int is_right)
1764 {
1765 target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1766 TCGv_i32 t0, t1;
1767
1768 /* load */
1769 if (op1 == OR_TMP0) {
1770 gen_op_ld_v(s, ot, s->T0, s->A0);
1771 } else {
1772 gen_op_mov_v_reg(s, ot, s->T0, op1);
1773 }
1774
1775 tcg_gen_andi_tl(s->T1, s->T1, mask);
1776
1777 switch (ot) {
1778 case MO_8:
1779 /* Replicate the 8-bit input so that a 32-bit rotate works. */
1780 tcg_gen_ext8u_tl(s->T0, s->T0);
1781 tcg_gen_muli_tl(s->T0, s->T0, 0x01010101);
1782 goto do_long;
1783 case MO_16:
1784 /* Replicate the 16-bit input so that a 32-bit rotate works. */
1785 tcg_gen_deposit_tl(s->T0, s->T0, s->T0, 16, 16);
1786 goto do_long;
1787 do_long:
1788 #ifdef TARGET_X86_64
1789 case MO_32:
1790 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
1791 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
1792 if (is_right) {
1793 tcg_gen_rotr_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
1794 } else {
1795 tcg_gen_rotl_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
1796 }
1797 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
1798 break;
1799 #endif
1800 default:
1801 if (is_right) {
1802 tcg_gen_rotr_tl(s->T0, s->T0, s->T1);
1803 } else {
1804 tcg_gen_rotl_tl(s->T0, s->T0, s->T1);
1805 }
1806 break;
1807 }
1808
1809 /* store */
1810 gen_op_st_rm_T0_A0(s, ot, op1);
1811
1812 /* We'll need the flags computed into CC_SRC. */
1813 gen_compute_eflags(s);
1814
1815 /* The value that was "rotated out" is now present at the other end
1816 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1817 since we've computed the flags into CC_SRC, these variables are
1818 currently dead. */
1819 if (is_right) {
1820 tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask - 1);
1821 tcg_gen_shri_tl(cpu_cc_dst, s->T0, mask);
1822 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1823 } else {
1824 tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask);
1825 tcg_gen_andi_tl(cpu_cc_dst, s->T0, 1);
1826 }
1827 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1828 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1829
1830 /* Now conditionally store the new CC_OP value. If the shift count
1831 is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1832 Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1833 exactly as we computed above. */
1834 t0 = tcg_constant_i32(0);
1835 t1 = tcg_temp_new_i32();
1836 tcg_gen_trunc_tl_i32(t1, s->T1);
1837 tcg_gen_movi_i32(s->tmp2_i32, CC_OP_ADCOX);
1838 tcg_gen_movi_i32(s->tmp3_i32, CC_OP_EFLAGS);
1839 tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0,
1840 s->tmp2_i32, s->tmp3_i32);
1841
1842 /* The CC_OP value is no longer predictable. */
1843 set_cc_op(s, CC_OP_DYNAMIC);
1844 }
1845
1846 static void gen_rot_rm_im(DisasContext *s, MemOp ot, int op1, int op2,
1847 int is_right)
1848 {
1849 int mask = (ot == MO_64 ? 0x3f : 0x1f);
1850 int shift;
1851
1852 /* load */
1853 if (op1 == OR_TMP0) {
1854 gen_op_ld_v(s, ot, s->T0, s->A0);
1855 } else {
1856 gen_op_mov_v_reg(s, ot, s->T0, op1);
1857 }
1858
1859 op2 &= mask;
1860 if (op2 != 0) {
1861 switch (ot) {
1862 #ifdef TARGET_X86_64
1863 case MO_32:
1864 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
1865 if (is_right) {
1866 tcg_gen_rotri_i32(s->tmp2_i32, s->tmp2_i32, op2);
1867 } else {
1868 tcg_gen_rotli_i32(s->tmp2_i32, s->tmp2_i32, op2);
1869 }
1870 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
1871 break;
1872 #endif
1873 default:
1874 if (is_right) {
1875 tcg_gen_rotri_tl(s->T0, s->T0, op2);
1876 } else {
1877 tcg_gen_rotli_tl(s->T0, s->T0, op2);
1878 }
1879 break;
1880 case MO_8:
1881 mask = 7;
1882 goto do_shifts;
1883 case MO_16:
1884 mask = 15;
1885 do_shifts:
1886 shift = op2 & mask;
1887 if (is_right) {
1888 shift = mask + 1 - shift;
1889 }
1890 gen_extu(ot, s->T0);
1891 tcg_gen_shli_tl(s->tmp0, s->T0, shift);
1892 tcg_gen_shri_tl(s->T0, s->T0, mask + 1 - shift);
1893 tcg_gen_or_tl(s->T0, s->T0, s->tmp0);
1894 break;
1895 }
1896 }
1897
1898 /* store */
1899 gen_op_st_rm_T0_A0(s, ot, op1);
1900
1901 if (op2 != 0) {
1902 /* Compute the flags into CC_SRC. */
1903 gen_compute_eflags(s);
1904
1905 /* The value that was "rotated out" is now present at the other end
1906 of the word. Compute C into CC_DST and O into CC_SRC2. Note that
1907 since we've computed the flags into CC_SRC, these variables are
1908 currently dead. */
1909 if (is_right) {
1910 tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask - 1);
1911 tcg_gen_shri_tl(cpu_cc_dst, s->T0, mask);
1912 tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1913 } else {
1914 tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask);
1915 tcg_gen_andi_tl(cpu_cc_dst, s->T0, 1);
1916 }
1917 tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1918 tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1919 set_cc_op(s, CC_OP_ADCOX);
1920 }
1921 }
1922
1923 /* XXX: add faster immediate = 1 case */
1924 static void gen_rotc_rm_T1(DisasContext *s, MemOp ot, int op1,
1925 int is_right)
1926 {
1927 gen_compute_eflags(s);
1928 assert(s->cc_op == CC_OP_EFLAGS);
1929
1930 /* load */
1931 if (op1 == OR_TMP0)
1932 gen_op_ld_v(s, ot, s->T0, s->A0);
1933 else
1934 gen_op_mov_v_reg(s, ot, s->T0, op1);
1935
1936 if (is_right) {
1937 switch (ot) {
1938 case MO_8:
1939 gen_helper_rcrb(s->T0, tcg_env, s->T0, s->T1);
1940 break;
1941 case MO_16:
1942 gen_helper_rcrw(s->T0, tcg_env, s->T0, s->T1);
1943 break;
1944 case MO_32:
1945 gen_helper_rcrl(s->T0, tcg_env, s->T0, s->T1);
1946 break;
1947 #ifdef TARGET_X86_64
1948 case MO_64:
1949 gen_helper_rcrq(s->T0, tcg_env, s->T0, s->T1);
1950 break;
1951 #endif
1952 default:
1953 g_assert_not_reached();
1954 }
1955 } else {
1956 switch (ot) {
1957 case MO_8:
1958 gen_helper_rclb(s->T0, tcg_env, s->T0, s->T1);
1959 break;
1960 case MO_16:
1961 gen_helper_rclw(s->T0, tcg_env, s->T0, s->T1);
1962 break;
1963 case MO_32:
1964 gen_helper_rcll(s->T0, tcg_env, s->T0, s->T1);
1965 break;
1966 #ifdef TARGET_X86_64
1967 case MO_64:
1968 gen_helper_rclq(s->T0, tcg_env, s->T0, s->T1);
1969 break;
1970 #endif
1971 default:
1972 g_assert_not_reached();
1973 }
1974 }
1975 /* store */
1976 gen_op_st_rm_T0_A0(s, ot, op1);
1977 }
1978
1979 /* XXX: add faster immediate case */
1980 static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, int op1,
1981 bool is_right, TCGv count_in)
1982 {
1983 target_ulong mask = (ot == MO_64 ? 63 : 31);
1984 TCGv count;
1985
1986 /* load */
1987 if (op1 == OR_TMP0) {
1988 gen_op_ld_v(s, ot, s->T0, s->A0);
1989 } else {
1990 gen_op_mov_v_reg(s, ot, s->T0, op1);
1991 }
1992
1993 count = tcg_temp_new();
1994 tcg_gen_andi_tl(count, count_in, mask);
1995
1996 switch (ot) {
1997 case MO_16:
1998 /* Note: we implement the Intel behaviour for shift count > 16.
1999 This means "shrdw C, B, A" shifts A:B:A >> C. Build the B:A
2000 portion by constructing it as a 32-bit value. */
2001 if (is_right) {
2002 tcg_gen_deposit_tl(s->tmp0, s->T0, s->T1, 16, 16);
2003 tcg_gen_mov_tl(s->T1, s->T0);
2004 tcg_gen_mov_tl(s->T0, s->tmp0);
2005 } else {
2006 tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16);
2007 }
2008 /*
2009 * If TARGET_X86_64 defined then fall through into MO_32 case,
2010 * otherwise fall through default case.
2011 */
2012 case MO_32:
2013 #ifdef TARGET_X86_64
2014 /* Concatenate the two 32-bit values and use a 64-bit shift. */
2015 tcg_gen_subi_tl(s->tmp0, count, 1);
2016 if (is_right) {
2017 tcg_gen_concat_tl_i64(s->T0, s->T0, s->T1);
2018 tcg_gen_shr_i64(s->tmp0, s->T0, s->tmp0);
2019 tcg_gen_shr_i64(s->T0, s->T0, count);
2020 } else {
2021 tcg_gen_concat_tl_i64(s->T0, s->T1, s->T0);
2022 tcg_gen_shl_i64(s->tmp0, s->T0, s->tmp0);
2023 tcg_gen_shl_i64(s->T0, s->T0, count);
2024 tcg_gen_shri_i64(s->tmp0, s->tmp0, 32);
2025 tcg_gen_shri_i64(s->T0, s->T0, 32);
2026 }
2027 break;
2028 #endif
2029 default:
2030 tcg_gen_subi_tl(s->tmp0, count, 1);
2031 if (is_right) {
2032 tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0);
2033
2034 tcg_gen_subfi_tl(s->tmp4, mask + 1, count);
2035 tcg_gen_shr_tl(s->T0, s->T0, count);
2036 tcg_gen_shl_tl(s->T1, s->T1, s->tmp4);
2037 } else {
2038 tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0);
2039 if (ot == MO_16) {
2040 /* Only needed if count > 16, for Intel behaviour. */
2041 tcg_gen_subfi_tl(s->tmp4, 33, count);
2042 tcg_gen_shr_tl(s->tmp4, s->T1, s->tmp4);
2043 tcg_gen_or_tl(s->tmp0, s->tmp0, s->tmp4);
2044 }
2045
2046 tcg_gen_subfi_tl(s->tmp4, mask + 1, count);
2047 tcg_gen_shl_tl(s->T0, s->T0, count);
2048 tcg_gen_shr_tl(s->T1, s->T1, s->tmp4);
2049 }
2050 tcg_gen_movi_tl(s->tmp4, 0);
2051 tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, s->tmp4,
2052 s->tmp4, s->T1);
2053 tcg_gen_or_tl(s->T0, s->T0, s->T1);
2054 break;
2055 }
2056
2057 /* store */
2058 gen_op_st_rm_T0_A0(s, ot, op1);
2059
2060 gen_shift_flags(s, ot, s->T0, s->tmp0, count, is_right);
2061 }
2062
2063 static void gen_shift(DisasContext *s1, int op, MemOp ot, int d, int s)
2064 {
2065 if (s != OR_TMP1)
2066 gen_op_mov_v_reg(s1, ot, s1->T1, s);
2067 switch(op) {
2068 case OP_ROL:
2069 gen_rot_rm_T1(s1, ot, d, 0);
2070 break;
2071 case OP_ROR:
2072 gen_rot_rm_T1(s1, ot, d, 1);
2073 break;
2074 case OP_SHL:
2075 case OP_SHL1:
2076 gen_shift_rm_T1(s1, ot, d, 0, 0);
2077 break;
2078 case OP_SHR:
2079 gen_shift_rm_T1(s1, ot, d, 1, 0);
2080 break;
2081 case OP_SAR:
2082 gen_shift_rm_T1(s1, ot, d, 1, 1);
2083 break;
2084 case OP_RCL:
2085 gen_rotc_rm_T1(s1, ot, d, 0);
2086 break;
2087 case OP_RCR:
2088 gen_rotc_rm_T1(s1, ot, d, 1);
2089 break;
2090 }
2091 }
2092
2093 static void gen_shifti(DisasContext *s1, int op, MemOp ot, int d, int c)
2094 {
2095 switch(op) {
2096 case OP_ROL:
2097 gen_rot_rm_im(s1, ot, d, c, 0);
2098 break;
2099 case OP_ROR:
2100 gen_rot_rm_im(s1, ot, d, c, 1);
2101 break;
2102 case OP_SHL:
2103 case OP_SHL1:
2104 gen_shift_rm_im(s1, ot, d, c, 0, 0);
2105 break;
2106 case OP_SHR:
2107 gen_shift_rm_im(s1, ot, d, c, 1, 0);
2108 break;
2109 case OP_SAR:
2110 gen_shift_rm_im(s1, ot, d, c, 1, 1);
2111 break;
2112 default:
2113 /* currently not optimized */
2114 tcg_gen_movi_tl(s1->T1, c);
2115 gen_shift(s1, op, ot, d, OR_TMP1);
2116 break;
2117 }
2118 }
2119
2120 #define X86_MAX_INSN_LENGTH 15
2121
2122 static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
2123 {
2124 uint64_t pc = s->pc;
2125
2126 /* This is a subsequent insn that crosses a page boundary. */
2127 if (s->base.num_insns > 1 &&
2128 !is_same_page(&s->base, s->pc + num_bytes - 1)) {
2129 siglongjmp(s->jmpbuf, 2);
2130 }
2131
2132 s->pc += num_bytes;
2133 if (unlikely(cur_insn_len(s) > X86_MAX_INSN_LENGTH)) {
2134 /* If the instruction's 16th byte is on a different page than the 1st, a
2135 * page fault on the second page wins over the general protection fault
2136 * caused by the instruction being too long.
2137 * This can happen even if the operand is only one byte long!
2138 */
2139 if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) {
2140 volatile uint8_t unused =
2141 cpu_ldub_code(env, (s->pc - 1) & TARGET_PAGE_MASK);
2142 (void) unused;
2143 }
2144 siglongjmp(s->jmpbuf, 1);
2145 }
2146
2147 return pc;
2148 }
2149
2150 static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
2151 {
2152 return translator_ldub(env, &s->base, advance_pc(env, s, 1));
2153 }
2154
2155 static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s)
2156 {
2157 return translator_lduw(env, &s->base, advance_pc(env, s, 2));
2158 }
2159
2160 static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
2161 {
2162 return translator_lduw(env, &s->base, advance_pc(env, s, 2));
2163 }
2164
2165 static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s)
2166 {
2167 return translator_ldl(env, &s->base, advance_pc(env, s, 4));
2168 }
2169
2170 #ifdef TARGET_X86_64
2171 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s)
2172 {
2173 return translator_ldq(env, &s->base, advance_pc(env, s, 8));
2174 }
2175 #endif
2176
2177 /* Decompose an address. */
2178
2179 typedef struct AddressParts {
2180 int def_seg;
2181 int base;
2182 int index;
2183 int scale;
2184 target_long disp;
2185 } AddressParts;
2186
2187 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
2188 int modrm)
2189 {
2190 int def_seg, base, index, scale, mod, rm;
2191 target_long disp;
2192 bool havesib;
2193
2194 def_seg = R_DS;
2195 index = -1;
2196 scale = 0;
2197 disp = 0;
2198
2199 mod = (modrm >> 6) & 3;
2200 rm = modrm & 7;
2201 base = rm | REX_B(s);
2202
2203 if (mod == 3) {
2204 /* Normally filtered out earlier, but including this path
2205 simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */
2206 goto done;
2207 }
2208
2209 switch (s->aflag) {
2210 case MO_64:
2211 case MO_32:
2212 havesib = 0;
2213 if (rm == 4) {
2214 int code = x86_ldub_code(env, s);
2215 scale = (code >> 6) & 3;
2216 index = ((code >> 3) & 7) | REX_X(s);
2217 if (index == 4) {
2218 index = -1; /* no index */
2219 }
2220 base = (code & 7) | REX_B(s);
2221 havesib = 1;
2222 }
2223
2224 switch (mod) {
2225 case 0:
2226 if ((base & 7) == 5) {
2227 base = -1;
2228 disp = (int32_t)x86_ldl_code(env, s);
2229 if (CODE64(s) && !havesib) {
2230 base = -2;
2231 disp += s->pc + s->rip_offset;
2232 }
2233 }
2234 break;
2235 case 1:
2236 disp = (int8_t)x86_ldub_code(env, s);
2237 break;
2238 default:
2239 case 2:
2240 disp = (int32_t)x86_ldl_code(env, s);
2241 break;
2242 }
2243
2244 /* For correct popl handling with esp. */
2245 if (base == R_ESP && s->popl_esp_hack) {
2246 disp += s->popl_esp_hack;
2247 }
2248 if (base == R_EBP || base == R_ESP) {
2249 def_seg = R_SS;
2250 }
2251 break;
2252
2253 case MO_16:
2254 if (mod == 0) {
2255 if (rm == 6) {
2256 base = -1;
2257 disp = x86_lduw_code(env, s);
2258 break;
2259 }
2260 } else if (mod == 1) {
2261 disp = (int8_t)x86_ldub_code(env, s);
2262 } else {
2263 disp = (int16_t)x86_lduw_code(env, s);
2264 }
2265
2266 switch (rm) {
2267 case 0:
2268 base = R_EBX;
2269 index = R_ESI;
2270 break;
2271 case 1:
2272 base = R_EBX;
2273 index = R_EDI;
2274 break;
2275 case 2:
2276 base = R_EBP;
2277 index = R_ESI;
2278 def_seg = R_SS;
2279 break;
2280 case 3:
2281 base = R_EBP;
2282 index = R_EDI;
2283 def_seg = R_SS;
2284 break;
2285 case 4:
2286 base = R_ESI;
2287 break;
2288 case 5:
2289 base = R_EDI;
2290 break;
2291 case 6:
2292 base = R_EBP;
2293 def_seg = R_SS;
2294 break;
2295 default:
2296 case 7:
2297 base = R_EBX;
2298 break;
2299 }
2300 break;
2301
2302 default:
2303 g_assert_not_reached();
2304 }
2305
2306 done:
2307 return (AddressParts){ def_seg, base, index, scale, disp };
2308 }
2309
2310 /* Compute the address, with a minimum number of TCG ops. */
2311 static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib)
2312 {
2313 TCGv ea = NULL;
2314
2315 if (a.index >= 0 && !is_vsib) {
2316 if (a.scale == 0) {
2317 ea = cpu_regs[a.index];
2318 } else {
2319 tcg_gen_shli_tl(s->A0, cpu_regs[a.index], a.scale);
2320 ea = s->A0;
2321 }
2322 if (a.base >= 0) {
2323 tcg_gen_add_tl(s->A0, ea, cpu_regs[a.base]);
2324 ea = s->A0;
2325 }
2326 } else if (a.base >= 0) {
2327 ea = cpu_regs[a.base];
2328 }
2329 if (!ea) {
2330 if (tb_cflags(s->base.tb) & CF_PCREL && a.base == -2) {
2331 /* With cpu_eip ~= pc_save, the expression is pc-relative. */
2332 tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save);
2333 } else {
2334 tcg_gen_movi_tl(s->A0, a.disp);
2335 }
2336 ea = s->A0;
2337 } else if (a.disp != 0) {
2338 tcg_gen_addi_tl(s->A0, ea, a.disp);
2339 ea = s->A0;
2340 }
2341
2342 return ea;
2343 }
2344
2345 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
2346 {
2347 AddressParts a = gen_lea_modrm_0(env, s, modrm);
2348 TCGv ea = gen_lea_modrm_1(s, a, false);
2349 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
2350 }
2351
2352 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2353 {
2354 (void)gen_lea_modrm_0(env, s, modrm);
2355 }
2356
2357 /* Used for BNDCL, BNDCU, BNDCN. */
2358 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm,
2359 TCGCond cond, TCGv_i64 bndv)
2360 {
2361 AddressParts a = gen_lea_modrm_0(env, s, modrm);
2362 TCGv ea = gen_lea_modrm_1(s, a, false);
2363
2364 tcg_gen_extu_tl_i64(s->tmp1_i64, ea);
2365 if (!CODE64(s)) {
2366 tcg_gen_ext32u_i64(s->tmp1_i64, s->tmp1_i64);
2367 }
2368 tcg_gen_setcond_i64(cond, s->tmp1_i64, s->tmp1_i64, bndv);
2369 tcg_gen_extrl_i64_i32(s->tmp2_i32, s->tmp1_i64);
2370 gen_helper_bndck(tcg_env, s->tmp2_i32);
2371 }
2372
2373 /* used for LEA and MOV AX, mem */
2374 static void gen_add_A0_ds_seg(DisasContext *s)
2375 {
2376 gen_lea_v_seg(s, s->aflag, s->A0, R_DS, s->override);
2377 }
2378
2379 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2380 OR_TMP0 */
2381 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2382 MemOp ot, int reg, int is_store)
2383 {
2384 int mod, rm;
2385
2386 mod = (modrm >> 6) & 3;
2387 rm = (modrm & 7) | REX_B(s);
2388 if (mod == 3) {
2389 if (is_store) {
2390 if (reg != OR_TMP0)
2391 gen_op_mov_v_reg(s, ot, s->T0, reg);
2392 gen_op_mov_reg_v(s, ot, rm, s->T0);
2393 } else {
2394 gen_op_mov_v_reg(s, ot, s->T0, rm);
2395 if (reg != OR_TMP0)
2396 gen_op_mov_reg_v(s, ot, reg, s->T0);
2397 }
2398 } else {
2399 gen_lea_modrm(env, s, modrm);
2400 if (is_store) {
2401 if (reg != OR_TMP0)
2402 gen_op_mov_v_reg(s, ot, s->T0, reg);
2403 gen_op_st_v(s, ot, s->T0, s->A0);
2404 } else {
2405 gen_op_ld_v(s, ot, s->T0, s->A0);
2406 if (reg != OR_TMP0)
2407 gen_op_mov_reg_v(s, ot, reg, s->T0);
2408 }
2409 }
2410 }
2411
2412 static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot)
2413 {
2414 target_ulong ret;
2415
2416 switch (ot) {
2417 case MO_8:
2418 ret = x86_ldub_code(env, s);
2419 break;
2420 case MO_16:
2421 ret = x86_lduw_code(env, s);
2422 break;
2423 case MO_32:
2424 ret = x86_ldl_code(env, s);
2425 break;
2426 #ifdef TARGET_X86_64
2427 case MO_64:
2428 ret = x86_ldq_code(env, s);
2429 break;
2430 #endif
2431 default:
2432 g_assert_not_reached();
2433 }
2434 return ret;
2435 }
2436
2437 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot)
2438 {
2439 uint32_t ret;
2440
2441 switch (ot) {
2442 case MO_8:
2443 ret = x86_ldub_code(env, s);
2444 break;
2445 case MO_16:
2446 ret = x86_lduw_code(env, s);
2447 break;
2448 case MO_32:
2449 #ifdef TARGET_X86_64
2450 case MO_64:
2451 #endif
2452 ret = x86_ldl_code(env, s);
2453 break;
2454 default:
2455 g_assert_not_reached();
2456 }
2457 return ret;
2458 }
2459
2460 static target_long insn_get_signed(CPUX86State *env, DisasContext *s, MemOp ot)
2461 {
2462 target_long ret;
2463
2464 switch (ot) {
2465 case MO_8:
2466 ret = (int8_t) x86_ldub_code(env, s);
2467 break;
2468 case MO_16:
2469 ret = (int16_t) x86_lduw_code(env, s);
2470 break;
2471 case MO_32:
2472 ret = (int32_t) x86_ldl_code(env, s);
2473 break;
2474 #ifdef TARGET_X86_64
2475 case MO_64:
2476 ret = x86_ldq_code(env, s);
2477 break;
2478 #endif
2479 default:
2480 g_assert_not_reached();
2481 }
2482 return ret;
2483 }
2484
2485 static inline int insn_const_size(MemOp ot)
2486 {
2487 if (ot <= MO_32) {
2488 return 1 << ot;
2489 } else {
2490 return 4;
2491 }
2492 }
2493
2494 static void gen_jcc(DisasContext *s, int b, int diff)
2495 {
2496 TCGLabel *l1 = gen_new_label();
2497
2498 gen_jcc1(s, b, l1);
2499 gen_jmp_rel_csize(s, 0, 1);
2500 gen_set_label(l1);
2501 gen_jmp_rel(s, s->dflag, diff, 0);
2502 }
2503
2504 static void gen_cmovcc1(DisasContext *s, int b, TCGv dest, TCGv src)
2505 {
2506 CCPrepare cc = gen_prepare_cc(s, b, s->T1);
2507
2508 if (cc.mask != -1) {
2509 TCGv t0 = tcg_temp_new();
2510 tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2511 cc.reg = t0;
2512 }
2513 if (!cc.use_reg2) {
2514 cc.reg2 = tcg_constant_tl(cc.imm);
2515 }
2516
2517 tcg_gen_movcond_tl(cc.cond, dest, cc.reg, cc.reg2, src, dest);
2518 }
2519
2520 static inline void gen_op_movl_T0_seg(DisasContext *s, X86Seg seg_reg)
2521 {
2522 tcg_gen_ld32u_tl(s->T0, tcg_env,
2523 offsetof(CPUX86State,segs[seg_reg].selector));
2524 }
2525
2526 static inline void gen_op_movl_seg_T0_vm(DisasContext *s, X86Seg seg_reg)
2527 {
2528 tcg_gen_ext16u_tl(s->T0, s->T0);
2529 tcg_gen_st32_tl(s->T0, tcg_env,
2530 offsetof(CPUX86State,segs[seg_reg].selector));
2531 tcg_gen_shli_tl(cpu_seg_base[seg_reg], s->T0, 4);
2532 }
2533
2534 /* move T0 to seg_reg and compute if the CPU state may change. Never
2535 call this function with seg_reg == R_CS */
2536 static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg)
2537 {
2538 if (PE(s) && !VM86(s)) {
2539 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
2540 gen_helper_load_seg(tcg_env, tcg_constant_i32(seg_reg), s->tmp2_i32);
2541 /* abort translation because the addseg value may change or
2542 because ss32 may change. For R_SS, translation must always
2543 stop as a special handling must be done to disable hardware
2544 interrupts for the next instruction */
2545 if (seg_reg == R_SS) {
2546 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
2547 } else if (CODE32(s) && seg_reg < R_FS) {
2548 s->base.is_jmp = DISAS_EOB_NEXT;
2549 }
2550 } else {
2551 gen_op_movl_seg_T0_vm(s, seg_reg);
2552 if (seg_reg == R_SS) {
2553 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
2554 }
2555 }
2556 }
2557
2558 static void gen_svm_check_intercept(DisasContext *s, uint32_t type)
2559 {
2560 /* no SVM activated; fast case */
2561 if (likely(!GUEST(s))) {
2562 return;
2563 }
2564 gen_helper_svm_check_intercept(tcg_env, tcg_constant_i32(type));
2565 }
2566
2567 static inline void gen_stack_update(DisasContext *s, int addend)
2568 {
2569 gen_op_add_reg_im(s, mo_stacksize(s), R_ESP, addend);
2570 }
2571
2572 /* Generate a push. It depends on ss32, addseg and dflag. */
2573 static void gen_push_v(DisasContext *s, TCGv val)
2574 {
2575 MemOp d_ot = mo_pushpop(s, s->dflag);
2576 MemOp a_ot = mo_stacksize(s);
2577 int size = 1 << d_ot;
2578 TCGv new_esp = s->A0;
2579
2580 tcg_gen_subi_tl(s->A0, cpu_regs[R_ESP], size);
2581
2582 if (!CODE64(s)) {
2583 if (ADDSEG(s)) {
2584 new_esp = tcg_temp_new();
2585 tcg_gen_mov_tl(new_esp, s->A0);
2586 }
2587 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2588 }
2589
2590 gen_op_st_v(s, d_ot, val, s->A0);
2591 gen_op_mov_reg_v(s, a_ot, R_ESP, new_esp);
2592 }
2593
2594 /* two step pop is necessary for precise exceptions */
2595 static MemOp gen_pop_T0(DisasContext *s)
2596 {
2597 MemOp d_ot = mo_pushpop(s, s->dflag);
2598
2599 gen_lea_v_seg_dest(s, mo_stacksize(s), s->T0, cpu_regs[R_ESP], R_SS, -1);
2600 gen_op_ld_v(s, d_ot, s->T0, s->T0);
2601
2602 return d_ot;
2603 }
2604
2605 static inline void gen_pop_update(DisasContext *s, MemOp ot)
2606 {
2607 gen_stack_update(s, 1 << ot);
2608 }
2609
2610 static inline void gen_stack_A0(DisasContext *s)
2611 {
2612 gen_lea_v_seg(s, SS32(s) ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
2613 }
2614
2615 static void gen_pusha(DisasContext *s)
2616 {
2617 MemOp s_ot = SS32(s) ? MO_32 : MO_16;
2618 MemOp d_ot = s->dflag;
2619 int size = 1 << d_ot;
2620 int i;
2621
2622 for (i = 0; i < 8; i++) {
2623 tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], (i - 8) * size);
2624 gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1);
2625 gen_op_st_v(s, d_ot, cpu_regs[7 - i], s->A0);
2626 }
2627
2628 gen_stack_update(s, -8 * size);
2629 }
2630
2631 static void gen_popa(DisasContext *s)
2632 {
2633 MemOp s_ot = SS32(s) ? MO_32 : MO_16;
2634 MemOp d_ot = s->dflag;
2635 int size = 1 << d_ot;
2636 int i;
2637
2638 for (i = 0; i < 8; i++) {
2639 /* ESP is not reloaded */
2640 if (7 - i == R_ESP) {
2641 continue;
2642 }
2643 tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], i * size);
2644 gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1);
2645 gen_op_ld_v(s, d_ot, s->T0, s->A0);
2646 gen_op_mov_reg_v(s, d_ot, 7 - i, s->T0);
2647 }
2648
2649 gen_stack_update(s, 8 * size);
2650 }
2651
2652 static void gen_enter(DisasContext *s, int esp_addend, int level)
2653 {
2654 MemOp d_ot = mo_pushpop(s, s->dflag);
2655 MemOp a_ot = CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16;
2656 int size = 1 << d_ot;
2657
2658 /* Push BP; compute FrameTemp into T1. */
2659 tcg_gen_subi_tl(s->T1, cpu_regs[R_ESP], size);
2660 gen_lea_v_seg(s, a_ot, s->T1, R_SS, -1);
2661 gen_op_st_v(s, d_ot, cpu_regs[R_EBP], s->A0);
2662
2663 level &= 31;
2664 if (level != 0) {
2665 int i;
2666
2667 /* Copy level-1 pointers from the previous frame. */
2668 for (i = 1; i < level; ++i) {
2669 tcg_gen_subi_tl(s->A0, cpu_regs[R_EBP], size * i);
2670 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2671 gen_op_ld_v(s, d_ot, s->tmp0, s->A0);
2672
2673 tcg_gen_subi_tl(s->A0, s->T1, size * i);
2674 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2675 gen_op_st_v(s, d_ot, s->tmp0, s->A0);
2676 }
2677
2678 /* Push the current FrameTemp as the last level. */
2679 tcg_gen_subi_tl(s->A0, s->T1, size * level);
2680 gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2681 gen_op_st_v(s, d_ot, s->T1, s->A0);
2682 }
2683
2684 /* Copy the FrameTemp value to EBP. */
2685 gen_op_mov_reg_v(s, a_ot, R_EBP, s->T1);
2686
2687 /* Compute the final value of ESP. */
2688 tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level);
2689 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1);
2690 }
2691
2692 static void gen_leave(DisasContext *s)
2693 {
2694 MemOp d_ot = mo_pushpop(s, s->dflag);
2695 MemOp a_ot = mo_stacksize(s);
2696
2697 gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1);
2698 gen_op_ld_v(s, d_ot, s->T0, s->A0);
2699
2700 tcg_gen_addi_tl(s->T1, cpu_regs[R_EBP], 1 << d_ot);
2701
2702 gen_op_mov_reg_v(s, d_ot, R_EBP, s->T0);
2703 gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1);
2704 }
2705
2706 /* Similarly, except that the assumption here is that we don't decode
2707 the instruction at all -- either a missing opcode, an unimplemented
2708 feature, or just a bogus instruction stream. */
2709 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
2710 {
2711 gen_illegal_opcode(s);
2712
2713 if (qemu_loglevel_mask(LOG_UNIMP)) {
2714 FILE *logfile = qemu_log_trylock();
2715 if (logfile) {
2716 target_ulong pc = s->base.pc_next, end = s->pc;
2717
2718 fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc);
2719 for (; pc < end; ++pc) {
2720 fprintf(logfile, " %02x", cpu_ldub_code(env, pc));
2721 }
2722 fprintf(logfile, "\n");
2723 qemu_log_unlock(logfile);
2724 }
2725 }
2726 }
2727
2728 /* an interrupt is different from an exception because of the
2729 privilege checks */
2730 static void gen_interrupt(DisasContext *s, int intno)
2731 {
2732 gen_update_cc_op(s);
2733 gen_update_eip_cur(s);
2734 gen_helper_raise_interrupt(tcg_env, tcg_constant_i32(intno),
2735 cur_insn_len_i32(s));
2736 s->base.is_jmp = DISAS_NORETURN;
2737 }
2738
2739 static void gen_set_hflag(DisasContext *s, uint32_t mask)
2740 {
2741 if ((s->flags & mask) == 0) {
2742 TCGv_i32 t = tcg_temp_new_i32();
2743 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags));
2744 tcg_gen_ori_i32(t, t, mask);
2745 tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags));
2746 s->flags |= mask;
2747 }
2748 }
2749
2750 static void gen_reset_hflag(DisasContext *s, uint32_t mask)
2751 {
2752 if (s->flags & mask) {
2753 TCGv_i32 t = tcg_temp_new_i32();
2754 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUX86State, hflags));
2755 tcg_gen_andi_i32(t, t, ~mask);
2756 tcg_gen_st_i32(t, tcg_env, offsetof(CPUX86State, hflags));
2757 s->flags &= ~mask;
2758 }
2759 }
2760
2761 static void gen_set_eflags(DisasContext *s, target_ulong mask)
2762 {
2763 TCGv t = tcg_temp_new();
2764
2765 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags));
2766 tcg_gen_ori_tl(t, t, mask);
2767 tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags));
2768 }
2769
2770 static void gen_reset_eflags(DisasContext *s, target_ulong mask)
2771 {
2772 TCGv t = tcg_temp_new();
2773
2774 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, eflags));
2775 tcg_gen_andi_tl(t, t, ~mask);
2776 tcg_gen_st_tl(t, tcg_env, offsetof(CPUX86State, eflags));
2777 }
2778
2779 /* Clear BND registers during legacy branches. */
2780 static void gen_bnd_jmp(DisasContext *s)
2781 {
2782 /* Clear the registers only if BND prefix is missing, MPX is enabled,
2783 and if the BNDREGs are known to be in use (non-zero) already.
2784 The helper itself will check BNDPRESERVE at runtime. */
2785 if ((s->prefix & PREFIX_REPNZ) == 0
2786 && (s->flags & HF_MPX_EN_MASK) != 0
2787 && (s->flags & HF_MPX_IU_MASK) != 0) {
2788 gen_helper_bnd_jmp(tcg_env);
2789 }
2790 }
2791
2792 /* Generate an end of block. Trace exception is also generated if needed.
2793 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2794 If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2795 S->TF. This is used by the syscall/sysret insns. */
2796 static void
2797 do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
2798 {
2799 gen_update_cc_op(s);
2800
2801 /* If several instructions disable interrupts, only the first does it. */
2802 if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
2803 gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
2804 } else {
2805 gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
2806 }
2807
2808 if (s->base.tb->flags & HF_RF_MASK) {
2809 gen_reset_eflags(s, RF_MASK);
2810 }
2811 if (recheck_tf) {
2812 gen_helper_rechecking_single_step(tcg_env);
2813 tcg_gen_exit_tb(NULL, 0);
2814 } else if (s->flags & HF_TF_MASK) {
2815 gen_helper_single_step(tcg_env);
2816 } else if (jr) {
2817 tcg_gen_lookup_and_goto_ptr();
2818 } else {
2819 tcg_gen_exit_tb(NULL, 0);
2820 }
2821 s->base.is_jmp = DISAS_NORETURN;
2822 }
2823
2824 static inline void
2825 gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf)
2826 {
2827 do_gen_eob_worker(s, inhibit, recheck_tf, false);
2828 }
2829
2830 /* End of block.
2831 If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */
2832 static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
2833 {
2834 gen_eob_worker(s, inhibit, false);
2835 }
2836
2837 /* End of block, resetting the inhibit irq flag. */
2838 static void gen_eob(DisasContext *s)
2839 {
2840 gen_eob_worker(s, false, false);
2841 }
2842
2843 /* Jump to register */
2844 static void gen_jr(DisasContext *s)
2845 {
2846 do_gen_eob_worker(s, false, false, true);
2847 }
2848
2849 /* Jump to eip+diff, truncating the result to OT. */
2850 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
2851 {
2852 bool use_goto_tb = s->jmp_opt;
2853 target_ulong mask = -1;
2854 target_ulong new_pc = s->pc + diff;
2855 target_ulong new_eip = new_pc - s->cs_base;
2856
2857 /* In 64-bit mode, operand size is fixed at 64 bits. */
2858 if (!CODE64(s)) {
2859 if (ot == MO_16) {
2860 mask = 0xffff;
2861 if (tb_cflags(s->base.tb) & CF_PCREL && CODE32(s)) {
2862 use_goto_tb = false;
2863 }
2864 } else {
2865 mask = 0xffffffff;
2866 }
2867 }
2868 new_eip &= mask;
2869
2870 gen_update_cc_op(s);
2871 set_cc_op(s, CC_OP_DYNAMIC);
2872
2873 if (tb_cflags(s->base.tb) & CF_PCREL) {
2874 tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save);
2875 /*
2876 * If we can prove the branch does not leave the page and we have
2877 * no extra masking to apply (data16 branch in code32, see above),
2878 * then we have also proven that the addition does not wrap.
2879 */
2880 if (!use_goto_tb || !is_same_page(&s->base, new_pc)) {
2881 tcg_gen_andi_tl(cpu_eip, cpu_eip, mask);
2882 use_goto_tb = false;
2883 }
2884 } else if (!CODE64(s)) {
2885 new_pc = (uint32_t)(new_eip + s->cs_base);
2886 }
2887
2888 if (use_goto_tb && translator_use_goto_tb(&s->base, new_pc)) {
2889 /* jump to same page: we can use a direct jump */
2890 tcg_gen_goto_tb(tb_num);
2891 if (!(tb_cflags(s->base.tb) & CF_PCREL)) {
2892 tcg_gen_movi_tl(cpu_eip, new_eip);
2893 }
2894 tcg_gen_exit_tb(s->base.tb, tb_num);
2895 s->base.is_jmp = DISAS_NORETURN;
2896 } else {
2897 if (!(tb_cflags(s->base.tb) & CF_PCREL)) {
2898 tcg_gen_movi_tl(cpu_eip, new_eip);
2899 }
2900 if (s->jmp_opt) {
2901 gen_jr(s); /* jump to another page */
2902 } else {
2903 gen_eob(s); /* exit to main loop */
2904 }
2905 }
2906 }
2907
2908 /* Jump to eip+diff, truncating to the current code size. */
2909 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num)
2910 {
2911 /* CODE64 ignores the OT argument, so we need not consider it. */
2912 gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num);
2913 }
2914
2915 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2916 {
2917 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
2918 tcg_gen_st_i64(s->tmp1_i64, tcg_env, offset);
2919 }
2920
2921 static inline void gen_stq_env_A0(DisasContext *s, int offset)
2922 {
2923 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, offset);
2924 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
2925 }
2926
2927 static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align)
2928 {
2929 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX
2930 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR);
2931 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0);
2932 int mem_index = s->mem_index;
2933 TCGv_i128 t = tcg_temp_new_i128();
2934
2935 tcg_gen_qemu_ld_i128(t, s->A0, mem_index, mop);
2936 tcg_gen_st_i128(t, tcg_env, offset);
2937 }
2938
2939 static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align)
2940 {
2941 MemOp atom = (s->cpuid_ext_features & CPUID_EXT_AVX
2942 ? MO_ATOM_IFALIGN : MO_ATOM_IFALIGN_PAIR);
2943 MemOp mop = MO_128 | MO_LE | atom | (align ? MO_ALIGN_16 : 0);
2944 int mem_index = s->mem_index;
2945 TCGv_i128 t = tcg_temp_new_i128();
2946
2947 tcg_gen_ld_i128(t, tcg_env, offset);
2948 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop);
2949 }
2950
2951 static void gen_ldy_env_A0(DisasContext *s, int offset, bool align)
2952 {
2953 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR;
2954 int mem_index = s->mem_index;
2955 TCGv_i128 t0 = tcg_temp_new_i128();
2956 TCGv_i128 t1 = tcg_temp_new_i128();
2957
2958 tcg_gen_qemu_ld_i128(t0, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0));
2959 tcg_gen_addi_tl(s->tmp0, s->A0, 16);
2960 tcg_gen_qemu_ld_i128(t1, s->tmp0, mem_index, mop);
2961
2962 tcg_gen_st_i128(t0, tcg_env, offset + offsetof(YMMReg, YMM_X(0)));
2963 tcg_gen_st_i128(t1, tcg_env, offset + offsetof(YMMReg, YMM_X(1)));
2964 }
2965
2966 static void gen_sty_env_A0(DisasContext *s, int offset, bool align)
2967 {
2968 MemOp mop = MO_128 | MO_LE | MO_ATOM_IFALIGN_PAIR;
2969 int mem_index = s->mem_index;
2970 TCGv_i128 t = tcg_temp_new_i128();
2971
2972 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(0)));
2973 tcg_gen_qemu_st_i128(t, s->A0, mem_index, mop | (align ? MO_ALIGN_32 : 0));
2974 tcg_gen_addi_tl(s->tmp0, s->A0, 16);
2975 tcg_gen_ld_i128(t, tcg_env, offset + offsetof(YMMReg, YMM_X(1)));
2976 tcg_gen_qemu_st_i128(t, s->tmp0, mem_index, mop);
2977 }
2978
2979 #include "decode-new.h"
2980 #include "emit.c.inc"
2981 #include "decode-new.c.inc"
2982
2983 static void gen_cmpxchg8b(DisasContext *s, CPUX86State *env, int modrm)
2984 {
2985 TCGv_i64 cmp, val, old;
2986 TCGv Z;
2987
2988 gen_lea_modrm(env, s, modrm);
2989
2990 cmp = tcg_temp_new_i64();
2991 val = tcg_temp_new_i64();
2992 old = tcg_temp_new_i64();
2993
2994 /* Construct the comparison values from the register pair. */
2995 tcg_gen_concat_tl_i64(cmp, cpu_regs[R_EAX], cpu_regs[R_EDX]);
2996 tcg_gen_concat_tl_i64(val, cpu_regs[R_EBX], cpu_regs[R_ECX]);
2997
2998 /* Only require atomic with LOCK; non-parallel handled in generator. */
2999 if (s->prefix & PREFIX_LOCK) {
3000 tcg_gen_atomic_cmpxchg_i64(old, s->A0, cmp, val, s->mem_index, MO_TEUQ);
3001 } else {
3002 tcg_gen_nonatomic_cmpxchg_i64(old, s->A0, cmp, val,
3003 s->mem_index, MO_TEUQ);
3004 }
3005
3006 /* Set tmp0 to match the required value of Z. */
3007 tcg_gen_setcond_i64(TCG_COND_EQ, cmp, old, cmp);
3008 Z = tcg_temp_new();
3009 tcg_gen_trunc_i64_tl(Z, cmp);
3010
3011 /*
3012 * Extract the result values for the register pair.
3013 * For 32-bit, we may do this unconditionally, because on success (Z=1),
3014 * the old value matches the previous value in EDX:EAX. For x86_64,
3015 * the store must be conditional, because we must leave the source
3016 * registers unchanged on success, and zero-extend the writeback
3017 * on failure (Z=0).
3018 */
3019 if (TARGET_LONG_BITS == 32) {
3020 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], old);
3021 } else {
3022 TCGv zero = tcg_constant_tl(0);
3023
3024 tcg_gen_extr_i64_tl(s->T0, s->T1, old);
3025 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_regs[R_EAX], Z, zero,
3026 s->T0, cpu_regs[R_EAX]);
3027 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_regs[R_EDX], Z, zero,
3028 s->T1, cpu_regs[R_EDX]);
3029 }
3030
3031 /* Update Z. */
3032 gen_compute_eflags(s);
3033 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, Z, ctz32(CC_Z), 1);
3034 }
3035
3036 #ifdef TARGET_X86_64
3037 static void gen_cmpxchg16b(DisasContext *s, CPUX86State *env, int modrm)
3038 {
3039 MemOp mop = MO_TE | MO_128 | MO_ALIGN;
3040 TCGv_i64 t0, t1;
3041 TCGv_i128 cmp, val;
3042
3043 gen_lea_modrm(env, s, modrm);
3044
3045 cmp = tcg_temp_new_i128();
3046 val = tcg_temp_new_i128();
3047 tcg_gen_concat_i64_i128(cmp, cpu_regs[R_EAX], cpu_regs[R_EDX]);
3048 tcg_gen_concat_i64_i128(val, cpu_regs[R_EBX], cpu_regs[R_ECX]);
3049
3050 /* Only require atomic with LOCK; non-parallel handled in generator. */
3051 if (s->prefix & PREFIX_LOCK) {
3052 tcg_gen_atomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop);
3053 } else {
3054 tcg_gen_nonatomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop);
3055 }
3056
3057 tcg_gen_extr_i128_i64(s->T0, s->T1, val);
3058
3059 /* Determine success after the fact. */
3060 t0 = tcg_temp_new_i64();
3061 t1 = tcg_temp_new_i64();
3062 tcg_gen_xor_i64(t0, s->T0, cpu_regs[R_EAX]);
3063 tcg_gen_xor_i64(t1, s->T1, cpu_regs[R_EDX]);
3064 tcg_gen_or_i64(t0, t0, t1);
3065
3066 /* Update Z. */
3067 gen_compute_eflags(s);
3068 tcg_gen_setcondi_i64(TCG_COND_EQ, t0, t0, 0);
3069 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, t0, ctz32(CC_Z), 1);
3070
3071 /*
3072 * Extract the result values for the register pair. We may do this
3073 * unconditionally, because on success (Z=1), the old value matches
3074 * the previous value in RDX:RAX.
3075 */
3076 tcg_gen_mov_i64(cpu_regs[R_EAX], s->T0);
3077 tcg_gen_mov_i64(cpu_regs[R_EDX], s->T1);
3078 }
3079 #endif
3080
3081 /* convert one instruction. s->base.is_jmp is set if the translation must
3082 be stopped. Return the next pc value */
3083 static bool disas_insn(DisasContext *s, CPUState *cpu)
3084 {
3085 CPUX86State *env = cpu_env(cpu);
3086 int b, prefixes;
3087 int shift;
3088 MemOp ot, aflag, dflag;
3089 int modrm, reg, rm, mod, op, opreg, val;
3090 bool orig_cc_op_dirty = s->cc_op_dirty;
3091 CCOp orig_cc_op = s->cc_op;
3092 target_ulong orig_pc_save = s->pc_save;
3093
3094 s->pc = s->base.pc_next;
3095 s->override = -1;
3096 #ifdef TARGET_X86_64
3097 s->rex_r = 0;
3098 s->rex_x = 0;
3099 s->rex_b = 0;
3100 #endif
3101 s->rip_offset = 0; /* for relative ip address */
3102 s->vex_l = 0;
3103 s->vex_v = 0;
3104 s->vex_w = false;
3105 switch (sigsetjmp(s->jmpbuf, 0)) {
3106 case 0:
3107 break;
3108 case 1:
3109 gen_exception_gpf(s);
3110 return true;
3111 case 2:
3112 /* Restore state that may affect the next instruction. */
3113 s->pc = s->base.pc_next;
3114 /*
3115 * TODO: These save/restore can be removed after the table-based
3116 * decoder is complete; we will be decoding the insn completely
3117 * before any code generation that might affect these variables.
3118 */
3119 s->cc_op_dirty = orig_cc_op_dirty;
3120 s->cc_op = orig_cc_op;
3121 s->pc_save = orig_pc_save;
3122 /* END TODO */
3123 s->base.num_insns--;
3124 tcg_remove_ops_after(s->prev_insn_end);
3125 s->base.is_jmp = DISAS_TOO_MANY;
3126 return false;
3127 default:
3128 g_assert_not_reached();
3129 }
3130
3131 prefixes = 0;
3132
3133 next_byte:
3134 s->prefix = prefixes;
3135 b = x86_ldub_code(env, s);
3136 /* Collect prefixes. */
3137 switch (b) {
3138 default:
3139 break;
3140 case 0x0f:
3141 b = x86_ldub_code(env, s) + 0x100;
3142 break;
3143 case 0xf3:
3144 prefixes |= PREFIX_REPZ;
3145 prefixes &= ~PREFIX_REPNZ;
3146 goto next_byte;
3147 case 0xf2:
3148 prefixes |= PREFIX_REPNZ;
3149 prefixes &= ~PREFIX_REPZ;
3150 goto next_byte;
3151 case 0xf0:
3152 prefixes |= PREFIX_LOCK;
3153 goto next_byte;
3154 case 0x2e:
3155 s->override = R_CS;
3156 goto next_byte;
3157 case 0x36:
3158 s->override = R_SS;
3159 goto next_byte;
3160 case 0x3e:
3161 s->override = R_DS;
3162 goto next_byte;
3163 case 0x26:
3164 s->override = R_ES;
3165 goto next_byte;
3166 case 0x64:
3167 s->override = R_FS;
3168 goto next_byte;
3169 case 0x65:
3170 s->override = R_GS;
3171 goto next_byte;
3172 case 0x66:
3173 prefixes |= PREFIX_DATA;
3174 goto next_byte;
3175 case 0x67:
3176 prefixes |= PREFIX_ADR;
3177 goto next_byte;
3178 #ifdef TARGET_X86_64
3179 case 0x40 ... 0x4f:
3180 if (CODE64(s)) {
3181 /* REX prefix */
3182 prefixes |= PREFIX_REX;
3183 s->vex_w = (b >> 3) & 1;
3184 s->rex_r = (b & 0x4) << 1;
3185 s->rex_x = (b & 0x2) << 2;
3186 s->rex_b = (b & 0x1) << 3;
3187 goto next_byte;
3188 }
3189 break;
3190 #endif
3191 case 0xc5: /* 2-byte VEX */
3192 case 0xc4: /* 3-byte VEX */
3193 if (CODE32(s) && !VM86(s)) {
3194 int vex2 = x86_ldub_code(env, s);
3195 s->pc--; /* rewind the advance_pc() x86_ldub_code() did */
3196
3197 if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
3198 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
3199 otherwise the instruction is LES or LDS. */
3200 break;
3201 }
3202 disas_insn_new(s, cpu, b);
3203 return s->pc;
3204 }
3205 break;
3206 }
3207
3208 /* Post-process prefixes. */
3209 if (CODE64(s)) {
3210 /* In 64-bit mode, the default data size is 32-bit. Select 64-bit
3211 data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
3212 over 0x66 if both are present. */
3213 dflag = (REX_W(s) ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
3214 /* In 64-bit mode, 0x67 selects 32-bit addressing. */
3215 aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
3216 } else {
3217 /* In 16/32-bit mode, 0x66 selects the opposite data size. */
3218 if (CODE32(s) ^ ((prefixes & PREFIX_DATA) != 0)) {
3219 dflag = MO_32;
3220 } else {
3221 dflag = MO_16;
3222 }
3223 /* In 16/32-bit mode, 0x67 selects the opposite addressing. */
3224 if (CODE32(s) ^ ((prefixes & PREFIX_ADR) != 0)) {
3225 aflag = MO_32;
3226 } else {
3227 aflag = MO_16;
3228 }
3229 }
3230
3231 s->prefix = prefixes;
3232 s->aflag = aflag;
3233 s->dflag = dflag;
3234
3235 /* now check op code */
3236 switch (b) {
3237 /**************************/
3238 /* arith & logic */
3239 case 0x00 ... 0x05:
3240 case 0x08 ... 0x0d:
3241 case 0x10 ... 0x15:
3242 case 0x18 ... 0x1d:
3243 case 0x20 ... 0x25:
3244 case 0x28 ... 0x2d:
3245 case 0x30 ... 0x35:
3246 case 0x38 ... 0x3d:
3247 {
3248 int f;
3249 op = (b >> 3) & 7;
3250 f = (b >> 1) & 3;
3251
3252 ot = mo_b_d(b, dflag);
3253
3254 switch(f) {
3255 case 0: /* OP Ev, Gv */
3256 modrm = x86_ldub_code(env, s);
3257 reg = ((modrm >> 3) & 7) | REX_R(s);
3258 mod = (modrm >> 6) & 3;
3259 rm = (modrm & 7) | REX_B(s);
3260 if (mod != 3) {
3261 gen_lea_modrm(env, s, modrm);
3262 opreg = OR_TMP0;
3263 } else if (op == OP_XORL && rm == reg) {
3264 xor_zero:
3265 /* xor reg, reg optimisation */
3266 set_cc_op(s, CC_OP_CLR);
3267 tcg_gen_movi_tl(s->T0, 0);
3268 gen_op_mov_reg_v(s, ot, reg, s->T0);
3269 break;
3270 } else {
3271 opreg = rm;
3272 }
3273 gen_op_mov_v_reg(s, ot, s->T1, reg);
3274 gen_op(s, op, ot, opreg);
3275 break;
3276 case 1: /* OP Gv, Ev */
3277 modrm = x86_ldub_code(env, s);
3278 mod = (modrm >> 6) & 3;
3279 reg = ((modrm >> 3) & 7) | REX_R(s);
3280 rm = (modrm & 7) | REX_B(s);
3281 if (mod != 3) {
3282 gen_lea_modrm(env, s, modrm);
3283 gen_op_ld_v(s, ot, s->T1, s->A0);
3284 } else if (op == OP_XORL && rm == reg) {
3285 goto xor_zero;
3286 } else {
3287 gen_op_mov_v_reg(s, ot, s->T1, rm);
3288 }
3289 gen_op(s, op, ot, reg);
3290 break;
3291 case 2: /* OP A, Iv */
3292 val = insn_get(env, s, ot);
3293 tcg_gen_movi_tl(s->T1, val);
3294 gen_op(s, op, ot, OR_EAX);
3295 break;
3296 }
3297 }
3298 break;
3299
3300 case 0x82:
3301 if (CODE64(s))
3302 goto illegal_op;
3303 /* fall through */
3304 case 0x80: /* GRP1 */
3305 case 0x81:
3306 case 0x83:
3307 {
3308 ot = mo_b_d(b, dflag);
3309
3310 modrm = x86_ldub_code(env, s);
3311 mod = (modrm >> 6) & 3;
3312 rm = (modrm & 7) | REX_B(s);
3313 op = (modrm >> 3) & 7;
3314
3315 if (mod != 3) {
3316 if (b == 0x83)
3317 s->rip_offset = 1;
3318 else
3319 s->rip_offset = insn_const_size(ot);
3320 gen_lea_modrm(env, s, modrm);
3321 opreg = OR_TMP0;
3322 } else {
3323 opreg = rm;
3324 }
3325
3326 switch(b) {
3327 default:
3328 case 0x80:
3329 case 0x81:
3330 case 0x82:
3331 val = insn_get(env, s, ot);
3332 break;
3333 case 0x83:
3334 val = (int8_t)insn_get(env, s, MO_8);
3335 break;
3336 }
3337 tcg_gen_movi_tl(s->T1, val);
3338 gen_op(s, op, ot, opreg);
3339 }
3340 break;
3341
3342 /**************************/
3343 /* inc, dec, and other misc arith */
3344 case 0x40 ... 0x47: /* inc Gv */
3345 ot = dflag;
3346 gen_inc(s, ot, OR_EAX + (b & 7), 1);
3347 break;
3348 case 0x48 ... 0x4f: /* dec Gv */
3349 ot = dflag;
3350 gen_inc(s, ot, OR_EAX + (b & 7), -1);
3351 break;
3352 case 0xf6: /* GRP3 */
3353 case 0xf7:
3354 ot = mo_b_d(b, dflag);
3355
3356 modrm = x86_ldub_code(env, s);
3357 mod = (modrm >> 6) & 3;
3358 rm = (modrm & 7) | REX_B(s);
3359 op = (modrm >> 3) & 7;
3360 if (mod != 3) {
3361 if (op == 0) {
3362 s->rip_offset = insn_const_size(ot);
3363 }
3364 gen_lea_modrm(env, s, modrm);
3365 /* For those below that handle locked memory, don't load here. */
3366 if (!(s->prefix & PREFIX_LOCK)
3367 || op != 2) {
3368 gen_op_ld_v(s, ot, s->T0, s->A0);
3369 }
3370 } else {
3371 gen_op_mov_v_reg(s, ot, s->T0, rm);
3372 }
3373
3374 switch(op) {
3375 case 0: /* test */
3376 val = insn_get(env, s, ot);
3377 tcg_gen_movi_tl(s->T1, val);
3378 gen_op_testl_T0_T1_cc(s);
3379 set_cc_op(s, CC_OP_LOGICB + ot);
3380 break;
3381 case 2: /* not */
3382 if (s->prefix & PREFIX_LOCK) {
3383 if (mod == 3) {
3384 goto illegal_op;
3385 }
3386 tcg_gen_movi_tl(s->T0, ~0);
3387 tcg_gen_atomic_xor_fetch_tl(s->T0, s->A0, s->T0,
3388 s->mem_index, ot | MO_LE);
3389 } else {
3390 tcg_gen_not_tl(s->T0, s->T0);
3391 if (mod != 3) {
3392 gen_op_st_v(s, ot, s->T0, s->A0);
3393 } else {
3394 gen_op_mov_reg_v(s, ot, rm, s->T0);
3395 }
3396 }
3397 break;
3398 case 3: /* neg */
3399 if (s->prefix & PREFIX_LOCK) {
3400 TCGLabel *label1;
3401 TCGv a0, t0, t1, t2;
3402
3403 if (mod == 3) {
3404 goto illegal_op;
3405 }
3406 a0 = s->A0;
3407 t0 = s->T0;
3408 label1 = gen_new_label();
3409
3410 gen_set_label(label1);
3411 t1 = tcg_temp_new();
3412 t2 = tcg_temp_new();
3413 tcg_gen_mov_tl(t2, t0);
3414 tcg_gen_neg_tl(t1, t0);
3415 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
3416 s->mem_index, ot | MO_LE);
3417 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
3418
3419 tcg_gen_neg_tl(s->T0, t0);
3420 } else {
3421 tcg_gen_neg_tl(s->T0, s->T0);
3422 if (mod != 3) {
3423 gen_op_st_v(s, ot, s->T0, s->A0);
3424 } else {
3425 gen_op_mov_reg_v(s, ot, rm, s->T0);
3426 }
3427 }
3428 gen_op_update_neg_cc(s);
3429 set_cc_op(s, CC_OP_SUBB + ot);
3430 break;
3431 case 4: /* mul */
3432 switch(ot) {
3433 case MO_8:
3434 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX);
3435 tcg_gen_ext8u_tl(s->T0, s->T0);
3436 tcg_gen_ext8u_tl(s->T1, s->T1);
3437 /* XXX: use 32 bit mul which could be faster */
3438 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3439 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3440 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3441 tcg_gen_andi_tl(cpu_cc_src, s->T0, 0xff00);
3442 set_cc_op(s, CC_OP_MULB);
3443 break;
3444 case MO_16:
3445 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX);
3446 tcg_gen_ext16u_tl(s->T0, s->T0);
3447 tcg_gen_ext16u_tl(s->T1, s->T1);
3448 /* XXX: use 32 bit mul which could be faster */
3449 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3450 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3451 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3452 tcg_gen_shri_tl(s->T0, s->T0, 16);
3453 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
3454 tcg_gen_mov_tl(cpu_cc_src, s->T0);
3455 set_cc_op(s, CC_OP_MULW);
3456 break;
3457 default:
3458 case MO_32:
3459 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3460 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]);
3461 tcg_gen_mulu2_i32(s->tmp2_i32, s->tmp3_i32,
3462 s->tmp2_i32, s->tmp3_i32);
3463 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32);
3464 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32);
3465 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
3466 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
3467 set_cc_op(s, CC_OP_MULL);
3468 break;
3469 #ifdef TARGET_X86_64
3470 case MO_64:
3471 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
3472 s->T0, cpu_regs[R_EAX]);
3473 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
3474 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
3475 set_cc_op(s, CC_OP_MULQ);
3476 break;
3477 #endif
3478 }
3479 break;
3480 case 5: /* imul */
3481 switch(ot) {
3482 case MO_8:
3483 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX);
3484 tcg_gen_ext8s_tl(s->T0, s->T0);
3485 tcg_gen_ext8s_tl(s->T1, s->T1);
3486 /* XXX: use 32 bit mul which could be faster */
3487 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3488 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3489 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3490 tcg_gen_ext8s_tl(s->tmp0, s->T0);
3491 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
3492 set_cc_op(s, CC_OP_MULB);
3493 break;
3494 case MO_16:
3495 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX);
3496 tcg_gen_ext16s_tl(s->T0, s->T0);
3497 tcg_gen_ext16s_tl(s->T1, s->T1);
3498 /* XXX: use 32 bit mul which could be faster */
3499 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3500 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3501 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3502 tcg_gen_ext16s_tl(s->tmp0, s->T0);
3503 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
3504 tcg_gen_shri_tl(s->T0, s->T0, 16);
3505 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
3506 set_cc_op(s, CC_OP_MULW);
3507 break;
3508 default:
3509 case MO_32:
3510 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3511 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]);
3512 tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32,
3513 s->tmp2_i32, s->tmp3_i32);
3514 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32);
3515 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32);
3516 tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31);
3517 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
3518 tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
3519 tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32);
3520 set_cc_op(s, CC_OP_MULL);
3521 break;
3522 #ifdef TARGET_X86_64
3523 case MO_64:
3524 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
3525 s->T0, cpu_regs[R_EAX]);
3526 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
3527 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
3528 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
3529 set_cc_op(s, CC_OP_MULQ);
3530 break;
3531 #endif
3532 }
3533 break;
3534 case 6: /* div */
3535 switch(ot) {
3536 case MO_8:
3537 gen_helper_divb_AL(tcg_env, s->T0);
3538 break;
3539 case MO_16:
3540 gen_helper_divw_AX(tcg_env, s->T0);
3541 break;
3542 default:
3543 case MO_32:
3544 gen_helper_divl_EAX(tcg_env, s->T0);
3545 break;
3546 #ifdef TARGET_X86_64
3547 case MO_64:
3548 gen_helper_divq_EAX(tcg_env, s->T0);
3549 break;
3550 #endif
3551 }
3552 break;
3553 case 7: /* idiv */
3554 switch(ot) {
3555 case MO_8:
3556 gen_helper_idivb_AL(tcg_env, s->T0);
3557 break;
3558 case MO_16:
3559 gen_helper_idivw_AX(tcg_env, s->T0);
3560 break;
3561 default:
3562 case MO_32:
3563 gen_helper_idivl_EAX(tcg_env, s->T0);
3564 break;
3565 #ifdef TARGET_X86_64
3566 case MO_64:
3567 gen_helper_idivq_EAX(tcg_env, s->T0);
3568 break;
3569 #endif
3570 }
3571 break;
3572 default:
3573 goto unknown_op;
3574 }
3575 break;
3576
3577 case 0xfe: /* GRP4 */
3578 case 0xff: /* GRP5 */
3579 ot = mo_b_d(b, dflag);
3580
3581 modrm = x86_ldub_code(env, s);
3582 mod = (modrm >> 6) & 3;
3583 rm = (modrm & 7) | REX_B(s);
3584 op = (modrm >> 3) & 7;
3585 if (op >= 2 && b == 0xfe) {
3586 goto unknown_op;
3587 }
3588 if (CODE64(s)) {
3589 if (op == 2 || op == 4) {
3590 /* operand size for jumps is 64 bit */
3591 ot = MO_64;
3592 } else if (op == 3 || op == 5) {
3593 ot = dflag != MO_16 ? MO_32 + REX_W(s) : MO_16;
3594 } else if (op == 6) {
3595 /* default push size is 64 bit */
3596 ot = mo_pushpop(s, dflag);
3597 }
3598 }
3599 if (mod != 3) {
3600 gen_lea_modrm(env, s, modrm);
3601 if (op >= 2 && op != 3 && op != 5)
3602 gen_op_ld_v(s, ot, s->T0, s->A0);
3603 } else {
3604 gen_op_mov_v_reg(s, ot, s->T0, rm);
3605 }
3606
3607 switch(op) {
3608 case 0: /* inc Ev */
3609 if (mod != 3)
3610 opreg = OR_TMP0;
3611 else
3612 opreg = rm;
3613 gen_inc(s, ot, opreg, 1);
3614 break;
3615 case 1: /* dec Ev */
3616 if (mod != 3)
3617 opreg = OR_TMP0;
3618 else
3619 opreg = rm;
3620 gen_inc(s, ot, opreg, -1);
3621 break;
3622 case 2: /* call Ev */
3623 /* XXX: optimize if memory (no 'and' is necessary) */
3624 if (dflag == MO_16) {
3625 tcg_gen_ext16u_tl(s->T0, s->T0);
3626 }
3627 gen_push_v(s, eip_next_tl(s));
3628 gen_op_jmp_v(s, s->T0);
3629 gen_bnd_jmp(s);
3630 s->base.is_jmp = DISAS_JUMP;
3631 break;
3632 case 3: /* lcall Ev */
3633 if (mod == 3) {
3634 goto illegal_op;
3635 }
3636 gen_op_ld_v(s, ot, s->T1, s->A0);
3637 gen_add_A0_im(s, 1 << ot);
3638 gen_op_ld_v(s, MO_16, s->T0, s->A0);
3639 do_lcall:
3640 if (PE(s) && !VM86(s)) {
3641 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3642 gen_helper_lcall_protected(tcg_env, s->tmp2_i32, s->T1,
3643 tcg_constant_i32(dflag - 1),
3644 eip_next_tl(s));
3645 } else {
3646 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3647 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
3648 gen_helper_lcall_real(tcg_env, s->tmp2_i32, s->tmp3_i32,
3649 tcg_constant_i32(dflag - 1),
3650 eip_next_i32(s));
3651 }
3652 s->base.is_jmp = DISAS_JUMP;
3653 break;
3654 case 4: /* jmp Ev */
3655 if (dflag == MO_16) {
3656 tcg_gen_ext16u_tl(s->T0, s->T0);
3657 }
3658 gen_op_jmp_v(s, s->T0);
3659 gen_bnd_jmp(s);
3660 s->base.is_jmp = DISAS_JUMP;
3661 break;
3662 case 5: /* ljmp Ev */
3663 if (mod == 3) {
3664 goto illegal_op;
3665 }
3666 gen_op_ld_v(s, ot, s->T1, s->A0);
3667 gen_add_A0_im(s, 1 << ot);
3668 gen_op_ld_v(s, MO_16, s->T0, s->A0);
3669 do_ljmp:
3670 if (PE(s) && !VM86(s)) {
3671 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3672 gen_helper_ljmp_protected(tcg_env, s->tmp2_i32, s->T1,
3673 eip_next_tl(s));
3674 } else {
3675 gen_op_movl_seg_T0_vm(s, R_CS);
3676 gen_op_jmp_v(s, s->T1);
3677 }
3678 s->base.is_jmp = DISAS_JUMP;
3679 break;
3680 case 6: /* push Ev */
3681 gen_push_v(s, s->T0);
3682 break;
3683 default:
3684 goto unknown_op;
3685 }
3686 break;
3687
3688 case 0x84: /* test Ev, Gv */
3689 case 0x85:
3690 ot = mo_b_d(b, dflag);
3691
3692 modrm = x86_ldub_code(env, s);
3693 reg = ((modrm >> 3) & 7) | REX_R(s);
3694
3695 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3696 gen_op_mov_v_reg(s, ot, s->T1, reg);
3697 gen_op_testl_T0_T1_cc(s);
3698 set_cc_op(s, CC_OP_LOGICB + ot);
3699 break;
3700
3701 case 0xa8: /* test eAX, Iv */
3702 case 0xa9:
3703 ot = mo_b_d(b, dflag);
3704 val = insn_get(env, s, ot);
3705
3706 gen_op_mov_v_reg(s, ot, s->T0, OR_EAX);
3707 tcg_gen_movi_tl(s->T1, val);
3708 gen_op_testl_T0_T1_cc(s);
3709 set_cc_op(s, CC_OP_LOGICB + ot);
3710 break;
3711
3712 case 0x98: /* CWDE/CBW */
3713 switch (dflag) {
3714 #ifdef TARGET_X86_64
3715 case MO_64:
3716 gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
3717 tcg_gen_ext32s_tl(s->T0, s->T0);
3718 gen_op_mov_reg_v(s, MO_64, R_EAX, s->T0);
3719 break;
3720 #endif
3721 case MO_32:
3722 gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX);
3723 tcg_gen_ext16s_tl(s->T0, s->T0);
3724 gen_op_mov_reg_v(s, MO_32, R_EAX, s->T0);
3725 break;
3726 case MO_16:
3727 gen_op_mov_v_reg(s, MO_8, s->T0, R_EAX);
3728 tcg_gen_ext8s_tl(s->T0, s->T0);
3729 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
3730 break;
3731 default:
3732 g_assert_not_reached();
3733 }
3734 break;
3735 case 0x99: /* CDQ/CWD */
3736 switch (dflag) {
3737 #ifdef TARGET_X86_64
3738 case MO_64:
3739 gen_op_mov_v_reg(s, MO_64, s->T0, R_EAX);
3740 tcg_gen_sari_tl(s->T0, s->T0, 63);
3741 gen_op_mov_reg_v(s, MO_64, R_EDX, s->T0);
3742 break;
3743 #endif
3744 case MO_32:
3745 gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
3746 tcg_gen_ext32s_tl(s->T0, s->T0);
3747 tcg_gen_sari_tl(s->T0, s->T0, 31);
3748 gen_op_mov_reg_v(s, MO_32, R_EDX, s->T0);
3749 break;
3750 case MO_16:
3751 gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX);
3752 tcg_gen_ext16s_tl(s->T0, s->T0);
3753 tcg_gen_sari_tl(s->T0, s->T0, 15);
3754 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
3755 break;
3756 default:
3757 g_assert_not_reached();
3758 }
3759 break;
3760 case 0x1af: /* imul Gv, Ev */
3761 case 0x69: /* imul Gv, Ev, I */
3762 case 0x6b:
3763 ot = dflag;
3764 modrm = x86_ldub_code(env, s);
3765 reg = ((modrm >> 3) & 7) | REX_R(s);
3766 if (b == 0x69)
3767 s->rip_offset = insn_const_size(ot);
3768 else if (b == 0x6b)
3769 s->rip_offset = 1;
3770 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3771 if (b == 0x69) {
3772 val = insn_get(env, s, ot);
3773 tcg_gen_movi_tl(s->T1, val);
3774 } else if (b == 0x6b) {
3775 val = (int8_t)insn_get(env, s, MO_8);
3776 tcg_gen_movi_tl(s->T1, val);
3777 } else {
3778 gen_op_mov_v_reg(s, ot, s->T1, reg);
3779 }
3780 switch (ot) {
3781 #ifdef TARGET_X86_64
3782 case MO_64:
3783 tcg_gen_muls2_i64(cpu_regs[reg], s->T1, s->T0, s->T1);
3784 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
3785 tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
3786 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, s->T1);
3787 break;
3788 #endif
3789 case MO_32:
3790 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3791 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
3792 tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32,
3793 s->tmp2_i32, s->tmp3_i32);
3794 tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
3795 tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31);
3796 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
3797 tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
3798 tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32);
3799 break;
3800 default:
3801 tcg_gen_ext16s_tl(s->T0, s->T0);
3802 tcg_gen_ext16s_tl(s->T1, s->T1);
3803 /* XXX: use 32 bit mul which could be faster */
3804 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
3805 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
3806 tcg_gen_ext16s_tl(s->tmp0, s->T0);
3807 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
3808 gen_op_mov_reg_v(s, ot, reg, s->T0);
3809 break;
3810 }
3811 set_cc_op(s, CC_OP_MULB + ot);
3812 break;
3813 case 0x1c0:
3814 case 0x1c1: /* xadd Ev, Gv */
3815 ot = mo_b_d(b, dflag);
3816 modrm = x86_ldub_code(env, s);
3817 reg = ((modrm >> 3) & 7) | REX_R(s);
3818 mod = (modrm >> 6) & 3;
3819 gen_op_mov_v_reg(s, ot, s->T0, reg);
3820 if (mod == 3) {
3821 rm = (modrm & 7) | REX_B(s);
3822 gen_op_mov_v_reg(s, ot, s->T1, rm);
3823 tcg_gen_add_tl(s->T0, s->T0, s->T1);
3824 gen_op_mov_reg_v(s, ot, reg, s->T1);
3825 gen_op_mov_reg_v(s, ot, rm, s->T0);
3826 } else {
3827 gen_lea_modrm(env, s, modrm);
3828 if (s->prefix & PREFIX_LOCK) {
3829 tcg_gen_atomic_fetch_add_tl(s->T1, s->A0, s->T0,
3830 s->mem_index, ot | MO_LE);
3831 tcg_gen_add_tl(s->T0, s->T0, s->T1);
3832 } else {
3833 gen_op_ld_v(s, ot, s->T1, s->A0);
3834 tcg_gen_add_tl(s->T0, s->T0, s->T1);
3835 gen_op_st_v(s, ot, s->T0, s->A0);
3836 }
3837 gen_op_mov_reg_v(s, ot, reg, s->T1);
3838 }
3839 gen_op_update2_cc(s);
3840 set_cc_op(s, CC_OP_ADDB + ot);
3841 break;
3842 case 0x1b0:
3843 case 0x1b1: /* cmpxchg Ev, Gv */
3844 {
3845 TCGv oldv, newv, cmpv, dest;
3846
3847 ot = mo_b_d(b, dflag);
3848 modrm = x86_ldub_code(env, s);
3849 reg = ((modrm >> 3) & 7) | REX_R(s);
3850 mod = (modrm >> 6) & 3;
3851 oldv = tcg_temp_new();
3852 newv = tcg_temp_new();
3853 cmpv = tcg_temp_new();
3854 gen_op_mov_v_reg(s, ot, newv, reg);
3855 tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]);
3856 gen_extu(ot, cmpv);
3857 if (s->prefix & PREFIX_LOCK) {
3858 if (mod == 3) {
3859 goto illegal_op;
3860 }
3861 gen_lea_modrm(env, s, modrm);
3862 tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, cmpv, newv,
3863 s->mem_index, ot | MO_LE);
3864 } else {
3865 if (mod == 3) {
3866 rm = (modrm & 7) | REX_B(s);
3867 gen_op_mov_v_reg(s, ot, oldv, rm);
3868 gen_extu(ot, oldv);
3869
3870 /*
3871 * Unlike the memory case, where "the destination operand receives
3872 * a write cycle without regard to the result of the comparison",
3873 * rm must not be touched altogether if the write fails, including
3874 * not zero-extending it on 64-bit processors. So, precompute
3875 * the result of a successful writeback and perform the movcond
3876 * directly on cpu_regs. Also need to write accumulator first, in
3877 * case rm is part of RAX too.
3878 */
3879 dest = gen_op_deposit_reg_v(s, ot, rm, newv, newv);
3880 tcg_gen_movcond_tl(TCG_COND_EQ, dest, oldv, cmpv, newv, dest);
3881 } else {
3882 gen_lea_modrm(env, s, modrm);
3883 gen_op_ld_v(s, ot, oldv, s->A0);
3884
3885 /*
3886 * Perform an unconditional store cycle like physical cpu;
3887 * must be before changing accumulator to ensure
3888 * idempotency if the store faults and the instruction
3889 * is restarted
3890 */
3891 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv);
3892 gen_op_st_v(s, ot, newv, s->A0);
3893 }
3894 }
3895 /*
3896 * Write EAX only if the cmpxchg fails; reuse newv as the destination,
3897 * since it's dead here.
3898 */
3899 dest = gen_op_deposit_reg_v(s, ot, R_EAX, newv, oldv);
3900 tcg_gen_movcond_tl(TCG_COND_EQ, dest, oldv, cmpv, dest, newv);
3901 tcg_gen_mov_tl(cpu_cc_src, oldv);
3902 tcg_gen_mov_tl(s->cc_srcT, cmpv);
3903 tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv);
3904 set_cc_op(s, CC_OP_SUBB + ot);
3905 }
3906 break;
3907 case 0x1c7: /* cmpxchg8b */
3908 modrm = x86_ldub_code(env, s);
3909 mod = (modrm >> 6) & 3;
3910 switch ((modrm >> 3) & 7) {
3911 case 1: /* CMPXCHG8, CMPXCHG16 */
3912 if (mod == 3) {
3913 goto illegal_op;
3914 }
3915 #ifdef TARGET_X86_64
3916 if (dflag == MO_64) {
3917 if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) {
3918 goto illegal_op;
3919 }
3920 gen_cmpxchg16b(s, env, modrm);
3921 break;
3922 }
3923 #endif
3924 if (!(s->cpuid_features & CPUID_CX8)) {
3925 goto illegal_op;
3926 }
3927 gen_cmpxchg8b(s, env, modrm);
3928 break;
3929
3930 case 7: /* RDSEED, RDPID with f3 prefix */
3931 if (mod != 3 ||
3932 (s->prefix & (PREFIX_LOCK | PREFIX_REPNZ))) {
3933 goto illegal_op;
3934 }
3935 if (s->prefix & PREFIX_REPZ) {
3936 if (!(s->cpuid_ext_features & CPUID_7_0_ECX_RDPID)) {
3937 goto illegal_op;
3938 }
3939 gen_helper_rdpid(s->T0, tcg_env);
3940 rm = (modrm & 7) | REX_B(s);
3941 gen_op_mov_reg_v(s, dflag, rm, s->T0);
3942 break;
3943 } else {
3944 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_RDSEED)) {
3945 goto illegal_op;
3946 }
3947 goto do_rdrand;
3948 }
3949
3950 case 6: /* RDRAND */
3951 if (mod != 3 ||
3952 (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) ||
3953 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) {
3954 goto illegal_op;
3955 }
3956 do_rdrand:
3957 translator_io_start(&s->base);
3958 gen_helper_rdrand(s->T0, tcg_env);
3959 rm = (modrm & 7) | REX_B(s);
3960 gen_op_mov_reg_v(s, dflag, rm, s->T0);
3961 set_cc_op(s, CC_OP_EFLAGS);
3962 break;
3963
3964 default:
3965 goto illegal_op;
3966 }
3967 break;
3968
3969 /**************************/
3970 /* push/pop */
3971 case 0x50 ... 0x57: /* push */
3972 gen_op_mov_v_reg(s, MO_32, s->T0, (b & 7) | REX_B(s));
3973 gen_push_v(s, s->T0);
3974 break;
3975 case 0x58 ... 0x5f: /* pop */
3976 ot = gen_pop_T0(s);
3977 /* NOTE: order is important for pop %sp */
3978 gen_pop_update(s, ot);
3979 gen_op_mov_reg_v(s, ot, (b & 7) | REX_B(s), s->T0);
3980 break;
3981 case 0x60: /* pusha */
3982 if (CODE64(s))
3983 goto illegal_op;
3984 gen_pusha(s);
3985 break;
3986 case 0x61: /* popa */
3987 if (CODE64(s))
3988 goto illegal_op;
3989 gen_popa(s);
3990 break;
3991 case 0x68: /* push Iv */
3992 case 0x6a:
3993 ot = mo_pushpop(s, dflag);
3994 if (b == 0x68)
3995 val = insn_get(env, s, ot);
3996 else
3997 val = (int8_t)insn_get(env, s, MO_8);
3998 tcg_gen_movi_tl(s->T0, val);
3999 gen_push_v(s, s->T0);
4000 break;
4001 case 0x8f: /* pop Ev */
4002 modrm = x86_ldub_code(env, s);
4003 mod = (modrm >> 6) & 3;
4004 ot = gen_pop_T0(s);
4005 if (mod == 3) {
4006 /* NOTE: order is important for pop %sp */
4007 gen_pop_update(s, ot);
4008 rm = (modrm & 7) | REX_B(s);
4009 gen_op_mov_reg_v(s, ot, rm, s->T0);
4010 } else {
4011 /* NOTE: order is important too for MMU exceptions */
4012 s->popl_esp_hack = 1 << ot;
4013 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
4014 s->popl_esp_hack = 0;
4015 gen_pop_update(s, ot);
4016 }
4017 break;
4018 case 0xc8: /* enter */
4019 {
4020 int level;
4021 val = x86_lduw_code(env, s);
4022 level = x86_ldub_code(env, s);
4023 gen_enter(s, val, level);
4024 }
4025 break;
4026 case 0xc9: /* leave */
4027 gen_leave(s);
4028 break;
4029 case 0x06: /* push es */
4030 case 0x0e: /* push cs */
4031 case 0x16: /* push ss */
4032 case 0x1e: /* push ds */
4033 if (CODE64(s))
4034 goto illegal_op;
4035 gen_op_movl_T0_seg(s, b >> 3);
4036 gen_push_v(s, s->T0);
4037 break;
4038 case 0x1a0: /* push fs */
4039 case 0x1a8: /* push gs */
4040 gen_op_movl_T0_seg(s, (b >> 3) & 7);
4041 gen_push_v(s, s->T0);
4042 break;
4043 case 0x07: /* pop es */
4044 case 0x17: /* pop ss */
4045 case 0x1f: /* pop ds */
4046 if (CODE64(s))
4047 goto illegal_op;
4048 reg = b >> 3;
4049 ot = gen_pop_T0(s);
4050 gen_movl_seg_T0(s, reg);
4051 gen_pop_update(s, ot);
4052 break;
4053 case 0x1a1: /* pop fs */
4054 case 0x1a9: /* pop gs */
4055 ot = gen_pop_T0(s);
4056 gen_movl_seg_T0(s, (b >> 3) & 7);
4057 gen_pop_update(s, ot);
4058 break;
4059
4060 /**************************/
4061 /* mov */
4062 case 0x88:
4063 case 0x89: /* mov Gv, Ev */
4064 ot = mo_b_d(b, dflag);
4065 modrm = x86_ldub_code(env, s);
4066 reg = ((modrm >> 3) & 7) | REX_R(s);
4067
4068 /* generate a generic store */
4069 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
4070 break;
4071 case 0xc6:
4072 case 0xc7: /* mov Ev, Iv */
4073 ot = mo_b_d(b, dflag);
4074 modrm = x86_ldub_code(env, s);
4075 mod = (modrm >> 6) & 3;
4076 if (mod != 3) {
4077 s->rip_offset = insn_const_size(ot);
4078 gen_lea_modrm(env, s, modrm);
4079 }
4080 val = insn_get(env, s, ot);
4081 tcg_gen_movi_tl(s->T0, val);
4082 if (mod != 3) {
4083 gen_op_st_v(s, ot, s->T0, s->A0);
4084 } else {
4085 gen_op_mov_reg_v(s, ot, (modrm & 7) | REX_B(s), s->T0);
4086 }
4087 break;
4088 case 0x8a:
4089 case 0x8b: /* mov Ev, Gv */
4090 ot = mo_b_d(b, dflag);
4091 modrm = x86_ldub_code(env, s);
4092 reg = ((modrm >> 3) & 7) | REX_R(s);
4093
4094 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4095 gen_op_mov_reg_v(s, ot, reg, s->T0);
4096 break;
4097 case 0x8e: /* mov seg, Gv */
4098 modrm = x86_ldub_code(env, s);
4099 reg = (modrm >> 3) & 7;
4100 if (reg >= 6 || reg == R_CS)
4101 goto illegal_op;
4102 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
4103 gen_movl_seg_T0(s, reg);
4104 break;
4105 case 0x8c: /* mov Gv, seg */
4106 modrm = x86_ldub_code(env, s);
4107 reg = (modrm >> 3) & 7;
4108 mod = (modrm >> 6) & 3;
4109 if (reg >= 6)
4110 goto illegal_op;
4111 gen_op_movl_T0_seg(s, reg);
4112 ot = mod == 3 ? dflag : MO_16;
4113 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
4114 break;
4115
4116 case 0x1b6: /* movzbS Gv, Eb */
4117 case 0x1b7: /* movzwS Gv, Eb */
4118 case 0x1be: /* movsbS Gv, Eb */
4119 case 0x1bf: /* movswS Gv, Eb */
4120 {
4121 MemOp d_ot;
4122 MemOp s_ot;
4123
4124 /* d_ot is the size of destination */
4125 d_ot = dflag;
4126 /* ot is the size of source */
4127 ot = (b & 1) + MO_8;
4128 /* s_ot is the sign+size of source */
4129 s_ot = b & 8 ? MO_SIGN | ot : ot;
4130
4131 modrm = x86_ldub_code(env, s);
4132 reg = ((modrm >> 3) & 7) | REX_R(s);
4133 mod = (modrm >> 6) & 3;
4134 rm = (modrm & 7) | REX_B(s);
4135
4136 if (mod == 3) {
4137 if (s_ot == MO_SB && byte_reg_is_xH(s, rm)) {
4138 tcg_gen_sextract_tl(s->T0, cpu_regs[rm - 4], 8, 8);
4139 } else {
4140 gen_op_mov_v_reg(s, ot, s->T0, rm);
4141 switch (s_ot) {
4142 case MO_UB:
4143 tcg_gen_ext8u_tl(s->T0, s->T0);
4144 break;
4145 case MO_SB:
4146 tcg_gen_ext8s_tl(s->T0, s->T0);
4147 break;
4148 case MO_UW:
4149 tcg_gen_ext16u_tl(s->T0, s->T0);
4150 break;
4151 default:
4152 case MO_SW:
4153 tcg_gen_ext16s_tl(s->T0, s->T0);
4154 break;
4155 }
4156 }
4157 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
4158 } else {
4159 gen_lea_modrm(env, s, modrm);
4160 gen_op_ld_v(s, s_ot, s->T0, s->A0);
4161 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
4162 }
4163 }
4164 break;
4165
4166 case 0x8d: /* lea */
4167 modrm = x86_ldub_code(env, s);
4168 mod = (modrm >> 6) & 3;
4169 if (mod == 3)
4170 goto illegal_op;
4171 reg = ((modrm >> 3) & 7) | REX_R(s);
4172 {
4173 AddressParts a = gen_lea_modrm_0(env, s, modrm);
4174 TCGv ea = gen_lea_modrm_1(s, a, false);
4175 gen_lea_v_seg(s, s->aflag, ea, -1, -1);
4176 gen_op_mov_reg_v(s, dflag, reg, s->A0);
4177 }
4178 break;
4179
4180 case 0xa0: /* mov EAX, Ov */
4181 case 0xa1:
4182 case 0xa2: /* mov Ov, EAX */
4183 case 0xa3:
4184 {
4185 target_ulong offset_addr;
4186
4187 ot = mo_b_d(b, dflag);
4188 offset_addr = insn_get_addr(env, s, s->aflag);
4189 tcg_gen_movi_tl(s->A0, offset_addr);
4190 gen_add_A0_ds_seg(s);
4191 if ((b & 2) == 0) {
4192 gen_op_ld_v(s, ot, s->T0, s->A0);
4193 gen_op_mov_reg_v(s, ot, R_EAX, s->T0);
4194 } else {
4195 gen_op_mov_v_reg(s, ot, s->T0, R_EAX);
4196 gen_op_st_v(s, ot, s->T0, s->A0);
4197 }
4198 }
4199 break;
4200 case 0xd7: /* xlat */
4201 tcg_gen_mov_tl(s->A0, cpu_regs[R_EBX]);
4202 tcg_gen_ext8u_tl(s->T0, cpu_regs[R_EAX]);
4203 tcg_gen_add_tl(s->A0, s->A0, s->T0);
4204 gen_add_A0_ds_seg(s);
4205 gen_op_ld_v(s, MO_8, s->T0, s->A0);
4206 gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0);
4207 break;
4208 case 0xb0 ... 0xb7: /* mov R, Ib */
4209 val = insn_get(env, s, MO_8);
4210 tcg_gen_movi_tl(s->T0, val);
4211 gen_op_mov_reg_v(s, MO_8, (b & 7) | REX_B(s), s->T0);
4212 break;
4213 case 0xb8 ... 0xbf: /* mov R, Iv */
4214 #ifdef TARGET_X86_64
4215 if (dflag == MO_64) {
4216 uint64_t tmp;
4217 /* 64 bit case */
4218 tmp = x86_ldq_code(env, s);
4219 reg = (b & 7) | REX_B(s);
4220 tcg_gen_movi_tl(s->T0, tmp);
4221 gen_op_mov_reg_v(s, MO_64, reg, s->T0);
4222 } else
4223 #endif
4224 {
4225 ot = dflag;
4226 val = insn_get(env, s, ot);
4227 reg = (b & 7) | REX_B(s);
4228 tcg_gen_movi_tl(s->T0, val);
4229 gen_op_mov_reg_v(s, ot, reg, s->T0);
4230 }
4231 break;
4232
4233 case 0x91 ... 0x97: /* xchg R, EAX */
4234 do_xchg_reg_eax:
4235 ot = dflag;
4236 reg = (b & 7) | REX_B(s);
4237 rm = R_EAX;
4238 goto do_xchg_reg;
4239 case 0x86:
4240 case 0x87: /* xchg Ev, Gv */
4241 ot = mo_b_d(b, dflag);
4242 modrm = x86_ldub_code(env, s);
4243 reg = ((modrm >> 3) & 7) | REX_R(s);
4244 mod = (modrm >> 6) & 3;
4245 if (mod == 3) {
4246 rm = (modrm & 7) | REX_B(s);
4247 do_xchg_reg:
4248 gen_op_mov_v_reg(s, ot, s->T0, reg);
4249 gen_op_mov_v_reg(s, ot, s->T1, rm);
4250 gen_op_mov_reg_v(s, ot, rm, s->T0);
4251 gen_op_mov_reg_v(s, ot, reg, s->T1);
4252 } else {
4253 gen_lea_modrm(env, s, modrm);
4254 gen_op_mov_v_reg(s, ot, s->T0, reg);
4255 /* for xchg, lock is implicit */
4256 tcg_gen_atomic_xchg_tl(s->T1, s->A0, s->T0,
4257 s->mem_index, ot | MO_LE);
4258 gen_op_mov_reg_v(s, ot, reg, s->T1);
4259 }
4260 break;
4261 case 0xc4: /* les Gv */
4262 /* In CODE64 this is VEX3; see above. */
4263 op = R_ES;
4264 goto do_lxx;
4265 case 0xc5: /* lds Gv */
4266 /* In CODE64 this is VEX2; see above. */
4267 op = R_DS;
4268 goto do_lxx;
4269 case 0x1b2: /* lss Gv */
4270 op = R_SS;
4271 goto do_lxx;
4272 case 0x1b4: /* lfs Gv */
4273 op = R_FS;
4274 goto do_lxx;
4275 case 0x1b5: /* lgs Gv */
4276 op = R_GS;
4277 do_lxx:
4278 ot = dflag != MO_16 ? MO_32 : MO_16;
4279 modrm = x86_ldub_code(env, s);
4280 reg = ((modrm >> 3) & 7) | REX_R(s);
4281 mod = (modrm >> 6) & 3;
4282 if (mod == 3)
4283 goto illegal_op;
4284 gen_lea_modrm(env, s, modrm);
4285 gen_op_ld_v(s, ot, s->T1, s->A0);
4286 gen_add_A0_im(s, 1 << ot);
4287 /* load the segment first to handle exceptions properly */
4288 gen_op_ld_v(s, MO_16, s->T0, s->A0);
4289 gen_movl_seg_T0(s, op);
4290 /* then put the data */
4291 gen_op_mov_reg_v(s, ot, reg, s->T1);
4292 break;
4293
4294 /************************/
4295 /* shifts */
4296 case 0xc0:
4297 case 0xc1:
4298 /* shift Ev,Ib */
4299 shift = 2;
4300 grp2:
4301 {
4302 ot = mo_b_d(b, dflag);
4303 modrm = x86_ldub_code(env, s);
4304 mod = (modrm >> 6) & 3;
4305 op = (modrm >> 3) & 7;
4306
4307 if (mod != 3) {
4308 if (shift == 2) {
4309 s->rip_offset = 1;
4310 }
4311 gen_lea_modrm(env, s, modrm);
4312 opreg = OR_TMP0;
4313 } else {
4314 opreg = (modrm & 7) | REX_B(s);
4315 }
4316
4317 /* simpler op */
4318 if (shift == 0) {
4319 gen_shift(s, op, ot, opreg, OR_ECX);
4320 } else {
4321 if (shift == 2) {
4322 shift = x86_ldub_code(env, s);
4323 }
4324 gen_shifti(s, op, ot, opreg, shift);
4325 }
4326 }
4327 break;
4328 case 0xd0:
4329 case 0xd1:
4330 /* shift Ev,1 */
4331 shift = 1;
4332 goto grp2;
4333 case 0xd2:
4334 case 0xd3:
4335 /* shift Ev,cl */
4336 shift = 0;
4337 goto grp2;
4338
4339 case 0x1a4: /* shld imm */
4340 op = 0;
4341 shift = 1;
4342 goto do_shiftd;
4343 case 0x1a5: /* shld cl */
4344 op = 0;
4345 shift = 0;
4346 goto do_shiftd;
4347 case 0x1ac: /* shrd imm */
4348 op = 1;
4349 shift = 1;
4350 goto do_shiftd;
4351 case 0x1ad: /* shrd cl */
4352 op = 1;
4353 shift = 0;
4354 do_shiftd:
4355 ot = dflag;
4356 modrm = x86_ldub_code(env, s);
4357 mod = (modrm >> 6) & 3;
4358 rm = (modrm & 7) | REX_B(s);
4359 reg = ((modrm >> 3) & 7) | REX_R(s);
4360 if (mod != 3) {
4361 gen_lea_modrm(env, s, modrm);
4362 opreg = OR_TMP0;
4363 } else {
4364 opreg = rm;
4365 }
4366 gen_op_mov_v_reg(s, ot, s->T1, reg);
4367
4368 if (shift) {
4369 TCGv imm = tcg_constant_tl(x86_ldub_code(env, s));
4370 gen_shiftd_rm_T1(s, ot, opreg, op, imm);
4371 } else {
4372 gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
4373 }
4374 break;
4375
4376 /************************/
4377 /* floats */
4378 case 0xd8 ... 0xdf:
4379 {
4380 bool update_fip = true;
4381
4382 if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
4383 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
4384 /* XXX: what to do if illegal op ? */
4385 gen_exception(s, EXCP07_PREX);
4386 break;
4387 }
4388 modrm = x86_ldub_code(env, s);
4389 mod = (modrm >> 6) & 3;
4390 rm = modrm & 7;
4391 op = ((b & 7) << 3) | ((modrm >> 3) & 7);
4392 if (mod != 3) {
4393 /* memory op */
4394 AddressParts a = gen_lea_modrm_0(env, s, modrm);
4395 TCGv ea = gen_lea_modrm_1(s, a, false);
4396 TCGv last_addr = tcg_temp_new();
4397 bool update_fdp = true;
4398
4399 tcg_gen_mov_tl(last_addr, ea);
4400 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
4401
4402 switch (op) {
4403 case 0x00 ... 0x07: /* fxxxs */
4404 case 0x10 ... 0x17: /* fixxxl */
4405 case 0x20 ... 0x27: /* fxxxl */
4406 case 0x30 ... 0x37: /* fixxx */
4407 {
4408 int op1;
4409 op1 = op & 7;
4410
4411 switch (op >> 4) {
4412 case 0:
4413 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4414 s->mem_index, MO_LEUL);
4415 gen_helper_flds_FT0(tcg_env, s->tmp2_i32);
4416 break;
4417 case 1:
4418 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4419 s->mem_index, MO_LEUL);
4420 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32);
4421 break;
4422 case 2:
4423 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4424 s->mem_index, MO_LEUQ);
4425 gen_helper_fldl_FT0(tcg_env, s->tmp1_i64);
4426 break;
4427 case 3:
4428 default:
4429 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4430 s->mem_index, MO_LESW);
4431 gen_helper_fildl_FT0(tcg_env, s->tmp2_i32);
4432 break;
4433 }
4434
4435 gen_helper_fp_arith_ST0_FT0(op1);
4436 if (op1 == 3) {
4437 /* fcomp needs pop */
4438 gen_helper_fpop(tcg_env);
4439 }
4440 }
4441 break;
4442 case 0x08: /* flds */
4443 case 0x0a: /* fsts */
4444 case 0x0b: /* fstps */
4445 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
4446 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
4447 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
4448 switch (op & 7) {
4449 case 0:
4450 switch (op >> 4) {
4451 case 0:
4452 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4453 s->mem_index, MO_LEUL);
4454 gen_helper_flds_ST0(tcg_env, s->tmp2_i32);
4455 break;
4456 case 1:
4457 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4458 s->mem_index, MO_LEUL);
4459 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32);
4460 break;
4461 case 2:
4462 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4463 s->mem_index, MO_LEUQ);
4464 gen_helper_fldl_ST0(tcg_env, s->tmp1_i64);
4465 break;
4466 case 3:
4467 default:
4468 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4469 s->mem_index, MO_LESW);
4470 gen_helper_fildl_ST0(tcg_env, s->tmp2_i32);
4471 break;
4472 }
4473 break;
4474 case 1:
4475 /* XXX: the corresponding CPUID bit must be tested ! */
4476 switch (op >> 4) {
4477 case 1:
4478 gen_helper_fisttl_ST0(s->tmp2_i32, tcg_env);
4479 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4480 s->mem_index, MO_LEUL);
4481 break;
4482 case 2:
4483 gen_helper_fisttll_ST0(s->tmp1_i64, tcg_env);
4484 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4485 s->mem_index, MO_LEUQ);
4486 break;
4487 case 3:
4488 default:
4489 gen_helper_fistt_ST0(s->tmp2_i32, tcg_env);
4490 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4491 s->mem_index, MO_LEUW);
4492 break;
4493 }
4494 gen_helper_fpop(tcg_env);
4495 break;
4496 default:
4497 switch (op >> 4) {
4498 case 0:
4499 gen_helper_fsts_ST0(s->tmp2_i32, tcg_env);
4500 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4501 s->mem_index, MO_LEUL);
4502 break;
4503 case 1:
4504 gen_helper_fistl_ST0(s->tmp2_i32, tcg_env);
4505 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4506 s->mem_index, MO_LEUL);
4507 break;
4508 case 2:
4509 gen_helper_fstl_ST0(s->tmp1_i64, tcg_env);
4510 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4511 s->mem_index, MO_LEUQ);
4512 break;
4513 case 3:
4514 default:
4515 gen_helper_fist_ST0(s->tmp2_i32, tcg_env);
4516 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4517 s->mem_index, MO_LEUW);
4518 break;
4519 }
4520 if ((op & 7) == 3) {
4521 gen_helper_fpop(tcg_env);
4522 }
4523 break;
4524 }
4525 break;
4526 case 0x0c: /* fldenv mem */
4527 gen_helper_fldenv(tcg_env, s->A0,
4528 tcg_constant_i32(dflag - 1));
4529 update_fip = update_fdp = false;
4530 break;
4531 case 0x0d: /* fldcw mem */
4532 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4533 s->mem_index, MO_LEUW);
4534 gen_helper_fldcw(tcg_env, s->tmp2_i32);
4535 update_fip = update_fdp = false;
4536 break;
4537 case 0x0e: /* fnstenv mem */
4538 gen_helper_fstenv(tcg_env, s->A0,
4539 tcg_constant_i32(dflag - 1));
4540 update_fip = update_fdp = false;
4541 break;
4542 case 0x0f: /* fnstcw mem */
4543 gen_helper_fnstcw(s->tmp2_i32, tcg_env);
4544 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4545 s->mem_index, MO_LEUW);
4546 update_fip = update_fdp = false;
4547 break;
4548 case 0x1d: /* fldt mem */
4549 gen_helper_fldt_ST0(tcg_env, s->A0);
4550 break;
4551 case 0x1f: /* fstpt mem */
4552 gen_helper_fstt_ST0(tcg_env, s->A0);
4553 gen_helper_fpop(tcg_env);
4554 break;
4555 case 0x2c: /* frstor mem */
4556 gen_helper_frstor(tcg_env, s->A0,
4557 tcg_constant_i32(dflag - 1));
4558 update_fip = update_fdp = false;
4559 break;
4560 case 0x2e: /* fnsave mem */
4561 gen_helper_fsave(tcg_env, s->A0,
4562 tcg_constant_i32(dflag - 1));
4563 update_fip = update_fdp = false;
4564 break;
4565 case 0x2f: /* fnstsw mem */
4566 gen_helper_fnstsw(s->tmp2_i32, tcg_env);
4567 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4568 s->mem_index, MO_LEUW);
4569 update_fip = update_fdp = false;
4570 break;
4571 case 0x3c: /* fbld */
4572 gen_helper_fbld_ST0(tcg_env, s->A0);
4573 break;
4574 case 0x3e: /* fbstp */
4575 gen_helper_fbst_ST0(tcg_env, s->A0);
4576 gen_helper_fpop(tcg_env);
4577 break;
4578 case 0x3d: /* fildll */
4579 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4580 s->mem_index, MO_LEUQ);
4581 gen_helper_fildll_ST0(tcg_env, s->tmp1_i64);
4582 break;
4583 case 0x3f: /* fistpll */
4584 gen_helper_fistll_ST0(s->tmp1_i64, tcg_env);
4585 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4586 s->mem_index, MO_LEUQ);
4587 gen_helper_fpop(tcg_env);
4588 break;
4589 default:
4590 goto unknown_op;
4591 }
4592
4593 if (update_fdp) {
4594 int last_seg = s->override >= 0 ? s->override : a.def_seg;
4595
4596 tcg_gen_ld_i32(s->tmp2_i32, tcg_env,
4597 offsetof(CPUX86State,
4598 segs[last_seg].selector));
4599 tcg_gen_st16_i32(s->tmp2_i32, tcg_env,
4600 offsetof(CPUX86State, fpds));
4601 tcg_gen_st_tl(last_addr, tcg_env,
4602 offsetof(CPUX86State, fpdp));
4603 }
4604 } else {
4605 /* register float ops */
4606 opreg = rm;
4607
4608 switch (op) {
4609 case 0x08: /* fld sti */
4610 gen_helper_fpush(tcg_env);
4611 gen_helper_fmov_ST0_STN(tcg_env,
4612 tcg_constant_i32((opreg + 1) & 7));
4613 break;
4614 case 0x09: /* fxchg sti */
4615 case 0x29: /* fxchg4 sti, undocumented op */
4616 case 0x39: /* fxchg7 sti, undocumented op */
4617 gen_helper_fxchg_ST0_STN(tcg_env, tcg_constant_i32(opreg));
4618 break;
4619 case 0x0a: /* grp d9/2 */
4620 switch (rm) {
4621 case 0: /* fnop */
4622 /*
4623 * check exceptions (FreeBSD FPU probe)
4624 * needs to be treated as I/O because of ferr_irq
4625 */
4626 translator_io_start(&s->base);
4627 gen_helper_fwait(tcg_env);
4628 update_fip = false;
4629 break;
4630 default:
4631 goto unknown_op;
4632 }
4633 break;
4634 case 0x0c: /* grp d9/4 */
4635 switch (rm) {
4636 case 0: /* fchs */
4637 gen_helper_fchs_ST0(tcg_env);
4638 break;
4639 case 1: /* fabs */
4640 gen_helper_fabs_ST0(tcg_env);
4641 break;
4642 case 4: /* ftst */
4643 gen_helper_fldz_FT0(tcg_env);
4644 gen_helper_fcom_ST0_FT0(tcg_env);
4645 break;
4646 case 5: /* fxam */
4647 gen_helper_fxam_ST0(tcg_env);
4648 break;
4649 default:
4650 goto unknown_op;
4651 }
4652 break;
4653 case 0x0d: /* grp d9/5 */
4654 {
4655 switch (rm) {
4656 case 0:
4657 gen_helper_fpush(tcg_env);
4658 gen_helper_fld1_ST0(tcg_env);
4659 break;
4660 case 1:
4661 gen_helper_fpush(tcg_env);
4662 gen_helper_fldl2t_ST0(tcg_env);
4663 break;
4664 case 2:
4665 gen_helper_fpush(tcg_env);
4666 gen_helper_fldl2e_ST0(tcg_env);
4667 break;
4668 case 3:
4669 gen_helper_fpush(tcg_env);
4670 gen_helper_fldpi_ST0(tcg_env);
4671 break;
4672 case 4:
4673 gen_helper_fpush(tcg_env);
4674 gen_helper_fldlg2_ST0(tcg_env);
4675 break;
4676 case 5:
4677 gen_helper_fpush(tcg_env);
4678 gen_helper_fldln2_ST0(tcg_env);
4679 break;
4680 case 6:
4681 gen_helper_fpush(tcg_env);
4682 gen_helper_fldz_ST0(tcg_env);
4683 break;
4684 default:
4685 goto unknown_op;
4686 }
4687 }
4688 break;
4689 case 0x0e: /* grp d9/6 */
4690 switch (rm) {
4691 case 0: /* f2xm1 */
4692 gen_helper_f2xm1(tcg_env);
4693 break;
4694 case 1: /* fyl2x */
4695 gen_helper_fyl2x(tcg_env);
4696 break;
4697 case 2: /* fptan */
4698 gen_helper_fptan(tcg_env);
4699 break;
4700 case 3: /* fpatan */
4701 gen_helper_fpatan(tcg_env);
4702 break;
4703 case 4: /* fxtract */
4704 gen_helper_fxtract(tcg_env);
4705 break;
4706 case 5: /* fprem1 */
4707 gen_helper_fprem1(tcg_env);
4708 break;
4709 case 6: /* fdecstp */
4710 gen_helper_fdecstp(tcg_env);
4711 break;
4712 default:
4713 case 7: /* fincstp */
4714 gen_helper_fincstp(tcg_env);
4715 break;
4716 }
4717 break;
4718 case 0x0f: /* grp d9/7 */
4719 switch (rm) {
4720 case 0: /* fprem */
4721 gen_helper_fprem(tcg_env);
4722 break;
4723 case 1: /* fyl2xp1 */
4724 gen_helper_fyl2xp1(tcg_env);
4725 break;
4726 case 2: /* fsqrt */
4727 gen_helper_fsqrt(tcg_env);
4728 break;
4729 case 3: /* fsincos */
4730 gen_helper_fsincos(tcg_env);
4731 break;
4732 case 5: /* fscale */
4733 gen_helper_fscale(tcg_env);
4734 break;
4735 case 4: /* frndint */
4736 gen_helper_frndint(tcg_env);
4737 break;
4738 case 6: /* fsin */
4739 gen_helper_fsin(tcg_env);
4740 break;
4741 default:
4742 case 7: /* fcos */
4743 gen_helper_fcos(tcg_env);
4744 break;
4745 }
4746 break;
4747 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
4748 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
4749 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
4750 {
4751 int op1;
4752
4753 op1 = op & 7;
4754 if (op >= 0x20) {
4755 gen_helper_fp_arith_STN_ST0(op1, opreg);
4756 if (op >= 0x30) {
4757 gen_helper_fpop(tcg_env);
4758 }
4759 } else {
4760 gen_helper_fmov_FT0_STN(tcg_env,
4761 tcg_constant_i32(opreg));
4762 gen_helper_fp_arith_ST0_FT0(op1);
4763 }
4764 }
4765 break;
4766 case 0x02: /* fcom */
4767 case 0x22: /* fcom2, undocumented op */
4768 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4769 gen_helper_fcom_ST0_FT0(tcg_env);
4770 break;
4771 case 0x03: /* fcomp */
4772 case 0x23: /* fcomp3, undocumented op */
4773 case 0x32: /* fcomp5, undocumented op */
4774 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4775 gen_helper_fcom_ST0_FT0(tcg_env);
4776 gen_helper_fpop(tcg_env);
4777 break;
4778 case 0x15: /* da/5 */
4779 switch (rm) {
4780 case 1: /* fucompp */
4781 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1));
4782 gen_helper_fucom_ST0_FT0(tcg_env);
4783 gen_helper_fpop(tcg_env);
4784 gen_helper_fpop(tcg_env);
4785 break;
4786 default:
4787 goto unknown_op;
4788 }
4789 break;
4790 case 0x1c:
4791 switch (rm) {
4792 case 0: /* feni (287 only, just do nop here) */
4793 break;
4794 case 1: /* fdisi (287 only, just do nop here) */
4795 break;
4796 case 2: /* fclex */
4797 gen_helper_fclex(tcg_env);
4798 update_fip = false;
4799 break;
4800 case 3: /* fninit */
4801 gen_helper_fninit(tcg_env);
4802 update_fip = false;
4803 break;
4804 case 4: /* fsetpm (287 only, just do nop here) */
4805 break;
4806 default:
4807 goto unknown_op;
4808 }
4809 break;
4810 case 0x1d: /* fucomi */
4811 if (!(s->cpuid_features & CPUID_CMOV)) {
4812 goto illegal_op;
4813 }
4814 gen_update_cc_op(s);
4815 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4816 gen_helper_fucomi_ST0_FT0(tcg_env);
4817 set_cc_op(s, CC_OP_EFLAGS);
4818 break;
4819 case 0x1e: /* fcomi */
4820 if (!(s->cpuid_features & CPUID_CMOV)) {
4821 goto illegal_op;
4822 }
4823 gen_update_cc_op(s);
4824 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4825 gen_helper_fcomi_ST0_FT0(tcg_env);
4826 set_cc_op(s, CC_OP_EFLAGS);
4827 break;
4828 case 0x28: /* ffree sti */
4829 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg));
4830 break;
4831 case 0x2a: /* fst sti */
4832 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg));
4833 break;
4834 case 0x2b: /* fstp sti */
4835 case 0x0b: /* fstp1 sti, undocumented op */
4836 case 0x3a: /* fstp8 sti, undocumented op */
4837 case 0x3b: /* fstp9 sti, undocumented op */
4838 gen_helper_fmov_STN_ST0(tcg_env, tcg_constant_i32(opreg));
4839 gen_helper_fpop(tcg_env);
4840 break;
4841 case 0x2c: /* fucom st(i) */
4842 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4843 gen_helper_fucom_ST0_FT0(tcg_env);
4844 break;
4845 case 0x2d: /* fucomp st(i) */
4846 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4847 gen_helper_fucom_ST0_FT0(tcg_env);
4848 gen_helper_fpop(tcg_env);
4849 break;
4850 case 0x33: /* de/3 */
4851 switch (rm) {
4852 case 1: /* fcompp */
4853 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(1));
4854 gen_helper_fcom_ST0_FT0(tcg_env);
4855 gen_helper_fpop(tcg_env);
4856 gen_helper_fpop(tcg_env);
4857 break;
4858 default:
4859 goto unknown_op;
4860 }
4861 break;
4862 case 0x38: /* ffreep sti, undocumented op */
4863 gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg));
4864 gen_helper_fpop(tcg_env);
4865 break;
4866 case 0x3c: /* df/4 */
4867 switch (rm) {
4868 case 0:
4869 gen_helper_fnstsw(s->tmp2_i32, tcg_env);
4870 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
4871 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
4872 break;
4873 default:
4874 goto unknown_op;
4875 }
4876 break;
4877 case 0x3d: /* fucomip */
4878 if (!(s->cpuid_features & CPUID_CMOV)) {
4879 goto illegal_op;
4880 }
4881 gen_update_cc_op(s);
4882 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4883 gen_helper_fucomi_ST0_FT0(tcg_env);
4884 gen_helper_fpop(tcg_env);
4885 set_cc_op(s, CC_OP_EFLAGS);
4886 break;
4887 case 0x3e: /* fcomip */
4888 if (!(s->cpuid_features & CPUID_CMOV)) {
4889 goto illegal_op;
4890 }
4891 gen_update_cc_op(s);
4892 gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
4893 gen_helper_fcomi_ST0_FT0(tcg_env);
4894 gen_helper_fpop(tcg_env);
4895 set_cc_op(s, CC_OP_EFLAGS);
4896 break;
4897 case 0x10 ... 0x13: /* fcmovxx */
4898 case 0x18 ... 0x1b:
4899 {
4900 int op1;
4901 TCGLabel *l1;
4902 static const uint8_t fcmov_cc[8] = {
4903 (JCC_B << 1),
4904 (JCC_Z << 1),
4905 (JCC_BE << 1),
4906 (JCC_P << 1),
4907 };
4908
4909 if (!(s->cpuid_features & CPUID_CMOV)) {
4910 goto illegal_op;
4911 }
4912 op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
4913 l1 = gen_new_label();
4914 gen_jcc1_noeob(s, op1, l1);
4915 gen_helper_fmov_ST0_STN(tcg_env,
4916 tcg_constant_i32(opreg));
4917 gen_set_label(l1);
4918 }
4919 break;
4920 default:
4921 goto unknown_op;
4922 }
4923 }
4924
4925 if (update_fip) {
4926 tcg_gen_ld_i32(s->tmp2_i32, tcg_env,
4927 offsetof(CPUX86State, segs[R_CS].selector));
4928 tcg_gen_st16_i32(s->tmp2_i32, tcg_env,
4929 offsetof(CPUX86State, fpcs));
4930 tcg_gen_st_tl(eip_cur_tl(s),
4931 tcg_env, offsetof(CPUX86State, fpip));
4932 }
4933 }
4934 break;
4935 /************************/
4936 /* string ops */
4937
4938 case 0xa4: /* movsS */
4939 case 0xa5:
4940 ot = mo_b_d(b, dflag);
4941 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4942 gen_repz_movs(s, ot);
4943 } else {
4944 gen_movs(s, ot);
4945 }
4946 break;
4947
4948 case 0xaa: /* stosS */
4949 case 0xab:
4950 ot = mo_b_d(b, dflag);
4951 gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
4952 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4953 gen_repz_stos(s, ot);
4954 } else {
4955 gen_stos(s, ot);
4956 }
4957 break;
4958 case 0xac: /* lodsS */
4959 case 0xad:
4960 ot = mo_b_d(b, dflag);
4961 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4962 gen_repz_lods(s, ot);
4963 } else {
4964 gen_lods(s, ot);
4965 }
4966 break;
4967 case 0xae: /* scasS */
4968 case 0xaf:
4969 ot = mo_b_d(b, dflag);
4970 gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
4971 if (prefixes & PREFIX_REPNZ) {
4972 gen_repz_scas(s, ot, 1);
4973 } else if (prefixes & PREFIX_REPZ) {
4974 gen_repz_scas(s, ot, 0);
4975 } else {
4976 gen_scas(s, ot);
4977 }
4978 break;
4979
4980 case 0xa6: /* cmpsS */
4981 case 0xa7:
4982 ot = mo_b_d(b, dflag);
4983 if (prefixes & PREFIX_REPNZ) {
4984 gen_repz_cmps(s, ot, 1);
4985 } else if (prefixes & PREFIX_REPZ) {
4986 gen_repz_cmps(s, ot, 0);
4987 } else {
4988 gen_cmps(s, ot);
4989 }
4990 break;
4991 case 0x6c: /* insS */
4992 case 0x6d:
4993 ot = mo_b_d32(b, dflag);
4994 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
4995 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
4996 if (!gen_check_io(s, ot, s->tmp2_i32,
4997 SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) {
4998 break;
4999 }
5000 translator_io_start(&s->base);
5001 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5002 gen_repz_ins(s, ot);
5003 } else {
5004 gen_ins(s, ot);
5005 }
5006 break;
5007 case 0x6e: /* outsS */
5008 case 0x6f:
5009 ot = mo_b_d32(b, dflag);
5010 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
5011 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
5012 if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_STR_MASK)) {
5013 break;
5014 }
5015 translator_io_start(&s->base);
5016 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5017 gen_repz_outs(s, ot);
5018 } else {
5019 gen_outs(s, ot);
5020 }
5021 break;
5022
5023 /************************/
5024 /* port I/O */
5025
5026 case 0xe4:
5027 case 0xe5:
5028 ot = mo_b_d32(b, dflag);
5029 val = x86_ldub_code(env, s);
5030 tcg_gen_movi_i32(s->tmp2_i32, val);
5031 if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
5032 break;
5033 }
5034 translator_io_start(&s->base);
5035 gen_helper_in_func(ot, s->T1, s->tmp2_i32);
5036 gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
5037 gen_bpt_io(s, s->tmp2_i32, ot);
5038 break;
5039 case 0xe6:
5040 case 0xe7:
5041 ot = mo_b_d32(b, dflag);
5042 val = x86_ldub_code(env, s);
5043 tcg_gen_movi_i32(s->tmp2_i32, val);
5044 if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
5045 break;
5046 }
5047 translator_io_start(&s->base);
5048 gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
5049 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
5050 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
5051 gen_bpt_io(s, s->tmp2_i32, ot);
5052 break;
5053 case 0xec:
5054 case 0xed:
5055 ot = mo_b_d32(b, dflag);
5056 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
5057 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
5058 if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
5059 break;
5060 }
5061 translator_io_start(&s->base);
5062 gen_helper_in_func(ot, s->T1, s->tmp2_i32);
5063 gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
5064 gen_bpt_io(s, s->tmp2_i32, ot);
5065 break;
5066 case 0xee:
5067 case 0xef:
5068 ot = mo_b_d32(b, dflag);
5069 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
5070 tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
5071 if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
5072 break;
5073 }
5074 translator_io_start(&s->base);
5075 gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
5076 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
5077 gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
5078 gen_bpt_io(s, s->tmp2_i32, ot);
5079 break;
5080
5081 /************************/
5082 /* control */
5083 case 0xc2: /* ret im */
5084 val = x86_ldsw_code(env, s);
5085 ot = gen_pop_T0(s);
5086 gen_stack_update(s, val + (1 << ot));
5087 /* Note that gen_pop_T0 uses a zero-extending load. */
5088 gen_op_jmp_v(s, s->T0);
5089 gen_bnd_jmp(s);
5090 s->base.is_jmp = DISAS_JUMP;
5091 break;
5092 case 0xc3: /* ret */
5093 ot = gen_pop_T0(s);
5094 gen_pop_update(s, ot);
5095 /* Note that gen_pop_T0 uses a zero-extending load. */
5096 gen_op_jmp_v(s, s->T0);
5097 gen_bnd_jmp(s);
5098 s->base.is_jmp = DISAS_JUMP;
5099 break;
5100 case 0xca: /* lret im */
5101 val = x86_ldsw_code(env, s);
5102 do_lret:
5103 if (PE(s) && !VM86(s)) {
5104 gen_update_cc_op(s);
5105 gen_update_eip_cur(s);
5106 gen_helper_lret_protected(tcg_env, tcg_constant_i32(dflag - 1),
5107 tcg_constant_i32(val));
5108 } else {
5109 gen_stack_A0(s);
5110 /* pop offset */
5111 gen_op_ld_v(s, dflag, s->T0, s->A0);
5112 /* NOTE: keeping EIP updated is not a problem in case of
5113 exception */
5114 gen_op_jmp_v(s, s->T0);
5115 /* pop selector */
5116 gen_add_A0_im(s, 1 << dflag);
5117 gen_op_ld_v(s, dflag, s->T0, s->A0);
5118 gen_op_movl_seg_T0_vm(s, R_CS);
5119 /* add stack offset */
5120 gen_stack_update(s, val + (2 << dflag));
5121 }
5122 s->base.is_jmp = DISAS_EOB_ONLY;
5123 break;
5124 case 0xcb: /* lret */
5125 val = 0;
5126 goto do_lret;
5127 case 0xcf: /* iret */
5128 gen_svm_check_intercept(s, SVM_EXIT_IRET);
5129 if (!PE(s) || VM86(s)) {
5130 /* real mode or vm86 mode */
5131 if (!check_vm86_iopl(s)) {
5132 break;
5133 }
5134 gen_helper_iret_real(tcg_env, tcg_constant_i32(dflag - 1));
5135 } else {
5136 gen_helper_iret_protected(tcg_env, tcg_constant_i32(dflag - 1),
5137 eip_next_i32(s));
5138 }
5139 set_cc_op(s, CC_OP_EFLAGS);
5140 s->base.is_jmp = DISAS_EOB_ONLY;
5141 break;
5142 case 0xe8: /* call im */
5143 {
5144 int diff = (dflag != MO_16
5145 ? (int32_t)insn_get(env, s, MO_32)
5146 : (int16_t)insn_get(env, s, MO_16));
5147 gen_push_v(s, eip_next_tl(s));
5148 gen_bnd_jmp(s);
5149 gen_jmp_rel(s, dflag, diff, 0);
5150 }
5151 break;
5152 case 0x9a: /* lcall im */
5153 {
5154 unsigned int selector, offset;
5155
5156 if (CODE64(s))
5157 goto illegal_op;
5158 ot = dflag;
5159 offset = insn_get(env, s, ot);
5160 selector = insn_get(env, s, MO_16);
5161
5162 tcg_gen_movi_tl(s->T0, selector);
5163 tcg_gen_movi_tl(s->T1, offset);
5164 }
5165 goto do_lcall;
5166 case 0xe9: /* jmp im */
5167 {
5168 int diff = (dflag != MO_16
5169 ? (int32_t)insn_get(env, s, MO_32)
5170 : (int16_t)insn_get(env, s, MO_16));
5171 gen_bnd_jmp(s);
5172 gen_jmp_rel(s, dflag, diff, 0);
5173 }
5174 break;
5175 case 0xea: /* ljmp im */
5176 {
5177 unsigned int selector, offset;
5178
5179 if (CODE64(s))
5180 goto illegal_op;
5181 ot = dflag;
5182 offset = insn_get(env, s, ot);
5183 selector = insn_get(env, s, MO_16);
5184
5185 tcg_gen_movi_tl(s->T0, selector);
5186 tcg_gen_movi_tl(s->T1, offset);
5187 }
5188 goto do_ljmp;
5189 case 0xeb: /* jmp Jb */
5190 {
5191 int diff = (int8_t)insn_get(env, s, MO_8);
5192 gen_jmp_rel(s, dflag, diff, 0);
5193 }
5194 break;
5195 case 0x70 ... 0x7f: /* jcc Jb */
5196 {
5197 int diff = (int8_t)insn_get(env, s, MO_8);
5198 gen_bnd_jmp(s);
5199 gen_jcc(s, b, diff);
5200 }
5201 break;
5202 case 0x180 ... 0x18f: /* jcc Jv */
5203 {
5204 int diff = (dflag != MO_16
5205 ? (int32_t)insn_get(env, s, MO_32)
5206 : (int16_t)insn_get(env, s, MO_16));
5207 gen_bnd_jmp(s);
5208 gen_jcc(s, b, diff);
5209 }
5210 break;
5211
5212 case 0x190 ... 0x19f: /* setcc Gv */
5213 modrm = x86_ldub_code(env, s);
5214 gen_setcc1(s, b, s->T0);
5215 gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
5216 break;
5217 case 0x140 ... 0x14f: /* cmov Gv, Ev */
5218 if (!(s->cpuid_features & CPUID_CMOV)) {
5219 goto illegal_op;
5220 }
5221 ot = dflag;
5222 modrm = x86_ldub_code(env, s);
5223 reg = ((modrm >> 3) & 7) | REX_R(s);
5224 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5225 gen_cmovcc1(s, b ^ 1, s->T0, cpu_regs[reg]);
5226 gen_op_mov_reg_v(s, ot, reg, s->T0);
5227 break;
5228
5229 /************************/
5230 /* flags */
5231 case 0x9c: /* pushf */
5232 gen_svm_check_intercept(s, SVM_EXIT_PUSHF);
5233 if (check_vm86_iopl(s)) {
5234 gen_update_cc_op(s);
5235 gen_helper_read_eflags(s->T0, tcg_env);
5236 gen_push_v(s, s->T0);
5237 }
5238 break;
5239 case 0x9d: /* popf */
5240 gen_svm_check_intercept(s, SVM_EXIT_POPF);
5241 if (check_vm86_iopl(s)) {
5242 int mask = TF_MASK | AC_MASK | ID_MASK | NT_MASK;
5243
5244 if (CPL(s) == 0) {
5245 mask |= IF_MASK | IOPL_MASK;
5246 } else if (CPL(s) <= IOPL(s)) {
5247 mask |= IF_MASK;
5248 }
5249 if (dflag == MO_16) {
5250 mask &= 0xffff;
5251 }
5252
5253 ot = gen_pop_T0(s);
5254 gen_helper_write_eflags(tcg_env, s->T0, tcg_constant_i32(mask));
5255 gen_pop_update(s, ot);
5256 set_cc_op(s, CC_OP_EFLAGS);
5257 /* abort translation because TF/AC flag may change */
5258 s->base.is_jmp = DISAS_EOB_NEXT;
5259 }
5260 break;
5261 case 0x9e: /* sahf */
5262 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
5263 goto illegal_op;
5264 tcg_gen_shri_tl(s->T0, cpu_regs[R_EAX], 8);
5265 gen_compute_eflags(s);
5266 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
5267 tcg_gen_andi_tl(s->T0, s->T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
5268 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, s->T0);
5269 break;
5270 case 0x9f: /* lahf */
5271 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
5272 goto illegal_op;
5273 gen_compute_eflags(s);
5274 /* Note: gen_compute_eflags() only gives the condition codes */
5275 tcg_gen_ori_tl(s->T0, cpu_cc_src, 0x02);
5276 tcg_gen_deposit_tl(cpu_regs[R_EAX], cpu_regs[R_EAX], s->T0, 8, 8);
5277 break;
5278 case 0xf5: /* cmc */
5279 gen_compute_eflags(s);
5280 tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5281 break;
5282 case 0xf8: /* clc */
5283 gen_compute_eflags(s);
5284 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
5285 break;
5286 case 0xf9: /* stc */
5287 gen_compute_eflags(s);
5288 tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5289 break;
5290 case 0xfc: /* cld */
5291 tcg_gen_movi_i32(s->tmp2_i32, 1);
5292 tcg_gen_st_i32(s->tmp2_i32, tcg_env, offsetof(CPUX86State, df));
5293 break;
5294 case 0xfd: /* std */
5295 tcg_gen_movi_i32(s->tmp2_i32, -1);
5296 tcg_gen_st_i32(s->tmp2_i32, tcg_env, offsetof(CPUX86State, df));
5297 break;
5298
5299 /************************/
5300 /* bit operations */
5301 case 0x1ba: /* bt/bts/btr/btc Gv, im */
5302 ot = dflag;
5303 modrm = x86_ldub_code(env, s);
5304 op = (modrm >> 3) & 7;
5305 mod = (modrm >> 6) & 3;
5306 rm = (modrm & 7) | REX_B(s);
5307 if (mod != 3) {
5308 s->rip_offset = 1;
5309 gen_lea_modrm(env, s, modrm);
5310 if (!(s->prefix & PREFIX_LOCK)) {
5311 gen_op_ld_v(s, ot, s->T0, s->A0);
5312 }
5313 } else {
5314 gen_op_mov_v_reg(s, ot, s->T0, rm);
5315 }
5316 /* load shift */
5317 val = x86_ldub_code(env, s);
5318 tcg_gen_movi_tl(s->T1, val);
5319 if (op < 4)
5320 goto unknown_op;
5321 op -= 4;
5322 goto bt_op;
5323 case 0x1a3: /* bt Gv, Ev */
5324 op = 0;
5325 goto do_btx;
5326 case 0x1ab: /* bts */
5327 op = 1;
5328 goto do_btx;
5329 case 0x1b3: /* btr */
5330 op = 2;
5331 goto do_btx;
5332 case 0x1bb: /* btc */
5333 op = 3;
5334 do_btx:
5335 ot = dflag;
5336 modrm = x86_ldub_code(env, s);
5337 reg = ((modrm >> 3) & 7) | REX_R(s);
5338 mod = (modrm >> 6) & 3;
5339 rm = (modrm & 7) | REX_B(s);
5340 gen_op_mov_v_reg(s, MO_32, s->T1, reg);
5341 if (mod != 3) {
5342 AddressParts a = gen_lea_modrm_0(env, s, modrm);
5343 /* specific case: we need to add a displacement */
5344 gen_exts(ot, s->T1);
5345 tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot);
5346 tcg_gen_shli_tl(s->tmp0, s->tmp0, ot);
5347 tcg_gen_add_tl(s->A0, gen_lea_modrm_1(s, a, false), s->tmp0);
5348 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
5349 if (!(s->prefix & PREFIX_LOCK)) {
5350 gen_op_ld_v(s, ot, s->T0, s->A0);
5351 }
5352 } else {
5353 gen_op_mov_v_reg(s, ot, s->T0, rm);
5354 }
5355 bt_op:
5356 tcg_gen_andi_tl(s->T1, s->T1, (1 << (3 + ot)) - 1);
5357 tcg_gen_movi_tl(s->tmp0, 1);
5358 tcg_gen_shl_tl(s->tmp0, s->tmp0, s->T1);
5359 if (s->prefix & PREFIX_LOCK) {
5360 switch (op) {
5361 case 0: /* bt */
5362 /* Needs no atomic ops; we suppressed the normal
5363 memory load for LOCK above so do it now. */
5364 gen_op_ld_v(s, ot, s->T0, s->A0);
5365 break;
5366 case 1: /* bts */
5367 tcg_gen_atomic_fetch_or_tl(s->T0, s->A0, s->tmp0,
5368 s->mem_index, ot | MO_LE);
5369 break;
5370 case 2: /* btr */
5371 tcg_gen_not_tl(s->tmp0, s->tmp0);
5372 tcg_gen_atomic_fetch_and_tl(s->T0, s->A0, s->tmp0,
5373 s->mem_index, ot | MO_LE);
5374 break;
5375 default:
5376 case 3: /* btc */
5377 tcg_gen_atomic_fetch_xor_tl(s->T0, s->A0, s->tmp0,
5378 s->mem_index, ot | MO_LE);
5379 break;
5380 }
5381 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1);
5382 } else {
5383 tcg_gen_shr_tl(s->tmp4, s->T0, s->T1);
5384 switch (op) {
5385 case 0: /* bt */
5386 /* Data already loaded; nothing to do. */
5387 break;
5388 case 1: /* bts */
5389 tcg_gen_or_tl(s->T0, s->T0, s->tmp0);
5390 break;
5391 case 2: /* btr */
5392 tcg_gen_andc_tl(s->T0, s->T0, s->tmp0);
5393 break;
5394 default:
5395 case 3: /* btc */
5396 tcg_gen_xor_tl(s->T0, s->T0, s->tmp0);
5397 break;
5398 }
5399 if (op != 0) {
5400 if (mod != 3) {
5401 gen_op_st_v(s, ot, s->T0, s->A0);
5402 } else {
5403 gen_op_mov_reg_v(s, ot, rm, s->T0);
5404 }
5405 }
5406 }
5407
5408 /* Delay all CC updates until after the store above. Note that
5409 C is the result of the test, Z is unchanged, and the others
5410 are all undefined. */
5411 switch (s->cc_op) {
5412 case CC_OP_MULB ... CC_OP_MULQ:
5413 case CC_OP_ADDB ... CC_OP_ADDQ:
5414 case CC_OP_ADCB ... CC_OP_ADCQ:
5415 case CC_OP_SUBB ... CC_OP_SUBQ:
5416 case CC_OP_SBBB ... CC_OP_SBBQ:
5417 case CC_OP_LOGICB ... CC_OP_LOGICQ:
5418 case CC_OP_INCB ... CC_OP_INCQ:
5419 case CC_OP_DECB ... CC_OP_DECQ:
5420 case CC_OP_SHLB ... CC_OP_SHLQ:
5421 case CC_OP_SARB ... CC_OP_SARQ:
5422 case CC_OP_BMILGB ... CC_OP_BMILGQ:
5423 /* Z was going to be computed from the non-zero status of CC_DST.
5424 We can get that same Z value (and the new C value) by leaving
5425 CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
5426 same width. */
5427 tcg_gen_mov_tl(cpu_cc_src, s->tmp4);
5428 set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
5429 break;
5430 default:
5431 /* Otherwise, generate EFLAGS and replace the C bit. */
5432 gen_compute_eflags(s);
5433 tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, s->tmp4,
5434 ctz32(CC_C), 1);
5435 break;
5436 }
5437 break;
5438 case 0x1bc: /* bsf / tzcnt */
5439 case 0x1bd: /* bsr / lzcnt */
5440 ot = dflag;
5441 modrm = x86_ldub_code(env, s);
5442 reg = ((modrm >> 3) & 7) | REX_R(s);
5443 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5444 gen_extu(ot, s->T0);
5445
5446 /* Note that lzcnt and tzcnt are in different extensions. */
5447 if ((prefixes & PREFIX_REPZ)
5448 && (b & 1
5449 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
5450 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
5451 int size = 8 << ot;
5452 /* For lzcnt/tzcnt, C bit is defined related to the input. */
5453 tcg_gen_mov_tl(cpu_cc_src, s->T0);
5454 if (b & 1) {
5455 /* For lzcnt, reduce the target_ulong result by the
5456 number of zeros that we expect to find at the top. */
5457 tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS);
5458 tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - size);
5459 } else {
5460 /* For tzcnt, a zero input must return the operand size. */
5461 tcg_gen_ctzi_tl(s->T0, s->T0, size);
5462 }
5463 /* For lzcnt/tzcnt, Z bit is defined related to the result. */
5464 gen_op_update1_cc(s);
5465 set_cc_op(s, CC_OP_BMILGB + ot);
5466 } else {
5467 /* For bsr/bsf, only the Z bit is defined and it is related
5468 to the input and not the result. */
5469 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
5470 set_cc_op(s, CC_OP_LOGICB + ot);
5471
5472 /* ??? The manual says that the output is undefined when the
5473 input is zero, but real hardware leaves it unchanged, and
5474 real programs appear to depend on that. Accomplish this
5475 by passing the output as the value to return upon zero. */
5476 if (b & 1) {
5477 /* For bsr, return the bit index of the first 1 bit,
5478 not the count of leading zeros. */
5479 tcg_gen_xori_tl(s->T1, cpu_regs[reg], TARGET_LONG_BITS - 1);
5480 tcg_gen_clz_tl(s->T0, s->T0, s->T1);
5481 tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1);
5482 } else {
5483 tcg_gen_ctz_tl(s->T0, s->T0, cpu_regs[reg]);
5484 }
5485 }
5486 gen_op_mov_reg_v(s, ot, reg, s->T0);
5487 break;
5488 /************************/
5489 /* bcd */
5490 case 0x27: /* daa */
5491 if (CODE64(s))
5492 goto illegal_op;
5493 gen_update_cc_op(s);
5494 gen_helper_daa(tcg_env);
5495 set_cc_op(s, CC_OP_EFLAGS);
5496 break;
5497 case 0x2f: /* das */
5498 if (CODE64(s))
5499 goto illegal_op;
5500 gen_update_cc_op(s);
5501 gen_helper_das(tcg_env);
5502 set_cc_op(s, CC_OP_EFLAGS);
5503 break;
5504 case 0x37: /* aaa */
5505 if (CODE64(s))
5506 goto illegal_op;
5507 gen_update_cc_op(s);
5508 gen_helper_aaa(tcg_env);
5509 set_cc_op(s, CC_OP_EFLAGS);
5510 break;
5511 case 0x3f: /* aas */
5512 if (CODE64(s))
5513 goto illegal_op;
5514 gen_update_cc_op(s);
5515 gen_helper_aas(tcg_env);
5516 set_cc_op(s, CC_OP_EFLAGS);
5517 break;
5518 case 0xd4: /* aam */
5519 if (CODE64(s))
5520 goto illegal_op;
5521 val = x86_ldub_code(env, s);
5522 if (val == 0) {
5523 gen_exception(s, EXCP00_DIVZ);
5524 } else {
5525 gen_helper_aam(tcg_env, tcg_constant_i32(val));
5526 set_cc_op(s, CC_OP_LOGICB);
5527 }
5528 break;
5529 case 0xd5: /* aad */
5530 if (CODE64(s))
5531 goto illegal_op;
5532 val = x86_ldub_code(env, s);
5533 gen_helper_aad(tcg_env, tcg_constant_i32(val));
5534 set_cc_op(s, CC_OP_LOGICB);
5535 break;
5536 /************************/
5537 /* misc */
5538 case 0x90: /* nop */
5539 /* XXX: correct lock test for all insn */
5540 if (prefixes & PREFIX_LOCK) {
5541 goto illegal_op;
5542 }
5543 /* If REX_B is set, then this is xchg eax, r8d, not a nop. */
5544 if (REX_B(s)) {
5545 goto do_xchg_reg_eax;
5546 }
5547 if (prefixes & PREFIX_REPZ) {
5548 gen_update_cc_op(s);
5549 gen_update_eip_cur(s);
5550 gen_helper_pause(tcg_env, cur_insn_len_i32(s));
5551 s->base.is_jmp = DISAS_NORETURN;
5552 }
5553 break;
5554 case 0x9b: /* fwait */
5555 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
5556 (HF_MP_MASK | HF_TS_MASK)) {
5557 gen_exception(s, EXCP07_PREX);
5558 } else {
5559 /* needs to be treated as I/O because of ferr_irq */
5560 translator_io_start(&s->base);
5561 gen_helper_fwait(tcg_env);
5562 }
5563 break;
5564 case 0xcc: /* int3 */
5565 gen_interrupt(s, EXCP03_INT3);
5566 break;
5567 case 0xcd: /* int N */
5568 val = x86_ldub_code(env, s);
5569 if (check_vm86_iopl(s)) {
5570 gen_interrupt(s, val);
5571 }
5572 break;
5573 case 0xce: /* into */
5574 if (CODE64(s))
5575 goto illegal_op;
5576 gen_update_cc_op(s);
5577 gen_update_eip_cur(s);
5578 gen_helper_into(tcg_env, cur_insn_len_i32(s));
5579 break;
5580 #ifdef WANT_ICEBP
5581 case 0xf1: /* icebp (undocumented, exits to external debugger) */
5582 gen_svm_check_intercept(s, SVM_EXIT_ICEBP);
5583 gen_debug(s);
5584 break;
5585 #endif
5586 case 0xfa: /* cli */
5587 if (check_iopl(s)) {
5588 gen_reset_eflags(s, IF_MASK);
5589 }
5590 break;
5591 case 0xfb: /* sti */
5592 if (check_iopl(s)) {
5593 gen_set_eflags(s, IF_MASK);
5594 /* interruptions are enabled only the first insn after sti */
5595 gen_update_eip_next(s);
5596 gen_eob_inhibit_irq(s, true);
5597 }
5598 break;
5599 case 0x62: /* bound */
5600 if (CODE64(s))
5601 goto illegal_op;
5602 ot = dflag;
5603 modrm = x86_ldub_code(env, s);
5604 reg = (modrm >> 3) & 7;
5605 mod = (modrm >> 6) & 3;
5606 if (mod == 3)
5607 goto illegal_op;
5608 gen_op_mov_v_reg(s, ot, s->T0, reg);
5609 gen_lea_modrm(env, s, modrm);
5610 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5611 if (ot == MO_16) {
5612 gen_helper_boundw(tcg_env, s->A0, s->tmp2_i32);
5613 } else {
5614 gen_helper_boundl(tcg_env, s->A0, s->tmp2_i32);
5615 }
5616 break;
5617 case 0x1c8 ... 0x1cf: /* bswap reg */
5618 reg = (b & 7) | REX_B(s);
5619 #ifdef TARGET_X86_64
5620 if (dflag == MO_64) {
5621 tcg_gen_bswap64_i64(cpu_regs[reg], cpu_regs[reg]);
5622 break;
5623 }
5624 #endif
5625 tcg_gen_bswap32_tl(cpu_regs[reg], cpu_regs[reg], TCG_BSWAP_OZ);
5626 break;
5627 case 0xd6: /* salc */
5628 if (CODE64(s))
5629 goto illegal_op;
5630 gen_compute_eflags_c(s, s->T0);
5631 tcg_gen_neg_tl(s->T0, s->T0);
5632 gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0);
5633 break;
5634 case 0xe0: /* loopnz */
5635 case 0xe1: /* loopz */
5636 case 0xe2: /* loop */
5637 case 0xe3: /* jecxz */
5638 {
5639 TCGLabel *l1, *l2;
5640 int diff = (int8_t)insn_get(env, s, MO_8);
5641
5642 l1 = gen_new_label();
5643 l2 = gen_new_label();
5644 gen_update_cc_op(s);
5645 b &= 3;
5646 switch(b) {
5647 case 0: /* loopnz */
5648 case 1: /* loopz */
5649 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
5650 gen_op_jz_ecx(s, l2);
5651 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
5652 break;
5653 case 2: /* loop */
5654 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
5655 gen_op_jnz_ecx(s, l1);
5656 break;
5657 default:
5658 case 3: /* jcxz */
5659 gen_op_jz_ecx(s, l1);
5660 break;
5661 }
5662
5663 gen_set_label(l2);
5664 gen_jmp_rel_csize(s, 0, 1);
5665
5666 gen_set_label(l1);
5667 gen_jmp_rel(s, dflag, diff, 0);
5668 }
5669 break;
5670 case 0x130: /* wrmsr */
5671 case 0x132: /* rdmsr */
5672 if (check_cpl0(s)) {
5673 gen_update_cc_op(s);
5674 gen_update_eip_cur(s);
5675 if (b & 2) {
5676 gen_helper_rdmsr(tcg_env);
5677 } else {
5678 gen_helper_wrmsr(tcg_env);
5679 s->base.is_jmp = DISAS_EOB_NEXT;
5680 }
5681 }
5682 break;
5683 case 0x131: /* rdtsc */
5684 gen_update_cc_op(s);
5685 gen_update_eip_cur(s);
5686 translator_io_start(&s->base);
5687 gen_helper_rdtsc(tcg_env);
5688 break;
5689 case 0x133: /* rdpmc */
5690 gen_update_cc_op(s);
5691 gen_update_eip_cur(s);
5692 gen_helper_rdpmc(tcg_env);
5693 s->base.is_jmp = DISAS_NORETURN;
5694 break;
5695 case 0x134: /* sysenter */
5696 /* For AMD SYSENTER is not valid in long mode */
5697 if (LMA(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) {
5698 goto illegal_op;
5699 }
5700 if (!PE(s)) {
5701 gen_exception_gpf(s);
5702 } else {
5703 gen_helper_sysenter(tcg_env);
5704 s->base.is_jmp = DISAS_EOB_ONLY;
5705 }
5706 break;
5707 case 0x135: /* sysexit */
5708 /* For AMD SYSEXIT is not valid in long mode */
5709 if (LMA(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1) {
5710 goto illegal_op;
5711 }
5712 if (!PE(s) || CPL(s) != 0) {
5713 gen_exception_gpf(s);
5714 } else {
5715 gen_helper_sysexit(tcg_env, tcg_constant_i32(dflag - 1));
5716 s->base.is_jmp = DISAS_EOB_ONLY;
5717 }
5718 break;
5719 case 0x105: /* syscall */
5720 /* For Intel SYSCALL is only valid in long mode */
5721 if (!LMA(s) && env->cpuid_vendor1 == CPUID_VENDOR_INTEL_1) {
5722 goto illegal_op;
5723 }
5724 gen_update_cc_op(s);
5725 gen_update_eip_cur(s);
5726 gen_helper_syscall(tcg_env, cur_insn_len_i32(s));
5727 /* TF handling for the syscall insn is different. The TF bit is checked
5728 after the syscall insn completes. This allows #DB to not be
5729 generated after one has entered CPL0 if TF is set in FMASK. */
5730 gen_eob_worker(s, false, true);
5731 break;
5732 case 0x107: /* sysret */
5733 /* For Intel SYSRET is only valid in long mode */
5734 if (!LMA(s) && env->cpuid_vendor1 == CPUID_VENDOR_INTEL_1) {
5735 goto illegal_op;
5736 }
5737 if (!PE(s) || CPL(s) != 0) {
5738 gen_exception_gpf(s);
5739 } else {
5740 gen_helper_sysret(tcg_env, tcg_constant_i32(dflag - 1));
5741 /* condition codes are modified only in long mode */
5742 if (LMA(s)) {
5743 set_cc_op(s, CC_OP_EFLAGS);
5744 }
5745 /* TF handling for the sysret insn is different. The TF bit is
5746 checked after the sysret insn completes. This allows #DB to be
5747 generated "as if" the syscall insn in userspace has just
5748 completed. */
5749 gen_eob_worker(s, false, true);
5750 }
5751 break;
5752 case 0x1a2: /* cpuid */
5753 gen_update_cc_op(s);
5754 gen_update_eip_cur(s);
5755 gen_helper_cpuid(tcg_env);
5756 break;
5757 case 0xf4: /* hlt */
5758 if (check_cpl0(s)) {
5759 gen_update_cc_op(s);
5760 gen_update_eip_cur(s);
5761 gen_helper_hlt(tcg_env, cur_insn_len_i32(s));
5762 s->base.is_jmp = DISAS_NORETURN;
5763 }
5764 break;
5765 case 0x100:
5766 modrm = x86_ldub_code(env, s);
5767 mod = (modrm >> 6) & 3;
5768 op = (modrm >> 3) & 7;
5769 switch(op) {
5770 case 0: /* sldt */
5771 if (!PE(s) || VM86(s))
5772 goto illegal_op;
5773 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5774 break;
5775 }
5776 gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ);
5777 tcg_gen_ld32u_tl(s->T0, tcg_env,
5778 offsetof(CPUX86State, ldt.selector));
5779 ot = mod == 3 ? dflag : MO_16;
5780 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5781 break;
5782 case 2: /* lldt */
5783 if (!PE(s) || VM86(s))
5784 goto illegal_op;
5785 if (check_cpl0(s)) {
5786 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE);
5787 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5788 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5789 gen_helper_lldt(tcg_env, s->tmp2_i32);
5790 }
5791 break;
5792 case 1: /* str */
5793 if (!PE(s) || VM86(s))
5794 goto illegal_op;
5795 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5796 break;
5797 }
5798 gen_svm_check_intercept(s, SVM_EXIT_TR_READ);
5799 tcg_gen_ld32u_tl(s->T0, tcg_env,
5800 offsetof(CPUX86State, tr.selector));
5801 ot = mod == 3 ? dflag : MO_16;
5802 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5803 break;
5804 case 3: /* ltr */
5805 if (!PE(s) || VM86(s))
5806 goto illegal_op;
5807 if (check_cpl0(s)) {
5808 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE);
5809 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5810 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5811 gen_helper_ltr(tcg_env, s->tmp2_i32);
5812 }
5813 break;
5814 case 4: /* verr */
5815 case 5: /* verw */
5816 if (!PE(s) || VM86(s))
5817 goto illegal_op;
5818 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5819 gen_update_cc_op(s);
5820 if (op == 4) {
5821 gen_helper_verr(tcg_env, s->T0);
5822 } else {
5823 gen_helper_verw(tcg_env, s->T0);
5824 }
5825 set_cc_op(s, CC_OP_EFLAGS);
5826 break;
5827 default:
5828 goto unknown_op;
5829 }
5830 break;
5831
5832 case 0x101:
5833 modrm = x86_ldub_code(env, s);
5834 switch (modrm) {
5835 CASE_MODRM_MEM_OP(0): /* sgdt */
5836 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5837 break;
5838 }
5839 gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ);
5840 gen_lea_modrm(env, s, modrm);
5841 tcg_gen_ld32u_tl(s->T0,
5842 tcg_env, offsetof(CPUX86State, gdt.limit));
5843 gen_op_st_v(s, MO_16, s->T0, s->A0);
5844 gen_add_A0_im(s, 2);
5845 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base));
5846 if (dflag == MO_16) {
5847 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
5848 }
5849 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
5850 break;
5851
5852 case 0xc8: /* monitor */
5853 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
5854 goto illegal_op;
5855 }
5856 gen_update_cc_op(s);
5857 gen_update_eip_cur(s);
5858 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
5859 gen_add_A0_ds_seg(s);
5860 gen_helper_monitor(tcg_env, s->A0);
5861 break;
5862
5863 case 0xc9: /* mwait */
5864 if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
5865 goto illegal_op;
5866 }
5867 gen_update_cc_op(s);
5868 gen_update_eip_cur(s);
5869 gen_helper_mwait(tcg_env, cur_insn_len_i32(s));
5870 s->base.is_jmp = DISAS_NORETURN;
5871 break;
5872
5873 case 0xca: /* clac */
5874 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
5875 || CPL(s) != 0) {
5876 goto illegal_op;
5877 }
5878 gen_reset_eflags(s, AC_MASK);
5879 s->base.is_jmp = DISAS_EOB_NEXT;
5880 break;
5881
5882 case 0xcb: /* stac */
5883 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
5884 || CPL(s) != 0) {
5885 goto illegal_op;
5886 }
5887 gen_set_eflags(s, AC_MASK);
5888 s->base.is_jmp = DISAS_EOB_NEXT;
5889 break;
5890
5891 CASE_MODRM_MEM_OP(1): /* sidt */
5892 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5893 break;
5894 }
5895 gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ);
5896 gen_lea_modrm(env, s, modrm);
5897 tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.limit));
5898 gen_op_st_v(s, MO_16, s->T0, s->A0);
5899 gen_add_A0_im(s, 2);
5900 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base));
5901 if (dflag == MO_16) {
5902 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
5903 }
5904 gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
5905 break;
5906
5907 case 0xd0: /* xgetbv */
5908 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
5909 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
5910 | PREFIX_REPZ | PREFIX_REPNZ))) {
5911 goto illegal_op;
5912 }
5913 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
5914 gen_helper_xgetbv(s->tmp1_i64, tcg_env, s->tmp2_i32);
5915 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
5916 break;
5917
5918 case 0xd1: /* xsetbv */
5919 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
5920 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
5921 | PREFIX_REPZ | PREFIX_REPNZ))) {
5922 goto illegal_op;
5923 }
5924 gen_svm_check_intercept(s, SVM_EXIT_XSETBV);
5925 if (!check_cpl0(s)) {
5926 break;
5927 }
5928 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
5929 cpu_regs[R_EDX]);
5930 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
5931 gen_helper_xsetbv(tcg_env, s->tmp2_i32, s->tmp1_i64);
5932 /* End TB because translation flags may change. */
5933 s->base.is_jmp = DISAS_EOB_NEXT;
5934 break;
5935
5936 case 0xd8: /* VMRUN */
5937 if (!SVME(s) || !PE(s)) {
5938 goto illegal_op;
5939 }
5940 if (!check_cpl0(s)) {
5941 break;
5942 }
5943 gen_update_cc_op(s);
5944 gen_update_eip_cur(s);
5945 gen_helper_vmrun(tcg_env, tcg_constant_i32(s->aflag - 1),
5946 cur_insn_len_i32(s));
5947 tcg_gen_exit_tb(NULL, 0);
5948 s->base.is_jmp = DISAS_NORETURN;
5949 break;
5950
5951 case 0xd9: /* VMMCALL */
5952 if (!SVME(s)) {
5953 goto illegal_op;
5954 }
5955 gen_update_cc_op(s);
5956 gen_update_eip_cur(s);
5957 gen_helper_vmmcall(tcg_env);
5958 break;
5959
5960 case 0xda: /* VMLOAD */
5961 if (!SVME(s) || !PE(s)) {
5962 goto illegal_op;
5963 }
5964 if (!check_cpl0(s)) {
5965 break;
5966 }
5967 gen_update_cc_op(s);
5968 gen_update_eip_cur(s);
5969 gen_helper_vmload(tcg_env, tcg_constant_i32(s->aflag - 1));
5970 break;
5971
5972 case 0xdb: /* VMSAVE */
5973 if (!SVME(s) || !PE(s)) {
5974 goto illegal_op;
5975 }
5976 if (!check_cpl0(s)) {
5977 break;
5978 }
5979 gen_update_cc_op(s);
5980 gen_update_eip_cur(s);
5981 gen_helper_vmsave(tcg_env, tcg_constant_i32(s->aflag - 1));
5982 break;
5983
5984 case 0xdc: /* STGI */
5985 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
5986 || !PE(s)) {
5987 goto illegal_op;
5988 }
5989 if (!check_cpl0(s)) {
5990 break;
5991 }
5992 gen_update_cc_op(s);
5993 gen_helper_stgi(tcg_env);
5994 s->base.is_jmp = DISAS_EOB_NEXT;
5995 break;
5996
5997 case 0xdd: /* CLGI */
5998 if (!SVME(s) || !PE(s)) {
5999 goto illegal_op;
6000 }
6001 if (!check_cpl0(s)) {
6002 break;
6003 }
6004 gen_update_cc_op(s);
6005 gen_update_eip_cur(s);
6006 gen_helper_clgi(tcg_env);
6007 break;
6008
6009 case 0xde: /* SKINIT */
6010 if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
6011 || !PE(s)) {
6012 goto illegal_op;
6013 }
6014 gen_svm_check_intercept(s, SVM_EXIT_SKINIT);
6015 /* If not intercepted, not implemented -- raise #UD. */
6016 goto illegal_op;
6017
6018 case 0xdf: /* INVLPGA */
6019 if (!SVME(s) || !PE(s)) {
6020 goto illegal_op;
6021 }
6022 if (!check_cpl0(s)) {
6023 break;
6024 }
6025 gen_svm_check_intercept(s, SVM_EXIT_INVLPGA);
6026 if (s->aflag == MO_64) {
6027 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
6028 } else {
6029 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]);
6030 }
6031 gen_helper_flush_page(tcg_env, s->A0);
6032 s->base.is_jmp = DISAS_EOB_NEXT;
6033 break;
6034
6035 CASE_MODRM_MEM_OP(2): /* lgdt */
6036 if (!check_cpl0(s)) {
6037 break;
6038 }
6039 gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE);
6040 gen_lea_modrm(env, s, modrm);
6041 gen_op_ld_v(s, MO_16, s->T1, s->A0);
6042 gen_add_A0_im(s, 2);
6043 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
6044 if (dflag == MO_16) {
6045 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
6046 }
6047 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base));
6048 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, gdt.limit));
6049 break;
6050
6051 CASE_MODRM_MEM_OP(3): /* lidt */
6052 if (!check_cpl0(s)) {
6053 break;
6054 }
6055 gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE);
6056 gen_lea_modrm(env, s, modrm);
6057 gen_op_ld_v(s, MO_16, s->T1, s->A0);
6058 gen_add_A0_im(s, 2);
6059 gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
6060 if (dflag == MO_16) {
6061 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
6062 }
6063 tcg_gen_st_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base));
6064 tcg_gen_st32_tl(s->T1, tcg_env, offsetof(CPUX86State, idt.limit));
6065 break;
6066
6067 CASE_MODRM_OP(4): /* smsw */
6068 if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
6069 break;
6070 }
6071 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0);
6072 tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, cr[0]));
6073 /*
6074 * In 32-bit mode, the higher 16 bits of the destination
6075 * register are undefined. In practice CR0[31:0] is stored
6076 * just like in 64-bit mode.
6077 */
6078 mod = (modrm >> 6) & 3;
6079 ot = (mod != 3 ? MO_16 : s->dflag);
6080 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
6081 break;
6082 case 0xee: /* rdpkru */
6083 if (prefixes & PREFIX_LOCK) {
6084 goto illegal_op;
6085 }
6086 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
6087 gen_helper_rdpkru(s->tmp1_i64, tcg_env, s->tmp2_i32);
6088 tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
6089 break;
6090 case 0xef: /* wrpkru */
6091 if (prefixes & PREFIX_LOCK) {
6092 goto illegal_op;
6093 }
6094 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6095 cpu_regs[R_EDX]);
6096 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
6097 gen_helper_wrpkru(tcg_env, s->tmp2_i32, s->tmp1_i64);
6098 break;
6099
6100 CASE_MODRM_OP(6): /* lmsw */
6101 if (!check_cpl0(s)) {
6102 break;
6103 }
6104 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
6105 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
6106 /*
6107 * Only the 4 lower bits of CR0 are modified.
6108 * PE cannot be set to zero if already set to one.
6109 */
6110 tcg_gen_ld_tl(s->T1, tcg_env, offsetof(CPUX86State, cr[0]));
6111 tcg_gen_andi_tl(s->T0, s->T0, 0xf);
6112 tcg_gen_andi_tl(s->T1, s->T1, ~0xe);
6113 tcg_gen_or_tl(s->T0, s->T0, s->T1);
6114 gen_helper_write_crN(tcg_env, tcg_constant_i32(0), s->T0);
6115 s->base.is_jmp = DISAS_EOB_NEXT;
6116 break;
6117
6118 CASE_MODRM_MEM_OP(7): /* invlpg */
6119 if (!check_cpl0(s)) {
6120 break;
6121 }
6122 gen_svm_check_intercept(s, SVM_EXIT_INVLPG);
6123 gen_lea_modrm(env, s, modrm);
6124 gen_helper_flush_page(tcg_env, s->A0);
6125 s->base.is_jmp = DISAS_EOB_NEXT;
6126 break;
6127
6128 case 0xf8: /* swapgs */
6129 #ifdef TARGET_X86_64
6130 if (CODE64(s)) {
6131 if (check_cpl0(s)) {
6132 tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]);
6133 tcg_gen_ld_tl(cpu_seg_base[R_GS], tcg_env,
6134 offsetof(CPUX86State, kernelgsbase));
6135 tcg_gen_st_tl(s->T0, tcg_env,
6136 offsetof(CPUX86State, kernelgsbase));
6137 }
6138 break;
6139 }
6140 #endif
6141 goto illegal_op;
6142
6143 case 0xf9: /* rdtscp */
6144 if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
6145 goto illegal_op;
6146 }
6147 gen_update_cc_op(s);
6148 gen_update_eip_cur(s);
6149 translator_io_start(&s->base);
6150 gen_helper_rdtsc(tcg_env);
6151 gen_helper_rdpid(s->T0, tcg_env);
6152 gen_op_mov_reg_v(s, dflag, R_ECX, s->T0);
6153 break;
6154
6155 default:
6156 goto unknown_op;
6157 }
6158 break;
6159
6160 case 0x108: /* invd */
6161 case 0x109: /* wbinvd; wbnoinvd with REPZ prefix */
6162 if (check_cpl0(s)) {
6163 gen_svm_check_intercept(s, (b & 1) ? SVM_EXIT_WBINVD : SVM_EXIT_INVD);
6164 /* nothing to do */
6165 }
6166 break;
6167 case 0x63: /* arpl or movslS (x86_64) */
6168 #ifdef TARGET_X86_64
6169 if (CODE64(s)) {
6170 int d_ot;
6171 /* d_ot is the size of destination */
6172 d_ot = dflag;
6173
6174 modrm = x86_ldub_code(env, s);
6175 reg = ((modrm >> 3) & 7) | REX_R(s);
6176 mod = (modrm >> 6) & 3;
6177 rm = (modrm & 7) | REX_B(s);
6178
6179 if (mod == 3) {
6180 gen_op_mov_v_reg(s, MO_32, s->T0, rm);
6181 /* sign extend */
6182 if (d_ot == MO_64) {
6183 tcg_gen_ext32s_tl(s->T0, s->T0);
6184 }
6185 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
6186 } else {
6187 gen_lea_modrm(env, s, modrm);
6188 gen_op_ld_v(s, MO_32 | MO_SIGN, s->T0, s->A0);
6189 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
6190 }
6191 } else
6192 #endif
6193 {
6194 TCGLabel *label1;
6195 TCGv t0, t1, t2;
6196
6197 if (!PE(s) || VM86(s))
6198 goto illegal_op;
6199 t0 = tcg_temp_new();
6200 t1 = tcg_temp_new();
6201 t2 = tcg_temp_new();
6202 ot = MO_16;
6203 modrm = x86_ldub_code(env, s);
6204 reg = (modrm >> 3) & 7;
6205 mod = (modrm >> 6) & 3;
6206 rm = modrm & 7;
6207 if (mod != 3) {
6208 gen_lea_modrm(env, s, modrm);
6209 gen_op_ld_v(s, ot, t0, s->A0);
6210 } else {
6211 gen_op_mov_v_reg(s, ot, t0, rm);
6212 }
6213 gen_op_mov_v_reg(s, ot, t1, reg);
6214 tcg_gen_andi_tl(s->tmp0, t0, 3);
6215 tcg_gen_andi_tl(t1, t1, 3);
6216 tcg_gen_movi_tl(t2, 0);
6217 label1 = gen_new_label();
6218 tcg_gen_brcond_tl(TCG_COND_GE, s->tmp0, t1, label1);
6219 tcg_gen_andi_tl(t0, t0, ~3);
6220 tcg_gen_or_tl(t0, t0, t1);
6221 tcg_gen_movi_tl(t2, CC_Z);
6222 gen_set_label(label1);
6223 if (mod != 3) {
6224 gen_op_st_v(s, ot, t0, s->A0);
6225 } else {
6226 gen_op_mov_reg_v(s, ot, rm, t0);
6227 }
6228 gen_compute_eflags(s);
6229 tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
6230 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
6231 }
6232 break;
6233 case 0x102: /* lar */
6234 case 0x103: /* lsl */
6235 {
6236 TCGLabel *label1;
6237 TCGv t0;
6238 if (!PE(s) || VM86(s))
6239 goto illegal_op;
6240 ot = dflag != MO_16 ? MO_32 : MO_16;
6241 modrm = x86_ldub_code(env, s);
6242 reg = ((modrm >> 3) & 7) | REX_R(s);
6243 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
6244 t0 = tcg_temp_new();
6245 gen_update_cc_op(s);
6246 if (b == 0x102) {
6247 gen_helper_lar(t0, tcg_env, s->T0);
6248 } else {
6249 gen_helper_lsl(t0, tcg_env, s->T0);
6250 }
6251 tcg_gen_andi_tl(s->tmp0, cpu_cc_src, CC_Z);
6252 label1 = gen_new_label();
6253 tcg_gen_brcondi_tl(TCG_COND_EQ, s->tmp0, 0, label1);
6254 gen_op_mov_reg_v(s, ot, reg, t0);
6255 gen_set_label(label1);
6256 set_cc_op(s, CC_OP_EFLAGS);
6257 }
6258 break;
6259 case 0x118:
6260 modrm = x86_ldub_code(env, s);
6261 mod = (modrm >> 6) & 3;
6262 op = (modrm >> 3) & 7;
6263 switch(op) {
6264 case 0: /* prefetchnta */
6265 case 1: /* prefetchnt0 */
6266 case 2: /* prefetchnt0 */
6267 case 3: /* prefetchnt0 */
6268 if (mod == 3)
6269 goto illegal_op;
6270 gen_nop_modrm(env, s, modrm);
6271 /* nothing more to do */
6272 break;
6273 default: /* nop (multi byte) */
6274 gen_nop_modrm(env, s, modrm);
6275 break;
6276 }
6277 break;
6278 case 0x11a:
6279 modrm = x86_ldub_code(env, s);
6280 if (s->flags & HF_MPX_EN_MASK) {
6281 mod = (modrm >> 6) & 3;
6282 reg = ((modrm >> 3) & 7) | REX_R(s);
6283 if (prefixes & PREFIX_REPZ) {
6284 /* bndcl */
6285 if (reg >= 4
6286 || (prefixes & PREFIX_LOCK)
6287 || s->aflag == MO_16) {
6288 goto illegal_op;
6289 }
6290 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
6291 } else if (prefixes & PREFIX_REPNZ) {
6292 /* bndcu */
6293 if (reg >= 4
6294 || (prefixes & PREFIX_LOCK)
6295 || s->aflag == MO_16) {
6296 goto illegal_op;
6297 }
6298 TCGv_i64 notu = tcg_temp_new_i64();
6299 tcg_gen_not_i64(notu, cpu_bndu[reg]);
6300 gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
6301 } else if (prefixes & PREFIX_DATA) {
6302 /* bndmov -- from reg/mem */
6303 if (reg >= 4 || s->aflag == MO_16) {
6304 goto illegal_op;
6305 }
6306 if (mod == 3) {
6307 int reg2 = (modrm & 7) | REX_B(s);
6308 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
6309 goto illegal_op;
6310 }
6311 if (s->flags & HF_MPX_IU_MASK) {
6312 tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
6313 tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
6314 }
6315 } else {
6316 gen_lea_modrm(env, s, modrm);
6317 if (CODE64(s)) {
6318 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
6319 s->mem_index, MO_LEUQ);
6320 tcg_gen_addi_tl(s->A0, s->A0, 8);
6321 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
6322 s->mem_index, MO_LEUQ);
6323 } else {
6324 tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
6325 s->mem_index, MO_LEUL);
6326 tcg_gen_addi_tl(s->A0, s->A0, 4);
6327 tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
6328 s->mem_index, MO_LEUL);
6329 }
6330 /* bnd registers are now in-use */
6331 gen_set_hflag(s, HF_MPX_IU_MASK);
6332 }
6333 } else if (mod != 3) {
6334 /* bndldx */
6335 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6336 if (reg >= 4
6337 || (prefixes & PREFIX_LOCK)
6338 || s->aflag == MO_16
6339 || a.base < -1) {
6340 goto illegal_op;
6341 }
6342 if (a.base >= 0) {
6343 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
6344 } else {
6345 tcg_gen_movi_tl(s->A0, 0);
6346 }
6347 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
6348 if (a.index >= 0) {
6349 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
6350 } else {
6351 tcg_gen_movi_tl(s->T0, 0);
6352 }
6353 if (CODE64(s)) {
6354 gen_helper_bndldx64(cpu_bndl[reg], tcg_env, s->A0, s->T0);
6355 tcg_gen_ld_i64(cpu_bndu[reg], tcg_env,
6356 offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
6357 } else {
6358 gen_helper_bndldx32(cpu_bndu[reg], tcg_env, s->A0, s->T0);
6359 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
6360 tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
6361 }
6362 gen_set_hflag(s, HF_MPX_IU_MASK);
6363 }
6364 }
6365 gen_nop_modrm(env, s, modrm);
6366 break;
6367 case 0x11b:
6368 modrm = x86_ldub_code(env, s);
6369 if (s->flags & HF_MPX_EN_MASK) {
6370 mod = (modrm >> 6) & 3;
6371 reg = ((modrm >> 3) & 7) | REX_R(s);
6372 if (mod != 3 && (prefixes & PREFIX_REPZ)) {
6373 /* bndmk */
6374 if (reg >= 4
6375 || (prefixes & PREFIX_LOCK)
6376 || s->aflag == MO_16) {
6377 goto illegal_op;
6378 }
6379 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6380 if (a.base >= 0) {
6381 tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
6382 if (!CODE64(s)) {
6383 tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
6384 }
6385 } else if (a.base == -1) {
6386 /* no base register has lower bound of 0 */
6387 tcg_gen_movi_i64(cpu_bndl[reg], 0);
6388 } else {
6389 /* rip-relative generates #ud */
6390 goto illegal_op;
6391 }
6392 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, a, false));
6393 if (!CODE64(s)) {
6394 tcg_gen_ext32u_tl(s->A0, s->A0);
6395 }
6396 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0);
6397 /* bnd registers are now in-use */
6398 gen_set_hflag(s, HF_MPX_IU_MASK);
6399 break;
6400 } else if (prefixes & PREFIX_REPNZ) {
6401 /* bndcn */
6402 if (reg >= 4
6403 || (prefixes & PREFIX_LOCK)
6404 || s->aflag == MO_16) {
6405 goto illegal_op;
6406 }
6407 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
6408 } else if (prefixes & PREFIX_DATA) {
6409 /* bndmov -- to reg/mem */
6410 if (reg >= 4 || s->aflag == MO_16) {
6411 goto illegal_op;
6412 }
6413 if (mod == 3) {
6414 int reg2 = (modrm & 7) | REX_B(s);
6415 if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
6416 goto illegal_op;
6417 }
6418 if (s->flags & HF_MPX_IU_MASK) {
6419 tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
6420 tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
6421 }
6422 } else {
6423 gen_lea_modrm(env, s, modrm);
6424 if (CODE64(s)) {
6425 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
6426 s->mem_index, MO_LEUQ);
6427 tcg_gen_addi_tl(s->A0, s->A0, 8);
6428 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
6429 s->mem_index, MO_LEUQ);
6430 } else {
6431 tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
6432 s->mem_index, MO_LEUL);
6433 tcg_gen_addi_tl(s->A0, s->A0, 4);
6434 tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
6435 s->mem_index, MO_LEUL);
6436 }
6437 }
6438 } else if (mod != 3) {
6439 /* bndstx */
6440 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6441 if (reg >= 4
6442 || (prefixes & PREFIX_LOCK)
6443 || s->aflag == MO_16
6444 || a.base < -1) {
6445 goto illegal_op;
6446 }
6447 if (a.base >= 0) {
6448 tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
6449 } else {
6450 tcg_gen_movi_tl(s->A0, 0);
6451 }
6452 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
6453 if (a.index >= 0) {
6454 tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
6455 } else {
6456 tcg_gen_movi_tl(s->T0, 0);
6457 }
6458 if (CODE64(s)) {
6459 gen_helper_bndstx64(tcg_env, s->A0, s->T0,
6460 cpu_bndl[reg], cpu_bndu[reg]);
6461 } else {
6462 gen_helper_bndstx32(tcg_env, s->A0, s->T0,
6463 cpu_bndl[reg], cpu_bndu[reg]);
6464 }
6465 }
6466 }
6467 gen_nop_modrm(env, s, modrm);
6468 break;
6469 case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
6470 modrm = x86_ldub_code(env, s);
6471 gen_nop_modrm(env, s, modrm);
6472 break;
6473
6474 case 0x120: /* mov reg, crN */
6475 case 0x122: /* mov crN, reg */
6476 if (!check_cpl0(s)) {
6477 break;
6478 }
6479 modrm = x86_ldub_code(env, s);
6480 /*
6481 * Ignore the mod bits (assume (modrm&0xc0)==0xc0).
6482 * AMD documentation (24594.pdf) and testing of Intel 386 and 486
6483 * processors all show that the mod bits are assumed to be 1's,
6484 * regardless of actual values.
6485 */
6486 rm = (modrm & 7) | REX_B(s);
6487 reg = ((modrm >> 3) & 7) | REX_R(s);
6488 switch (reg) {
6489 case 0:
6490 if ((prefixes & PREFIX_LOCK) &&
6491 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
6492 reg = 8;
6493 }
6494 break;
6495 case 2:
6496 case 3:
6497 case 4:
6498 case 8:
6499 break;
6500 default:
6501 goto unknown_op;
6502 }
6503 ot = (CODE64(s) ? MO_64 : MO_32);
6504
6505 translator_io_start(&s->base);
6506 if (b & 2) {
6507 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
6508 gen_op_mov_v_reg(s, ot, s->T0, rm);
6509 gen_helper_write_crN(tcg_env, tcg_constant_i32(reg), s->T0);
6510 s->base.is_jmp = DISAS_EOB_NEXT;
6511 } else {
6512 gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
6513 gen_helper_read_crN(s->T0, tcg_env, tcg_constant_i32(reg));
6514 gen_op_mov_reg_v(s, ot, rm, s->T0);
6515 }
6516 break;
6517
6518 case 0x121: /* mov reg, drN */
6519 case 0x123: /* mov drN, reg */
6520 if (check_cpl0(s)) {
6521 modrm = x86_ldub_code(env, s);
6522 /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
6523 * AMD documentation (24594.pdf) and testing of
6524 * intel 386 and 486 processors all show that the mod bits
6525 * are assumed to be 1's, regardless of actual values.
6526 */
6527 rm = (modrm & 7) | REX_B(s);
6528 reg = ((modrm >> 3) & 7) | REX_R(s);
6529 if (CODE64(s))
6530 ot = MO_64;
6531 else
6532 ot = MO_32;
6533 if (reg >= 8) {
6534 goto illegal_op;
6535 }
6536 if (b & 2) {
6537 gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg);
6538 gen_op_mov_v_reg(s, ot, s->T0, rm);
6539 tcg_gen_movi_i32(s->tmp2_i32, reg);
6540 gen_helper_set_dr(tcg_env, s->tmp2_i32, s->T0);
6541 s->base.is_jmp = DISAS_EOB_NEXT;
6542 } else {
6543 gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg);
6544 tcg_gen_movi_i32(s->tmp2_i32, reg);
6545 gen_helper_get_dr(s->T0, tcg_env, s->tmp2_i32);
6546 gen_op_mov_reg_v(s, ot, rm, s->T0);
6547 }
6548 }
6549 break;
6550 case 0x106: /* clts */
6551 if (check_cpl0(s)) {
6552 gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
6553 gen_helper_clts(tcg_env);
6554 /* abort block because static cpu state changed */
6555 s->base.is_jmp = DISAS_EOB_NEXT;
6556 }
6557 break;
6558 /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
6559 case 0x1c3: /* MOVNTI reg, mem */
6560 if (!(s->cpuid_features & CPUID_SSE2))
6561 goto illegal_op;
6562 ot = mo_64_32(dflag);
6563 modrm = x86_ldub_code(env, s);
6564 mod = (modrm >> 6) & 3;
6565 if (mod == 3)
6566 goto illegal_op;
6567 reg = ((modrm >> 3) & 7) | REX_R(s);
6568 /* generate a generic store */
6569 gen_ldst_modrm(env, s, modrm, ot, reg, 1);
6570 break;
6571 case 0x1ae:
6572 modrm = x86_ldub_code(env, s);
6573 switch (modrm) {
6574 CASE_MODRM_MEM_OP(0): /* fxsave */
6575 if (!(s->cpuid_features & CPUID_FXSR)
6576 || (prefixes & PREFIX_LOCK)) {
6577 goto illegal_op;
6578 }
6579 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
6580 gen_exception(s, EXCP07_PREX);
6581 break;
6582 }
6583 gen_lea_modrm(env, s, modrm);
6584 gen_helper_fxsave(tcg_env, s->A0);
6585 break;
6586
6587 CASE_MODRM_MEM_OP(1): /* fxrstor */
6588 if (!(s->cpuid_features & CPUID_FXSR)
6589 || (prefixes & PREFIX_LOCK)) {
6590 goto illegal_op;
6591 }
6592 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
6593 gen_exception(s, EXCP07_PREX);
6594 break;
6595 }
6596 gen_lea_modrm(env, s, modrm);
6597 gen_helper_fxrstor(tcg_env, s->A0);
6598 break;
6599
6600 CASE_MODRM_MEM_OP(2): /* ldmxcsr */
6601 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
6602 goto illegal_op;
6603 }
6604 if (s->flags & HF_TS_MASK) {
6605 gen_exception(s, EXCP07_PREX);
6606 break;
6607 }
6608 gen_lea_modrm(env, s, modrm);
6609 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
6610 gen_helper_ldmxcsr(tcg_env, s->tmp2_i32);
6611 break;
6612
6613 CASE_MODRM_MEM_OP(3): /* stmxcsr */
6614 if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
6615 goto illegal_op;
6616 }
6617 if (s->flags & HF_TS_MASK) {
6618 gen_exception(s, EXCP07_PREX);
6619 break;
6620 }
6621 gen_helper_update_mxcsr(tcg_env);
6622 gen_lea_modrm(env, s, modrm);
6623 tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, mxcsr));
6624 gen_op_st_v(s, MO_32, s->T0, s->A0);
6625 break;
6626
6627 CASE_MODRM_MEM_OP(4): /* xsave */
6628 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
6629 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
6630 | PREFIX_REPZ | PREFIX_REPNZ))) {
6631 goto illegal_op;
6632 }
6633 gen_lea_modrm(env, s, modrm);
6634 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6635 cpu_regs[R_EDX]);
6636 gen_helper_xsave(tcg_env, s->A0, s->tmp1_i64);
6637 break;
6638
6639 CASE_MODRM_MEM_OP(5): /* xrstor */
6640 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
6641 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
6642 | PREFIX_REPZ | PREFIX_REPNZ))) {
6643 goto illegal_op;
6644 }
6645 gen_lea_modrm(env, s, modrm);
6646 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6647 cpu_regs[R_EDX]);
6648 gen_helper_xrstor(tcg_env, s->A0, s->tmp1_i64);
6649 /* XRSTOR is how MPX is enabled, which changes how
6650 we translate. Thus we need to end the TB. */
6651 s->base.is_jmp = DISAS_EOB_NEXT;
6652 break;
6653
6654 CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
6655 if (prefixes & PREFIX_LOCK) {
6656 goto illegal_op;
6657 }
6658 if (prefixes & PREFIX_DATA) {
6659 /* clwb */
6660 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
6661 goto illegal_op;
6662 }
6663 gen_nop_modrm(env, s, modrm);
6664 } else {
6665 /* xsaveopt */
6666 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
6667 || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
6668 || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
6669 goto illegal_op;
6670 }
6671 gen_lea_modrm(env, s, modrm);
6672 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6673 cpu_regs[R_EDX]);
6674 gen_helper_xsaveopt(tcg_env, s->A0, s->tmp1_i64);
6675 }
6676 break;
6677
6678 CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
6679 if (prefixes & PREFIX_LOCK) {
6680 goto illegal_op;
6681 }
6682 if (prefixes & PREFIX_DATA) {
6683 /* clflushopt */
6684 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
6685 goto illegal_op;
6686 }
6687 } else {
6688 /* clflush */
6689 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))
6690 || !(s->cpuid_features & CPUID_CLFLUSH)) {
6691 goto illegal_op;
6692 }
6693 }
6694 gen_nop_modrm(env, s, modrm);
6695 break;
6696
6697 case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
6698 case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
6699 case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
6700 case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
6701 if (CODE64(s)
6702 && (prefixes & PREFIX_REPZ)
6703 && !(prefixes & PREFIX_LOCK)
6704 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
6705 TCGv base, treg, src, dst;
6706
6707 /* Preserve hflags bits by testing CR4 at runtime. */
6708 tcg_gen_movi_i32(s->tmp2_i32, CR4_FSGSBASE_MASK);
6709 gen_helper_cr4_testbit(tcg_env, s->tmp2_i32);
6710
6711 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
6712 treg = cpu_regs[(modrm & 7) | REX_B(s)];
6713
6714 if (modrm & 0x10) {
6715 /* wr*base */
6716 dst = base, src = treg;
6717 } else {
6718 /* rd*base */
6719 dst = treg, src = base;
6720 }
6721
6722 if (s->dflag == MO_32) {
6723 tcg_gen_ext32u_tl(dst, src);
6724 } else {
6725 tcg_gen_mov_tl(dst, src);
6726 }
6727 break;
6728 }
6729 goto unknown_op;
6730
6731 case 0xf8: /* sfence / pcommit */
6732 if (prefixes & PREFIX_DATA) {
6733 /* pcommit */
6734 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
6735 || (prefixes & PREFIX_LOCK)) {
6736 goto illegal_op;
6737 }
6738 break;
6739 }
6740 /* fallthru */
6741 case 0xf9 ... 0xff: /* sfence */
6742 if (!(s->cpuid_features & CPUID_SSE)
6743 || (prefixes & PREFIX_LOCK)) {
6744 goto illegal_op;
6745 }
6746 tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
6747 break;
6748 case 0xe8 ... 0xef: /* lfence */
6749 if (!(s->cpuid_features & CPUID_SSE)
6750 || (prefixes & PREFIX_LOCK)) {
6751 goto illegal_op;
6752 }
6753 tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
6754 break;
6755 case 0xf0 ... 0xf7: /* mfence */
6756 if (!(s->cpuid_features & CPUID_SSE2)
6757 || (prefixes & PREFIX_LOCK)) {
6758 goto illegal_op;
6759 }
6760 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
6761 break;
6762
6763 default:
6764 goto unknown_op;
6765 }
6766 break;
6767
6768 case 0x10d: /* 3DNow! prefetch(w) */
6769 modrm = x86_ldub_code(env, s);
6770 mod = (modrm >> 6) & 3;
6771 if (mod == 3)
6772 goto illegal_op;
6773 gen_nop_modrm(env, s, modrm);
6774 break;
6775 case 0x1aa: /* rsm */
6776 gen_svm_check_intercept(s, SVM_EXIT_RSM);
6777 if (!(s->flags & HF_SMM_MASK))
6778 goto illegal_op;
6779 #ifdef CONFIG_USER_ONLY
6780 /* we should not be in SMM mode */
6781 g_assert_not_reached();
6782 #else
6783 gen_update_cc_op(s);
6784 gen_update_eip_next(s);
6785 gen_helper_rsm(tcg_env);
6786 #endif /* CONFIG_USER_ONLY */
6787 s->base.is_jmp = DISAS_EOB_ONLY;
6788 break;
6789 case 0x1b8: /* SSE4.2 popcnt */
6790 if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
6791 PREFIX_REPZ)
6792 goto illegal_op;
6793 if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
6794 goto illegal_op;
6795
6796 modrm = x86_ldub_code(env, s);
6797 reg = ((modrm >> 3) & 7) | REX_R(s);
6798
6799 if (s->prefix & PREFIX_DATA) {
6800 ot = MO_16;
6801 } else {
6802 ot = mo_64_32(dflag);
6803 }
6804
6805 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6806 gen_extu(ot, s->T0);
6807 tcg_gen_mov_tl(cpu_cc_src, s->T0);
6808 tcg_gen_ctpop_tl(s->T0, s->T0);
6809 gen_op_mov_reg_v(s, ot, reg, s->T0);
6810
6811 set_cc_op(s, CC_OP_POPCNT);
6812 break;
6813 case 0x10e ... 0x117:
6814 case 0x128 ... 0x12f:
6815 case 0x138 ... 0x13a:
6816 case 0x150 ... 0x179:
6817 case 0x17c ... 0x17f:
6818 case 0x1c2:
6819 case 0x1c4 ... 0x1c6:
6820 case 0x1d0 ... 0x1fe:
6821 disas_insn_new(s, cpu, b);
6822 break;
6823 default:
6824 goto unknown_op;
6825 }
6826 return true;
6827 illegal_op:
6828 gen_illegal_opcode(s);
6829 return true;
6830 unknown_op:
6831 gen_unknown_opcode(env, s);
6832 return true;
6833 }
6834
6835 void tcg_x86_init(void)
6836 {
6837 static const char reg_names[CPU_NB_REGS][4] = {
6838 #ifdef TARGET_X86_64
6839 [R_EAX] = "rax",
6840 [R_EBX] = "rbx",
6841 [R_ECX] = "rcx",
6842 [R_EDX] = "rdx",
6843 [R_ESI] = "rsi",
6844 [R_EDI] = "rdi",
6845 [R_EBP] = "rbp",
6846 [R_ESP] = "rsp",
6847 [8] = "r8",
6848 [9] = "r9",
6849 [10] = "r10",
6850 [11] = "r11",
6851 [12] = "r12",
6852 [13] = "r13",
6853 [14] = "r14",
6854 [15] = "r15",
6855 #else
6856 [R_EAX] = "eax",
6857 [R_EBX] = "ebx",
6858 [R_ECX] = "ecx",
6859 [R_EDX] = "edx",
6860 [R_ESI] = "esi",
6861 [R_EDI] = "edi",
6862 [R_EBP] = "ebp",
6863 [R_ESP] = "esp",
6864 #endif
6865 };
6866 static const char eip_name[] = {
6867 #ifdef TARGET_X86_64
6868 "rip"
6869 #else
6870 "eip"
6871 #endif
6872 };
6873 static const char seg_base_names[6][8] = {
6874 [R_CS] = "cs_base",
6875 [R_DS] = "ds_base",
6876 [R_ES] = "es_base",
6877 [R_FS] = "fs_base",
6878 [R_GS] = "gs_base",
6879 [R_SS] = "ss_base",
6880 };
6881 static const char bnd_regl_names[4][8] = {
6882 "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
6883 };
6884 static const char bnd_regu_names[4][8] = {
6885 "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
6886 };
6887 int i;
6888
6889 cpu_cc_op = tcg_global_mem_new_i32(tcg_env,
6890 offsetof(CPUX86State, cc_op), "cc_op");
6891 cpu_cc_dst = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_dst),
6892 "cc_dst");
6893 cpu_cc_src = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src),
6894 "cc_src");
6895 cpu_cc_src2 = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, cc_src2),
6896 "cc_src2");
6897 cpu_eip = tcg_global_mem_new(tcg_env, offsetof(CPUX86State, eip), eip_name);
6898
6899 for (i = 0; i < CPU_NB_REGS; ++i) {
6900 cpu_regs[i] = tcg_global_mem_new(tcg_env,
6901 offsetof(CPUX86State, regs[i]),
6902 reg_names[i]);
6903 }
6904
6905 for (i = 0; i < 6; ++i) {
6906 cpu_seg_base[i]
6907 = tcg_global_mem_new(tcg_env,
6908 offsetof(CPUX86State, segs[i].base),
6909 seg_base_names[i]);
6910 }
6911
6912 for (i = 0; i < 4; ++i) {
6913 cpu_bndl[i]
6914 = tcg_global_mem_new_i64(tcg_env,
6915 offsetof(CPUX86State, bnd_regs[i].lb),
6916 bnd_regl_names[i]);
6917 cpu_bndu[i]
6918 = tcg_global_mem_new_i64(tcg_env,
6919 offsetof(CPUX86State, bnd_regs[i].ub),
6920 bnd_regu_names[i]);
6921 }
6922 }
6923
6924 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
6925 {
6926 DisasContext *dc = container_of(dcbase, DisasContext, base);
6927 CPUX86State *env = cpu_env(cpu);
6928 uint32_t flags = dc->base.tb->flags;
6929 uint32_t cflags = tb_cflags(dc->base.tb);
6930 int cpl = (flags >> HF_CPL_SHIFT) & 3;
6931 int iopl = (flags >> IOPL_SHIFT) & 3;
6932
6933 dc->cs_base = dc->base.tb->cs_base;
6934 dc->pc_save = dc->base.pc_next;
6935 dc->flags = flags;
6936 #ifndef CONFIG_USER_ONLY
6937 dc->cpl = cpl;
6938 dc->iopl = iopl;
6939 #endif
6940
6941 /* We make some simplifying assumptions; validate they're correct. */
6942 g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0));
6943 g_assert(CPL(dc) == cpl);
6944 g_assert(IOPL(dc) == iopl);
6945 g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0));
6946 g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0));
6947 g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0));
6948 g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0));
6949 g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
6950 g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
6951 g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0));
6952 g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0));
6953
6954 dc->cc_op = CC_OP_DYNAMIC;
6955 dc->cc_op_dirty = false;
6956 dc->popl_esp_hack = 0;
6957 /* select memory access functions */
6958 dc->mem_index = cpu_mmu_index(env, false);
6959 dc->cpuid_features = env->features[FEAT_1_EDX];
6960 dc->cpuid_ext_features = env->features[FEAT_1_ECX];
6961 dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
6962 dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
6963 dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
6964 dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX];
6965 dc->cpuid_7_1_eax_features = env->features[FEAT_7_1_EAX];
6966 dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
6967 dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) ||
6968 (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
6969 /*
6970 * If jmp_opt, we want to handle each string instruction individually.
6971 * For icount also disable repz optimization so that each iteration
6972 * is accounted separately.
6973 */
6974 dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT);
6975
6976 dc->T0 = tcg_temp_new();
6977 dc->T1 = tcg_temp_new();
6978 dc->A0 = tcg_temp_new();
6979
6980 dc->tmp0 = tcg_temp_new();
6981 dc->tmp1_i64 = tcg_temp_new_i64();
6982 dc->tmp2_i32 = tcg_temp_new_i32();
6983 dc->tmp3_i32 = tcg_temp_new_i32();
6984 dc->tmp4 = tcg_temp_new();
6985 dc->cc_srcT = tcg_temp_new();
6986 }
6987
6988 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
6989 {
6990 }
6991
6992 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
6993 {
6994 DisasContext *dc = container_of(dcbase, DisasContext, base);
6995 target_ulong pc_arg = dc->base.pc_next;
6996
6997 dc->prev_insn_end = tcg_last_op();
6998 if (tb_cflags(dcbase->tb) & CF_PCREL) {
6999 pc_arg &= ~TARGET_PAGE_MASK;
7000 }
7001 tcg_gen_insn_start(pc_arg, dc->cc_op);
7002 }
7003
7004 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
7005 {
7006 DisasContext *dc = container_of(dcbase, DisasContext, base);
7007
7008 #ifdef TARGET_VSYSCALL_PAGE
7009 /*
7010 * Detect entry into the vsyscall page and invoke the syscall.
7011 */
7012 if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) {
7013 gen_exception(dc, EXCP_VSYSCALL);
7014 dc->base.pc_next = dc->pc + 1;
7015 return;
7016 }
7017 #endif
7018
7019 if (disas_insn(dc, cpu)) {
7020 target_ulong pc_next = dc->pc;
7021 dc->base.pc_next = pc_next;
7022
7023 if (dc->base.is_jmp == DISAS_NEXT) {
7024 if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
7025 /*
7026 * If single step mode, we generate only one instruction and
7027 * generate an exception.
7028 * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7029 * the flag and abort the translation to give the irqs a
7030 * chance to happen.
7031 */
7032 dc->base.is_jmp = DISAS_EOB_NEXT;
7033 } else if (!is_same_page(&dc->base, pc_next)) {
7034 dc->base.is_jmp = DISAS_TOO_MANY;
7035 }
7036 }
7037 }
7038 }
7039
7040 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
7041 {
7042 DisasContext *dc = container_of(dcbase, DisasContext, base);
7043
7044 switch (dc->base.is_jmp) {
7045 case DISAS_NORETURN:
7046 break;
7047 case DISAS_TOO_MANY:
7048 gen_update_cc_op(dc);
7049 gen_jmp_rel_csize(dc, 0, 0);
7050 break;
7051 case DISAS_EOB_NEXT:
7052 gen_update_cc_op(dc);
7053 gen_update_eip_cur(dc);
7054 /* fall through */
7055 case DISAS_EOB_ONLY:
7056 gen_eob(dc);
7057 break;
7058 case DISAS_EOB_INHIBIT_IRQ:
7059 gen_update_cc_op(dc);
7060 gen_update_eip_cur(dc);
7061 gen_eob_inhibit_irq(dc, true);
7062 break;
7063 case DISAS_JUMP:
7064 gen_jr(dc);
7065 break;
7066 default:
7067 g_assert_not_reached();
7068 }
7069 }
7070
7071 static void i386_tr_disas_log(const DisasContextBase *dcbase,
7072 CPUState *cpu, FILE *logfile)
7073 {
7074 DisasContext *dc = container_of(dcbase, DisasContext, base);
7075
7076 fprintf(logfile, "IN: %s\n", lookup_symbol(dc->base.pc_first));
7077 target_disas(logfile, cpu, dc->base.pc_first, dc->base.tb->size);
7078 }
7079
7080 static const TranslatorOps i386_tr_ops = {
7081 .init_disas_context = i386_tr_init_disas_context,
7082 .tb_start = i386_tr_tb_start,
7083 .insn_start = i386_tr_insn_start,
7084 .translate_insn = i386_tr_translate_insn,
7085 .tb_stop = i386_tr_tb_stop,
7086 .disas_log = i386_tr_disas_log,
7087 };
7088
7089 /* generate intermediate code for basic block 'tb'. */
7090 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
7091 target_ulong pc, void *host_pc)
7092 {
7093 DisasContext dc;
7094
7095 translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base);
7096 }