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