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