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