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