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