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