xref: /qemu/target/i386/tcg/translate.c (revision 6bbeb98d10f9d93e723a0fa3d35457750f5e69ac)
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 
30 #include "exec/helper-proto.h"
31 #include "exec/helper-gen.h"
32 #include "helper-tcg.h"
33 
34 #include "exec/log.h"
35 
36 #define PREFIX_REPZ   0x01
37 #define PREFIX_REPNZ  0x02
38 #define PREFIX_LOCK   0x04
39 #define PREFIX_DATA   0x08
40 #define PREFIX_ADR    0x10
41 #define PREFIX_VEX    0x20
42 #define PREFIX_REX    0x40
43 
44 #ifdef TARGET_X86_64
45 # define ctztl  ctz64
46 # define clztl  clz64
47 #else
48 # define ctztl  ctz32
49 # define clztl  clz32
50 #endif
51 
52 /* For a switch indexed by MODRM, match all memory operands for a given OP.  */
53 #define CASE_MODRM_MEM_OP(OP) \
54     case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
55     case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
56     case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7
57 
58 #define CASE_MODRM_OP(OP) \
59     case (0 << 6) | (OP << 3) | 0 ... (0 << 6) | (OP << 3) | 7: \
60     case (1 << 6) | (OP << 3) | 0 ... (1 << 6) | (OP << 3) | 7: \
61     case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
62     case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
63 
64 //#define MACRO_TEST   1
65 
66 /* global register indexes */
67 static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2;
68 static TCGv cpu_eip;
69 static TCGv_i32 cpu_cc_op;
70 static TCGv cpu_regs[CPU_NB_REGS];
71 static TCGv cpu_seg_base[6];
72 static TCGv_i64 cpu_bndl[4];
73 static TCGv_i64 cpu_bndu[4];
74 
75 #include "exec/gen-icount.h"
76 
77 typedef struct DisasContext {
78     DisasContextBase base;
79 
80     target_ulong pc;       /* pc = eip + cs_base */
81     target_ulong cs_base;  /* base of CS segment */
82     target_ulong pc_save;
83 
84     MemOp aflag;
85     MemOp dflag;
86 
87     int8_t override; /* -1 if no override, else R_CS, R_DS, etc */
88     uint8_t prefix;
89 
90     bool has_modrm;
91     uint8_t modrm;
92 
93 #ifndef CONFIG_USER_ONLY
94     uint8_t cpl;   /* code priv level */
95     uint8_t iopl;  /* i/o priv level */
96 #endif
97     uint8_t vex_l;  /* vex vector length */
98     uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
99     uint8_t popl_esp_hack; /* for correct popl with esp base handling */
100     uint8_t rip_offset; /* only used in x86_64, but left for simplicity */
101 
102 #ifdef TARGET_X86_64
103     uint8_t rex_r;
104     uint8_t rex_x;
105     uint8_t rex_b;
106 #endif
107     bool vex_w; /* used by AVX even on 32-bit processors */
108     bool jmp_opt; /* use direct block chaining for direct jumps */
109     bool repz_opt; /* optimize jumps within repz instructions */
110     bool cc_op_dirty;
111 
112     CCOp cc_op;  /* current CC operation */
113     int mem_index; /* select memory access functions */
114     uint32_t flags; /* all execution flags */
115     int cpuid_features;
116     int cpuid_ext_features;
117     int cpuid_ext2_features;
118     int cpuid_ext3_features;
119     int cpuid_7_0_ebx_features;
120     int cpuid_7_0_ecx_features;
121     int cpuid_xsave_features;
122 
123     /* TCG local temps */
124     TCGv cc_srcT;
125     TCGv A0;
126     TCGv T0;
127     TCGv T1;
128 
129     /* TCG local register indexes (only used inside old micro ops) */
130     TCGv tmp0;
131     TCGv tmp4;
132     TCGv_ptr ptr0;
133     TCGv_ptr ptr1;
134     TCGv_ptr ptr2;
135     TCGv_i32 tmp2_i32;
136     TCGv_i32 tmp3_i32;
137     TCGv_i64 tmp1_i64;
138 
139     sigjmp_buf jmpbuf;
140     TCGOp *prev_insn_end;
141 } DisasContext;
142 
143 #define DISAS_EOB_ONLY         DISAS_TARGET_0
144 #define DISAS_EOB_NEXT         DISAS_TARGET_1
145 #define DISAS_EOB_INHIBIT_IRQ  DISAS_TARGET_2
146 #define DISAS_JUMP             DISAS_TARGET_3
147 
148 /* The environment in which user-only runs is constrained. */
149 #ifdef CONFIG_USER_ONLY
150 #define PE(S)     true
151 #define CPL(S)    3
152 #define IOPL(S)   0
153 #define SVME(S)   false
154 #define GUEST(S)  false
155 #else
156 #define PE(S)     (((S)->flags & HF_PE_MASK) != 0)
157 #define CPL(S)    ((S)->cpl)
158 #define IOPL(S)   ((S)->iopl)
159 #define SVME(S)   (((S)->flags & HF_SVME_MASK) != 0)
160 #define GUEST(S)  (((S)->flags & HF_GUEST_MASK) != 0)
161 #endif
162 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
163 #define VM86(S)   false
164 #define CODE32(S) true
165 #define SS32(S)   true
166 #define ADDSEG(S) false
167 #else
168 #define VM86(S)   (((S)->flags & HF_VM_MASK) != 0)
169 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0)
170 #define SS32(S)   (((S)->flags & HF_SS32_MASK) != 0)
171 #define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0)
172 #endif
173 #if !defined(TARGET_X86_64)
174 #define CODE64(S) false
175 #define LMA(S)    false
176 #elif defined(CONFIG_USER_ONLY)
177 #define CODE64(S) true
178 #define LMA(S)    true
179 #else
180 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0)
181 #define LMA(S)    (((S)->flags & HF_LMA_MASK) != 0)
182 #endif
183 
184 #ifdef TARGET_X86_64
185 #define REX_PREFIX(S)  (((S)->prefix & PREFIX_REX) != 0)
186 #define REX_W(S)       ((S)->vex_w)
187 #define REX_R(S)       ((S)->rex_r + 0)
188 #define REX_X(S)       ((S)->rex_x + 0)
189 #define REX_B(S)       ((S)->rex_b + 0)
190 #else
191 #define REX_PREFIX(S)  false
192 #define REX_W(S)       false
193 #define REX_R(S)       0
194 #define REX_X(S)       0
195 #define REX_B(S)       0
196 #endif
197 
198 /*
199  * Many sysemu-only helpers are not reachable for user-only.
200  * Define stub generators here, so that we need not either sprinkle
201  * ifdefs through the translator, nor provide the helper function.
202  */
203 #define STUB_HELPER(NAME, ...) \
204     static inline void gen_helper_##NAME(__VA_ARGS__) \
205     { qemu_build_not_reached(); }
206 
207 #ifdef CONFIG_USER_ONLY
208 STUB_HELPER(clgi, TCGv_env env)
209 STUB_HELPER(flush_page, TCGv_env env, TCGv addr)
210 STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs)
211 STUB_HELPER(inb, TCGv ret, TCGv_env env, TCGv_i32 port)
212 STUB_HELPER(inw, TCGv ret, TCGv_env env, TCGv_i32 port)
213 STUB_HELPER(inl, TCGv ret, TCGv_env env, TCGv_i32 port)
214 STUB_HELPER(monitor, TCGv_env env, TCGv addr)
215 STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs)
216 STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
217 STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
218 STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
219 STUB_HELPER(rdmsr, TCGv_env env)
220 STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg)
221 STUB_HELPER(get_dr, TCGv ret, TCGv_env env, TCGv_i32 reg)
222 STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
223 STUB_HELPER(stgi, TCGv_env env)
224 STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type)
225 STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag)
226 STUB_HELPER(vmmcall, TCGv_env env)
227 STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs)
228 STUB_HELPER(vmsave, TCGv_env env, TCGv_i32 aflag)
229 STUB_HELPER(write_crN, TCGv_env env, TCGv_i32 reg, TCGv val)
230 STUB_HELPER(wrmsr, TCGv_env env)
231 #endif
232 
233 static void gen_eob(DisasContext *s);
234 static void gen_jr(DisasContext *s);
235 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num);
236 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num);
237 static void gen_op(DisasContext *s1, int op, MemOp ot, int d);
238 static void gen_exception_gpf(DisasContext *s);
239 
240 /* i386 arith/logic operations */
241 enum {
242     OP_ADDL,
243     OP_ORL,
244     OP_ADCL,
245     OP_SBBL,
246     OP_ANDL,
247     OP_SUBL,
248     OP_XORL,
249     OP_CMPL,
250 };
251 
252 /* i386 shift ops */
253 enum {
254     OP_ROL,
255     OP_ROR,
256     OP_RCL,
257     OP_RCR,
258     OP_SHL,
259     OP_SHR,
260     OP_SHL1, /* undocumented */
261     OP_SAR = 7,
262 };
263 
264 enum {
265     JCC_O,
266     JCC_B,
267     JCC_Z,
268     JCC_BE,
269     JCC_S,
270     JCC_P,
271     JCC_L,
272     JCC_LE,
273 };
274 
275 enum {
276     /* I386 int registers */
277     OR_EAX,   /* MUST be even numbered */
278     OR_ECX,
279     OR_EDX,
280     OR_EBX,
281     OR_ESP,
282     OR_EBP,
283     OR_ESI,
284     OR_EDI,
285 
286     OR_TMP0 = 16,    /* temporary operand register */
287     OR_TMP1,
288     OR_A0, /* temporary register used when doing address evaluation */
289 };
290 
291 enum {
292     USES_CC_DST  = 1,
293     USES_CC_SRC  = 2,
294     USES_CC_SRC2 = 4,
295     USES_CC_SRCT = 8,
296 };
297 
298 /* Bit set if the global variable is live after setting CC_OP to X.  */
299 static const uint8_t cc_op_live[CC_OP_NB] = {
300     [CC_OP_DYNAMIC] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
301     [CC_OP_EFLAGS] = USES_CC_SRC,
302     [CC_OP_MULB ... CC_OP_MULQ] = USES_CC_DST | USES_CC_SRC,
303     [CC_OP_ADDB ... CC_OP_ADDQ] = USES_CC_DST | USES_CC_SRC,
304     [CC_OP_ADCB ... CC_OP_ADCQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
305     [CC_OP_SUBB ... CC_OP_SUBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRCT,
306     [CC_OP_SBBB ... CC_OP_SBBQ] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
307     [CC_OP_LOGICB ... CC_OP_LOGICQ] = USES_CC_DST,
308     [CC_OP_INCB ... CC_OP_INCQ] = USES_CC_DST | USES_CC_SRC,
309     [CC_OP_DECB ... CC_OP_DECQ] = USES_CC_DST | USES_CC_SRC,
310     [CC_OP_SHLB ... CC_OP_SHLQ] = USES_CC_DST | USES_CC_SRC,
311     [CC_OP_SARB ... CC_OP_SARQ] = USES_CC_DST | USES_CC_SRC,
312     [CC_OP_BMILGB ... CC_OP_BMILGQ] = USES_CC_DST | USES_CC_SRC,
313     [CC_OP_ADCX] = USES_CC_DST | USES_CC_SRC,
314     [CC_OP_ADOX] = USES_CC_SRC | USES_CC_SRC2,
315     [CC_OP_ADCOX] = USES_CC_DST | USES_CC_SRC | USES_CC_SRC2,
316     [CC_OP_CLR] = 0,
317     [CC_OP_POPCNT] = USES_CC_SRC,
318 };
319 
320 static void set_cc_op(DisasContext *s, CCOp op)
321 {
322     int dead;
323 
324     if (s->cc_op == op) {
325         return;
326     }
327 
328     /* Discard CC computation that will no longer be used.  */
329     dead = cc_op_live[s->cc_op] & ~cc_op_live[op];
330     if (dead & USES_CC_DST) {
331         tcg_gen_discard_tl(cpu_cc_dst);
332     }
333     if (dead & USES_CC_SRC) {
334         tcg_gen_discard_tl(cpu_cc_src);
335     }
336     if (dead & USES_CC_SRC2) {
337         tcg_gen_discard_tl(cpu_cc_src2);
338     }
339     if (dead & USES_CC_SRCT) {
340         tcg_gen_discard_tl(s->cc_srcT);
341     }
342 
343     if (op == CC_OP_DYNAMIC) {
344         /* The DYNAMIC setting is translator only, and should never be
345            stored.  Thus we always consider it clean.  */
346         s->cc_op_dirty = false;
347     } else {
348         /* Discard any computed CC_OP value (see shifts).  */
349         if (s->cc_op == CC_OP_DYNAMIC) {
350             tcg_gen_discard_i32(cpu_cc_op);
351         }
352         s->cc_op_dirty = true;
353     }
354     s->cc_op = op;
355 }
356 
357 static void gen_update_cc_op(DisasContext *s)
358 {
359     if (s->cc_op_dirty) {
360         tcg_gen_movi_i32(cpu_cc_op, s->cc_op);
361         s->cc_op_dirty = false;
362     }
363 }
364 
365 #ifdef TARGET_X86_64
366 
367 #define NB_OP_SIZES 4
368 
369 #else /* !TARGET_X86_64 */
370 
371 #define NB_OP_SIZES 3
372 
373 #endif /* !TARGET_X86_64 */
374 
375 #if HOST_BIG_ENDIAN
376 #define REG_B_OFFSET (sizeof(target_ulong) - 1)
377 #define REG_H_OFFSET (sizeof(target_ulong) - 2)
378 #define REG_W_OFFSET (sizeof(target_ulong) - 2)
379 #define REG_L_OFFSET (sizeof(target_ulong) - 4)
380 #define REG_LH_OFFSET (sizeof(target_ulong) - 8)
381 #else
382 #define REG_B_OFFSET 0
383 #define REG_H_OFFSET 1
384 #define REG_W_OFFSET 0
385 #define REG_L_OFFSET 0
386 #define REG_LH_OFFSET 4
387 #endif
388 
389 /* In instruction encodings for byte register accesses the
390  * register number usually indicates "low 8 bits of register N";
391  * however there are some special cases where N 4..7 indicates
392  * [AH, CH, DH, BH], ie "bits 15..8 of register N-4". Return
393  * true for this special case, false otherwise.
394  */
395 static inline bool byte_reg_is_xH(DisasContext *s, int reg)
396 {
397     /* Any time the REX prefix is present, byte registers are uniform */
398     if (reg < 4 || REX_PREFIX(s)) {
399         return false;
400     }
401     return true;
402 }
403 
404 /* Select the size of a push/pop operation.  */
405 static inline MemOp mo_pushpop(DisasContext *s, MemOp ot)
406 {
407     if (CODE64(s)) {
408         return ot == MO_16 ? MO_16 : MO_64;
409     } else {
410         return ot;
411     }
412 }
413 
414 /* Select the size of the stack pointer.  */
415 static inline MemOp mo_stacksize(DisasContext *s)
416 {
417     return CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16;
418 }
419 
420 /* Select only size 64 else 32.  Used for SSE operand sizes.  */
421 static inline MemOp mo_64_32(MemOp ot)
422 {
423 #ifdef TARGET_X86_64
424     return ot == MO_64 ? MO_64 : MO_32;
425 #else
426     return MO_32;
427 #endif
428 }
429 
430 /* Select size 8 if lsb of B is clear, else OT.  Used for decoding
431    byte vs word opcodes.  */
432 static inline MemOp mo_b_d(int b, MemOp ot)
433 {
434     return b & 1 ? ot : MO_8;
435 }
436 
437 /* Select size 8 if lsb of B is clear, else OT capped at 32.
438    Used for decoding operand size of port opcodes.  */
439 static inline MemOp mo_b_d32(int b, MemOp ot)
440 {
441     return b & 1 ? (ot == MO_16 ? MO_16 : MO_32) : MO_8;
442 }
443 
444 static void gen_op_mov_reg_v(DisasContext *s, MemOp ot, int reg, TCGv t0)
445 {
446     switch(ot) {
447     case MO_8:
448         if (!byte_reg_is_xH(s, reg)) {
449             tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);
450         } else {
451             tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);
452         }
453         break;
454     case MO_16:
455         tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);
456         break;
457     case MO_32:
458         /* For x86_64, this sets the higher half of register to zero.
459            For i386, this is equivalent to a mov. */
460         tcg_gen_ext32u_tl(cpu_regs[reg], t0);
461         break;
462 #ifdef TARGET_X86_64
463     case MO_64:
464         tcg_gen_mov_tl(cpu_regs[reg], t0);
465         break;
466 #endif
467     default:
468         tcg_abort();
469     }
470 }
471 
472 static inline
473 void gen_op_mov_v_reg(DisasContext *s, MemOp ot, TCGv t0, int reg)
474 {
475     if (ot == MO_8 && byte_reg_is_xH(s, reg)) {
476         tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8);
477     } else {
478         tcg_gen_mov_tl(t0, cpu_regs[reg]);
479     }
480 }
481 
482 static void gen_add_A0_im(DisasContext *s, int val)
483 {
484     tcg_gen_addi_tl(s->A0, s->A0, val);
485     if (!CODE64(s)) {
486         tcg_gen_ext32u_tl(s->A0, s->A0);
487     }
488 }
489 
490 static inline void gen_op_jmp_v(DisasContext *s, TCGv dest)
491 {
492     tcg_gen_mov_tl(cpu_eip, dest);
493     s->pc_save = -1;
494 }
495 
496 static inline
497 void gen_op_add_reg_im(DisasContext *s, MemOp size, int reg, int32_t val)
498 {
499     tcg_gen_addi_tl(s->tmp0, cpu_regs[reg], val);
500     gen_op_mov_reg_v(s, size, reg, s->tmp0);
501 }
502 
503 static inline void gen_op_add_reg_T0(DisasContext *s, MemOp size, int reg)
504 {
505     tcg_gen_add_tl(s->tmp0, cpu_regs[reg], s->T0);
506     gen_op_mov_reg_v(s, size, reg, s->tmp0);
507 }
508 
509 static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
510 {
511     tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
512 }
513 
514 static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
515 {
516     tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
517 }
518 
519 static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
520 {
521     if (d == OR_TMP0) {
522         gen_op_st_v(s, idx, s->T0, s->A0);
523     } else {
524         gen_op_mov_reg_v(s, idx, d, s->T0);
525     }
526 }
527 
528 static void gen_update_eip_cur(DisasContext *s)
529 {
530     assert(s->pc_save != -1);
531     if (TARGET_TB_PCREL) {
532         tcg_gen_addi_tl(cpu_eip, cpu_eip, s->base.pc_next - s->pc_save);
533     } else {
534         tcg_gen_movi_tl(cpu_eip, s->base.pc_next - s->cs_base);
535     }
536     s->pc_save = s->base.pc_next;
537 }
538 
539 static void gen_update_eip_next(DisasContext *s)
540 {
541     assert(s->pc_save != -1);
542     if (TARGET_TB_PCREL) {
543         tcg_gen_addi_tl(cpu_eip, cpu_eip, s->pc - s->pc_save);
544     } else {
545         tcg_gen_movi_tl(cpu_eip, s->pc - s->cs_base);
546     }
547     s->pc_save = s->pc;
548 }
549 
550 static int cur_insn_len(DisasContext *s)
551 {
552     return s->pc - s->base.pc_next;
553 }
554 
555 static TCGv_i32 cur_insn_len_i32(DisasContext *s)
556 {
557     return tcg_constant_i32(cur_insn_len(s));
558 }
559 
560 static TCGv_i32 eip_next_i32(DisasContext *s)
561 {
562     assert(s->pc_save != -1);
563     /*
564      * This function has two users: lcall_real (always 16-bit mode), and
565      * iret_protected (16, 32, or 64-bit mode).  IRET only uses the value
566      * when EFLAGS.NT is set, which is illegal in 64-bit mode, which is
567      * why passing a 32-bit value isn't broken.  To avoid using this where
568      * we shouldn't, return -1 in 64-bit mode so that execution goes into
569      * the weeds quickly.
570      */
571     if (CODE64(s)) {
572         return tcg_constant_i32(-1);
573     }
574     if (TARGET_TB_PCREL) {
575         TCGv_i32 ret = tcg_temp_new_i32();
576         tcg_gen_trunc_tl_i32(ret, cpu_eip);
577         tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save);
578         return ret;
579     } else {
580         return tcg_constant_i32(s->pc - s->cs_base);
581     }
582 }
583 
584 static TCGv eip_next_tl(DisasContext *s)
585 {
586     assert(s->pc_save != -1);
587     if (TARGET_TB_PCREL) {
588         TCGv ret = tcg_temp_new();
589         tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save);
590         return ret;
591     } else {
592         return tcg_constant_tl(s->pc - s->cs_base);
593     }
594 }
595 
596 static TCGv eip_cur_tl(DisasContext *s)
597 {
598     assert(s->pc_save != -1);
599     if (TARGET_TB_PCREL) {
600         TCGv ret = tcg_temp_new();
601         tcg_gen_addi_tl(ret, cpu_eip, s->base.pc_next - s->pc_save);
602         return ret;
603     } else {
604         return tcg_constant_tl(s->base.pc_next - s->cs_base);
605     }
606 }
607 
608 /* Compute SEG:REG into A0.  SEG is selected from the override segment
609    (OVR_SEG) and the default segment (DEF_SEG).  OVR_SEG may be -1 to
610    indicate no override.  */
611 static void gen_lea_v_seg(DisasContext *s, MemOp aflag, TCGv a0,
612                           int def_seg, int ovr_seg)
613 {
614     switch (aflag) {
615 #ifdef TARGET_X86_64
616     case MO_64:
617         if (ovr_seg < 0) {
618             tcg_gen_mov_tl(s->A0, a0);
619             return;
620         }
621         break;
622 #endif
623     case MO_32:
624         /* 32 bit address */
625         if (ovr_seg < 0 && ADDSEG(s)) {
626             ovr_seg = def_seg;
627         }
628         if (ovr_seg < 0) {
629             tcg_gen_ext32u_tl(s->A0, a0);
630             return;
631         }
632         break;
633     case MO_16:
634         /* 16 bit address */
635         tcg_gen_ext16u_tl(s->A0, a0);
636         a0 = s->A0;
637         if (ovr_seg < 0) {
638             if (ADDSEG(s)) {
639                 ovr_seg = def_seg;
640             } else {
641                 return;
642             }
643         }
644         break;
645     default:
646         tcg_abort();
647     }
648 
649     if (ovr_seg >= 0) {
650         TCGv seg = cpu_seg_base[ovr_seg];
651 
652         if (aflag == MO_64) {
653             tcg_gen_add_tl(s->A0, a0, seg);
654         } else if (CODE64(s)) {
655             tcg_gen_ext32u_tl(s->A0, a0);
656             tcg_gen_add_tl(s->A0, s->A0, seg);
657         } else {
658             tcg_gen_add_tl(s->A0, a0, seg);
659             tcg_gen_ext32u_tl(s->A0, s->A0);
660         }
661     }
662 }
663 
664 static inline void gen_string_movl_A0_ESI(DisasContext *s)
665 {
666     gen_lea_v_seg(s, s->aflag, cpu_regs[R_ESI], R_DS, s->override);
667 }
668 
669 static inline void gen_string_movl_A0_EDI(DisasContext *s)
670 {
671     gen_lea_v_seg(s, s->aflag, cpu_regs[R_EDI], R_ES, -1);
672 }
673 
674 static inline void gen_op_movl_T0_Dshift(DisasContext *s, MemOp ot)
675 {
676     tcg_gen_ld32s_tl(s->T0, cpu_env, offsetof(CPUX86State, df));
677     tcg_gen_shli_tl(s->T0, s->T0, ot);
678 };
679 
680 static TCGv gen_ext_tl(TCGv dst, TCGv src, MemOp size, bool sign)
681 {
682     switch (size) {
683     case MO_8:
684         if (sign) {
685             tcg_gen_ext8s_tl(dst, src);
686         } else {
687             tcg_gen_ext8u_tl(dst, src);
688         }
689         return dst;
690     case MO_16:
691         if (sign) {
692             tcg_gen_ext16s_tl(dst, src);
693         } else {
694             tcg_gen_ext16u_tl(dst, src);
695         }
696         return dst;
697 #ifdef TARGET_X86_64
698     case MO_32:
699         if (sign) {
700             tcg_gen_ext32s_tl(dst, src);
701         } else {
702             tcg_gen_ext32u_tl(dst, src);
703         }
704         return dst;
705 #endif
706     default:
707         return src;
708     }
709 }
710 
711 static void gen_extu(MemOp ot, TCGv reg)
712 {
713     gen_ext_tl(reg, reg, ot, false);
714 }
715 
716 static void gen_exts(MemOp ot, TCGv reg)
717 {
718     gen_ext_tl(reg, reg, ot, true);
719 }
720 
721 static void gen_op_j_ecx(DisasContext *s, TCGCond cond, TCGLabel *label1)
722 {
723     tcg_gen_mov_tl(s->tmp0, cpu_regs[R_ECX]);
724     gen_extu(s->aflag, s->tmp0);
725     tcg_gen_brcondi_tl(cond, s->tmp0, 0, label1);
726 }
727 
728 static inline void gen_op_jz_ecx(DisasContext *s, TCGLabel *label1)
729 {
730     gen_op_j_ecx(s, TCG_COND_EQ, label1);
731 }
732 
733 static inline void gen_op_jnz_ecx(DisasContext *s, TCGLabel *label1)
734 {
735     gen_op_j_ecx(s, TCG_COND_NE, label1);
736 }
737 
738 static void gen_helper_in_func(MemOp ot, TCGv v, TCGv_i32 n)
739 {
740     switch (ot) {
741     case MO_8:
742         gen_helper_inb(v, cpu_env, n);
743         break;
744     case MO_16:
745         gen_helper_inw(v, cpu_env, n);
746         break;
747     case MO_32:
748         gen_helper_inl(v, cpu_env, n);
749         break;
750     default:
751         tcg_abort();
752     }
753 }
754 
755 static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n)
756 {
757     switch (ot) {
758     case MO_8:
759         gen_helper_outb(cpu_env, v, n);
760         break;
761     case MO_16:
762         gen_helper_outw(cpu_env, v, n);
763         break;
764     case MO_32:
765         gen_helper_outl(cpu_env, v, n);
766         break;
767     default:
768         tcg_abort();
769     }
770 }
771 
772 /*
773  * Validate that access to [port, port + 1<<ot) is allowed.
774  * Raise #GP, or VMM exit if not.
775  */
776 static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
777                          uint32_t svm_flags)
778 {
779 #ifdef CONFIG_USER_ONLY
780     /*
781      * We do not implement the ioperm(2) syscall, so the TSS check
782      * will always fail.
783      */
784     gen_exception_gpf(s);
785     return false;
786 #else
787     if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) {
788         gen_helper_check_io(cpu_env, port, tcg_constant_i32(1 << ot));
789     }
790     if (GUEST(s)) {
791         gen_update_cc_op(s);
792         gen_update_eip_cur(s);
793         if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
794             svm_flags |= SVM_IOIO_REP_MASK;
795         }
796         svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot);
797         gen_helper_svm_check_io(cpu_env, port,
798                                 tcg_constant_i32(svm_flags),
799                                 cur_insn_len_i32(s));
800     }
801     return true;
802 #endif
803 }
804 
805 static void gen_movs(DisasContext *s, MemOp ot)
806 {
807     gen_string_movl_A0_ESI(s);
808     gen_op_ld_v(s, ot, s->T0, s->A0);
809     gen_string_movl_A0_EDI(s);
810     gen_op_st_v(s, ot, s->T0, s->A0);
811     gen_op_movl_T0_Dshift(s, ot);
812     gen_op_add_reg_T0(s, s->aflag, R_ESI);
813     gen_op_add_reg_T0(s, s->aflag, R_EDI);
814 }
815 
816 static void gen_op_update1_cc(DisasContext *s)
817 {
818     tcg_gen_mov_tl(cpu_cc_dst, s->T0);
819 }
820 
821 static void gen_op_update2_cc(DisasContext *s)
822 {
823     tcg_gen_mov_tl(cpu_cc_src, s->T1);
824     tcg_gen_mov_tl(cpu_cc_dst, s->T0);
825 }
826 
827 static void gen_op_update3_cc(DisasContext *s, TCGv reg)
828 {
829     tcg_gen_mov_tl(cpu_cc_src2, reg);
830     tcg_gen_mov_tl(cpu_cc_src, s->T1);
831     tcg_gen_mov_tl(cpu_cc_dst, s->T0);
832 }
833 
834 static inline void gen_op_testl_T0_T1_cc(DisasContext *s)
835 {
836     tcg_gen_and_tl(cpu_cc_dst, s->T0, s->T1);
837 }
838 
839 static void gen_op_update_neg_cc(DisasContext *s)
840 {
841     tcg_gen_mov_tl(cpu_cc_dst, s->T0);
842     tcg_gen_neg_tl(cpu_cc_src, s->T0);
843     tcg_gen_movi_tl(s->cc_srcT, 0);
844 }
845 
846 /* compute all eflags to cc_src */
847 static void gen_compute_eflags(DisasContext *s)
848 {
849     TCGv zero, dst, src1, src2;
850     int live, dead;
851 
852     if (s->cc_op == CC_OP_EFLAGS) {
853         return;
854     }
855     if (s->cc_op == CC_OP_CLR) {
856         tcg_gen_movi_tl(cpu_cc_src, CC_Z | CC_P);
857         set_cc_op(s, CC_OP_EFLAGS);
858         return;
859     }
860 
861     zero = NULL;
862     dst = cpu_cc_dst;
863     src1 = cpu_cc_src;
864     src2 = cpu_cc_src2;
865 
866     /* Take care to not read values that are not live.  */
867     live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
868     dead = live ^ (USES_CC_DST | USES_CC_SRC | USES_CC_SRC2);
869     if (dead) {
870         zero = tcg_const_tl(0);
871         if (dead & USES_CC_DST) {
872             dst = zero;
873         }
874         if (dead & USES_CC_SRC) {
875             src1 = zero;
876         }
877         if (dead & USES_CC_SRC2) {
878             src2 = zero;
879         }
880     }
881 
882     gen_update_cc_op(s);
883     gen_helper_cc_compute_all(cpu_cc_src, dst, src1, src2, cpu_cc_op);
884     set_cc_op(s, CC_OP_EFLAGS);
885 
886     if (dead) {
887         tcg_temp_free(zero);
888     }
889 }
890 
891 typedef struct CCPrepare {
892     TCGCond cond;
893     TCGv reg;
894     TCGv reg2;
895     target_ulong imm;
896     target_ulong mask;
897     bool use_reg2;
898     bool no_setcond;
899 } CCPrepare;
900 
901 /* compute eflags.C to reg */
902 static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
903 {
904     TCGv t0, t1;
905     int size, shift;
906 
907     switch (s->cc_op) {
908     case CC_OP_SUBB ... CC_OP_SUBQ:
909         /* (DATA_TYPE)CC_SRCT < (DATA_TYPE)CC_SRC */
910         size = s->cc_op - CC_OP_SUBB;
911         t1 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false);
912         /* If no temporary was used, be careful not to alias t1 and t0.  */
913         t0 = t1 == cpu_cc_src ? s->tmp0 : reg;
914         tcg_gen_mov_tl(t0, s->cc_srcT);
915         gen_extu(size, t0);
916         goto add_sub;
917 
918     case CC_OP_ADDB ... CC_OP_ADDQ:
919         /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
920         size = s->cc_op - CC_OP_ADDB;
921         t1 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false);
922         t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
923     add_sub:
924         return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,
925                              .reg2 = t1, .mask = -1, .use_reg2 = true };
926 
927     case CC_OP_LOGICB ... CC_OP_LOGICQ:
928     case CC_OP_CLR:
929     case CC_OP_POPCNT:
930         return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
931 
932     case CC_OP_INCB ... CC_OP_INCQ:
933     case CC_OP_DECB ... CC_OP_DECQ:
934         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
935                              .mask = -1, .no_setcond = true };
936 
937     case CC_OP_SHLB ... CC_OP_SHLQ:
938         /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
939         size = s->cc_op - CC_OP_SHLB;
940         shift = (8 << size) - 1;
941         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
942                              .mask = (target_ulong)1 << shift };
943 
944     case CC_OP_MULB ... CC_OP_MULQ:
945         return (CCPrepare) { .cond = TCG_COND_NE,
946                              .reg = cpu_cc_src, .mask = -1 };
947 
948     case CC_OP_BMILGB ... CC_OP_BMILGQ:
949         size = s->cc_op - CC_OP_BMILGB;
950         t0 = gen_ext_tl(reg, cpu_cc_src, size, false);
951         return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
952 
953     case CC_OP_ADCX:
954     case CC_OP_ADCOX:
955         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
956                              .mask = -1, .no_setcond = true };
957 
958     case CC_OP_EFLAGS:
959     case CC_OP_SARB ... CC_OP_SARQ:
960         /* CC_SRC & 1 */
961         return (CCPrepare) { .cond = TCG_COND_NE,
962                              .reg = cpu_cc_src, .mask = CC_C };
963 
964     default:
965        /* The need to compute only C from CC_OP_DYNAMIC is important
966           in efficiently implementing e.g. INC at the start of a TB.  */
967        gen_update_cc_op(s);
968        gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
969                                cpu_cc_src2, cpu_cc_op);
970        return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
971                             .mask = -1, .no_setcond = true };
972     }
973 }
974 
975 /* compute eflags.P to reg */
976 static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
977 {
978     gen_compute_eflags(s);
979     return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
980                          .mask = CC_P };
981 }
982 
983 /* compute eflags.S to reg */
984 static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
985 {
986     switch (s->cc_op) {
987     case CC_OP_DYNAMIC:
988         gen_compute_eflags(s);
989         /* FALLTHRU */
990     case CC_OP_EFLAGS:
991     case CC_OP_ADCX:
992     case CC_OP_ADOX:
993     case CC_OP_ADCOX:
994         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
995                              .mask = CC_S };
996     case CC_OP_CLR:
997     case CC_OP_POPCNT:
998         return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
999     default:
1000         {
1001             MemOp size = (s->cc_op - CC_OP_ADDB) & 3;
1002             TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, true);
1003             return (CCPrepare) { .cond = TCG_COND_LT, .reg = t0, .mask = -1 };
1004         }
1005     }
1006 }
1007 
1008 /* compute eflags.O to reg */
1009 static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
1010 {
1011     switch (s->cc_op) {
1012     case CC_OP_ADOX:
1013     case CC_OP_ADCOX:
1014         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
1015                              .mask = -1, .no_setcond = true };
1016     case CC_OP_CLR:
1017     case CC_OP_POPCNT:
1018         return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
1019     default:
1020         gen_compute_eflags(s);
1021         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1022                              .mask = CC_O };
1023     }
1024 }
1025 
1026 /* compute eflags.Z to reg */
1027 static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
1028 {
1029     switch (s->cc_op) {
1030     case CC_OP_DYNAMIC:
1031         gen_compute_eflags(s);
1032         /* FALLTHRU */
1033     case CC_OP_EFLAGS:
1034     case CC_OP_ADCX:
1035     case CC_OP_ADOX:
1036     case CC_OP_ADCOX:
1037         return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1038                              .mask = CC_Z };
1039     case CC_OP_CLR:
1040         return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
1041     case CC_OP_POPCNT:
1042         return (CCPrepare) { .cond = TCG_COND_EQ, .reg = cpu_cc_src,
1043                              .mask = -1 };
1044     default:
1045         {
1046             MemOp size = (s->cc_op - CC_OP_ADDB) & 3;
1047             TCGv t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);
1048             return (CCPrepare) { .cond = TCG_COND_EQ, .reg = t0, .mask = -1 };
1049         }
1050     }
1051 }
1052 
1053 /* perform a conditional store into register 'reg' according to jump opcode
1054    value 'b'. In the fast case, T0 is guaranted not to be used. */
1055 static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
1056 {
1057     int inv, jcc_op, cond;
1058     MemOp size;
1059     CCPrepare cc;
1060     TCGv t0;
1061 
1062     inv = b & 1;
1063     jcc_op = (b >> 1) & 7;
1064 
1065     switch (s->cc_op) {
1066     case CC_OP_SUBB ... CC_OP_SUBQ:
1067         /* We optimize relational operators for the cmp/jcc case.  */
1068         size = s->cc_op - CC_OP_SUBB;
1069         switch (jcc_op) {
1070         case JCC_BE:
1071             tcg_gen_mov_tl(s->tmp4, s->cc_srcT);
1072             gen_extu(size, s->tmp4);
1073             t0 = gen_ext_tl(s->tmp0, cpu_cc_src, size, false);
1074             cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = s->tmp4,
1075                                .reg2 = t0, .mask = -1, .use_reg2 = true };
1076             break;
1077 
1078         case JCC_L:
1079             cond = TCG_COND_LT;
1080             goto fast_jcc_l;
1081         case JCC_LE:
1082             cond = TCG_COND_LE;
1083         fast_jcc_l:
1084             tcg_gen_mov_tl(s->tmp4, s->cc_srcT);
1085             gen_exts(size, s->tmp4);
1086             t0 = gen_ext_tl(s->tmp0, cpu_cc_src, size, true);
1087             cc = (CCPrepare) { .cond = cond, .reg = s->tmp4,
1088                                .reg2 = t0, .mask = -1, .use_reg2 = true };
1089             break;
1090 
1091         default:
1092             goto slow_jcc;
1093         }
1094         break;
1095 
1096     default:
1097     slow_jcc:
1098         /* This actually generates good code for JC, JZ and JS.  */
1099         switch (jcc_op) {
1100         case JCC_O:
1101             cc = gen_prepare_eflags_o(s, reg);
1102             break;
1103         case JCC_B:
1104             cc = gen_prepare_eflags_c(s, reg);
1105             break;
1106         case JCC_Z:
1107             cc = gen_prepare_eflags_z(s, reg);
1108             break;
1109         case JCC_BE:
1110             gen_compute_eflags(s);
1111             cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
1112                                .mask = CC_Z | CC_C };
1113             break;
1114         case JCC_S:
1115             cc = gen_prepare_eflags_s(s, reg);
1116             break;
1117         case JCC_P:
1118             cc = gen_prepare_eflags_p(s, reg);
1119             break;
1120         case JCC_L:
1121             gen_compute_eflags(s);
1122             if (reg == cpu_cc_src) {
1123                 reg = s->tmp0;
1124             }
1125             tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
1126             tcg_gen_xor_tl(reg, reg, cpu_cc_src);
1127             cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1128                                .mask = CC_S };
1129             break;
1130         default:
1131         case JCC_LE:
1132             gen_compute_eflags(s);
1133             if (reg == cpu_cc_src) {
1134                 reg = s->tmp0;
1135             }
1136             tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */
1137             tcg_gen_xor_tl(reg, reg, cpu_cc_src);
1138             cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
1139                                .mask = CC_S | CC_Z };
1140             break;
1141         }
1142         break;
1143     }
1144 
1145     if (inv) {
1146         cc.cond = tcg_invert_cond(cc.cond);
1147     }
1148     return cc;
1149 }
1150 
1151 static void gen_setcc1(DisasContext *s, int b, TCGv reg)
1152 {
1153     CCPrepare cc = gen_prepare_cc(s, b, reg);
1154 
1155     if (cc.no_setcond) {
1156         if (cc.cond == TCG_COND_EQ) {
1157             tcg_gen_xori_tl(reg, cc.reg, 1);
1158         } else {
1159             tcg_gen_mov_tl(reg, cc.reg);
1160         }
1161         return;
1162     }
1163 
1164     if (cc.cond == TCG_COND_NE && !cc.use_reg2 && cc.imm == 0 &&
1165         cc.mask != 0 && (cc.mask & (cc.mask - 1)) == 0) {
1166         tcg_gen_shri_tl(reg, cc.reg, ctztl(cc.mask));
1167         tcg_gen_andi_tl(reg, reg, 1);
1168         return;
1169     }
1170     if (cc.mask != -1) {
1171         tcg_gen_andi_tl(reg, cc.reg, cc.mask);
1172         cc.reg = reg;
1173     }
1174     if (cc.use_reg2) {
1175         tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1176     } else {
1177         tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1178     }
1179 }
1180 
1181 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
1182 {
1183     gen_setcc1(s, JCC_B << 1, reg);
1184 }
1185 
1186 /* generate a conditional jump to label 'l1' according to jump opcode
1187    value 'b'. In the fast case, T0 is guaranted not to be used. */
1188 static inline void gen_jcc1_noeob(DisasContext *s, int b, TCGLabel *l1)
1189 {
1190     CCPrepare cc = gen_prepare_cc(s, b, s->T0);
1191 
1192     if (cc.mask != -1) {
1193         tcg_gen_andi_tl(s->T0, cc.reg, cc.mask);
1194         cc.reg = s->T0;
1195     }
1196     if (cc.use_reg2) {
1197         tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1198     } else {
1199         tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1200     }
1201 }
1202 
1203 /* Generate a conditional jump to label 'l1' according to jump opcode
1204    value 'b'. In the fast case, T0 is guaranted not to be used.
1205    A translation block must end soon.  */
1206 static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
1207 {
1208     CCPrepare cc = gen_prepare_cc(s, b, s->T0);
1209 
1210     gen_update_cc_op(s);
1211     if (cc.mask != -1) {
1212         tcg_gen_andi_tl(s->T0, cc.reg, cc.mask);
1213         cc.reg = s->T0;
1214     }
1215     set_cc_op(s, CC_OP_DYNAMIC);
1216     if (cc.use_reg2) {
1217         tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1218     } else {
1219         tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1220     }
1221 }
1222 
1223 /* XXX: does not work with gdbstub "ice" single step - not a
1224    serious problem */
1225 static TCGLabel *gen_jz_ecx_string(DisasContext *s)
1226 {
1227     TCGLabel *l1 = gen_new_label();
1228     TCGLabel *l2 = gen_new_label();
1229     gen_op_jnz_ecx(s, l1);
1230     gen_set_label(l2);
1231     gen_jmp_rel_csize(s, 0, 1);
1232     gen_set_label(l1);
1233     return l2;
1234 }
1235 
1236 static void gen_stos(DisasContext *s, MemOp ot)
1237 {
1238     gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
1239     gen_string_movl_A0_EDI(s);
1240     gen_op_st_v(s, ot, s->T0, s->A0);
1241     gen_op_movl_T0_Dshift(s, ot);
1242     gen_op_add_reg_T0(s, s->aflag, R_EDI);
1243 }
1244 
1245 static void gen_lods(DisasContext *s, MemOp ot)
1246 {
1247     gen_string_movl_A0_ESI(s);
1248     gen_op_ld_v(s, ot, s->T0, s->A0);
1249     gen_op_mov_reg_v(s, ot, R_EAX, s->T0);
1250     gen_op_movl_T0_Dshift(s, ot);
1251     gen_op_add_reg_T0(s, s->aflag, R_ESI);
1252 }
1253 
1254 static void gen_scas(DisasContext *s, MemOp ot)
1255 {
1256     gen_string_movl_A0_EDI(s);
1257     gen_op_ld_v(s, ot, s->T1, s->A0);
1258     gen_op(s, OP_CMPL, ot, R_EAX);
1259     gen_op_movl_T0_Dshift(s, ot);
1260     gen_op_add_reg_T0(s, s->aflag, R_EDI);
1261 }
1262 
1263 static void gen_cmps(DisasContext *s, MemOp ot)
1264 {
1265     gen_string_movl_A0_EDI(s);
1266     gen_op_ld_v(s, ot, s->T1, s->A0);
1267     gen_string_movl_A0_ESI(s);
1268     gen_op(s, OP_CMPL, ot, OR_TMP0);
1269     gen_op_movl_T0_Dshift(s, ot);
1270     gen_op_add_reg_T0(s, s->aflag, R_ESI);
1271     gen_op_add_reg_T0(s, s->aflag, R_EDI);
1272 }
1273 
1274 static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
1275 {
1276     if (s->flags & HF_IOBPT_MASK) {
1277 #ifdef CONFIG_USER_ONLY
1278         /* user-mode cpu should not be in IOBPT mode */
1279         g_assert_not_reached();
1280 #else
1281         TCGv_i32 t_size = tcg_constant_i32(1 << ot);
1282         TCGv t_next = eip_next_tl(s);
1283         gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
1284 #endif /* CONFIG_USER_ONLY */
1285     }
1286 }
1287 
1288 static void gen_ins(DisasContext *s, MemOp ot)
1289 {
1290     gen_string_movl_A0_EDI(s);
1291     /* Note: we must do this dummy write first to be restartable in
1292        case of page fault. */
1293     tcg_gen_movi_tl(s->T0, 0);
1294     gen_op_st_v(s, ot, s->T0, s->A0);
1295     tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
1296     tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff);
1297     gen_helper_in_func(ot, s->T0, s->tmp2_i32);
1298     gen_op_st_v(s, ot, s->T0, s->A0);
1299     gen_op_movl_T0_Dshift(s, ot);
1300     gen_op_add_reg_T0(s, s->aflag, R_EDI);
1301     gen_bpt_io(s, s->tmp2_i32, ot);
1302 }
1303 
1304 static void gen_outs(DisasContext *s, MemOp ot)
1305 {
1306     gen_string_movl_A0_ESI(s);
1307     gen_op_ld_v(s, ot, s->T0, s->A0);
1308 
1309     tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
1310     tcg_gen_andi_i32(s->tmp2_i32, s->tmp2_i32, 0xffff);
1311     tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T0);
1312     gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
1313     gen_op_movl_T0_Dshift(s, ot);
1314     gen_op_add_reg_T0(s, s->aflag, R_ESI);
1315     gen_bpt_io(s, s->tmp2_i32, ot);
1316 }
1317 
1318 /* Generate jumps to current or next instruction */
1319 static void gen_repz(DisasContext *s, MemOp ot,
1320                      void (*fn)(DisasContext *s, MemOp ot))
1321 {
1322     TCGLabel *l2;
1323     gen_update_cc_op(s);
1324     l2 = gen_jz_ecx_string(s);
1325     fn(s, ot);
1326     gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
1327     /*
1328      * A loop would cause two single step exceptions if ECX = 1
1329      * before rep string_insn
1330      */
1331     if (s->repz_opt) {
1332         gen_op_jz_ecx(s, l2);
1333     }
1334     gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
1335 }
1336 
1337 #define GEN_REPZ(op) \
1338     static inline void gen_repz_ ## op(DisasContext *s, MemOp ot) \
1339     { gen_repz(s, ot, gen_##op); }
1340 
1341 static void gen_repz2(DisasContext *s, MemOp ot, int nz,
1342                       void (*fn)(DisasContext *s, MemOp ot))
1343 {
1344     TCGLabel *l2;
1345     gen_update_cc_op(s);
1346     l2 = gen_jz_ecx_string(s);
1347     fn(s, ot);
1348     gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
1349     gen_update_cc_op(s);
1350     gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2);
1351     if (s->repz_opt) {
1352         gen_op_jz_ecx(s, l2);
1353     }
1354     gen_jmp_rel_csize(s, -cur_insn_len(s), 0);
1355 }
1356 
1357 #define GEN_REPZ2(op) \
1358     static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, int nz) \
1359     { gen_repz2(s, ot, nz, gen_##op); }
1360 
1361 GEN_REPZ(movs)
1362 GEN_REPZ(stos)
1363 GEN_REPZ(lods)
1364 GEN_REPZ(ins)
1365 GEN_REPZ(outs)
1366 GEN_REPZ2(scas)
1367 GEN_REPZ2(cmps)
1368 
1369 static void gen_helper_fp_arith_ST0_FT0(int op)
1370 {
1371     switch (op) {
1372     case 0:
1373         gen_helper_fadd_ST0_FT0(cpu_env);
1374         break;
1375     case 1:
1376         gen_helper_fmul_ST0_FT0(cpu_env);
1377         break;
1378     case 2:
1379         gen_helper_fcom_ST0_FT0(cpu_env);
1380         break;
1381     case 3:
1382         gen_helper_fcom_ST0_FT0(cpu_env);
1383         break;
1384     case 4:
1385         gen_helper_fsub_ST0_FT0(cpu_env);
1386         break;
1387     case 5:
1388         gen_helper_fsubr_ST0_FT0(cpu_env);
1389         break;
1390     case 6:
1391         gen_helper_fdiv_ST0_FT0(cpu_env);
1392         break;
1393     case 7:
1394         gen_helper_fdivr_ST0_FT0(cpu_env);
1395         break;
1396     }
1397 }
1398 
1399 /* NOTE the exception in "r" op ordering */
1400 static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
1401 {
1402     TCGv_i32 tmp = tcg_const_i32(opreg);
1403     switch (op) {
1404     case 0:
1405         gen_helper_fadd_STN_ST0(cpu_env, tmp);
1406         break;
1407     case 1:
1408         gen_helper_fmul_STN_ST0(cpu_env, tmp);
1409         break;
1410     case 4:
1411         gen_helper_fsubr_STN_ST0(cpu_env, tmp);
1412         break;
1413     case 5:
1414         gen_helper_fsub_STN_ST0(cpu_env, tmp);
1415         break;
1416     case 6:
1417         gen_helper_fdivr_STN_ST0(cpu_env, tmp);
1418         break;
1419     case 7:
1420         gen_helper_fdiv_STN_ST0(cpu_env, tmp);
1421         break;
1422     }
1423 }
1424 
1425 static void gen_exception(DisasContext *s, int trapno)
1426 {
1427     gen_update_cc_op(s);
1428     gen_update_eip_cur(s);
1429     gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
1430     s->base.is_jmp = DISAS_NORETURN;
1431 }
1432 
1433 /* Generate #UD for the current instruction.  The assumption here is that
1434    the instruction is known, but it isn't allowed in the current cpu mode.  */
1435 static void gen_illegal_opcode(DisasContext *s)
1436 {
1437     gen_exception(s, EXCP06_ILLOP);
1438 }
1439 
1440 /* Generate #GP for the current instruction. */
1441 static void gen_exception_gpf(DisasContext *s)
1442 {
1443     gen_exception(s, EXCP0D_GPF);
1444 }
1445 
1446 /* Check for cpl == 0; if not, raise #GP and return false. */
1447 static bool check_cpl0(DisasContext *s)
1448 {
1449     if (CPL(s) == 0) {
1450         return true;
1451     }
1452     gen_exception_gpf(s);
1453     return false;
1454 }
1455 
1456 /* If vm86, check for iopl == 3; if not, raise #GP and return false. */
1457 static bool check_vm86_iopl(DisasContext *s)
1458 {
1459     if (!VM86(s) || IOPL(s) == 3) {
1460         return true;
1461     }
1462     gen_exception_gpf(s);
1463     return false;
1464 }
1465 
1466 /* Check for iopl allowing access; if not, raise #GP and return false. */
1467 static bool check_iopl(DisasContext *s)
1468 {
1469     if (VM86(s) ? IOPL(s) == 3 : CPL(s) <= IOPL(s)) {
1470         return true;
1471     }
1472     gen_exception_gpf(s);
1473     return false;
1474 }
1475 
1476 /* if d == OR_TMP0, it means memory operand (address in A0) */
1477 static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
1478 {
1479     if (d != OR_TMP0) {
1480         if (s1->prefix & PREFIX_LOCK) {
1481             /* Lock prefix when destination is not memory.  */
1482             gen_illegal_opcode(s1);
1483             return;
1484         }
1485         gen_op_mov_v_reg(s1, ot, s1->T0, d);
1486     } else if (!(s1->prefix & PREFIX_LOCK)) {
1487         gen_op_ld_v(s1, ot, s1->T0, s1->A0);
1488     }
1489     switch(op) {
1490     case OP_ADCL:
1491         gen_compute_eflags_c(s1, s1->tmp4);
1492         if (s1->prefix & PREFIX_LOCK) {
1493             tcg_gen_add_tl(s1->T0, s1->tmp4, s1->T1);
1494             tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
1495                                         s1->mem_index, ot | MO_LE);
1496         } else {
1497             tcg_gen_add_tl(s1->T0, s1->T0, s1->T1);
1498             tcg_gen_add_tl(s1->T0, s1->T0, s1->tmp4);
1499             gen_op_st_rm_T0_A0(s1, ot, d);
1500         }
1501         gen_op_update3_cc(s1, s1->tmp4);
1502         set_cc_op(s1, CC_OP_ADCB + ot);
1503         break;
1504     case OP_SBBL:
1505         gen_compute_eflags_c(s1, s1->tmp4);
1506         if (s1->prefix & PREFIX_LOCK) {
1507             tcg_gen_add_tl(s1->T0, s1->T1, s1->tmp4);
1508             tcg_gen_neg_tl(s1->T0, s1->T0);
1509             tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
1510                                         s1->mem_index, ot | MO_LE);
1511         } else {
1512             tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1);
1513             tcg_gen_sub_tl(s1->T0, s1->T0, s1->tmp4);
1514             gen_op_st_rm_T0_A0(s1, ot, d);
1515         }
1516         gen_op_update3_cc(s1, s1->tmp4);
1517         set_cc_op(s1, CC_OP_SBBB + ot);
1518         break;
1519     case OP_ADDL:
1520         if (s1->prefix & PREFIX_LOCK) {
1521             tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T1,
1522                                         s1->mem_index, ot | MO_LE);
1523         } else {
1524             tcg_gen_add_tl(s1->T0, s1->T0, s1->T1);
1525             gen_op_st_rm_T0_A0(s1, ot, d);
1526         }
1527         gen_op_update2_cc(s1);
1528         set_cc_op(s1, CC_OP_ADDB + ot);
1529         break;
1530     case OP_SUBL:
1531         if (s1->prefix & PREFIX_LOCK) {
1532             tcg_gen_neg_tl(s1->T0, s1->T1);
1533             tcg_gen_atomic_fetch_add_tl(s1->cc_srcT, s1->A0, s1->T0,
1534                                         s1->mem_index, ot | MO_LE);
1535             tcg_gen_sub_tl(s1->T0, s1->cc_srcT, s1->T1);
1536         } else {
1537             tcg_gen_mov_tl(s1->cc_srcT, s1->T0);
1538             tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1);
1539             gen_op_st_rm_T0_A0(s1, ot, d);
1540         }
1541         gen_op_update2_cc(s1);
1542         set_cc_op(s1, CC_OP_SUBB + ot);
1543         break;
1544     default:
1545     case OP_ANDL:
1546         if (s1->prefix & PREFIX_LOCK) {
1547             tcg_gen_atomic_and_fetch_tl(s1->T0, s1->A0, s1->T1,
1548                                         s1->mem_index, ot | MO_LE);
1549         } else {
1550             tcg_gen_and_tl(s1->T0, s1->T0, s1->T1);
1551             gen_op_st_rm_T0_A0(s1, ot, d);
1552         }
1553         gen_op_update1_cc(s1);
1554         set_cc_op(s1, CC_OP_LOGICB + ot);
1555         break;
1556     case OP_ORL:
1557         if (s1->prefix & PREFIX_LOCK) {
1558             tcg_gen_atomic_or_fetch_tl(s1->T0, s1->A0, s1->T1,
1559                                        s1->mem_index, ot | MO_LE);
1560         } else {
1561             tcg_gen_or_tl(s1->T0, s1->T0, s1->T1);
1562             gen_op_st_rm_T0_A0(s1, ot, d);
1563         }
1564         gen_op_update1_cc(s1);
1565         set_cc_op(s1, CC_OP_LOGICB + ot);
1566         break;
1567     case OP_XORL:
1568         if (s1->prefix & PREFIX_LOCK) {
1569             tcg_gen_atomic_xor_fetch_tl(s1->T0, s1->A0, s1->T1,
1570                                         s1->mem_index, ot | MO_LE);
1571         } else {
1572             tcg_gen_xor_tl(s1->T0, s1->T0, s1->T1);
1573             gen_op_st_rm_T0_A0(s1, ot, d);
1574         }
1575         gen_op_update1_cc(s1);
1576         set_cc_op(s1, CC_OP_LOGICB + ot);
1577         break;
1578     case OP_CMPL:
1579         tcg_gen_mov_tl(cpu_cc_src, s1->T1);
1580         tcg_gen_mov_tl(s1->cc_srcT, s1->T0);
1581         tcg_gen_sub_tl(cpu_cc_dst, s1->T0, s1->T1);
1582         set_cc_op(s1, CC_OP_SUBB + ot);
1583         break;
1584     }
1585 }
1586 
1587 /* if d == OR_TMP0, it means memory operand (address in A0) */
1588 static void gen_inc(DisasContext *s1, MemOp ot, int d, int c)
1589 {
1590     if (s1->prefix & PREFIX_LOCK) {
1591         if (d != OR_TMP0) {
1592             /* Lock prefix when destination is not memory */
1593             gen_illegal_opcode(s1);
1594             return;
1595         }
1596         tcg_gen_movi_tl(s1->T0, c > 0 ? 1 : -1);
1597         tcg_gen_atomic_add_fetch_tl(s1->T0, s1->A0, s1->T0,
1598                                     s1->mem_index, ot | MO_LE);
1599     } else {
1600         if (d != OR_TMP0) {
1601             gen_op_mov_v_reg(s1, ot, s1->T0, d);
1602         } else {
1603             gen_op_ld_v(s1, ot, s1->T0, s1->A0);
1604         }
1605         tcg_gen_addi_tl(s1->T0, s1->T0, (c > 0 ? 1 : -1));
1606         gen_op_st_rm_T0_A0(s1, ot, d);
1607     }
1608 
1609     gen_compute_eflags_c(s1, cpu_cc_src);
1610     tcg_gen_mov_tl(cpu_cc_dst, s1->T0);
1611     set_cc_op(s1, (c > 0 ? CC_OP_INCB : CC_OP_DECB) + ot);
1612 }
1613 
1614 static void gen_shift_flags(DisasContext *s, MemOp ot, TCGv result,
1615                             TCGv shm1, TCGv count, bool is_right)
1616 {
1617     TCGv_i32 z32, s32, oldop;
1618     TCGv z_tl;
1619 
1620     /* Store the results into the CC variables.  If we know that the
1621        variable must be dead, store unconditionally.  Otherwise we'll
1622        need to not disrupt the current contents.  */
1623     z_tl = tcg_const_tl(0);
1624     if (cc_op_live[s->cc_op] & USES_CC_DST) {
1625         tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_dst, count, z_tl,
1626                            result, cpu_cc_dst);
1627     } else {
1628         tcg_gen_mov_tl(cpu_cc_dst, result);
1629     }
1630     if (cc_op_live[s->cc_op] & USES_CC_SRC) {
1631         tcg_gen_movcond_tl(TCG_COND_NE, cpu_cc_src, count, z_tl,
1632                            shm1, cpu_cc_src);
1633     } else {
1634         tcg_gen_mov_tl(cpu_cc_src, shm1);
1635     }
1636     tcg_temp_free(z_tl);
1637 
1638     /* Get the two potential CC_OP values into temporaries.  */
1639     tcg_gen_movi_i32(s->tmp2_i32, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1640     if (s->cc_op == CC_OP_DYNAMIC) {
1641         oldop = cpu_cc_op;
1642     } else {
1643         tcg_gen_movi_i32(s->tmp3_i32, s->cc_op);
1644         oldop = s->tmp3_i32;
1645     }
1646 
1647     /* Conditionally store the CC_OP value.  */
1648     z32 = tcg_const_i32(0);
1649     s32 = tcg_temp_new_i32();
1650     tcg_gen_trunc_tl_i32(s32, count);
1651     tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, s32, z32, s->tmp2_i32, oldop);
1652     tcg_temp_free_i32(z32);
1653     tcg_temp_free_i32(s32);
1654 
1655     /* The CC_OP value is no longer predictable.  */
1656     set_cc_op(s, CC_OP_DYNAMIC);
1657 }
1658 
1659 static void gen_shift_rm_T1(DisasContext *s, MemOp ot, int op1,
1660                             int is_right, int is_arith)
1661 {
1662     target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1663 
1664     /* load */
1665     if (op1 == OR_TMP0) {
1666         gen_op_ld_v(s, ot, s->T0, s->A0);
1667     } else {
1668         gen_op_mov_v_reg(s, ot, s->T0, op1);
1669     }
1670 
1671     tcg_gen_andi_tl(s->T1, s->T1, mask);
1672     tcg_gen_subi_tl(s->tmp0, s->T1, 1);
1673 
1674     if (is_right) {
1675         if (is_arith) {
1676             gen_exts(ot, s->T0);
1677             tcg_gen_sar_tl(s->tmp0, s->T0, s->tmp0);
1678             tcg_gen_sar_tl(s->T0, s->T0, s->T1);
1679         } else {
1680             gen_extu(ot, s->T0);
1681             tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0);
1682             tcg_gen_shr_tl(s->T0, s->T0, s->T1);
1683         }
1684     } else {
1685         tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0);
1686         tcg_gen_shl_tl(s->T0, s->T0, s->T1);
1687     }
1688 
1689     /* store */
1690     gen_op_st_rm_T0_A0(s, ot, op1);
1691 
1692     gen_shift_flags(s, ot, s->T0, s->tmp0, s->T1, is_right);
1693 }
1694 
1695 static void gen_shift_rm_im(DisasContext *s, MemOp ot, int op1, int op2,
1696                             int is_right, int is_arith)
1697 {
1698     int mask = (ot == MO_64 ? 0x3f : 0x1f);
1699 
1700     /* load */
1701     if (op1 == OR_TMP0)
1702         gen_op_ld_v(s, ot, s->T0, s->A0);
1703     else
1704         gen_op_mov_v_reg(s, ot, s->T0, op1);
1705 
1706     op2 &= mask;
1707     if (op2 != 0) {
1708         if (is_right) {
1709             if (is_arith) {
1710                 gen_exts(ot, s->T0);
1711                 tcg_gen_sari_tl(s->tmp4, s->T0, op2 - 1);
1712                 tcg_gen_sari_tl(s->T0, s->T0, op2);
1713             } else {
1714                 gen_extu(ot, s->T0);
1715                 tcg_gen_shri_tl(s->tmp4, s->T0, op2 - 1);
1716                 tcg_gen_shri_tl(s->T0, s->T0, op2);
1717             }
1718         } else {
1719             tcg_gen_shli_tl(s->tmp4, s->T0, op2 - 1);
1720             tcg_gen_shli_tl(s->T0, s->T0, op2);
1721         }
1722     }
1723 
1724     /* store */
1725     gen_op_st_rm_T0_A0(s, ot, op1);
1726 
1727     /* update eflags if non zero shift */
1728     if (op2 != 0) {
1729         tcg_gen_mov_tl(cpu_cc_src, s->tmp4);
1730         tcg_gen_mov_tl(cpu_cc_dst, s->T0);
1731         set_cc_op(s, (is_right ? CC_OP_SARB : CC_OP_SHLB) + ot);
1732     }
1733 }
1734 
1735 static void gen_rot_rm_T1(DisasContext *s, MemOp ot, int op1, int is_right)
1736 {
1737     target_ulong mask = (ot == MO_64 ? 0x3f : 0x1f);
1738     TCGv_i32 t0, t1;
1739 
1740     /* load */
1741     if (op1 == OR_TMP0) {
1742         gen_op_ld_v(s, ot, s->T0, s->A0);
1743     } else {
1744         gen_op_mov_v_reg(s, ot, s->T0, op1);
1745     }
1746 
1747     tcg_gen_andi_tl(s->T1, s->T1, mask);
1748 
1749     switch (ot) {
1750     case MO_8:
1751         /* Replicate the 8-bit input so that a 32-bit rotate works.  */
1752         tcg_gen_ext8u_tl(s->T0, s->T0);
1753         tcg_gen_muli_tl(s->T0, s->T0, 0x01010101);
1754         goto do_long;
1755     case MO_16:
1756         /* Replicate the 16-bit input so that a 32-bit rotate works.  */
1757         tcg_gen_deposit_tl(s->T0, s->T0, s->T0, 16, 16);
1758         goto do_long;
1759     do_long:
1760 #ifdef TARGET_X86_64
1761     case MO_32:
1762         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
1763         tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
1764         if (is_right) {
1765             tcg_gen_rotr_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
1766         } else {
1767             tcg_gen_rotl_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
1768         }
1769         tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
1770         break;
1771 #endif
1772     default:
1773         if (is_right) {
1774             tcg_gen_rotr_tl(s->T0, s->T0, s->T1);
1775         } else {
1776             tcg_gen_rotl_tl(s->T0, s->T0, s->T1);
1777         }
1778         break;
1779     }
1780 
1781     /* store */
1782     gen_op_st_rm_T0_A0(s, ot, op1);
1783 
1784     /* We'll need the flags computed into CC_SRC.  */
1785     gen_compute_eflags(s);
1786 
1787     /* The value that was "rotated out" is now present at the other end
1788        of the word.  Compute C into CC_DST and O into CC_SRC2.  Note that
1789        since we've computed the flags into CC_SRC, these variables are
1790        currently dead.  */
1791     if (is_right) {
1792         tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask - 1);
1793         tcg_gen_shri_tl(cpu_cc_dst, s->T0, mask);
1794         tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1795     } else {
1796         tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask);
1797         tcg_gen_andi_tl(cpu_cc_dst, s->T0, 1);
1798     }
1799     tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1800     tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1801 
1802     /* Now conditionally store the new CC_OP value.  If the shift count
1803        is 0 we keep the CC_OP_EFLAGS setting so that only CC_SRC is live.
1804        Otherwise reuse CC_OP_ADCOX which have the C and O flags split out
1805        exactly as we computed above.  */
1806     t0 = tcg_const_i32(0);
1807     t1 = tcg_temp_new_i32();
1808     tcg_gen_trunc_tl_i32(t1, s->T1);
1809     tcg_gen_movi_i32(s->tmp2_i32, CC_OP_ADCOX);
1810     tcg_gen_movi_i32(s->tmp3_i32, CC_OP_EFLAGS);
1811     tcg_gen_movcond_i32(TCG_COND_NE, cpu_cc_op, t1, t0,
1812                         s->tmp2_i32, s->tmp3_i32);
1813     tcg_temp_free_i32(t0);
1814     tcg_temp_free_i32(t1);
1815 
1816     /* The CC_OP value is no longer predictable.  */
1817     set_cc_op(s, CC_OP_DYNAMIC);
1818 }
1819 
1820 static void gen_rot_rm_im(DisasContext *s, MemOp ot, int op1, int op2,
1821                           int is_right)
1822 {
1823     int mask = (ot == MO_64 ? 0x3f : 0x1f);
1824     int shift;
1825 
1826     /* load */
1827     if (op1 == OR_TMP0) {
1828         gen_op_ld_v(s, ot, s->T0, s->A0);
1829     } else {
1830         gen_op_mov_v_reg(s, ot, s->T0, op1);
1831     }
1832 
1833     op2 &= mask;
1834     if (op2 != 0) {
1835         switch (ot) {
1836 #ifdef TARGET_X86_64
1837         case MO_32:
1838             tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
1839             if (is_right) {
1840                 tcg_gen_rotri_i32(s->tmp2_i32, s->tmp2_i32, op2);
1841             } else {
1842                 tcg_gen_rotli_i32(s->tmp2_i32, s->tmp2_i32, op2);
1843             }
1844             tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
1845             break;
1846 #endif
1847         default:
1848             if (is_right) {
1849                 tcg_gen_rotri_tl(s->T0, s->T0, op2);
1850             } else {
1851                 tcg_gen_rotli_tl(s->T0, s->T0, op2);
1852             }
1853             break;
1854         case MO_8:
1855             mask = 7;
1856             goto do_shifts;
1857         case MO_16:
1858             mask = 15;
1859         do_shifts:
1860             shift = op2 & mask;
1861             if (is_right) {
1862                 shift = mask + 1 - shift;
1863             }
1864             gen_extu(ot, s->T0);
1865             tcg_gen_shli_tl(s->tmp0, s->T0, shift);
1866             tcg_gen_shri_tl(s->T0, s->T0, mask + 1 - shift);
1867             tcg_gen_or_tl(s->T0, s->T0, s->tmp0);
1868             break;
1869         }
1870     }
1871 
1872     /* store */
1873     gen_op_st_rm_T0_A0(s, ot, op1);
1874 
1875     if (op2 != 0) {
1876         /* Compute the flags into CC_SRC.  */
1877         gen_compute_eflags(s);
1878 
1879         /* The value that was "rotated out" is now present at the other end
1880            of the word.  Compute C into CC_DST and O into CC_SRC2.  Note that
1881            since we've computed the flags into CC_SRC, these variables are
1882            currently dead.  */
1883         if (is_right) {
1884             tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask - 1);
1885             tcg_gen_shri_tl(cpu_cc_dst, s->T0, mask);
1886             tcg_gen_andi_tl(cpu_cc_dst, cpu_cc_dst, 1);
1887         } else {
1888             tcg_gen_shri_tl(cpu_cc_src2, s->T0, mask);
1889             tcg_gen_andi_tl(cpu_cc_dst, s->T0, 1);
1890         }
1891         tcg_gen_andi_tl(cpu_cc_src2, cpu_cc_src2, 1);
1892         tcg_gen_xor_tl(cpu_cc_src2, cpu_cc_src2, cpu_cc_dst);
1893         set_cc_op(s, CC_OP_ADCOX);
1894     }
1895 }
1896 
1897 /* XXX: add faster immediate = 1 case */
1898 static void gen_rotc_rm_T1(DisasContext *s, MemOp ot, int op1,
1899                            int is_right)
1900 {
1901     gen_compute_eflags(s);
1902     assert(s->cc_op == CC_OP_EFLAGS);
1903 
1904     /* load */
1905     if (op1 == OR_TMP0)
1906         gen_op_ld_v(s, ot, s->T0, s->A0);
1907     else
1908         gen_op_mov_v_reg(s, ot, s->T0, op1);
1909 
1910     if (is_right) {
1911         switch (ot) {
1912         case MO_8:
1913             gen_helper_rcrb(s->T0, cpu_env, s->T0, s->T1);
1914             break;
1915         case MO_16:
1916             gen_helper_rcrw(s->T0, cpu_env, s->T0, s->T1);
1917             break;
1918         case MO_32:
1919             gen_helper_rcrl(s->T0, cpu_env, s->T0, s->T1);
1920             break;
1921 #ifdef TARGET_X86_64
1922         case MO_64:
1923             gen_helper_rcrq(s->T0, cpu_env, s->T0, s->T1);
1924             break;
1925 #endif
1926         default:
1927             tcg_abort();
1928         }
1929     } else {
1930         switch (ot) {
1931         case MO_8:
1932             gen_helper_rclb(s->T0, cpu_env, s->T0, s->T1);
1933             break;
1934         case MO_16:
1935             gen_helper_rclw(s->T0, cpu_env, s->T0, s->T1);
1936             break;
1937         case MO_32:
1938             gen_helper_rcll(s->T0, cpu_env, s->T0, s->T1);
1939             break;
1940 #ifdef TARGET_X86_64
1941         case MO_64:
1942             gen_helper_rclq(s->T0, cpu_env, s->T0, s->T1);
1943             break;
1944 #endif
1945         default:
1946             tcg_abort();
1947         }
1948     }
1949     /* store */
1950     gen_op_st_rm_T0_A0(s, ot, op1);
1951 }
1952 
1953 /* XXX: add faster immediate case */
1954 static void gen_shiftd_rm_T1(DisasContext *s, MemOp ot, int op1,
1955                              bool is_right, TCGv count_in)
1956 {
1957     target_ulong mask = (ot == MO_64 ? 63 : 31);
1958     TCGv count;
1959 
1960     /* load */
1961     if (op1 == OR_TMP0) {
1962         gen_op_ld_v(s, ot, s->T0, s->A0);
1963     } else {
1964         gen_op_mov_v_reg(s, ot, s->T0, op1);
1965     }
1966 
1967     count = tcg_temp_new();
1968     tcg_gen_andi_tl(count, count_in, mask);
1969 
1970     switch (ot) {
1971     case MO_16:
1972         /* Note: we implement the Intel behaviour for shift count > 16.
1973            This means "shrdw C, B, A" shifts A:B:A >> C.  Build the B:A
1974            portion by constructing it as a 32-bit value.  */
1975         if (is_right) {
1976             tcg_gen_deposit_tl(s->tmp0, s->T0, s->T1, 16, 16);
1977             tcg_gen_mov_tl(s->T1, s->T0);
1978             tcg_gen_mov_tl(s->T0, s->tmp0);
1979         } else {
1980             tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 16, 16);
1981         }
1982         /*
1983          * If TARGET_X86_64 defined then fall through into MO_32 case,
1984          * otherwise fall through default case.
1985          */
1986     case MO_32:
1987 #ifdef TARGET_X86_64
1988         /* Concatenate the two 32-bit values and use a 64-bit shift.  */
1989         tcg_gen_subi_tl(s->tmp0, count, 1);
1990         if (is_right) {
1991             tcg_gen_concat_tl_i64(s->T0, s->T0, s->T1);
1992             tcg_gen_shr_i64(s->tmp0, s->T0, s->tmp0);
1993             tcg_gen_shr_i64(s->T0, s->T0, count);
1994         } else {
1995             tcg_gen_concat_tl_i64(s->T0, s->T1, s->T0);
1996             tcg_gen_shl_i64(s->tmp0, s->T0, s->tmp0);
1997             tcg_gen_shl_i64(s->T0, s->T0, count);
1998             tcg_gen_shri_i64(s->tmp0, s->tmp0, 32);
1999             tcg_gen_shri_i64(s->T0, s->T0, 32);
2000         }
2001         break;
2002 #endif
2003     default:
2004         tcg_gen_subi_tl(s->tmp0, count, 1);
2005         if (is_right) {
2006             tcg_gen_shr_tl(s->tmp0, s->T0, s->tmp0);
2007 
2008             tcg_gen_subfi_tl(s->tmp4, mask + 1, count);
2009             tcg_gen_shr_tl(s->T0, s->T0, count);
2010             tcg_gen_shl_tl(s->T1, s->T1, s->tmp4);
2011         } else {
2012             tcg_gen_shl_tl(s->tmp0, s->T0, s->tmp0);
2013             if (ot == MO_16) {
2014                 /* Only needed if count > 16, for Intel behaviour.  */
2015                 tcg_gen_subfi_tl(s->tmp4, 33, count);
2016                 tcg_gen_shr_tl(s->tmp4, s->T1, s->tmp4);
2017                 tcg_gen_or_tl(s->tmp0, s->tmp0, s->tmp4);
2018             }
2019 
2020             tcg_gen_subfi_tl(s->tmp4, mask + 1, count);
2021             tcg_gen_shl_tl(s->T0, s->T0, count);
2022             tcg_gen_shr_tl(s->T1, s->T1, s->tmp4);
2023         }
2024         tcg_gen_movi_tl(s->tmp4, 0);
2025         tcg_gen_movcond_tl(TCG_COND_EQ, s->T1, count, s->tmp4,
2026                            s->tmp4, s->T1);
2027         tcg_gen_or_tl(s->T0, s->T0, s->T1);
2028         break;
2029     }
2030 
2031     /* store */
2032     gen_op_st_rm_T0_A0(s, ot, op1);
2033 
2034     gen_shift_flags(s, ot, s->T0, s->tmp0, count, is_right);
2035     tcg_temp_free(count);
2036 }
2037 
2038 static void gen_shift(DisasContext *s1, int op, MemOp ot, int d, int s)
2039 {
2040     if (s != OR_TMP1)
2041         gen_op_mov_v_reg(s1, ot, s1->T1, s);
2042     switch(op) {
2043     case OP_ROL:
2044         gen_rot_rm_T1(s1, ot, d, 0);
2045         break;
2046     case OP_ROR:
2047         gen_rot_rm_T1(s1, ot, d, 1);
2048         break;
2049     case OP_SHL:
2050     case OP_SHL1:
2051         gen_shift_rm_T1(s1, ot, d, 0, 0);
2052         break;
2053     case OP_SHR:
2054         gen_shift_rm_T1(s1, ot, d, 1, 0);
2055         break;
2056     case OP_SAR:
2057         gen_shift_rm_T1(s1, ot, d, 1, 1);
2058         break;
2059     case OP_RCL:
2060         gen_rotc_rm_T1(s1, ot, d, 0);
2061         break;
2062     case OP_RCR:
2063         gen_rotc_rm_T1(s1, ot, d, 1);
2064         break;
2065     }
2066 }
2067 
2068 static void gen_shifti(DisasContext *s1, int op, MemOp ot, int d, int c)
2069 {
2070     switch(op) {
2071     case OP_ROL:
2072         gen_rot_rm_im(s1, ot, d, c, 0);
2073         break;
2074     case OP_ROR:
2075         gen_rot_rm_im(s1, ot, d, c, 1);
2076         break;
2077     case OP_SHL:
2078     case OP_SHL1:
2079         gen_shift_rm_im(s1, ot, d, c, 0, 0);
2080         break;
2081     case OP_SHR:
2082         gen_shift_rm_im(s1, ot, d, c, 1, 0);
2083         break;
2084     case OP_SAR:
2085         gen_shift_rm_im(s1, ot, d, c, 1, 1);
2086         break;
2087     default:
2088         /* currently not optimized */
2089         tcg_gen_movi_tl(s1->T1, c);
2090         gen_shift(s1, op, ot, d, OR_TMP1);
2091         break;
2092     }
2093 }
2094 
2095 #define X86_MAX_INSN_LENGTH 15
2096 
2097 static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
2098 {
2099     uint64_t pc = s->pc;
2100 
2101     /* This is a subsequent insn that crosses a page boundary.  */
2102     if (s->base.num_insns > 1 &&
2103         !is_same_page(&s->base, s->pc + num_bytes - 1)) {
2104         siglongjmp(s->jmpbuf, 2);
2105     }
2106 
2107     s->pc += num_bytes;
2108     if (unlikely(cur_insn_len(s) > X86_MAX_INSN_LENGTH)) {
2109         /* If the instruction's 16th byte is on a different page than the 1st, a
2110          * page fault on the second page wins over the general protection fault
2111          * caused by the instruction being too long.
2112          * This can happen even if the operand is only one byte long!
2113          */
2114         if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) {
2115             volatile uint8_t unused =
2116                 cpu_ldub_code(env, (s->pc - 1) & TARGET_PAGE_MASK);
2117             (void) unused;
2118         }
2119         siglongjmp(s->jmpbuf, 1);
2120     }
2121 
2122     return pc;
2123 }
2124 
2125 static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
2126 {
2127     return translator_ldub(env, &s->base, advance_pc(env, s, 1));
2128 }
2129 
2130 static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s)
2131 {
2132     return translator_lduw(env, &s->base, advance_pc(env, s, 2));
2133 }
2134 
2135 static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
2136 {
2137     return translator_lduw(env, &s->base, advance_pc(env, s, 2));
2138 }
2139 
2140 static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s)
2141 {
2142     return translator_ldl(env, &s->base, advance_pc(env, s, 4));
2143 }
2144 
2145 #ifdef TARGET_X86_64
2146 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s)
2147 {
2148     return translator_ldq(env, &s->base, advance_pc(env, s, 8));
2149 }
2150 #endif
2151 
2152 /* Decompose an address.  */
2153 
2154 typedef struct AddressParts {
2155     int def_seg;
2156     int base;
2157     int index;
2158     int scale;
2159     target_long disp;
2160 } AddressParts;
2161 
2162 static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
2163                                     int modrm)
2164 {
2165     int def_seg, base, index, scale, mod, rm;
2166     target_long disp;
2167     bool havesib;
2168 
2169     def_seg = R_DS;
2170     index = -1;
2171     scale = 0;
2172     disp = 0;
2173 
2174     mod = (modrm >> 6) & 3;
2175     rm = modrm & 7;
2176     base = rm | REX_B(s);
2177 
2178     if (mod == 3) {
2179         /* Normally filtered out earlier, but including this path
2180            simplifies multi-byte nop, as well as bndcl, bndcu, bndcn.  */
2181         goto done;
2182     }
2183 
2184     switch (s->aflag) {
2185     case MO_64:
2186     case MO_32:
2187         havesib = 0;
2188         if (rm == 4) {
2189             int code = x86_ldub_code(env, s);
2190             scale = (code >> 6) & 3;
2191             index = ((code >> 3) & 7) | REX_X(s);
2192             if (index == 4) {
2193                 index = -1;  /* no index */
2194             }
2195             base = (code & 7) | REX_B(s);
2196             havesib = 1;
2197         }
2198 
2199         switch (mod) {
2200         case 0:
2201             if ((base & 7) == 5) {
2202                 base = -1;
2203                 disp = (int32_t)x86_ldl_code(env, s);
2204                 if (CODE64(s) && !havesib) {
2205                     base = -2;
2206                     disp += s->pc + s->rip_offset;
2207                 }
2208             }
2209             break;
2210         case 1:
2211             disp = (int8_t)x86_ldub_code(env, s);
2212             break;
2213         default:
2214         case 2:
2215             disp = (int32_t)x86_ldl_code(env, s);
2216             break;
2217         }
2218 
2219         /* For correct popl handling with esp.  */
2220         if (base == R_ESP && s->popl_esp_hack) {
2221             disp += s->popl_esp_hack;
2222         }
2223         if (base == R_EBP || base == R_ESP) {
2224             def_seg = R_SS;
2225         }
2226         break;
2227 
2228     case MO_16:
2229         if (mod == 0) {
2230             if (rm == 6) {
2231                 base = -1;
2232                 disp = x86_lduw_code(env, s);
2233                 break;
2234             }
2235         } else if (mod == 1) {
2236             disp = (int8_t)x86_ldub_code(env, s);
2237         } else {
2238             disp = (int16_t)x86_lduw_code(env, s);
2239         }
2240 
2241         switch (rm) {
2242         case 0:
2243             base = R_EBX;
2244             index = R_ESI;
2245             break;
2246         case 1:
2247             base = R_EBX;
2248             index = R_EDI;
2249             break;
2250         case 2:
2251             base = R_EBP;
2252             index = R_ESI;
2253             def_seg = R_SS;
2254             break;
2255         case 3:
2256             base = R_EBP;
2257             index = R_EDI;
2258             def_seg = R_SS;
2259             break;
2260         case 4:
2261             base = R_ESI;
2262             break;
2263         case 5:
2264             base = R_EDI;
2265             break;
2266         case 6:
2267             base = R_EBP;
2268             def_seg = R_SS;
2269             break;
2270         default:
2271         case 7:
2272             base = R_EBX;
2273             break;
2274         }
2275         break;
2276 
2277     default:
2278         tcg_abort();
2279     }
2280 
2281  done:
2282     return (AddressParts){ def_seg, base, index, scale, disp };
2283 }
2284 
2285 /* Compute the address, with a minimum number of TCG ops.  */
2286 static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib)
2287 {
2288     TCGv ea = NULL;
2289 
2290     if (a.index >= 0 && !is_vsib) {
2291         if (a.scale == 0) {
2292             ea = cpu_regs[a.index];
2293         } else {
2294             tcg_gen_shli_tl(s->A0, cpu_regs[a.index], a.scale);
2295             ea = s->A0;
2296         }
2297         if (a.base >= 0) {
2298             tcg_gen_add_tl(s->A0, ea, cpu_regs[a.base]);
2299             ea = s->A0;
2300         }
2301     } else if (a.base >= 0) {
2302         ea = cpu_regs[a.base];
2303     }
2304     if (!ea) {
2305         if (TARGET_TB_PCREL && a.base == -2) {
2306             /* With cpu_eip ~= pc_save, the expression is pc-relative. */
2307             tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save);
2308         } else {
2309             tcg_gen_movi_tl(s->A0, a.disp);
2310         }
2311         ea = s->A0;
2312     } else if (a.disp != 0) {
2313         tcg_gen_addi_tl(s->A0, ea, a.disp);
2314         ea = s->A0;
2315     }
2316 
2317     return ea;
2318 }
2319 
2320 static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
2321 {
2322     AddressParts a = gen_lea_modrm_0(env, s, modrm);
2323     TCGv ea = gen_lea_modrm_1(s, a, false);
2324     gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
2325 }
2326 
2327 static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
2328 {
2329     (void)gen_lea_modrm_0(env, s, modrm);
2330 }
2331 
2332 /* Used for BNDCL, BNDCU, BNDCN.  */
2333 static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm,
2334                       TCGCond cond, TCGv_i64 bndv)
2335 {
2336     AddressParts a = gen_lea_modrm_0(env, s, modrm);
2337     TCGv ea = gen_lea_modrm_1(s, a, false);
2338 
2339     tcg_gen_extu_tl_i64(s->tmp1_i64, ea);
2340     if (!CODE64(s)) {
2341         tcg_gen_ext32u_i64(s->tmp1_i64, s->tmp1_i64);
2342     }
2343     tcg_gen_setcond_i64(cond, s->tmp1_i64, s->tmp1_i64, bndv);
2344     tcg_gen_extrl_i64_i32(s->tmp2_i32, s->tmp1_i64);
2345     gen_helper_bndck(cpu_env, s->tmp2_i32);
2346 }
2347 
2348 /* used for LEA and MOV AX, mem */
2349 static void gen_add_A0_ds_seg(DisasContext *s)
2350 {
2351     gen_lea_v_seg(s, s->aflag, s->A0, R_DS, s->override);
2352 }
2353 
2354 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg ==
2355    OR_TMP0 */
2356 static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
2357                            MemOp ot, int reg, int is_store)
2358 {
2359     int mod, rm;
2360 
2361     mod = (modrm >> 6) & 3;
2362     rm = (modrm & 7) | REX_B(s);
2363     if (mod == 3) {
2364         if (is_store) {
2365             if (reg != OR_TMP0)
2366                 gen_op_mov_v_reg(s, ot, s->T0, reg);
2367             gen_op_mov_reg_v(s, ot, rm, s->T0);
2368         } else {
2369             gen_op_mov_v_reg(s, ot, s->T0, rm);
2370             if (reg != OR_TMP0)
2371                 gen_op_mov_reg_v(s, ot, reg, s->T0);
2372         }
2373     } else {
2374         gen_lea_modrm(env, s, modrm);
2375         if (is_store) {
2376             if (reg != OR_TMP0)
2377                 gen_op_mov_v_reg(s, ot, s->T0, reg);
2378             gen_op_st_v(s, ot, s->T0, s->A0);
2379         } else {
2380             gen_op_ld_v(s, ot, s->T0, s->A0);
2381             if (reg != OR_TMP0)
2382                 gen_op_mov_reg_v(s, ot, reg, s->T0);
2383         }
2384     }
2385 }
2386 
2387 static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot)
2388 {
2389     target_ulong ret;
2390 
2391     switch (ot) {
2392     case MO_8:
2393         ret = x86_ldub_code(env, s);
2394         break;
2395     case MO_16:
2396         ret = x86_lduw_code(env, s);
2397         break;
2398     case MO_32:
2399         ret = x86_ldl_code(env, s);
2400         break;
2401 #ifdef TARGET_X86_64
2402     case MO_64:
2403         ret = x86_ldq_code(env, s);
2404         break;
2405 #endif
2406     default:
2407         g_assert_not_reached();
2408     }
2409     return ret;
2410 }
2411 
2412 static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot)
2413 {
2414     uint32_t ret;
2415 
2416     switch (ot) {
2417     case MO_8:
2418         ret = x86_ldub_code(env, s);
2419         break;
2420     case MO_16:
2421         ret = x86_lduw_code(env, s);
2422         break;
2423     case MO_32:
2424 #ifdef TARGET_X86_64
2425     case MO_64:
2426 #endif
2427         ret = x86_ldl_code(env, s);
2428         break;
2429     default:
2430         tcg_abort();
2431     }
2432     return ret;
2433 }
2434 
2435 static target_long insn_get_signed(CPUX86State *env, DisasContext *s, MemOp ot)
2436 {
2437     target_long ret;
2438 
2439     switch (ot) {
2440     case MO_8:
2441         ret = (int8_t) x86_ldub_code(env, s);
2442         break;
2443     case MO_16:
2444         ret = (int16_t) x86_lduw_code(env, s);
2445         break;
2446     case MO_32:
2447         ret = (int32_t) x86_ldl_code(env, s);
2448         break;
2449 #ifdef TARGET_X86_64
2450     case MO_64:
2451         ret = x86_ldq_code(env, s);
2452         break;
2453 #endif
2454     default:
2455         g_assert_not_reached();
2456     }
2457     return ret;
2458 }
2459 
2460 static inline int insn_const_size(MemOp ot)
2461 {
2462     if (ot <= MO_32) {
2463         return 1 << ot;
2464     } else {
2465         return 4;
2466     }
2467 }
2468 
2469 static void gen_jcc(DisasContext *s, int b, int diff)
2470 {
2471     TCGLabel *l1 = gen_new_label();
2472 
2473     gen_jcc1(s, b, l1);
2474     gen_jmp_rel_csize(s, 0, 1);
2475     gen_set_label(l1);
2476     gen_jmp_rel(s, s->dflag, diff, 0);
2477 }
2478 
2479 static void gen_cmovcc1(CPUX86State *env, DisasContext *s, MemOp ot, int b,
2480                         int modrm, int reg)
2481 {
2482     CCPrepare cc;
2483 
2484     gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
2485 
2486     cc = gen_prepare_cc(s, b, s->T1);
2487     if (cc.mask != -1) {
2488         TCGv t0 = tcg_temp_new();
2489         tcg_gen_andi_tl(t0, cc.reg, cc.mask);
2490         cc.reg = t0;
2491     }
2492     if (!cc.use_reg2) {
2493         cc.reg2 = tcg_const_tl(cc.imm);
2494     }
2495 
2496     tcg_gen_movcond_tl(cc.cond, s->T0, cc.reg, cc.reg2,
2497                        s->T0, cpu_regs[reg]);
2498     gen_op_mov_reg_v(s, ot, reg, s->T0);
2499 
2500     if (cc.mask != -1) {
2501         tcg_temp_free(cc.reg);
2502     }
2503     if (!cc.use_reg2) {
2504         tcg_temp_free(cc.reg2);
2505     }
2506 }
2507 
2508 static inline void gen_op_movl_T0_seg(DisasContext *s, X86Seg seg_reg)
2509 {
2510     tcg_gen_ld32u_tl(s->T0, cpu_env,
2511                      offsetof(CPUX86State,segs[seg_reg].selector));
2512 }
2513 
2514 static inline void gen_op_movl_seg_T0_vm(DisasContext *s, X86Seg seg_reg)
2515 {
2516     tcg_gen_ext16u_tl(s->T0, s->T0);
2517     tcg_gen_st32_tl(s->T0, cpu_env,
2518                     offsetof(CPUX86State,segs[seg_reg].selector));
2519     tcg_gen_shli_tl(cpu_seg_base[seg_reg], s->T0, 4);
2520 }
2521 
2522 /* move T0 to seg_reg and compute if the CPU state may change. Never
2523    call this function with seg_reg == R_CS */
2524 static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg)
2525 {
2526     if (PE(s) && !VM86(s)) {
2527         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
2528         gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), s->tmp2_i32);
2529         /* abort translation because the addseg value may change or
2530            because ss32 may change. For R_SS, translation must always
2531            stop as a special handling must be done to disable hardware
2532            interrupts for the next instruction */
2533         if (seg_reg == R_SS) {
2534             s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
2535         } else if (CODE32(s) && seg_reg < R_FS) {
2536             s->base.is_jmp = DISAS_EOB_NEXT;
2537         }
2538     } else {
2539         gen_op_movl_seg_T0_vm(s, seg_reg);
2540         if (seg_reg == R_SS) {
2541             s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
2542         }
2543     }
2544 }
2545 
2546 static void gen_svm_check_intercept(DisasContext *s, uint32_t type)
2547 {
2548     /* no SVM activated; fast case */
2549     if (likely(!GUEST(s))) {
2550         return;
2551     }
2552     gen_helper_svm_check_intercept(cpu_env, tcg_constant_i32(type));
2553 }
2554 
2555 static inline void gen_stack_update(DisasContext *s, int addend)
2556 {
2557     gen_op_add_reg_im(s, mo_stacksize(s), R_ESP, addend);
2558 }
2559 
2560 /* Generate a push. It depends on ss32, addseg and dflag.  */
2561 static void gen_push_v(DisasContext *s, TCGv val)
2562 {
2563     MemOp d_ot = mo_pushpop(s, s->dflag);
2564     MemOp a_ot = mo_stacksize(s);
2565     int size = 1 << d_ot;
2566     TCGv new_esp = s->A0;
2567 
2568     tcg_gen_subi_tl(s->A0, cpu_regs[R_ESP], size);
2569 
2570     if (!CODE64(s)) {
2571         if (ADDSEG(s)) {
2572             new_esp = s->tmp4;
2573             tcg_gen_mov_tl(new_esp, s->A0);
2574         }
2575         gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2576     }
2577 
2578     gen_op_st_v(s, d_ot, val, s->A0);
2579     gen_op_mov_reg_v(s, a_ot, R_ESP, new_esp);
2580 }
2581 
2582 /* two step pop is necessary for precise exceptions */
2583 static MemOp gen_pop_T0(DisasContext *s)
2584 {
2585     MemOp d_ot = mo_pushpop(s, s->dflag);
2586 
2587     gen_lea_v_seg(s, mo_stacksize(s), cpu_regs[R_ESP], R_SS, -1);
2588     gen_op_ld_v(s, d_ot, s->T0, s->A0);
2589 
2590     return d_ot;
2591 }
2592 
2593 static inline void gen_pop_update(DisasContext *s, MemOp ot)
2594 {
2595     gen_stack_update(s, 1 << ot);
2596 }
2597 
2598 static inline void gen_stack_A0(DisasContext *s)
2599 {
2600     gen_lea_v_seg(s, SS32(s) ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
2601 }
2602 
2603 static void gen_pusha(DisasContext *s)
2604 {
2605     MemOp s_ot = SS32(s) ? MO_32 : MO_16;
2606     MemOp d_ot = s->dflag;
2607     int size = 1 << d_ot;
2608     int i;
2609 
2610     for (i = 0; i < 8; i++) {
2611         tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], (i - 8) * size);
2612         gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1);
2613         gen_op_st_v(s, d_ot, cpu_regs[7 - i], s->A0);
2614     }
2615 
2616     gen_stack_update(s, -8 * size);
2617 }
2618 
2619 static void gen_popa(DisasContext *s)
2620 {
2621     MemOp s_ot = SS32(s) ? MO_32 : MO_16;
2622     MemOp d_ot = s->dflag;
2623     int size = 1 << d_ot;
2624     int i;
2625 
2626     for (i = 0; i < 8; i++) {
2627         /* ESP is not reloaded */
2628         if (7 - i == R_ESP) {
2629             continue;
2630         }
2631         tcg_gen_addi_tl(s->A0, cpu_regs[R_ESP], i * size);
2632         gen_lea_v_seg(s, s_ot, s->A0, R_SS, -1);
2633         gen_op_ld_v(s, d_ot, s->T0, s->A0);
2634         gen_op_mov_reg_v(s, d_ot, 7 - i, s->T0);
2635     }
2636 
2637     gen_stack_update(s, 8 * size);
2638 }
2639 
2640 static void gen_enter(DisasContext *s, int esp_addend, int level)
2641 {
2642     MemOp d_ot = mo_pushpop(s, s->dflag);
2643     MemOp a_ot = CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16;
2644     int size = 1 << d_ot;
2645 
2646     /* Push BP; compute FrameTemp into T1.  */
2647     tcg_gen_subi_tl(s->T1, cpu_regs[R_ESP], size);
2648     gen_lea_v_seg(s, a_ot, s->T1, R_SS, -1);
2649     gen_op_st_v(s, d_ot, cpu_regs[R_EBP], s->A0);
2650 
2651     level &= 31;
2652     if (level != 0) {
2653         int i;
2654 
2655         /* Copy level-1 pointers from the previous frame.  */
2656         for (i = 1; i < level; ++i) {
2657             tcg_gen_subi_tl(s->A0, cpu_regs[R_EBP], size * i);
2658             gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2659             gen_op_ld_v(s, d_ot, s->tmp0, s->A0);
2660 
2661             tcg_gen_subi_tl(s->A0, s->T1, size * i);
2662             gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2663             gen_op_st_v(s, d_ot, s->tmp0, s->A0);
2664         }
2665 
2666         /* Push the current FrameTemp as the last level.  */
2667         tcg_gen_subi_tl(s->A0, s->T1, size * level);
2668         gen_lea_v_seg(s, a_ot, s->A0, R_SS, -1);
2669         gen_op_st_v(s, d_ot, s->T1, s->A0);
2670     }
2671 
2672     /* Copy the FrameTemp value to EBP.  */
2673     gen_op_mov_reg_v(s, a_ot, R_EBP, s->T1);
2674 
2675     /* Compute the final value of ESP.  */
2676     tcg_gen_subi_tl(s->T1, s->T1, esp_addend + size * level);
2677     gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1);
2678 }
2679 
2680 static void gen_leave(DisasContext *s)
2681 {
2682     MemOp d_ot = mo_pushpop(s, s->dflag);
2683     MemOp a_ot = mo_stacksize(s);
2684 
2685     gen_lea_v_seg(s, a_ot, cpu_regs[R_EBP], R_SS, -1);
2686     gen_op_ld_v(s, d_ot, s->T0, s->A0);
2687 
2688     tcg_gen_addi_tl(s->T1, cpu_regs[R_EBP], 1 << d_ot);
2689 
2690     gen_op_mov_reg_v(s, d_ot, R_EBP, s->T0);
2691     gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1);
2692 }
2693 
2694 /* Similarly, except that the assumption here is that we don't decode
2695    the instruction at all -- either a missing opcode, an unimplemented
2696    feature, or just a bogus instruction stream.  */
2697 static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
2698 {
2699     gen_illegal_opcode(s);
2700 
2701     if (qemu_loglevel_mask(LOG_UNIMP)) {
2702         FILE *logfile = qemu_log_trylock();
2703         if (logfile) {
2704             target_ulong pc = s->base.pc_next, end = s->pc;
2705 
2706             fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc);
2707             for (; pc < end; ++pc) {
2708                 fprintf(logfile, " %02x", cpu_ldub_code(env, pc));
2709             }
2710             fprintf(logfile, "\n");
2711             qemu_log_unlock(logfile);
2712         }
2713     }
2714 }
2715 
2716 /* an interrupt is different from an exception because of the
2717    privilege checks */
2718 static void gen_interrupt(DisasContext *s, int intno)
2719 {
2720     gen_update_cc_op(s);
2721     gen_update_eip_cur(s);
2722     gen_helper_raise_interrupt(cpu_env, tcg_constant_i32(intno),
2723                                cur_insn_len_i32(s));
2724     s->base.is_jmp = DISAS_NORETURN;
2725 }
2726 
2727 static void gen_set_hflag(DisasContext *s, uint32_t mask)
2728 {
2729     if ((s->flags & mask) == 0) {
2730         TCGv_i32 t = tcg_temp_new_i32();
2731         tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2732         tcg_gen_ori_i32(t, t, mask);
2733         tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2734         tcg_temp_free_i32(t);
2735         s->flags |= mask;
2736     }
2737 }
2738 
2739 static void gen_reset_hflag(DisasContext *s, uint32_t mask)
2740 {
2741     if (s->flags & mask) {
2742         TCGv_i32 t = tcg_temp_new_i32();
2743         tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2744         tcg_gen_andi_i32(t, t, ~mask);
2745         tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2746         tcg_temp_free_i32(t);
2747         s->flags &= ~mask;
2748     }
2749 }
2750 
2751 /* Clear BND registers during legacy branches.  */
2752 static void gen_bnd_jmp(DisasContext *s)
2753 {
2754     /* Clear the registers only if BND prefix is missing, MPX is enabled,
2755        and if the BNDREGs are known to be in use (non-zero) already.
2756        The helper itself will check BNDPRESERVE at runtime.  */
2757     if ((s->prefix & PREFIX_REPNZ) == 0
2758         && (s->flags & HF_MPX_EN_MASK) != 0
2759         && (s->flags & HF_MPX_IU_MASK) != 0) {
2760         gen_helper_bnd_jmp(cpu_env);
2761     }
2762 }
2763 
2764 /* Generate an end of block. Trace exception is also generated if needed.
2765    If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2766    If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2767    S->TF.  This is used by the syscall/sysret insns.  */
2768 static void
2769 do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
2770 {
2771     gen_update_cc_op(s);
2772 
2773     /* If several instructions disable interrupts, only the first does it.  */
2774     if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
2775         gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
2776     } else {
2777         gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
2778     }
2779 
2780     if (s->base.tb->flags & HF_RF_MASK) {
2781         gen_helper_reset_rf(cpu_env);
2782     }
2783     if (recheck_tf) {
2784         gen_helper_rechecking_single_step(cpu_env);
2785         tcg_gen_exit_tb(NULL, 0);
2786     } else if (s->flags & HF_TF_MASK) {
2787         gen_helper_single_step(cpu_env);
2788     } else if (jr) {
2789         tcg_gen_lookup_and_goto_ptr();
2790     } else {
2791         tcg_gen_exit_tb(NULL, 0);
2792     }
2793     s->base.is_jmp = DISAS_NORETURN;
2794 }
2795 
2796 static inline void
2797 gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf)
2798 {
2799     do_gen_eob_worker(s, inhibit, recheck_tf, false);
2800 }
2801 
2802 /* End of block.
2803    If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.  */
2804 static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
2805 {
2806     gen_eob_worker(s, inhibit, false);
2807 }
2808 
2809 /* End of block, resetting the inhibit irq flag.  */
2810 static void gen_eob(DisasContext *s)
2811 {
2812     gen_eob_worker(s, false, false);
2813 }
2814 
2815 /* Jump to register */
2816 static void gen_jr(DisasContext *s)
2817 {
2818     do_gen_eob_worker(s, false, false, true);
2819 }
2820 
2821 /* Jump to eip+diff, truncating the result to OT. */
2822 static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
2823 {
2824     bool use_goto_tb = s->jmp_opt;
2825     target_ulong mask = -1;
2826     target_ulong new_pc = s->pc + diff;
2827     target_ulong new_eip = new_pc - s->cs_base;
2828 
2829     /* In 64-bit mode, operand size is fixed at 64 bits. */
2830     if (!CODE64(s)) {
2831         if (ot == MO_16) {
2832             mask = 0xffff;
2833             if (TARGET_TB_PCREL && CODE32(s)) {
2834                 use_goto_tb = false;
2835             }
2836         } else {
2837             mask = 0xffffffff;
2838         }
2839     }
2840     new_eip &= mask;
2841 
2842     gen_update_cc_op(s);
2843     set_cc_op(s, CC_OP_DYNAMIC);
2844 
2845     if (TARGET_TB_PCREL) {
2846         tcg_gen_addi_tl(cpu_eip, cpu_eip, new_pc - s->pc_save);
2847         /*
2848          * If we can prove the branch does not leave the page and we have
2849          * no extra masking to apply (data16 branch in code32, see above),
2850          * then we have also proven that the addition does not wrap.
2851          */
2852         if (!use_goto_tb || !is_same_page(&s->base, new_pc)) {
2853             tcg_gen_andi_tl(cpu_eip, cpu_eip, mask);
2854             use_goto_tb = false;
2855         }
2856     }
2857 
2858     if (use_goto_tb &&
2859         translator_use_goto_tb(&s->base, new_eip + s->cs_base)) {
2860         /* jump to same page: we can use a direct jump */
2861         tcg_gen_goto_tb(tb_num);
2862         if (!TARGET_TB_PCREL) {
2863             tcg_gen_movi_tl(cpu_eip, new_eip);
2864         }
2865         tcg_gen_exit_tb(s->base.tb, tb_num);
2866         s->base.is_jmp = DISAS_NORETURN;
2867     } else {
2868         if (!TARGET_TB_PCREL) {
2869             tcg_gen_movi_tl(cpu_eip, new_eip);
2870         }
2871         if (s->jmp_opt) {
2872             gen_jr(s);   /* jump to another page */
2873         } else {
2874             gen_eob(s);  /* exit to main loop */
2875         }
2876     }
2877 }
2878 
2879 /* Jump to eip+diff, truncating to the current code size. */
2880 static void gen_jmp_rel_csize(DisasContext *s, int diff, int tb_num)
2881 {
2882     /* CODE64 ignores the OT argument, so we need not consider it. */
2883     gen_jmp_rel(s, CODE32(s) ? MO_32 : MO_16, diff, tb_num);
2884 }
2885 
2886 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2887 {
2888     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
2889     tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset);
2890 }
2891 
2892 static inline void gen_stq_env_A0(DisasContext *s, int offset)
2893 {
2894     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset);
2895     tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
2896 }
2897 
2898 static inline void gen_ldo_env_A0(DisasContext *s, int offset, bool align)
2899 {
2900     int mem_index = s->mem_index;
2901     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index,
2902                         MO_LEUQ | (align ? MO_ALIGN_16 : 0));
2903     tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2904     tcg_gen_addi_tl(s->tmp0, s->A0, 8);
2905     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2906     tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2907 }
2908 
2909 static inline void gen_sto_env_A0(DisasContext *s, int offset, bool align)
2910 {
2911     int mem_index = s->mem_index;
2912     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));
2913     tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index,
2914                         MO_LEUQ | (align ? MO_ALIGN_16 : 0));
2915     tcg_gen_addi_tl(s->tmp0, s->A0, 8);
2916     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));
2917     tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2918 }
2919 
2920 static void gen_ldy_env_A0(DisasContext *s, int offset, bool align)
2921 {
2922     int mem_index = s->mem_index;
2923     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index,
2924                         MO_LEUQ | (align ? MO_ALIGN_32 : 0));
2925     tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(0)));
2926     tcg_gen_addi_tl(s->tmp0, s->A0, 8);
2927     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2928     tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(1)));
2929 
2930     tcg_gen_addi_tl(s->tmp0, s->A0, 16);
2931     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2932     tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(2)));
2933     tcg_gen_addi_tl(s->tmp0, s->A0, 24);
2934     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2935     tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(3)));
2936 }
2937 
2938 static void gen_sty_env_A0(DisasContext *s, int offset, bool align)
2939 {
2940     int mem_index = s->mem_index;
2941     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(0)));
2942     tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index,
2943                         MO_LEUQ | (align ? MO_ALIGN_32 : 0));
2944     tcg_gen_addi_tl(s->tmp0, s->A0, 8);
2945     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(1)));
2946     tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2947     tcg_gen_addi_tl(s->tmp0, s->A0, 16);
2948     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(2)));
2949     tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2950     tcg_gen_addi_tl(s->tmp0, s->A0, 24);
2951     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(YMMReg, YMM_Q(3)));
2952     tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEUQ);
2953 }
2954 
2955 static inline void gen_op_movo(DisasContext *s, int d_offset, int s_offset)
2956 {
2957     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, s_offset + offsetof(XMMReg, XMM_Q(0)));
2958     tcg_gen_st_i64(s->tmp1_i64, cpu_env, d_offset + offsetof(XMMReg, XMM_Q(0)));
2959     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, s_offset + offsetof(XMMReg, XMM_Q(1)));
2960     tcg_gen_st_i64(s->tmp1_i64, cpu_env, d_offset + offsetof(XMMReg, XMM_Q(1)));
2961 }
2962 
2963 static inline void gen_op_movq(DisasContext *s, int d_offset, int s_offset)
2964 {
2965     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, s_offset);
2966     tcg_gen_st_i64(s->tmp1_i64, cpu_env, d_offset);
2967 }
2968 
2969 static inline void gen_op_movl(DisasContext *s, int d_offset, int s_offset)
2970 {
2971     tcg_gen_ld_i32(s->tmp2_i32, cpu_env, s_offset);
2972     tcg_gen_st_i32(s->tmp2_i32, cpu_env, d_offset);
2973 }
2974 
2975 static inline void gen_op_movq_env_0(DisasContext *s, int d_offset)
2976 {
2977     tcg_gen_movi_i64(s->tmp1_i64, 0);
2978     tcg_gen_st_i64(s->tmp1_i64, cpu_env, d_offset);
2979 }
2980 
2981 #define ZMM_OFFSET(reg) offsetof(CPUX86State, xmm_regs[reg])
2982 #define XMM_OFFSET(reg) offsetof(CPUX86State, xmm_regs[reg].ZMM_X(0))
2983 
2984 typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2985 typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2986 typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2987 typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2988 typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2989 typedef void (*SSEFunc_0_eppp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2990                                TCGv_ptr reg_c);
2991 typedef void (*SSEFunc_0_epppp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2992                                 TCGv_ptr reg_c, TCGv_ptr reg_d);
2993 typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2994                                TCGv_i32 val);
2995 typedef void (*SSEFunc_0_epppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2996                                 TCGv_ptr reg_c, TCGv_i32 val);
2997 typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2998 typedef void (*SSEFunc_0_pppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_ptr reg_c,
2999                                TCGv_i32 val);
3000 typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
3001                                TCGv val);
3002 typedef void (*SSEFunc_0_epppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
3003                                 TCGv_ptr reg_c, TCGv val);
3004 
3005 static bool first = true; static unsigned long limit;
3006 #include "decode-new.h"
3007 #include "emit.c.inc"
3008 #include "decode-new.c.inc"
3009 
3010 #define SSE_OPF_V0        (1 << 0) /* vex.v must be 1111b (only 2 operands) */
3011 #define SSE_OPF_CMP       (1 << 1) /* does not write for first operand */
3012 #define SSE_OPF_BLENDV    (1 << 2) /* blendv* instruction */
3013 #define SSE_OPF_SPECIAL   (1 << 3) /* magic */
3014 #define SSE_OPF_3DNOW     (1 << 4) /* 3DNow! instruction */
3015 #define SSE_OPF_MMX       (1 << 5) /* MMX/integer/AVX2 instruction */
3016 #define SSE_OPF_SCALAR    (1 << 6) /* Has SSE scalar variants */
3017 #define SSE_OPF_SHUF      (1 << 9) /* pshufx/shufpx */
3018 
3019 #define OP(op, flags, a, b, c, d)       \
3020     {flags, {{.op = a}, {.op = b}, {.op = c}, {.op = d} } }
3021 
3022 #define MMX_OP(x) OP(op2, SSE_OPF_MMX, \
3023         gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm, NULL, NULL)
3024 
3025 #define SSE_FOP(name) OP(op2, SSE_OPF_SCALAR, \
3026         gen_helper_##name##ps##_xmm, gen_helper_##name##pd##_xmm, \
3027         gen_helper_##name##ss, gen_helper_##name##sd)
3028 #define SSE_OP(sname, dname, op, flags) OP(op, flags, \
3029         gen_helper_##sname##_xmm, gen_helper_##dname##_xmm, NULL, NULL)
3030 
3031 #define SSE_OP_UNARY(a, b, c, d)       \
3032     {SSE_OPF_SCALAR | SSE_OPF_V0, {{.op1 = a}, {.op1 = b}, {.op2 = c}, {.op2 = d} } }
3033 
3034 typedef union SSEFuncs {
3035     SSEFunc_0_epp op1;
3036     SSEFunc_0_ppi op1i;
3037     SSEFunc_0_eppt op1t;
3038     SSEFunc_0_eppp op2;
3039     SSEFunc_0_pppi op2i;
3040     SSEFunc_0_epppp op3;
3041 } SSEFuncs;
3042 
3043 struct SSEOpHelper_table1 {
3044     int flags;
3045     SSEFuncs fn[4];
3046 };
3047 
3048 #define SSE_3DNOW { SSE_OPF_3DNOW }
3049 #define SSE_SPECIAL { SSE_OPF_SPECIAL }
3050 
3051 static const struct SSEOpHelper_table1 sse_op_table1[256] = {
3052     /* 3DNow! extensions */
3053     [0x0e] = SSE_SPECIAL, /* femms */
3054     [0x0f] = SSE_3DNOW, /* pf... (sse_op_table5) */
3055     /* pure SSE operations */
3056     [0x10] = SSE_SPECIAL, /* movups, movupd, movss, movsd */
3057     [0x11] = SSE_SPECIAL, /* movups, movupd, movss, movsd */
3058     [0x12] = SSE_SPECIAL, /* movlps, movlpd, movsldup, movddup */
3059     [0x13] = SSE_SPECIAL, /* movlps, movlpd */
3060     [0x14] = SSE_OP(punpckldq, punpcklqdq, op2, 0), /* unpcklps, unpcklpd */
3061     [0x15] = SSE_OP(punpckhdq, punpckhqdq, op2, 0), /* unpckhps, unpckhpd */
3062     [0x16] = SSE_SPECIAL, /* movhps, movhpd, movshdup */
3063     [0x17] = SSE_SPECIAL, /* movhps, movhpd */
3064 
3065     [0x28] = SSE_SPECIAL, /* movaps, movapd */
3066     [0x29] = SSE_SPECIAL, /* movaps, movapd */
3067     [0x2a] = SSE_SPECIAL, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
3068     [0x2b] = SSE_SPECIAL, /* movntps, movntpd, movntss, movntsd */
3069     [0x2c] = SSE_SPECIAL, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
3070     [0x2d] = SSE_SPECIAL, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
3071     [0x2e] = OP(op1, SSE_OPF_CMP | SSE_OPF_SCALAR | SSE_OPF_V0,
3072             gen_helper_ucomiss, gen_helper_ucomisd, NULL, NULL),
3073     [0x2f] = OP(op1, SSE_OPF_CMP | SSE_OPF_SCALAR | SSE_OPF_V0,
3074             gen_helper_comiss, gen_helper_comisd, NULL, NULL),
3075     [0x50] = SSE_SPECIAL, /* movmskps, movmskpd */
3076     [0x51] = SSE_OP_UNARY(
3077                 gen_helper_sqrtps_xmm, gen_helper_sqrtpd_xmm,
3078                 gen_helper_sqrtss, gen_helper_sqrtsd),
3079     [0x52] = SSE_OP_UNARY(
3080                 gen_helper_rsqrtps_xmm, NULL, gen_helper_rsqrtss, NULL),
3081     [0x53] = SSE_OP_UNARY(
3082                 gen_helper_rcpps_xmm, NULL, gen_helper_rcpss, NULL),
3083     [0x54] = SSE_OP(pand, pand, op2, 0), /* andps, andpd */
3084     [0x55] = SSE_OP(pandn, pandn, op2, 0), /* andnps, andnpd */
3085     [0x56] = SSE_OP(por, por, op2, 0), /* orps, orpd */
3086     [0x57] = SSE_OP(pxor, pxor, op2, 0), /* xorps, xorpd */
3087     [0x58] = SSE_FOP(add),
3088     [0x59] = SSE_FOP(mul),
3089     [0x5a] = SSE_OP_UNARY(
3090                  gen_helper_cvtps2pd_xmm, gen_helper_cvtpd2ps_xmm,
3091                  gen_helper_cvtss2sd, gen_helper_cvtsd2ss),
3092     [0x5b] = OP(op1, SSE_OPF_V0,
3093                 gen_helper_cvtdq2ps_xmm, gen_helper_cvtps2dq_xmm,
3094                 gen_helper_cvttps2dq_xmm, NULL),
3095     [0x5c] = SSE_FOP(sub),
3096     [0x5d] = SSE_FOP(min),
3097     [0x5e] = SSE_FOP(div),
3098     [0x5f] = SSE_FOP(max),
3099 
3100     [0xc2] = SSE_FOP(cmpeq), /* sse_op_table4 */
3101     [0xc6] = SSE_OP(shufps, shufpd, op2i, SSE_OPF_SHUF),
3102 
3103     /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX.  */
3104     [0x38] = SSE_SPECIAL,
3105     [0x3a] = SSE_SPECIAL,
3106 
3107     /* MMX ops and their SSE extensions */
3108     [0x60] = MMX_OP(punpcklbw),
3109     [0x61] = MMX_OP(punpcklwd),
3110     [0x62] = MMX_OP(punpckldq),
3111     [0x63] = MMX_OP(packsswb),
3112     [0x64] = MMX_OP(pcmpgtb),
3113     [0x65] = MMX_OP(pcmpgtw),
3114     [0x66] = MMX_OP(pcmpgtl),
3115     [0x67] = MMX_OP(packuswb),
3116     [0x68] = MMX_OP(punpckhbw),
3117     [0x69] = MMX_OP(punpckhwd),
3118     [0x6a] = MMX_OP(punpckhdq),
3119     [0x6b] = MMX_OP(packssdw),
3120     [0x6c] = OP(op2, SSE_OPF_MMX,
3121                 NULL, gen_helper_punpcklqdq_xmm, NULL, NULL),
3122     [0x6d] = OP(op2, SSE_OPF_MMX,
3123                 NULL, gen_helper_punpckhqdq_xmm, NULL, NULL),
3124     [0x6e] = SSE_SPECIAL, /* movd mm, ea */
3125     [0x6f] = SSE_SPECIAL, /* movq, movdqa, , movqdu */
3126     [0x70] = OP(op1i, SSE_OPF_SHUF | SSE_OPF_MMX | SSE_OPF_V0,
3127             gen_helper_pshufw_mmx, gen_helper_pshufd_xmm,
3128             gen_helper_pshufhw_xmm, gen_helper_pshuflw_xmm),
3129     [0x71] = SSE_SPECIAL, /* shiftw */
3130     [0x72] = SSE_SPECIAL, /* shiftd */
3131     [0x73] = SSE_SPECIAL, /* shiftq */
3132     [0x74] = MMX_OP(pcmpeqb),
3133     [0x75] = MMX_OP(pcmpeqw),
3134     [0x76] = MMX_OP(pcmpeql),
3135     [0x77] = SSE_SPECIAL, /* emms */
3136     [0x78] = SSE_SPECIAL, /* extrq_i, insertq_i (sse4a) */
3137     [0x79] = OP(op1, SSE_OPF_V0,
3138             NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r),
3139     [0x7c] = OP(op2, 0,
3140                 NULL, gen_helper_haddpd_xmm, NULL, gen_helper_haddps_xmm),
3141     [0x7d] = OP(op2, 0,
3142                 NULL, gen_helper_hsubpd_xmm, NULL, gen_helper_hsubps_xmm),
3143     [0x7e] = SSE_SPECIAL, /* movd, movd, , movq */
3144     [0x7f] = SSE_SPECIAL, /* movq, movdqa, movdqu */
3145     [0xc4] = SSE_SPECIAL, /* pinsrw */
3146     [0xc5] = SSE_SPECIAL, /* pextrw */
3147     [0xd0] = OP(op2, 0,
3148                 NULL, gen_helper_addsubpd_xmm, NULL, gen_helper_addsubps_xmm),
3149     [0xd1] = MMX_OP(psrlw),
3150     [0xd2] = MMX_OP(psrld),
3151     [0xd3] = MMX_OP(psrlq),
3152     [0xd4] = MMX_OP(paddq),
3153     [0xd5] = MMX_OP(pmullw),
3154     [0xd6] = SSE_SPECIAL,
3155     [0xd7] = SSE_SPECIAL, /* pmovmskb */
3156     [0xd8] = MMX_OP(psubusb),
3157     [0xd9] = MMX_OP(psubusw),
3158     [0xda] = MMX_OP(pminub),
3159     [0xdb] = MMX_OP(pand),
3160     [0xdc] = MMX_OP(paddusb),
3161     [0xdd] = MMX_OP(paddusw),
3162     [0xde] = MMX_OP(pmaxub),
3163     [0xdf] = MMX_OP(pandn),
3164     [0xe0] = MMX_OP(pavgb),
3165     [0xe1] = MMX_OP(psraw),
3166     [0xe2] = MMX_OP(psrad),
3167     [0xe3] = MMX_OP(pavgw),
3168     [0xe4] = MMX_OP(pmulhuw),
3169     [0xe5] = MMX_OP(pmulhw),
3170     [0xe6] = OP(op1, SSE_OPF_V0,
3171             NULL, gen_helper_cvttpd2dq_xmm,
3172             gen_helper_cvtdq2pd_xmm, gen_helper_cvtpd2dq_xmm),
3173     [0xe7] = SSE_SPECIAL,  /* movntq, movntq */
3174     [0xe8] = MMX_OP(psubsb),
3175     [0xe9] = MMX_OP(psubsw),
3176     [0xea] = MMX_OP(pminsw),
3177     [0xeb] = MMX_OP(por),
3178     [0xec] = MMX_OP(paddsb),
3179     [0xed] = MMX_OP(paddsw),
3180     [0xee] = MMX_OP(pmaxsw),
3181     [0xef] = MMX_OP(pxor),
3182     [0xf0] = SSE_SPECIAL, /* lddqu */
3183     [0xf1] = MMX_OP(psllw),
3184     [0xf2] = MMX_OP(pslld),
3185     [0xf3] = MMX_OP(psllq),
3186     [0xf4] = MMX_OP(pmuludq),
3187     [0xf5] = MMX_OP(pmaddwd),
3188     [0xf6] = MMX_OP(psadbw),
3189     [0xf7] = OP(op1t, SSE_OPF_MMX | SSE_OPF_V0,
3190                 gen_helper_maskmov_mmx, gen_helper_maskmov_xmm, NULL, NULL),
3191     [0xf8] = MMX_OP(psubb),
3192     [0xf9] = MMX_OP(psubw),
3193     [0xfa] = MMX_OP(psubl),
3194     [0xfb] = MMX_OP(psubq),
3195     [0xfc] = MMX_OP(paddb),
3196     [0xfd] = MMX_OP(paddw),
3197     [0xfe] = MMX_OP(paddl),
3198 };
3199 #undef MMX_OP
3200 #undef OP
3201 #undef SSE_FOP
3202 #undef SSE_OP
3203 #undef SSE_SPECIAL
3204 
3205 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
3206 
3207 static const SSEFunc_0_eppp sse_op_table2[3 * 8][2] = {
3208     [0 + 2] = MMX_OP2(psrlw),
3209     [0 + 4] = MMX_OP2(psraw),
3210     [0 + 6] = MMX_OP2(psllw),
3211     [8 + 2] = MMX_OP2(psrld),
3212     [8 + 4] = MMX_OP2(psrad),
3213     [8 + 6] = MMX_OP2(pslld),
3214     [16 + 2] = MMX_OP2(psrlq),
3215     [16 + 3] = { NULL, gen_helper_psrldq_xmm },
3216     [16 + 6] = MMX_OP2(psllq),
3217     [16 + 7] = { NULL, gen_helper_pslldq_xmm },
3218 };
3219 
3220 static const SSEFunc_0_epi sse_op_table3ai[] = {
3221     gen_helper_cvtsi2ss,
3222     gen_helper_cvtsi2sd
3223 };
3224 
3225 #ifdef TARGET_X86_64
3226 static const SSEFunc_0_epl sse_op_table3aq[] = {
3227     gen_helper_cvtsq2ss,
3228     gen_helper_cvtsq2sd
3229 };
3230 #endif
3231 
3232 static const SSEFunc_i_ep sse_op_table3bi[] = {
3233     gen_helper_cvttss2si,
3234     gen_helper_cvtss2si,
3235     gen_helper_cvttsd2si,
3236     gen_helper_cvtsd2si
3237 };
3238 
3239 #ifdef TARGET_X86_64
3240 static const SSEFunc_l_ep sse_op_table3bq[] = {
3241     gen_helper_cvttss2sq,
3242     gen_helper_cvtss2sq,
3243     gen_helper_cvttsd2sq,
3244     gen_helper_cvtsd2sq
3245 };
3246 #endif
3247 
3248 #define SSE_CMP(x) { \
3249     gen_helper_ ## x ## ps ## _xmm, gen_helper_ ## x ## pd ## _xmm, \
3250     gen_helper_ ## x ## ss, gen_helper_ ## x ## sd}
3251 static const SSEFunc_0_eppp sse_op_table4[8][4] = {
3252     SSE_CMP(cmpeq),
3253     SSE_CMP(cmplt),
3254     SSE_CMP(cmple),
3255     SSE_CMP(cmpunord),
3256     SSE_CMP(cmpneq),
3257     SSE_CMP(cmpnlt),
3258     SSE_CMP(cmpnle),
3259     SSE_CMP(cmpord),
3260 };
3261 #undef SSE_CMP
3262 
3263 static void gen_helper_pavgusb(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b)
3264 {
3265     gen_helper_pavgb_mmx(env, reg_a, reg_a, reg_b);
3266 }
3267 
3268 static const SSEFunc_0_epp sse_op_table5[256] = {
3269     [0x0c] = gen_helper_pi2fw,
3270     [0x0d] = gen_helper_pi2fd,
3271     [0x1c] = gen_helper_pf2iw,
3272     [0x1d] = gen_helper_pf2id,
3273     [0x8a] = gen_helper_pfnacc,
3274     [0x8e] = gen_helper_pfpnacc,
3275     [0x90] = gen_helper_pfcmpge,
3276     [0x94] = gen_helper_pfmin,
3277     [0x96] = gen_helper_pfrcp,
3278     [0x97] = gen_helper_pfrsqrt,
3279     [0x9a] = gen_helper_pfsub,
3280     [0x9e] = gen_helper_pfadd,
3281     [0xa0] = gen_helper_pfcmpgt,
3282     [0xa4] = gen_helper_pfmax,
3283     [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
3284     [0xa7] = gen_helper_movq, /* pfrsqit1 */
3285     [0xaa] = gen_helper_pfsubr,
3286     [0xae] = gen_helper_pfacc,
3287     [0xb0] = gen_helper_pfcmpeq,
3288     [0xb4] = gen_helper_pfmul,
3289     [0xb6] = gen_helper_movq, /* pfrcpit2 */
3290     [0xb7] = gen_helper_pmulhrw_mmx,
3291     [0xbb] = gen_helper_pswapd,
3292     [0xbf] = gen_helper_pavgusb,
3293 };
3294 
3295 struct SSEOpHelper_table6 {
3296     SSEFuncs fn[2];
3297     uint32_t ext_mask;
3298     int flags;
3299 };
3300 
3301 struct SSEOpHelper_table7 {
3302     union {
3303         SSEFunc_0_eppi op1;
3304         SSEFunc_0_epppi op2;
3305         SSEFunc_0_epppp op3;
3306     } fn[2];
3307     uint32_t ext_mask;
3308     int flags;
3309 };
3310 
3311 #define gen_helper_special_xmm NULL
3312 
3313 #define OP(name, op, flags, ext, mmx_name) \
3314     {{{.op = mmx_name}, {.op = gen_helper_ ## name ## _xmm} }, \
3315         CPUID_EXT_ ## ext, flags}
3316 #define BINARY_OP_MMX(name, ext) \
3317     OP(name, op2, SSE_OPF_MMX, ext, gen_helper_ ## name ## _mmx)
3318 #define BINARY_OP(name, ext, flags) \
3319     OP(name, op2, flags, ext, NULL)
3320 #define UNARY_OP_MMX(name, ext) \
3321     OP(name, op1, SSE_OPF_V0 | SSE_OPF_MMX, ext, gen_helper_ ## name ## _mmx)
3322 #define UNARY_OP(name, ext, flags) \
3323     OP(name, op1, SSE_OPF_V0 | flags, ext, NULL)
3324 #define BLENDV_OP(name, ext, flags) OP(name, op3, SSE_OPF_BLENDV, ext, NULL)
3325 #define CMP_OP(name, ext) OP(name, op1, SSE_OPF_CMP | SSE_OPF_V0, ext, NULL)
3326 #define SPECIAL_OP(ext) OP(special, op1, SSE_OPF_SPECIAL, ext, NULL)
3327 
3328 /* prefix [66] 0f 38 */
3329 static const struct SSEOpHelper_table6 sse_op_table6[256] = {
3330     [0x00] = BINARY_OP_MMX(pshufb, SSSE3),
3331     [0x01] = BINARY_OP_MMX(phaddw, SSSE3),
3332     [0x02] = BINARY_OP_MMX(phaddd, SSSE3),
3333     [0x03] = BINARY_OP_MMX(phaddsw, SSSE3),
3334     [0x04] = BINARY_OP_MMX(pmaddubsw, SSSE3),
3335     [0x05] = BINARY_OP_MMX(phsubw, SSSE3),
3336     [0x06] = BINARY_OP_MMX(phsubd, SSSE3),
3337     [0x07] = BINARY_OP_MMX(phsubsw, SSSE3),
3338     [0x08] = BINARY_OP_MMX(psignb, SSSE3),
3339     [0x09] = BINARY_OP_MMX(psignw, SSSE3),
3340     [0x0a] = BINARY_OP_MMX(psignd, SSSE3),
3341     [0x0b] = BINARY_OP_MMX(pmulhrsw, SSSE3),
3342     [0x10] = BLENDV_OP(pblendvb, SSE41, SSE_OPF_MMX),
3343     [0x14] = BLENDV_OP(blendvps, SSE41, 0),
3344     [0x15] = BLENDV_OP(blendvpd, SSE41, 0),
3345     [0x17] = CMP_OP(ptest, SSE41),
3346     [0x1c] = UNARY_OP_MMX(pabsb, SSSE3),
3347     [0x1d] = UNARY_OP_MMX(pabsw, SSSE3),
3348     [0x1e] = UNARY_OP_MMX(pabsd, SSSE3),
3349     [0x20] = UNARY_OP(pmovsxbw, SSE41, SSE_OPF_MMX),
3350     [0x21] = UNARY_OP(pmovsxbd, SSE41, SSE_OPF_MMX),
3351     [0x22] = UNARY_OP(pmovsxbq, SSE41, SSE_OPF_MMX),
3352     [0x23] = UNARY_OP(pmovsxwd, SSE41, SSE_OPF_MMX),
3353     [0x24] = UNARY_OP(pmovsxwq, SSE41, SSE_OPF_MMX),
3354     [0x25] = UNARY_OP(pmovsxdq, SSE41, SSE_OPF_MMX),
3355     [0x28] = BINARY_OP(pmuldq, SSE41, SSE_OPF_MMX),
3356     [0x29] = BINARY_OP(pcmpeqq, SSE41, SSE_OPF_MMX),
3357     [0x2a] = SPECIAL_OP(SSE41), /* movntdqa */
3358     [0x2b] = BINARY_OP(packusdw, SSE41, SSE_OPF_MMX),
3359     [0x30] = UNARY_OP(pmovzxbw, SSE41, SSE_OPF_MMX),
3360     [0x31] = UNARY_OP(pmovzxbd, SSE41, SSE_OPF_MMX),
3361     [0x32] = UNARY_OP(pmovzxbq, SSE41, SSE_OPF_MMX),
3362     [0x33] = UNARY_OP(pmovzxwd, SSE41, SSE_OPF_MMX),
3363     [0x34] = UNARY_OP(pmovzxwq, SSE41, SSE_OPF_MMX),
3364     [0x35] = UNARY_OP(pmovzxdq, SSE41, SSE_OPF_MMX),
3365     [0x37] = BINARY_OP(pcmpgtq, SSE41, SSE_OPF_MMX),
3366     [0x38] = BINARY_OP(pminsb, SSE41, SSE_OPF_MMX),
3367     [0x39] = BINARY_OP(pminsd, SSE41, SSE_OPF_MMX),
3368     [0x3a] = BINARY_OP(pminuw, SSE41, SSE_OPF_MMX),
3369     [0x3b] = BINARY_OP(pminud, SSE41, SSE_OPF_MMX),
3370     [0x3c] = BINARY_OP(pmaxsb, SSE41, SSE_OPF_MMX),
3371     [0x3d] = BINARY_OP(pmaxsd, SSE41, SSE_OPF_MMX),
3372     [0x3e] = BINARY_OP(pmaxuw, SSE41, SSE_OPF_MMX),
3373     [0x3f] = BINARY_OP(pmaxud, SSE41, SSE_OPF_MMX),
3374     [0x40] = BINARY_OP(pmulld, SSE41, SSE_OPF_MMX),
3375     [0x41] = UNARY_OP(phminposuw, SSE41, 0),
3376     [0xdb] = UNARY_OP(aesimc, AES, 0),
3377     [0xdc] = BINARY_OP(aesenc, AES, 0),
3378     [0xdd] = BINARY_OP(aesenclast, AES, 0),
3379     [0xde] = BINARY_OP(aesdec, AES, 0),
3380     [0xdf] = BINARY_OP(aesdeclast, AES, 0),
3381 };
3382 
3383 /* prefix [66] 0f 3a */
3384 static const struct SSEOpHelper_table7 sse_op_table7[256] = {
3385     [0x08] = UNARY_OP(roundps, SSE41, 0),
3386     [0x09] = UNARY_OP(roundpd, SSE41, 0),
3387     [0x0a] = BINARY_OP(roundss, SSE41, SSE_OPF_SCALAR),
3388     [0x0b] = BINARY_OP(roundsd, SSE41, SSE_OPF_SCALAR),
3389     [0x0c] = BINARY_OP(blendps, SSE41, 0),
3390     [0x0d] = BINARY_OP(blendpd, SSE41, 0),
3391     [0x0e] = BINARY_OP(pblendw, SSE41, SSE_OPF_MMX),
3392     [0x0f] = BINARY_OP_MMX(palignr, SSSE3),
3393     [0x14] = SPECIAL_OP(SSE41), /* pextrb */
3394     [0x15] = SPECIAL_OP(SSE41), /* pextrw */
3395     [0x16] = SPECIAL_OP(SSE41), /* pextrd/pextrq */
3396     [0x17] = SPECIAL_OP(SSE41), /* extractps */
3397     [0x20] = SPECIAL_OP(SSE41), /* pinsrb */
3398     [0x21] = SPECIAL_OP(SSE41), /* insertps */
3399     [0x22] = SPECIAL_OP(SSE41), /* pinsrd/pinsrq */
3400     [0x40] = BINARY_OP(dpps, SSE41, 0),
3401     [0x41] = BINARY_OP(dppd, SSE41, 0),
3402     [0x42] = BINARY_OP(mpsadbw, SSE41, SSE_OPF_MMX),
3403     [0x44] = BINARY_OP(pclmulqdq, PCLMULQDQ, 0),
3404     [0x60] = CMP_OP(pcmpestrm, SSE42),
3405     [0x61] = CMP_OP(pcmpestri, SSE42),
3406     [0x62] = CMP_OP(pcmpistrm, SSE42),
3407     [0x63] = CMP_OP(pcmpistri, SSE42),
3408     [0xdf] = UNARY_OP(aeskeygenassist, AES, 0),
3409 };
3410 
3411 #undef OP
3412 #undef BINARY_OP_MMX
3413 #undef BINARY_OP
3414 #undef UNARY_OP_MMX
3415 #undef UNARY_OP
3416 #undef BLENDV_OP
3417 #undef SPECIAL_OP
3418 
3419 /* VEX prefix not allowed */
3420 #define CHECK_NO_VEX(s) do { \
3421     if (s->prefix & PREFIX_VEX) \
3422         goto illegal_op; \
3423     } while (0)
3424 
3425 static void gen_sse(CPUX86State *env, DisasContext *s, int b)
3426 {
3427     int b1, op1_offset, op2_offset, is_xmm, val;
3428     int modrm, mod, rm, reg;
3429     int sse_op_flags;
3430     SSEFuncs sse_op_fn;
3431     const struct SSEOpHelper_table6 *op6;
3432     const struct SSEOpHelper_table7 *op7;
3433     MemOp ot;
3434 
3435     b &= 0xff;
3436     if (s->prefix & PREFIX_DATA)
3437         b1 = 1;
3438     else if (s->prefix & PREFIX_REPZ)
3439         b1 = 2;
3440     else if (s->prefix & PREFIX_REPNZ)
3441         b1 = 3;
3442     else
3443         b1 = 0;
3444     sse_op_flags = sse_op_table1[b].flags;
3445     sse_op_fn = sse_op_table1[b].fn[b1];
3446     if ((sse_op_flags & (SSE_OPF_SPECIAL | SSE_OPF_3DNOW)) == 0
3447             && !sse_op_fn.op1) {
3448         goto unknown_op;
3449     }
3450     if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
3451         is_xmm = 1;
3452     } else {
3453         if (b1 == 0) {
3454             /* MMX case */
3455             is_xmm = 0;
3456         } else {
3457             is_xmm = 1;
3458         }
3459     }
3460     if (sse_op_flags & SSE_OPF_3DNOW) {
3461         if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
3462             goto illegal_op;
3463         }
3464     }
3465     /* simple MMX/SSE operation */
3466     if (s->flags & HF_TS_MASK) {
3467         gen_exception(s, EXCP07_PREX);
3468         return;
3469     }
3470     if (s->flags & HF_EM_MASK) {
3471     illegal_op:
3472         gen_illegal_opcode(s);
3473         return;
3474     }
3475     if (is_xmm
3476         && !(s->flags & HF_OSFXSR_MASK)
3477         && (b != 0x38 && b != 0x3a)) {
3478         goto unknown_op;
3479     }
3480     if (b == 0x0e) {
3481         if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
3482             /* If we were fully decoding this we might use illegal_op.  */
3483             goto unknown_op;
3484         }
3485         /* femms */
3486         gen_helper_emms(cpu_env);
3487         return;
3488     }
3489     if (b == 0x77) {
3490         /* emms */
3491         gen_helper_emms(cpu_env);
3492         return;
3493     }
3494     /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3495        the static cpu state) */
3496     if (!is_xmm) {
3497         gen_helper_enter_mmx(cpu_env);
3498     }
3499 
3500     modrm = x86_ldub_code(env, s);
3501     reg = ((modrm >> 3) & 7);
3502     if (is_xmm) {
3503         reg |= REX_R(s);
3504     }
3505     mod = (modrm >> 6) & 3;
3506     if (sse_op_flags & SSE_OPF_SPECIAL) {
3507         b |= (b1 << 8);
3508         switch(b) {
3509         case 0x0e7: /* movntq */
3510             CHECK_NO_VEX(s);
3511             if (mod == 3) {
3512                 goto illegal_op;
3513             }
3514             gen_lea_modrm(env, s, modrm);
3515             gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3516             break;
3517         case 0x1e7: /* movntdq */
3518         case 0x02b: /* movntps */
3519         case 0x12b: /* movntpd */
3520             if (mod == 3)
3521                 goto illegal_op;
3522             gen_lea_modrm(env, s, modrm);
3523             gen_sto_env_A0(s, XMM_OFFSET(reg), true);
3524             break;
3525         case 0x3f0: /* lddqu */
3526             if (mod == 3)
3527                 goto illegal_op;
3528             gen_lea_modrm(env, s, modrm);
3529             gen_ldo_env_A0(s, XMM_OFFSET(reg), true);
3530             break;
3531         case 0x22b: /* movntss */
3532         case 0x32b: /* movntsd */
3533             if (mod == 3)
3534                 goto illegal_op;
3535             gen_lea_modrm(env, s, modrm);
3536             if (b1 & 1) {
3537                 gen_stq_env_A0(s, offsetof(CPUX86State,
3538                                            xmm_regs[reg].ZMM_Q(0)));
3539             } else {
3540                 tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State,
3541                     xmm_regs[reg].ZMM_L(0)));
3542                 gen_op_st_v(s, MO_32, s->T0, s->A0);
3543             }
3544             break;
3545         case 0x6e: /* movd mm, ea */
3546             CHECK_NO_VEX(s);
3547 #ifdef TARGET_X86_64
3548             if (s->dflag == MO_64) {
3549                 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3550                 tcg_gen_st_tl(s->T0, cpu_env,
3551                               offsetof(CPUX86State, fpregs[reg].mmx));
3552             } else
3553 #endif
3554             {
3555                 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3556                 tcg_gen_addi_ptr(s->ptr0, cpu_env,
3557                                  offsetof(CPUX86State,fpregs[reg].mmx));
3558                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3559                 gen_helper_movl_mm_T0_mmx(s->ptr0, s->tmp2_i32);
3560             }
3561             break;
3562         case 0x16e: /* movd xmm, ea */
3563 #ifdef TARGET_X86_64
3564             if (s->dflag == MO_64) {
3565                 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3566                 tcg_gen_addi_ptr(s->ptr0, cpu_env, ZMM_OFFSET(reg));
3567                 gen_helper_movq_mm_T0_xmm(s->ptr0, s->T0);
3568             } else
3569 #endif
3570             {
3571                 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3572                 tcg_gen_addi_ptr(s->ptr0, cpu_env, ZMM_OFFSET(reg));
3573                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3574                 gen_helper_movl_mm_T0_xmm(s->ptr0, s->tmp2_i32);
3575             }
3576             break;
3577         case 0x6f: /* movq mm, ea */
3578             CHECK_NO_VEX(s);
3579             if (mod != 3) {
3580                 gen_lea_modrm(env, s, modrm);
3581                 gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3582             } else {
3583                 rm = (modrm & 7);
3584                 tcg_gen_ld_i64(s->tmp1_i64, cpu_env,
3585                                offsetof(CPUX86State,fpregs[rm].mmx));
3586                 tcg_gen_st_i64(s->tmp1_i64, cpu_env,
3587                                offsetof(CPUX86State,fpregs[reg].mmx));
3588             }
3589             break;
3590         case 0x010: /* movups */
3591         case 0x110: /* movupd */
3592         case 0x028: /* movaps */
3593         case 0x128: /* movapd */
3594         case 0x16f: /* movdqa xmm, ea */
3595         case 0x26f: /* movdqu xmm, ea */
3596             if (mod != 3) {
3597                 gen_lea_modrm(env, s, modrm);
3598                 gen_ldo_env_A0(s, XMM_OFFSET(reg),
3599                                /* movaps, movapd, movdqa */
3600                                b == 0x028 || b == 0x128 || b == 0x16f);
3601             } else {
3602                 rm = (modrm & 7) | REX_B(s);
3603                 gen_op_movo(s, XMM_OFFSET(reg), XMM_OFFSET(rm));
3604             }
3605             break;
3606         case 0x210: /* movss xmm, ea */
3607             if (mod != 3) {
3608                 gen_lea_modrm(env, s, modrm);
3609                 gen_op_ld_v(s, MO_32, s->T0, s->A0);
3610                 tcg_gen_st32_tl(s->T0, cpu_env,
3611                                 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)));
3612                 tcg_gen_movi_tl(s->T0, 0);
3613                 tcg_gen_st32_tl(s->T0, cpu_env,
3614                                 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(1)));
3615                 tcg_gen_st32_tl(s->T0, cpu_env,
3616                                 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2)));
3617                 tcg_gen_st32_tl(s->T0, cpu_env,
3618                                 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3)));
3619             } else {
3620                 rm = (modrm & 7) | REX_B(s);
3621                 tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
3622                                offsetof(CPUX86State, xmm_regs[rm].ZMM_L(0)));
3623                 tcg_gen_st_i32(s->tmp2_i32, cpu_env,
3624                                offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)));
3625             }
3626             break;
3627         case 0x310: /* movsd xmm, ea */
3628             if (mod != 3) {
3629                 gen_lea_modrm(env, s, modrm);
3630                 gen_ldq_env_A0(s, offsetof(CPUX86State,
3631                                            xmm_regs[reg].ZMM_Q(0)));
3632                 tcg_gen_movi_tl(s->T0, 0);
3633                 tcg_gen_st32_tl(s->T0, cpu_env,
3634                                 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2)));
3635                 tcg_gen_st32_tl(s->T0, cpu_env,
3636                                 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3)));
3637             } else {
3638                 rm = (modrm & 7) | REX_B(s);
3639                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)),
3640                             offsetof(CPUX86State, xmm_regs[rm].ZMM_Q(0)));
3641             }
3642             break;
3643         case 0x012: /* movlps */
3644         case 0x112: /* movlpd */
3645             if (mod != 3) {
3646                 gen_lea_modrm(env, s, modrm);
3647                 gen_ldq_env_A0(s, offsetof(CPUX86State,
3648                                            xmm_regs[reg].ZMM_Q(0)));
3649             } else {
3650                 /* movhlps */
3651                 rm = (modrm & 7) | REX_B(s);
3652                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)),
3653                             offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3654             }
3655             break;
3656         case 0x212: /* movsldup */
3657             if (mod != 3) {
3658                 gen_lea_modrm(env, s, modrm);
3659                 gen_ldo_env_A0(s, XMM_OFFSET(reg), true);
3660             } else {
3661                 rm = (modrm & 7) | REX_B(s);
3662                 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)),
3663                             offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3664                 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2)),
3665                             offsetof(CPUX86State,xmm_regs[rm].ZMM_L(2)));
3666             }
3667             gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(1)),
3668                         offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3669             gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3)),
3670                         offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3671             break;
3672         case 0x312: /* movddup */
3673             if (mod != 3) {
3674                 gen_lea_modrm(env, s, modrm);
3675                 gen_ldq_env_A0(s, offsetof(CPUX86State,
3676                                            xmm_regs[reg].ZMM_Q(0)));
3677             } else {
3678                 rm = (modrm & 7) | REX_B(s);
3679                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)),
3680                             offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3681             }
3682             gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1)),
3683                         offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3684             break;
3685         case 0x016: /* movhps */
3686         case 0x116: /* movhpd */
3687             if (mod != 3) {
3688                 gen_lea_modrm(env, s, modrm);
3689                 gen_ldq_env_A0(s, offsetof(CPUX86State,
3690                                            xmm_regs[reg].ZMM_Q(1)));
3691             } else {
3692                 /* movlhps */
3693                 rm = (modrm & 7) | REX_B(s);
3694                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1)),
3695                             offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3696             }
3697             break;
3698         case 0x216: /* movshdup */
3699             if (mod != 3) {
3700                 gen_lea_modrm(env, s, modrm);
3701                 gen_ldo_env_A0(s, XMM_OFFSET(reg), true);
3702             } else {
3703                 rm = (modrm & 7) | REX_B(s);
3704                 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(1)),
3705                             offsetof(CPUX86State,xmm_regs[rm].ZMM_L(1)));
3706                 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3)),
3707                             offsetof(CPUX86State,xmm_regs[rm].ZMM_L(3)));
3708             }
3709             gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)),
3710                         offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3711             gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2)),
3712                         offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3713             break;
3714         case 0x178:
3715         case 0x378:
3716             CHECK_NO_VEX(s);
3717             {
3718                 int bit_index, field_length;
3719 
3720                 if (b1 == 1 && reg != 0)
3721                     goto illegal_op;
3722                 field_length = x86_ldub_code(env, s) & 0x3F;
3723                 bit_index = x86_ldub_code(env, s) & 0x3F;
3724                 tcg_gen_addi_ptr(s->ptr0, cpu_env, ZMM_OFFSET(reg));
3725                 if (b1 == 1)
3726                     gen_helper_extrq_i(cpu_env, s->ptr0,
3727                                        tcg_const_i32(bit_index),
3728                                        tcg_const_i32(field_length));
3729                 else {
3730                     if (mod != 3) {
3731                         gen_lea_modrm(env, s, modrm);
3732                         op2_offset = offsetof(CPUX86State, xmm_t0);
3733                         gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0)));
3734                     } else {
3735                         rm = (modrm & 7) | REX_B(s);
3736                         op2_offset = ZMM_OFFSET(rm);
3737                     }
3738                     tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
3739                     gen_helper_insertq_i(cpu_env, s->ptr0, s->ptr1,
3740                                          tcg_const_i32(bit_index),
3741                                          tcg_const_i32(field_length));
3742                 }
3743             }
3744             break;
3745         case 0x7e: /* movd ea, mm */
3746             CHECK_NO_VEX(s);
3747 #ifdef TARGET_X86_64
3748             if (s->dflag == MO_64) {
3749                 tcg_gen_ld_i64(s->T0, cpu_env,
3750                                offsetof(CPUX86State,fpregs[reg].mmx));
3751                 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3752             } else
3753 #endif
3754             {
3755                 tcg_gen_ld32u_tl(s->T0, cpu_env,
3756                                  offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3757                 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3758             }
3759             break;
3760         case 0x17e: /* movd ea, xmm */
3761 #ifdef TARGET_X86_64
3762             if (s->dflag == MO_64) {
3763                 tcg_gen_ld_i64(s->T0, cpu_env,
3764                                offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3765                 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3766             } else
3767 #endif
3768             {
3769                 tcg_gen_ld32u_tl(s->T0, cpu_env,
3770                                  offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3771                 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3772             }
3773             break;
3774         case 0x27e: /* movq xmm, ea */
3775             if (mod != 3) {
3776                 gen_lea_modrm(env, s, modrm);
3777                 gen_ldq_env_A0(s, offsetof(CPUX86State,
3778                                            xmm_regs[reg].ZMM_Q(0)));
3779             } else {
3780                 rm = (modrm & 7) | REX_B(s);
3781                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)),
3782                             offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3783             }
3784             gen_op_movq_env_0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1)));
3785             break;
3786         case 0x7f: /* movq ea, mm */
3787             CHECK_NO_VEX(s);
3788             if (mod != 3) {
3789                 gen_lea_modrm(env, s, modrm);
3790                 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3791             } else {
3792                 rm = (modrm & 7);
3793                 gen_op_movq(s, offsetof(CPUX86State, fpregs[rm].mmx),
3794                             offsetof(CPUX86State,fpregs[reg].mmx));
3795             }
3796             break;
3797         case 0x011: /* movups */
3798         case 0x111: /* movupd */
3799         case 0x029: /* movaps */
3800         case 0x129: /* movapd */
3801         case 0x17f: /* movdqa ea, xmm */
3802         case 0x27f: /* movdqu ea, xmm */
3803             if (mod != 3) {
3804                 gen_lea_modrm(env, s, modrm);
3805                 gen_sto_env_A0(s, XMM_OFFSET(reg),
3806                                /* movaps, movapd, movdqa */
3807                                b == 0x029 || b == 0x129 || b == 0x17f);
3808             } else {
3809                 rm = (modrm & 7) | REX_B(s);
3810                 gen_op_movo(s, XMM_OFFSET(rm), XMM_OFFSET(reg));
3811             }
3812             break;
3813         case 0x211: /* movss ea, xmm */
3814             if (mod != 3) {
3815                 gen_lea_modrm(env, s, modrm);
3816                 tcg_gen_ld32u_tl(s->T0, cpu_env,
3817                                  offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)));
3818                 gen_op_st_v(s, MO_32, s->T0, s->A0);
3819             } else {
3820                 rm = (modrm & 7) | REX_B(s);
3821                 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[rm].ZMM_L(0)),
3822                             offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3823             }
3824             break;
3825         case 0x311: /* movsd ea, xmm */
3826             if (mod != 3) {
3827                 gen_lea_modrm(env, s, modrm);
3828                 gen_stq_env_A0(s, offsetof(CPUX86State,
3829                                            xmm_regs[reg].ZMM_Q(0)));
3830             } else {
3831                 rm = (modrm & 7) | REX_B(s);
3832                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[rm].ZMM_Q(0)),
3833                             offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3834             }
3835             break;
3836         case 0x013: /* movlps */
3837         case 0x113: /* movlpd */
3838             if (mod != 3) {
3839                 gen_lea_modrm(env, s, modrm);
3840                 gen_stq_env_A0(s, offsetof(CPUX86State,
3841                                            xmm_regs[reg].ZMM_Q(0)));
3842             } else {
3843                 goto illegal_op;
3844             }
3845             break;
3846         case 0x017: /* movhps */
3847         case 0x117: /* movhpd */
3848             if (mod != 3) {
3849                 gen_lea_modrm(env, s, modrm);
3850                 gen_stq_env_A0(s, offsetof(CPUX86State,
3851                                            xmm_regs[reg].ZMM_Q(1)));
3852             } else {
3853                 goto illegal_op;
3854             }
3855             break;
3856         case 0x71: /* shift mm, im */
3857         case 0x72:
3858         case 0x73:
3859         case 0x171: /* shift xmm, im */
3860         case 0x172:
3861         case 0x173:
3862             val = x86_ldub_code(env, s);
3863             if (is_xmm) {
3864                 tcg_gen_movi_tl(s->T0, val);
3865                 tcg_gen_st32_tl(s->T0, cpu_env,
3866                                 offsetof(CPUX86State, xmm_t0.ZMM_L(0)));
3867                 tcg_gen_movi_tl(s->T0, 0);
3868                 tcg_gen_st32_tl(s->T0, cpu_env,
3869                                 offsetof(CPUX86State, xmm_t0.ZMM_L(1)));
3870                 op1_offset = offsetof(CPUX86State,xmm_t0);
3871             } else {
3872                 CHECK_NO_VEX(s);
3873                 tcg_gen_movi_tl(s->T0, val);
3874                 tcg_gen_st32_tl(s->T0, cpu_env,
3875                                 offsetof(CPUX86State, mmx_t0.MMX_L(0)));
3876                 tcg_gen_movi_tl(s->T0, 0);
3877                 tcg_gen_st32_tl(s->T0, cpu_env,
3878                                 offsetof(CPUX86State, mmx_t0.MMX_L(1)));
3879                 op1_offset = offsetof(CPUX86State,mmx_t0);
3880             }
3881             assert(b1 < 2);
3882             SSEFunc_0_eppp fn = sse_op_table2[((b - 1) & 3) * 8 +
3883                                        (((modrm >> 3)) & 7)][b1];
3884             if (!fn) {
3885                 goto unknown_op;
3886             }
3887             if (is_xmm) {
3888                 rm = (modrm & 7) | REX_B(s);
3889                 op2_offset = ZMM_OFFSET(rm);
3890             } else {
3891                 rm = (modrm & 7);
3892                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3893             }
3894             tcg_gen_addi_ptr(s->ptr0, cpu_env, op2_offset);
3895             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
3896             tcg_gen_addi_ptr(s->ptr2, cpu_env, op1_offset);
3897             fn(cpu_env, s->ptr0, s->ptr1, s->ptr2);
3898             break;
3899         case 0x050: /* movmskps */
3900             rm = (modrm & 7) | REX_B(s);
3901             tcg_gen_addi_ptr(s->ptr0, cpu_env, ZMM_OFFSET(rm));
3902             gen_helper_movmskps_xmm(s->tmp2_i32, cpu_env, s->ptr0);
3903             tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
3904             break;
3905         case 0x150: /* movmskpd */
3906             rm = (modrm & 7) | REX_B(s);
3907             tcg_gen_addi_ptr(s->ptr0, cpu_env, ZMM_OFFSET(rm));
3908             gen_helper_movmskpd_xmm(s->tmp2_i32, cpu_env, s->ptr0);
3909             tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
3910             break;
3911         case 0x02a: /* cvtpi2ps */
3912         case 0x12a: /* cvtpi2pd */
3913             CHECK_NO_VEX(s);
3914             gen_helper_enter_mmx(cpu_env);
3915             if (mod != 3) {
3916                 gen_lea_modrm(env, s, modrm);
3917                 op2_offset = offsetof(CPUX86State,mmx_t0);
3918                 gen_ldq_env_A0(s, op2_offset);
3919             } else {
3920                 rm = (modrm & 7);
3921                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3922             }
3923             op1_offset = ZMM_OFFSET(reg);
3924             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
3925             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
3926             switch(b >> 8) {
3927             case 0x0:
3928                 gen_helper_cvtpi2ps(cpu_env, s->ptr0, s->ptr1);
3929                 break;
3930             default:
3931             case 0x1:
3932                 gen_helper_cvtpi2pd(cpu_env, s->ptr0, s->ptr1);
3933                 break;
3934             }
3935             break;
3936         case 0x22a: /* cvtsi2ss */
3937         case 0x32a: /* cvtsi2sd */
3938             ot = mo_64_32(s->dflag);
3939             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3940             op1_offset = ZMM_OFFSET(reg);
3941             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
3942             if (ot == MO_32) {
3943                 SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
3944                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3945                 sse_fn_epi(cpu_env, s->ptr0, s->tmp2_i32);
3946             } else {
3947 #ifdef TARGET_X86_64
3948                 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
3949                 sse_fn_epl(cpu_env, s->ptr0, s->T0);
3950 #else
3951                 goto illegal_op;
3952 #endif
3953             }
3954             break;
3955         case 0x02c: /* cvttps2pi */
3956         case 0x12c: /* cvttpd2pi */
3957         case 0x02d: /* cvtps2pi */
3958         case 0x12d: /* cvtpd2pi */
3959             CHECK_NO_VEX(s);
3960             gen_helper_enter_mmx(cpu_env);
3961             if (mod != 3) {
3962                 gen_lea_modrm(env, s, modrm);
3963                 op2_offset = offsetof(CPUX86State, xmm_t0.ZMM_X(0));
3964                 /* FIXME: should be 64-bit access if b1 == 0.  */
3965                 gen_ldo_env_A0(s, op2_offset, !!b1);
3966             } else {
3967                 rm = (modrm & 7) | REX_B(s);
3968                 op2_offset = ZMM_OFFSET(rm);
3969             }
3970             op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3971             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
3972             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
3973             switch(b) {
3974             case 0x02c:
3975                 gen_helper_cvttps2pi(cpu_env, s->ptr0, s->ptr1);
3976                 break;
3977             case 0x12c:
3978                 gen_helper_cvttpd2pi(cpu_env, s->ptr0, s->ptr1);
3979                 break;
3980             case 0x02d:
3981                 gen_helper_cvtps2pi(cpu_env, s->ptr0, s->ptr1);
3982                 break;
3983             case 0x12d:
3984                 gen_helper_cvtpd2pi(cpu_env, s->ptr0, s->ptr1);
3985                 break;
3986             }
3987             break;
3988         case 0x22c: /* cvttss2si */
3989         case 0x32c: /* cvttsd2si */
3990         case 0x22d: /* cvtss2si */
3991         case 0x32d: /* cvtsd2si */
3992             ot = mo_64_32(s->dflag);
3993             if (mod != 3) {
3994                 gen_lea_modrm(env, s, modrm);
3995                 if ((b >> 8) & 1) {
3996                     gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_Q(0)));
3997                 } else {
3998                     gen_op_ld_v(s, MO_32, s->T0, s->A0);
3999                     tcg_gen_st32_tl(s->T0, cpu_env,
4000                                     offsetof(CPUX86State, xmm_t0.ZMM_L(0)));
4001                 }
4002                 op2_offset = offsetof(CPUX86State,xmm_t0);
4003             } else {
4004                 rm = (modrm & 7) | REX_B(s);
4005                 op2_offset = ZMM_OFFSET(rm);
4006             }
4007             tcg_gen_addi_ptr(s->ptr0, cpu_env, op2_offset);
4008             if (ot == MO_32) {
4009                 SSEFunc_i_ep sse_fn_i_ep =
4010                     sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
4011                 sse_fn_i_ep(s->tmp2_i32, cpu_env, s->ptr0);
4012                 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
4013             } else {
4014 #ifdef TARGET_X86_64
4015                 SSEFunc_l_ep sse_fn_l_ep =
4016                     sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
4017                 sse_fn_l_ep(s->T0, cpu_env, s->ptr0);
4018 #else
4019                 goto illegal_op;
4020 #endif
4021             }
4022             gen_op_mov_reg_v(s, ot, reg, s->T0);
4023             break;
4024         case 0xc4: /* pinsrw */
4025         case 0x1c4:
4026             s->rip_offset = 1;
4027             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
4028             val = x86_ldub_code(env, s);
4029             if (b1) {
4030                 val &= 7;
4031                 tcg_gen_st16_tl(s->T0, cpu_env,
4032                                 offsetof(CPUX86State,xmm_regs[reg].ZMM_W(val)));
4033             } else {
4034                 CHECK_NO_VEX(s);
4035                 val &= 3;
4036                 tcg_gen_st16_tl(s->T0, cpu_env,
4037                                 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
4038             }
4039             break;
4040         case 0xc5: /* pextrw */
4041         case 0x1c5:
4042             if (mod != 3)
4043                 goto illegal_op;
4044             ot = mo_64_32(s->dflag);
4045             val = x86_ldub_code(env, s);
4046             if (b1) {
4047                 val &= 7;
4048                 rm = (modrm & 7) | REX_B(s);
4049                 tcg_gen_ld16u_tl(s->T0, cpu_env,
4050                                  offsetof(CPUX86State,xmm_regs[rm].ZMM_W(val)));
4051             } else {
4052                 val &= 3;
4053                 rm = (modrm & 7);
4054                 tcg_gen_ld16u_tl(s->T0, cpu_env,
4055                                 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
4056             }
4057             reg = ((modrm >> 3) & 7) | REX_R(s);
4058             gen_op_mov_reg_v(s, ot, reg, s->T0);
4059             break;
4060         case 0x1d6: /* movq ea, xmm */
4061             if (mod != 3) {
4062                 gen_lea_modrm(env, s, modrm);
4063                 gen_stq_env_A0(s, offsetof(CPUX86State,
4064                                            xmm_regs[reg].ZMM_Q(0)));
4065             } else {
4066                 rm = (modrm & 7) | REX_B(s);
4067                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[rm].ZMM_Q(0)),
4068                             offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
4069                 gen_op_movq_env_0(s,
4070                                   offsetof(CPUX86State, xmm_regs[rm].ZMM_Q(1)));
4071             }
4072             break;
4073         case 0x2d6: /* movq2dq */
4074             CHECK_NO_VEX(s);
4075             gen_helper_enter_mmx(cpu_env);
4076             rm = (modrm & 7);
4077             gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)),
4078                         offsetof(CPUX86State,fpregs[rm].mmx));
4079             gen_op_movq_env_0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1)));
4080             break;
4081         case 0x3d6: /* movdq2q */
4082             CHECK_NO_VEX(s);
4083             gen_helper_enter_mmx(cpu_env);
4084             rm = (modrm & 7) | REX_B(s);
4085             gen_op_movq(s, offsetof(CPUX86State, fpregs[reg & 7].mmx),
4086                         offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
4087             break;
4088         case 0xd7: /* pmovmskb */
4089         case 0x1d7:
4090             if (mod != 3)
4091                 goto illegal_op;
4092             if (b1) {
4093                 rm = (modrm & 7) | REX_B(s);
4094                 tcg_gen_addi_ptr(s->ptr0, cpu_env, ZMM_OFFSET(rm));
4095                 gen_helper_pmovmskb_xmm(s->tmp2_i32, cpu_env, s->ptr0);
4096             } else {
4097                 CHECK_NO_VEX(s);
4098                 rm = (modrm & 7);
4099                 tcg_gen_addi_ptr(s->ptr0, cpu_env,
4100                                  offsetof(CPUX86State, fpregs[rm].mmx));
4101                 gen_helper_pmovmskb_mmx(s->tmp2_i32, cpu_env, s->ptr0);
4102             }
4103             reg = ((modrm >> 3) & 7) | REX_R(s);
4104             tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
4105             break;
4106 
4107         case 0x138:
4108         case 0x038:
4109             b = modrm;
4110             if ((b & 0xf0) == 0xf0) {
4111                 goto do_0f_38_fx;
4112             }
4113             modrm = x86_ldub_code(env, s);
4114             rm = modrm & 7;
4115             reg = ((modrm >> 3) & 7) | REX_R(s);
4116             mod = (modrm >> 6) & 3;
4117 
4118             assert(b1 < 2);
4119             op6 = &sse_op_table6[b];
4120             if (op6->ext_mask == 0) {
4121                 goto unknown_op;
4122             }
4123             if (!(s->cpuid_ext_features & op6->ext_mask)) {
4124                 goto illegal_op;
4125             }
4126 
4127             if (b1) {
4128                 op1_offset = ZMM_OFFSET(reg);
4129                 if (mod == 3) {
4130                     op2_offset = ZMM_OFFSET(rm | REX_B(s));
4131                 } else {
4132                     op2_offset = offsetof(CPUX86State,xmm_t0);
4133                     gen_lea_modrm(env, s, modrm);
4134                     switch (b) {
4135                     case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
4136                     case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
4137                     case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
4138                         gen_ldq_env_A0(s, op2_offset +
4139                                         offsetof(ZMMReg, ZMM_Q(0)));
4140                         break;
4141                     case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
4142                     case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
4143                         tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4144                                             s->mem_index, MO_LEUL);
4145                         tcg_gen_st_i32(s->tmp2_i32, cpu_env, op2_offset +
4146                                         offsetof(ZMMReg, ZMM_L(0)));
4147                         break;
4148                     case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
4149                         tcg_gen_qemu_ld_tl(s->tmp0, s->A0,
4150                                            s->mem_index, MO_LEUW);
4151                         tcg_gen_st16_tl(s->tmp0, cpu_env, op2_offset +
4152                                         offsetof(ZMMReg, ZMM_W(0)));
4153                         break;
4154                     case 0x2a:            /* movntdqa */
4155                         gen_ldo_env_A0(s, op1_offset + offsetof(ZMMReg, ZMM_X(0)), true);
4156                         return;
4157                     default:
4158                         gen_ldo_env_A0(s, op2_offset + offsetof(ZMMReg, ZMM_X(0)), true);
4159                     }
4160                 }
4161                 if (!op6->fn[b1].op1) {
4162                     goto illegal_op;
4163                 }
4164                 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4165                 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4166                 if (op6->flags & SSE_OPF_V0) {
4167                     op6->fn[b1].op1(cpu_env, s->ptr0, s->ptr1);
4168                 } else {
4169                     tcg_gen_addi_ptr(s->ptr2, cpu_env, op1_offset);
4170                     if (op6->flags & SSE_OPF_BLENDV) {
4171                         TCGv_ptr mask = tcg_temp_new_ptr();
4172                         tcg_gen_addi_ptr(mask, cpu_env, ZMM_OFFSET(0));
4173                         op6->fn[b1].op3(cpu_env, s->ptr0, s->ptr2, s->ptr1,
4174                                        mask);
4175                         tcg_temp_free_ptr(mask);
4176                     } else {
4177                         SSEFunc_0_eppp fn = op6->fn[b1].op2;
4178                         fn(cpu_env, s->ptr0, s->ptr2, s->ptr1);
4179                     }
4180                 }
4181             } else {
4182                 CHECK_NO_VEX(s);
4183                 if ((op6->flags & SSE_OPF_MMX) == 0) {
4184                     goto unknown_op;
4185                 }
4186                 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4187                 if (mod == 3) {
4188                     op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4189                 } else {
4190                     op2_offset = offsetof(CPUX86State,mmx_t0);
4191                     gen_lea_modrm(env, s, modrm);
4192                     gen_ldq_env_A0(s, op2_offset);
4193                 }
4194                 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4195                 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4196                 if (op6->flags & SSE_OPF_V0) {
4197                     op6->fn[0].op1(cpu_env, s->ptr0, s->ptr1);
4198                 } else {
4199                     op6->fn[0].op2(cpu_env, s->ptr0, s->ptr0, s->ptr1);
4200                 }
4201             }
4202 
4203             if (op6->flags & SSE_OPF_CMP) {
4204                 set_cc_op(s, CC_OP_EFLAGS);
4205             }
4206             break;
4207 
4208         case 0x238:
4209         case 0x338:
4210         do_0f_38_fx:
4211             /* Various integer extensions at 0f 38 f[0-f].  */
4212             b = modrm | (b1 << 8);
4213             modrm = x86_ldub_code(env, s);
4214             reg = ((modrm >> 3) & 7) | REX_R(s);
4215 
4216             switch (b) {
4217             case 0x3f0: /* crc32 Gd,Eb */
4218             case 0x3f1: /* crc32 Gd,Ey */
4219             do_crc32:
4220                 CHECK_NO_VEX(s);
4221                 if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {
4222                     goto illegal_op;
4223                 }
4224                 if ((b & 0xff) == 0xf0) {
4225                     ot = MO_8;
4226                 } else if (s->dflag != MO_64) {
4227                     ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
4228                 } else {
4229                     ot = MO_64;
4230                 }
4231 
4232                 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[reg]);
4233                 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4234                 gen_helper_crc32(s->T0, s->tmp2_i32,
4235                                  s->T0, tcg_const_i32(8 << ot));
4236 
4237                 ot = mo_64_32(s->dflag);
4238                 gen_op_mov_reg_v(s, ot, reg, s->T0);
4239                 break;
4240 
4241             case 0x1f0: /* crc32 or movbe */
4242             case 0x1f1:
4243                 CHECK_NO_VEX(s);
4244                 /* For these insns, the f3 prefix is supposed to have priority
4245                    over the 66 prefix, but that's not what we implement above
4246                    setting b1.  */
4247                 if (s->prefix & PREFIX_REPNZ) {
4248                     goto do_crc32;
4249                 }
4250                 /* FALLTHRU */
4251             case 0x0f0: /* movbe Gy,My */
4252             case 0x0f1: /* movbe My,Gy */
4253                 CHECK_NO_VEX(s);
4254                 if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {
4255                     goto illegal_op;
4256                 }
4257                 if (s->dflag != MO_64) {
4258                     ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
4259                 } else {
4260                     ot = MO_64;
4261                 }
4262 
4263                 gen_lea_modrm(env, s, modrm);
4264                 if ((b & 1) == 0) {
4265                     tcg_gen_qemu_ld_tl(s->T0, s->A0,
4266                                        s->mem_index, ot | MO_BE);
4267                     gen_op_mov_reg_v(s, ot, reg, s->T0);
4268                 } else {
4269                     tcg_gen_qemu_st_tl(cpu_regs[reg], s->A0,
4270                                        s->mem_index, ot | MO_BE);
4271                 }
4272                 break;
4273             case 0x1f6: /* adcx Gy, Ey */
4274             case 0x2f6: /* adox Gy, Ey */
4275                 CHECK_NO_VEX(s);
4276                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {
4277                     goto illegal_op;
4278                 } else {
4279                     TCGv carry_in, carry_out, zero;
4280                     int end_op;
4281 
4282                     ot = mo_64_32(s->dflag);
4283                     gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4284 
4285                     /* Re-use the carry-out from a previous round.  */
4286                     carry_in = NULL;
4287                     carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);
4288                     switch (s->cc_op) {
4289                     case CC_OP_ADCX:
4290                         if (b == 0x1f6) {
4291                             carry_in = cpu_cc_dst;
4292                             end_op = CC_OP_ADCX;
4293                         } else {
4294                             end_op = CC_OP_ADCOX;
4295                         }
4296                         break;
4297                     case CC_OP_ADOX:
4298                         if (b == 0x1f6) {
4299                             end_op = CC_OP_ADCOX;
4300                         } else {
4301                             carry_in = cpu_cc_src2;
4302                             end_op = CC_OP_ADOX;
4303                         }
4304                         break;
4305                     case CC_OP_ADCOX:
4306                         end_op = CC_OP_ADCOX;
4307                         carry_in = carry_out;
4308                         break;
4309                     default:
4310                         end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX);
4311                         break;
4312                     }
4313                     /* If we can't reuse carry-out, get it out of EFLAGS.  */
4314                     if (!carry_in) {
4315                         if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
4316                             gen_compute_eflags(s);
4317                         }
4318                         carry_in = s->tmp0;
4319                         tcg_gen_extract_tl(carry_in, cpu_cc_src,
4320                                            ctz32(b == 0x1f6 ? CC_C : CC_O), 1);
4321                     }
4322 
4323                     switch (ot) {
4324 #ifdef TARGET_X86_64
4325                     case MO_32:
4326                         /* If we know TL is 64-bit, and we want a 32-bit
4327                            result, just do everything in 64-bit arithmetic.  */
4328                         tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]);
4329                         tcg_gen_ext32u_i64(s->T0, s->T0);
4330                         tcg_gen_add_i64(s->T0, s->T0, cpu_regs[reg]);
4331                         tcg_gen_add_i64(s->T0, s->T0, carry_in);
4332                         tcg_gen_ext32u_i64(cpu_regs[reg], s->T0);
4333                         tcg_gen_shri_i64(carry_out, s->T0, 32);
4334                         break;
4335 #endif
4336                     default:
4337                         /* Otherwise compute the carry-out in two steps.  */
4338                         zero = tcg_const_tl(0);
4339                         tcg_gen_add2_tl(s->T0, carry_out,
4340                                         s->T0, zero,
4341                                         carry_in, zero);
4342                         tcg_gen_add2_tl(cpu_regs[reg], carry_out,
4343                                         cpu_regs[reg], carry_out,
4344                                         s->T0, zero);
4345                         tcg_temp_free(zero);
4346                         break;
4347                     }
4348                     set_cc_op(s, end_op);
4349                 }
4350                 break;
4351 
4352             }
4353             break;
4354 
4355         case 0x03a:
4356         case 0x13a:
4357             b = modrm;
4358             modrm = x86_ldub_code(env, s);
4359             rm = modrm & 7;
4360             reg = ((modrm >> 3) & 7) | REX_R(s);
4361             mod = (modrm >> 6) & 3;
4362 
4363             assert(b1 < 2);
4364             op7 = &sse_op_table7[b];
4365             if (op7->ext_mask == 0) {
4366                 goto unknown_op;
4367             }
4368             if (!(s->cpuid_ext_features & op7->ext_mask)) {
4369                 goto illegal_op;
4370             }
4371 
4372             s->rip_offset = 1;
4373 
4374             if (op7->flags & SSE_OPF_SPECIAL) {
4375                 /* None of the "special" ops are valid on mmx registers */
4376                 if (b1 == 0) {
4377                     goto illegal_op;
4378                 }
4379                 ot = mo_64_32(s->dflag);
4380                 rm = (modrm & 7) | REX_B(s);
4381                 if (mod != 3)
4382                     gen_lea_modrm(env, s, modrm);
4383                 reg = ((modrm >> 3) & 7) | REX_R(s);
4384                 val = x86_ldub_code(env, s);
4385                 switch (b) {
4386                 case 0x14: /* pextrb */
4387                     tcg_gen_ld8u_tl(s->T0, cpu_env, offsetof(CPUX86State,
4388                                             xmm_regs[reg].ZMM_B(val & 15)));
4389                     if (mod == 3) {
4390                         gen_op_mov_reg_v(s, ot, rm, s->T0);
4391                     } else {
4392                         tcg_gen_qemu_st_tl(s->T0, s->A0,
4393                                            s->mem_index, MO_UB);
4394                     }
4395                     break;
4396                 case 0x15: /* pextrw */
4397                     tcg_gen_ld16u_tl(s->T0, cpu_env, offsetof(CPUX86State,
4398                                             xmm_regs[reg].ZMM_W(val & 7)));
4399                     if (mod == 3) {
4400                         gen_op_mov_reg_v(s, ot, rm, s->T0);
4401                     } else {
4402                         tcg_gen_qemu_st_tl(s->T0, s->A0,
4403                                            s->mem_index, MO_LEUW);
4404                     }
4405                     break;
4406                 case 0x16:
4407                     if (ot == MO_32) { /* pextrd */
4408                         tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
4409                                         offsetof(CPUX86State,
4410                                                 xmm_regs[reg].ZMM_L(val & 3)));
4411                         if (mod == 3) {
4412                             tcg_gen_extu_i32_tl(cpu_regs[rm], s->tmp2_i32);
4413                         } else {
4414                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4415                                                 s->mem_index, MO_LEUL);
4416                         }
4417                     } else { /* pextrq */
4418 #ifdef TARGET_X86_64
4419                         tcg_gen_ld_i64(s->tmp1_i64, cpu_env,
4420                                         offsetof(CPUX86State,
4421                                                 xmm_regs[reg].ZMM_Q(val & 1)));
4422                         if (mod == 3) {
4423                             tcg_gen_mov_i64(cpu_regs[rm], s->tmp1_i64);
4424                         } else {
4425                             tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4426                                                 s->mem_index, MO_LEUQ);
4427                         }
4428 #else
4429                         goto illegal_op;
4430 #endif
4431                     }
4432                     break;
4433                 case 0x17: /* extractps */
4434                     tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State,
4435                                             xmm_regs[reg].ZMM_L(val & 3)));
4436                     if (mod == 3) {
4437                         gen_op_mov_reg_v(s, ot, rm, s->T0);
4438                     } else {
4439                         tcg_gen_qemu_st_tl(s->T0, s->A0,
4440                                            s->mem_index, MO_LEUL);
4441                     }
4442                     break;
4443                 case 0x20: /* pinsrb */
4444                     if (mod == 3) {
4445                         gen_op_mov_v_reg(s, MO_32, s->T0, rm);
4446                     } else {
4447                         tcg_gen_qemu_ld_tl(s->T0, s->A0,
4448                                            s->mem_index, MO_UB);
4449                     }
4450                     tcg_gen_st8_tl(s->T0, cpu_env, offsetof(CPUX86State,
4451                                             xmm_regs[reg].ZMM_B(val & 15)));
4452                     break;
4453                 case 0x21: /* insertps */
4454                     if (mod == 3) {
4455                         tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
4456                                         offsetof(CPUX86State,xmm_regs[rm]
4457                                                 .ZMM_L((val >> 6) & 3)));
4458                     } else {
4459                         tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4460                                             s->mem_index, MO_LEUL);
4461                     }
4462                     tcg_gen_st_i32(s->tmp2_i32, cpu_env,
4463                                     offsetof(CPUX86State,xmm_regs[reg]
4464                                             .ZMM_L((val >> 4) & 3)));
4465                     if ((val >> 0) & 1)
4466                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4467                                         cpu_env, offsetof(CPUX86State,
4468                                                 xmm_regs[reg].ZMM_L(0)));
4469                     if ((val >> 1) & 1)
4470                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4471                                         cpu_env, offsetof(CPUX86State,
4472                                                 xmm_regs[reg].ZMM_L(1)));
4473                     if ((val >> 2) & 1)
4474                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4475                                         cpu_env, offsetof(CPUX86State,
4476                                                 xmm_regs[reg].ZMM_L(2)));
4477                     if ((val >> 3) & 1)
4478                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4479                                         cpu_env, offsetof(CPUX86State,
4480                                                 xmm_regs[reg].ZMM_L(3)));
4481                     break;
4482                 case 0x22:
4483                     if (ot == MO_32) { /* pinsrd */
4484                         if (mod == 3) {
4485                             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[rm]);
4486                         } else {
4487                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4488                                                 s->mem_index, MO_LEUL);
4489                         }
4490                         tcg_gen_st_i32(s->tmp2_i32, cpu_env,
4491                                         offsetof(CPUX86State,
4492                                                 xmm_regs[reg].ZMM_L(val & 3)));
4493                     } else { /* pinsrq */
4494 #ifdef TARGET_X86_64
4495                         if (mod == 3) {
4496                             gen_op_mov_v_reg(s, ot, s->tmp1_i64, rm);
4497                         } else {
4498                             tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4499                                                 s->mem_index, MO_LEUQ);
4500                         }
4501                         tcg_gen_st_i64(s->tmp1_i64, cpu_env,
4502                                         offsetof(CPUX86State,
4503                                                 xmm_regs[reg].ZMM_Q(val & 1)));
4504 #else
4505                         goto illegal_op;
4506 #endif
4507                     }
4508                     break;
4509                 }
4510                 return;
4511             }
4512 
4513             if (b1 == 0) {
4514                 CHECK_NO_VEX(s);
4515                 /* MMX */
4516                 if ((op7->flags & SSE_OPF_MMX) == 0) {
4517                     goto illegal_op;
4518                 }
4519                 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4520                 if (mod == 3) {
4521                     op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4522                 } else {
4523                     op2_offset = offsetof(CPUX86State,mmx_t0);
4524                     gen_lea_modrm(env, s, modrm);
4525                     gen_ldq_env_A0(s, op2_offset);
4526                 }
4527                 val = x86_ldub_code(env, s);
4528                 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4529                 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4530 
4531                 /* We only actually have one MMX instuction (palignr) */
4532                 assert(b == 0x0f);
4533 
4534                 op7->fn[0].op2(cpu_env, s->ptr0, s->ptr0, s->ptr1,
4535                                tcg_const_i32(val));
4536                 break;
4537             }
4538 
4539             /* SSE */
4540             op1_offset = ZMM_OFFSET(reg);
4541             if (mod == 3) {
4542                 op2_offset = ZMM_OFFSET(rm | REX_B(s));
4543             } else {
4544                 op2_offset = offsetof(CPUX86State, xmm_t0);
4545                 gen_lea_modrm(env, s, modrm);
4546                 gen_ldo_env_A0(s, op2_offset + offsetof(ZMMReg, ZMM_X(0)), true);
4547             }
4548 
4549             val = x86_ldub_code(env, s);
4550             if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4551                 set_cc_op(s, CC_OP_EFLAGS);
4552 
4553                 if (s->dflag == MO_64) {
4554                     /* The helper must use entire 64-bit gp registers */
4555                     val |= 1 << 8;
4556                 }
4557             }
4558 
4559             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4560             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4561             if (op7->flags & SSE_OPF_V0) {
4562                 op7->fn[b1].op1(cpu_env, s->ptr0, s->ptr1, tcg_const_i32(val));
4563             } else {
4564                 tcg_gen_addi_ptr(s->ptr2, cpu_env, op1_offset);
4565                 op7->fn[b1].op2(cpu_env, s->ptr0, s->ptr2, s->ptr1,
4566                                tcg_const_i32(val));
4567             }
4568             if (op7->flags & SSE_OPF_CMP) {
4569                 set_cc_op(s, CC_OP_EFLAGS);
4570             }
4571             break;
4572 
4573         default:
4574         unknown_op:
4575             gen_unknown_opcode(env, s);
4576             return;
4577         }
4578     } else {
4579         /* generic MMX or SSE operation */
4580         switch(b) {
4581         case 0x70: /* pshufx insn */
4582         case 0xc6: /* pshufx insn */
4583         case 0xc2: /* compare insns */
4584             s->rip_offset = 1;
4585             break;
4586         default:
4587             break;
4588         }
4589         if (is_xmm) {
4590             op1_offset = ZMM_OFFSET(reg);
4591             if (mod != 3) {
4592                 int sz = 4;
4593 
4594                 gen_lea_modrm(env, s, modrm);
4595                 op2_offset = offsetof(CPUX86State, xmm_t0);
4596 
4597                 if (sse_op_flags & SSE_OPF_SCALAR) {
4598                     if (sse_op_flags & SSE_OPF_CMP) {
4599                         /* ucomis[sd], comis[sd] */
4600                         if (b1 == 0) {
4601                             sz = 2;
4602                         } else {
4603                             sz = 3;
4604                         }
4605                     } else {
4606                         /* Most sse scalar operations.  */
4607                         if (b1 == 2) {
4608                             sz = 2;
4609                         } else if (b1 == 3) {
4610                             sz = 3;
4611                         }
4612                     }
4613                 }
4614 
4615                 switch (sz) {
4616                 case 2:
4617                     /* 32 bit access */
4618                     gen_op_ld_v(s, MO_32, s->T0, s->A0);
4619                     tcg_gen_st32_tl(s->T0, cpu_env,
4620                                     offsetof(CPUX86State, xmm_t0.ZMM_L(0)));
4621                     break;
4622                 case 3:
4623                     /* 64 bit access */
4624                     gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0)));
4625                     break;
4626                 default:
4627                     /* 128 bit access */
4628                     gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_X(0)), true);
4629                     break;
4630                 }
4631             } else {
4632                 rm = (modrm & 7) | REX_B(s);
4633                 op2_offset = ZMM_OFFSET(rm);
4634             }
4635         } else {
4636             CHECK_NO_VEX(s);
4637             op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4638             if (mod != 3) {
4639                 gen_lea_modrm(env, s, modrm);
4640                 op2_offset = offsetof(CPUX86State,mmx_t0);
4641                 gen_ldq_env_A0(s, op2_offset);
4642             } else {
4643                 rm = (modrm & 7);
4644                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4645             }
4646             if (sse_op_flags & SSE_OPF_3DNOW) {
4647                 /* 3DNow! data insns */
4648                 val = x86_ldub_code(env, s);
4649                 SSEFunc_0_epp op_3dnow = sse_op_table5[val];
4650                 if (!op_3dnow) {
4651                     goto unknown_op;
4652                 }
4653                 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4654                 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4655                 op_3dnow(cpu_env, s->ptr0, s->ptr1);
4656                 return;
4657             }
4658         }
4659 
4660 
4661         tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4662         tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4663         if ((sse_op_flags & SSE_OPF_V0) &&
4664             !((sse_op_flags & SSE_OPF_SCALAR) && b1 >= 2)) {
4665             if (sse_op_flags & SSE_OPF_SHUF) {
4666                 val = x86_ldub_code(env, s);
4667                 sse_op_fn.op1i(s->ptr0, s->ptr1, tcg_const_i32(val));
4668             } else if (b == 0xf7) {
4669                 /* maskmov : we must prepare A0 */
4670                 if (mod != 3) {
4671                     goto illegal_op;
4672                 }
4673                 tcg_gen_mov_tl(s->A0, cpu_regs[R_EDI]);
4674                 gen_extu(s->aflag, s->A0);
4675                 gen_add_A0_ds_seg(s);
4676 
4677                 tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4678                 tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4679                 sse_op_fn.op1t(cpu_env, s->ptr0, s->ptr1, s->A0);
4680                 /* Does not write to the fist operand */
4681                 return;
4682             } else {
4683                 sse_op_fn.op1(cpu_env, s->ptr0, s->ptr1);
4684             }
4685         } else {
4686             tcg_gen_addi_ptr(s->ptr2, cpu_env, op1_offset);
4687             if (sse_op_flags & SSE_OPF_SHUF) {
4688                 val = x86_ldub_code(env, s);
4689                 sse_op_fn.op2i(s->ptr0, s->ptr2, s->ptr1,
4690                                    tcg_const_i32(val));
4691             } else {
4692                 SSEFunc_0_eppp fn = sse_op_fn.op2;
4693                 if (b == 0xc2) {
4694                     /* compare insns */
4695                     val = x86_ldub_code(env, s) & 7;
4696                     fn = sse_op_table4[val][b1];
4697                 }
4698                 fn(cpu_env, s->ptr0, s->ptr2, s->ptr1);
4699             }
4700         }
4701 
4702         if (sse_op_flags & SSE_OPF_CMP) {
4703             set_cc_op(s, CC_OP_EFLAGS);
4704         }
4705     }
4706 }
4707 
4708 /* convert one instruction. s->base.is_jmp is set if the translation must
4709    be stopped. Return the next pc value */
4710 static bool disas_insn(DisasContext *s, CPUState *cpu)
4711 {
4712     CPUX86State *env = cpu->env_ptr;
4713     int b, prefixes;
4714     int shift;
4715     MemOp ot, aflag, dflag;
4716     int modrm, reg, rm, mod, op, opreg, val;
4717     bool orig_cc_op_dirty = s->cc_op_dirty;
4718     CCOp orig_cc_op = s->cc_op;
4719     target_ulong orig_pc_save = s->pc_save;
4720 
4721     s->pc = s->base.pc_next;
4722     s->override = -1;
4723 #ifdef TARGET_X86_64
4724     s->rex_r = 0;
4725     s->rex_x = 0;
4726     s->rex_b = 0;
4727 #endif
4728     s->rip_offset = 0; /* for relative ip address */
4729     s->vex_l = 0;
4730     s->vex_v = 0;
4731     s->vex_w = false;
4732     switch (sigsetjmp(s->jmpbuf, 0)) {
4733     case 0:
4734         break;
4735     case 1:
4736         gen_exception_gpf(s);
4737         return true;
4738     case 2:
4739         /* Restore state that may affect the next instruction. */
4740         s->pc = s->base.pc_next;
4741         /*
4742          * TODO: These save/restore can be removed after the table-based
4743          * decoder is complete; we will be decoding the insn completely
4744          * before any code generation that might affect these variables.
4745          */
4746         s->cc_op_dirty = orig_cc_op_dirty;
4747         s->cc_op = orig_cc_op;
4748         s->pc_save = orig_pc_save;
4749         /* END TODO */
4750         s->base.num_insns--;
4751         tcg_remove_ops_after(s->prev_insn_end);
4752         s->base.is_jmp = DISAS_TOO_MANY;
4753         return false;
4754     default:
4755         g_assert_not_reached();
4756     }
4757 
4758     prefixes = 0;
4759 
4760     if (first) first = false, limit = getenv("LIMIT") ? atol(getenv("LIMIT")) : -1;
4761     bool use_new = true;
4762 #ifdef CONFIG_USER_ONLY
4763     use_new &= limit > 0;
4764 #endif
4765  next_byte:
4766     s->prefix = prefixes;
4767     b = x86_ldub_code(env, s);
4768     /* Collect prefixes.  */
4769     switch (b) {
4770     default:
4771 #ifndef CONFIG_USER_ONLY
4772         use_new &= b <= limit;
4773 #endif
4774         if (use_new && 0) {
4775             disas_insn_new(s, cpu, b);
4776             return s->pc;
4777         }
4778         break;
4779     case 0x0f:
4780         b = x86_ldub_code(env, s) + 0x100;
4781 #ifndef CONFIG_USER_ONLY
4782         use_new &= b <= limit;
4783 #endif
4784         if (use_new &&
4785             ((b >= 0x150 && b <= 0x17f) ||
4786              (b >= 0x1d0 && b <= 0x1ff))) {
4787             disas_insn_new(s, cpu, b + 0x100);
4788             return s->pc;
4789         }
4790         break;
4791     case 0xf3:
4792         prefixes |= PREFIX_REPZ;
4793         prefixes &= ~PREFIX_REPNZ;
4794         goto next_byte;
4795     case 0xf2:
4796         prefixes |= PREFIX_REPNZ;
4797         prefixes &= ~PREFIX_REPZ;
4798         goto next_byte;
4799     case 0xf0:
4800         prefixes |= PREFIX_LOCK;
4801         goto next_byte;
4802     case 0x2e:
4803         s->override = R_CS;
4804         goto next_byte;
4805     case 0x36:
4806         s->override = R_SS;
4807         goto next_byte;
4808     case 0x3e:
4809         s->override = R_DS;
4810         goto next_byte;
4811     case 0x26:
4812         s->override = R_ES;
4813         goto next_byte;
4814     case 0x64:
4815         s->override = R_FS;
4816         goto next_byte;
4817     case 0x65:
4818         s->override = R_GS;
4819         goto next_byte;
4820     case 0x66:
4821         prefixes |= PREFIX_DATA;
4822         goto next_byte;
4823     case 0x67:
4824         prefixes |= PREFIX_ADR;
4825         goto next_byte;
4826 #ifdef TARGET_X86_64
4827     case 0x40 ... 0x4f:
4828         if (CODE64(s)) {
4829             /* REX prefix */
4830             prefixes |= PREFIX_REX;
4831             s->vex_w = (b >> 3) & 1;
4832             s->rex_r = (b & 0x4) << 1;
4833             s->rex_x = (b & 0x2) << 2;
4834             s->rex_b = (b & 0x1) << 3;
4835             goto next_byte;
4836         }
4837         break;
4838 #endif
4839     case 0xc5: /* 2-byte VEX */
4840     case 0xc4: /* 3-byte VEX */
4841         if (CODE32(s) && !VM86(s)) {
4842             int vex2 = x86_ldub_code(env, s);
4843             s->pc--; /* rewind the advance_pc() x86_ldub_code() did */
4844 
4845             if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4846                 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4847                    otherwise the instruction is LES or LDS.  */
4848                 break;
4849             }
4850             disas_insn_new(s, cpu, b);
4851             return s->pc;
4852         }
4853         break;
4854     }
4855 
4856     /* Post-process prefixes.  */
4857     if (CODE64(s)) {
4858         /* In 64-bit mode, the default data size is 32-bit.  Select 64-bit
4859            data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4860            over 0x66 if both are present.  */
4861         dflag = (REX_W(s) ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
4862         /* In 64-bit mode, 0x67 selects 32-bit addressing.  */
4863         aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
4864     } else {
4865         /* In 16/32-bit mode, 0x66 selects the opposite data size.  */
4866         if (CODE32(s) ^ ((prefixes & PREFIX_DATA) != 0)) {
4867             dflag = MO_32;
4868         } else {
4869             dflag = MO_16;
4870         }
4871         /* In 16/32-bit mode, 0x67 selects the opposite addressing.  */
4872         if (CODE32(s) ^ ((prefixes & PREFIX_ADR) != 0)) {
4873             aflag = MO_32;
4874         }  else {
4875             aflag = MO_16;
4876         }
4877     }
4878 
4879     s->prefix = prefixes;
4880     s->aflag = aflag;
4881     s->dflag = dflag;
4882 
4883     /* now check op code */
4884     switch (b) {
4885         /**************************/
4886         /* arith & logic */
4887     case 0x00 ... 0x05:
4888     case 0x08 ... 0x0d:
4889     case 0x10 ... 0x15:
4890     case 0x18 ... 0x1d:
4891     case 0x20 ... 0x25:
4892     case 0x28 ... 0x2d:
4893     case 0x30 ... 0x35:
4894     case 0x38 ... 0x3d:
4895         {
4896             int op, f, val;
4897             op = (b >> 3) & 7;
4898             f = (b >> 1) & 3;
4899 
4900             ot = mo_b_d(b, dflag);
4901 
4902             switch(f) {
4903             case 0: /* OP Ev, Gv */
4904                 modrm = x86_ldub_code(env, s);
4905                 reg = ((modrm >> 3) & 7) | REX_R(s);
4906                 mod = (modrm >> 6) & 3;
4907                 rm = (modrm & 7) | REX_B(s);
4908                 if (mod != 3) {
4909                     gen_lea_modrm(env, s, modrm);
4910                     opreg = OR_TMP0;
4911                 } else if (op == OP_XORL && rm == reg) {
4912                 xor_zero:
4913                     /* xor reg, reg optimisation */
4914                     set_cc_op(s, CC_OP_CLR);
4915                     tcg_gen_movi_tl(s->T0, 0);
4916                     gen_op_mov_reg_v(s, ot, reg, s->T0);
4917                     break;
4918                 } else {
4919                     opreg = rm;
4920                 }
4921                 gen_op_mov_v_reg(s, ot, s->T1, reg);
4922                 gen_op(s, op, ot, opreg);
4923                 break;
4924             case 1: /* OP Gv, Ev */
4925                 modrm = x86_ldub_code(env, s);
4926                 mod = (modrm >> 6) & 3;
4927                 reg = ((modrm >> 3) & 7) | REX_R(s);
4928                 rm = (modrm & 7) | REX_B(s);
4929                 if (mod != 3) {
4930                     gen_lea_modrm(env, s, modrm);
4931                     gen_op_ld_v(s, ot, s->T1, s->A0);
4932                 } else if (op == OP_XORL && rm == reg) {
4933                     goto xor_zero;
4934                 } else {
4935                     gen_op_mov_v_reg(s, ot, s->T1, rm);
4936                 }
4937                 gen_op(s, op, ot, reg);
4938                 break;
4939             case 2: /* OP A, Iv */
4940                 val = insn_get(env, s, ot);
4941                 tcg_gen_movi_tl(s->T1, val);
4942                 gen_op(s, op, ot, OR_EAX);
4943                 break;
4944             }
4945         }
4946         break;
4947 
4948     case 0x82:
4949         if (CODE64(s))
4950             goto illegal_op;
4951         /* fall through */
4952     case 0x80: /* GRP1 */
4953     case 0x81:
4954     case 0x83:
4955         {
4956             int val;
4957 
4958             ot = mo_b_d(b, dflag);
4959 
4960             modrm = x86_ldub_code(env, s);
4961             mod = (modrm >> 6) & 3;
4962             rm = (modrm & 7) | REX_B(s);
4963             op = (modrm >> 3) & 7;
4964 
4965             if (mod != 3) {
4966                 if (b == 0x83)
4967                     s->rip_offset = 1;
4968                 else
4969                     s->rip_offset = insn_const_size(ot);
4970                 gen_lea_modrm(env, s, modrm);
4971                 opreg = OR_TMP0;
4972             } else {
4973                 opreg = rm;
4974             }
4975 
4976             switch(b) {
4977             default:
4978             case 0x80:
4979             case 0x81:
4980             case 0x82:
4981                 val = insn_get(env, s, ot);
4982                 break;
4983             case 0x83:
4984                 val = (int8_t)insn_get(env, s, MO_8);
4985                 break;
4986             }
4987             tcg_gen_movi_tl(s->T1, val);
4988             gen_op(s, op, ot, opreg);
4989         }
4990         break;
4991 
4992         /**************************/
4993         /* inc, dec, and other misc arith */
4994     case 0x40 ... 0x47: /* inc Gv */
4995         ot = dflag;
4996         gen_inc(s, ot, OR_EAX + (b & 7), 1);
4997         break;
4998     case 0x48 ... 0x4f: /* dec Gv */
4999         ot = dflag;
5000         gen_inc(s, ot, OR_EAX + (b & 7), -1);
5001         break;
5002     case 0xf6: /* GRP3 */
5003     case 0xf7:
5004         ot = mo_b_d(b, dflag);
5005 
5006         modrm = x86_ldub_code(env, s);
5007         mod = (modrm >> 6) & 3;
5008         rm = (modrm & 7) | REX_B(s);
5009         op = (modrm >> 3) & 7;
5010         if (mod != 3) {
5011             if (op == 0) {
5012                 s->rip_offset = insn_const_size(ot);
5013             }
5014             gen_lea_modrm(env, s, modrm);
5015             /* For those below that handle locked memory, don't load here.  */
5016             if (!(s->prefix & PREFIX_LOCK)
5017                 || op != 2) {
5018                 gen_op_ld_v(s, ot, s->T0, s->A0);
5019             }
5020         } else {
5021             gen_op_mov_v_reg(s, ot, s->T0, rm);
5022         }
5023 
5024         switch(op) {
5025         case 0: /* test */
5026             val = insn_get(env, s, ot);
5027             tcg_gen_movi_tl(s->T1, val);
5028             gen_op_testl_T0_T1_cc(s);
5029             set_cc_op(s, CC_OP_LOGICB + ot);
5030             break;
5031         case 2: /* not */
5032             if (s->prefix & PREFIX_LOCK) {
5033                 if (mod == 3) {
5034                     goto illegal_op;
5035                 }
5036                 tcg_gen_movi_tl(s->T0, ~0);
5037                 tcg_gen_atomic_xor_fetch_tl(s->T0, s->A0, s->T0,
5038                                             s->mem_index, ot | MO_LE);
5039             } else {
5040                 tcg_gen_not_tl(s->T0, s->T0);
5041                 if (mod != 3) {
5042                     gen_op_st_v(s, ot, s->T0, s->A0);
5043                 } else {
5044                     gen_op_mov_reg_v(s, ot, rm, s->T0);
5045                 }
5046             }
5047             break;
5048         case 3: /* neg */
5049             if (s->prefix & PREFIX_LOCK) {
5050                 TCGLabel *label1;
5051                 TCGv a0, t0, t1, t2;
5052 
5053                 if (mod == 3) {
5054                     goto illegal_op;
5055                 }
5056                 a0 = tcg_temp_local_new();
5057                 t0 = tcg_temp_local_new();
5058                 label1 = gen_new_label();
5059 
5060                 tcg_gen_mov_tl(a0, s->A0);
5061                 tcg_gen_mov_tl(t0, s->T0);
5062 
5063                 gen_set_label(label1);
5064                 t1 = tcg_temp_new();
5065                 t2 = tcg_temp_new();
5066                 tcg_gen_mov_tl(t2, t0);
5067                 tcg_gen_neg_tl(t1, t0);
5068                 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
5069                                           s->mem_index, ot | MO_LE);
5070                 tcg_temp_free(t1);
5071                 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
5072 
5073                 tcg_temp_free(t2);
5074                 tcg_temp_free(a0);
5075                 tcg_gen_mov_tl(s->T0, t0);
5076                 tcg_temp_free(t0);
5077             } else {
5078                 tcg_gen_neg_tl(s->T0, s->T0);
5079                 if (mod != 3) {
5080                     gen_op_st_v(s, ot, s->T0, s->A0);
5081                 } else {
5082                     gen_op_mov_reg_v(s, ot, rm, s->T0);
5083                 }
5084             }
5085             gen_op_update_neg_cc(s);
5086             set_cc_op(s, CC_OP_SUBB + ot);
5087             break;
5088         case 4: /* mul */
5089             switch(ot) {
5090             case MO_8:
5091                 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX);
5092                 tcg_gen_ext8u_tl(s->T0, s->T0);
5093                 tcg_gen_ext8u_tl(s->T1, s->T1);
5094                 /* XXX: use 32 bit mul which could be faster */
5095                 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
5096                 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
5097                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
5098                 tcg_gen_andi_tl(cpu_cc_src, s->T0, 0xff00);
5099                 set_cc_op(s, CC_OP_MULB);
5100                 break;
5101             case MO_16:
5102                 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX);
5103                 tcg_gen_ext16u_tl(s->T0, s->T0);
5104                 tcg_gen_ext16u_tl(s->T1, s->T1);
5105                 /* XXX: use 32 bit mul which could be faster */
5106                 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
5107                 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
5108                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
5109                 tcg_gen_shri_tl(s->T0, s->T0, 16);
5110                 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
5111                 tcg_gen_mov_tl(cpu_cc_src, s->T0);
5112                 set_cc_op(s, CC_OP_MULW);
5113                 break;
5114             default:
5115             case MO_32:
5116                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5117                 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]);
5118                 tcg_gen_mulu2_i32(s->tmp2_i32, s->tmp3_i32,
5119                                   s->tmp2_i32, s->tmp3_i32);
5120                 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32);
5121                 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32);
5122                 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
5123                 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
5124                 set_cc_op(s, CC_OP_MULL);
5125                 break;
5126 #ifdef TARGET_X86_64
5127             case MO_64:
5128                 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
5129                                   s->T0, cpu_regs[R_EAX]);
5130                 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
5131                 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
5132                 set_cc_op(s, CC_OP_MULQ);
5133                 break;
5134 #endif
5135             }
5136             break;
5137         case 5: /* imul */
5138             switch(ot) {
5139             case MO_8:
5140                 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX);
5141                 tcg_gen_ext8s_tl(s->T0, s->T0);
5142                 tcg_gen_ext8s_tl(s->T1, s->T1);
5143                 /* XXX: use 32 bit mul which could be faster */
5144                 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
5145                 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
5146                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
5147                 tcg_gen_ext8s_tl(s->tmp0, s->T0);
5148                 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
5149                 set_cc_op(s, CC_OP_MULB);
5150                 break;
5151             case MO_16:
5152                 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX);
5153                 tcg_gen_ext16s_tl(s->T0, s->T0);
5154                 tcg_gen_ext16s_tl(s->T1, s->T1);
5155                 /* XXX: use 32 bit mul which could be faster */
5156                 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
5157                 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
5158                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
5159                 tcg_gen_ext16s_tl(s->tmp0, s->T0);
5160                 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
5161                 tcg_gen_shri_tl(s->T0, s->T0, 16);
5162                 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
5163                 set_cc_op(s, CC_OP_MULW);
5164                 break;
5165             default:
5166             case MO_32:
5167                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5168                 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]);
5169                 tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32,
5170                                   s->tmp2_i32, s->tmp3_i32);
5171                 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32);
5172                 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32);
5173                 tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31);
5174                 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
5175                 tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
5176                 tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32);
5177                 set_cc_op(s, CC_OP_MULL);
5178                 break;
5179 #ifdef TARGET_X86_64
5180             case MO_64:
5181                 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
5182                                   s->T0, cpu_regs[R_EAX]);
5183                 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
5184                 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
5185                 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
5186                 set_cc_op(s, CC_OP_MULQ);
5187                 break;
5188 #endif
5189             }
5190             break;
5191         case 6: /* div */
5192             switch(ot) {
5193             case MO_8:
5194                 gen_helper_divb_AL(cpu_env, s->T0);
5195                 break;
5196             case MO_16:
5197                 gen_helper_divw_AX(cpu_env, s->T0);
5198                 break;
5199             default:
5200             case MO_32:
5201                 gen_helper_divl_EAX(cpu_env, s->T0);
5202                 break;
5203 #ifdef TARGET_X86_64
5204             case MO_64:
5205                 gen_helper_divq_EAX(cpu_env, s->T0);
5206                 break;
5207 #endif
5208             }
5209             break;
5210         case 7: /* idiv */
5211             switch(ot) {
5212             case MO_8:
5213                 gen_helper_idivb_AL(cpu_env, s->T0);
5214                 break;
5215             case MO_16:
5216                 gen_helper_idivw_AX(cpu_env, s->T0);
5217                 break;
5218             default:
5219             case MO_32:
5220                 gen_helper_idivl_EAX(cpu_env, s->T0);
5221                 break;
5222 #ifdef TARGET_X86_64
5223             case MO_64:
5224                 gen_helper_idivq_EAX(cpu_env, s->T0);
5225                 break;
5226 #endif
5227             }
5228             break;
5229         default:
5230             goto unknown_op;
5231         }
5232         break;
5233 
5234     case 0xfe: /* GRP4 */
5235     case 0xff: /* GRP5 */
5236         ot = mo_b_d(b, dflag);
5237 
5238         modrm = x86_ldub_code(env, s);
5239         mod = (modrm >> 6) & 3;
5240         rm = (modrm & 7) | REX_B(s);
5241         op = (modrm >> 3) & 7;
5242         if (op >= 2 && b == 0xfe) {
5243             goto unknown_op;
5244         }
5245         if (CODE64(s)) {
5246             if (op == 2 || op == 4) {
5247                 /* operand size for jumps is 64 bit */
5248                 ot = MO_64;
5249             } else if (op == 3 || op == 5) {
5250                 ot = dflag != MO_16 ? MO_32 + REX_W(s) : MO_16;
5251             } else if (op == 6) {
5252                 /* default push size is 64 bit */
5253                 ot = mo_pushpop(s, dflag);
5254             }
5255         }
5256         if (mod != 3) {
5257             gen_lea_modrm(env, s, modrm);
5258             if (op >= 2 && op != 3 && op != 5)
5259                 gen_op_ld_v(s, ot, s->T0, s->A0);
5260         } else {
5261             gen_op_mov_v_reg(s, ot, s->T0, rm);
5262         }
5263 
5264         switch(op) {
5265         case 0: /* inc Ev */
5266             if (mod != 3)
5267                 opreg = OR_TMP0;
5268             else
5269                 opreg = rm;
5270             gen_inc(s, ot, opreg, 1);
5271             break;
5272         case 1: /* dec Ev */
5273             if (mod != 3)
5274                 opreg = OR_TMP0;
5275             else
5276                 opreg = rm;
5277             gen_inc(s, ot, opreg, -1);
5278             break;
5279         case 2: /* call Ev */
5280             /* XXX: optimize if memory (no 'and' is necessary) */
5281             if (dflag == MO_16) {
5282                 tcg_gen_ext16u_tl(s->T0, s->T0);
5283             }
5284             gen_push_v(s, eip_next_tl(s));
5285             gen_op_jmp_v(s, s->T0);
5286             gen_bnd_jmp(s);
5287             s->base.is_jmp = DISAS_JUMP;
5288             break;
5289         case 3: /* lcall Ev */
5290             if (mod == 3) {
5291                 goto illegal_op;
5292             }
5293             gen_op_ld_v(s, ot, s->T1, s->A0);
5294             gen_add_A0_im(s, 1 << ot);
5295             gen_op_ld_v(s, MO_16, s->T0, s->A0);
5296         do_lcall:
5297             if (PE(s) && !VM86(s)) {
5298                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5299                 gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1,
5300                                            tcg_constant_i32(dflag - 1),
5301                                            eip_next_tl(s));
5302             } else {
5303                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5304                 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
5305                 gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32,
5306                                       tcg_constant_i32(dflag - 1),
5307                                       eip_next_i32(s));
5308             }
5309             s->base.is_jmp = DISAS_JUMP;
5310             break;
5311         case 4: /* jmp Ev */
5312             if (dflag == MO_16) {
5313                 tcg_gen_ext16u_tl(s->T0, s->T0);
5314             }
5315             gen_op_jmp_v(s, s->T0);
5316             gen_bnd_jmp(s);
5317             s->base.is_jmp = DISAS_JUMP;
5318             break;
5319         case 5: /* ljmp Ev */
5320             if (mod == 3) {
5321                 goto illegal_op;
5322             }
5323             gen_op_ld_v(s, ot, s->T1, s->A0);
5324             gen_add_A0_im(s, 1 << ot);
5325             gen_op_ld_v(s, MO_16, s->T0, s->A0);
5326         do_ljmp:
5327             if (PE(s) && !VM86(s)) {
5328                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5329                 gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1,
5330                                           eip_next_tl(s));
5331             } else {
5332                 gen_op_movl_seg_T0_vm(s, R_CS);
5333                 gen_op_jmp_v(s, s->T1);
5334             }
5335             s->base.is_jmp = DISAS_JUMP;
5336             break;
5337         case 6: /* push Ev */
5338             gen_push_v(s, s->T0);
5339             break;
5340         default:
5341             goto unknown_op;
5342         }
5343         break;
5344 
5345     case 0x84: /* test Ev, Gv */
5346     case 0x85:
5347         ot = mo_b_d(b, dflag);
5348 
5349         modrm = x86_ldub_code(env, s);
5350         reg = ((modrm >> 3) & 7) | REX_R(s);
5351 
5352         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5353         gen_op_mov_v_reg(s, ot, s->T1, reg);
5354         gen_op_testl_T0_T1_cc(s);
5355         set_cc_op(s, CC_OP_LOGICB + ot);
5356         break;
5357 
5358     case 0xa8: /* test eAX, Iv */
5359     case 0xa9:
5360         ot = mo_b_d(b, dflag);
5361         val = insn_get(env, s, ot);
5362 
5363         gen_op_mov_v_reg(s, ot, s->T0, OR_EAX);
5364         tcg_gen_movi_tl(s->T1, val);
5365         gen_op_testl_T0_T1_cc(s);
5366         set_cc_op(s, CC_OP_LOGICB + ot);
5367         break;
5368 
5369     case 0x98: /* CWDE/CBW */
5370         switch (dflag) {
5371 #ifdef TARGET_X86_64
5372         case MO_64:
5373             gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
5374             tcg_gen_ext32s_tl(s->T0, s->T0);
5375             gen_op_mov_reg_v(s, MO_64, R_EAX, s->T0);
5376             break;
5377 #endif
5378         case MO_32:
5379             gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX);
5380             tcg_gen_ext16s_tl(s->T0, s->T0);
5381             gen_op_mov_reg_v(s, MO_32, R_EAX, s->T0);
5382             break;
5383         case MO_16:
5384             gen_op_mov_v_reg(s, MO_8, s->T0, R_EAX);
5385             tcg_gen_ext8s_tl(s->T0, s->T0);
5386             gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
5387             break;
5388         default:
5389             tcg_abort();
5390         }
5391         break;
5392     case 0x99: /* CDQ/CWD */
5393         switch (dflag) {
5394 #ifdef TARGET_X86_64
5395         case MO_64:
5396             gen_op_mov_v_reg(s, MO_64, s->T0, R_EAX);
5397             tcg_gen_sari_tl(s->T0, s->T0, 63);
5398             gen_op_mov_reg_v(s, MO_64, R_EDX, s->T0);
5399             break;
5400 #endif
5401         case MO_32:
5402             gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
5403             tcg_gen_ext32s_tl(s->T0, s->T0);
5404             tcg_gen_sari_tl(s->T0, s->T0, 31);
5405             gen_op_mov_reg_v(s, MO_32, R_EDX, s->T0);
5406             break;
5407         case MO_16:
5408             gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX);
5409             tcg_gen_ext16s_tl(s->T0, s->T0);
5410             tcg_gen_sari_tl(s->T0, s->T0, 15);
5411             gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
5412             break;
5413         default:
5414             tcg_abort();
5415         }
5416         break;
5417     case 0x1af: /* imul Gv, Ev */
5418     case 0x69: /* imul Gv, Ev, I */
5419     case 0x6b:
5420         ot = dflag;
5421         modrm = x86_ldub_code(env, s);
5422         reg = ((modrm >> 3) & 7) | REX_R(s);
5423         if (b == 0x69)
5424             s->rip_offset = insn_const_size(ot);
5425         else if (b == 0x6b)
5426             s->rip_offset = 1;
5427         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5428         if (b == 0x69) {
5429             val = insn_get(env, s, ot);
5430             tcg_gen_movi_tl(s->T1, val);
5431         } else if (b == 0x6b) {
5432             val = (int8_t)insn_get(env, s, MO_8);
5433             tcg_gen_movi_tl(s->T1, val);
5434         } else {
5435             gen_op_mov_v_reg(s, ot, s->T1, reg);
5436         }
5437         switch (ot) {
5438 #ifdef TARGET_X86_64
5439         case MO_64:
5440             tcg_gen_muls2_i64(cpu_regs[reg], s->T1, s->T0, s->T1);
5441             tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5442             tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
5443             tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, s->T1);
5444             break;
5445 #endif
5446         case MO_32:
5447             tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5448             tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
5449             tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32,
5450                               s->tmp2_i32, s->tmp3_i32);
5451             tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
5452             tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31);
5453             tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5454             tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
5455             tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32);
5456             break;
5457         default:
5458             tcg_gen_ext16s_tl(s->T0, s->T0);
5459             tcg_gen_ext16s_tl(s->T1, s->T1);
5460             /* XXX: use 32 bit mul which could be faster */
5461             tcg_gen_mul_tl(s->T0, s->T0, s->T1);
5462             tcg_gen_mov_tl(cpu_cc_dst, s->T0);
5463             tcg_gen_ext16s_tl(s->tmp0, s->T0);
5464             tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
5465             gen_op_mov_reg_v(s, ot, reg, s->T0);
5466             break;
5467         }
5468         set_cc_op(s, CC_OP_MULB + ot);
5469         break;
5470     case 0x1c0:
5471     case 0x1c1: /* xadd Ev, Gv */
5472         ot = mo_b_d(b, dflag);
5473         modrm = x86_ldub_code(env, s);
5474         reg = ((modrm >> 3) & 7) | REX_R(s);
5475         mod = (modrm >> 6) & 3;
5476         gen_op_mov_v_reg(s, ot, s->T0, reg);
5477         if (mod == 3) {
5478             rm = (modrm & 7) | REX_B(s);
5479             gen_op_mov_v_reg(s, ot, s->T1, rm);
5480             tcg_gen_add_tl(s->T0, s->T0, s->T1);
5481             gen_op_mov_reg_v(s, ot, reg, s->T1);
5482             gen_op_mov_reg_v(s, ot, rm, s->T0);
5483         } else {
5484             gen_lea_modrm(env, s, modrm);
5485             if (s->prefix & PREFIX_LOCK) {
5486                 tcg_gen_atomic_fetch_add_tl(s->T1, s->A0, s->T0,
5487                                             s->mem_index, ot | MO_LE);
5488                 tcg_gen_add_tl(s->T0, s->T0, s->T1);
5489             } else {
5490                 gen_op_ld_v(s, ot, s->T1, s->A0);
5491                 tcg_gen_add_tl(s->T0, s->T0, s->T1);
5492                 gen_op_st_v(s, ot, s->T0, s->A0);
5493             }
5494             gen_op_mov_reg_v(s, ot, reg, s->T1);
5495         }
5496         gen_op_update2_cc(s);
5497         set_cc_op(s, CC_OP_ADDB + ot);
5498         break;
5499     case 0x1b0:
5500     case 0x1b1: /* cmpxchg Ev, Gv */
5501         {
5502             TCGv oldv, newv, cmpv;
5503 
5504             ot = mo_b_d(b, dflag);
5505             modrm = x86_ldub_code(env, s);
5506             reg = ((modrm >> 3) & 7) | REX_R(s);
5507             mod = (modrm >> 6) & 3;
5508             oldv = tcg_temp_new();
5509             newv = tcg_temp_new();
5510             cmpv = tcg_temp_new();
5511             gen_op_mov_v_reg(s, ot, newv, reg);
5512             tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]);
5513 
5514             if (s->prefix & PREFIX_LOCK) {
5515                 if (mod == 3) {
5516                     goto illegal_op;
5517                 }
5518                 gen_lea_modrm(env, s, modrm);
5519                 tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, cmpv, newv,
5520                                           s->mem_index, ot | MO_LE);
5521                 gen_op_mov_reg_v(s, ot, R_EAX, oldv);
5522             } else {
5523                 if (mod == 3) {
5524                     rm = (modrm & 7) | REX_B(s);
5525                     gen_op_mov_v_reg(s, ot, oldv, rm);
5526                 } else {
5527                     gen_lea_modrm(env, s, modrm);
5528                     gen_op_ld_v(s, ot, oldv, s->A0);
5529                     rm = 0; /* avoid warning */
5530                 }
5531                 gen_extu(ot, oldv);
5532                 gen_extu(ot, cmpv);
5533                 /* store value = (old == cmp ? new : old);  */
5534                 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv);
5535                 if (mod == 3) {
5536                     gen_op_mov_reg_v(s, ot, R_EAX, oldv);
5537                     gen_op_mov_reg_v(s, ot, rm, newv);
5538                 } else {
5539                     /* Perform an unconditional store cycle like physical cpu;
5540                        must be before changing accumulator to ensure
5541                        idempotency if the store faults and the instruction
5542                        is restarted */
5543                     gen_op_st_v(s, ot, newv, s->A0);
5544                     gen_op_mov_reg_v(s, ot, R_EAX, oldv);
5545                 }
5546             }
5547             tcg_gen_mov_tl(cpu_cc_src, oldv);
5548             tcg_gen_mov_tl(s->cc_srcT, cmpv);
5549             tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv);
5550             set_cc_op(s, CC_OP_SUBB + ot);
5551             tcg_temp_free(oldv);
5552             tcg_temp_free(newv);
5553             tcg_temp_free(cmpv);
5554         }
5555         break;
5556     case 0x1c7: /* cmpxchg8b */
5557         modrm = x86_ldub_code(env, s);
5558         mod = (modrm >> 6) & 3;
5559         switch ((modrm >> 3) & 7) {
5560         case 1: /* CMPXCHG8, CMPXCHG16 */
5561             if (mod == 3) {
5562                 goto illegal_op;
5563             }
5564 #ifdef TARGET_X86_64
5565             if (dflag == MO_64) {
5566                 if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) {
5567                     goto illegal_op;
5568                 }
5569                 gen_lea_modrm(env, s, modrm);
5570                 if ((s->prefix & PREFIX_LOCK) &&
5571                     (tb_cflags(s->base.tb) & CF_PARALLEL)) {
5572                     gen_helper_cmpxchg16b(cpu_env, s->A0);
5573                 } else {
5574                     gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0);
5575                 }
5576                 set_cc_op(s, CC_OP_EFLAGS);
5577                 break;
5578             }
5579 #endif
5580             if (!(s->cpuid_features & CPUID_CX8)) {
5581                 goto illegal_op;
5582             }
5583             gen_lea_modrm(env, s, modrm);
5584             if ((s->prefix & PREFIX_LOCK) &&
5585                 (tb_cflags(s->base.tb) & CF_PARALLEL)) {
5586                 gen_helper_cmpxchg8b(cpu_env, s->A0);
5587             } else {
5588                 gen_helper_cmpxchg8b_unlocked(cpu_env, s->A0);
5589             }
5590             set_cc_op(s, CC_OP_EFLAGS);
5591             break;
5592 
5593         case 7: /* RDSEED */
5594         case 6: /* RDRAND */
5595             if (mod != 3 ||
5596                 (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) ||
5597                 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) {
5598                 goto illegal_op;
5599             }
5600             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
5601                 gen_io_start();
5602                 s->base.is_jmp = DISAS_TOO_MANY;
5603             }
5604             gen_helper_rdrand(s->T0, cpu_env);
5605             rm = (modrm & 7) | REX_B(s);
5606             gen_op_mov_reg_v(s, dflag, rm, s->T0);
5607             set_cc_op(s, CC_OP_EFLAGS);
5608             break;
5609 
5610         default:
5611             goto illegal_op;
5612         }
5613         break;
5614 
5615         /**************************/
5616         /* push/pop */
5617     case 0x50 ... 0x57: /* push */
5618         gen_op_mov_v_reg(s, MO_32, s->T0, (b & 7) | REX_B(s));
5619         gen_push_v(s, s->T0);
5620         break;
5621     case 0x58 ... 0x5f: /* pop */
5622         ot = gen_pop_T0(s);
5623         /* NOTE: order is important for pop %sp */
5624         gen_pop_update(s, ot);
5625         gen_op_mov_reg_v(s, ot, (b & 7) | REX_B(s), s->T0);
5626         break;
5627     case 0x60: /* pusha */
5628         if (CODE64(s))
5629             goto illegal_op;
5630         gen_pusha(s);
5631         break;
5632     case 0x61: /* popa */
5633         if (CODE64(s))
5634             goto illegal_op;
5635         gen_popa(s);
5636         break;
5637     case 0x68: /* push Iv */
5638     case 0x6a:
5639         ot = mo_pushpop(s, dflag);
5640         if (b == 0x68)
5641             val = insn_get(env, s, ot);
5642         else
5643             val = (int8_t)insn_get(env, s, MO_8);
5644         tcg_gen_movi_tl(s->T0, val);
5645         gen_push_v(s, s->T0);
5646         break;
5647     case 0x8f: /* pop Ev */
5648         modrm = x86_ldub_code(env, s);
5649         mod = (modrm >> 6) & 3;
5650         ot = gen_pop_T0(s);
5651         if (mod == 3) {
5652             /* NOTE: order is important for pop %sp */
5653             gen_pop_update(s, ot);
5654             rm = (modrm & 7) | REX_B(s);
5655             gen_op_mov_reg_v(s, ot, rm, s->T0);
5656         } else {
5657             /* NOTE: order is important too for MMU exceptions */
5658             s->popl_esp_hack = 1 << ot;
5659             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5660             s->popl_esp_hack = 0;
5661             gen_pop_update(s, ot);
5662         }
5663         break;
5664     case 0xc8: /* enter */
5665         {
5666             int level;
5667             val = x86_lduw_code(env, s);
5668             level = x86_ldub_code(env, s);
5669             gen_enter(s, val, level);
5670         }
5671         break;
5672     case 0xc9: /* leave */
5673         gen_leave(s);
5674         break;
5675     case 0x06: /* push es */
5676     case 0x0e: /* push cs */
5677     case 0x16: /* push ss */
5678     case 0x1e: /* push ds */
5679         if (CODE64(s))
5680             goto illegal_op;
5681         gen_op_movl_T0_seg(s, b >> 3);
5682         gen_push_v(s, s->T0);
5683         break;
5684     case 0x1a0: /* push fs */
5685     case 0x1a8: /* push gs */
5686         gen_op_movl_T0_seg(s, (b >> 3) & 7);
5687         gen_push_v(s, s->T0);
5688         break;
5689     case 0x07: /* pop es */
5690     case 0x17: /* pop ss */
5691     case 0x1f: /* pop ds */
5692         if (CODE64(s))
5693             goto illegal_op;
5694         reg = b >> 3;
5695         ot = gen_pop_T0(s);
5696         gen_movl_seg_T0(s, reg);
5697         gen_pop_update(s, ot);
5698         break;
5699     case 0x1a1: /* pop fs */
5700     case 0x1a9: /* pop gs */
5701         ot = gen_pop_T0(s);
5702         gen_movl_seg_T0(s, (b >> 3) & 7);
5703         gen_pop_update(s, ot);
5704         break;
5705 
5706         /**************************/
5707         /* mov */
5708     case 0x88:
5709     case 0x89: /* mov Gv, Ev */
5710         ot = mo_b_d(b, dflag);
5711         modrm = x86_ldub_code(env, s);
5712         reg = ((modrm >> 3) & 7) | REX_R(s);
5713 
5714         /* generate a generic store */
5715         gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5716         break;
5717     case 0xc6:
5718     case 0xc7: /* mov Ev, Iv */
5719         ot = mo_b_d(b, dflag);
5720         modrm = x86_ldub_code(env, s);
5721         mod = (modrm >> 6) & 3;
5722         if (mod != 3) {
5723             s->rip_offset = insn_const_size(ot);
5724             gen_lea_modrm(env, s, modrm);
5725         }
5726         val = insn_get(env, s, ot);
5727         tcg_gen_movi_tl(s->T0, val);
5728         if (mod != 3) {
5729             gen_op_st_v(s, ot, s->T0, s->A0);
5730         } else {
5731             gen_op_mov_reg_v(s, ot, (modrm & 7) | REX_B(s), s->T0);
5732         }
5733         break;
5734     case 0x8a:
5735     case 0x8b: /* mov Ev, Gv */
5736         ot = mo_b_d(b, dflag);
5737         modrm = x86_ldub_code(env, s);
5738         reg = ((modrm >> 3) & 7) | REX_R(s);
5739 
5740         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5741         gen_op_mov_reg_v(s, ot, reg, s->T0);
5742         break;
5743     case 0x8e: /* mov seg, Gv */
5744         modrm = x86_ldub_code(env, s);
5745         reg = (modrm >> 3) & 7;
5746         if (reg >= 6 || reg == R_CS)
5747             goto illegal_op;
5748         gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5749         gen_movl_seg_T0(s, reg);
5750         break;
5751     case 0x8c: /* mov Gv, seg */
5752         modrm = x86_ldub_code(env, s);
5753         reg = (modrm >> 3) & 7;
5754         mod = (modrm >> 6) & 3;
5755         if (reg >= 6)
5756             goto illegal_op;
5757         gen_op_movl_T0_seg(s, reg);
5758         ot = mod == 3 ? dflag : MO_16;
5759         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5760         break;
5761 
5762     case 0x1b6: /* movzbS Gv, Eb */
5763     case 0x1b7: /* movzwS Gv, Eb */
5764     case 0x1be: /* movsbS Gv, Eb */
5765     case 0x1bf: /* movswS Gv, Eb */
5766         {
5767             MemOp d_ot;
5768             MemOp s_ot;
5769 
5770             /* d_ot is the size of destination */
5771             d_ot = dflag;
5772             /* ot is the size of source */
5773             ot = (b & 1) + MO_8;
5774             /* s_ot is the sign+size of source */
5775             s_ot = b & 8 ? MO_SIGN | ot : ot;
5776 
5777             modrm = x86_ldub_code(env, s);
5778             reg = ((modrm >> 3) & 7) | REX_R(s);
5779             mod = (modrm >> 6) & 3;
5780             rm = (modrm & 7) | REX_B(s);
5781 
5782             if (mod == 3) {
5783                 if (s_ot == MO_SB && byte_reg_is_xH(s, rm)) {
5784                     tcg_gen_sextract_tl(s->T0, cpu_regs[rm - 4], 8, 8);
5785                 } else {
5786                     gen_op_mov_v_reg(s, ot, s->T0, rm);
5787                     switch (s_ot) {
5788                     case MO_UB:
5789                         tcg_gen_ext8u_tl(s->T0, s->T0);
5790                         break;
5791                     case MO_SB:
5792                         tcg_gen_ext8s_tl(s->T0, s->T0);
5793                         break;
5794                     case MO_UW:
5795                         tcg_gen_ext16u_tl(s->T0, s->T0);
5796                         break;
5797                     default:
5798                     case MO_SW:
5799                         tcg_gen_ext16s_tl(s->T0, s->T0);
5800                         break;
5801                     }
5802                 }
5803                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
5804             } else {
5805                 gen_lea_modrm(env, s, modrm);
5806                 gen_op_ld_v(s, s_ot, s->T0, s->A0);
5807                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
5808             }
5809         }
5810         break;
5811 
5812     case 0x8d: /* lea */
5813         modrm = x86_ldub_code(env, s);
5814         mod = (modrm >> 6) & 3;
5815         if (mod == 3)
5816             goto illegal_op;
5817         reg = ((modrm >> 3) & 7) | REX_R(s);
5818         {
5819             AddressParts a = gen_lea_modrm_0(env, s, modrm);
5820             TCGv ea = gen_lea_modrm_1(s, a, false);
5821             gen_lea_v_seg(s, s->aflag, ea, -1, -1);
5822             gen_op_mov_reg_v(s, dflag, reg, s->A0);
5823         }
5824         break;
5825 
5826     case 0xa0: /* mov EAX, Ov */
5827     case 0xa1:
5828     case 0xa2: /* mov Ov, EAX */
5829     case 0xa3:
5830         {
5831             target_ulong offset_addr;
5832 
5833             ot = mo_b_d(b, dflag);
5834             offset_addr = insn_get_addr(env, s, s->aflag);
5835             tcg_gen_movi_tl(s->A0, offset_addr);
5836             gen_add_A0_ds_seg(s);
5837             if ((b & 2) == 0) {
5838                 gen_op_ld_v(s, ot, s->T0, s->A0);
5839                 gen_op_mov_reg_v(s, ot, R_EAX, s->T0);
5840             } else {
5841                 gen_op_mov_v_reg(s, ot, s->T0, R_EAX);
5842                 gen_op_st_v(s, ot, s->T0, s->A0);
5843             }
5844         }
5845         break;
5846     case 0xd7: /* xlat */
5847         tcg_gen_mov_tl(s->A0, cpu_regs[R_EBX]);
5848         tcg_gen_ext8u_tl(s->T0, cpu_regs[R_EAX]);
5849         tcg_gen_add_tl(s->A0, s->A0, s->T0);
5850         gen_extu(s->aflag, s->A0);
5851         gen_add_A0_ds_seg(s);
5852         gen_op_ld_v(s, MO_8, s->T0, s->A0);
5853         gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0);
5854         break;
5855     case 0xb0 ... 0xb7: /* mov R, Ib */
5856         val = insn_get(env, s, MO_8);
5857         tcg_gen_movi_tl(s->T0, val);
5858         gen_op_mov_reg_v(s, MO_8, (b & 7) | REX_B(s), s->T0);
5859         break;
5860     case 0xb8 ... 0xbf: /* mov R, Iv */
5861 #ifdef TARGET_X86_64
5862         if (dflag == MO_64) {
5863             uint64_t tmp;
5864             /* 64 bit case */
5865             tmp = x86_ldq_code(env, s);
5866             reg = (b & 7) | REX_B(s);
5867             tcg_gen_movi_tl(s->T0, tmp);
5868             gen_op_mov_reg_v(s, MO_64, reg, s->T0);
5869         } else
5870 #endif
5871         {
5872             ot = dflag;
5873             val = insn_get(env, s, ot);
5874             reg = (b & 7) | REX_B(s);
5875             tcg_gen_movi_tl(s->T0, val);
5876             gen_op_mov_reg_v(s, ot, reg, s->T0);
5877         }
5878         break;
5879 
5880     case 0x91 ... 0x97: /* xchg R, EAX */
5881     do_xchg_reg_eax:
5882         ot = dflag;
5883         reg = (b & 7) | REX_B(s);
5884         rm = R_EAX;
5885         goto do_xchg_reg;
5886     case 0x86:
5887     case 0x87: /* xchg Ev, Gv */
5888         ot = mo_b_d(b, dflag);
5889         modrm = x86_ldub_code(env, s);
5890         reg = ((modrm >> 3) & 7) | REX_R(s);
5891         mod = (modrm >> 6) & 3;
5892         if (mod == 3) {
5893             rm = (modrm & 7) | REX_B(s);
5894         do_xchg_reg:
5895             gen_op_mov_v_reg(s, ot, s->T0, reg);
5896             gen_op_mov_v_reg(s, ot, s->T1, rm);
5897             gen_op_mov_reg_v(s, ot, rm, s->T0);
5898             gen_op_mov_reg_v(s, ot, reg, s->T1);
5899         } else {
5900             gen_lea_modrm(env, s, modrm);
5901             gen_op_mov_v_reg(s, ot, s->T0, reg);
5902             /* for xchg, lock is implicit */
5903             tcg_gen_atomic_xchg_tl(s->T1, s->A0, s->T0,
5904                                    s->mem_index, ot | MO_LE);
5905             gen_op_mov_reg_v(s, ot, reg, s->T1);
5906         }
5907         break;
5908     case 0xc4: /* les Gv */
5909         /* In CODE64 this is VEX3; see above.  */
5910         op = R_ES;
5911         goto do_lxx;
5912     case 0xc5: /* lds Gv */
5913         /* In CODE64 this is VEX2; see above.  */
5914         op = R_DS;
5915         goto do_lxx;
5916     case 0x1b2: /* lss Gv */
5917         op = R_SS;
5918         goto do_lxx;
5919     case 0x1b4: /* lfs Gv */
5920         op = R_FS;
5921         goto do_lxx;
5922     case 0x1b5: /* lgs Gv */
5923         op = R_GS;
5924     do_lxx:
5925         ot = dflag != MO_16 ? MO_32 : MO_16;
5926         modrm = x86_ldub_code(env, s);
5927         reg = ((modrm >> 3) & 7) | REX_R(s);
5928         mod = (modrm >> 6) & 3;
5929         if (mod == 3)
5930             goto illegal_op;
5931         gen_lea_modrm(env, s, modrm);
5932         gen_op_ld_v(s, ot, s->T1, s->A0);
5933         gen_add_A0_im(s, 1 << ot);
5934         /* load the segment first to handle exceptions properly */
5935         gen_op_ld_v(s, MO_16, s->T0, s->A0);
5936         gen_movl_seg_T0(s, op);
5937         /* then put the data */
5938         gen_op_mov_reg_v(s, ot, reg, s->T1);
5939         break;
5940 
5941         /************************/
5942         /* shifts */
5943     case 0xc0:
5944     case 0xc1:
5945         /* shift Ev,Ib */
5946         shift = 2;
5947     grp2:
5948         {
5949             ot = mo_b_d(b, dflag);
5950             modrm = x86_ldub_code(env, s);
5951             mod = (modrm >> 6) & 3;
5952             op = (modrm >> 3) & 7;
5953 
5954             if (mod != 3) {
5955                 if (shift == 2) {
5956                     s->rip_offset = 1;
5957                 }
5958                 gen_lea_modrm(env, s, modrm);
5959                 opreg = OR_TMP0;
5960             } else {
5961                 opreg = (modrm & 7) | REX_B(s);
5962             }
5963 
5964             /* simpler op */
5965             if (shift == 0) {
5966                 gen_shift(s, op, ot, opreg, OR_ECX);
5967             } else {
5968                 if (shift == 2) {
5969                     shift = x86_ldub_code(env, s);
5970                 }
5971                 gen_shifti(s, op, ot, opreg, shift);
5972             }
5973         }
5974         break;
5975     case 0xd0:
5976     case 0xd1:
5977         /* shift Ev,1 */
5978         shift = 1;
5979         goto grp2;
5980     case 0xd2:
5981     case 0xd3:
5982         /* shift Ev,cl */
5983         shift = 0;
5984         goto grp2;
5985 
5986     case 0x1a4: /* shld imm */
5987         op = 0;
5988         shift = 1;
5989         goto do_shiftd;
5990     case 0x1a5: /* shld cl */
5991         op = 0;
5992         shift = 0;
5993         goto do_shiftd;
5994     case 0x1ac: /* shrd imm */
5995         op = 1;
5996         shift = 1;
5997         goto do_shiftd;
5998     case 0x1ad: /* shrd cl */
5999         op = 1;
6000         shift = 0;
6001     do_shiftd:
6002         ot = dflag;
6003         modrm = x86_ldub_code(env, s);
6004         mod = (modrm >> 6) & 3;
6005         rm = (modrm & 7) | REX_B(s);
6006         reg = ((modrm >> 3) & 7) | REX_R(s);
6007         if (mod != 3) {
6008             gen_lea_modrm(env, s, modrm);
6009             opreg = OR_TMP0;
6010         } else {
6011             opreg = rm;
6012         }
6013         gen_op_mov_v_reg(s, ot, s->T1, reg);
6014 
6015         if (shift) {
6016             TCGv imm = tcg_const_tl(x86_ldub_code(env, s));
6017             gen_shiftd_rm_T1(s, ot, opreg, op, imm);
6018             tcg_temp_free(imm);
6019         } else {
6020             gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
6021         }
6022         break;
6023 
6024         /************************/
6025         /* floats */
6026     case 0xd8 ... 0xdf:
6027         {
6028             bool update_fip = true;
6029 
6030             if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
6031                 /* if CR0.EM or CR0.TS are set, generate an FPU exception */
6032                 /* XXX: what to do if illegal op ? */
6033                 gen_exception(s, EXCP07_PREX);
6034                 break;
6035             }
6036             modrm = x86_ldub_code(env, s);
6037             mod = (modrm >> 6) & 3;
6038             rm = modrm & 7;
6039             op = ((b & 7) << 3) | ((modrm >> 3) & 7);
6040             if (mod != 3) {
6041                 /* memory op */
6042                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
6043                 TCGv ea = gen_lea_modrm_1(s, a, false);
6044                 TCGv last_addr = tcg_temp_new();
6045                 bool update_fdp = true;
6046 
6047                 tcg_gen_mov_tl(last_addr, ea);
6048                 gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
6049 
6050                 switch (op) {
6051                 case 0x00 ... 0x07: /* fxxxs */
6052                 case 0x10 ... 0x17: /* fixxxl */
6053                 case 0x20 ... 0x27: /* fxxxl */
6054                 case 0x30 ... 0x37: /* fixxx */
6055                     {
6056                         int op1;
6057                         op1 = op & 7;
6058 
6059                         switch (op >> 4) {
6060                         case 0:
6061                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
6062                                                 s->mem_index, MO_LEUL);
6063                             gen_helper_flds_FT0(cpu_env, s->tmp2_i32);
6064                             break;
6065                         case 1:
6066                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
6067                                                 s->mem_index, MO_LEUL);
6068                             gen_helper_fildl_FT0(cpu_env, s->tmp2_i32);
6069                             break;
6070                         case 2:
6071                             tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
6072                                                 s->mem_index, MO_LEUQ);
6073                             gen_helper_fldl_FT0(cpu_env, s->tmp1_i64);
6074                             break;
6075                         case 3:
6076                         default:
6077                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
6078                                                 s->mem_index, MO_LESW);
6079                             gen_helper_fildl_FT0(cpu_env, s->tmp2_i32);
6080                             break;
6081                         }
6082 
6083                         gen_helper_fp_arith_ST0_FT0(op1);
6084                         if (op1 == 3) {
6085                             /* fcomp needs pop */
6086                             gen_helper_fpop(cpu_env);
6087                         }
6088                     }
6089                     break;
6090                 case 0x08: /* flds */
6091                 case 0x0a: /* fsts */
6092                 case 0x0b: /* fstps */
6093                 case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
6094                 case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
6095                 case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
6096                     switch (op & 7) {
6097                     case 0:
6098                         switch (op >> 4) {
6099                         case 0:
6100                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
6101                                                 s->mem_index, MO_LEUL);
6102                             gen_helper_flds_ST0(cpu_env, s->tmp2_i32);
6103                             break;
6104                         case 1:
6105                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
6106                                                 s->mem_index, MO_LEUL);
6107                             gen_helper_fildl_ST0(cpu_env, s->tmp2_i32);
6108                             break;
6109                         case 2:
6110                             tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
6111                                                 s->mem_index, MO_LEUQ);
6112                             gen_helper_fldl_ST0(cpu_env, s->tmp1_i64);
6113                             break;
6114                         case 3:
6115                         default:
6116                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
6117                                                 s->mem_index, MO_LESW);
6118                             gen_helper_fildl_ST0(cpu_env, s->tmp2_i32);
6119                             break;
6120                         }
6121                         break;
6122                     case 1:
6123                         /* XXX: the corresponding CPUID bit must be tested ! */
6124                         switch (op >> 4) {
6125                         case 1:
6126                             gen_helper_fisttl_ST0(s->tmp2_i32, cpu_env);
6127                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
6128                                                 s->mem_index, MO_LEUL);
6129                             break;
6130                         case 2:
6131                             gen_helper_fisttll_ST0(s->tmp1_i64, cpu_env);
6132                             tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
6133                                                 s->mem_index, MO_LEUQ);
6134                             break;
6135                         case 3:
6136                         default:
6137                             gen_helper_fistt_ST0(s->tmp2_i32, cpu_env);
6138                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
6139                                                 s->mem_index, MO_LEUW);
6140                             break;
6141                         }
6142                         gen_helper_fpop(cpu_env);
6143                         break;
6144                     default:
6145                         switch (op >> 4) {
6146                         case 0:
6147                             gen_helper_fsts_ST0(s->tmp2_i32, cpu_env);
6148                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
6149                                                 s->mem_index, MO_LEUL);
6150                             break;
6151                         case 1:
6152                             gen_helper_fistl_ST0(s->tmp2_i32, cpu_env);
6153                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
6154                                                 s->mem_index, MO_LEUL);
6155                             break;
6156                         case 2:
6157                             gen_helper_fstl_ST0(s->tmp1_i64, cpu_env);
6158                             tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
6159                                                 s->mem_index, MO_LEUQ);
6160                             break;
6161                         case 3:
6162                         default:
6163                             gen_helper_fist_ST0(s->tmp2_i32, cpu_env);
6164                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
6165                                                 s->mem_index, MO_LEUW);
6166                             break;
6167                         }
6168                         if ((op & 7) == 3) {
6169                             gen_helper_fpop(cpu_env);
6170                         }
6171                         break;
6172                     }
6173                     break;
6174                 case 0x0c: /* fldenv mem */
6175                     gen_helper_fldenv(cpu_env, s->A0,
6176                                       tcg_const_i32(dflag - 1));
6177                     update_fip = update_fdp = false;
6178                     break;
6179                 case 0x0d: /* fldcw mem */
6180                     tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
6181                                         s->mem_index, MO_LEUW);
6182                     gen_helper_fldcw(cpu_env, s->tmp2_i32);
6183                     update_fip = update_fdp = false;
6184                     break;
6185                 case 0x0e: /* fnstenv mem */
6186                     gen_helper_fstenv(cpu_env, s->A0,
6187                                       tcg_const_i32(dflag - 1));
6188                     update_fip = update_fdp = false;
6189                     break;
6190                 case 0x0f: /* fnstcw mem */
6191                     gen_helper_fnstcw(s->tmp2_i32, cpu_env);
6192                     tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
6193                                         s->mem_index, MO_LEUW);
6194                     update_fip = update_fdp = false;
6195                     break;
6196                 case 0x1d: /* fldt mem */
6197                     gen_helper_fldt_ST0(cpu_env, s->A0);
6198                     break;
6199                 case 0x1f: /* fstpt mem */
6200                     gen_helper_fstt_ST0(cpu_env, s->A0);
6201                     gen_helper_fpop(cpu_env);
6202                     break;
6203                 case 0x2c: /* frstor mem */
6204                     gen_helper_frstor(cpu_env, s->A0,
6205                                       tcg_const_i32(dflag - 1));
6206                     update_fip = update_fdp = false;
6207                     break;
6208                 case 0x2e: /* fnsave mem */
6209                     gen_helper_fsave(cpu_env, s->A0,
6210                                      tcg_const_i32(dflag - 1));
6211                     update_fip = update_fdp = false;
6212                     break;
6213                 case 0x2f: /* fnstsw mem */
6214                     gen_helper_fnstsw(s->tmp2_i32, cpu_env);
6215                     tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
6216                                         s->mem_index, MO_LEUW);
6217                     update_fip = update_fdp = false;
6218                     break;
6219                 case 0x3c: /* fbld */
6220                     gen_helper_fbld_ST0(cpu_env, s->A0);
6221                     break;
6222                 case 0x3e: /* fbstp */
6223                     gen_helper_fbst_ST0(cpu_env, s->A0);
6224                     gen_helper_fpop(cpu_env);
6225                     break;
6226                 case 0x3d: /* fildll */
6227                     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
6228                                         s->mem_index, MO_LEUQ);
6229                     gen_helper_fildll_ST0(cpu_env, s->tmp1_i64);
6230                     break;
6231                 case 0x3f: /* fistpll */
6232                     gen_helper_fistll_ST0(s->tmp1_i64, cpu_env);
6233                     tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
6234                                         s->mem_index, MO_LEUQ);
6235                     gen_helper_fpop(cpu_env);
6236                     break;
6237                 default:
6238                     goto unknown_op;
6239                 }
6240 
6241                 if (update_fdp) {
6242                     int last_seg = s->override >= 0 ? s->override : a.def_seg;
6243 
6244                     tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
6245                                    offsetof(CPUX86State,
6246                                             segs[last_seg].selector));
6247                     tcg_gen_st16_i32(s->tmp2_i32, cpu_env,
6248                                      offsetof(CPUX86State, fpds));
6249                     tcg_gen_st_tl(last_addr, cpu_env,
6250                                   offsetof(CPUX86State, fpdp));
6251                 }
6252                 tcg_temp_free(last_addr);
6253             } else {
6254                 /* register float ops */
6255                 opreg = rm;
6256 
6257                 switch (op) {
6258                 case 0x08: /* fld sti */
6259                     gen_helper_fpush(cpu_env);
6260                     gen_helper_fmov_ST0_STN(cpu_env,
6261                                             tcg_const_i32((opreg + 1) & 7));
6262                     break;
6263                 case 0x09: /* fxchg sti */
6264                 case 0x29: /* fxchg4 sti, undocumented op */
6265                 case 0x39: /* fxchg7 sti, undocumented op */
6266                     gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
6267                     break;
6268                 case 0x0a: /* grp d9/2 */
6269                     switch (rm) {
6270                     case 0: /* fnop */
6271                         /* check exceptions (FreeBSD FPU probe) */
6272                         gen_helper_fwait(cpu_env);
6273                         update_fip = false;
6274                         break;
6275                     default:
6276                         goto unknown_op;
6277                     }
6278                     break;
6279                 case 0x0c: /* grp d9/4 */
6280                     switch (rm) {
6281                     case 0: /* fchs */
6282                         gen_helper_fchs_ST0(cpu_env);
6283                         break;
6284                     case 1: /* fabs */
6285                         gen_helper_fabs_ST0(cpu_env);
6286                         break;
6287                     case 4: /* ftst */
6288                         gen_helper_fldz_FT0(cpu_env);
6289                         gen_helper_fcom_ST0_FT0(cpu_env);
6290                         break;
6291                     case 5: /* fxam */
6292                         gen_helper_fxam_ST0(cpu_env);
6293                         break;
6294                     default:
6295                         goto unknown_op;
6296                     }
6297                     break;
6298                 case 0x0d: /* grp d9/5 */
6299                     {
6300                         switch (rm) {
6301                         case 0:
6302                             gen_helper_fpush(cpu_env);
6303                             gen_helper_fld1_ST0(cpu_env);
6304                             break;
6305                         case 1:
6306                             gen_helper_fpush(cpu_env);
6307                             gen_helper_fldl2t_ST0(cpu_env);
6308                             break;
6309                         case 2:
6310                             gen_helper_fpush(cpu_env);
6311                             gen_helper_fldl2e_ST0(cpu_env);
6312                             break;
6313                         case 3:
6314                             gen_helper_fpush(cpu_env);
6315                             gen_helper_fldpi_ST0(cpu_env);
6316                             break;
6317                         case 4:
6318                             gen_helper_fpush(cpu_env);
6319                             gen_helper_fldlg2_ST0(cpu_env);
6320                             break;
6321                         case 5:
6322                             gen_helper_fpush(cpu_env);
6323                             gen_helper_fldln2_ST0(cpu_env);
6324                             break;
6325                         case 6:
6326                             gen_helper_fpush(cpu_env);
6327                             gen_helper_fldz_ST0(cpu_env);
6328                             break;
6329                         default:
6330                             goto unknown_op;
6331                         }
6332                     }
6333                     break;
6334                 case 0x0e: /* grp d9/6 */
6335                     switch (rm) {
6336                     case 0: /* f2xm1 */
6337                         gen_helper_f2xm1(cpu_env);
6338                         break;
6339                     case 1: /* fyl2x */
6340                         gen_helper_fyl2x(cpu_env);
6341                         break;
6342                     case 2: /* fptan */
6343                         gen_helper_fptan(cpu_env);
6344                         break;
6345                     case 3: /* fpatan */
6346                         gen_helper_fpatan(cpu_env);
6347                         break;
6348                     case 4: /* fxtract */
6349                         gen_helper_fxtract(cpu_env);
6350                         break;
6351                     case 5: /* fprem1 */
6352                         gen_helper_fprem1(cpu_env);
6353                         break;
6354                     case 6: /* fdecstp */
6355                         gen_helper_fdecstp(cpu_env);
6356                         break;
6357                     default:
6358                     case 7: /* fincstp */
6359                         gen_helper_fincstp(cpu_env);
6360                         break;
6361                     }
6362                     break;
6363                 case 0x0f: /* grp d9/7 */
6364                     switch (rm) {
6365                     case 0: /* fprem */
6366                         gen_helper_fprem(cpu_env);
6367                         break;
6368                     case 1: /* fyl2xp1 */
6369                         gen_helper_fyl2xp1(cpu_env);
6370                         break;
6371                     case 2: /* fsqrt */
6372                         gen_helper_fsqrt(cpu_env);
6373                         break;
6374                     case 3: /* fsincos */
6375                         gen_helper_fsincos(cpu_env);
6376                         break;
6377                     case 5: /* fscale */
6378                         gen_helper_fscale(cpu_env);
6379                         break;
6380                     case 4: /* frndint */
6381                         gen_helper_frndint(cpu_env);
6382                         break;
6383                     case 6: /* fsin */
6384                         gen_helper_fsin(cpu_env);
6385                         break;
6386                     default:
6387                     case 7: /* fcos */
6388                         gen_helper_fcos(cpu_env);
6389                         break;
6390                     }
6391                     break;
6392                 case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6393                 case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6394                 case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6395                     {
6396                         int op1;
6397 
6398                         op1 = op & 7;
6399                         if (op >= 0x20) {
6400                             gen_helper_fp_arith_STN_ST0(op1, opreg);
6401                             if (op >= 0x30) {
6402                                 gen_helper_fpop(cpu_env);
6403                             }
6404                         } else {
6405                             gen_helper_fmov_FT0_STN(cpu_env,
6406                                                     tcg_const_i32(opreg));
6407                             gen_helper_fp_arith_ST0_FT0(op1);
6408                         }
6409                     }
6410                     break;
6411                 case 0x02: /* fcom */
6412                 case 0x22: /* fcom2, undocumented op */
6413                     gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6414                     gen_helper_fcom_ST0_FT0(cpu_env);
6415                     break;
6416                 case 0x03: /* fcomp */
6417                 case 0x23: /* fcomp3, undocumented op */
6418                 case 0x32: /* fcomp5, undocumented op */
6419                     gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6420                     gen_helper_fcom_ST0_FT0(cpu_env);
6421                     gen_helper_fpop(cpu_env);
6422                     break;
6423                 case 0x15: /* da/5 */
6424                     switch (rm) {
6425                     case 1: /* fucompp */
6426                         gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6427                         gen_helper_fucom_ST0_FT0(cpu_env);
6428                         gen_helper_fpop(cpu_env);
6429                         gen_helper_fpop(cpu_env);
6430                         break;
6431                     default:
6432                         goto unknown_op;
6433                     }
6434                     break;
6435                 case 0x1c:
6436                     switch (rm) {
6437                     case 0: /* feni (287 only, just do nop here) */
6438                         break;
6439                     case 1: /* fdisi (287 only, just do nop here) */
6440                         break;
6441                     case 2: /* fclex */
6442                         gen_helper_fclex(cpu_env);
6443                         update_fip = false;
6444                         break;
6445                     case 3: /* fninit */
6446                         gen_helper_fninit(cpu_env);
6447                         update_fip = false;
6448                         break;
6449                     case 4: /* fsetpm (287 only, just do nop here) */
6450                         break;
6451                     default:
6452                         goto unknown_op;
6453                     }
6454                     break;
6455                 case 0x1d: /* fucomi */
6456                     if (!(s->cpuid_features & CPUID_CMOV)) {
6457                         goto illegal_op;
6458                     }
6459                     gen_update_cc_op(s);
6460                     gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6461                     gen_helper_fucomi_ST0_FT0(cpu_env);
6462                     set_cc_op(s, CC_OP_EFLAGS);
6463                     break;
6464                 case 0x1e: /* fcomi */
6465                     if (!(s->cpuid_features & CPUID_CMOV)) {
6466                         goto illegal_op;
6467                     }
6468                     gen_update_cc_op(s);
6469                     gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6470                     gen_helper_fcomi_ST0_FT0(cpu_env);
6471                     set_cc_op(s, CC_OP_EFLAGS);
6472                     break;
6473                 case 0x28: /* ffree sti */
6474                     gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6475                     break;
6476                 case 0x2a: /* fst sti */
6477                     gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6478                     break;
6479                 case 0x2b: /* fstp sti */
6480                 case 0x0b: /* fstp1 sti, undocumented op */
6481                 case 0x3a: /* fstp8 sti, undocumented op */
6482                 case 0x3b: /* fstp9 sti, undocumented op */
6483                     gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6484                     gen_helper_fpop(cpu_env);
6485                     break;
6486                 case 0x2c: /* fucom st(i) */
6487                     gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6488                     gen_helper_fucom_ST0_FT0(cpu_env);
6489                     break;
6490                 case 0x2d: /* fucomp st(i) */
6491                     gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6492                     gen_helper_fucom_ST0_FT0(cpu_env);
6493                     gen_helper_fpop(cpu_env);
6494                     break;
6495                 case 0x33: /* de/3 */
6496                     switch (rm) {
6497                     case 1: /* fcompp */
6498                         gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6499                         gen_helper_fcom_ST0_FT0(cpu_env);
6500                         gen_helper_fpop(cpu_env);
6501                         gen_helper_fpop(cpu_env);
6502                         break;
6503                     default:
6504                         goto unknown_op;
6505                     }
6506                     break;
6507                 case 0x38: /* ffreep sti, undocumented op */
6508                     gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6509                     gen_helper_fpop(cpu_env);
6510                     break;
6511                 case 0x3c: /* df/4 */
6512                     switch (rm) {
6513                     case 0:
6514                         gen_helper_fnstsw(s->tmp2_i32, cpu_env);
6515                         tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
6516                         gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
6517                         break;
6518                     default:
6519                         goto unknown_op;
6520                     }
6521                     break;
6522                 case 0x3d: /* fucomip */
6523                     if (!(s->cpuid_features & CPUID_CMOV)) {
6524                         goto illegal_op;
6525                     }
6526                     gen_update_cc_op(s);
6527                     gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6528                     gen_helper_fucomi_ST0_FT0(cpu_env);
6529                     gen_helper_fpop(cpu_env);
6530                     set_cc_op(s, CC_OP_EFLAGS);
6531                     break;
6532                 case 0x3e: /* fcomip */
6533                     if (!(s->cpuid_features & CPUID_CMOV)) {
6534                         goto illegal_op;
6535                     }
6536                     gen_update_cc_op(s);
6537                     gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6538                     gen_helper_fcomi_ST0_FT0(cpu_env);
6539                     gen_helper_fpop(cpu_env);
6540                     set_cc_op(s, CC_OP_EFLAGS);
6541                     break;
6542                 case 0x10 ... 0x13: /* fcmovxx */
6543                 case 0x18 ... 0x1b:
6544                     {
6545                         int op1;
6546                         TCGLabel *l1;
6547                         static const uint8_t fcmov_cc[8] = {
6548                             (JCC_B << 1),
6549                             (JCC_Z << 1),
6550                             (JCC_BE << 1),
6551                             (JCC_P << 1),
6552                         };
6553 
6554                         if (!(s->cpuid_features & CPUID_CMOV)) {
6555                             goto illegal_op;
6556                         }
6557                         op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6558                         l1 = gen_new_label();
6559                         gen_jcc1_noeob(s, op1, l1);
6560                         gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6561                         gen_set_label(l1);
6562                     }
6563                     break;
6564                 default:
6565                     goto unknown_op;
6566                 }
6567             }
6568 
6569             if (update_fip) {
6570                 tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
6571                                offsetof(CPUX86State, segs[R_CS].selector));
6572                 tcg_gen_st16_i32(s->tmp2_i32, cpu_env,
6573                                  offsetof(CPUX86State, fpcs));
6574                 tcg_gen_st_tl(eip_cur_tl(s),
6575                               cpu_env, offsetof(CPUX86State, fpip));
6576             }
6577         }
6578         break;
6579         /************************/
6580         /* string ops */
6581 
6582     case 0xa4: /* movsS */
6583     case 0xa5:
6584         ot = mo_b_d(b, dflag);
6585         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6586             gen_repz_movs(s, ot);
6587         } else {
6588             gen_movs(s, ot);
6589         }
6590         break;
6591 
6592     case 0xaa: /* stosS */
6593     case 0xab:
6594         ot = mo_b_d(b, dflag);
6595         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6596             gen_repz_stos(s, ot);
6597         } else {
6598             gen_stos(s, ot);
6599         }
6600         break;
6601     case 0xac: /* lodsS */
6602     case 0xad:
6603         ot = mo_b_d(b, dflag);
6604         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6605             gen_repz_lods(s, ot);
6606         } else {
6607             gen_lods(s, ot);
6608         }
6609         break;
6610     case 0xae: /* scasS */
6611     case 0xaf:
6612         ot = mo_b_d(b, dflag);
6613         if (prefixes & PREFIX_REPNZ) {
6614             gen_repz_scas(s, ot, 1);
6615         } else if (prefixes & PREFIX_REPZ) {
6616             gen_repz_scas(s, ot, 0);
6617         } else {
6618             gen_scas(s, ot);
6619         }
6620         break;
6621 
6622     case 0xa6: /* cmpsS */
6623     case 0xa7:
6624         ot = mo_b_d(b, dflag);
6625         if (prefixes & PREFIX_REPNZ) {
6626             gen_repz_cmps(s, ot, 1);
6627         } else if (prefixes & PREFIX_REPZ) {
6628             gen_repz_cmps(s, ot, 0);
6629         } else {
6630             gen_cmps(s, ot);
6631         }
6632         break;
6633     case 0x6c: /* insS */
6634     case 0x6d:
6635         ot = mo_b_d32(b, dflag);
6636         tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
6637         tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
6638         if (!gen_check_io(s, ot, s->tmp2_i32,
6639                           SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) {
6640             break;
6641         }
6642         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6643             gen_io_start();
6644             s->base.is_jmp = DISAS_TOO_MANY;
6645         }
6646         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6647             gen_repz_ins(s, ot);
6648         } else {
6649             gen_ins(s, ot);
6650         }
6651         break;
6652     case 0x6e: /* outsS */
6653     case 0x6f:
6654         ot = mo_b_d32(b, dflag);
6655         tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
6656         tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
6657         if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_STR_MASK)) {
6658             break;
6659         }
6660         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6661             gen_io_start();
6662             s->base.is_jmp = DISAS_TOO_MANY;
6663         }
6664         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6665             gen_repz_outs(s, ot);
6666         } else {
6667             gen_outs(s, ot);
6668         }
6669         break;
6670 
6671         /************************/
6672         /* port I/O */
6673 
6674     case 0xe4:
6675     case 0xe5:
6676         ot = mo_b_d32(b, dflag);
6677         val = x86_ldub_code(env, s);
6678         tcg_gen_movi_i32(s->tmp2_i32, val);
6679         if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
6680             break;
6681         }
6682         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6683             gen_io_start();
6684             s->base.is_jmp = DISAS_TOO_MANY;
6685         }
6686         gen_helper_in_func(ot, s->T1, s->tmp2_i32);
6687         gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
6688         gen_bpt_io(s, s->tmp2_i32, ot);
6689         break;
6690     case 0xe6:
6691     case 0xe7:
6692         ot = mo_b_d32(b, dflag);
6693         val = x86_ldub_code(env, s);
6694         tcg_gen_movi_i32(s->tmp2_i32, val);
6695         if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
6696             break;
6697         }
6698         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6699             gen_io_start();
6700             s->base.is_jmp = DISAS_TOO_MANY;
6701         }
6702         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
6703         tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
6704         gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
6705         gen_bpt_io(s, s->tmp2_i32, ot);
6706         break;
6707     case 0xec:
6708     case 0xed:
6709         ot = mo_b_d32(b, dflag);
6710         tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
6711         tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
6712         if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
6713             break;
6714         }
6715         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6716             gen_io_start();
6717             s->base.is_jmp = DISAS_TOO_MANY;
6718         }
6719         gen_helper_in_func(ot, s->T1, s->tmp2_i32);
6720         gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
6721         gen_bpt_io(s, s->tmp2_i32, ot);
6722         break;
6723     case 0xee:
6724     case 0xef:
6725         ot = mo_b_d32(b, dflag);
6726         tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
6727         tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
6728         if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
6729             break;
6730         }
6731         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6732             gen_io_start();
6733             s->base.is_jmp = DISAS_TOO_MANY;
6734         }
6735         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
6736         tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
6737         gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
6738         gen_bpt_io(s, s->tmp2_i32, ot);
6739         break;
6740 
6741         /************************/
6742         /* control */
6743     case 0xc2: /* ret im */
6744         val = x86_ldsw_code(env, s);
6745         ot = gen_pop_T0(s);
6746         gen_stack_update(s, val + (1 << ot));
6747         /* Note that gen_pop_T0 uses a zero-extending load.  */
6748         gen_op_jmp_v(s, s->T0);
6749         gen_bnd_jmp(s);
6750         s->base.is_jmp = DISAS_JUMP;
6751         break;
6752     case 0xc3: /* ret */
6753         ot = gen_pop_T0(s);
6754         gen_pop_update(s, ot);
6755         /* Note that gen_pop_T0 uses a zero-extending load.  */
6756         gen_op_jmp_v(s, s->T0);
6757         gen_bnd_jmp(s);
6758         s->base.is_jmp = DISAS_JUMP;
6759         break;
6760     case 0xca: /* lret im */
6761         val = x86_ldsw_code(env, s);
6762     do_lret:
6763         if (PE(s) && !VM86(s)) {
6764             gen_update_cc_op(s);
6765             gen_update_eip_cur(s);
6766             gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
6767                                       tcg_const_i32(val));
6768         } else {
6769             gen_stack_A0(s);
6770             /* pop offset */
6771             gen_op_ld_v(s, dflag, s->T0, s->A0);
6772             /* NOTE: keeping EIP updated is not a problem in case of
6773                exception */
6774             gen_op_jmp_v(s, s->T0);
6775             /* pop selector */
6776             gen_add_A0_im(s, 1 << dflag);
6777             gen_op_ld_v(s, dflag, s->T0, s->A0);
6778             gen_op_movl_seg_T0_vm(s, R_CS);
6779             /* add stack offset */
6780             gen_stack_update(s, val + (2 << dflag));
6781         }
6782         s->base.is_jmp = DISAS_EOB_ONLY;
6783         break;
6784     case 0xcb: /* lret */
6785         val = 0;
6786         goto do_lret;
6787     case 0xcf: /* iret */
6788         gen_svm_check_intercept(s, SVM_EXIT_IRET);
6789         if (!PE(s) || VM86(s)) {
6790             /* real mode or vm86 mode */
6791             if (!check_vm86_iopl(s)) {
6792                 break;
6793             }
6794             gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6795         } else {
6796             gen_helper_iret_protected(cpu_env, tcg_constant_i32(dflag - 1),
6797                                       eip_next_i32(s));
6798         }
6799         set_cc_op(s, CC_OP_EFLAGS);
6800         s->base.is_jmp = DISAS_EOB_ONLY;
6801         break;
6802     case 0xe8: /* call im */
6803         {
6804             int diff = (dflag != MO_16
6805                         ? (int32_t)insn_get(env, s, MO_32)
6806                         : (int16_t)insn_get(env, s, MO_16));
6807             gen_push_v(s, eip_next_tl(s));
6808             gen_bnd_jmp(s);
6809             gen_jmp_rel(s, dflag, diff, 0);
6810         }
6811         break;
6812     case 0x9a: /* lcall im */
6813         {
6814             unsigned int selector, offset;
6815 
6816             if (CODE64(s))
6817                 goto illegal_op;
6818             ot = dflag;
6819             offset = insn_get(env, s, ot);
6820             selector = insn_get(env, s, MO_16);
6821 
6822             tcg_gen_movi_tl(s->T0, selector);
6823             tcg_gen_movi_tl(s->T1, offset);
6824         }
6825         goto do_lcall;
6826     case 0xe9: /* jmp im */
6827         {
6828             int diff = (dflag != MO_16
6829                         ? (int32_t)insn_get(env, s, MO_32)
6830                         : (int16_t)insn_get(env, s, MO_16));
6831             gen_bnd_jmp(s);
6832             gen_jmp_rel(s, dflag, diff, 0);
6833         }
6834         break;
6835     case 0xea: /* ljmp im */
6836         {
6837             unsigned int selector, offset;
6838 
6839             if (CODE64(s))
6840                 goto illegal_op;
6841             ot = dflag;
6842             offset = insn_get(env, s, ot);
6843             selector = insn_get(env, s, MO_16);
6844 
6845             tcg_gen_movi_tl(s->T0, selector);
6846             tcg_gen_movi_tl(s->T1, offset);
6847         }
6848         goto do_ljmp;
6849     case 0xeb: /* jmp Jb */
6850         {
6851             int diff = (int8_t)insn_get(env, s, MO_8);
6852             gen_jmp_rel(s, dflag, diff, 0);
6853         }
6854         break;
6855     case 0x70 ... 0x7f: /* jcc Jb */
6856         {
6857             int diff = (int8_t)insn_get(env, s, MO_8);
6858             gen_bnd_jmp(s);
6859             gen_jcc(s, b, diff);
6860         }
6861         break;
6862     case 0x180 ... 0x18f: /* jcc Jv */
6863         {
6864             int diff = (dflag != MO_16
6865                         ? (int32_t)insn_get(env, s, MO_32)
6866                         : (int16_t)insn_get(env, s, MO_16));
6867             gen_bnd_jmp(s);
6868             gen_jcc(s, b, diff);
6869         }
6870         break;
6871 
6872     case 0x190 ... 0x19f: /* setcc Gv */
6873         modrm = x86_ldub_code(env, s);
6874         gen_setcc1(s, b, s->T0);
6875         gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
6876         break;
6877     case 0x140 ... 0x14f: /* cmov Gv, Ev */
6878         if (!(s->cpuid_features & CPUID_CMOV)) {
6879             goto illegal_op;
6880         }
6881         ot = dflag;
6882         modrm = x86_ldub_code(env, s);
6883         reg = ((modrm >> 3) & 7) | REX_R(s);
6884         gen_cmovcc1(env, s, ot, b, modrm, reg);
6885         break;
6886 
6887         /************************/
6888         /* flags */
6889     case 0x9c: /* pushf */
6890         gen_svm_check_intercept(s, SVM_EXIT_PUSHF);
6891         if (check_vm86_iopl(s)) {
6892             gen_update_cc_op(s);
6893             gen_helper_read_eflags(s->T0, cpu_env);
6894             gen_push_v(s, s->T0);
6895         }
6896         break;
6897     case 0x9d: /* popf */
6898         gen_svm_check_intercept(s, SVM_EXIT_POPF);
6899         if (check_vm86_iopl(s)) {
6900             ot = gen_pop_T0(s);
6901             if (CPL(s) == 0) {
6902                 if (dflag != MO_16) {
6903                     gen_helper_write_eflags(cpu_env, s->T0,
6904                                             tcg_const_i32((TF_MASK | AC_MASK |
6905                                                            ID_MASK | NT_MASK |
6906                                                            IF_MASK |
6907                                                            IOPL_MASK)));
6908                 } else {
6909                     gen_helper_write_eflags(cpu_env, s->T0,
6910                                             tcg_const_i32((TF_MASK | AC_MASK |
6911                                                            ID_MASK | NT_MASK |
6912                                                            IF_MASK | IOPL_MASK)
6913                                                           & 0xffff));
6914                 }
6915             } else {
6916                 if (CPL(s) <= IOPL(s)) {
6917                     if (dflag != MO_16) {
6918                         gen_helper_write_eflags(cpu_env, s->T0,
6919                                                 tcg_const_i32((TF_MASK |
6920                                                                AC_MASK |
6921                                                                ID_MASK |
6922                                                                NT_MASK |
6923                                                                IF_MASK)));
6924                     } else {
6925                         gen_helper_write_eflags(cpu_env, s->T0,
6926                                                 tcg_const_i32((TF_MASK |
6927                                                                AC_MASK |
6928                                                                ID_MASK |
6929                                                                NT_MASK |
6930                                                                IF_MASK)
6931                                                               & 0xffff));
6932                     }
6933                 } else {
6934                     if (dflag != MO_16) {
6935                         gen_helper_write_eflags(cpu_env, s->T0,
6936                                            tcg_const_i32((TF_MASK | AC_MASK |
6937                                                           ID_MASK | NT_MASK)));
6938                     } else {
6939                         gen_helper_write_eflags(cpu_env, s->T0,
6940                                            tcg_const_i32((TF_MASK | AC_MASK |
6941                                                           ID_MASK | NT_MASK)
6942                                                          & 0xffff));
6943                     }
6944                 }
6945             }
6946             gen_pop_update(s, ot);
6947             set_cc_op(s, CC_OP_EFLAGS);
6948             /* abort translation because TF/AC flag may change */
6949             s->base.is_jmp = DISAS_EOB_NEXT;
6950         }
6951         break;
6952     case 0x9e: /* sahf */
6953         if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6954             goto illegal_op;
6955         gen_op_mov_v_reg(s, MO_8, s->T0, R_AH);
6956         gen_compute_eflags(s);
6957         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6958         tcg_gen_andi_tl(s->T0, s->T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
6959         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, s->T0);
6960         break;
6961     case 0x9f: /* lahf */
6962         if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6963             goto illegal_op;
6964         gen_compute_eflags(s);
6965         /* Note: gen_compute_eflags() only gives the condition codes */
6966         tcg_gen_ori_tl(s->T0, cpu_cc_src, 0x02);
6967         gen_op_mov_reg_v(s, MO_8, R_AH, s->T0);
6968         break;
6969     case 0xf5: /* cmc */
6970         gen_compute_eflags(s);
6971         tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6972         break;
6973     case 0xf8: /* clc */
6974         gen_compute_eflags(s);
6975         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6976         break;
6977     case 0xf9: /* stc */
6978         gen_compute_eflags(s);
6979         tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6980         break;
6981     case 0xfc: /* cld */
6982         tcg_gen_movi_i32(s->tmp2_i32, 1);
6983         tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6984         break;
6985     case 0xfd: /* std */
6986         tcg_gen_movi_i32(s->tmp2_i32, -1);
6987         tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6988         break;
6989 
6990         /************************/
6991         /* bit operations */
6992     case 0x1ba: /* bt/bts/btr/btc Gv, im */
6993         ot = dflag;
6994         modrm = x86_ldub_code(env, s);
6995         op = (modrm >> 3) & 7;
6996         mod = (modrm >> 6) & 3;
6997         rm = (modrm & 7) | REX_B(s);
6998         if (mod != 3) {
6999             s->rip_offset = 1;
7000             gen_lea_modrm(env, s, modrm);
7001             if (!(s->prefix & PREFIX_LOCK)) {
7002                 gen_op_ld_v(s, ot, s->T0, s->A0);
7003             }
7004         } else {
7005             gen_op_mov_v_reg(s, ot, s->T0, rm);
7006         }
7007         /* load shift */
7008         val = x86_ldub_code(env, s);
7009         tcg_gen_movi_tl(s->T1, val);
7010         if (op < 4)
7011             goto unknown_op;
7012         op -= 4;
7013         goto bt_op;
7014     case 0x1a3: /* bt Gv, Ev */
7015         op = 0;
7016         goto do_btx;
7017     case 0x1ab: /* bts */
7018         op = 1;
7019         goto do_btx;
7020     case 0x1b3: /* btr */
7021         op = 2;
7022         goto do_btx;
7023     case 0x1bb: /* btc */
7024         op = 3;
7025     do_btx:
7026         ot = dflag;
7027         modrm = x86_ldub_code(env, s);
7028         reg = ((modrm >> 3) & 7) | REX_R(s);
7029         mod = (modrm >> 6) & 3;
7030         rm = (modrm & 7) | REX_B(s);
7031         gen_op_mov_v_reg(s, MO_32, s->T1, reg);
7032         if (mod != 3) {
7033             AddressParts a = gen_lea_modrm_0(env, s, modrm);
7034             /* specific case: we need to add a displacement */
7035             gen_exts(ot, s->T1);
7036             tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot);
7037             tcg_gen_shli_tl(s->tmp0, s->tmp0, ot);
7038             tcg_gen_add_tl(s->A0, gen_lea_modrm_1(s, a, false), s->tmp0);
7039             gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
7040             if (!(s->prefix & PREFIX_LOCK)) {
7041                 gen_op_ld_v(s, ot, s->T0, s->A0);
7042             }
7043         } else {
7044             gen_op_mov_v_reg(s, ot, s->T0, rm);
7045         }
7046     bt_op:
7047         tcg_gen_andi_tl(s->T1, s->T1, (1 << (3 + ot)) - 1);
7048         tcg_gen_movi_tl(s->tmp0, 1);
7049         tcg_gen_shl_tl(s->tmp0, s->tmp0, s->T1);
7050         if (s->prefix & PREFIX_LOCK) {
7051             switch (op) {
7052             case 0: /* bt */
7053                 /* Needs no atomic ops; we surpressed the normal
7054                    memory load for LOCK above so do it now.  */
7055                 gen_op_ld_v(s, ot, s->T0, s->A0);
7056                 break;
7057             case 1: /* bts */
7058                 tcg_gen_atomic_fetch_or_tl(s->T0, s->A0, s->tmp0,
7059                                            s->mem_index, ot | MO_LE);
7060                 break;
7061             case 2: /* btr */
7062                 tcg_gen_not_tl(s->tmp0, s->tmp0);
7063                 tcg_gen_atomic_fetch_and_tl(s->T0, s->A0, s->tmp0,
7064                                             s->mem_index, ot | MO_LE);
7065                 break;
7066             default:
7067             case 3: /* btc */
7068                 tcg_gen_atomic_fetch_xor_tl(s->T0, s->A0, s->tmp0,
7069                                             s->mem_index, ot | MO_LE);
7070                 break;
7071             }
7072             tcg_gen_shr_tl(s->tmp4, s->T0, s->T1);
7073         } else {
7074             tcg_gen_shr_tl(s->tmp4, s->T0, s->T1);
7075             switch (op) {
7076             case 0: /* bt */
7077                 /* Data already loaded; nothing to do.  */
7078                 break;
7079             case 1: /* bts */
7080                 tcg_gen_or_tl(s->T0, s->T0, s->tmp0);
7081                 break;
7082             case 2: /* btr */
7083                 tcg_gen_andc_tl(s->T0, s->T0, s->tmp0);
7084                 break;
7085             default:
7086             case 3: /* btc */
7087                 tcg_gen_xor_tl(s->T0, s->T0, s->tmp0);
7088                 break;
7089             }
7090             if (op != 0) {
7091                 if (mod != 3) {
7092                     gen_op_st_v(s, ot, s->T0, s->A0);
7093                 } else {
7094                     gen_op_mov_reg_v(s, ot, rm, s->T0);
7095                 }
7096             }
7097         }
7098 
7099         /* Delay all CC updates until after the store above.  Note that
7100            C is the result of the test, Z is unchanged, and the others
7101            are all undefined.  */
7102         switch (s->cc_op) {
7103         case CC_OP_MULB ... CC_OP_MULQ:
7104         case CC_OP_ADDB ... CC_OP_ADDQ:
7105         case CC_OP_ADCB ... CC_OP_ADCQ:
7106         case CC_OP_SUBB ... CC_OP_SUBQ:
7107         case CC_OP_SBBB ... CC_OP_SBBQ:
7108         case CC_OP_LOGICB ... CC_OP_LOGICQ:
7109         case CC_OP_INCB ... CC_OP_INCQ:
7110         case CC_OP_DECB ... CC_OP_DECQ:
7111         case CC_OP_SHLB ... CC_OP_SHLQ:
7112         case CC_OP_SARB ... CC_OP_SARQ:
7113         case CC_OP_BMILGB ... CC_OP_BMILGQ:
7114             /* Z was going to be computed from the non-zero status of CC_DST.
7115                We can get that same Z value (and the new C value) by leaving
7116                CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
7117                same width.  */
7118             tcg_gen_mov_tl(cpu_cc_src, s->tmp4);
7119             set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
7120             break;
7121         default:
7122             /* Otherwise, generate EFLAGS and replace the C bit.  */
7123             gen_compute_eflags(s);
7124             tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, s->tmp4,
7125                                ctz32(CC_C), 1);
7126             break;
7127         }
7128         break;
7129     case 0x1bc: /* bsf / tzcnt */
7130     case 0x1bd: /* bsr / lzcnt */
7131         ot = dflag;
7132         modrm = x86_ldub_code(env, s);
7133         reg = ((modrm >> 3) & 7) | REX_R(s);
7134         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
7135         gen_extu(ot, s->T0);
7136 
7137         /* Note that lzcnt and tzcnt are in different extensions.  */
7138         if ((prefixes & PREFIX_REPZ)
7139             && (b & 1
7140                 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
7141                 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
7142             int size = 8 << ot;
7143             /* For lzcnt/tzcnt, C bit is defined related to the input. */
7144             tcg_gen_mov_tl(cpu_cc_src, s->T0);
7145             if (b & 1) {
7146                 /* For lzcnt, reduce the target_ulong result by the
7147                    number of zeros that we expect to find at the top.  */
7148                 tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS);
7149                 tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - size);
7150             } else {
7151                 /* For tzcnt, a zero input must return the operand size.  */
7152                 tcg_gen_ctzi_tl(s->T0, s->T0, size);
7153             }
7154             /* For lzcnt/tzcnt, Z bit is defined related to the result.  */
7155             gen_op_update1_cc(s);
7156             set_cc_op(s, CC_OP_BMILGB + ot);
7157         } else {
7158             /* For bsr/bsf, only the Z bit is defined and it is related
7159                to the input and not the result.  */
7160             tcg_gen_mov_tl(cpu_cc_dst, s->T0);
7161             set_cc_op(s, CC_OP_LOGICB + ot);
7162 
7163             /* ??? The manual says that the output is undefined when the
7164                input is zero, but real hardware leaves it unchanged, and
7165                real programs appear to depend on that.  Accomplish this
7166                by passing the output as the value to return upon zero.  */
7167             if (b & 1) {
7168                 /* For bsr, return the bit index of the first 1 bit,
7169                    not the count of leading zeros.  */
7170                 tcg_gen_xori_tl(s->T1, cpu_regs[reg], TARGET_LONG_BITS - 1);
7171                 tcg_gen_clz_tl(s->T0, s->T0, s->T1);
7172                 tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1);
7173             } else {
7174                 tcg_gen_ctz_tl(s->T0, s->T0, cpu_regs[reg]);
7175             }
7176         }
7177         gen_op_mov_reg_v(s, ot, reg, s->T0);
7178         break;
7179         /************************/
7180         /* bcd */
7181     case 0x27: /* daa */
7182         if (CODE64(s))
7183             goto illegal_op;
7184         gen_update_cc_op(s);
7185         gen_helper_daa(cpu_env);
7186         set_cc_op(s, CC_OP_EFLAGS);
7187         break;
7188     case 0x2f: /* das */
7189         if (CODE64(s))
7190             goto illegal_op;
7191         gen_update_cc_op(s);
7192         gen_helper_das(cpu_env);
7193         set_cc_op(s, CC_OP_EFLAGS);
7194         break;
7195     case 0x37: /* aaa */
7196         if (CODE64(s))
7197             goto illegal_op;
7198         gen_update_cc_op(s);
7199         gen_helper_aaa(cpu_env);
7200         set_cc_op(s, CC_OP_EFLAGS);
7201         break;
7202     case 0x3f: /* aas */
7203         if (CODE64(s))
7204             goto illegal_op;
7205         gen_update_cc_op(s);
7206         gen_helper_aas(cpu_env);
7207         set_cc_op(s, CC_OP_EFLAGS);
7208         break;
7209     case 0xd4: /* aam */
7210         if (CODE64(s))
7211             goto illegal_op;
7212         val = x86_ldub_code(env, s);
7213         if (val == 0) {
7214             gen_exception(s, EXCP00_DIVZ);
7215         } else {
7216             gen_helper_aam(cpu_env, tcg_const_i32(val));
7217             set_cc_op(s, CC_OP_LOGICB);
7218         }
7219         break;
7220     case 0xd5: /* aad */
7221         if (CODE64(s))
7222             goto illegal_op;
7223         val = x86_ldub_code(env, s);
7224         gen_helper_aad(cpu_env, tcg_const_i32(val));
7225         set_cc_op(s, CC_OP_LOGICB);
7226         break;
7227         /************************/
7228         /* misc */
7229     case 0x90: /* nop */
7230         /* XXX: correct lock test for all insn */
7231         if (prefixes & PREFIX_LOCK) {
7232             goto illegal_op;
7233         }
7234         /* If REX_B is set, then this is xchg eax, r8d, not a nop.  */
7235         if (REX_B(s)) {
7236             goto do_xchg_reg_eax;
7237         }
7238         if (prefixes & PREFIX_REPZ) {
7239             gen_update_cc_op(s);
7240             gen_update_eip_cur(s);
7241             gen_helper_pause(cpu_env, cur_insn_len_i32(s));
7242             s->base.is_jmp = DISAS_NORETURN;
7243         }
7244         break;
7245     case 0x9b: /* fwait */
7246         if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
7247             (HF_MP_MASK | HF_TS_MASK)) {
7248             gen_exception(s, EXCP07_PREX);
7249         } else {
7250             gen_helper_fwait(cpu_env);
7251         }
7252         break;
7253     case 0xcc: /* int3 */
7254         gen_interrupt(s, EXCP03_INT3);
7255         break;
7256     case 0xcd: /* int N */
7257         val = x86_ldub_code(env, s);
7258         if (check_vm86_iopl(s)) {
7259             gen_interrupt(s, val);
7260         }
7261         break;
7262     case 0xce: /* into */
7263         if (CODE64(s))
7264             goto illegal_op;
7265         gen_update_cc_op(s);
7266         gen_update_eip_cur(s);
7267         gen_helper_into(cpu_env, cur_insn_len_i32(s));
7268         break;
7269 #ifdef WANT_ICEBP
7270     case 0xf1: /* icebp (undocumented, exits to external debugger) */
7271         gen_svm_check_intercept(s, SVM_EXIT_ICEBP);
7272         gen_debug(s);
7273         break;
7274 #endif
7275     case 0xfa: /* cli */
7276         if (check_iopl(s)) {
7277             gen_helper_cli(cpu_env);
7278         }
7279         break;
7280     case 0xfb: /* sti */
7281         if (check_iopl(s)) {
7282             gen_helper_sti(cpu_env);
7283             /* interruptions are enabled only the first insn after sti */
7284             gen_update_eip_next(s);
7285             gen_eob_inhibit_irq(s, true);
7286         }
7287         break;
7288     case 0x62: /* bound */
7289         if (CODE64(s))
7290             goto illegal_op;
7291         ot = dflag;
7292         modrm = x86_ldub_code(env, s);
7293         reg = (modrm >> 3) & 7;
7294         mod = (modrm >> 6) & 3;
7295         if (mod == 3)
7296             goto illegal_op;
7297         gen_op_mov_v_reg(s, ot, s->T0, reg);
7298         gen_lea_modrm(env, s, modrm);
7299         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
7300         if (ot == MO_16) {
7301             gen_helper_boundw(cpu_env, s->A0, s->tmp2_i32);
7302         } else {
7303             gen_helper_boundl(cpu_env, s->A0, s->tmp2_i32);
7304         }
7305         break;
7306     case 0x1c8 ... 0x1cf: /* bswap reg */
7307         reg = (b & 7) | REX_B(s);
7308 #ifdef TARGET_X86_64
7309         if (dflag == MO_64) {
7310             tcg_gen_bswap64_i64(cpu_regs[reg], cpu_regs[reg]);
7311             break;
7312         }
7313 #endif
7314         tcg_gen_bswap32_tl(cpu_regs[reg], cpu_regs[reg], TCG_BSWAP_OZ);
7315         break;
7316     case 0xd6: /* salc */
7317         if (CODE64(s))
7318             goto illegal_op;
7319         gen_compute_eflags_c(s, s->T0);
7320         tcg_gen_neg_tl(s->T0, s->T0);
7321         gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0);
7322         break;
7323     case 0xe0: /* loopnz */
7324     case 0xe1: /* loopz */
7325     case 0xe2: /* loop */
7326     case 0xe3: /* jecxz */
7327         {
7328             TCGLabel *l1, *l2;
7329             int diff = (int8_t)insn_get(env, s, MO_8);
7330 
7331             l1 = gen_new_label();
7332             l2 = gen_new_label();
7333             gen_update_cc_op(s);
7334             b &= 3;
7335             switch(b) {
7336             case 0: /* loopnz */
7337             case 1: /* loopz */
7338                 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
7339                 gen_op_jz_ecx(s, l2);
7340                 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
7341                 break;
7342             case 2: /* loop */
7343                 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
7344                 gen_op_jnz_ecx(s, l1);
7345                 break;
7346             default:
7347             case 3: /* jcxz */
7348                 gen_op_jz_ecx(s, l1);
7349                 break;
7350             }
7351 
7352             gen_set_label(l2);
7353             gen_jmp_rel_csize(s, 0, 1);
7354 
7355             gen_set_label(l1);
7356             gen_jmp_rel(s, dflag, diff, 0);
7357         }
7358         break;
7359     case 0x130: /* wrmsr */
7360     case 0x132: /* rdmsr */
7361         if (check_cpl0(s)) {
7362             gen_update_cc_op(s);
7363             gen_update_eip_cur(s);
7364             if (b & 2) {
7365                 gen_helper_rdmsr(cpu_env);
7366             } else {
7367                 gen_helper_wrmsr(cpu_env);
7368                 s->base.is_jmp = DISAS_EOB_NEXT;
7369             }
7370         }
7371         break;
7372     case 0x131: /* rdtsc */
7373         gen_update_cc_op(s);
7374         gen_update_eip_cur(s);
7375         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7376             gen_io_start();
7377             s->base.is_jmp = DISAS_TOO_MANY;
7378         }
7379         gen_helper_rdtsc(cpu_env);
7380         break;
7381     case 0x133: /* rdpmc */
7382         gen_update_cc_op(s);
7383         gen_update_eip_cur(s);
7384         gen_helper_rdpmc(cpu_env);
7385         s->base.is_jmp = DISAS_NORETURN;
7386         break;
7387     case 0x134: /* sysenter */
7388         /* For Intel SYSENTER is valid on 64-bit */
7389         if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7390             goto illegal_op;
7391         if (!PE(s)) {
7392             gen_exception_gpf(s);
7393         } else {
7394             gen_helper_sysenter(cpu_env);
7395             s->base.is_jmp = DISAS_EOB_ONLY;
7396         }
7397         break;
7398     case 0x135: /* sysexit */
7399         /* For Intel SYSEXIT is valid on 64-bit */
7400         if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7401             goto illegal_op;
7402         if (!PE(s)) {
7403             gen_exception_gpf(s);
7404         } else {
7405             gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
7406             s->base.is_jmp = DISAS_EOB_ONLY;
7407         }
7408         break;
7409 #ifdef TARGET_X86_64
7410     case 0x105: /* syscall */
7411         /* XXX: is it usable in real mode ? */
7412         gen_update_cc_op(s);
7413         gen_update_eip_cur(s);
7414         gen_helper_syscall(cpu_env, cur_insn_len_i32(s));
7415         /* TF handling for the syscall insn is different. The TF bit is  checked
7416            after the syscall insn completes. This allows #DB to not be
7417            generated after one has entered CPL0 if TF is set in FMASK.  */
7418         gen_eob_worker(s, false, true);
7419         break;
7420     case 0x107: /* sysret */
7421         if (!PE(s)) {
7422             gen_exception_gpf(s);
7423         } else {
7424             gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
7425             /* condition codes are modified only in long mode */
7426             if (LMA(s)) {
7427                 set_cc_op(s, CC_OP_EFLAGS);
7428             }
7429             /* TF handling for the sysret insn is different. The TF bit is
7430                checked after the sysret insn completes. This allows #DB to be
7431                generated "as if" the syscall insn in userspace has just
7432                completed.  */
7433             gen_eob_worker(s, false, true);
7434         }
7435         break;
7436 #endif
7437     case 0x1a2: /* cpuid */
7438         gen_update_cc_op(s);
7439         gen_update_eip_cur(s);
7440         gen_helper_cpuid(cpu_env);
7441         break;
7442     case 0xf4: /* hlt */
7443         if (check_cpl0(s)) {
7444             gen_update_cc_op(s);
7445             gen_update_eip_cur(s);
7446             gen_helper_hlt(cpu_env, cur_insn_len_i32(s));
7447             s->base.is_jmp = DISAS_NORETURN;
7448         }
7449         break;
7450     case 0x100:
7451         modrm = x86_ldub_code(env, s);
7452         mod = (modrm >> 6) & 3;
7453         op = (modrm >> 3) & 7;
7454         switch(op) {
7455         case 0: /* sldt */
7456             if (!PE(s) || VM86(s))
7457                 goto illegal_op;
7458             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
7459                 break;
7460             }
7461             gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ);
7462             tcg_gen_ld32u_tl(s->T0, cpu_env,
7463                              offsetof(CPUX86State, ldt.selector));
7464             ot = mod == 3 ? dflag : MO_16;
7465             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7466             break;
7467         case 2: /* lldt */
7468             if (!PE(s) || VM86(s))
7469                 goto illegal_op;
7470             if (check_cpl0(s)) {
7471                 gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE);
7472                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7473                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
7474                 gen_helper_lldt(cpu_env, s->tmp2_i32);
7475             }
7476             break;
7477         case 1: /* str */
7478             if (!PE(s) || VM86(s))
7479                 goto illegal_op;
7480             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
7481                 break;
7482             }
7483             gen_svm_check_intercept(s, SVM_EXIT_TR_READ);
7484             tcg_gen_ld32u_tl(s->T0, cpu_env,
7485                              offsetof(CPUX86State, tr.selector));
7486             ot = mod == 3 ? dflag : MO_16;
7487             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7488             break;
7489         case 3: /* ltr */
7490             if (!PE(s) || VM86(s))
7491                 goto illegal_op;
7492             if (check_cpl0(s)) {
7493                 gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE);
7494                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7495                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
7496                 gen_helper_ltr(cpu_env, s->tmp2_i32);
7497             }
7498             break;
7499         case 4: /* verr */
7500         case 5: /* verw */
7501             if (!PE(s) || VM86(s))
7502                 goto illegal_op;
7503             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7504             gen_update_cc_op(s);
7505             if (op == 4) {
7506                 gen_helper_verr(cpu_env, s->T0);
7507             } else {
7508                 gen_helper_verw(cpu_env, s->T0);
7509             }
7510             set_cc_op(s, CC_OP_EFLAGS);
7511             break;
7512         default:
7513             goto unknown_op;
7514         }
7515         break;
7516 
7517     case 0x101:
7518         modrm = x86_ldub_code(env, s);
7519         switch (modrm) {
7520         CASE_MODRM_MEM_OP(0): /* sgdt */
7521             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
7522                 break;
7523             }
7524             gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ);
7525             gen_lea_modrm(env, s, modrm);
7526             tcg_gen_ld32u_tl(s->T0,
7527                              cpu_env, offsetof(CPUX86State, gdt.limit));
7528             gen_op_st_v(s, MO_16, s->T0, s->A0);
7529             gen_add_A0_im(s, 2);
7530             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base));
7531             if (dflag == MO_16) {
7532                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
7533             }
7534             gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
7535             break;
7536 
7537         case 0xc8: /* monitor */
7538             if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
7539                 goto illegal_op;
7540             }
7541             gen_update_cc_op(s);
7542             gen_update_eip_cur(s);
7543             tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
7544             gen_extu(s->aflag, s->A0);
7545             gen_add_A0_ds_seg(s);
7546             gen_helper_monitor(cpu_env, s->A0);
7547             break;
7548 
7549         case 0xc9: /* mwait */
7550             if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
7551                 goto illegal_op;
7552             }
7553             gen_update_cc_op(s);
7554             gen_update_eip_cur(s);
7555             gen_helper_mwait(cpu_env, cur_insn_len_i32(s));
7556             s->base.is_jmp = DISAS_NORETURN;
7557             break;
7558 
7559         case 0xca: /* clac */
7560             if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7561                 || CPL(s) != 0) {
7562                 goto illegal_op;
7563             }
7564             gen_helper_clac(cpu_env);
7565             s->base.is_jmp = DISAS_EOB_NEXT;
7566             break;
7567 
7568         case 0xcb: /* stac */
7569             if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7570                 || CPL(s) != 0) {
7571                 goto illegal_op;
7572             }
7573             gen_helper_stac(cpu_env);
7574             s->base.is_jmp = DISAS_EOB_NEXT;
7575             break;
7576 
7577         CASE_MODRM_MEM_OP(1): /* sidt */
7578             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
7579                 break;
7580             }
7581             gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ);
7582             gen_lea_modrm(env, s, modrm);
7583             tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.limit));
7584             gen_op_st_v(s, MO_16, s->T0, s->A0);
7585             gen_add_A0_im(s, 2);
7586             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base));
7587             if (dflag == MO_16) {
7588                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
7589             }
7590             gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
7591             break;
7592 
7593         case 0xd0: /* xgetbv */
7594             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7595                 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7596                                  | PREFIX_REPZ | PREFIX_REPNZ))) {
7597                 goto illegal_op;
7598             }
7599             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
7600             gen_helper_xgetbv(s->tmp1_i64, cpu_env, s->tmp2_i32);
7601             tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
7602             break;
7603 
7604         case 0xd1: /* xsetbv */
7605             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7606                 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7607                                  | PREFIX_REPZ | PREFIX_REPNZ))) {
7608                 goto illegal_op;
7609             }
7610             if (!check_cpl0(s)) {
7611                 break;
7612             }
7613             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
7614                                   cpu_regs[R_EDX]);
7615             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
7616             gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64);
7617             /* End TB because translation flags may change.  */
7618             s->base.is_jmp = DISAS_EOB_NEXT;
7619             break;
7620 
7621         case 0xd8: /* VMRUN */
7622             if (!SVME(s) || !PE(s)) {
7623                 goto illegal_op;
7624             }
7625             if (!check_cpl0(s)) {
7626                 break;
7627             }
7628             gen_update_cc_op(s);
7629             gen_update_eip_cur(s);
7630             gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
7631                              cur_insn_len_i32(s));
7632             tcg_gen_exit_tb(NULL, 0);
7633             s->base.is_jmp = DISAS_NORETURN;
7634             break;
7635 
7636         case 0xd9: /* VMMCALL */
7637             if (!SVME(s)) {
7638                 goto illegal_op;
7639             }
7640             gen_update_cc_op(s);
7641             gen_update_eip_cur(s);
7642             gen_helper_vmmcall(cpu_env);
7643             break;
7644 
7645         case 0xda: /* VMLOAD */
7646             if (!SVME(s) || !PE(s)) {
7647                 goto illegal_op;
7648             }
7649             if (!check_cpl0(s)) {
7650                 break;
7651             }
7652             gen_update_cc_op(s);
7653             gen_update_eip_cur(s);
7654             gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
7655             break;
7656 
7657         case 0xdb: /* VMSAVE */
7658             if (!SVME(s) || !PE(s)) {
7659                 goto illegal_op;
7660             }
7661             if (!check_cpl0(s)) {
7662                 break;
7663             }
7664             gen_update_cc_op(s);
7665             gen_update_eip_cur(s);
7666             gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
7667             break;
7668 
7669         case 0xdc: /* STGI */
7670             if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7671                 || !PE(s)) {
7672                 goto illegal_op;
7673             }
7674             if (!check_cpl0(s)) {
7675                 break;
7676             }
7677             gen_update_cc_op(s);
7678             gen_helper_stgi(cpu_env);
7679             s->base.is_jmp = DISAS_EOB_NEXT;
7680             break;
7681 
7682         case 0xdd: /* CLGI */
7683             if (!SVME(s) || !PE(s)) {
7684                 goto illegal_op;
7685             }
7686             if (!check_cpl0(s)) {
7687                 break;
7688             }
7689             gen_update_cc_op(s);
7690             gen_update_eip_cur(s);
7691             gen_helper_clgi(cpu_env);
7692             break;
7693 
7694         case 0xde: /* SKINIT */
7695             if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7696                 || !PE(s)) {
7697                 goto illegal_op;
7698             }
7699             gen_svm_check_intercept(s, SVM_EXIT_SKINIT);
7700             /* If not intercepted, not implemented -- raise #UD. */
7701             goto illegal_op;
7702 
7703         case 0xdf: /* INVLPGA */
7704             if (!SVME(s) || !PE(s)) {
7705                 goto illegal_op;
7706             }
7707             if (!check_cpl0(s)) {
7708                 break;
7709             }
7710             gen_svm_check_intercept(s, SVM_EXIT_INVLPGA);
7711             if (s->aflag == MO_64) {
7712                 tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
7713             } else {
7714                 tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]);
7715             }
7716             gen_helper_flush_page(cpu_env, s->A0);
7717             s->base.is_jmp = DISAS_EOB_NEXT;
7718             break;
7719 
7720         CASE_MODRM_MEM_OP(2): /* lgdt */
7721             if (!check_cpl0(s)) {
7722                 break;
7723             }
7724             gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE);
7725             gen_lea_modrm(env, s, modrm);
7726             gen_op_ld_v(s, MO_16, s->T1, s->A0);
7727             gen_add_A0_im(s, 2);
7728             gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
7729             if (dflag == MO_16) {
7730                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
7731             }
7732             tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base));
7733             tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, gdt.limit));
7734             break;
7735 
7736         CASE_MODRM_MEM_OP(3): /* lidt */
7737             if (!check_cpl0(s)) {
7738                 break;
7739             }
7740             gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE);
7741             gen_lea_modrm(env, s, modrm);
7742             gen_op_ld_v(s, MO_16, s->T1, s->A0);
7743             gen_add_A0_im(s, 2);
7744             gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
7745             if (dflag == MO_16) {
7746                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
7747             }
7748             tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base));
7749             tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, idt.limit));
7750             break;
7751 
7752         CASE_MODRM_OP(4): /* smsw */
7753             if (s->flags & HF_UMIP_MASK && !check_cpl0(s)) {
7754                 break;
7755             }
7756             gen_svm_check_intercept(s, SVM_EXIT_READ_CR0);
7757             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, cr[0]));
7758             /*
7759              * In 32-bit mode, the higher 16 bits of the destination
7760              * register are undefined.  In practice CR0[31:0] is stored
7761              * just like in 64-bit mode.
7762              */
7763             mod = (modrm >> 6) & 3;
7764             ot = (mod != 3 ? MO_16 : s->dflag);
7765             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7766             break;
7767         case 0xee: /* rdpkru */
7768             if (prefixes & PREFIX_LOCK) {
7769                 goto illegal_op;
7770             }
7771             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
7772             gen_helper_rdpkru(s->tmp1_i64, cpu_env, s->tmp2_i32);
7773             tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
7774             break;
7775         case 0xef: /* wrpkru */
7776             if (prefixes & PREFIX_LOCK) {
7777                 goto illegal_op;
7778             }
7779             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
7780                                   cpu_regs[R_EDX]);
7781             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
7782             gen_helper_wrpkru(cpu_env, s->tmp2_i32, s->tmp1_i64);
7783             break;
7784 
7785         CASE_MODRM_OP(6): /* lmsw */
7786             if (!check_cpl0(s)) {
7787                 break;
7788             }
7789             gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
7790             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7791             /*
7792              * Only the 4 lower bits of CR0 are modified.
7793              * PE cannot be set to zero if already set to one.
7794              */
7795             tcg_gen_ld_tl(s->T1, cpu_env, offsetof(CPUX86State, cr[0]));
7796             tcg_gen_andi_tl(s->T0, s->T0, 0xf);
7797             tcg_gen_andi_tl(s->T1, s->T1, ~0xe);
7798             tcg_gen_or_tl(s->T0, s->T0, s->T1);
7799             gen_helper_write_crN(cpu_env, tcg_constant_i32(0), s->T0);
7800             s->base.is_jmp = DISAS_EOB_NEXT;
7801             break;
7802 
7803         CASE_MODRM_MEM_OP(7): /* invlpg */
7804             if (!check_cpl0(s)) {
7805                 break;
7806             }
7807             gen_svm_check_intercept(s, SVM_EXIT_INVLPG);
7808             gen_lea_modrm(env, s, modrm);
7809             gen_helper_flush_page(cpu_env, s->A0);
7810             s->base.is_jmp = DISAS_EOB_NEXT;
7811             break;
7812 
7813         case 0xf8: /* swapgs */
7814 #ifdef TARGET_X86_64
7815             if (CODE64(s)) {
7816                 if (check_cpl0(s)) {
7817                     tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]);
7818                     tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
7819                                   offsetof(CPUX86State, kernelgsbase));
7820                     tcg_gen_st_tl(s->T0, cpu_env,
7821                                   offsetof(CPUX86State, kernelgsbase));
7822                 }
7823                 break;
7824             }
7825 #endif
7826             goto illegal_op;
7827 
7828         case 0xf9: /* rdtscp */
7829             if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
7830                 goto illegal_op;
7831             }
7832             gen_update_cc_op(s);
7833             gen_update_eip_cur(s);
7834             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7835                 gen_io_start();
7836                 s->base.is_jmp = DISAS_TOO_MANY;
7837             }
7838             gen_helper_rdtscp(cpu_env);
7839             break;
7840 
7841         default:
7842             goto unknown_op;
7843         }
7844         break;
7845 
7846     case 0x108: /* invd */
7847     case 0x109: /* wbinvd */
7848         if (check_cpl0(s)) {
7849             gen_svm_check_intercept(s, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7850             /* nothing to do */
7851         }
7852         break;
7853     case 0x63: /* arpl or movslS (x86_64) */
7854 #ifdef TARGET_X86_64
7855         if (CODE64(s)) {
7856             int d_ot;
7857             /* d_ot is the size of destination */
7858             d_ot = dflag;
7859 
7860             modrm = x86_ldub_code(env, s);
7861             reg = ((modrm >> 3) & 7) | REX_R(s);
7862             mod = (modrm >> 6) & 3;
7863             rm = (modrm & 7) | REX_B(s);
7864 
7865             if (mod == 3) {
7866                 gen_op_mov_v_reg(s, MO_32, s->T0, rm);
7867                 /* sign extend */
7868                 if (d_ot == MO_64) {
7869                     tcg_gen_ext32s_tl(s->T0, s->T0);
7870                 }
7871                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
7872             } else {
7873                 gen_lea_modrm(env, s, modrm);
7874                 gen_op_ld_v(s, MO_32 | MO_SIGN, s->T0, s->A0);
7875                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
7876             }
7877         } else
7878 #endif
7879         {
7880             TCGLabel *label1;
7881             TCGv t0, t1, t2, a0;
7882 
7883             if (!PE(s) || VM86(s))
7884                 goto illegal_op;
7885             t0 = tcg_temp_local_new();
7886             t1 = tcg_temp_local_new();
7887             t2 = tcg_temp_local_new();
7888             ot = MO_16;
7889             modrm = x86_ldub_code(env, s);
7890             reg = (modrm >> 3) & 7;
7891             mod = (modrm >> 6) & 3;
7892             rm = modrm & 7;
7893             if (mod != 3) {
7894                 gen_lea_modrm(env, s, modrm);
7895                 gen_op_ld_v(s, ot, t0, s->A0);
7896                 a0 = tcg_temp_local_new();
7897                 tcg_gen_mov_tl(a0, s->A0);
7898             } else {
7899                 gen_op_mov_v_reg(s, ot, t0, rm);
7900                 a0 = NULL;
7901             }
7902             gen_op_mov_v_reg(s, ot, t1, reg);
7903             tcg_gen_andi_tl(s->tmp0, t0, 3);
7904             tcg_gen_andi_tl(t1, t1, 3);
7905             tcg_gen_movi_tl(t2, 0);
7906             label1 = gen_new_label();
7907             tcg_gen_brcond_tl(TCG_COND_GE, s->tmp0, t1, label1);
7908             tcg_gen_andi_tl(t0, t0, ~3);
7909             tcg_gen_or_tl(t0, t0, t1);
7910             tcg_gen_movi_tl(t2, CC_Z);
7911             gen_set_label(label1);
7912             if (mod != 3) {
7913                 gen_op_st_v(s, ot, t0, a0);
7914                 tcg_temp_free(a0);
7915            } else {
7916                 gen_op_mov_reg_v(s, ot, rm, t0);
7917             }
7918             gen_compute_eflags(s);
7919             tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7920             tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7921             tcg_temp_free(t0);
7922             tcg_temp_free(t1);
7923             tcg_temp_free(t2);
7924         }
7925         break;
7926     case 0x102: /* lar */
7927     case 0x103: /* lsl */
7928         {
7929             TCGLabel *label1;
7930             TCGv t0;
7931             if (!PE(s) || VM86(s))
7932                 goto illegal_op;
7933             ot = dflag != MO_16 ? MO_32 : MO_16;
7934             modrm = x86_ldub_code(env, s);
7935             reg = ((modrm >> 3) & 7) | REX_R(s);
7936             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7937             t0 = tcg_temp_local_new();
7938             gen_update_cc_op(s);
7939             if (b == 0x102) {
7940                 gen_helper_lar(t0, cpu_env, s->T0);
7941             } else {
7942                 gen_helper_lsl(t0, cpu_env, s->T0);
7943             }
7944             tcg_gen_andi_tl(s->tmp0, cpu_cc_src, CC_Z);
7945             label1 = gen_new_label();
7946             tcg_gen_brcondi_tl(TCG_COND_EQ, s->tmp0, 0, label1);
7947             gen_op_mov_reg_v(s, ot, reg, t0);
7948             gen_set_label(label1);
7949             set_cc_op(s, CC_OP_EFLAGS);
7950             tcg_temp_free(t0);
7951         }
7952         break;
7953     case 0x118:
7954         modrm = x86_ldub_code(env, s);
7955         mod = (modrm >> 6) & 3;
7956         op = (modrm >> 3) & 7;
7957         switch(op) {
7958         case 0: /* prefetchnta */
7959         case 1: /* prefetchnt0 */
7960         case 2: /* prefetchnt0 */
7961         case 3: /* prefetchnt0 */
7962             if (mod == 3)
7963                 goto illegal_op;
7964             gen_nop_modrm(env, s, modrm);
7965             /* nothing more to do */
7966             break;
7967         default: /* nop (multi byte) */
7968             gen_nop_modrm(env, s, modrm);
7969             break;
7970         }
7971         break;
7972     case 0x11a:
7973         modrm = x86_ldub_code(env, s);
7974         if (s->flags & HF_MPX_EN_MASK) {
7975             mod = (modrm >> 6) & 3;
7976             reg = ((modrm >> 3) & 7) | REX_R(s);
7977             if (prefixes & PREFIX_REPZ) {
7978                 /* bndcl */
7979                 if (reg >= 4
7980                     || (prefixes & PREFIX_LOCK)
7981                     || s->aflag == MO_16) {
7982                     goto illegal_op;
7983                 }
7984                 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
7985             } else if (prefixes & PREFIX_REPNZ) {
7986                 /* bndcu */
7987                 if (reg >= 4
7988                     || (prefixes & PREFIX_LOCK)
7989                     || s->aflag == MO_16) {
7990                     goto illegal_op;
7991                 }
7992                 TCGv_i64 notu = tcg_temp_new_i64();
7993                 tcg_gen_not_i64(notu, cpu_bndu[reg]);
7994                 gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
7995                 tcg_temp_free_i64(notu);
7996             } else if (prefixes & PREFIX_DATA) {
7997                 /* bndmov -- from reg/mem */
7998                 if (reg >= 4 || s->aflag == MO_16) {
7999                     goto illegal_op;
8000                 }
8001                 if (mod == 3) {
8002                     int reg2 = (modrm & 7) | REX_B(s);
8003                     if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
8004                         goto illegal_op;
8005                     }
8006                     if (s->flags & HF_MPX_IU_MASK) {
8007                         tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
8008                         tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
8009                     }
8010                 } else {
8011                     gen_lea_modrm(env, s, modrm);
8012                     if (CODE64(s)) {
8013                         tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
8014                                             s->mem_index, MO_LEUQ);
8015                         tcg_gen_addi_tl(s->A0, s->A0, 8);
8016                         tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
8017                                             s->mem_index, MO_LEUQ);
8018                     } else {
8019                         tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
8020                                             s->mem_index, MO_LEUL);
8021                         tcg_gen_addi_tl(s->A0, s->A0, 4);
8022                         tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
8023                                             s->mem_index, MO_LEUL);
8024                     }
8025                     /* bnd registers are now in-use */
8026                     gen_set_hflag(s, HF_MPX_IU_MASK);
8027                 }
8028             } else if (mod != 3) {
8029                 /* bndldx */
8030                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
8031                 if (reg >= 4
8032                     || (prefixes & PREFIX_LOCK)
8033                     || s->aflag == MO_16
8034                     || a.base < -1) {
8035                     goto illegal_op;
8036                 }
8037                 if (a.base >= 0) {
8038                     tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
8039                 } else {
8040                     tcg_gen_movi_tl(s->A0, 0);
8041                 }
8042                 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
8043                 if (a.index >= 0) {
8044                     tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
8045                 } else {
8046                     tcg_gen_movi_tl(s->T0, 0);
8047                 }
8048                 if (CODE64(s)) {
8049                     gen_helper_bndldx64(cpu_bndl[reg], cpu_env, s->A0, s->T0);
8050                     tcg_gen_ld_i64(cpu_bndu[reg], cpu_env,
8051                                    offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
8052                 } else {
8053                     gen_helper_bndldx32(cpu_bndu[reg], cpu_env, s->A0, s->T0);
8054                     tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
8055                     tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
8056                 }
8057                 gen_set_hflag(s, HF_MPX_IU_MASK);
8058             }
8059         }
8060         gen_nop_modrm(env, s, modrm);
8061         break;
8062     case 0x11b:
8063         modrm = x86_ldub_code(env, s);
8064         if (s->flags & HF_MPX_EN_MASK) {
8065             mod = (modrm >> 6) & 3;
8066             reg = ((modrm >> 3) & 7) | REX_R(s);
8067             if (mod != 3 && (prefixes & PREFIX_REPZ)) {
8068                 /* bndmk */
8069                 if (reg >= 4
8070                     || (prefixes & PREFIX_LOCK)
8071                     || s->aflag == MO_16) {
8072                     goto illegal_op;
8073                 }
8074                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
8075                 if (a.base >= 0) {
8076                     tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
8077                     if (!CODE64(s)) {
8078                         tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
8079                     }
8080                 } else if (a.base == -1) {
8081                     /* no base register has lower bound of 0 */
8082                     tcg_gen_movi_i64(cpu_bndl[reg], 0);
8083                 } else {
8084                     /* rip-relative generates #ud */
8085                     goto illegal_op;
8086                 }
8087                 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, a, false));
8088                 if (!CODE64(s)) {
8089                     tcg_gen_ext32u_tl(s->A0, s->A0);
8090                 }
8091                 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0);
8092                 /* bnd registers are now in-use */
8093                 gen_set_hflag(s, HF_MPX_IU_MASK);
8094                 break;
8095             } else if (prefixes & PREFIX_REPNZ) {
8096                 /* bndcn */
8097                 if (reg >= 4
8098                     || (prefixes & PREFIX_LOCK)
8099                     || s->aflag == MO_16) {
8100                     goto illegal_op;
8101                 }
8102                 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
8103             } else if (prefixes & PREFIX_DATA) {
8104                 /* bndmov -- to reg/mem */
8105                 if (reg >= 4 || s->aflag == MO_16) {
8106                     goto illegal_op;
8107                 }
8108                 if (mod == 3) {
8109                     int reg2 = (modrm & 7) | REX_B(s);
8110                     if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
8111                         goto illegal_op;
8112                     }
8113                     if (s->flags & HF_MPX_IU_MASK) {
8114                         tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
8115                         tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
8116                     }
8117                 } else {
8118                     gen_lea_modrm(env, s, modrm);
8119                     if (CODE64(s)) {
8120                         tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
8121                                             s->mem_index, MO_LEUQ);
8122                         tcg_gen_addi_tl(s->A0, s->A0, 8);
8123                         tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
8124                                             s->mem_index, MO_LEUQ);
8125                     } else {
8126                         tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
8127                                             s->mem_index, MO_LEUL);
8128                         tcg_gen_addi_tl(s->A0, s->A0, 4);
8129                         tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
8130                                             s->mem_index, MO_LEUL);
8131                     }
8132                 }
8133             } else if (mod != 3) {
8134                 /* bndstx */
8135                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
8136                 if (reg >= 4
8137                     || (prefixes & PREFIX_LOCK)
8138                     || s->aflag == MO_16
8139                     || a.base < -1) {
8140                     goto illegal_op;
8141                 }
8142                 if (a.base >= 0) {
8143                     tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
8144                 } else {
8145                     tcg_gen_movi_tl(s->A0, 0);
8146                 }
8147                 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
8148                 if (a.index >= 0) {
8149                     tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
8150                 } else {
8151                     tcg_gen_movi_tl(s->T0, 0);
8152                 }
8153                 if (CODE64(s)) {
8154                     gen_helper_bndstx64(cpu_env, s->A0, s->T0,
8155                                         cpu_bndl[reg], cpu_bndu[reg]);
8156                 } else {
8157                     gen_helper_bndstx32(cpu_env, s->A0, s->T0,
8158                                         cpu_bndl[reg], cpu_bndu[reg]);
8159                 }
8160             }
8161         }
8162         gen_nop_modrm(env, s, modrm);
8163         break;
8164     case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
8165         modrm = x86_ldub_code(env, s);
8166         gen_nop_modrm(env, s, modrm);
8167         break;
8168 
8169     case 0x120: /* mov reg, crN */
8170     case 0x122: /* mov crN, reg */
8171         if (!check_cpl0(s)) {
8172             break;
8173         }
8174         modrm = x86_ldub_code(env, s);
8175         /*
8176          * Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8177          * AMD documentation (24594.pdf) and testing of Intel 386 and 486
8178          * processors all show that the mod bits are assumed to be 1's,
8179          * regardless of actual values.
8180          */
8181         rm = (modrm & 7) | REX_B(s);
8182         reg = ((modrm >> 3) & 7) | REX_R(s);
8183         switch (reg) {
8184         case 0:
8185             if ((prefixes & PREFIX_LOCK) &&
8186                 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
8187                 reg = 8;
8188             }
8189             break;
8190         case 2:
8191         case 3:
8192         case 4:
8193         case 8:
8194             break;
8195         default:
8196             goto unknown_op;
8197         }
8198         ot  = (CODE64(s) ? MO_64 : MO_32);
8199 
8200         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
8201             gen_io_start();
8202             s->base.is_jmp = DISAS_TOO_MANY;
8203         }
8204         if (b & 2) {
8205             gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
8206             gen_op_mov_v_reg(s, ot, s->T0, rm);
8207             gen_helper_write_crN(cpu_env, tcg_constant_i32(reg), s->T0);
8208             s->base.is_jmp = DISAS_EOB_NEXT;
8209         } else {
8210             gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
8211             gen_helper_read_crN(s->T0, cpu_env, tcg_constant_i32(reg));
8212             gen_op_mov_reg_v(s, ot, rm, s->T0);
8213         }
8214         break;
8215 
8216     case 0x121: /* mov reg, drN */
8217     case 0x123: /* mov drN, reg */
8218         if (check_cpl0(s)) {
8219             modrm = x86_ldub_code(env, s);
8220             /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8221              * AMD documentation (24594.pdf) and testing of
8222              * intel 386 and 486 processors all show that the mod bits
8223              * are assumed to be 1's, regardless of actual values.
8224              */
8225             rm = (modrm & 7) | REX_B(s);
8226             reg = ((modrm >> 3) & 7) | REX_R(s);
8227             if (CODE64(s))
8228                 ot = MO_64;
8229             else
8230                 ot = MO_32;
8231             if (reg >= 8) {
8232                 goto illegal_op;
8233             }
8234             if (b & 2) {
8235                 gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg);
8236                 gen_op_mov_v_reg(s, ot, s->T0, rm);
8237                 tcg_gen_movi_i32(s->tmp2_i32, reg);
8238                 gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0);
8239                 s->base.is_jmp = DISAS_EOB_NEXT;
8240             } else {
8241                 gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg);
8242                 tcg_gen_movi_i32(s->tmp2_i32, reg);
8243                 gen_helper_get_dr(s->T0, cpu_env, s->tmp2_i32);
8244                 gen_op_mov_reg_v(s, ot, rm, s->T0);
8245             }
8246         }
8247         break;
8248     case 0x106: /* clts */
8249         if (check_cpl0(s)) {
8250             gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
8251             gen_helper_clts(cpu_env);
8252             /* abort block because static cpu state changed */
8253             s->base.is_jmp = DISAS_EOB_NEXT;
8254         }
8255         break;
8256     /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8257     case 0x1c3: /* MOVNTI reg, mem */
8258         if (!(s->cpuid_features & CPUID_SSE2))
8259             goto illegal_op;
8260         ot = mo_64_32(dflag);
8261         modrm = x86_ldub_code(env, s);
8262         mod = (modrm >> 6) & 3;
8263         if (mod == 3)
8264             goto illegal_op;
8265         reg = ((modrm >> 3) & 7) | REX_R(s);
8266         /* generate a generic store */
8267         gen_ldst_modrm(env, s, modrm, ot, reg, 1);
8268         break;
8269     case 0x1ae:
8270         modrm = x86_ldub_code(env, s);
8271         switch (modrm) {
8272         CASE_MODRM_MEM_OP(0): /* fxsave */
8273             if (!(s->cpuid_features & CPUID_FXSR)
8274                 || (prefixes & PREFIX_LOCK)) {
8275                 goto illegal_op;
8276             }
8277             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8278                 gen_exception(s, EXCP07_PREX);
8279                 break;
8280             }
8281             gen_lea_modrm(env, s, modrm);
8282             gen_helper_fxsave(cpu_env, s->A0);
8283             break;
8284 
8285         CASE_MODRM_MEM_OP(1): /* fxrstor */
8286             if (!(s->cpuid_features & CPUID_FXSR)
8287                 || (prefixes & PREFIX_LOCK)) {
8288                 goto illegal_op;
8289             }
8290             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8291                 gen_exception(s, EXCP07_PREX);
8292                 break;
8293             }
8294             gen_lea_modrm(env, s, modrm);
8295             gen_helper_fxrstor(cpu_env, s->A0);
8296             break;
8297 
8298         CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8299             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8300                 goto illegal_op;
8301             }
8302             if (s->flags & HF_TS_MASK) {
8303                 gen_exception(s, EXCP07_PREX);
8304                 break;
8305             }
8306             gen_lea_modrm(env, s, modrm);
8307             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
8308             gen_helper_ldmxcsr(cpu_env, s->tmp2_i32);
8309             break;
8310 
8311         CASE_MODRM_MEM_OP(3): /* stmxcsr */
8312             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8313                 goto illegal_op;
8314             }
8315             if (s->flags & HF_TS_MASK) {
8316                 gen_exception(s, EXCP07_PREX);
8317                 break;
8318             }
8319             gen_helper_update_mxcsr(cpu_env);
8320             gen_lea_modrm(env, s, modrm);
8321             tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, mxcsr));
8322             gen_op_st_v(s, MO_32, s->T0, s->A0);
8323             break;
8324 
8325         CASE_MODRM_MEM_OP(4): /* xsave */
8326             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8327                 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8328                                 | PREFIX_REPZ | PREFIX_REPNZ))) {
8329                 goto illegal_op;
8330             }
8331             gen_lea_modrm(env, s, modrm);
8332             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
8333                                   cpu_regs[R_EDX]);
8334             gen_helper_xsave(cpu_env, s->A0, s->tmp1_i64);
8335             break;
8336 
8337         CASE_MODRM_MEM_OP(5): /* xrstor */
8338             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8339                 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8340                                 | PREFIX_REPZ | PREFIX_REPNZ))) {
8341                 goto illegal_op;
8342             }
8343             gen_lea_modrm(env, s, modrm);
8344             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
8345                                   cpu_regs[R_EDX]);
8346             gen_helper_xrstor(cpu_env, s->A0, s->tmp1_i64);
8347             /* XRSTOR is how MPX is enabled, which changes how
8348                we translate.  Thus we need to end the TB.  */
8349             s->base.is_jmp = DISAS_EOB_NEXT;
8350             break;
8351 
8352         CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8353             if (prefixes & PREFIX_LOCK) {
8354                 goto illegal_op;
8355             }
8356             if (prefixes & PREFIX_DATA) {
8357                 /* clwb */
8358                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
8359                     goto illegal_op;
8360                 }
8361                 gen_nop_modrm(env, s, modrm);
8362             } else {
8363                 /* xsaveopt */
8364                 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8365                     || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
8366                     || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
8367                     goto illegal_op;
8368                 }
8369                 gen_lea_modrm(env, s, modrm);
8370                 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
8371                                       cpu_regs[R_EDX]);
8372                 gen_helper_xsaveopt(cpu_env, s->A0, s->tmp1_i64);
8373             }
8374             break;
8375 
8376         CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8377             if (prefixes & PREFIX_LOCK) {
8378                 goto illegal_op;
8379             }
8380             if (prefixes & PREFIX_DATA) {
8381                 /* clflushopt */
8382                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
8383                     goto illegal_op;
8384                 }
8385             } else {
8386                 /* clflush */
8387                 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))
8388                     || !(s->cpuid_features & CPUID_CLFLUSH)) {
8389                     goto illegal_op;
8390                 }
8391             }
8392             gen_nop_modrm(env, s, modrm);
8393             break;
8394 
8395         case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8396         case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
8397         case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8398         case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
8399             if (CODE64(s)
8400                 && (prefixes & PREFIX_REPZ)
8401                 && !(prefixes & PREFIX_LOCK)
8402                 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
8403                 TCGv base, treg, src, dst;
8404 
8405                 /* Preserve hflags bits by testing CR4 at runtime.  */
8406                 tcg_gen_movi_i32(s->tmp2_i32, CR4_FSGSBASE_MASK);
8407                 gen_helper_cr4_testbit(cpu_env, s->tmp2_i32);
8408 
8409                 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
8410                 treg = cpu_regs[(modrm & 7) | REX_B(s)];
8411 
8412                 if (modrm & 0x10) {
8413                     /* wr*base */
8414                     dst = base, src = treg;
8415                 } else {
8416                     /* rd*base */
8417                     dst = treg, src = base;
8418                 }
8419 
8420                 if (s->dflag == MO_32) {
8421                     tcg_gen_ext32u_tl(dst, src);
8422                 } else {
8423                     tcg_gen_mov_tl(dst, src);
8424                 }
8425                 break;
8426             }
8427             goto unknown_op;
8428 
8429         case 0xf8: /* sfence / pcommit */
8430             if (prefixes & PREFIX_DATA) {
8431                 /* pcommit */
8432                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
8433                     || (prefixes & PREFIX_LOCK)) {
8434                     goto illegal_op;
8435                 }
8436                 break;
8437             }
8438             /* fallthru */
8439         case 0xf9 ... 0xff: /* sfence */
8440             if (!(s->cpuid_features & CPUID_SSE)
8441                 || (prefixes & PREFIX_LOCK)) {
8442                 goto illegal_op;
8443             }
8444             tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
8445             break;
8446         case 0xe8 ... 0xef: /* lfence */
8447             if (!(s->cpuid_features & CPUID_SSE)
8448                 || (prefixes & PREFIX_LOCK)) {
8449                 goto illegal_op;
8450             }
8451             tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
8452             break;
8453         case 0xf0 ... 0xf7: /* mfence */
8454             if (!(s->cpuid_features & CPUID_SSE2)
8455                 || (prefixes & PREFIX_LOCK)) {
8456                 goto illegal_op;
8457             }
8458             tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8459             break;
8460 
8461         default:
8462             goto unknown_op;
8463         }
8464         break;
8465 
8466     case 0x10d: /* 3DNow! prefetch(w) */
8467         modrm = x86_ldub_code(env, s);
8468         mod = (modrm >> 6) & 3;
8469         if (mod == 3)
8470             goto illegal_op;
8471         gen_nop_modrm(env, s, modrm);
8472         break;
8473     case 0x1aa: /* rsm */
8474         gen_svm_check_intercept(s, SVM_EXIT_RSM);
8475         if (!(s->flags & HF_SMM_MASK))
8476             goto illegal_op;
8477 #ifdef CONFIG_USER_ONLY
8478         /* we should not be in SMM mode */
8479         g_assert_not_reached();
8480 #else
8481         gen_update_cc_op(s);
8482         gen_update_eip_next(s);
8483         gen_helper_rsm(cpu_env);
8484 #endif /* CONFIG_USER_ONLY */
8485         s->base.is_jmp = DISAS_EOB_ONLY;
8486         break;
8487     case 0x1b8: /* SSE4.2 popcnt */
8488         if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
8489              PREFIX_REPZ)
8490             goto illegal_op;
8491         if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
8492             goto illegal_op;
8493 
8494         modrm = x86_ldub_code(env, s);
8495         reg = ((modrm >> 3) & 7) | REX_R(s);
8496 
8497         if (s->prefix & PREFIX_DATA) {
8498             ot = MO_16;
8499         } else {
8500             ot = mo_64_32(dflag);
8501         }
8502 
8503         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
8504         gen_extu(ot, s->T0);
8505         tcg_gen_mov_tl(cpu_cc_src, s->T0);
8506         tcg_gen_ctpop_tl(s->T0, s->T0);
8507         gen_op_mov_reg_v(s, ot, reg, s->T0);
8508 
8509         set_cc_op(s, CC_OP_POPCNT);
8510         break;
8511     case 0x10e ... 0x10f:
8512         /* 3DNow! instructions, ignore prefixes */
8513         s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
8514         /* fall through */
8515     case 0x110 ... 0x117:
8516     case 0x128 ... 0x12f:
8517     case 0x138 ... 0x13a:
8518     case 0x150 ... 0x179:
8519     case 0x17c ... 0x17f:
8520     case 0x1c2:
8521     case 0x1c4 ... 0x1c6:
8522     case 0x1d0 ... 0x1fe:
8523         gen_sse(env, s, b);
8524         break;
8525     default:
8526         goto unknown_op;
8527     }
8528     return true;
8529  illegal_op:
8530     gen_illegal_opcode(s);
8531     return true;
8532  unknown_op:
8533     gen_unknown_opcode(env, s);
8534     return true;
8535 }
8536 
8537 void tcg_x86_init(void)
8538 {
8539     static const char reg_names[CPU_NB_REGS][4] = {
8540 #ifdef TARGET_X86_64
8541         [R_EAX] = "rax",
8542         [R_EBX] = "rbx",
8543         [R_ECX] = "rcx",
8544         [R_EDX] = "rdx",
8545         [R_ESI] = "rsi",
8546         [R_EDI] = "rdi",
8547         [R_EBP] = "rbp",
8548         [R_ESP] = "rsp",
8549         [8]  = "r8",
8550         [9]  = "r9",
8551         [10] = "r10",
8552         [11] = "r11",
8553         [12] = "r12",
8554         [13] = "r13",
8555         [14] = "r14",
8556         [15] = "r15",
8557 #else
8558         [R_EAX] = "eax",
8559         [R_EBX] = "ebx",
8560         [R_ECX] = "ecx",
8561         [R_EDX] = "edx",
8562         [R_ESI] = "esi",
8563         [R_EDI] = "edi",
8564         [R_EBP] = "ebp",
8565         [R_ESP] = "esp",
8566 #endif
8567     };
8568     static const char eip_name[] = {
8569 #ifdef TARGET_X86_64
8570         "rip"
8571 #else
8572         "eip"
8573 #endif
8574     };
8575     static const char seg_base_names[6][8] = {
8576         [R_CS] = "cs_base",
8577         [R_DS] = "ds_base",
8578         [R_ES] = "es_base",
8579         [R_FS] = "fs_base",
8580         [R_GS] = "gs_base",
8581         [R_SS] = "ss_base",
8582     };
8583     static const char bnd_regl_names[4][8] = {
8584         "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8585     };
8586     static const char bnd_regu_names[4][8] = {
8587         "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8588     };
8589     int i;
8590 
8591     cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
8592                                        offsetof(CPUX86State, cc_op), "cc_op");
8593     cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
8594                                     "cc_dst");
8595     cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src),
8596                                     "cc_src");
8597     cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
8598                                      "cc_src2");
8599     cpu_eip = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, eip), eip_name);
8600 
8601     for (i = 0; i < CPU_NB_REGS; ++i) {
8602         cpu_regs[i] = tcg_global_mem_new(cpu_env,
8603                                          offsetof(CPUX86State, regs[i]),
8604                                          reg_names[i]);
8605     }
8606 
8607     for (i = 0; i < 6; ++i) {
8608         cpu_seg_base[i]
8609             = tcg_global_mem_new(cpu_env,
8610                                  offsetof(CPUX86State, segs[i].base),
8611                                  seg_base_names[i]);
8612     }
8613 
8614     for (i = 0; i < 4; ++i) {
8615         cpu_bndl[i]
8616             = tcg_global_mem_new_i64(cpu_env,
8617                                      offsetof(CPUX86State, bnd_regs[i].lb),
8618                                      bnd_regl_names[i]);
8619         cpu_bndu[i]
8620             = tcg_global_mem_new_i64(cpu_env,
8621                                      offsetof(CPUX86State, bnd_regs[i].ub),
8622                                      bnd_regu_names[i]);
8623     }
8624 }
8625 
8626 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
8627 {
8628     DisasContext *dc = container_of(dcbase, DisasContext, base);
8629     CPUX86State *env = cpu->env_ptr;
8630     uint32_t flags = dc->base.tb->flags;
8631     uint32_t cflags = tb_cflags(dc->base.tb);
8632     int cpl = (flags >> HF_CPL_SHIFT) & 3;
8633     int iopl = (flags >> IOPL_SHIFT) & 3;
8634 
8635     dc->cs_base = dc->base.tb->cs_base;
8636     dc->pc_save = dc->base.pc_next;
8637     dc->flags = flags;
8638 #ifndef CONFIG_USER_ONLY
8639     dc->cpl = cpl;
8640     dc->iopl = iopl;
8641 #endif
8642 
8643     /* We make some simplifying assumptions; validate they're correct. */
8644     g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0));
8645     g_assert(CPL(dc) == cpl);
8646     g_assert(IOPL(dc) == iopl);
8647     g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0));
8648     g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0));
8649     g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0));
8650     g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0));
8651     g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
8652     g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
8653     g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0));
8654     g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0));
8655 
8656     dc->cc_op = CC_OP_DYNAMIC;
8657     dc->cc_op_dirty = false;
8658     dc->popl_esp_hack = 0;
8659     /* select memory access functions */
8660     dc->mem_index = 0;
8661 #ifdef CONFIG_SOFTMMU
8662     dc->mem_index = cpu_mmu_index(env, false);
8663 #endif
8664     dc->cpuid_features = env->features[FEAT_1_EDX];
8665     dc->cpuid_ext_features = env->features[FEAT_1_ECX];
8666     dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
8667     dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
8668     dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
8669     dc->cpuid_7_0_ecx_features = env->features[FEAT_7_0_ECX];
8670     dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
8671     dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) ||
8672                     (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
8673     /*
8674      * If jmp_opt, we want to handle each string instruction individually.
8675      * For icount also disable repz optimization so that each iteration
8676      * is accounted separately.
8677      */
8678     dc->repz_opt = !dc->jmp_opt && !(cflags & CF_USE_ICOUNT);
8679 
8680     dc->T0 = tcg_temp_new();
8681     dc->T1 = tcg_temp_new();
8682     dc->A0 = tcg_temp_new();
8683 
8684     dc->tmp0 = tcg_temp_new();
8685     dc->tmp1_i64 = tcg_temp_new_i64();
8686     dc->tmp2_i32 = tcg_temp_new_i32();
8687     dc->tmp3_i32 = tcg_temp_new_i32();
8688     dc->tmp4 = tcg_temp_new();
8689     dc->ptr0 = tcg_temp_new_ptr();
8690     dc->ptr1 = tcg_temp_new_ptr();
8691     dc->ptr2 = tcg_temp_new_ptr();
8692     dc->cc_srcT = tcg_temp_local_new();
8693 }
8694 
8695 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
8696 {
8697 }
8698 
8699 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
8700 {
8701     DisasContext *dc = container_of(dcbase, DisasContext, base);
8702     target_ulong pc_arg = dc->base.pc_next;
8703 
8704     dc->prev_insn_end = tcg_last_op();
8705     if (TARGET_TB_PCREL) {
8706         pc_arg -= dc->cs_base;
8707         pc_arg &= ~TARGET_PAGE_MASK;
8708     }
8709     tcg_gen_insn_start(pc_arg, dc->cc_op);
8710 }
8711 
8712 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
8713 {
8714     DisasContext *dc = container_of(dcbase, DisasContext, base);
8715 
8716 #ifdef TARGET_VSYSCALL_PAGE
8717     /*
8718      * Detect entry into the vsyscall page and invoke the syscall.
8719      */
8720     if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) {
8721         gen_exception(dc, EXCP_VSYSCALL);
8722         dc->base.pc_next = dc->pc + 1;
8723         return;
8724     }
8725 #endif
8726 
8727     if (disas_insn(dc, cpu)) {
8728         target_ulong pc_next = dc->pc;
8729         dc->base.pc_next = pc_next;
8730 
8731         if (dc->base.is_jmp == DISAS_NEXT) {
8732             if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
8733                 /*
8734                  * If single step mode, we generate only one instruction and
8735                  * generate an exception.
8736                  * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8737                  * the flag and abort the translation to give the irqs a
8738                  * chance to happen.
8739                  */
8740                 dc->base.is_jmp = DISAS_EOB_NEXT;
8741             } else if (!is_same_page(&dc->base, pc_next)) {
8742                 dc->base.is_jmp = DISAS_TOO_MANY;
8743             }
8744         }
8745     }
8746 }
8747 
8748 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
8749 {
8750     DisasContext *dc = container_of(dcbase, DisasContext, base);
8751 
8752     switch (dc->base.is_jmp) {
8753     case DISAS_NORETURN:
8754         break;
8755     case DISAS_TOO_MANY:
8756         gen_update_cc_op(dc);
8757         gen_jmp_rel_csize(dc, 0, 0);
8758         break;
8759     case DISAS_EOB_NEXT:
8760         gen_update_cc_op(dc);
8761         gen_update_eip_cur(dc);
8762         /* fall through */
8763     case DISAS_EOB_ONLY:
8764         gen_eob(dc);
8765         break;
8766     case DISAS_EOB_INHIBIT_IRQ:
8767         gen_update_cc_op(dc);
8768         gen_update_eip_cur(dc);
8769         gen_eob_inhibit_irq(dc, true);
8770         break;
8771     case DISAS_JUMP:
8772         gen_jr(dc);
8773         break;
8774     default:
8775         g_assert_not_reached();
8776     }
8777 }
8778 
8779 static void i386_tr_disas_log(const DisasContextBase *dcbase,
8780                               CPUState *cpu, FILE *logfile)
8781 {
8782     DisasContext *dc = container_of(dcbase, DisasContext, base);
8783 
8784     fprintf(logfile, "IN: %s\n", lookup_symbol(dc->base.pc_first));
8785     target_disas(logfile, cpu, dc->base.pc_first, dc->base.tb->size);
8786 }
8787 
8788 static const TranslatorOps i386_tr_ops = {
8789     .init_disas_context = i386_tr_init_disas_context,
8790     .tb_start           = i386_tr_tb_start,
8791     .insn_start         = i386_tr_insn_start,
8792     .translate_insn     = i386_tr_translate_insn,
8793     .tb_stop            = i386_tr_tb_stop,
8794     .disas_log          = i386_tr_disas_log,
8795 };
8796 
8797 /* generate intermediate code for basic block 'tb'.  */
8798 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns,
8799                            target_ulong pc, void *host_pc)
8800 {
8801     DisasContext dc;
8802 
8803     translator_loop(cpu, tb, max_insns, pc, host_pc, &i386_tr_ops, &dc.base);
8804 }
8805 
8806 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
8807                           target_ulong *data)
8808 {
8809     int cc_op = data[1];
8810 
8811     if (TARGET_TB_PCREL) {
8812         env->eip = (env->eip & TARGET_PAGE_MASK) | data[0];
8813     } else {
8814         env->eip = data[0] - tb->cs_base;
8815     }
8816     if (cc_op != CC_OP_DYNAMIC) {
8817         env->cc_op = cc_op;
8818     }
8819 }
8820