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