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