xref: /openbmc/qemu/target/i386/tcg/translate.c (revision d53106c997e5c8e61e37ae9ff9f0e1f243b03968)
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 #include "exec/gen-icount.h"
82 
83 typedef struct DisasContext {
84     DisasContextBase base;
85 
86     target_ulong pc;       /* pc = eip + cs_base */
87     target_ulong cs_base;  /* base of CS segment */
88     target_ulong pc_save;
89 
90     MemOp aflag;
91     MemOp dflag;
92 
93     int8_t override; /* -1 if no override, else R_CS, R_DS, etc */
94     uint8_t prefix;
95 
96     bool has_modrm;
97     uint8_t modrm;
98 
99 #ifndef CONFIG_USER_ONLY
100     uint8_t cpl;   /* code priv level */
101     uint8_t iopl;  /* i/o priv level */
102 #endif
103     uint8_t vex_l;  /* vex vector length */
104     uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
105     uint8_t popl_esp_hack; /* for correct popl with esp base handling */
106     uint8_t rip_offset; /* only used in x86_64, but left for simplicity */
107 
108 #ifdef TARGET_X86_64
109     uint8_t rex_r;
110     uint8_t rex_x;
111     uint8_t rex_b;
112 #endif
113     bool vex_w; /* used by AVX even on 32-bit processors */
114     bool jmp_opt; /* use direct block chaining for direct jumps */
115     bool repz_opt; /* optimize jumps within repz instructions */
116     bool cc_op_dirty;
117 
118     CCOp cc_op;  /* current CC operation */
119     int mem_index; /* select memory access functions */
120     uint32_t flags; /* all execution flags */
121     int cpuid_features;
122     int cpuid_ext_features;
123     int cpuid_ext2_features;
124     int cpuid_ext3_features;
125     int cpuid_7_0_ebx_features;
126     int cpuid_7_0_ecx_features;
127     int cpuid_xsave_features;
128 
129     /* TCG local temps */
130     TCGv cc_srcT;
131     TCGv A0;
132     TCGv T0;
133     TCGv T1;
134 
135     /* TCG local register indexes (only used inside old micro ops) */
136     TCGv tmp0;
137     TCGv tmp4;
138     TCGv_i32 tmp2_i32;
139     TCGv_i32 tmp3_i32;
140     TCGv_i64 tmp1_i64;
141 
142     sigjmp_buf jmpbuf;
143     TCGOp *prev_insn_end;
144 } DisasContext;
145 
146 #define DISAS_EOB_ONLY         DISAS_TARGET_0
147 #define DISAS_EOB_NEXT         DISAS_TARGET_1
148 #define DISAS_EOB_INHIBIT_IRQ  DISAS_TARGET_2
149 #define DISAS_JUMP             DISAS_TARGET_3
150 
151 /* The environment in which user-only runs is constrained. */
152 #ifdef CONFIG_USER_ONLY
153 #define PE(S)     true
154 #define CPL(S)    3
155 #define IOPL(S)   0
156 #define SVME(S)   false
157 #define GUEST(S)  false
158 #else
159 #define PE(S)     (((S)->flags & HF_PE_MASK) != 0)
160 #define CPL(S)    ((S)->cpl)
161 #define IOPL(S)   ((S)->iopl)
162 #define SVME(S)   (((S)->flags & HF_SVME_MASK) != 0)
163 #define GUEST(S)  (((S)->flags & HF_GUEST_MASK) != 0)
164 #endif
165 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
166 #define VM86(S)   false
167 #define CODE32(S) true
168 #define SS32(S)   true
169 #define ADDSEG(S) false
170 #else
171 #define VM86(S)   (((S)->flags & HF_VM_MASK) != 0)
172 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0)
173 #define SS32(S)   (((S)->flags & HF_SS32_MASK) != 0)
174 #define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0)
175 #endif
176 #if !defined(TARGET_X86_64)
177 #define CODE64(S) false
178 #define LMA(S)    false
179 #elif defined(CONFIG_USER_ONLY)
180 #define CODE64(S) true
181 #define LMA(S)    true
182 #else
183 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0)
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 */
3930         case 6: /* RDRAND */
3931             if (mod != 3 ||
3932                 (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) ||
3933                 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) {
3934                 goto illegal_op;
3935             }
3936             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3937                 gen_io_start();
3938                 s->base.is_jmp = DISAS_TOO_MANY;
3939             }
3940             gen_helper_rdrand(s->T0, cpu_env);
3941             rm = (modrm & 7) | REX_B(s);
3942             gen_op_mov_reg_v(s, dflag, rm, s->T0);
3943             set_cc_op(s, CC_OP_EFLAGS);
3944             break;
3945 
3946         default:
3947             goto illegal_op;
3948         }
3949         break;
3950 
3951         /**************************/
3952         /* push/pop */
3953     case 0x50 ... 0x57: /* push */
3954         gen_op_mov_v_reg(s, MO_32, s->T0, (b & 7) | REX_B(s));
3955         gen_push_v(s, s->T0);
3956         break;
3957     case 0x58 ... 0x5f: /* pop */
3958         ot = gen_pop_T0(s);
3959         /* NOTE: order is important for pop %sp */
3960         gen_pop_update(s, ot);
3961         gen_op_mov_reg_v(s, ot, (b & 7) | REX_B(s), s->T0);
3962         break;
3963     case 0x60: /* pusha */
3964         if (CODE64(s))
3965             goto illegal_op;
3966         gen_pusha(s);
3967         break;
3968     case 0x61: /* popa */
3969         if (CODE64(s))
3970             goto illegal_op;
3971         gen_popa(s);
3972         break;
3973     case 0x68: /* push Iv */
3974     case 0x6a:
3975         ot = mo_pushpop(s, dflag);
3976         if (b == 0x68)
3977             val = insn_get(env, s, ot);
3978         else
3979             val = (int8_t)insn_get(env, s, MO_8);
3980         tcg_gen_movi_tl(s->T0, val);
3981         gen_push_v(s, s->T0);
3982         break;
3983     case 0x8f: /* pop Ev */
3984         modrm = x86_ldub_code(env, s);
3985         mod = (modrm >> 6) & 3;
3986         ot = gen_pop_T0(s);
3987         if (mod == 3) {
3988             /* NOTE: order is important for pop %sp */
3989             gen_pop_update(s, ot);
3990             rm = (modrm & 7) | REX_B(s);
3991             gen_op_mov_reg_v(s, ot, rm, s->T0);
3992         } else {
3993             /* NOTE: order is important too for MMU exceptions */
3994             s->popl_esp_hack = 1 << ot;
3995             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
3996             s->popl_esp_hack = 0;
3997             gen_pop_update(s, ot);
3998         }
3999         break;
4000     case 0xc8: /* enter */
4001         {
4002             int level;
4003             val = x86_lduw_code(env, s);
4004             level = x86_ldub_code(env, s);
4005             gen_enter(s, val, level);
4006         }
4007         break;
4008     case 0xc9: /* leave */
4009         gen_leave(s);
4010         break;
4011     case 0x06: /* push es */
4012     case 0x0e: /* push cs */
4013     case 0x16: /* push ss */
4014     case 0x1e: /* push ds */
4015         if (CODE64(s))
4016             goto illegal_op;
4017         gen_op_movl_T0_seg(s, b >> 3);
4018         gen_push_v(s, s->T0);
4019         break;
4020     case 0x1a0: /* push fs */
4021     case 0x1a8: /* push gs */
4022         gen_op_movl_T0_seg(s, (b >> 3) & 7);
4023         gen_push_v(s, s->T0);
4024         break;
4025     case 0x07: /* pop es */
4026     case 0x17: /* pop ss */
4027     case 0x1f: /* pop ds */
4028         if (CODE64(s))
4029             goto illegal_op;
4030         reg = b >> 3;
4031         ot = gen_pop_T0(s);
4032         gen_movl_seg_T0(s, reg);
4033         gen_pop_update(s, ot);
4034         break;
4035     case 0x1a1: /* pop fs */
4036     case 0x1a9: /* pop gs */
4037         ot = gen_pop_T0(s);
4038         gen_movl_seg_T0(s, (b >> 3) & 7);
4039         gen_pop_update(s, ot);
4040         break;
4041 
4042         /**************************/
4043         /* mov */
4044     case 0x88:
4045     case 0x89: /* mov Gv, Ev */
4046         ot = mo_b_d(b, dflag);
4047         modrm = x86_ldub_code(env, s);
4048         reg = ((modrm >> 3) & 7) | REX_R(s);
4049 
4050         /* generate a generic store */
4051         gen_ldst_modrm(env, s, modrm, ot, reg, 1);
4052         break;
4053     case 0xc6:
4054     case 0xc7: /* mov Ev, Iv */
4055         ot = mo_b_d(b, dflag);
4056         modrm = x86_ldub_code(env, s);
4057         mod = (modrm >> 6) & 3;
4058         if (mod != 3) {
4059             s->rip_offset = insn_const_size(ot);
4060             gen_lea_modrm(env, s, modrm);
4061         }
4062         val = insn_get(env, s, ot);
4063         tcg_gen_movi_tl(s->T0, val);
4064         if (mod != 3) {
4065             gen_op_st_v(s, ot, s->T0, s->A0);
4066         } else {
4067             gen_op_mov_reg_v(s, ot, (modrm & 7) | REX_B(s), s->T0);
4068         }
4069         break;
4070     case 0x8a:
4071     case 0x8b: /* mov Ev, Gv */
4072         ot = mo_b_d(b, dflag);
4073         modrm = x86_ldub_code(env, s);
4074         reg = ((modrm >> 3) & 7) | REX_R(s);
4075 
4076         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4077         gen_op_mov_reg_v(s, ot, reg, s->T0);
4078         break;
4079     case 0x8e: /* mov seg, Gv */
4080         modrm = x86_ldub_code(env, s);
4081         reg = (modrm >> 3) & 7;
4082         if (reg >= 6 || reg == R_CS)
4083             goto illegal_op;
4084         gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
4085         gen_movl_seg_T0(s, reg);
4086         break;
4087     case 0x8c: /* mov Gv, seg */
4088         modrm = x86_ldub_code(env, s);
4089         reg = (modrm >> 3) & 7;
4090         mod = (modrm >> 6) & 3;
4091         if (reg >= 6)
4092             goto illegal_op;
4093         gen_op_movl_T0_seg(s, reg);
4094         ot = mod == 3 ? dflag : MO_16;
4095         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
4096         break;
4097 
4098     case 0x1b6: /* movzbS Gv, Eb */
4099     case 0x1b7: /* movzwS Gv, Eb */
4100     case 0x1be: /* movsbS Gv, Eb */
4101     case 0x1bf: /* movswS Gv, Eb */
4102         {
4103             MemOp d_ot;
4104             MemOp s_ot;
4105 
4106             /* d_ot is the size of destination */
4107             d_ot = dflag;
4108             /* ot is the size of source */
4109             ot = (b & 1) + MO_8;
4110             /* s_ot is the sign+size of source */
4111             s_ot = b & 8 ? MO_SIGN | ot : ot;
4112 
4113             modrm = x86_ldub_code(env, s);
4114             reg = ((modrm >> 3) & 7) | REX_R(s);
4115             mod = (modrm >> 6) & 3;
4116             rm = (modrm & 7) | REX_B(s);
4117 
4118             if (mod == 3) {
4119                 if (s_ot == MO_SB && byte_reg_is_xH(s, rm)) {
4120                     tcg_gen_sextract_tl(s->T0, cpu_regs[rm - 4], 8, 8);
4121                 } else {
4122                     gen_op_mov_v_reg(s, ot, s->T0, rm);
4123                     switch (s_ot) {
4124                     case MO_UB:
4125                         tcg_gen_ext8u_tl(s->T0, s->T0);
4126                         break;
4127                     case MO_SB:
4128                         tcg_gen_ext8s_tl(s->T0, s->T0);
4129                         break;
4130                     case MO_UW:
4131                         tcg_gen_ext16u_tl(s->T0, s->T0);
4132                         break;
4133                     default:
4134                     case MO_SW:
4135                         tcg_gen_ext16s_tl(s->T0, s->T0);
4136                         break;
4137                     }
4138                 }
4139                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
4140             } else {
4141                 gen_lea_modrm(env, s, modrm);
4142                 gen_op_ld_v(s, s_ot, s->T0, s->A0);
4143                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
4144             }
4145         }
4146         break;
4147 
4148     case 0x8d: /* lea */
4149         modrm = x86_ldub_code(env, s);
4150         mod = (modrm >> 6) & 3;
4151         if (mod == 3)
4152             goto illegal_op;
4153         reg = ((modrm >> 3) & 7) | REX_R(s);
4154         {
4155             AddressParts a = gen_lea_modrm_0(env, s, modrm);
4156             TCGv ea = gen_lea_modrm_1(s, a, false);
4157             gen_lea_v_seg(s, s->aflag, ea, -1, -1);
4158             gen_op_mov_reg_v(s, dflag, reg, s->A0);
4159         }
4160         break;
4161 
4162     case 0xa0: /* mov EAX, Ov */
4163     case 0xa1:
4164     case 0xa2: /* mov Ov, EAX */
4165     case 0xa3:
4166         {
4167             target_ulong offset_addr;
4168 
4169             ot = mo_b_d(b, dflag);
4170             offset_addr = insn_get_addr(env, s, s->aflag);
4171             tcg_gen_movi_tl(s->A0, offset_addr);
4172             gen_add_A0_ds_seg(s);
4173             if ((b & 2) == 0) {
4174                 gen_op_ld_v(s, ot, s->T0, s->A0);
4175                 gen_op_mov_reg_v(s, ot, R_EAX, s->T0);
4176             } else {
4177                 gen_op_mov_v_reg(s, ot, s->T0, R_EAX);
4178                 gen_op_st_v(s, ot, s->T0, s->A0);
4179             }
4180         }
4181         break;
4182     case 0xd7: /* xlat */
4183         tcg_gen_mov_tl(s->A0, cpu_regs[R_EBX]);
4184         tcg_gen_ext8u_tl(s->T0, cpu_regs[R_EAX]);
4185         tcg_gen_add_tl(s->A0, s->A0, s->T0);
4186         gen_extu(s->aflag, s->A0);
4187         gen_add_A0_ds_seg(s);
4188         gen_op_ld_v(s, MO_8, s->T0, s->A0);
4189         gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0);
4190         break;
4191     case 0xb0 ... 0xb7: /* mov R, Ib */
4192         val = insn_get(env, s, MO_8);
4193         tcg_gen_movi_tl(s->T0, val);
4194         gen_op_mov_reg_v(s, MO_8, (b & 7) | REX_B(s), s->T0);
4195         break;
4196     case 0xb8 ... 0xbf: /* mov R, Iv */
4197 #ifdef TARGET_X86_64
4198         if (dflag == MO_64) {
4199             uint64_t tmp;
4200             /* 64 bit case */
4201             tmp = x86_ldq_code(env, s);
4202             reg = (b & 7) | REX_B(s);
4203             tcg_gen_movi_tl(s->T0, tmp);
4204             gen_op_mov_reg_v(s, MO_64, reg, s->T0);
4205         } else
4206 #endif
4207         {
4208             ot = dflag;
4209             val = insn_get(env, s, ot);
4210             reg = (b & 7) | REX_B(s);
4211             tcg_gen_movi_tl(s->T0, val);
4212             gen_op_mov_reg_v(s, ot, reg, s->T0);
4213         }
4214         break;
4215 
4216     case 0x91 ... 0x97: /* xchg R, EAX */
4217     do_xchg_reg_eax:
4218         ot = dflag;
4219         reg = (b & 7) | REX_B(s);
4220         rm = R_EAX;
4221         goto do_xchg_reg;
4222     case 0x86:
4223     case 0x87: /* xchg Ev, Gv */
4224         ot = mo_b_d(b, dflag);
4225         modrm = x86_ldub_code(env, s);
4226         reg = ((modrm >> 3) & 7) | REX_R(s);
4227         mod = (modrm >> 6) & 3;
4228         if (mod == 3) {
4229             rm = (modrm & 7) | REX_B(s);
4230         do_xchg_reg:
4231             gen_op_mov_v_reg(s, ot, s->T0, reg);
4232             gen_op_mov_v_reg(s, ot, s->T1, rm);
4233             gen_op_mov_reg_v(s, ot, rm, s->T0);
4234             gen_op_mov_reg_v(s, ot, reg, s->T1);
4235         } else {
4236             gen_lea_modrm(env, s, modrm);
4237             gen_op_mov_v_reg(s, ot, s->T0, reg);
4238             /* for xchg, lock is implicit */
4239             tcg_gen_atomic_xchg_tl(s->T1, s->A0, s->T0,
4240                                    s->mem_index, ot | MO_LE);
4241             gen_op_mov_reg_v(s, ot, reg, s->T1);
4242         }
4243         break;
4244     case 0xc4: /* les Gv */
4245         /* In CODE64 this is VEX3; see above.  */
4246         op = R_ES;
4247         goto do_lxx;
4248     case 0xc5: /* lds Gv */
4249         /* In CODE64 this is VEX2; see above.  */
4250         op = R_DS;
4251         goto do_lxx;
4252     case 0x1b2: /* lss Gv */
4253         op = R_SS;
4254         goto do_lxx;
4255     case 0x1b4: /* lfs Gv */
4256         op = R_FS;
4257         goto do_lxx;
4258     case 0x1b5: /* lgs Gv */
4259         op = R_GS;
4260     do_lxx:
4261         ot = dflag != MO_16 ? MO_32 : MO_16;
4262         modrm = x86_ldub_code(env, s);
4263         reg = ((modrm >> 3) & 7) | REX_R(s);
4264         mod = (modrm >> 6) & 3;
4265         if (mod == 3)
4266             goto illegal_op;
4267         gen_lea_modrm(env, s, modrm);
4268         gen_op_ld_v(s, ot, s->T1, s->A0);
4269         gen_add_A0_im(s, 1 << ot);
4270         /* load the segment first to handle exceptions properly */
4271         gen_op_ld_v(s, MO_16, s->T0, s->A0);
4272         gen_movl_seg_T0(s, op);
4273         /* then put the data */
4274         gen_op_mov_reg_v(s, ot, reg, s->T1);
4275         break;
4276 
4277         /************************/
4278         /* shifts */
4279     case 0xc0:
4280     case 0xc1:
4281         /* shift Ev,Ib */
4282         shift = 2;
4283     grp2:
4284         {
4285             ot = mo_b_d(b, dflag);
4286             modrm = x86_ldub_code(env, s);
4287             mod = (modrm >> 6) & 3;
4288             op = (modrm >> 3) & 7;
4289 
4290             if (mod != 3) {
4291                 if (shift == 2) {
4292                     s->rip_offset = 1;
4293                 }
4294                 gen_lea_modrm(env, s, modrm);
4295                 opreg = OR_TMP0;
4296             } else {
4297                 opreg = (modrm & 7) | REX_B(s);
4298             }
4299 
4300             /* simpler op */
4301             if (shift == 0) {
4302                 gen_shift(s, op, ot, opreg, OR_ECX);
4303             } else {
4304                 if (shift == 2) {
4305                     shift = x86_ldub_code(env, s);
4306                 }
4307                 gen_shifti(s, op, ot, opreg, shift);
4308             }
4309         }
4310         break;
4311     case 0xd0:
4312     case 0xd1:
4313         /* shift Ev,1 */
4314         shift = 1;
4315         goto grp2;
4316     case 0xd2:
4317     case 0xd3:
4318         /* shift Ev,cl */
4319         shift = 0;
4320         goto grp2;
4321 
4322     case 0x1a4: /* shld imm */
4323         op = 0;
4324         shift = 1;
4325         goto do_shiftd;
4326     case 0x1a5: /* shld cl */
4327         op = 0;
4328         shift = 0;
4329         goto do_shiftd;
4330     case 0x1ac: /* shrd imm */
4331         op = 1;
4332         shift = 1;
4333         goto do_shiftd;
4334     case 0x1ad: /* shrd cl */
4335         op = 1;
4336         shift = 0;
4337     do_shiftd:
4338         ot = dflag;
4339         modrm = x86_ldub_code(env, s);
4340         mod = (modrm >> 6) & 3;
4341         rm = (modrm & 7) | REX_B(s);
4342         reg = ((modrm >> 3) & 7) | REX_R(s);
4343         if (mod != 3) {
4344             gen_lea_modrm(env, s, modrm);
4345             opreg = OR_TMP0;
4346         } else {
4347             opreg = rm;
4348         }
4349         gen_op_mov_v_reg(s, ot, s->T1, reg);
4350 
4351         if (shift) {
4352             TCGv imm = tcg_constant_tl(x86_ldub_code(env, s));
4353             gen_shiftd_rm_T1(s, ot, opreg, op, imm);
4354         } else {
4355             gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
4356         }
4357         break;
4358 
4359         /************************/
4360         /* floats */
4361     case 0xd8 ... 0xdf:
4362         {
4363             bool update_fip = true;
4364 
4365             if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
4366                 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
4367                 /* XXX: what to do if illegal op ? */
4368                 gen_exception(s, EXCP07_PREX);
4369                 break;
4370             }
4371             modrm = x86_ldub_code(env, s);
4372             mod = (modrm >> 6) & 3;
4373             rm = modrm & 7;
4374             op = ((b & 7) << 3) | ((modrm >> 3) & 7);
4375             if (mod != 3) {
4376                 /* memory op */
4377                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
4378                 TCGv ea = gen_lea_modrm_1(s, a, false);
4379                 TCGv last_addr = tcg_temp_new();
4380                 bool update_fdp = true;
4381 
4382                 tcg_gen_mov_tl(last_addr, ea);
4383                 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
4384 
4385                 switch (op) {
4386                 case 0x00 ... 0x07: /* fxxxs */
4387                 case 0x10 ... 0x17: /* fixxxl */
4388                 case 0x20 ... 0x27: /* fxxxl */
4389                 case 0x30 ... 0x37: /* fixxx */
4390                     {
4391                         int op1;
4392                         op1 = op & 7;
4393 
4394                         switch (op >> 4) {
4395                         case 0:
4396                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4397                                                 s->mem_index, MO_LEUL);
4398                             gen_helper_flds_FT0(cpu_env, s->tmp2_i32);
4399                             break;
4400                         case 1:
4401                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4402                                                 s->mem_index, MO_LEUL);
4403                             gen_helper_fildl_FT0(cpu_env, s->tmp2_i32);
4404                             break;
4405                         case 2:
4406                             tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4407                                                 s->mem_index, MO_LEUQ);
4408                             gen_helper_fldl_FT0(cpu_env, s->tmp1_i64);
4409                             break;
4410                         case 3:
4411                         default:
4412                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4413                                                 s->mem_index, MO_LESW);
4414                             gen_helper_fildl_FT0(cpu_env, s->tmp2_i32);
4415                             break;
4416                         }
4417 
4418                         gen_helper_fp_arith_ST0_FT0(op1);
4419                         if (op1 == 3) {
4420                             /* fcomp needs pop */
4421                             gen_helper_fpop(cpu_env);
4422                         }
4423                     }
4424                     break;
4425                 case 0x08: /* flds */
4426                 case 0x0a: /* fsts */
4427                 case 0x0b: /* fstps */
4428                 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
4429                 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
4430                 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
4431                     switch (op & 7) {
4432                     case 0:
4433                         switch (op >> 4) {
4434                         case 0:
4435                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4436                                                 s->mem_index, MO_LEUL);
4437                             gen_helper_flds_ST0(cpu_env, s->tmp2_i32);
4438                             break;
4439                         case 1:
4440                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4441                                                 s->mem_index, MO_LEUL);
4442                             gen_helper_fildl_ST0(cpu_env, s->tmp2_i32);
4443                             break;
4444                         case 2:
4445                             tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4446                                                 s->mem_index, MO_LEUQ);
4447                             gen_helper_fldl_ST0(cpu_env, s->tmp1_i64);
4448                             break;
4449                         case 3:
4450                         default:
4451                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4452                                                 s->mem_index, MO_LESW);
4453                             gen_helper_fildl_ST0(cpu_env, s->tmp2_i32);
4454                             break;
4455                         }
4456                         break;
4457                     case 1:
4458                         /* XXX: the corresponding CPUID bit must be tested ! */
4459                         switch (op >> 4) {
4460                         case 1:
4461                             gen_helper_fisttl_ST0(s->tmp2_i32, cpu_env);
4462                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4463                                                 s->mem_index, MO_LEUL);
4464                             break;
4465                         case 2:
4466                             gen_helper_fisttll_ST0(s->tmp1_i64, cpu_env);
4467                             tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4468                                                 s->mem_index, MO_LEUQ);
4469                             break;
4470                         case 3:
4471                         default:
4472                             gen_helper_fistt_ST0(s->tmp2_i32, cpu_env);
4473                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4474                                                 s->mem_index, MO_LEUW);
4475                             break;
4476                         }
4477                         gen_helper_fpop(cpu_env);
4478                         break;
4479                     default:
4480                         switch (op >> 4) {
4481                         case 0:
4482                             gen_helper_fsts_ST0(s->tmp2_i32, cpu_env);
4483                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4484                                                 s->mem_index, MO_LEUL);
4485                             break;
4486                         case 1:
4487                             gen_helper_fistl_ST0(s->tmp2_i32, cpu_env);
4488                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4489                                                 s->mem_index, MO_LEUL);
4490                             break;
4491                         case 2:
4492                             gen_helper_fstl_ST0(s->tmp1_i64, cpu_env);
4493                             tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4494                                                 s->mem_index, MO_LEUQ);
4495                             break;
4496                         case 3:
4497                         default:
4498                             gen_helper_fist_ST0(s->tmp2_i32, cpu_env);
4499                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4500                                                 s->mem_index, MO_LEUW);
4501                             break;
4502                         }
4503                         if ((op & 7) == 3) {
4504                             gen_helper_fpop(cpu_env);
4505                         }
4506                         break;
4507                     }
4508                     break;
4509                 case 0x0c: /* fldenv mem */
4510                     gen_helper_fldenv(cpu_env, s->A0,
4511                                       tcg_constant_i32(dflag - 1));
4512                     update_fip = update_fdp = false;
4513                     break;
4514                 case 0x0d: /* fldcw mem */
4515                     tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4516                                         s->mem_index, MO_LEUW);
4517                     gen_helper_fldcw(cpu_env, s->tmp2_i32);
4518                     update_fip = update_fdp = false;
4519                     break;
4520                 case 0x0e: /* fnstenv mem */
4521                     gen_helper_fstenv(cpu_env, s->A0,
4522                                       tcg_constant_i32(dflag - 1));
4523                     update_fip = update_fdp = false;
4524                     break;
4525                 case 0x0f: /* fnstcw mem */
4526                     gen_helper_fnstcw(s->tmp2_i32, cpu_env);
4527                     tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4528                                         s->mem_index, MO_LEUW);
4529                     update_fip = update_fdp = false;
4530                     break;
4531                 case 0x1d: /* fldt mem */
4532                     gen_helper_fldt_ST0(cpu_env, s->A0);
4533                     break;
4534                 case 0x1f: /* fstpt mem */
4535                     gen_helper_fstt_ST0(cpu_env, s->A0);
4536                     gen_helper_fpop(cpu_env);
4537                     break;
4538                 case 0x2c: /* frstor mem */
4539                     gen_helper_frstor(cpu_env, s->A0,
4540                                       tcg_constant_i32(dflag - 1));
4541                     update_fip = update_fdp = false;
4542                     break;
4543                 case 0x2e: /* fnsave mem */
4544                     gen_helper_fsave(cpu_env, s->A0,
4545                                      tcg_constant_i32(dflag - 1));
4546                     update_fip = update_fdp = false;
4547                     break;
4548                 case 0x2f: /* fnstsw mem */
4549                     gen_helper_fnstsw(s->tmp2_i32, cpu_env);
4550                     tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4551                                         s->mem_index, MO_LEUW);
4552                     update_fip = update_fdp = false;
4553                     break;
4554                 case 0x3c: /* fbld */
4555                     gen_helper_fbld_ST0(cpu_env, s->A0);
4556                     break;
4557                 case 0x3e: /* fbstp */
4558                     gen_helper_fbst_ST0(cpu_env, s->A0);
4559                     gen_helper_fpop(cpu_env);
4560                     break;
4561                 case 0x3d: /* fildll */
4562                     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4563                                         s->mem_index, MO_LEUQ);
4564                     gen_helper_fildll_ST0(cpu_env, s->tmp1_i64);
4565                     break;
4566                 case 0x3f: /* fistpll */
4567                     gen_helper_fistll_ST0(s->tmp1_i64, cpu_env);
4568                     tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4569                                         s->mem_index, MO_LEUQ);
4570                     gen_helper_fpop(cpu_env);
4571                     break;
4572                 default:
4573                     goto unknown_op;
4574                 }
4575 
4576                 if (update_fdp) {
4577                     int last_seg = s->override >= 0 ? s->override : a.def_seg;
4578 
4579                     tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
4580                                    offsetof(CPUX86State,
4581                                             segs[last_seg].selector));
4582                     tcg_gen_st16_i32(s->tmp2_i32, cpu_env,
4583                                      offsetof(CPUX86State, fpds));
4584                     tcg_gen_st_tl(last_addr, cpu_env,
4585                                   offsetof(CPUX86State, fpdp));
4586                 }
4587             } else {
4588                 /* register float ops */
4589                 opreg = rm;
4590 
4591                 switch (op) {
4592                 case 0x08: /* fld sti */
4593                     gen_helper_fpush(cpu_env);
4594                     gen_helper_fmov_ST0_STN(cpu_env,
4595                                             tcg_constant_i32((opreg + 1) & 7));
4596                     break;
4597                 case 0x09: /* fxchg sti */
4598                 case 0x29: /* fxchg4 sti, undocumented op */
4599                 case 0x39: /* fxchg7 sti, undocumented op */
4600                     gen_helper_fxchg_ST0_STN(cpu_env, tcg_constant_i32(opreg));
4601                     break;
4602                 case 0x0a: /* grp d9/2 */
4603                     switch (rm) {
4604                     case 0: /* fnop */
4605                         /* check exceptions (FreeBSD FPU probe) */
4606                         gen_helper_fwait(cpu_env);
4607                         update_fip = false;
4608                         break;
4609                     default:
4610                         goto unknown_op;
4611                     }
4612                     break;
4613                 case 0x0c: /* grp d9/4 */
4614                     switch (rm) {
4615                     case 0: /* fchs */
4616                         gen_helper_fchs_ST0(cpu_env);
4617                         break;
4618                     case 1: /* fabs */
4619                         gen_helper_fabs_ST0(cpu_env);
4620                         break;
4621                     case 4: /* ftst */
4622                         gen_helper_fldz_FT0(cpu_env);
4623                         gen_helper_fcom_ST0_FT0(cpu_env);
4624                         break;
4625                     case 5: /* fxam */
4626                         gen_helper_fxam_ST0(cpu_env);
4627                         break;
4628                     default:
4629                         goto unknown_op;
4630                     }
4631                     break;
4632                 case 0x0d: /* grp d9/5 */
4633                     {
4634                         switch (rm) {
4635                         case 0:
4636                             gen_helper_fpush(cpu_env);
4637                             gen_helper_fld1_ST0(cpu_env);
4638                             break;
4639                         case 1:
4640                             gen_helper_fpush(cpu_env);
4641                             gen_helper_fldl2t_ST0(cpu_env);
4642                             break;
4643                         case 2:
4644                             gen_helper_fpush(cpu_env);
4645                             gen_helper_fldl2e_ST0(cpu_env);
4646                             break;
4647                         case 3:
4648                             gen_helper_fpush(cpu_env);
4649                             gen_helper_fldpi_ST0(cpu_env);
4650                             break;
4651                         case 4:
4652                             gen_helper_fpush(cpu_env);
4653                             gen_helper_fldlg2_ST0(cpu_env);
4654                             break;
4655                         case 5:
4656                             gen_helper_fpush(cpu_env);
4657                             gen_helper_fldln2_ST0(cpu_env);
4658                             break;
4659                         case 6:
4660                             gen_helper_fpush(cpu_env);
4661                             gen_helper_fldz_ST0(cpu_env);
4662                             break;
4663                         default:
4664                             goto unknown_op;
4665                         }
4666                     }
4667                     break;
4668                 case 0x0e: /* grp d9/6 */
4669                     switch (rm) {
4670                     case 0: /* f2xm1 */
4671                         gen_helper_f2xm1(cpu_env);
4672                         break;
4673                     case 1: /* fyl2x */
4674                         gen_helper_fyl2x(cpu_env);
4675                         break;
4676                     case 2: /* fptan */
4677                         gen_helper_fptan(cpu_env);
4678                         break;
4679                     case 3: /* fpatan */
4680                         gen_helper_fpatan(cpu_env);
4681                         break;
4682                     case 4: /* fxtract */
4683                         gen_helper_fxtract(cpu_env);
4684                         break;
4685                     case 5: /* fprem1 */
4686                         gen_helper_fprem1(cpu_env);
4687                         break;
4688                     case 6: /* fdecstp */
4689                         gen_helper_fdecstp(cpu_env);
4690                         break;
4691                     default:
4692                     case 7: /* fincstp */
4693                         gen_helper_fincstp(cpu_env);
4694                         break;
4695                     }
4696                     break;
4697                 case 0x0f: /* grp d9/7 */
4698                     switch (rm) {
4699                     case 0: /* fprem */
4700                         gen_helper_fprem(cpu_env);
4701                         break;
4702                     case 1: /* fyl2xp1 */
4703                         gen_helper_fyl2xp1(cpu_env);
4704                         break;
4705                     case 2: /* fsqrt */
4706                         gen_helper_fsqrt(cpu_env);
4707                         break;
4708                     case 3: /* fsincos */
4709                         gen_helper_fsincos(cpu_env);
4710                         break;
4711                     case 5: /* fscale */
4712                         gen_helper_fscale(cpu_env);
4713                         break;
4714                     case 4: /* frndint */
4715                         gen_helper_frndint(cpu_env);
4716                         break;
4717                     case 6: /* fsin */
4718                         gen_helper_fsin(cpu_env);
4719                         break;
4720                     default:
4721                     case 7: /* fcos */
4722                         gen_helper_fcos(cpu_env);
4723                         break;
4724                     }
4725                     break;
4726                 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
4727                 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
4728                 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
4729                     {
4730                         int op1;
4731 
4732                         op1 = op & 7;
4733                         if (op >= 0x20) {
4734                             gen_helper_fp_arith_STN_ST0(op1, opreg);
4735                             if (op >= 0x30) {
4736                                 gen_helper_fpop(cpu_env);
4737                             }
4738                         } else {
4739                             gen_helper_fmov_FT0_STN(cpu_env,
4740                                                     tcg_constant_i32(opreg));
4741                             gen_helper_fp_arith_ST0_FT0(op1);
4742                         }
4743                     }
4744                     break;
4745                 case 0x02: /* fcom */
4746                 case 0x22: /* fcom2, undocumented op */
4747                     gen_helper_fmov_FT0_STN(cpu_env, tcg_constant_i32(opreg));
4748                     gen_helper_fcom_ST0_FT0(cpu_env);
4749                     break;
4750                 case 0x03: /* fcomp */
4751                 case 0x23: /* fcomp3, undocumented op */
4752                 case 0x32: /* fcomp5, undocumented op */
4753                     gen_helper_fmov_FT0_STN(cpu_env, tcg_constant_i32(opreg));
4754                     gen_helper_fcom_ST0_FT0(cpu_env);
4755                     gen_helper_fpop(cpu_env);
4756                     break;
4757                 case 0x15: /* da/5 */
4758                     switch (rm) {
4759                     case 1: /* fucompp */
4760                         gen_helper_fmov_FT0_STN(cpu_env, tcg_constant_i32(1));
4761                         gen_helper_fucom_ST0_FT0(cpu_env);
4762                         gen_helper_fpop(cpu_env);
4763                         gen_helper_fpop(cpu_env);
4764                         break;
4765                     default:
4766                         goto unknown_op;
4767                     }
4768                     break;
4769                 case 0x1c:
4770                     switch (rm) {
4771                     case 0: /* feni (287 only, just do nop here) */
4772                         break;
4773                     case 1: /* fdisi (287 only, just do nop here) */
4774                         break;
4775                     case 2: /* fclex */
4776                         gen_helper_fclex(cpu_env);
4777                         update_fip = false;
4778                         break;
4779                     case 3: /* fninit */
4780                         gen_helper_fninit(cpu_env);
4781                         update_fip = false;
4782                         break;
4783                     case 4: /* fsetpm (287 only, just do nop here) */
4784                         break;
4785                     default:
4786                         goto unknown_op;
4787                     }
4788                     break;
4789                 case 0x1d: /* fucomi */
4790                     if (!(s->cpuid_features & CPUID_CMOV)) {
4791                         goto illegal_op;
4792                     }
4793                     gen_update_cc_op(s);
4794                     gen_helper_fmov_FT0_STN(cpu_env, tcg_constant_i32(opreg));
4795                     gen_helper_fucomi_ST0_FT0(cpu_env);
4796                     set_cc_op(s, CC_OP_EFLAGS);
4797                     break;
4798                 case 0x1e: /* fcomi */
4799                     if (!(s->cpuid_features & CPUID_CMOV)) {
4800                         goto illegal_op;
4801                     }
4802                     gen_update_cc_op(s);
4803                     gen_helper_fmov_FT0_STN(cpu_env, tcg_constant_i32(opreg));
4804                     gen_helper_fcomi_ST0_FT0(cpu_env);
4805                     set_cc_op(s, CC_OP_EFLAGS);
4806                     break;
4807                 case 0x28: /* ffree sti */
4808                     gen_helper_ffree_STN(cpu_env, tcg_constant_i32(opreg));
4809                     break;
4810                 case 0x2a: /* fst sti */
4811                     gen_helper_fmov_STN_ST0(cpu_env, tcg_constant_i32(opreg));
4812                     break;
4813                 case 0x2b: /* fstp sti */
4814                 case 0x0b: /* fstp1 sti, undocumented op */
4815                 case 0x3a: /* fstp8 sti, undocumented op */
4816                 case 0x3b: /* fstp9 sti, undocumented op */
4817                     gen_helper_fmov_STN_ST0(cpu_env, tcg_constant_i32(opreg));
4818                     gen_helper_fpop(cpu_env);
4819                     break;
4820                 case 0x2c: /* fucom st(i) */
4821                     gen_helper_fmov_FT0_STN(cpu_env, tcg_constant_i32(opreg));
4822                     gen_helper_fucom_ST0_FT0(cpu_env);
4823                     break;
4824                 case 0x2d: /* fucomp st(i) */
4825                     gen_helper_fmov_FT0_STN(cpu_env, tcg_constant_i32(opreg));
4826                     gen_helper_fucom_ST0_FT0(cpu_env);
4827                     gen_helper_fpop(cpu_env);
4828                     break;
4829                 case 0x33: /* de/3 */
4830                     switch (rm) {
4831                     case 1: /* fcompp */
4832                         gen_helper_fmov_FT0_STN(cpu_env, tcg_constant_i32(1));
4833                         gen_helper_fcom_ST0_FT0(cpu_env);
4834                         gen_helper_fpop(cpu_env);
4835                         gen_helper_fpop(cpu_env);
4836                         break;
4837                     default:
4838                         goto unknown_op;
4839                     }
4840                     break;
4841                 case 0x38: /* ffreep sti, undocumented op */
4842                     gen_helper_ffree_STN(cpu_env, tcg_constant_i32(opreg));
4843                     gen_helper_fpop(cpu_env);
4844                     break;
4845                 case 0x3c: /* df/4 */
4846                     switch (rm) {
4847                     case 0:
4848                         gen_helper_fnstsw(s->tmp2_i32, cpu_env);
4849                         tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
4850                         gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
4851                         break;
4852                     default:
4853                         goto unknown_op;
4854                     }
4855                     break;
4856                 case 0x3d: /* fucomip */
4857                     if (!(s->cpuid_features & CPUID_CMOV)) {
4858                         goto illegal_op;
4859                     }
4860                     gen_update_cc_op(s);
4861                     gen_helper_fmov_FT0_STN(cpu_env, tcg_constant_i32(opreg));
4862                     gen_helper_fucomi_ST0_FT0(cpu_env);
4863                     gen_helper_fpop(cpu_env);
4864                     set_cc_op(s, CC_OP_EFLAGS);
4865                     break;
4866                 case 0x3e: /* fcomip */
4867                     if (!(s->cpuid_features & CPUID_CMOV)) {
4868                         goto illegal_op;
4869                     }
4870                     gen_update_cc_op(s);
4871                     gen_helper_fmov_FT0_STN(cpu_env, tcg_constant_i32(opreg));
4872                     gen_helper_fcomi_ST0_FT0(cpu_env);
4873                     gen_helper_fpop(cpu_env);
4874                     set_cc_op(s, CC_OP_EFLAGS);
4875                     break;
4876                 case 0x10 ... 0x13: /* fcmovxx */
4877                 case 0x18 ... 0x1b:
4878                     {
4879                         int op1;
4880                         TCGLabel *l1;
4881                         static const uint8_t fcmov_cc[8] = {
4882                             (JCC_B << 1),
4883                             (JCC_Z << 1),
4884                             (JCC_BE << 1),
4885                             (JCC_P << 1),
4886                         };
4887 
4888                         if (!(s->cpuid_features & CPUID_CMOV)) {
4889                             goto illegal_op;
4890                         }
4891                         op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
4892                         l1 = gen_new_label();
4893                         gen_jcc1_noeob(s, op1, l1);
4894                         gen_helper_fmov_ST0_STN(cpu_env,
4895                                                 tcg_constant_i32(opreg));
4896                         gen_set_label(l1);
4897                     }
4898                     break;
4899                 default:
4900                     goto unknown_op;
4901                 }
4902             }
4903 
4904             if (update_fip) {
4905                 tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
4906                                offsetof(CPUX86State, segs[R_CS].selector));
4907                 tcg_gen_st16_i32(s->tmp2_i32, cpu_env,
4908                                  offsetof(CPUX86State, fpcs));
4909                 tcg_gen_st_tl(eip_cur_tl(s),
4910                               cpu_env, offsetof(CPUX86State, fpip));
4911             }
4912         }
4913         break;
4914         /************************/
4915         /* string ops */
4916 
4917     case 0xa4: /* movsS */
4918     case 0xa5:
4919         ot = mo_b_d(b, dflag);
4920         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4921             gen_repz_movs(s, ot);
4922         } else {
4923             gen_movs(s, ot);
4924         }
4925         break;
4926 
4927     case 0xaa: /* stosS */
4928     case 0xab:
4929         ot = mo_b_d(b, dflag);
4930         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4931             gen_repz_stos(s, ot);
4932         } else {
4933             gen_stos(s, ot);
4934         }
4935         break;
4936     case 0xac: /* lodsS */
4937     case 0xad:
4938         ot = mo_b_d(b, dflag);
4939         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4940             gen_repz_lods(s, ot);
4941         } else {
4942             gen_lods(s, ot);
4943         }
4944         break;
4945     case 0xae: /* scasS */
4946     case 0xaf:
4947         ot = mo_b_d(b, dflag);
4948         if (prefixes & PREFIX_REPNZ) {
4949             gen_repz_scas(s, ot, 1);
4950         } else if (prefixes & PREFIX_REPZ) {
4951             gen_repz_scas(s, ot, 0);
4952         } else {
4953             gen_scas(s, ot);
4954         }
4955         break;
4956 
4957     case 0xa6: /* cmpsS */
4958     case 0xa7:
4959         ot = mo_b_d(b, dflag);
4960         if (prefixes & PREFIX_REPNZ) {
4961             gen_repz_cmps(s, ot, 1);
4962         } else if (prefixes & PREFIX_REPZ) {
4963             gen_repz_cmps(s, ot, 0);
4964         } else {
4965             gen_cmps(s, ot);
4966         }
4967         break;
4968     case 0x6c: /* insS */
4969     case 0x6d:
4970         ot = mo_b_d32(b, dflag);
4971         tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
4972         tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
4973         if (!gen_check_io(s, ot, s->tmp2_i32,
4974                           SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) {
4975             break;
4976         }
4977         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4978             gen_io_start();
4979             s->base.is_jmp = DISAS_TOO_MANY;
4980         }
4981         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4982             gen_repz_ins(s, ot);
4983         } else {
4984             gen_ins(s, ot);
4985         }
4986         break;
4987     case 0x6e: /* outsS */
4988     case 0x6f:
4989         ot = mo_b_d32(b, dflag);
4990         tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
4991         tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
4992         if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_STR_MASK)) {
4993             break;
4994         }
4995         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4996             gen_io_start();
4997             s->base.is_jmp = DISAS_TOO_MANY;
4998         }
4999         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
5000             gen_repz_outs(s, ot);
5001         } else {
5002             gen_outs(s, ot);
5003         }
5004         break;
5005 
5006         /************************/
5007         /* port I/O */
5008 
5009     case 0xe4:
5010     case 0xe5:
5011         ot = mo_b_d32(b, dflag);
5012         val = x86_ldub_code(env, s);
5013         tcg_gen_movi_i32(s->tmp2_i32, val);
5014         if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
5015             break;
5016         }
5017         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
5018             gen_io_start();
5019             s->base.is_jmp = DISAS_TOO_MANY;
5020         }
5021         gen_helper_in_func(ot, s->T1, s->tmp2_i32);
5022         gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
5023         gen_bpt_io(s, s->tmp2_i32, ot);
5024         break;
5025     case 0xe6:
5026     case 0xe7:
5027         ot = mo_b_d32(b, dflag);
5028         val = x86_ldub_code(env, s);
5029         tcg_gen_movi_i32(s->tmp2_i32, val);
5030         if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
5031             break;
5032         }
5033         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
5034             gen_io_start();
5035             s->base.is_jmp = DISAS_TOO_MANY;
5036         }
5037         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
5038         tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
5039         gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
5040         gen_bpt_io(s, s->tmp2_i32, ot);
5041         break;
5042     case 0xec:
5043     case 0xed:
5044         ot = mo_b_d32(b, dflag);
5045         tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
5046         tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
5047         if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
5048             break;
5049         }
5050         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
5051             gen_io_start();
5052             s->base.is_jmp = DISAS_TOO_MANY;
5053         }
5054         gen_helper_in_func(ot, s->T1, s->tmp2_i32);
5055         gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
5056         gen_bpt_io(s, s->tmp2_i32, ot);
5057         break;
5058     case 0xee:
5059     case 0xef:
5060         ot = mo_b_d32(b, dflag);
5061         tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
5062         tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
5063         if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
5064             break;
5065         }
5066         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
5067             gen_io_start();
5068             s->base.is_jmp = DISAS_TOO_MANY;
5069         }
5070         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
5071         tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
5072         gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
5073         gen_bpt_io(s, s->tmp2_i32, ot);
5074         break;
5075 
5076         /************************/
5077         /* control */
5078     case 0xc2: /* ret im */
5079         val = x86_ldsw_code(env, s);
5080         ot = gen_pop_T0(s);
5081         gen_stack_update(s, val + (1 << ot));
5082         /* Note that gen_pop_T0 uses a zero-extending load.  */
5083         gen_op_jmp_v(s, s->T0);
5084         gen_bnd_jmp(s);
5085         s->base.is_jmp = DISAS_JUMP;
5086         break;
5087     case 0xc3: /* ret */
5088         ot = gen_pop_T0(s);
5089         gen_pop_update(s, ot);
5090         /* Note that gen_pop_T0 uses a zero-extending load.  */
5091         gen_op_jmp_v(s, s->T0);
5092         gen_bnd_jmp(s);
5093         s->base.is_jmp = DISAS_JUMP;
5094         break;
5095     case 0xca: /* lret im */
5096         val = x86_ldsw_code(env, s);
5097     do_lret:
5098         if (PE(s) && !VM86(s)) {
5099             gen_update_cc_op(s);
5100             gen_update_eip_cur(s);
5101             gen_helper_lret_protected(cpu_env, tcg_constant_i32(dflag - 1),
5102                                       tcg_constant_i32(val));
5103         } else {
5104             gen_stack_A0(s);
5105             /* pop offset */
5106             gen_op_ld_v(s, dflag, s->T0, s->A0);
5107             /* NOTE: keeping EIP updated is not a problem in case of
5108                exception */
5109             gen_op_jmp_v(s, s->T0);
5110             /* pop selector */
5111             gen_add_A0_im(s, 1 << dflag);
5112             gen_op_ld_v(s, dflag, s->T0, s->A0);
5113             gen_op_movl_seg_T0_vm(s, R_CS);
5114             /* add stack offset */
5115             gen_stack_update(s, val + (2 << dflag));
5116         }
5117         s->base.is_jmp = DISAS_EOB_ONLY;
5118         break;
5119     case 0xcb: /* lret */
5120         val = 0;
5121         goto do_lret;
5122     case 0xcf: /* iret */
5123         gen_svm_check_intercept(s, SVM_EXIT_IRET);
5124         if (!PE(s) || VM86(s)) {
5125             /* real mode or vm86 mode */
5126             if (!check_vm86_iopl(s)) {
5127                 break;
5128             }
5129             gen_helper_iret_real(cpu_env, tcg_constant_i32(dflag - 1));
5130         } else {
5131             gen_helper_iret_protected(cpu_env, tcg_constant_i32(dflag - 1),
5132                                       eip_next_i32(s));
5133         }
5134         set_cc_op(s, CC_OP_EFLAGS);
5135         s->base.is_jmp = DISAS_EOB_ONLY;
5136         break;
5137     case 0xe8: /* call im */
5138         {
5139             int diff = (dflag != MO_16
5140                         ? (int32_t)insn_get(env, s, MO_32)
5141                         : (int16_t)insn_get(env, s, MO_16));
5142             gen_push_v(s, eip_next_tl(s));
5143             gen_bnd_jmp(s);
5144             gen_jmp_rel(s, dflag, diff, 0);
5145         }
5146         break;
5147     case 0x9a: /* lcall im */
5148         {
5149             unsigned int selector, offset;
5150 
5151             if (CODE64(s))
5152                 goto illegal_op;
5153             ot = dflag;
5154             offset = insn_get(env, s, ot);
5155             selector = insn_get(env, s, MO_16);
5156 
5157             tcg_gen_movi_tl(s->T0, selector);
5158             tcg_gen_movi_tl(s->T1, offset);
5159         }
5160         goto do_lcall;
5161     case 0xe9: /* jmp im */
5162         {
5163             int diff = (dflag != MO_16
5164                         ? (int32_t)insn_get(env, s, MO_32)
5165                         : (int16_t)insn_get(env, s, MO_16));
5166             gen_bnd_jmp(s);
5167             gen_jmp_rel(s, dflag, diff, 0);
5168         }
5169         break;
5170     case 0xea: /* ljmp im */
5171         {
5172             unsigned int selector, offset;
5173 
5174             if (CODE64(s))
5175                 goto illegal_op;
5176             ot = dflag;
5177             offset = insn_get(env, s, ot);
5178             selector = insn_get(env, s, MO_16);
5179 
5180             tcg_gen_movi_tl(s->T0, selector);
5181             tcg_gen_movi_tl(s->T1, offset);
5182         }
5183         goto do_ljmp;
5184     case 0xeb: /* jmp Jb */
5185         {
5186             int diff = (int8_t)insn_get(env, s, MO_8);
5187             gen_jmp_rel(s, dflag, diff, 0);
5188         }
5189         break;
5190     case 0x70 ... 0x7f: /* jcc Jb */
5191         {
5192             int diff = (int8_t)insn_get(env, s, MO_8);
5193             gen_bnd_jmp(s);
5194             gen_jcc(s, b, diff);
5195         }
5196         break;
5197     case 0x180 ... 0x18f: /* jcc Jv */
5198         {
5199             int diff = (dflag != MO_16
5200                         ? (int32_t)insn_get(env, s, MO_32)
5201                         : (int16_t)insn_get(env, s, MO_16));
5202             gen_bnd_jmp(s);
5203             gen_jcc(s, b, diff);
5204         }
5205         break;
5206 
5207     case 0x190 ... 0x19f: /* setcc Gv */
5208         modrm = x86_ldub_code(env, s);
5209         gen_setcc1(s, b, s->T0);
5210         gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
5211         break;
5212     case 0x140 ... 0x14f: /* cmov Gv, Ev */
5213         if (!(s->cpuid_features & CPUID_CMOV)) {
5214             goto illegal_op;
5215         }
5216         ot = dflag;
5217         modrm = x86_ldub_code(env, s);
5218         reg = ((modrm >> 3) & 7) | REX_R(s);
5219         gen_cmovcc1(env, s, ot, b, modrm, reg);
5220         break;
5221 
5222         /************************/
5223         /* flags */
5224     case 0x9c: /* pushf */
5225         gen_svm_check_intercept(s, SVM_EXIT_PUSHF);
5226         if (check_vm86_iopl(s)) {
5227             gen_update_cc_op(s);
5228             gen_helper_read_eflags(s->T0, cpu_env);
5229             gen_push_v(s, s->T0);
5230         }
5231         break;
5232     case 0x9d: /* popf */
5233         gen_svm_check_intercept(s, SVM_EXIT_POPF);
5234         if (check_vm86_iopl(s)) {
5235             int mask = TF_MASK | AC_MASK | ID_MASK | NT_MASK;
5236 
5237             if (CPL(s) == 0) {
5238                 mask |= IF_MASK | IOPL_MASK;
5239             } else if (CPL(s) <= IOPL(s)) {
5240                 mask |= IF_MASK;
5241             }
5242             if (dflag == MO_16) {
5243                 mask &= 0xffff;
5244             }
5245 
5246             ot = gen_pop_T0(s);
5247             gen_helper_write_eflags(cpu_env, s->T0, tcg_constant_i32(mask));
5248             gen_pop_update(s, ot);
5249             set_cc_op(s, CC_OP_EFLAGS);
5250             /* abort translation because TF/AC flag may change */
5251             s->base.is_jmp = DISAS_EOB_NEXT;
5252         }
5253         break;
5254     case 0x9e: /* sahf */
5255         if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
5256             goto illegal_op;
5257         tcg_gen_shri_tl(s->T0, cpu_regs[R_EAX], 8);
5258         gen_compute_eflags(s);
5259         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
5260         tcg_gen_andi_tl(s->T0, s->T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
5261         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, s->T0);
5262         break;
5263     case 0x9f: /* lahf */
5264         if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
5265             goto illegal_op;
5266         gen_compute_eflags(s);
5267         /* Note: gen_compute_eflags() only gives the condition codes */
5268         tcg_gen_ori_tl(s->T0, cpu_cc_src, 0x02);
5269         tcg_gen_deposit_tl(cpu_regs[R_EAX], cpu_regs[R_EAX], s->T0, 8, 8);
5270         break;
5271     case 0xf5: /* cmc */
5272         gen_compute_eflags(s);
5273         tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5274         break;
5275     case 0xf8: /* clc */
5276         gen_compute_eflags(s);
5277         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
5278         break;
5279     case 0xf9: /* stc */
5280         gen_compute_eflags(s);
5281         tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5282         break;
5283     case 0xfc: /* cld */
5284         tcg_gen_movi_i32(s->tmp2_i32, 1);
5285         tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df));
5286         break;
5287     case 0xfd: /* std */
5288         tcg_gen_movi_i32(s->tmp2_i32, -1);
5289         tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df));
5290         break;
5291 
5292         /************************/
5293         /* bit operations */
5294     case 0x1ba: /* bt/bts/btr/btc Gv, im */
5295         ot = dflag;
5296         modrm = x86_ldub_code(env, s);
5297         op = (modrm >> 3) & 7;
5298         mod = (modrm >> 6) & 3;
5299         rm = (modrm & 7) | REX_B(s);
5300         if (mod != 3) {
5301             s->rip_offset = 1;
5302             gen_lea_modrm(env, s, modrm);
5303             if (!(s->prefix & PREFIX_LOCK)) {
5304                 gen_op_ld_v(s, ot, s->T0, s->A0);
5305             }
5306         } else {
5307             gen_op_mov_v_reg(s, ot, s->T0, rm);
5308         }
5309         /* load shift */
5310         val = x86_ldub_code(env, s);
5311         tcg_gen_movi_tl(s->T1, val);
5312         if (op < 4)
5313             goto unknown_op;
5314         op -= 4;
5315         goto bt_op;
5316     case 0x1a3: /* bt Gv, Ev */
5317         op = 0;
5318         goto do_btx;
5319     case 0x1ab: /* bts */
5320         op = 1;
5321         goto do_btx;
5322     case 0x1b3: /* btr */
5323         op = 2;
5324         goto do_btx;
5325     case 0x1bb: /* btc */
5326         op = 3;
5327     do_btx:
5328         ot = dflag;
5329         modrm = x86_ldub_code(env, s);
5330         reg = ((modrm >> 3) & 7) | REX_R(s);
5331         mod = (modrm >> 6) & 3;
5332         rm = (modrm & 7) | REX_B(s);
5333         gen_op_mov_v_reg(s, MO_32, s->T1, reg);
5334         if (mod != 3) {
5335             AddressParts a = gen_lea_modrm_0(env, s, modrm);
5336             /* specific case: we need to add a displacement */
5337             gen_exts(ot, s->T1);
5338             tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot);
5339             tcg_gen_shli_tl(s->tmp0, s->tmp0, ot);
5340             tcg_gen_add_tl(s->A0, gen_lea_modrm_1(s, a, false), s->tmp0);
5341             gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
5342             if (!(s->prefix & PREFIX_LOCK)) {
5343                 gen_op_ld_v(s, ot, s->T0, s->A0);
5344             }
5345         } else {
5346             gen_op_mov_v_reg(s, ot, s->T0, rm);
5347         }
5348     bt_op:
5349         tcg_gen_andi_tl(s->T1, s->T1, (1 << (3 + ot)) - 1);
5350         tcg_gen_movi_tl(s->tmp0, 1);
5351         tcg_gen_shl_tl(s->tmp0, s->tmp0, s->T1);
5352         if (s->prefix & PREFIX_LOCK) {
5353             switch (op) {
5354             case 0: /* bt */
5355                 /* Needs no atomic ops; we surpressed the normal
5356                    memory load for LOCK above so do it now.  */
5357                 gen_op_ld_v(s, ot, s->T0, s->A0);
5358                 break;
5359             case 1: /* bts */
5360                 tcg_gen_atomic_fetch_or_tl(s->T0, s->A0, s->tmp0,
5361                                            s->mem_index, ot | MO_LE);
5362                 break;
5363             case 2: /* btr */
5364                 tcg_gen_not_tl(s->tmp0, s->tmp0);
5365                 tcg_gen_atomic_fetch_and_tl(s->T0, s->A0, s->tmp0,
5366                                             s->mem_index, ot | MO_LE);
5367                 break;
5368             default:
5369             case 3: /* btc */
5370                 tcg_gen_atomic_fetch_xor_tl(s->T0, s->A0, s->tmp0,
5371                                             s->mem_index, ot | MO_LE);
5372                 break;
5373             }
5374             tcg_gen_shr_tl(s->tmp4, s->T0, s->T1);
5375         } else {
5376             tcg_gen_shr_tl(s->tmp4, s->T0, s->T1);
5377             switch (op) {
5378             case 0: /* bt */
5379                 /* Data already loaded; nothing to do.  */
5380                 break;
5381             case 1: /* bts */
5382                 tcg_gen_or_tl(s->T0, s->T0, s->tmp0);
5383                 break;
5384             case 2: /* btr */
5385                 tcg_gen_andc_tl(s->T0, s->T0, s->tmp0);
5386                 break;
5387             default:
5388             case 3: /* btc */
5389                 tcg_gen_xor_tl(s->T0, s->T0, s->tmp0);
5390                 break;
5391             }
5392             if (op != 0) {
5393                 if (mod != 3) {
5394                     gen_op_st_v(s, ot, s->T0, s->A0);
5395                 } else {
5396                     gen_op_mov_reg_v(s, ot, rm, s->T0);
5397                 }
5398             }
5399         }
5400 
5401         /* Delay all CC updates until after the store above.  Note that
5402            C is the result of the test, Z is unchanged, and the others
5403            are all undefined.  */
5404         switch (s->cc_op) {
5405         case CC_OP_MULB ... CC_OP_MULQ:
5406         case CC_OP_ADDB ... CC_OP_ADDQ:
5407         case CC_OP_ADCB ... CC_OP_ADCQ:
5408         case CC_OP_SUBB ... CC_OP_SUBQ:
5409         case CC_OP_SBBB ... CC_OP_SBBQ:
5410         case CC_OP_LOGICB ... CC_OP_LOGICQ:
5411         case CC_OP_INCB ... CC_OP_INCQ:
5412         case CC_OP_DECB ... CC_OP_DECQ:
5413         case CC_OP_SHLB ... CC_OP_SHLQ:
5414         case CC_OP_SARB ... CC_OP_SARQ:
5415         case CC_OP_BMILGB ... CC_OP_BMILGQ:
5416             /* Z was going to be computed from the non-zero status of CC_DST.
5417                We can get that same Z value (and the new C value) by leaving
5418                CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
5419                same width.  */
5420             tcg_gen_mov_tl(cpu_cc_src, s->tmp4);
5421             set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
5422             break;
5423         default:
5424             /* Otherwise, generate EFLAGS and replace the C bit.  */
5425             gen_compute_eflags(s);
5426             tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, s->tmp4,
5427                                ctz32(CC_C), 1);
5428             break;
5429         }
5430         break;
5431     case 0x1bc: /* bsf / tzcnt */
5432     case 0x1bd: /* bsr / lzcnt */
5433         ot = dflag;
5434         modrm = x86_ldub_code(env, s);
5435         reg = ((modrm >> 3) & 7) | REX_R(s);
5436         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5437         gen_extu(ot, s->T0);
5438 
5439         /* Note that lzcnt and tzcnt are in different extensions.  */
5440         if ((prefixes & PREFIX_REPZ)
5441             && (b & 1
5442                 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
5443                 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
5444             int size = 8 << ot;
5445             /* For lzcnt/tzcnt, C bit is defined related to the input. */
5446             tcg_gen_mov_tl(cpu_cc_src, s->T0);
5447             if (b & 1) {
5448                 /* For lzcnt, reduce the target_ulong result by the
5449                    number of zeros that we expect to find at the top.  */
5450                 tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS);
5451                 tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - size);
5452             } else {
5453                 /* For tzcnt, a zero input must return the operand size.  */
5454                 tcg_gen_ctzi_tl(s->T0, s->T0, size);
5455             }
5456             /* For lzcnt/tzcnt, Z bit is defined related to the result.  */
5457             gen_op_update1_cc(s);
5458             set_cc_op(s, CC_OP_BMILGB + ot);
5459         } else {
5460             /* For bsr/bsf, only the Z bit is defined and it is related
5461                to the input and not the result.  */
5462             tcg_gen_mov_tl(cpu_cc_dst, s->T0);
5463             set_cc_op(s, CC_OP_LOGICB + ot);
5464 
5465             /* ??? The manual says that the output is undefined when the
5466                input is zero, but real hardware leaves it unchanged, and
5467                real programs appear to depend on that.  Accomplish this
5468                by passing the output as the value to return upon zero.  */
5469             if (b & 1) {
5470                 /* For bsr, return the bit index of the first 1 bit,
5471                    not the count of leading zeros.  */
5472                 tcg_gen_xori_tl(s->T1, cpu_regs[reg], TARGET_LONG_BITS - 1);
5473                 tcg_gen_clz_tl(s->T0, s->T0, s->T1);
5474                 tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1);
5475             } else {
5476                 tcg_gen_ctz_tl(s->T0, s->T0, cpu_regs[reg]);
5477             }
5478         }
5479         gen_op_mov_reg_v(s, ot, reg, s->T0);
5480         break;
5481         /************************/
5482         /* bcd */
5483     case 0x27: /* daa */
5484         if (CODE64(s))
5485             goto illegal_op;
5486         gen_update_cc_op(s);
5487         gen_helper_daa(cpu_env);
5488         set_cc_op(s, CC_OP_EFLAGS);
5489         break;
5490     case 0x2f: /* das */
5491         if (CODE64(s))
5492             goto illegal_op;
5493         gen_update_cc_op(s);
5494         gen_helper_das(cpu_env);
5495         set_cc_op(s, CC_OP_EFLAGS);
5496         break;
5497     case 0x37: /* aaa */
5498         if (CODE64(s))
5499             goto illegal_op;
5500         gen_update_cc_op(s);
5501         gen_helper_aaa(cpu_env);
5502         set_cc_op(s, CC_OP_EFLAGS);
5503         break;
5504     case 0x3f: /* aas */
5505         if (CODE64(s))
5506             goto illegal_op;
5507         gen_update_cc_op(s);
5508         gen_helper_aas(cpu_env);
5509         set_cc_op(s, CC_OP_EFLAGS);
5510         break;
5511     case 0xd4: /* aam */
5512         if (CODE64(s))
5513             goto illegal_op;
5514         val = x86_ldub_code(env, s);
5515         if (val == 0) {
5516             gen_exception(s, EXCP00_DIVZ);
5517         } else {
5518             gen_helper_aam(cpu_env, tcg_constant_i32(val));
5519             set_cc_op(s, CC_OP_LOGICB);
5520         }
5521         break;
5522     case 0xd5: /* aad */
5523         if (CODE64(s))
5524             goto illegal_op;
5525         val = x86_ldub_code(env, s);
5526         gen_helper_aad(cpu_env, tcg_constant_i32(val));
5527         set_cc_op(s, CC_OP_LOGICB);
5528         break;
5529         /************************/
5530         /* misc */
5531     case 0x90: /* nop */
5532         /* XXX: correct lock test for all insn */
5533         if (prefixes & PREFIX_LOCK) {
5534             goto illegal_op;
5535         }
5536         /* If REX_B is set, then this is xchg eax, r8d, not a nop.  */
5537         if (REX_B(s)) {
5538             goto do_xchg_reg_eax;
5539         }
5540         if (prefixes & PREFIX_REPZ) {
5541             gen_update_cc_op(s);
5542             gen_update_eip_cur(s);
5543             gen_helper_pause(cpu_env, cur_insn_len_i32(s));
5544             s->base.is_jmp = DISAS_NORETURN;
5545         }
5546         break;
5547     case 0x9b: /* fwait */
5548         if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
5549             (HF_MP_MASK | HF_TS_MASK)) {
5550             gen_exception(s, EXCP07_PREX);
5551         } else {
5552             gen_helper_fwait(cpu_env);
5553         }
5554         break;
5555     case 0xcc: /* int3 */
5556         gen_interrupt(s, EXCP03_INT3);
5557         break;
5558     case 0xcd: /* int N */
5559         val = x86_ldub_code(env, s);
5560         if (check_vm86_iopl(s)) {
5561             gen_interrupt(s, val);
5562         }
5563         break;
5564     case 0xce: /* into */
5565         if (CODE64(s))
5566             goto illegal_op;
5567         gen_update_cc_op(s);
5568         gen_update_eip_cur(s);
5569         gen_helper_into(cpu_env, cur_insn_len_i32(s));
5570         break;
5571 #ifdef WANT_ICEBP
5572     case 0xf1: /* icebp (undocumented, exits to external debugger) */
5573         gen_svm_check_intercept(s, SVM_EXIT_ICEBP);
5574         gen_debug(s);
5575         break;
5576 #endif
5577     case 0xfa: /* cli */
5578         if (check_iopl(s)) {
5579             gen_reset_eflags(s, IF_MASK);
5580         }
5581         break;
5582     case 0xfb: /* sti */
5583         if (check_iopl(s)) {
5584             gen_set_eflags(s, IF_MASK);
5585             /* interruptions are enabled only the first insn after sti */
5586             gen_update_eip_next(s);
5587             gen_eob_inhibit_irq(s, true);
5588         }
5589         break;
5590     case 0x62: /* bound */
5591         if (CODE64(s))
5592             goto illegal_op;
5593         ot = dflag;
5594         modrm = x86_ldub_code(env, s);
5595         reg = (modrm >> 3) & 7;
5596         mod = (modrm >> 6) & 3;
5597         if (mod == 3)
5598             goto illegal_op;
5599         gen_op_mov_v_reg(s, ot, s->T0, reg);
5600         gen_lea_modrm(env, s, modrm);
5601         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5602         if (ot == MO_16) {
5603             gen_helper_boundw(cpu_env, s->A0, s->tmp2_i32);
5604         } else {
5605             gen_helper_boundl(cpu_env, s->A0, s->tmp2_i32);
5606         }
5607         break;
5608     case 0x1c8 ... 0x1cf: /* bswap reg */
5609         reg = (b & 7) | REX_B(s);
5610 #ifdef TARGET_X86_64
5611         if (dflag == MO_64) {
5612             tcg_gen_bswap64_i64(cpu_regs[reg], cpu_regs[reg]);
5613             break;
5614         }
5615 #endif
5616         tcg_gen_bswap32_tl(cpu_regs[reg], cpu_regs[reg], TCG_BSWAP_OZ);
5617         break;
5618     case 0xd6: /* salc */
5619         if (CODE64(s))
5620             goto illegal_op;
5621         gen_compute_eflags_c(s, s->T0);
5622         tcg_gen_neg_tl(s->T0, s->T0);
5623         gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0);
5624         break;
5625     case 0xe0: /* loopnz */
5626     case 0xe1: /* loopz */
5627     case 0xe2: /* loop */
5628     case 0xe3: /* jecxz */
5629         {
5630             TCGLabel *l1, *l2;
5631             int diff = (int8_t)insn_get(env, s, MO_8);
5632 
5633             l1 = gen_new_label();
5634             l2 = gen_new_label();
5635             gen_update_cc_op(s);
5636             b &= 3;
5637             switch(b) {
5638             case 0: /* loopnz */
5639             case 1: /* loopz */
5640                 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
5641                 gen_op_jz_ecx(s, l2);
5642                 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
5643                 break;
5644             case 2: /* loop */
5645                 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
5646                 gen_op_jnz_ecx(s, l1);
5647                 break;
5648             default:
5649             case 3: /* jcxz */
5650                 gen_op_jz_ecx(s, l1);
5651                 break;
5652             }
5653 
5654             gen_set_label(l2);
5655             gen_jmp_rel_csize(s, 0, 1);
5656 
5657             gen_set_label(l1);
5658             gen_jmp_rel(s, dflag, diff, 0);
5659         }
5660         break;
5661     case 0x130: /* wrmsr */
5662     case 0x132: /* rdmsr */
5663         if (check_cpl0(s)) {
5664             gen_update_cc_op(s);
5665             gen_update_eip_cur(s);
5666             if (b & 2) {
5667                 gen_helper_rdmsr(cpu_env);
5668             } else {
5669                 gen_helper_wrmsr(cpu_env);
5670                 s->base.is_jmp = DISAS_EOB_NEXT;
5671             }
5672         }
5673         break;
5674     case 0x131: /* rdtsc */
5675         gen_update_cc_op(s);
5676         gen_update_eip_cur(s);
5677         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
5678             gen_io_start();
5679             s->base.is_jmp = DISAS_TOO_MANY;
5680         }
5681         gen_helper_rdtsc(cpu_env);
5682         break;
5683     case 0x133: /* rdpmc */
5684         gen_update_cc_op(s);
5685         gen_update_eip_cur(s);
5686         gen_helper_rdpmc(cpu_env);
5687         s->base.is_jmp = DISAS_NORETURN;
5688         break;
5689     case 0x134: /* sysenter */
5690         /* For Intel SYSENTER is valid on 64-bit */
5691         if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
5692             goto illegal_op;
5693         if (!PE(s)) {
5694             gen_exception_gpf(s);
5695         } else {
5696             gen_helper_sysenter(cpu_env);
5697             s->base.is_jmp = DISAS_EOB_ONLY;
5698         }
5699         break;
5700     case 0x135: /* sysexit */
5701         /* For Intel SYSEXIT is valid on 64-bit */
5702         if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
5703             goto illegal_op;
5704         if (!PE(s)) {
5705             gen_exception_gpf(s);
5706         } else {
5707             gen_helper_sysexit(cpu_env, tcg_constant_i32(dflag - 1));
5708             s->base.is_jmp = DISAS_EOB_ONLY;
5709         }
5710         break;
5711 #ifdef TARGET_X86_64
5712     case 0x105: /* syscall */
5713         /* XXX: is it usable in real mode ? */
5714         gen_update_cc_op(s);
5715         gen_update_eip_cur(s);
5716         gen_helper_syscall(cpu_env, cur_insn_len_i32(s));
5717         /* TF handling for the syscall insn is different. The TF bit is  checked
5718            after the syscall insn completes. This allows #DB to not be
5719            generated after one has entered CPL0 if TF is set in FMASK.  */
5720         gen_eob_worker(s, false, true);
5721         break;
5722     case 0x107: /* sysret */
5723         if (!PE(s)) {
5724             gen_exception_gpf(s);
5725         } else {
5726             gen_helper_sysret(cpu_env, tcg_constant_i32(dflag - 1));
5727             /* condition codes are modified only in long mode */
5728             if (LMA(s)) {
5729                 set_cc_op(s, CC_OP_EFLAGS);
5730             }
5731             /* TF handling for the sysret insn is different. The TF bit is
5732                checked after the sysret insn completes. This allows #DB to be
5733                generated "as if" the syscall insn in userspace has just
5734                completed.  */
5735             gen_eob_worker(s, false, true);
5736         }
5737         break;
5738 #endif
5739     case 0x1a2: /* cpuid */
5740         gen_update_cc_op(s);
5741         gen_update_eip_cur(s);
5742         gen_helper_cpuid(cpu_env);
5743         break;
5744     case 0xf4: /* hlt */
5745         if (check_cpl0(s)) {
5746             gen_update_cc_op(s);
5747             gen_update_eip_cur(s);
5748             gen_helper_hlt(cpu_env, cur_insn_len_i32(s));
5749             s->base.is_jmp = DISAS_NORETURN;
5750         }
5751         break;
5752     case 0x100:
5753         modrm = x86_ldub_code(env, s);
5754         mod = (modrm >> 6) & 3;
5755         op = (modrm >> 3) & 7;
5756         switch(op) {
5757         case 0: /* sldt */
5758             if (!PE(s) || VM86(s))
5759                 goto illegal_op;
5760             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5761                 break;
5762             }
5763             gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ);
5764             tcg_gen_ld32u_tl(s->T0, cpu_env,
5765                              offsetof(CPUX86State, ldt.selector));
5766             ot = mod == 3 ? dflag : MO_16;
5767             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5768             break;
5769         case 2: /* lldt */
5770             if (!PE(s) || VM86(s))
5771                 goto illegal_op;
5772             if (check_cpl0(s)) {
5773                 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE);
5774                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5775                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5776                 gen_helper_lldt(cpu_env, s->tmp2_i32);
5777             }
5778             break;
5779         case 1: /* str */
5780             if (!PE(s) || VM86(s))
5781                 goto illegal_op;
5782             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5783                 break;
5784             }
5785             gen_svm_check_intercept(s, SVM_EXIT_TR_READ);
5786             tcg_gen_ld32u_tl(s->T0, cpu_env,
5787                              offsetof(CPUX86State, tr.selector));
5788             ot = mod == 3 ? dflag : MO_16;
5789             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5790             break;
5791         case 3: /* ltr */
5792             if (!PE(s) || VM86(s))
5793                 goto illegal_op;
5794             if (check_cpl0(s)) {
5795                 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE);
5796                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5797                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5798                 gen_helper_ltr(cpu_env, s->tmp2_i32);
5799             }
5800             break;
5801         case 4: /* verr */
5802         case 5: /* verw */
5803             if (!PE(s) || VM86(s))
5804                 goto illegal_op;
5805             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5806             gen_update_cc_op(s);
5807             if (op == 4) {
5808                 gen_helper_verr(cpu_env, s->T0);
5809             } else {
5810                 gen_helper_verw(cpu_env, s->T0);
5811             }
5812             set_cc_op(s, CC_OP_EFLAGS);
5813             break;
5814         default:
5815             goto unknown_op;
5816         }
5817         break;
5818 
5819     case 0x101:
5820         modrm = x86_ldub_code(env, s);
5821         switch (modrm) {
5822         CASE_MODRM_MEM_OP(0): /* sgdt */
5823             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5824                 break;
5825             }
5826             gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ);
5827             gen_lea_modrm(env, s, modrm);
5828             tcg_gen_ld32u_tl(s->T0,
5829                              cpu_env, offsetof(CPUX86State, gdt.limit));
5830             gen_op_st_v(s, MO_16, s->T0, s->A0);
5831             gen_add_A0_im(s, 2);
5832             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base));
5833             if (dflag == MO_16) {
5834                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
5835             }
5836             gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
5837             break;
5838 
5839         case 0xc8: /* monitor */
5840             if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
5841                 goto illegal_op;
5842             }
5843             gen_update_cc_op(s);
5844             gen_update_eip_cur(s);
5845             tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
5846             gen_extu(s->aflag, s->A0);
5847             gen_add_A0_ds_seg(s);
5848             gen_helper_monitor(cpu_env, s->A0);
5849             break;
5850 
5851         case 0xc9: /* mwait */
5852             if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
5853                 goto illegal_op;
5854             }
5855             gen_update_cc_op(s);
5856             gen_update_eip_cur(s);
5857             gen_helper_mwait(cpu_env, cur_insn_len_i32(s));
5858             s->base.is_jmp = DISAS_NORETURN;
5859             break;
5860 
5861         case 0xca: /* clac */
5862             if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
5863                 || CPL(s) != 0) {
5864                 goto illegal_op;
5865             }
5866             gen_reset_eflags(s, AC_MASK);
5867             s->base.is_jmp = DISAS_EOB_NEXT;
5868             break;
5869 
5870         case 0xcb: /* stac */
5871             if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
5872                 || CPL(s) != 0) {
5873                 goto illegal_op;
5874             }
5875             gen_set_eflags(s, AC_MASK);
5876             s->base.is_jmp = DISAS_EOB_NEXT;
5877             break;
5878 
5879         CASE_MODRM_MEM_OP(1): /* sidt */
5880             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
5881                 break;
5882             }
5883             gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ);
5884             gen_lea_modrm(env, s, modrm);
5885             tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.limit));
5886             gen_op_st_v(s, MO_16, s->T0, s->A0);
5887             gen_add_A0_im(s, 2);
5888             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base));
5889             if (dflag == MO_16) {
5890                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
5891             }
5892             gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
5893             break;
5894 
5895         case 0xd0: /* xgetbv */
5896             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
5897                 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
5898                                  | PREFIX_REPZ | PREFIX_REPNZ))) {
5899                 goto illegal_op;
5900             }
5901             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
5902             gen_helper_xgetbv(s->tmp1_i64, cpu_env, s->tmp2_i32);
5903             tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
5904             break;
5905 
5906         case 0xd1: /* xsetbv */
5907             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
5908                 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
5909                                  | PREFIX_REPZ | PREFIX_REPNZ))) {
5910                 goto illegal_op;
5911             }
5912             if (!check_cpl0(s)) {
5913                 break;
5914             }
5915             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
5916                                   cpu_regs[R_EDX]);
5917             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
5918             gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64);
5919             /* End TB because translation flags may change.  */
5920             s->base.is_jmp = DISAS_EOB_NEXT;
5921             break;
5922 
5923         case 0xd8: /* VMRUN */
5924             if (!SVME(s) || !PE(s)) {
5925                 goto illegal_op;
5926             }
5927             if (!check_cpl0(s)) {
5928                 break;
5929             }
5930             gen_update_cc_op(s);
5931             gen_update_eip_cur(s);
5932             gen_helper_vmrun(cpu_env, tcg_constant_i32(s->aflag - 1),
5933                              cur_insn_len_i32(s));
5934             tcg_gen_exit_tb(NULL, 0);
5935             s->base.is_jmp = DISAS_NORETURN;
5936             break;
5937 
5938         case 0xd9: /* VMMCALL */
5939             if (!SVME(s)) {
5940                 goto illegal_op;
5941             }
5942             gen_update_cc_op(s);
5943             gen_update_eip_cur(s);
5944             gen_helper_vmmcall(cpu_env);
5945             break;
5946 
5947         case 0xda: /* VMLOAD */
5948             if (!SVME(s) || !PE(s)) {
5949                 goto illegal_op;
5950             }
5951             if (!check_cpl0(s)) {
5952                 break;
5953             }
5954             gen_update_cc_op(s);
5955             gen_update_eip_cur(s);
5956             gen_helper_vmload(cpu_env, tcg_constant_i32(s->aflag - 1));
5957             break;
5958 
5959         case 0xdb: /* VMSAVE */
5960             if (!SVME(s) || !PE(s)) {
5961                 goto illegal_op;
5962             }
5963             if (!check_cpl0(s)) {
5964                 break;
5965             }
5966             gen_update_cc_op(s);
5967             gen_update_eip_cur(s);
5968             gen_helper_vmsave(cpu_env, tcg_constant_i32(s->aflag - 1));
5969             break;
5970 
5971         case 0xdc: /* STGI */
5972             if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
5973                 || !PE(s)) {
5974                 goto illegal_op;
5975             }
5976             if (!check_cpl0(s)) {
5977                 break;
5978             }
5979             gen_update_cc_op(s);
5980             gen_helper_stgi(cpu_env);
5981             s->base.is_jmp = DISAS_EOB_NEXT;
5982             break;
5983 
5984         case 0xdd: /* CLGI */
5985             if (!SVME(s) || !PE(s)) {
5986                 goto illegal_op;
5987             }
5988             if (!check_cpl0(s)) {
5989                 break;
5990             }
5991             gen_update_cc_op(s);
5992             gen_update_eip_cur(s);
5993             gen_helper_clgi(cpu_env);
5994             break;
5995 
5996         case 0xde: /* SKINIT */
5997             if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
5998                 || !PE(s)) {
5999                 goto illegal_op;
6000             }
6001             gen_svm_check_intercept(s, SVM_EXIT_SKINIT);
6002             /* If not intercepted, not implemented -- raise #UD. */
6003             goto illegal_op;
6004 
6005         case 0xdf: /* INVLPGA */
6006             if (!SVME(s) || !PE(s)) {
6007                 goto illegal_op;
6008             }
6009             if (!check_cpl0(s)) {
6010                 break;
6011             }
6012             gen_svm_check_intercept(s, SVM_EXIT_INVLPGA);
6013             if (s->aflag == MO_64) {
6014                 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
6015             } else {
6016                 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]);
6017             }
6018             gen_helper_flush_page(cpu_env, s->A0);
6019             s->base.is_jmp = DISAS_EOB_NEXT;
6020             break;
6021 
6022         CASE_MODRM_MEM_OP(2): /* lgdt */
6023             if (!check_cpl0(s)) {
6024                 break;
6025             }
6026             gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE);
6027             gen_lea_modrm(env, s, modrm);
6028             gen_op_ld_v(s, MO_16, s->T1, s->A0);
6029             gen_add_A0_im(s, 2);
6030             gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
6031             if (dflag == MO_16) {
6032                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
6033             }
6034             tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base));
6035             tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, gdt.limit));
6036             break;
6037 
6038         CASE_MODRM_MEM_OP(3): /* lidt */
6039             if (!check_cpl0(s)) {
6040                 break;
6041             }
6042             gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE);
6043             gen_lea_modrm(env, s, modrm);
6044             gen_op_ld_v(s, MO_16, s->T1, s->A0);
6045             gen_add_A0_im(s, 2);
6046             gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
6047             if (dflag == MO_16) {
6048                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
6049             }
6050             tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base));
6051             tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, idt.limit));
6052             break;
6053 
6054         CASE_MODRM_OP(4): /* smsw */
6055             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
6056                 break;
6057             }
6058             gen_svm_check_intercept(s, SVM_EXIT_READ_CR0);
6059             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, cr[0]));
6060             /*
6061              * In 32-bit mode, the higher 16 bits of the destination
6062              * register are undefined.  In practice CR0[31:0] is stored
6063              * just like in 64-bit mode.
6064              */
6065             mod = (modrm >> 6) & 3;
6066             ot = (mod != 3 ? MO_16 : s->dflag);
6067             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
6068             break;
6069         case 0xee: /* rdpkru */
6070             if (prefixes & PREFIX_LOCK) {
6071                 goto illegal_op;
6072             }
6073             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
6074             gen_helper_rdpkru(s->tmp1_i64, cpu_env, s->tmp2_i32);
6075             tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
6076             break;
6077         case 0xef: /* wrpkru */
6078             if (prefixes & PREFIX_LOCK) {
6079                 goto illegal_op;
6080             }
6081             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6082                                   cpu_regs[R_EDX]);
6083             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
6084             gen_helper_wrpkru(cpu_env, s->tmp2_i32, s->tmp1_i64);
6085             break;
6086 
6087         CASE_MODRM_OP(6): /* lmsw */
6088             if (!check_cpl0(s)) {
6089                 break;
6090             }
6091             gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
6092             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
6093             /*
6094              * Only the 4 lower bits of CR0 are modified.
6095              * PE cannot be set to zero if already set to one.
6096              */
6097             tcg_gen_ld_tl(s->T1, cpu_env, offsetof(CPUX86State, cr[0]));
6098             tcg_gen_andi_tl(s->T0, s->T0, 0xf);
6099             tcg_gen_andi_tl(s->T1, s->T1, ~0xe);
6100             tcg_gen_or_tl(s->T0, s->T0, s->T1);
6101             gen_helper_write_crN(cpu_env, tcg_constant_i32(0), s->T0);
6102             s->base.is_jmp = DISAS_EOB_NEXT;
6103             break;
6104 
6105         CASE_MODRM_MEM_OP(7): /* invlpg */
6106             if (!check_cpl0(s)) {
6107                 break;
6108             }
6109             gen_svm_check_intercept(s, SVM_EXIT_INVLPG);
6110             gen_lea_modrm(env, s, modrm);
6111             gen_helper_flush_page(cpu_env, s->A0);
6112             s->base.is_jmp = DISAS_EOB_NEXT;
6113             break;
6114 
6115         case 0xf8: /* swapgs */
6116 #ifdef TARGET_X86_64
6117             if (CODE64(s)) {
6118                 if (check_cpl0(s)) {
6119                     tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]);
6120                     tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
6121                                   offsetof(CPUX86State, kernelgsbase));
6122                     tcg_gen_st_tl(s->T0, cpu_env,
6123                                   offsetof(CPUX86State, kernelgsbase));
6124                 }
6125                 break;
6126             }
6127 #endif
6128             goto illegal_op;
6129 
6130         case 0xf9: /* rdtscp */
6131             if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
6132                 goto illegal_op;
6133             }
6134             gen_update_cc_op(s);
6135             gen_update_eip_cur(s);
6136             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6137                 gen_io_start();
6138                 s->base.is_jmp = DISAS_TOO_MANY;
6139             }
6140             gen_helper_rdtscp(cpu_env);
6141             break;
6142 
6143         default:
6144             goto unknown_op;
6145         }
6146         break;
6147 
6148     case 0x108: /* invd */
6149     case 0x109: /* wbinvd */
6150         if (check_cpl0(s)) {
6151             gen_svm_check_intercept(s, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
6152             /* nothing to do */
6153         }
6154         break;
6155     case 0x63: /* arpl or movslS (x86_64) */
6156 #ifdef TARGET_X86_64
6157         if (CODE64(s)) {
6158             int d_ot;
6159             /* d_ot is the size of destination */
6160             d_ot = dflag;
6161 
6162             modrm = x86_ldub_code(env, s);
6163             reg = ((modrm >> 3) & 7) | REX_R(s);
6164             mod = (modrm >> 6) & 3;
6165             rm = (modrm & 7) | REX_B(s);
6166 
6167             if (mod == 3) {
6168                 gen_op_mov_v_reg(s, MO_32, s->T0, rm);
6169                 /* sign extend */
6170                 if (d_ot == MO_64) {
6171                     tcg_gen_ext32s_tl(s->T0, s->T0);
6172                 }
6173                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
6174             } else {
6175                 gen_lea_modrm(env, s, modrm);
6176                 gen_op_ld_v(s, MO_32 | MO_SIGN, s->T0, s->A0);
6177                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
6178             }
6179         } else
6180 #endif
6181         {
6182             TCGLabel *label1;
6183             TCGv t0, t1, t2;
6184 
6185             if (!PE(s) || VM86(s))
6186                 goto illegal_op;
6187             t0 = tcg_temp_new();
6188             t1 = tcg_temp_new();
6189             t2 = tcg_temp_new();
6190             ot = MO_16;
6191             modrm = x86_ldub_code(env, s);
6192             reg = (modrm >> 3) & 7;
6193             mod = (modrm >> 6) & 3;
6194             rm = modrm & 7;
6195             if (mod != 3) {
6196                 gen_lea_modrm(env, s, modrm);
6197                 gen_op_ld_v(s, ot, t0, s->A0);
6198             } else {
6199                 gen_op_mov_v_reg(s, ot, t0, rm);
6200             }
6201             gen_op_mov_v_reg(s, ot, t1, reg);
6202             tcg_gen_andi_tl(s->tmp0, t0, 3);
6203             tcg_gen_andi_tl(t1, t1, 3);
6204             tcg_gen_movi_tl(t2, 0);
6205             label1 = gen_new_label();
6206             tcg_gen_brcond_tl(TCG_COND_GE, s->tmp0, t1, label1);
6207             tcg_gen_andi_tl(t0, t0, ~3);
6208             tcg_gen_or_tl(t0, t0, t1);
6209             tcg_gen_movi_tl(t2, CC_Z);
6210             gen_set_label(label1);
6211             if (mod != 3) {
6212                 gen_op_st_v(s, ot, t0, s->A0);
6213            } else {
6214                 gen_op_mov_reg_v(s, ot, rm, t0);
6215             }
6216             gen_compute_eflags(s);
6217             tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
6218             tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
6219         }
6220         break;
6221     case 0x102: /* lar */
6222     case 0x103: /* lsl */
6223         {
6224             TCGLabel *label1;
6225             TCGv t0;
6226             if (!PE(s) || VM86(s))
6227                 goto illegal_op;
6228             ot = dflag != MO_16 ? MO_32 : MO_16;
6229             modrm = x86_ldub_code(env, s);
6230             reg = ((modrm >> 3) & 7) | REX_R(s);
6231             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
6232             t0 = tcg_temp_new();
6233             gen_update_cc_op(s);
6234             if (b == 0x102) {
6235                 gen_helper_lar(t0, cpu_env, s->T0);
6236             } else {
6237                 gen_helper_lsl(t0, cpu_env, s->T0);
6238             }
6239             tcg_gen_andi_tl(s->tmp0, cpu_cc_src, CC_Z);
6240             label1 = gen_new_label();
6241             tcg_gen_brcondi_tl(TCG_COND_EQ, s->tmp0, 0, label1);
6242             gen_op_mov_reg_v(s, ot, reg, t0);
6243             gen_set_label(label1);
6244             set_cc_op(s, CC_OP_EFLAGS);
6245         }
6246         break;
6247     case 0x118:
6248         modrm = x86_ldub_code(env, s);
6249         mod = (modrm >> 6) & 3;
6250         op = (modrm >> 3) & 7;
6251         switch(op) {
6252         case 0: /* prefetchnta */
6253         case 1: /* prefetchnt0 */
6254         case 2: /* prefetchnt0 */
6255         case 3: /* prefetchnt0 */
6256             if (mod == 3)
6257                 goto illegal_op;
6258             gen_nop_modrm(env, s, modrm);
6259             /* nothing more to do */
6260             break;
6261         default: /* nop (multi byte) */
6262             gen_nop_modrm(env, s, modrm);
6263             break;
6264         }
6265         break;
6266     case 0x11a:
6267         modrm = x86_ldub_code(env, s);
6268         if (s->flags & HF_MPX_EN_MASK) {
6269             mod = (modrm >> 6) & 3;
6270             reg = ((modrm >> 3) & 7) | REX_R(s);
6271             if (prefixes & PREFIX_REPZ) {
6272                 /* bndcl */
6273                 if (reg >= 4
6274                     || (prefixes & PREFIX_LOCK)
6275                     || s->aflag == MO_16) {
6276                     goto illegal_op;
6277                 }
6278                 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
6279             } else if (prefixes & PREFIX_REPNZ) {
6280                 /* bndcu */
6281                 if (reg >= 4
6282                     || (prefixes & PREFIX_LOCK)
6283                     || s->aflag == MO_16) {
6284                     goto illegal_op;
6285                 }
6286                 TCGv_i64 notu = tcg_temp_new_i64();
6287                 tcg_gen_not_i64(notu, cpu_bndu[reg]);
6288                 gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
6289             } else if (prefixes & PREFIX_DATA) {
6290                 /* bndmov -- from reg/mem */
6291                 if (reg >= 4 || s->aflag == MO_16) {
6292                     goto illegal_op;
6293                 }
6294                 if (mod == 3) {
6295                     int reg2 = (modrm & 7) | REX_B(s);
6296                     if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
6297                         goto illegal_op;
6298                     }
6299                     if (s->flags & HF_MPX_IU_MASK) {
6300                         tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
6301                         tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
6302                     }
6303                 } else {
6304                     gen_lea_modrm(env, s, modrm);
6305                     if (CODE64(s)) {
6306                         tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
6307                                             s->mem_index, MO_LEUQ);
6308                         tcg_gen_addi_tl(s->A0, s->A0, 8);
6309                         tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
6310                                             s->mem_index, MO_LEUQ);
6311                     } else {
6312                         tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
6313                                             s->mem_index, MO_LEUL);
6314                         tcg_gen_addi_tl(s->A0, s->A0, 4);
6315                         tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
6316                                             s->mem_index, MO_LEUL);
6317                     }
6318                     /* bnd registers are now in-use */
6319                     gen_set_hflag(s, HF_MPX_IU_MASK);
6320                 }
6321             } else if (mod != 3) {
6322                 /* bndldx */
6323                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6324                 if (reg >= 4
6325                     || (prefixes & PREFIX_LOCK)
6326                     || s->aflag == MO_16
6327                     || a.base < -1) {
6328                     goto illegal_op;
6329                 }
6330                 if (a.base >= 0) {
6331                     tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
6332                 } else {
6333                     tcg_gen_movi_tl(s->A0, 0);
6334                 }
6335                 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
6336                 if (a.index >= 0) {
6337                     tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
6338                 } else {
6339                     tcg_gen_movi_tl(s->T0, 0);
6340                 }
6341                 if (CODE64(s)) {
6342                     gen_helper_bndldx64(cpu_bndl[reg], cpu_env, s->A0, s->T0);
6343                     tcg_gen_ld_i64(cpu_bndu[reg], cpu_env,
6344                                    offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
6345                 } else {
6346                     gen_helper_bndldx32(cpu_bndu[reg], cpu_env, s->A0, s->T0);
6347                     tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
6348                     tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
6349                 }
6350                 gen_set_hflag(s, HF_MPX_IU_MASK);
6351             }
6352         }
6353         gen_nop_modrm(env, s, modrm);
6354         break;
6355     case 0x11b:
6356         modrm = x86_ldub_code(env, s);
6357         if (s->flags & HF_MPX_EN_MASK) {
6358             mod = (modrm >> 6) & 3;
6359             reg = ((modrm >> 3) & 7) | REX_R(s);
6360             if (mod != 3 && (prefixes & PREFIX_REPZ)) {
6361                 /* bndmk */
6362                 if (reg >= 4
6363                     || (prefixes & PREFIX_LOCK)
6364                     || s->aflag == MO_16) {
6365                     goto illegal_op;
6366                 }
6367                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6368                 if (a.base >= 0) {
6369                     tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
6370                     if (!CODE64(s)) {
6371                         tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
6372                     }
6373                 } else if (a.base == -1) {
6374                     /* no base register has lower bound of 0 */
6375                     tcg_gen_movi_i64(cpu_bndl[reg], 0);
6376                 } else {
6377                     /* rip-relative generates #ud */
6378                     goto illegal_op;
6379                 }
6380                 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, a, false));
6381                 if (!CODE64(s)) {
6382                     tcg_gen_ext32u_tl(s->A0, s->A0);
6383                 }
6384                 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0);
6385                 /* bnd registers are now in-use */
6386                 gen_set_hflag(s, HF_MPX_IU_MASK);
6387                 break;
6388             } else if (prefixes & PREFIX_REPNZ) {
6389                 /* bndcn */
6390                 if (reg >= 4
6391                     || (prefixes & PREFIX_LOCK)
6392                     || s->aflag == MO_16) {
6393                     goto illegal_op;
6394                 }
6395                 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
6396             } else if (prefixes & PREFIX_DATA) {
6397                 /* bndmov -- to reg/mem */
6398                 if (reg >= 4 || s->aflag == MO_16) {
6399                     goto illegal_op;
6400                 }
6401                 if (mod == 3) {
6402                     int reg2 = (modrm & 7) | REX_B(s);
6403                     if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
6404                         goto illegal_op;
6405                     }
6406                     if (s->flags & HF_MPX_IU_MASK) {
6407                         tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
6408                         tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
6409                     }
6410                 } else {
6411                     gen_lea_modrm(env, s, modrm);
6412                     if (CODE64(s)) {
6413                         tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
6414                                             s->mem_index, MO_LEUQ);
6415                         tcg_gen_addi_tl(s->A0, s->A0, 8);
6416                         tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
6417                                             s->mem_index, MO_LEUQ);
6418                     } else {
6419                         tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
6420                                             s->mem_index, MO_LEUL);
6421                         tcg_gen_addi_tl(s->A0, s->A0, 4);
6422                         tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
6423                                             s->mem_index, MO_LEUL);
6424                     }
6425                 }
6426             } else if (mod != 3) {
6427                 /* bndstx */
6428                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6429                 if (reg >= 4
6430                     || (prefixes & PREFIX_LOCK)
6431                     || s->aflag == MO_16
6432                     || a.base < -1) {
6433                     goto illegal_op;
6434                 }
6435                 if (a.base >= 0) {
6436                     tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
6437                 } else {
6438                     tcg_gen_movi_tl(s->A0, 0);
6439                 }
6440                 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
6441                 if (a.index >= 0) {
6442                     tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
6443                 } else {
6444                     tcg_gen_movi_tl(s->T0, 0);
6445                 }
6446                 if (CODE64(s)) {
6447                     gen_helper_bndstx64(cpu_env, s->A0, s->T0,
6448                                         cpu_bndl[reg], cpu_bndu[reg]);
6449                 } else {
6450                     gen_helper_bndstx32(cpu_env, s->A0, s->T0,
6451                                         cpu_bndl[reg], cpu_bndu[reg]);
6452                 }
6453             }
6454         }
6455         gen_nop_modrm(env, s, modrm);
6456         break;
6457     case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
6458         modrm = x86_ldub_code(env, s);
6459         gen_nop_modrm(env, s, modrm);
6460         break;
6461 
6462     case 0x120: /* mov reg, crN */
6463     case 0x122: /* mov crN, reg */
6464         if (!check_cpl0(s)) {
6465             break;
6466         }
6467         modrm = x86_ldub_code(env, s);
6468         /*
6469          * Ignore the mod bits (assume (modrm&0xc0)==0xc0).
6470          * AMD documentation (24594.pdf) and testing of Intel 386 and 486
6471          * processors all show that the mod bits are assumed to be 1's,
6472          * regardless of actual values.
6473          */
6474         rm = (modrm & 7) | REX_B(s);
6475         reg = ((modrm >> 3) & 7) | REX_R(s);
6476         switch (reg) {
6477         case 0:
6478             if ((prefixes & PREFIX_LOCK) &&
6479                 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
6480                 reg = 8;
6481             }
6482             break;
6483         case 2:
6484         case 3:
6485         case 4:
6486         case 8:
6487             break;
6488         default:
6489             goto unknown_op;
6490         }
6491         ot  = (CODE64(s) ? MO_64 : MO_32);
6492 
6493         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6494             gen_io_start();
6495             s->base.is_jmp = DISAS_TOO_MANY;
6496         }
6497         if (b & 2) {
6498             gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
6499             gen_op_mov_v_reg(s, ot, s->T0, rm);
6500             gen_helper_write_crN(cpu_env, tcg_constant_i32(reg), s->T0);
6501             s->base.is_jmp = DISAS_EOB_NEXT;
6502         } else {
6503             gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
6504             gen_helper_read_crN(s->T0, cpu_env, tcg_constant_i32(reg));
6505             gen_op_mov_reg_v(s, ot, rm, s->T0);
6506         }
6507         break;
6508 
6509     case 0x121: /* mov reg, drN */
6510     case 0x123: /* mov drN, reg */
6511         if (check_cpl0(s)) {
6512             modrm = x86_ldub_code(env, s);
6513             /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
6514              * AMD documentation (24594.pdf) and testing of
6515              * intel 386 and 486 processors all show that the mod bits
6516              * are assumed to be 1's, regardless of actual values.
6517              */
6518             rm = (modrm & 7) | REX_B(s);
6519             reg = ((modrm >> 3) & 7) | REX_R(s);
6520             if (CODE64(s))
6521                 ot = MO_64;
6522             else
6523                 ot = MO_32;
6524             if (reg >= 8) {
6525                 goto illegal_op;
6526             }
6527             if (b & 2) {
6528                 gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg);
6529                 gen_op_mov_v_reg(s, ot, s->T0, rm);
6530                 tcg_gen_movi_i32(s->tmp2_i32, reg);
6531                 gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0);
6532                 s->base.is_jmp = DISAS_EOB_NEXT;
6533             } else {
6534                 gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg);
6535                 tcg_gen_movi_i32(s->tmp2_i32, reg);
6536                 gen_helper_get_dr(s->T0, cpu_env, s->tmp2_i32);
6537                 gen_op_mov_reg_v(s, ot, rm, s->T0);
6538             }
6539         }
6540         break;
6541     case 0x106: /* clts */
6542         if (check_cpl0(s)) {
6543             gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
6544             gen_helper_clts(cpu_env);
6545             /* abort block because static cpu state changed */
6546             s->base.is_jmp = DISAS_EOB_NEXT;
6547         }
6548         break;
6549     /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
6550     case 0x1c3: /* MOVNTI reg, mem */
6551         if (!(s->cpuid_features & CPUID_SSE2))
6552             goto illegal_op;
6553         ot = mo_64_32(dflag);
6554         modrm = x86_ldub_code(env, s);
6555         mod = (modrm >> 6) & 3;
6556         if (mod == 3)
6557             goto illegal_op;
6558         reg = ((modrm >> 3) & 7) | REX_R(s);
6559         /* generate a generic store */
6560         gen_ldst_modrm(env, s, modrm, ot, reg, 1);
6561         break;
6562     case 0x1ae:
6563         modrm = x86_ldub_code(env, s);
6564         switch (modrm) {
6565         CASE_MODRM_MEM_OP(0): /* fxsave */
6566             if (!(s->cpuid_features & CPUID_FXSR)
6567                 || (prefixes & PREFIX_LOCK)) {
6568                 goto illegal_op;
6569             }
6570             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
6571                 gen_exception(s, EXCP07_PREX);
6572                 break;
6573             }
6574             gen_lea_modrm(env, s, modrm);
6575             gen_helper_fxsave(cpu_env, s->A0);
6576             break;
6577 
6578         CASE_MODRM_MEM_OP(1): /* fxrstor */
6579             if (!(s->cpuid_features & CPUID_FXSR)
6580                 || (prefixes & PREFIX_LOCK)) {
6581                 goto illegal_op;
6582             }
6583             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
6584                 gen_exception(s, EXCP07_PREX);
6585                 break;
6586             }
6587             gen_lea_modrm(env, s, modrm);
6588             gen_helper_fxrstor(cpu_env, s->A0);
6589             break;
6590 
6591         CASE_MODRM_MEM_OP(2): /* ldmxcsr */
6592             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
6593                 goto illegal_op;
6594             }
6595             if (s->flags & HF_TS_MASK) {
6596                 gen_exception(s, EXCP07_PREX);
6597                 break;
6598             }
6599             gen_lea_modrm(env, s, modrm);
6600             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
6601             gen_helper_ldmxcsr(cpu_env, s->tmp2_i32);
6602             break;
6603 
6604         CASE_MODRM_MEM_OP(3): /* stmxcsr */
6605             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
6606                 goto illegal_op;
6607             }
6608             if (s->flags & HF_TS_MASK) {
6609                 gen_exception(s, EXCP07_PREX);
6610                 break;
6611             }
6612             gen_helper_update_mxcsr(cpu_env);
6613             gen_lea_modrm(env, s, modrm);
6614             tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, mxcsr));
6615             gen_op_st_v(s, MO_32, s->T0, s->A0);
6616             break;
6617 
6618         CASE_MODRM_MEM_OP(4): /* xsave */
6619             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
6620                 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
6621                                 | PREFIX_REPZ | PREFIX_REPNZ))) {
6622                 goto illegal_op;
6623             }
6624             gen_lea_modrm(env, s, modrm);
6625             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6626                                   cpu_regs[R_EDX]);
6627             gen_helper_xsave(cpu_env, s->A0, s->tmp1_i64);
6628             break;
6629 
6630         CASE_MODRM_MEM_OP(5): /* xrstor */
6631             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
6632                 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
6633                                 | PREFIX_REPZ | PREFIX_REPNZ))) {
6634                 goto illegal_op;
6635             }
6636             gen_lea_modrm(env, s, modrm);
6637             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6638                                   cpu_regs[R_EDX]);
6639             gen_helper_xrstor(cpu_env, s->A0, s->tmp1_i64);
6640             /* XRSTOR is how MPX is enabled, which changes how
6641                we translate.  Thus we need to end the TB.  */
6642             s->base.is_jmp = DISAS_EOB_NEXT;
6643             break;
6644 
6645         CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
6646             if (prefixes & PREFIX_LOCK) {
6647                 goto illegal_op;
6648             }
6649             if (prefixes & PREFIX_DATA) {
6650                 /* clwb */
6651                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
6652                     goto illegal_op;
6653                 }
6654                 gen_nop_modrm(env, s, modrm);
6655             } else {
6656                 /* xsaveopt */
6657                 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
6658                     || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
6659                     || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
6660                     goto illegal_op;
6661                 }
6662                 gen_lea_modrm(env, s, modrm);
6663                 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
6664                                       cpu_regs[R_EDX]);
6665                 gen_helper_xsaveopt(cpu_env, s->A0, s->tmp1_i64);
6666             }
6667             break;
6668 
6669         CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
6670             if (prefixes & PREFIX_LOCK) {
6671                 goto illegal_op;
6672             }
6673             if (prefixes & PREFIX_DATA) {
6674                 /* clflushopt */
6675                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
6676                     goto illegal_op;
6677                 }
6678             } else {
6679                 /* clflush */
6680                 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))
6681                     || !(s->cpuid_features & CPUID_CLFLUSH)) {
6682                     goto illegal_op;
6683                 }
6684             }
6685             gen_nop_modrm(env, s, modrm);
6686             break;
6687 
6688         case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
6689         case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
6690         case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
6691         case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
6692             if (CODE64(s)
6693                 && (prefixes & PREFIX_REPZ)
6694                 && !(prefixes & PREFIX_LOCK)
6695                 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
6696                 TCGv base, treg, src, dst;
6697 
6698                 /* Preserve hflags bits by testing CR4 at runtime.  */
6699                 tcg_gen_movi_i32(s->tmp2_i32, CR4_FSGSBASE_MASK);
6700                 gen_helper_cr4_testbit(cpu_env, s->tmp2_i32);
6701 
6702                 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
6703                 treg = cpu_regs[(modrm & 7) | REX_B(s)];
6704 
6705                 if (modrm & 0x10) {
6706                     /* wr*base */
6707                     dst = base, src = treg;
6708                 } else {
6709                     /* rd*base */
6710                     dst = treg, src = base;
6711                 }
6712 
6713                 if (s->dflag == MO_32) {
6714                     tcg_gen_ext32u_tl(dst, src);
6715                 } else {
6716                     tcg_gen_mov_tl(dst, src);
6717                 }
6718                 break;
6719             }
6720             goto unknown_op;
6721 
6722         case 0xf8: /* sfence / pcommit */
6723             if (prefixes & PREFIX_DATA) {
6724                 /* pcommit */
6725                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
6726                     || (prefixes & PREFIX_LOCK)) {
6727                     goto illegal_op;
6728                 }
6729                 break;
6730             }
6731             /* fallthru */
6732         case 0xf9 ... 0xff: /* sfence */
6733             if (!(s->cpuid_features & CPUID_SSE)
6734                 || (prefixes & PREFIX_LOCK)) {
6735                 goto illegal_op;
6736             }
6737             tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
6738             break;
6739         case 0xe8 ... 0xef: /* lfence */
6740             if (!(s->cpuid_features & CPUID_SSE)
6741                 || (prefixes & PREFIX_LOCK)) {
6742                 goto illegal_op;
6743             }
6744             tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
6745             break;
6746         case 0xf0 ... 0xf7: /* mfence */
6747             if (!(s->cpuid_features & CPUID_SSE2)
6748                 || (prefixes & PREFIX_LOCK)) {
6749                 goto illegal_op;
6750             }
6751             tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
6752             break;
6753 
6754         default:
6755             goto unknown_op;
6756         }
6757         break;
6758 
6759     case 0x10d: /* 3DNow! prefetch(w) */
6760         modrm = x86_ldub_code(env, s);
6761         mod = (modrm >> 6) & 3;
6762         if (mod == 3)
6763             goto illegal_op;
6764         gen_nop_modrm(env, s, modrm);
6765         break;
6766     case 0x1aa: /* rsm */
6767         gen_svm_check_intercept(s, SVM_EXIT_RSM);
6768         if (!(s->flags & HF_SMM_MASK))
6769             goto illegal_op;
6770 #ifdef CONFIG_USER_ONLY
6771         /* we should not be in SMM mode */
6772         g_assert_not_reached();
6773 #else
6774         gen_update_cc_op(s);
6775         gen_update_eip_next(s);
6776         gen_helper_rsm(cpu_env);
6777 #endif /* CONFIG_USER_ONLY */
6778         s->base.is_jmp = DISAS_EOB_ONLY;
6779         break;
6780     case 0x1b8: /* SSE4.2 popcnt */
6781         if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
6782              PREFIX_REPZ)
6783             goto illegal_op;
6784         if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
6785             goto illegal_op;
6786 
6787         modrm = x86_ldub_code(env, s);
6788         reg = ((modrm >> 3) & 7) | REX_R(s);
6789 
6790         if (s->prefix & PREFIX_DATA) {
6791             ot = MO_16;
6792         } else {
6793             ot = mo_64_32(dflag);
6794         }
6795 
6796         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6797         gen_extu(ot, s->T0);
6798         tcg_gen_mov_tl(cpu_cc_src, s->T0);
6799         tcg_gen_ctpop_tl(s->T0, s->T0);
6800         gen_op_mov_reg_v(s, ot, reg, s->T0);
6801 
6802         set_cc_op(s, CC_OP_POPCNT);
6803         break;
6804     case 0x10e ... 0x117:
6805     case 0x128 ... 0x12f:
6806     case 0x138 ... 0x13a:
6807     case 0x150 ... 0x179:
6808     case 0x17c ... 0x17f:
6809     case 0x1c2:
6810     case 0x1c4 ... 0x1c6:
6811     case 0x1d0 ... 0x1fe:
6812         disas_insn_new(s, cpu, b);
6813         break;
6814     default:
6815         goto unknown_op;
6816     }
6817     return true;
6818  illegal_op:
6819     gen_illegal_opcode(s);
6820     return true;
6821  unknown_op:
6822     gen_unknown_opcode(env, s);
6823     return true;
6824 }
6825 
6826 void tcg_x86_init(void)
6827 {
6828     static const char reg_names[CPU_NB_REGS][4] = {
6829 #ifdef TARGET_X86_64
6830         [R_EAX] = "rax",
6831         [R_EBX] = "rbx",
6832         [R_ECX] = "rcx",
6833         [R_EDX] = "rdx",
6834         [R_ESI] = "rsi",
6835         [R_EDI] = "rdi",
6836         [R_EBP] = "rbp",
6837         [R_ESP] = "rsp",
6838         [8]  = "r8",
6839         [9]  = "r9",
6840         [10] = "r10",
6841         [11] = "r11",
6842         [12] = "r12",
6843         [13] = "r13",
6844         [14] = "r14",
6845         [15] = "r15",
6846 #else
6847         [R_EAX] = "eax",
6848         [R_EBX] = "ebx",
6849         [R_ECX] = "ecx",
6850         [R_EDX] = "edx",
6851         [R_ESI] = "esi",
6852         [R_EDI] = "edi",
6853         [R_EBP] = "ebp",
6854         [R_ESP] = "esp",
6855 #endif
6856     };
6857     static const char eip_name[] = {
6858 #ifdef TARGET_X86_64
6859         "rip"
6860 #else
6861         "eip"
6862 #endif
6863     };
6864     static const char seg_base_names[6][8] = {
6865         [R_CS] = "cs_base",
6866         [R_DS] = "ds_base",
6867         [R_ES] = "es_base",
6868         [R_FS] = "fs_base",
6869         [R_GS] = "gs_base",
6870         [R_SS] = "ss_base",
6871     };
6872     static const char bnd_regl_names[4][8] = {
6873         "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
6874     };
6875     static const char bnd_regu_names[4][8] = {
6876         "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
6877     };
6878     int i;
6879 
6880     cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
6881                                        offsetof(CPUX86State, cc_op), "cc_op");
6882     cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
6883                                     "cc_dst");
6884     cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src),
6885                                     "cc_src");
6886     cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
6887                                      "cc_src2");
6888     cpu_eip = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, eip), eip_name);
6889 
6890     for (i = 0; i < CPU_NB_REGS; ++i) {
6891         cpu_regs[i] = tcg_global_mem_new(cpu_env,
6892                                          offsetof(CPUX86State, regs[i]),
6893                                          reg_names[i]);
6894     }
6895 
6896     for (i = 0; i < 6; ++i) {
6897         cpu_seg_base[i]
6898             = tcg_global_mem_new(cpu_env,
6899                                  offsetof(CPUX86State, segs[i].base),
6900                                  seg_base_names[i]);
6901     }
6902 
6903     for (i = 0; i < 4; ++i) {
6904         cpu_bndl[i]
6905             = tcg_global_mem_new_i64(cpu_env,
6906                                      offsetof(CPUX86State, bnd_regs[i].lb),
6907                                      bnd_regl_names[i]);
6908         cpu_bndu[i]
6909             = tcg_global_mem_new_i64(cpu_env,
6910                                      offsetof(CPUX86State, bnd_regs[i].ub),
6911                                      bnd_regu_names[i]);
6912     }
6913 }
6914 
6915 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
6916 {
6917     DisasContext *dc = container_of(dcbase, DisasContext, base);
6918     CPUX86State *env = cpu->env_ptr;
6919     uint32_t flags = dc->base.tb->flags;
6920     uint32_t cflags = tb_cflags(dc->base.tb);
6921     int cpl = (flags >> HF_CPL_SHIFT) & 3;
6922     int iopl = (flags >> IOPL_SHIFT) & 3;
6923 
6924     dc->cs_base = dc->base.tb->cs_base;
6925     dc->pc_save = dc->base.pc_next;
6926     dc->flags = flags;
6927 #ifndef CONFIG_USER_ONLY
6928     dc->cpl = cpl;
6929     dc->iopl = iopl;
6930 #endif
6931 
6932     /* We make some simplifying assumptions; validate they're correct. */
6933     g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0));
6934     g_assert(CPL(dc) == cpl);
6935     g_assert(IOPL(dc) == iopl);
6936     g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0));
6937     g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0));
6938     g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0));
6939     g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0));
6940     g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
6941     g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
6942     g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0));
6943     g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0));
6944 
6945     dc->cc_op = CC_OP_DYNAMIC;
6946     dc->cc_op_dirty = false;
6947     dc->popl_esp_hack = 0;
6948     /* select memory access functions */
6949     dc->mem_index = 0;
6950 #ifdef CONFIG_SOFTMMU
6951     dc->mem_index = cpu_mmu_index(env, false);
6952 #endif
6953     dc->cpuid_features = env->features[FEAT_1_EDX];
6954     dc->cpuid_ext_features = env->features[FEAT_1_ECX];
6955     dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
6956     dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
6957     dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
6958     dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX];
6959     dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
6960     dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) ||
6961                     (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
6962     /*
6963      * If jmp_opt, we want to handle each string instruction individually.
6964      * For icount also disable repz optimization so that each iteration
6965      * is accounted separately.
6966      */
6967     dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT);
6968 
6969     dc->T0 = tcg_temp_new();
6970     dc->T1 = tcg_temp_new();
6971     dc->A0 = tcg_temp_new();
6972 
6973     dc->tmp0 = tcg_temp_new();
6974     dc->tmp1_i64 = tcg_temp_new_i64();
6975     dc->tmp2_i32 = tcg_temp_new_i32();
6976     dc->tmp3_i32 = tcg_temp_new_i32();
6977     dc->tmp4 = tcg_temp_new();
6978     dc->cc_srcT = tcg_temp_new();
6979 }
6980 
6981 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
6982 {
6983 }
6984 
6985 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
6986 {
6987     DisasContext *dc = container_of(dcbase, DisasContext, base);
6988     target_ulong pc_arg = dc->base.pc_next;
6989 
6990     dc->prev_insn_end = tcg_last_op();
6991     if (tb_cflags(dcbase->tb) & CF_PCREL) {
6992         pc_arg -= dc->cs_base;
6993         pc_arg &= ~TARGET_PAGE_MASK;
6994     }
6995     tcg_gen_insn_start(pc_arg, dc->cc_op);
6996 }
6997 
6998 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
6999 {
7000     DisasContext *dc = container_of(dcbase, DisasContext, base);
7001 
7002 #ifdef TARGET_VSYSCALL_PAGE
7003     /*
7004      * Detect entry into the vsyscall page and invoke the syscall.
7005      */
7006     if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) {
7007         gen_exception(dc, EXCP_VSYSCALL);
7008         dc->base.pc_next = dc->pc + 1;
7009         return;
7010     }
7011 #endif
7012 
7013     if (disas_insn(dc, cpu)) {
7014         target_ulong pc_next = dc->pc;
7015         dc->base.pc_next = pc_next;
7016 
7017         if (dc->base.is_jmp == DISAS_NEXT) {
7018             if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
7019                 /*
7020                  * If single step mode, we generate only one instruction and
7021                  * generate an exception.
7022                  * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
7023                  * the flag and abort the translation to give the irqs a
7024                  * chance to happen.
7025                  */
7026                 dc->base.is_jmp = DISAS_EOB_NEXT;
7027             } else if (!is_same_page(&dc->base, pc_next)) {
7028                 dc->base.is_jmp = DISAS_TOO_MANY;
7029             }
7030         }
7031     }
7032 }
7033 
7034 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
7035 {
7036     DisasContext *dc = container_of(dcbase, DisasContext, base);
7037 
7038     switch (dc->base.is_jmp) {
7039     case DISAS_NORETURN:
7040         break;
7041     case DISAS_TOO_MANY:
7042         gen_update_cc_op(dc);
7043         gen_jmp_rel_csize(dc, 0, 0);
7044         break;
7045     case DISAS_EOB_NEXT:
7046         gen_update_cc_op(dc);
7047         gen_update_eip_cur(dc);
7048         /* fall through */
7049     case DISAS_EOB_ONLY:
7050         gen_eob(dc);
7051         break;
7052     case DISAS_EOB_INHIBIT_IRQ:
7053         gen_update_cc_op(dc);
7054         gen_update_eip_cur(dc);
7055         gen_eob_inhibit_irq(dc, true);
7056         break;
7057     case DISAS_JUMP:
7058         gen_jr(dc);
7059         break;
7060     default:
7061         g_assert_not_reached();
7062     }
7063 }
7064 
7065 static void i386_tr_disas_log(const DisasContextBase *dcbase,
7066                               CPUState *cpu, FILE *logfile)
7067 {
7068     DisasContext *dc = container_of(dcbase, DisasContext, base);
7069 
7070     fprintf(logfile, "IN: %s\n", lookup_symbol(dc->base.pc_first));
7071     target_disas(logfile, cpu, dc->base.pc_first, dc->base.tb->size);
7072 }
7073 
7074 static const TranslatorOps i386_tr_ops = {
7075     .init_disas_context = i386_tr_init_disas_context,
7076     .tb_start           = i386_tr_tb_start,
7077     .insn_start         = i386_tr_insn_start,
7078     .translate_insn     = i386_tr_translate_insn,
7079     .tb_stop            = i386_tr_tb_stop,
7080     .disas_log          = i386_tr_disas_log,
7081 };
7082 
7083 /* generate intermediate code for basic block 'tb'.  */
7084 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
7085                            target_ulong pc, void *host_pc)
7086 {
7087     DisasContext dc;
7088 
7089     translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base);
7090 }
7091