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