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-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         target_ulong pc = s->pc_start, end = s->pc;
2506         qemu_log_lock();
2507         qemu_log("ILLOPC: " TARGET_FMT_lx ":", pc);
2508         for (; pc < end; ++pc) {
2509             qemu_log(" %02x", cpu_ldub_code(env, pc));
2510         }
2511         qemu_log("\n");
2512         qemu_log_unlock();
2513     }
2514 }
2515 
2516 /* an interrupt is different from an exception because of the
2517    privilege checks */
gen_interrupt(DisasContext * s,int intno,target_ulong cur_eip,target_ulong next_eip)2518 static void gen_interrupt(DisasContext *s, int intno,
2519                           target_ulong cur_eip, target_ulong next_eip)
2520 {
2521     gen_update_cc_op(s);
2522     gen_jmp_im(s, cur_eip);
2523     gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
2524                                tcg_const_i32(next_eip - cur_eip));
2525     s->base.is_jmp = DISAS_NORETURN;
2526 }
2527 
gen_debug(DisasContext * s,target_ulong cur_eip)2528 static void gen_debug(DisasContext *s, target_ulong cur_eip)
2529 {
2530     gen_update_cc_op(s);
2531     gen_jmp_im(s, cur_eip);
2532     gen_helper_debug(cpu_env);
2533     s->base.is_jmp = DISAS_NORETURN;
2534 }
2535 
gen_set_hflag(DisasContext * s,uint32_t mask)2536 static void gen_set_hflag(DisasContext *s, uint32_t mask)
2537 {
2538     if ((s->flags & mask) == 0) {
2539         TCGv_i32 t = tcg_temp_new_i32();
2540         tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2541         tcg_gen_ori_i32(t, t, mask);
2542         tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2543         tcg_temp_free_i32(t);
2544         s->flags |= mask;
2545     }
2546 }
2547 
gen_reset_hflag(DisasContext * s,uint32_t mask)2548 static void gen_reset_hflag(DisasContext *s, uint32_t mask)
2549 {
2550     if (s->flags & mask) {
2551         TCGv_i32 t = tcg_temp_new_i32();
2552         tcg_gen_ld_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2553         tcg_gen_andi_i32(t, t, ~mask);
2554         tcg_gen_st_i32(t, cpu_env, offsetof(CPUX86State, hflags));
2555         tcg_temp_free_i32(t);
2556         s->flags &= ~mask;
2557     }
2558 }
2559 
2560 /* Clear BND registers during legacy branches.  */
gen_bnd_jmp(DisasContext * s)2561 static void gen_bnd_jmp(DisasContext *s)
2562 {
2563     /* Clear the registers only if BND prefix is missing, MPX is enabled,
2564        and if the BNDREGs are known to be in use (non-zero) already.
2565        The helper itself will check BNDPRESERVE at runtime.  */
2566     if ((s->prefix & PREFIX_REPNZ) == 0
2567         && (s->flags & HF_MPX_EN_MASK) != 0
2568         && (s->flags & HF_MPX_IU_MASK) != 0) {
2569         gen_helper_bnd_jmp(cpu_env);
2570     }
2571 }
2572 
2573 /* Generate an end of block. Trace exception is also generated if needed.
2574    If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.
2575    If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
2576    S->TF.  This is used by the syscall/sysret insns.  */
2577 static void
do_gen_eob_worker(DisasContext * s,bool inhibit,bool recheck_tf,bool jr)2578 do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
2579 {
2580     gen_update_cc_op(s);
2581 
2582     /* If several instructions disable interrupts, only the first does it.  */
2583     if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
2584         gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
2585     } else {
2586         gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
2587     }
2588 
2589     if (s->base.tb->flags & HF_RF_MASK) {
2590         gen_helper_reset_rf(cpu_env);
2591     }
2592     if (s->base.singlestep_enabled) {
2593         gen_helper_debug(cpu_env);
2594     } else if (recheck_tf) {
2595         gen_helper_rechecking_single_step(cpu_env);
2596         tcg_gen_exit_tb(NULL, 0);
2597     } else if (s->tf) {
2598         gen_helper_single_step(cpu_env);
2599     } else if (jr) {
2600         tcg_gen_lookup_and_goto_ptr();
2601     } else {
2602         tcg_gen_exit_tb(NULL, 0);
2603     }
2604     s->base.is_jmp = DISAS_NORETURN;
2605 }
2606 
2607 static inline void
gen_eob_worker(DisasContext * s,bool inhibit,bool recheck_tf)2608 gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf)
2609 {
2610     do_gen_eob_worker(s, inhibit, recheck_tf, false);
2611 }
2612 
2613 /* End of block.
2614    If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set.  */
gen_eob_inhibit_irq(DisasContext * s,bool inhibit)2615 static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
2616 {
2617     gen_eob_worker(s, inhibit, false);
2618 }
2619 
2620 /* End of block, resetting the inhibit irq flag.  */
gen_eob(DisasContext * s)2621 static void gen_eob(DisasContext *s)
2622 {
2623     gen_eob_worker(s, false, false);
2624 }
2625 
2626 /* Jump to register */
gen_jr(DisasContext * s,TCGv dest)2627 static void gen_jr(DisasContext *s, TCGv dest)
2628 {
2629     do_gen_eob_worker(s, false, false, true);
2630 }
2631 
2632 /* generate a jump to eip. No segment change must happen before as a
2633    direct call to the next block may occur */
gen_jmp_tb(DisasContext * s,target_ulong eip,int tb_num)2634 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2635 {
2636     gen_update_cc_op(s);
2637     set_cc_op(s, CC_OP_DYNAMIC);
2638     if (s->jmp_opt) {
2639         gen_goto_tb(s, tb_num, eip);
2640     } else {
2641         gen_jmp_im(s, eip);
2642         gen_eob(s);
2643     }
2644 }
2645 
gen_jmp(DisasContext * s,target_ulong eip)2646 static void gen_jmp(DisasContext *s, target_ulong eip)
2647 {
2648     gen_jmp_tb(s, eip, 0);
2649 }
2650 
gen_ldq_env_A0(DisasContext * s,int offset)2651 static inline void gen_ldq_env_A0(DisasContext *s, int offset)
2652 {
2653     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEQ);
2654     tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset);
2655 }
2656 
gen_stq_env_A0(DisasContext * s,int offset)2657 static inline void gen_stq_env_A0(DisasContext *s, int offset)
2658 {
2659     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset);
2660     tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEQ);
2661 }
2662 
gen_ldo_env_A0(DisasContext * s,int offset)2663 static inline void gen_ldo_env_A0(DisasContext *s, int offset)
2664 {
2665     int mem_index = s->mem_index;
2666     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, mem_index, MO_LEQ);
2667     tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2668     tcg_gen_addi_tl(s->tmp0, s->A0, 8);
2669     tcg_gen_qemu_ld_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEQ);
2670     tcg_gen_st_i64(s->tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2671 }
2672 
gen_sto_env_A0(DisasContext * s,int offset)2673 static inline void gen_sto_env_A0(DisasContext *s, int offset)
2674 {
2675     int mem_index = s->mem_index;
2676     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(0)));
2677     tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, mem_index, MO_LEQ);
2678     tcg_gen_addi_tl(s->tmp0, s->A0, 8);
2679     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, offset + offsetof(ZMMReg, ZMM_Q(1)));
2680     tcg_gen_qemu_st_i64(s->tmp1_i64, s->tmp0, mem_index, MO_LEQ);
2681 }
2682 
gen_op_movo(DisasContext * s,int d_offset,int s_offset)2683 static inline void gen_op_movo(DisasContext *s, int d_offset, int s_offset)
2684 {
2685     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(0)));
2686     tcg_gen_st_i64(s->tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(0)));
2687     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, s_offset + offsetof(ZMMReg, ZMM_Q(1)));
2688     tcg_gen_st_i64(s->tmp1_i64, cpu_env, d_offset + offsetof(ZMMReg, ZMM_Q(1)));
2689 }
2690 
gen_op_movq(DisasContext * s,int d_offset,int s_offset)2691 static inline void gen_op_movq(DisasContext *s, int d_offset, int s_offset)
2692 {
2693     tcg_gen_ld_i64(s->tmp1_i64, cpu_env, s_offset);
2694     tcg_gen_st_i64(s->tmp1_i64, cpu_env, d_offset);
2695 }
2696 
gen_op_movl(DisasContext * s,int d_offset,int s_offset)2697 static inline void gen_op_movl(DisasContext *s, int d_offset, int s_offset)
2698 {
2699     tcg_gen_ld_i32(s->tmp2_i32, cpu_env, s_offset);
2700     tcg_gen_st_i32(s->tmp2_i32, cpu_env, d_offset);
2701 }
2702 
gen_op_movq_env_0(DisasContext * s,int d_offset)2703 static inline void gen_op_movq_env_0(DisasContext *s, int d_offset)
2704 {
2705     tcg_gen_movi_i64(s->tmp1_i64, 0);
2706     tcg_gen_st_i64(s->tmp1_i64, cpu_env, d_offset);
2707 }
2708 
2709 typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
2710 typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
2711 typedef void (*SSEFunc_0_epi)(TCGv_ptr env, TCGv_ptr reg, TCGv_i32 val);
2712 typedef void (*SSEFunc_0_epl)(TCGv_ptr env, TCGv_ptr reg, TCGv_i64 val);
2713 typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
2714 typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2715                                TCGv_i32 val);
2716 typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
2717 typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
2718                                TCGv val);
2719 
2720 #define SSE_SPECIAL ((void *)1)
2721 #define SSE_DUMMY ((void *)2)
2722 
2723 #define MMX_OP2(x) { gen_helper_ ## x ## _mmx, gen_helper_ ## x ## _xmm }
2724 #define SSE_FOP(x) { gen_helper_ ## x ## ps, gen_helper_ ## x ## pd, \
2725                      gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, }
2726 
2727 static const SSEFunc_0_epp sse_op_table1[256][4] = {
2728     /* 3DNow! extensions */
2729     [0x0e] = { SSE_DUMMY }, /* femms */
2730     [0x0f] = { SSE_DUMMY }, /* pf... */
2731     /* pure SSE operations */
2732     [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2733     [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2734     [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2735     [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2736     [0x14] = { gen_helper_punpckldq_xmm, gen_helper_punpcklqdq_xmm },
2737     [0x15] = { gen_helper_punpckhdq_xmm, gen_helper_punpckhqdq_xmm },
2738     [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2739     [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2740 
2741     [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2742     [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2743     [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2744     [0x2b] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movntps, movntpd, movntss, movntsd */
2745     [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2746     [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2747     [0x2e] = { gen_helper_ucomiss, gen_helper_ucomisd },
2748     [0x2f] = { gen_helper_comiss, gen_helper_comisd },
2749     [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2750     [0x51] = SSE_FOP(sqrt),
2751     [0x52] = { gen_helper_rsqrtps, NULL, gen_helper_rsqrtss, NULL },
2752     [0x53] = { gen_helper_rcpps, NULL, gen_helper_rcpss, NULL },
2753     [0x54] = { gen_helper_pand_xmm, gen_helper_pand_xmm }, /* andps, andpd */
2754     [0x55] = { gen_helper_pandn_xmm, gen_helper_pandn_xmm }, /* andnps, andnpd */
2755     [0x56] = { gen_helper_por_xmm, gen_helper_por_xmm }, /* orps, orpd */
2756     [0x57] = { gen_helper_pxor_xmm, gen_helper_pxor_xmm }, /* xorps, xorpd */
2757     [0x58] = SSE_FOP(add),
2758     [0x59] = SSE_FOP(mul),
2759     [0x5a] = { gen_helper_cvtps2pd, gen_helper_cvtpd2ps,
2760                gen_helper_cvtss2sd, gen_helper_cvtsd2ss },
2761     [0x5b] = { gen_helper_cvtdq2ps, gen_helper_cvtps2dq, gen_helper_cvttps2dq },
2762     [0x5c] = SSE_FOP(sub),
2763     [0x5d] = SSE_FOP(min),
2764     [0x5e] = SSE_FOP(div),
2765     [0x5f] = SSE_FOP(max),
2766 
2767     [0xc2] = SSE_FOP(cmpeq),
2768     [0xc6] = { (SSEFunc_0_epp)gen_helper_shufps,
2769                (SSEFunc_0_epp)gen_helper_shufpd }, /* XXX: casts */
2770 
2771     /* SSSE3, SSE4, MOVBE, CRC32, BMI1, BMI2, ADX.  */
2772     [0x38] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2773     [0x3a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2774 
2775     /* MMX ops and their SSE extensions */
2776     [0x60] = MMX_OP2(punpcklbw),
2777     [0x61] = MMX_OP2(punpcklwd),
2778     [0x62] = MMX_OP2(punpckldq),
2779     [0x63] = MMX_OP2(packsswb),
2780     [0x64] = MMX_OP2(pcmpgtb),
2781     [0x65] = MMX_OP2(pcmpgtw),
2782     [0x66] = MMX_OP2(pcmpgtl),
2783     [0x67] = MMX_OP2(packuswb),
2784     [0x68] = MMX_OP2(punpckhbw),
2785     [0x69] = MMX_OP2(punpckhwd),
2786     [0x6a] = MMX_OP2(punpckhdq),
2787     [0x6b] = MMX_OP2(packssdw),
2788     [0x6c] = { NULL, gen_helper_punpcklqdq_xmm },
2789     [0x6d] = { NULL, gen_helper_punpckhqdq_xmm },
2790     [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2791     [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2792     [0x70] = { (SSEFunc_0_epp)gen_helper_pshufw_mmx,
2793                (SSEFunc_0_epp)gen_helper_pshufd_xmm,
2794                (SSEFunc_0_epp)gen_helper_pshufhw_xmm,
2795                (SSEFunc_0_epp)gen_helper_pshuflw_xmm }, /* XXX: casts */
2796     [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2797     [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2798     [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2799     [0x74] = MMX_OP2(pcmpeqb),
2800     [0x75] = MMX_OP2(pcmpeqw),
2801     [0x76] = MMX_OP2(pcmpeql),
2802     [0x77] = { SSE_DUMMY }, /* emms */
2803     [0x78] = { NULL, SSE_SPECIAL, NULL, SSE_SPECIAL }, /* extrq_i, insertq_i */
2804     [0x79] = { NULL, gen_helper_extrq_r, NULL, gen_helper_insertq_r },
2805     [0x7c] = { NULL, gen_helper_haddpd, NULL, gen_helper_haddps },
2806     [0x7d] = { NULL, gen_helper_hsubpd, NULL, gen_helper_hsubps },
2807     [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2808     [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2809     [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2810     [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2811     [0xd0] = { NULL, gen_helper_addsubpd, NULL, gen_helper_addsubps },
2812     [0xd1] = MMX_OP2(psrlw),
2813     [0xd2] = MMX_OP2(psrld),
2814     [0xd3] = MMX_OP2(psrlq),
2815     [0xd4] = MMX_OP2(paddq),
2816     [0xd5] = MMX_OP2(pmullw),
2817     [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2818     [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2819     [0xd8] = MMX_OP2(psubusb),
2820     [0xd9] = MMX_OP2(psubusw),
2821     [0xda] = MMX_OP2(pminub),
2822     [0xdb] = MMX_OP2(pand),
2823     [0xdc] = MMX_OP2(paddusb),
2824     [0xdd] = MMX_OP2(paddusw),
2825     [0xde] = MMX_OP2(pmaxub),
2826     [0xdf] = MMX_OP2(pandn),
2827     [0xe0] = MMX_OP2(pavgb),
2828     [0xe1] = MMX_OP2(psraw),
2829     [0xe2] = MMX_OP2(psrad),
2830     [0xe3] = MMX_OP2(pavgw),
2831     [0xe4] = MMX_OP2(pmulhuw),
2832     [0xe5] = MMX_OP2(pmulhw),
2833     [0xe6] = { NULL, gen_helper_cvttpd2dq, gen_helper_cvtdq2pd, gen_helper_cvtpd2dq },
2834     [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
2835     [0xe8] = MMX_OP2(psubsb),
2836     [0xe9] = MMX_OP2(psubsw),
2837     [0xea] = MMX_OP2(pminsw),
2838     [0xeb] = MMX_OP2(por),
2839     [0xec] = MMX_OP2(paddsb),
2840     [0xed] = MMX_OP2(paddsw),
2841     [0xee] = MMX_OP2(pmaxsw),
2842     [0xef] = MMX_OP2(pxor),
2843     [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2844     [0xf1] = MMX_OP2(psllw),
2845     [0xf2] = MMX_OP2(pslld),
2846     [0xf3] = MMX_OP2(psllq),
2847     [0xf4] = MMX_OP2(pmuludq),
2848     [0xf5] = MMX_OP2(pmaddwd),
2849     [0xf6] = MMX_OP2(psadbw),
2850     [0xf7] = { (SSEFunc_0_epp)gen_helper_maskmov_mmx,
2851                (SSEFunc_0_epp)gen_helper_maskmov_xmm }, /* XXX: casts */
2852     [0xf8] = MMX_OP2(psubb),
2853     [0xf9] = MMX_OP2(psubw),
2854     [0xfa] = MMX_OP2(psubl),
2855     [0xfb] = MMX_OP2(psubq),
2856     [0xfc] = MMX_OP2(paddb),
2857     [0xfd] = MMX_OP2(paddw),
2858     [0xfe] = MMX_OP2(paddl),
2859 };
2860 
2861 static const SSEFunc_0_epp sse_op_table2[3 * 8][2] = {
2862     [0 + 2] = MMX_OP2(psrlw),
2863     [0 + 4] = MMX_OP2(psraw),
2864     [0 + 6] = MMX_OP2(psllw),
2865     [8 + 2] = MMX_OP2(psrld),
2866     [8 + 4] = MMX_OP2(psrad),
2867     [8 + 6] = MMX_OP2(pslld),
2868     [16 + 2] = MMX_OP2(psrlq),
2869     [16 + 3] = { NULL, gen_helper_psrldq_xmm },
2870     [16 + 6] = MMX_OP2(psllq),
2871     [16 + 7] = { NULL, gen_helper_pslldq_xmm },
2872 };
2873 
2874 static const SSEFunc_0_epi sse_op_table3ai[] = {
2875     gen_helper_cvtsi2ss,
2876     gen_helper_cvtsi2sd
2877 };
2878 
2879 #ifdef TARGET_X86_64
2880 static const SSEFunc_0_epl sse_op_table3aq[] = {
2881     gen_helper_cvtsq2ss,
2882     gen_helper_cvtsq2sd
2883 };
2884 #endif
2885 
2886 static const SSEFunc_i_ep sse_op_table3bi[] = {
2887     gen_helper_cvttss2si,
2888     gen_helper_cvtss2si,
2889     gen_helper_cvttsd2si,
2890     gen_helper_cvtsd2si
2891 };
2892 
2893 #ifdef TARGET_X86_64
2894 static const SSEFunc_l_ep sse_op_table3bq[] = {
2895     gen_helper_cvttss2sq,
2896     gen_helper_cvtss2sq,
2897     gen_helper_cvttsd2sq,
2898     gen_helper_cvtsd2sq
2899 };
2900 #endif
2901 
2902 static const SSEFunc_0_epp sse_op_table4[8][4] = {
2903     SSE_FOP(cmpeq),
2904     SSE_FOP(cmplt),
2905     SSE_FOP(cmple),
2906     SSE_FOP(cmpunord),
2907     SSE_FOP(cmpneq),
2908     SSE_FOP(cmpnlt),
2909     SSE_FOP(cmpnle),
2910     SSE_FOP(cmpord),
2911 };
2912 
2913 static const SSEFunc_0_epp sse_op_table5[256] = {
2914     [0x0c] = gen_helper_pi2fw,
2915     [0x0d] = gen_helper_pi2fd,
2916     [0x1c] = gen_helper_pf2iw,
2917     [0x1d] = gen_helper_pf2id,
2918     [0x8a] = gen_helper_pfnacc,
2919     [0x8e] = gen_helper_pfpnacc,
2920     [0x90] = gen_helper_pfcmpge,
2921     [0x94] = gen_helper_pfmin,
2922     [0x96] = gen_helper_pfrcp,
2923     [0x97] = gen_helper_pfrsqrt,
2924     [0x9a] = gen_helper_pfsub,
2925     [0x9e] = gen_helper_pfadd,
2926     [0xa0] = gen_helper_pfcmpgt,
2927     [0xa4] = gen_helper_pfmax,
2928     [0xa6] = gen_helper_movq, /* pfrcpit1; no need to actually increase precision */
2929     [0xa7] = gen_helper_movq, /* pfrsqit1 */
2930     [0xaa] = gen_helper_pfsubr,
2931     [0xae] = gen_helper_pfacc,
2932     [0xb0] = gen_helper_pfcmpeq,
2933     [0xb4] = gen_helper_pfmul,
2934     [0xb6] = gen_helper_movq, /* pfrcpit2 */
2935     [0xb7] = gen_helper_pmulhrw_mmx,
2936     [0xbb] = gen_helper_pswapd,
2937     [0xbf] = gen_helper_pavgb_mmx /* pavgusb */
2938 };
2939 
2940 struct SSEOpHelper_epp {
2941     SSEFunc_0_epp op[2];
2942     uint32_t ext_mask;
2943 };
2944 
2945 struct SSEOpHelper_eppi {
2946     SSEFunc_0_eppi op[2];
2947     uint32_t ext_mask;
2948 };
2949 
2950 #define SSSE3_OP(x) { MMX_OP2(x), CPUID_EXT_SSSE3 }
2951 #define SSE41_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE41 }
2952 #define SSE42_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_SSE42 }
2953 #define SSE41_SPECIAL { { NULL, SSE_SPECIAL }, CPUID_EXT_SSE41 }
2954 #define PCLMULQDQ_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, \
2955         CPUID_EXT_PCLMULQDQ }
2956 #define AESNI_OP(x) { { NULL, gen_helper_ ## x ## _xmm }, CPUID_EXT_AES }
2957 
2958 static const struct SSEOpHelper_epp sse_op_table6[256] = {
2959     [0x00] = SSSE3_OP(pshufb),
2960     [0x01] = SSSE3_OP(phaddw),
2961     [0x02] = SSSE3_OP(phaddd),
2962     [0x03] = SSSE3_OP(phaddsw),
2963     [0x04] = SSSE3_OP(pmaddubsw),
2964     [0x05] = SSSE3_OP(phsubw),
2965     [0x06] = SSSE3_OP(phsubd),
2966     [0x07] = SSSE3_OP(phsubsw),
2967     [0x08] = SSSE3_OP(psignb),
2968     [0x09] = SSSE3_OP(psignw),
2969     [0x0a] = SSSE3_OP(psignd),
2970     [0x0b] = SSSE3_OP(pmulhrsw),
2971     [0x10] = SSE41_OP(pblendvb),
2972     [0x14] = SSE41_OP(blendvps),
2973     [0x15] = SSE41_OP(blendvpd),
2974     [0x17] = SSE41_OP(ptest),
2975     [0x1c] = SSSE3_OP(pabsb),
2976     [0x1d] = SSSE3_OP(pabsw),
2977     [0x1e] = SSSE3_OP(pabsd),
2978     [0x20] = SSE41_OP(pmovsxbw),
2979     [0x21] = SSE41_OP(pmovsxbd),
2980     [0x22] = SSE41_OP(pmovsxbq),
2981     [0x23] = SSE41_OP(pmovsxwd),
2982     [0x24] = SSE41_OP(pmovsxwq),
2983     [0x25] = SSE41_OP(pmovsxdq),
2984     [0x28] = SSE41_OP(pmuldq),
2985     [0x29] = SSE41_OP(pcmpeqq),
2986     [0x2a] = SSE41_SPECIAL, /* movntqda */
2987     [0x2b] = SSE41_OP(packusdw),
2988     [0x30] = SSE41_OP(pmovzxbw),
2989     [0x31] = SSE41_OP(pmovzxbd),
2990     [0x32] = SSE41_OP(pmovzxbq),
2991     [0x33] = SSE41_OP(pmovzxwd),
2992     [0x34] = SSE41_OP(pmovzxwq),
2993     [0x35] = SSE41_OP(pmovzxdq),
2994     [0x37] = SSE42_OP(pcmpgtq),
2995     [0x38] = SSE41_OP(pminsb),
2996     [0x39] = SSE41_OP(pminsd),
2997     [0x3a] = SSE41_OP(pminuw),
2998     [0x3b] = SSE41_OP(pminud),
2999     [0x3c] = SSE41_OP(pmaxsb),
3000     [0x3d] = SSE41_OP(pmaxsd),
3001     [0x3e] = SSE41_OP(pmaxuw),
3002     [0x3f] = SSE41_OP(pmaxud),
3003     [0x40] = SSE41_OP(pmulld),
3004     [0x41] = SSE41_OP(phminposuw),
3005     [0xdb] = AESNI_OP(aesimc),
3006     [0xdc] = AESNI_OP(aesenc),
3007     [0xdd] = AESNI_OP(aesenclast),
3008     [0xde] = AESNI_OP(aesdec),
3009     [0xdf] = AESNI_OP(aesdeclast),
3010 };
3011 
3012 static const struct SSEOpHelper_eppi sse_op_table7[256] = {
3013     [0x08] = SSE41_OP(roundps),
3014     [0x09] = SSE41_OP(roundpd),
3015     [0x0a] = SSE41_OP(roundss),
3016     [0x0b] = SSE41_OP(roundsd),
3017     [0x0c] = SSE41_OP(blendps),
3018     [0x0d] = SSE41_OP(blendpd),
3019     [0x0e] = SSE41_OP(pblendw),
3020     [0x0f] = SSSE3_OP(palignr),
3021     [0x14] = SSE41_SPECIAL, /* pextrb */
3022     [0x15] = SSE41_SPECIAL, /* pextrw */
3023     [0x16] = SSE41_SPECIAL, /* pextrd/pextrq */
3024     [0x17] = SSE41_SPECIAL, /* extractps */
3025     [0x20] = SSE41_SPECIAL, /* pinsrb */
3026     [0x21] = SSE41_SPECIAL, /* insertps */
3027     [0x22] = SSE41_SPECIAL, /* pinsrd/pinsrq */
3028     [0x40] = SSE41_OP(dpps),
3029     [0x41] = SSE41_OP(dppd),
3030     [0x42] = SSE41_OP(mpsadbw),
3031     [0x44] = PCLMULQDQ_OP(pclmulqdq),
3032     [0x60] = SSE42_OP(pcmpestrm),
3033     [0x61] = SSE42_OP(pcmpestri),
3034     [0x62] = SSE42_OP(pcmpistrm),
3035     [0x63] = SSE42_OP(pcmpistri),
3036     [0xdf] = AESNI_OP(aeskeygenassist),
3037 };
3038 
gen_sse(CPUX86State * env,DisasContext * s,int b,target_ulong pc_start,int rex_r)3039 static void gen_sse(CPUX86State *env, DisasContext *s, int b,
3040                     target_ulong pc_start, int rex_r)
3041 {
3042     int b1, op1_offset, op2_offset, is_xmm, val;
3043     int modrm, mod, rm, reg;
3044     SSEFunc_0_epp sse_fn_epp;
3045     SSEFunc_0_eppi sse_fn_eppi;
3046     SSEFunc_0_ppi sse_fn_ppi;
3047     SSEFunc_0_eppt sse_fn_eppt;
3048     MemOp ot;
3049 
3050     b &= 0xff;
3051     if (s->prefix & PREFIX_DATA)
3052         b1 = 1;
3053     else if (s->prefix & PREFIX_REPZ)
3054         b1 = 2;
3055     else if (s->prefix & PREFIX_REPNZ)
3056         b1 = 3;
3057     else
3058         b1 = 0;
3059     sse_fn_epp = sse_op_table1[b][b1];
3060     if (!sse_fn_epp) {
3061         goto unknown_op;
3062     }
3063     if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {
3064         is_xmm = 1;
3065     } else {
3066         if (b1 == 0) {
3067             /* MMX case */
3068             is_xmm = 0;
3069         } else {
3070             is_xmm = 1;
3071         }
3072     }
3073     /* simple MMX/SSE operation */
3074     if (s->flags & HF_TS_MASK) {
3075         gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
3076         return;
3077     }
3078     if (s->flags & HF_EM_MASK) {
3079     illegal_op:
3080         gen_illegal_opcode(s);
3081         return;
3082     }
3083     if (is_xmm
3084         && !(s->flags & HF_OSFXSR_MASK)
3085         && ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))) {
3086         goto unknown_op;
3087     }
3088     if (b == 0x0e) {
3089         if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
3090             /* If we were fully decoding this we might use illegal_op.  */
3091             goto unknown_op;
3092         }
3093         /* femms */
3094         gen_helper_emms(cpu_env);
3095         return;
3096     }
3097     if (b == 0x77) {
3098         /* emms */
3099         gen_helper_emms(cpu_env);
3100         return;
3101     }
3102     /* prepare MMX state (XXX: optimize by storing fptt and fptags in
3103        the static cpu state) */
3104     if (!is_xmm) {
3105         gen_helper_enter_mmx(cpu_env);
3106     }
3107 
3108     modrm = x86_ldub_code(env, s);
3109     reg = ((modrm >> 3) & 7);
3110     if (is_xmm)
3111         reg |= rex_r;
3112     mod = (modrm >> 6) & 3;
3113     if (sse_fn_epp == SSE_SPECIAL) {
3114         b |= (b1 << 8);
3115         switch(b) {
3116         case 0x0e7: /* movntq */
3117             if (mod == 3) {
3118                 goto illegal_op;
3119             }
3120             gen_lea_modrm(env, s, modrm);
3121             gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3122             break;
3123         case 0x1e7: /* movntdq */
3124         case 0x02b: /* movntps */
3125         case 0x12b: /* movntps */
3126             if (mod == 3)
3127                 goto illegal_op;
3128             gen_lea_modrm(env, s, modrm);
3129             gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3130             break;
3131         case 0x3f0: /* lddqu */
3132             if (mod == 3)
3133                 goto illegal_op;
3134             gen_lea_modrm(env, s, modrm);
3135             gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3136             break;
3137         case 0x22b: /* movntss */
3138         case 0x32b: /* movntsd */
3139             if (mod == 3)
3140                 goto illegal_op;
3141             gen_lea_modrm(env, s, modrm);
3142             if (b1 & 1) {
3143                 gen_stq_env_A0(s, offsetof(CPUX86State,
3144                                            xmm_regs[reg].ZMM_Q(0)));
3145             } else {
3146                 tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State,
3147                     xmm_regs[reg].ZMM_L(0)));
3148                 gen_op_st_v(s, MO_32, s->T0, s->A0);
3149             }
3150             break;
3151         case 0x6e: /* movd mm, ea */
3152 #ifdef TARGET_X86_64
3153             if (s->dflag == MO_64) {
3154                 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3155                 tcg_gen_st_tl(s->T0, cpu_env,
3156                               offsetof(CPUX86State, fpregs[reg].mmx));
3157             } else
3158 #endif
3159             {
3160                 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3161                 tcg_gen_addi_ptr(s->ptr0, cpu_env,
3162                                  offsetof(CPUX86State,fpregs[reg].mmx));
3163                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3164                 gen_helper_movl_mm_T0_mmx(s->ptr0, s->tmp2_i32);
3165             }
3166             break;
3167         case 0x16e: /* movd xmm, ea */
3168 #ifdef TARGET_X86_64
3169             if (s->dflag == MO_64) {
3170                 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);
3171                 tcg_gen_addi_ptr(s->ptr0, cpu_env,
3172                                  offsetof(CPUX86State,xmm_regs[reg]));
3173                 gen_helper_movq_mm_T0_xmm(s->ptr0, s->T0);
3174             } else
3175 #endif
3176             {
3177                 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);
3178                 tcg_gen_addi_ptr(s->ptr0, cpu_env,
3179                                  offsetof(CPUX86State,xmm_regs[reg]));
3180                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3181                 gen_helper_movl_mm_T0_xmm(s->ptr0, s->tmp2_i32);
3182             }
3183             break;
3184         case 0x6f: /* movq mm, ea */
3185             if (mod != 3) {
3186                 gen_lea_modrm(env, s, modrm);
3187                 gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3188             } else {
3189                 rm = (modrm & 7);
3190                 tcg_gen_ld_i64(s->tmp1_i64, cpu_env,
3191                                offsetof(CPUX86State,fpregs[rm].mmx));
3192                 tcg_gen_st_i64(s->tmp1_i64, cpu_env,
3193                                offsetof(CPUX86State,fpregs[reg].mmx));
3194             }
3195             break;
3196         case 0x010: /* movups */
3197         case 0x110: /* movupd */
3198         case 0x028: /* movaps */
3199         case 0x128: /* movapd */
3200         case 0x16f: /* movdqa xmm, ea */
3201         case 0x26f: /* movdqu xmm, ea */
3202             if (mod != 3) {
3203                 gen_lea_modrm(env, s, modrm);
3204                 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3205             } else {
3206                 rm = (modrm & 7) | REX_B(s);
3207                 gen_op_movo(s, offsetof(CPUX86State, xmm_regs[reg]),
3208                             offsetof(CPUX86State,xmm_regs[rm]));
3209             }
3210             break;
3211         case 0x210: /* movss xmm, ea */
3212             if (mod != 3) {
3213                 gen_lea_modrm(env, s, modrm);
3214                 gen_op_ld_v(s, MO_32, s->T0, s->A0);
3215                 tcg_gen_st32_tl(s->T0, cpu_env,
3216                                 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)));
3217                 tcg_gen_movi_tl(s->T0, 0);
3218                 tcg_gen_st32_tl(s->T0, cpu_env,
3219                                 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(1)));
3220                 tcg_gen_st32_tl(s->T0, cpu_env,
3221                                 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2)));
3222                 tcg_gen_st32_tl(s->T0, cpu_env,
3223                                 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3)));
3224             } else {
3225                 rm = (modrm & 7) | REX_B(s);
3226                 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)),
3227                             offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3228             }
3229             break;
3230         case 0x310: /* movsd xmm, ea */
3231             if (mod != 3) {
3232                 gen_lea_modrm(env, s, modrm);
3233                 gen_ldq_env_A0(s, offsetof(CPUX86State,
3234                                            xmm_regs[reg].ZMM_Q(0)));
3235                 tcg_gen_movi_tl(s->T0, 0);
3236                 tcg_gen_st32_tl(s->T0, cpu_env,
3237                                 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2)));
3238                 tcg_gen_st32_tl(s->T0, cpu_env,
3239                                 offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3)));
3240             } else {
3241                 rm = (modrm & 7) | REX_B(s);
3242                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)),
3243                             offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3244             }
3245             break;
3246         case 0x012: /* movlps */
3247         case 0x112: /* movlpd */
3248             if (mod != 3) {
3249                 gen_lea_modrm(env, s, modrm);
3250                 gen_ldq_env_A0(s, offsetof(CPUX86State,
3251                                            xmm_regs[reg].ZMM_Q(0)));
3252             } else {
3253                 /* movhlps */
3254                 rm = (modrm & 7) | REX_B(s);
3255                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)),
3256                             offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));
3257             }
3258             break;
3259         case 0x212: /* movsldup */
3260             if (mod != 3) {
3261                 gen_lea_modrm(env, s, modrm);
3262                 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3263             } else {
3264                 rm = (modrm & 7) | REX_B(s);
3265                 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)),
3266                             offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));
3267                 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2)),
3268                             offsetof(CPUX86State,xmm_regs[rm].ZMM_L(2)));
3269             }
3270             gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(1)),
3271                         offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3272             gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3)),
3273                         offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));
3274             break;
3275         case 0x312: /* movddup */
3276             if (mod != 3) {
3277                 gen_lea_modrm(env, s, modrm);
3278                 gen_ldq_env_A0(s, offsetof(CPUX86State,
3279                                            xmm_regs[reg].ZMM_Q(0)));
3280             } else {
3281                 rm = (modrm & 7) | REX_B(s);
3282                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)),
3283                             offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3284             }
3285             gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1)),
3286                         offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3287             break;
3288         case 0x016: /* movhps */
3289         case 0x116: /* movhpd */
3290             if (mod != 3) {
3291                 gen_lea_modrm(env, s, modrm);
3292                 gen_ldq_env_A0(s, offsetof(CPUX86State,
3293                                            xmm_regs[reg].ZMM_Q(1)));
3294             } else {
3295                 /* movlhps */
3296                 rm = (modrm & 7) | REX_B(s);
3297                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1)),
3298                             offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3299             }
3300             break;
3301         case 0x216: /* movshdup */
3302             if (mod != 3) {
3303                 gen_lea_modrm(env, s, modrm);
3304                 gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3305             } else {
3306                 rm = (modrm & 7) | REX_B(s);
3307                 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(1)),
3308                             offsetof(CPUX86State,xmm_regs[rm].ZMM_L(1)));
3309                 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3)),
3310                             offsetof(CPUX86State,xmm_regs[rm].ZMM_L(3)));
3311             }
3312             gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)),
3313                         offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));
3314             gen_op_movl(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2)),
3315                         offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));
3316             break;
3317         case 0x178:
3318         case 0x378:
3319             {
3320                 int bit_index, field_length;
3321 
3322                 if (b1 == 1 && reg != 0)
3323                     goto illegal_op;
3324                 field_length = x86_ldub_code(env, s) & 0x3F;
3325                 bit_index = x86_ldub_code(env, s) & 0x3F;
3326                 tcg_gen_addi_ptr(s->ptr0, cpu_env,
3327                     offsetof(CPUX86State,xmm_regs[reg]));
3328                 if (b1 == 1)
3329                     gen_helper_extrq_i(cpu_env, s->ptr0,
3330                                        tcg_const_i32(bit_index),
3331                                        tcg_const_i32(field_length));
3332                 else
3333                     gen_helper_insertq_i(cpu_env, s->ptr0,
3334                                          tcg_const_i32(bit_index),
3335                                          tcg_const_i32(field_length));
3336             }
3337             break;
3338         case 0x7e: /* movd ea, mm */
3339 #ifdef TARGET_X86_64
3340             if (s->dflag == MO_64) {
3341                 tcg_gen_ld_i64(s->T0, cpu_env,
3342                                offsetof(CPUX86State,fpregs[reg].mmx));
3343                 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3344             } else
3345 #endif
3346             {
3347                 tcg_gen_ld32u_tl(s->T0, cpu_env,
3348                                  offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));
3349                 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3350             }
3351             break;
3352         case 0x17e: /* movd ea, xmm */
3353 #ifdef TARGET_X86_64
3354             if (s->dflag == MO_64) {
3355                 tcg_gen_ld_i64(s->T0, cpu_env,
3356                                offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3357                 gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);
3358             } else
3359 #endif
3360             {
3361                 tcg_gen_ld32u_tl(s->T0, cpu_env,
3362                                  offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3363                 gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);
3364             }
3365             break;
3366         case 0x27e: /* movq xmm, ea */
3367             if (mod != 3) {
3368                 gen_lea_modrm(env, s, modrm);
3369                 gen_ldq_env_A0(s, offsetof(CPUX86State,
3370                                            xmm_regs[reg].ZMM_Q(0)));
3371             } else {
3372                 rm = (modrm & 7) | REX_B(s);
3373                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)),
3374                             offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3375             }
3376             gen_op_movq_env_0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1)));
3377             break;
3378         case 0x7f: /* movq ea, mm */
3379             if (mod != 3) {
3380                 gen_lea_modrm(env, s, modrm);
3381                 gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));
3382             } else {
3383                 rm = (modrm & 7);
3384                 gen_op_movq(s, offsetof(CPUX86State, fpregs[rm].mmx),
3385                             offsetof(CPUX86State,fpregs[reg].mmx));
3386             }
3387             break;
3388         case 0x011: /* movups */
3389         case 0x111: /* movupd */
3390         case 0x029: /* movaps */
3391         case 0x129: /* movapd */
3392         case 0x17f: /* movdqa ea, xmm */
3393         case 0x27f: /* movdqu ea, xmm */
3394             if (mod != 3) {
3395                 gen_lea_modrm(env, s, modrm);
3396                 gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));
3397             } else {
3398                 rm = (modrm & 7) | REX_B(s);
3399                 gen_op_movo(s, offsetof(CPUX86State, xmm_regs[rm]),
3400                             offsetof(CPUX86State,xmm_regs[reg]));
3401             }
3402             break;
3403         case 0x211: /* movss ea, xmm */
3404             if (mod != 3) {
3405                 gen_lea_modrm(env, s, modrm);
3406                 tcg_gen_ld32u_tl(s->T0, cpu_env,
3407                                  offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0)));
3408                 gen_op_st_v(s, MO_32, s->T0, s->A0);
3409             } else {
3410                 rm = (modrm & 7) | REX_B(s);
3411                 gen_op_movl(s, offsetof(CPUX86State, xmm_regs[rm].ZMM_L(0)),
3412                             offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));
3413             }
3414             break;
3415         case 0x311: /* movsd ea, xmm */
3416             if (mod != 3) {
3417                 gen_lea_modrm(env, s, modrm);
3418                 gen_stq_env_A0(s, offsetof(CPUX86State,
3419                                            xmm_regs[reg].ZMM_Q(0)));
3420             } else {
3421                 rm = (modrm & 7) | REX_B(s);
3422                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[rm].ZMM_Q(0)),
3423                             offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3424             }
3425             break;
3426         case 0x013: /* movlps */
3427         case 0x113: /* movlpd */
3428             if (mod != 3) {
3429                 gen_lea_modrm(env, s, modrm);
3430                 gen_stq_env_A0(s, offsetof(CPUX86State,
3431                                            xmm_regs[reg].ZMM_Q(0)));
3432             } else {
3433                 goto illegal_op;
3434             }
3435             break;
3436         case 0x017: /* movhps */
3437         case 0x117: /* movhpd */
3438             if (mod != 3) {
3439                 gen_lea_modrm(env, s, modrm);
3440                 gen_stq_env_A0(s, offsetof(CPUX86State,
3441                                            xmm_regs[reg].ZMM_Q(1)));
3442             } else {
3443                 goto illegal_op;
3444             }
3445             break;
3446         case 0x71: /* shift mm, im */
3447         case 0x72:
3448         case 0x73:
3449         case 0x171: /* shift xmm, im */
3450         case 0x172:
3451         case 0x173:
3452             if (b1 >= 2) {
3453                 goto unknown_op;
3454             }
3455             val = x86_ldub_code(env, s);
3456             if (is_xmm) {
3457                 tcg_gen_movi_tl(s->T0, val);
3458                 tcg_gen_st32_tl(s->T0, cpu_env,
3459                                 offsetof(CPUX86State, xmm_t0.ZMM_L(0)));
3460                 tcg_gen_movi_tl(s->T0, 0);
3461                 tcg_gen_st32_tl(s->T0, cpu_env,
3462                                 offsetof(CPUX86State, xmm_t0.ZMM_L(1)));
3463                 op1_offset = offsetof(CPUX86State,xmm_t0);
3464             } else {
3465                 tcg_gen_movi_tl(s->T0, val);
3466                 tcg_gen_st32_tl(s->T0, cpu_env,
3467                                 offsetof(CPUX86State, mmx_t0.MMX_L(0)));
3468                 tcg_gen_movi_tl(s->T0, 0);
3469                 tcg_gen_st32_tl(s->T0, cpu_env,
3470                                 offsetof(CPUX86State, mmx_t0.MMX_L(1)));
3471                 op1_offset = offsetof(CPUX86State,mmx_t0);
3472             }
3473             sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
3474                                        (((modrm >> 3)) & 7)][b1];
3475             if (!sse_fn_epp) {
3476                 goto unknown_op;
3477             }
3478             if (is_xmm) {
3479                 rm = (modrm & 7) | REX_B(s);
3480                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3481             } else {
3482                 rm = (modrm & 7);
3483                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3484             }
3485             tcg_gen_addi_ptr(s->ptr0, cpu_env, op2_offset);
3486             tcg_gen_addi_ptr(s->ptr1, cpu_env, op1_offset);
3487             sse_fn_epp(cpu_env, s->ptr0, s->ptr1);
3488             break;
3489         case 0x050: /* movmskps */
3490             rm = (modrm & 7) | REX_B(s);
3491             tcg_gen_addi_ptr(s->ptr0, cpu_env,
3492                              offsetof(CPUX86State,xmm_regs[rm]));
3493             gen_helper_movmskps(s->tmp2_i32, cpu_env, s->ptr0);
3494             tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
3495             break;
3496         case 0x150: /* movmskpd */
3497             rm = (modrm & 7) | REX_B(s);
3498             tcg_gen_addi_ptr(s->ptr0, cpu_env,
3499                              offsetof(CPUX86State,xmm_regs[rm]));
3500             gen_helper_movmskpd(s->tmp2_i32, cpu_env, s->ptr0);
3501             tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
3502             break;
3503         case 0x02a: /* cvtpi2ps */
3504         case 0x12a: /* cvtpi2pd */
3505             gen_helper_enter_mmx(cpu_env);
3506             if (mod != 3) {
3507                 gen_lea_modrm(env, s, modrm);
3508                 op2_offset = offsetof(CPUX86State,mmx_t0);
3509                 gen_ldq_env_A0(s, op2_offset);
3510             } else {
3511                 rm = (modrm & 7);
3512                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3513             }
3514             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3515             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
3516             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
3517             switch(b >> 8) {
3518             case 0x0:
3519                 gen_helper_cvtpi2ps(cpu_env, s->ptr0, s->ptr1);
3520                 break;
3521             default:
3522             case 0x1:
3523                 gen_helper_cvtpi2pd(cpu_env, s->ptr0, s->ptr1);
3524                 break;
3525             }
3526             break;
3527         case 0x22a: /* cvtsi2ss */
3528         case 0x32a: /* cvtsi2sd */
3529             ot = mo_64_32(s->dflag);
3530             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3531             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3532             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
3533             if (ot == MO_32) {
3534                 SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];
3535                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3536                 sse_fn_epi(cpu_env, s->ptr0, s->tmp2_i32);
3537             } else {
3538 #ifdef TARGET_X86_64
3539                 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];
3540                 sse_fn_epl(cpu_env, s->ptr0, s->T0);
3541 #else
3542                 goto illegal_op;
3543 #endif
3544             }
3545             break;
3546         case 0x02c: /* cvttps2pi */
3547         case 0x12c: /* cvttpd2pi */
3548         case 0x02d: /* cvtps2pi */
3549         case 0x12d: /* cvtpd2pi */
3550             gen_helper_enter_mmx(cpu_env);
3551             if (mod != 3) {
3552                 gen_lea_modrm(env, s, modrm);
3553                 op2_offset = offsetof(CPUX86State,xmm_t0);
3554                 gen_ldo_env_A0(s, op2_offset);
3555             } else {
3556                 rm = (modrm & 7) | REX_B(s);
3557                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3558             }
3559             op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
3560             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
3561             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
3562             switch(b) {
3563             case 0x02c:
3564                 gen_helper_cvttps2pi(cpu_env, s->ptr0, s->ptr1);
3565                 break;
3566             case 0x12c:
3567                 gen_helper_cvttpd2pi(cpu_env, s->ptr0, s->ptr1);
3568                 break;
3569             case 0x02d:
3570                 gen_helper_cvtps2pi(cpu_env, s->ptr0, s->ptr1);
3571                 break;
3572             case 0x12d:
3573                 gen_helper_cvtpd2pi(cpu_env, s->ptr0, s->ptr1);
3574                 break;
3575             }
3576             break;
3577         case 0x22c: /* cvttss2si */
3578         case 0x32c: /* cvttsd2si */
3579         case 0x22d: /* cvtss2si */
3580         case 0x32d: /* cvtsd2si */
3581             ot = mo_64_32(s->dflag);
3582             if (mod != 3) {
3583                 gen_lea_modrm(env, s, modrm);
3584                 if ((b >> 8) & 1) {
3585                     gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_Q(0)));
3586                 } else {
3587                     gen_op_ld_v(s, MO_32, s->T0, s->A0);
3588                     tcg_gen_st32_tl(s->T0, cpu_env,
3589                                     offsetof(CPUX86State, xmm_t0.ZMM_L(0)));
3590                 }
3591                 op2_offset = offsetof(CPUX86State,xmm_t0);
3592             } else {
3593                 rm = (modrm & 7) | REX_B(s);
3594                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3595             }
3596             tcg_gen_addi_ptr(s->ptr0, cpu_env, op2_offset);
3597             if (ot == MO_32) {
3598                 SSEFunc_i_ep sse_fn_i_ep =
3599                     sse_op_table3bi[((b >> 7) & 2) | (b & 1)];
3600                 sse_fn_i_ep(s->tmp2_i32, cpu_env, s->ptr0);
3601                 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
3602             } else {
3603 #ifdef TARGET_X86_64
3604                 SSEFunc_l_ep sse_fn_l_ep =
3605                     sse_op_table3bq[((b >> 7) & 2) | (b & 1)];
3606                 sse_fn_l_ep(s->T0, cpu_env, s->ptr0);
3607 #else
3608                 goto illegal_op;
3609 #endif
3610             }
3611             gen_op_mov_reg_v(s, ot, reg, s->T0);
3612             break;
3613         case 0xc4: /* pinsrw */
3614         case 0x1c4:
3615             s->rip_offset = 1;
3616             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
3617             val = x86_ldub_code(env, s);
3618             if (b1) {
3619                 val &= 7;
3620                 tcg_gen_st16_tl(s->T0, cpu_env,
3621                                 offsetof(CPUX86State,xmm_regs[reg].ZMM_W(val)));
3622             } else {
3623                 val &= 3;
3624                 tcg_gen_st16_tl(s->T0, cpu_env,
3625                                 offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));
3626             }
3627             break;
3628         case 0xc5: /* pextrw */
3629         case 0x1c5:
3630             if (mod != 3)
3631                 goto illegal_op;
3632             ot = mo_64_32(s->dflag);
3633             val = x86_ldub_code(env, s);
3634             if (b1) {
3635                 val &= 7;
3636                 rm = (modrm & 7) | REX_B(s);
3637                 tcg_gen_ld16u_tl(s->T0, cpu_env,
3638                                  offsetof(CPUX86State,xmm_regs[rm].ZMM_W(val)));
3639             } else {
3640                 val &= 3;
3641                 rm = (modrm & 7);
3642                 tcg_gen_ld16u_tl(s->T0, cpu_env,
3643                                 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
3644             }
3645             reg = ((modrm >> 3) & 7) | rex_r;
3646             gen_op_mov_reg_v(s, ot, reg, s->T0);
3647             break;
3648         case 0x1d6: /* movq ea, xmm */
3649             if (mod != 3) {
3650                 gen_lea_modrm(env, s, modrm);
3651                 gen_stq_env_A0(s, offsetof(CPUX86State,
3652                                            xmm_regs[reg].ZMM_Q(0)));
3653             } else {
3654                 rm = (modrm & 7) | REX_B(s);
3655                 gen_op_movq(s, offsetof(CPUX86State, xmm_regs[rm].ZMM_Q(0)),
3656                             offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));
3657                 gen_op_movq_env_0(s,
3658                                   offsetof(CPUX86State, xmm_regs[rm].ZMM_Q(1)));
3659             }
3660             break;
3661         case 0x2d6: /* movq2dq */
3662             gen_helper_enter_mmx(cpu_env);
3663             rm = (modrm & 7);
3664             gen_op_movq(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0)),
3665                         offsetof(CPUX86State,fpregs[rm].mmx));
3666             gen_op_movq_env_0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1)));
3667             break;
3668         case 0x3d6: /* movdq2q */
3669             gen_helper_enter_mmx(cpu_env);
3670             rm = (modrm & 7) | REX_B(s);
3671             gen_op_movq(s, offsetof(CPUX86State, fpregs[reg & 7].mmx),
3672                         offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));
3673             break;
3674         case 0xd7: /* pmovmskb */
3675         case 0x1d7:
3676             if (mod != 3)
3677                 goto illegal_op;
3678             if (b1) {
3679                 rm = (modrm & 7) | REX_B(s);
3680                 tcg_gen_addi_ptr(s->ptr0, cpu_env,
3681                                  offsetof(CPUX86State, xmm_regs[rm]));
3682                 gen_helper_pmovmskb_xmm(s->tmp2_i32, cpu_env, s->ptr0);
3683             } else {
3684                 rm = (modrm & 7);
3685                 tcg_gen_addi_ptr(s->ptr0, cpu_env,
3686                                  offsetof(CPUX86State, fpregs[rm].mmx));
3687                 gen_helper_pmovmskb_mmx(s->tmp2_i32, cpu_env, s->ptr0);
3688             }
3689             reg = ((modrm >> 3) & 7) | rex_r;
3690             tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
3691             break;
3692 
3693         case 0x138:
3694         case 0x038:
3695             b = modrm;
3696             if ((b & 0xf0) == 0xf0) {
3697                 goto do_0f_38_fx;
3698             }
3699             modrm = x86_ldub_code(env, s);
3700             rm = modrm & 7;
3701             reg = ((modrm >> 3) & 7) | rex_r;
3702             mod = (modrm >> 6) & 3;
3703             if (b1 >= 2) {
3704                 goto unknown_op;
3705             }
3706 
3707             sse_fn_epp = sse_op_table6[b].op[b1];
3708             if (!sse_fn_epp) {
3709                 goto unknown_op;
3710             }
3711             if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))
3712                 goto illegal_op;
3713 
3714             if (b1) {
3715                 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3716                 if (mod == 3) {
3717                     op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
3718                 } else {
3719                     op2_offset = offsetof(CPUX86State,xmm_t0);
3720                     gen_lea_modrm(env, s, modrm);
3721                     switch (b) {
3722                     case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */
3723                     case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */
3724                     case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */
3725                         gen_ldq_env_A0(s, op2_offset +
3726                                         offsetof(ZMMReg, ZMM_Q(0)));
3727                         break;
3728                     case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
3729                     case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
3730                         tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
3731                                             s->mem_index, MO_LEUL);
3732                         tcg_gen_st_i32(s->tmp2_i32, cpu_env, op2_offset +
3733                                         offsetof(ZMMReg, ZMM_L(0)));
3734                         break;
3735                     case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
3736                         tcg_gen_qemu_ld_tl(s->tmp0, s->A0,
3737                                            s->mem_index, MO_LEUW);
3738                         tcg_gen_st16_tl(s->tmp0, cpu_env, op2_offset +
3739                                         offsetof(ZMMReg, ZMM_W(0)));
3740                         break;
3741                     case 0x2a:            /* movntqda */
3742                         gen_ldo_env_A0(s, op1_offset);
3743                         return;
3744                     default:
3745                         gen_ldo_env_A0(s, op2_offset);
3746                     }
3747                 }
3748             } else {
3749                 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3750                 if (mod == 3) {
3751                     op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3752                 } else {
3753                     op2_offset = offsetof(CPUX86State,mmx_t0);
3754                     gen_lea_modrm(env, s, modrm);
3755                     gen_ldq_env_A0(s, op2_offset);
3756                 }
3757             }
3758             if (sse_fn_epp == SSE_SPECIAL) {
3759                 goto unknown_op;
3760             }
3761 
3762             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
3763             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
3764             sse_fn_epp(cpu_env, s->ptr0, s->ptr1);
3765 
3766             if (b == 0x17) {
3767                 set_cc_op(s, CC_OP_EFLAGS);
3768             }
3769             break;
3770 
3771         case 0x238:
3772         case 0x338:
3773         do_0f_38_fx:
3774             /* Various integer extensions at 0f 38 f[0-f].  */
3775             b = modrm | (b1 << 8);
3776             modrm = x86_ldub_code(env, s);
3777             reg = ((modrm >> 3) & 7) | rex_r;
3778 
3779             switch (b) {
3780             case 0x3f0: /* crc32 Gd,Eb */
3781             case 0x3f1: /* crc32 Gd,Ey */
3782             do_crc32:
3783                 if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {
3784                     goto illegal_op;
3785                 }
3786                 if ((b & 0xff) == 0xf0) {
3787                     ot = MO_8;
3788                 } else if (s->dflag != MO_64) {
3789                     ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3790                 } else {
3791                     ot = MO_64;
3792                 }
3793 
3794                 tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[reg]);
3795                 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3796                 gen_helper_crc32(s->T0, s->tmp2_i32,
3797                                  s->T0, tcg_const_i32(8 << ot));
3798 
3799                 ot = mo_64_32(s->dflag);
3800                 gen_op_mov_reg_v(s, ot, reg, s->T0);
3801                 break;
3802 
3803             case 0x1f0: /* crc32 or movbe */
3804             case 0x1f1:
3805                 /* For these insns, the f3 prefix is supposed to have priority
3806                    over the 66 prefix, but that's not what we implement above
3807                    setting b1.  */
3808                 if (s->prefix & PREFIX_REPNZ) {
3809                     goto do_crc32;
3810                 }
3811                 /* FALLTHRU */
3812             case 0x0f0: /* movbe Gy,My */
3813             case 0x0f1: /* movbe My,Gy */
3814                 if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {
3815                     goto illegal_op;
3816                 }
3817                 if (s->dflag != MO_64) {
3818                     ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);
3819                 } else {
3820                     ot = MO_64;
3821                 }
3822 
3823                 gen_lea_modrm(env, s, modrm);
3824                 if ((b & 1) == 0) {
3825                     tcg_gen_qemu_ld_tl(s->T0, s->A0,
3826                                        s->mem_index, ot | MO_BE);
3827                     gen_op_mov_reg_v(s, ot, reg, s->T0);
3828                 } else {
3829                     tcg_gen_qemu_st_tl(cpu_regs[reg], s->A0,
3830                                        s->mem_index, ot | MO_BE);
3831                 }
3832                 break;
3833 
3834             case 0x0f2: /* andn Gy, By, Ey */
3835                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3836                     || !(s->prefix & PREFIX_VEX)
3837                     || s->vex_l != 0) {
3838                     goto illegal_op;
3839                 }
3840                 ot = mo_64_32(s->dflag);
3841                 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3842                 tcg_gen_andc_tl(s->T0, s->T0, cpu_regs[s->vex_v]);
3843                 gen_op_mov_reg_v(s, ot, reg, s->T0);
3844                 gen_op_update1_cc(s);
3845                 set_cc_op(s, CC_OP_LOGICB + ot);
3846                 break;
3847 
3848             case 0x0f7: /* bextr Gy, Ey, By */
3849                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
3850                     || !(s->prefix & PREFIX_VEX)
3851                     || s->vex_l != 0) {
3852                     goto illegal_op;
3853                 }
3854                 ot = mo_64_32(s->dflag);
3855                 {
3856                     TCGv bound, zero;
3857 
3858                     gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3859                     /* Extract START, and shift the operand.
3860                        Shifts larger than operand size get zeros.  */
3861                     tcg_gen_ext8u_tl(s->A0, cpu_regs[s->vex_v]);
3862                     tcg_gen_shr_tl(s->T0, s->T0, s->A0);
3863 
3864                     bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3865                     zero = tcg_const_tl(0);
3866                     tcg_gen_movcond_tl(TCG_COND_LEU, s->T0, s->A0, bound,
3867                                        s->T0, zero);
3868                     tcg_temp_free(zero);
3869 
3870                     /* Extract the LEN into a mask.  Lengths larger than
3871                        operand size get all ones.  */
3872                     tcg_gen_extract_tl(s->A0, cpu_regs[s->vex_v], 8, 8);
3873                     tcg_gen_movcond_tl(TCG_COND_LEU, s->A0, s->A0, bound,
3874                                        s->A0, bound);
3875                     tcg_temp_free(bound);
3876                     tcg_gen_movi_tl(s->T1, 1);
3877                     tcg_gen_shl_tl(s->T1, s->T1, s->A0);
3878                     tcg_gen_subi_tl(s->T1, s->T1, 1);
3879                     tcg_gen_and_tl(s->T0, s->T0, s->T1);
3880 
3881                     gen_op_mov_reg_v(s, ot, reg, s->T0);
3882                     gen_op_update1_cc(s);
3883                     set_cc_op(s, CC_OP_LOGICB + ot);
3884                 }
3885                 break;
3886 
3887             case 0x0f5: /* bzhi Gy, Ey, By */
3888                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3889                     || !(s->prefix & PREFIX_VEX)
3890                     || s->vex_l != 0) {
3891                     goto illegal_op;
3892                 }
3893                 ot = mo_64_32(s->dflag);
3894                 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3895                 tcg_gen_ext8u_tl(s->T1, cpu_regs[s->vex_v]);
3896                 {
3897                     TCGv bound = tcg_const_tl(ot == MO_64 ? 63 : 31);
3898                     /* Note that since we're using BMILG (in order to get O
3899                        cleared) we need to store the inverse into C.  */
3900                     tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src,
3901                                        s->T1, bound);
3902                     tcg_gen_movcond_tl(TCG_COND_GT, s->T1, s->T1,
3903                                        bound, bound, s->T1);
3904                     tcg_temp_free(bound);
3905                 }
3906                 tcg_gen_movi_tl(s->A0, -1);
3907                 tcg_gen_shl_tl(s->A0, s->A0, s->T1);
3908                 tcg_gen_andc_tl(s->T0, s->T0, s->A0);
3909                 gen_op_mov_reg_v(s, ot, reg, s->T0);
3910                 gen_op_update1_cc(s);
3911                 set_cc_op(s, CC_OP_BMILGB + ot);
3912                 break;
3913 
3914             case 0x3f6: /* mulx By, Gy, rdx, Ey */
3915                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3916                     || !(s->prefix & PREFIX_VEX)
3917                     || s->vex_l != 0) {
3918                     goto illegal_op;
3919                 }
3920                 ot = mo_64_32(s->dflag);
3921                 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3922                 switch (ot) {
3923                 default:
3924                     tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3925                     tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EDX]);
3926                     tcg_gen_mulu2_i32(s->tmp2_i32, s->tmp3_i32,
3927                                       s->tmp2_i32, s->tmp3_i32);
3928                     tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], s->tmp2_i32);
3929                     tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp3_i32);
3930                     break;
3931 #ifdef TARGET_X86_64
3932                 case MO_64:
3933                     tcg_gen_mulu2_i64(s->T0, s->T1,
3934                                       s->T0, cpu_regs[R_EDX]);
3935                     tcg_gen_mov_i64(cpu_regs[s->vex_v], s->T0);
3936                     tcg_gen_mov_i64(cpu_regs[reg], s->T1);
3937                     break;
3938 #endif
3939                 }
3940                 break;
3941 
3942             case 0x3f5: /* pdep Gy, By, Ey */
3943                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3944                     || !(s->prefix & PREFIX_VEX)
3945                     || s->vex_l != 0) {
3946                     goto illegal_op;
3947                 }
3948                 ot = mo_64_32(s->dflag);
3949                 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3950                 /* Note that by zero-extending the mask operand, we
3951                    automatically handle zero-extending the result.  */
3952                 if (ot == MO_64) {
3953                     tcg_gen_mov_tl(s->T1, cpu_regs[s->vex_v]);
3954                 } else {
3955                     tcg_gen_ext32u_tl(s->T1, cpu_regs[s->vex_v]);
3956                 }
3957                 gen_helper_pdep(cpu_regs[reg], s->T0, s->T1);
3958                 break;
3959 
3960             case 0x2f5: /* pext Gy, By, Ey */
3961                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
3962                     || !(s->prefix & PREFIX_VEX)
3963                     || s->vex_l != 0) {
3964                     goto illegal_op;
3965                 }
3966                 ot = mo_64_32(s->dflag);
3967                 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3968                 /* Note that by zero-extending the mask operand, we
3969                    automatically handle zero-extending the result.  */
3970                 if (ot == MO_64) {
3971                     tcg_gen_mov_tl(s->T1, cpu_regs[s->vex_v]);
3972                 } else {
3973                     tcg_gen_ext32u_tl(s->T1, cpu_regs[s->vex_v]);
3974                 }
3975                 gen_helper_pext(cpu_regs[reg], s->T0, s->T1);
3976                 break;
3977 
3978             case 0x1f6: /* adcx Gy, Ey */
3979             case 0x2f6: /* adox Gy, Ey */
3980                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {
3981                     goto illegal_op;
3982                 } else {
3983                     TCGv carry_in, carry_out, zero;
3984                     int end_op;
3985 
3986                     ot = mo_64_32(s->dflag);
3987                     gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
3988 
3989                     /* Re-use the carry-out from a previous round.  */
3990                     carry_in = NULL;
3991                     carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);
3992                     switch (s->cc_op) {
3993                     case CC_OP_ADCX:
3994                         if (b == 0x1f6) {
3995                             carry_in = cpu_cc_dst;
3996                             end_op = CC_OP_ADCX;
3997                         } else {
3998                             end_op = CC_OP_ADCOX;
3999                         }
4000                         break;
4001                     case CC_OP_ADOX:
4002                         if (b == 0x1f6) {
4003                             end_op = CC_OP_ADCOX;
4004                         } else {
4005                             carry_in = cpu_cc_src2;
4006                             end_op = CC_OP_ADOX;
4007                         }
4008                         break;
4009                     case CC_OP_ADCOX:
4010                         end_op = CC_OP_ADCOX;
4011                         carry_in = carry_out;
4012                         break;
4013                     default:
4014                         end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX);
4015                         break;
4016                     }
4017                     /* If we can't reuse carry-out, get it out of EFLAGS.  */
4018                     if (!carry_in) {
4019                         if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {
4020                             gen_compute_eflags(s);
4021                         }
4022                         carry_in = s->tmp0;
4023                         tcg_gen_extract_tl(carry_in, cpu_cc_src,
4024                                            ctz32(b == 0x1f6 ? CC_C : CC_O), 1);
4025                     }
4026 
4027                     switch (ot) {
4028 #ifdef TARGET_X86_64
4029                     case MO_32:
4030                         /* If we know TL is 64-bit, and we want a 32-bit
4031                            result, just do everything in 64-bit arithmetic.  */
4032                         tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]);
4033                         tcg_gen_ext32u_i64(s->T0, s->T0);
4034                         tcg_gen_add_i64(s->T0, s->T0, cpu_regs[reg]);
4035                         tcg_gen_add_i64(s->T0, s->T0, carry_in);
4036                         tcg_gen_ext32u_i64(cpu_regs[reg], s->T0);
4037                         tcg_gen_shri_i64(carry_out, s->T0, 32);
4038                         break;
4039 #endif
4040                     default:
4041                         /* Otherwise compute the carry-out in two steps.  */
4042                         zero = tcg_const_tl(0);
4043                         tcg_gen_add2_tl(s->T0, carry_out,
4044                                         s->T0, zero,
4045                                         carry_in, zero);
4046                         tcg_gen_add2_tl(cpu_regs[reg], carry_out,
4047                                         cpu_regs[reg], carry_out,
4048                                         s->T0, zero);
4049                         tcg_temp_free(zero);
4050                         break;
4051                     }
4052                     set_cc_op(s, end_op);
4053                 }
4054                 break;
4055 
4056             case 0x1f7: /* shlx Gy, Ey, By */
4057             case 0x2f7: /* sarx Gy, Ey, By */
4058             case 0x3f7: /* shrx Gy, Ey, By */
4059                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4060                     || !(s->prefix & PREFIX_VEX)
4061                     || s->vex_l != 0) {
4062                     goto illegal_op;
4063                 }
4064                 ot = mo_64_32(s->dflag);
4065                 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4066                 if (ot == MO_64) {
4067                     tcg_gen_andi_tl(s->T1, cpu_regs[s->vex_v], 63);
4068                 } else {
4069                     tcg_gen_andi_tl(s->T1, cpu_regs[s->vex_v], 31);
4070                 }
4071                 if (b == 0x1f7) {
4072                     tcg_gen_shl_tl(s->T0, s->T0, s->T1);
4073                 } else if (b == 0x2f7) {
4074                     if (ot != MO_64) {
4075                         tcg_gen_ext32s_tl(s->T0, s->T0);
4076                     }
4077                     tcg_gen_sar_tl(s->T0, s->T0, s->T1);
4078                 } else {
4079                     if (ot != MO_64) {
4080                         tcg_gen_ext32u_tl(s->T0, s->T0);
4081                     }
4082                     tcg_gen_shr_tl(s->T0, s->T0, s->T1);
4083                 }
4084                 gen_op_mov_reg_v(s, ot, reg, s->T0);
4085                 break;
4086 
4087             case 0x0f3:
4088             case 0x1f3:
4089             case 0x2f3:
4090             case 0x3f3: /* Group 17 */
4091                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)
4092                     || !(s->prefix & PREFIX_VEX)
4093                     || s->vex_l != 0) {
4094                     goto illegal_op;
4095                 }
4096                 ot = mo_64_32(s->dflag);
4097                 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4098 
4099                 tcg_gen_mov_tl(cpu_cc_src, s->T0);
4100                 switch (reg & 7) {
4101                 case 1: /* blsr By,Ey */
4102                     tcg_gen_subi_tl(s->T1, s->T0, 1);
4103                     tcg_gen_and_tl(s->T0, s->T0, s->T1);
4104                     break;
4105                 case 2: /* blsmsk By,Ey */
4106                     tcg_gen_subi_tl(s->T1, s->T0, 1);
4107                     tcg_gen_xor_tl(s->T0, s->T0, s->T1);
4108                     break;
4109                 case 3: /* blsi By, Ey */
4110                     tcg_gen_neg_tl(s->T1, s->T0);
4111                     tcg_gen_and_tl(s->T0, s->T0, s->T1);
4112                     break;
4113                 default:
4114                     goto unknown_op;
4115                 }
4116                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
4117                 gen_op_mov_reg_v(s, ot, s->vex_v, s->T0);
4118                 set_cc_op(s, CC_OP_BMILGB + ot);
4119                 break;
4120 
4121             default:
4122                 goto unknown_op;
4123             }
4124             break;
4125 
4126         case 0x03a:
4127         case 0x13a:
4128             b = modrm;
4129             modrm = x86_ldub_code(env, s);
4130             rm = modrm & 7;
4131             reg = ((modrm >> 3) & 7) | rex_r;
4132             mod = (modrm >> 6) & 3;
4133             if (b1 >= 2) {
4134                 goto unknown_op;
4135             }
4136 
4137             sse_fn_eppi = sse_op_table7[b].op[b1];
4138             if (!sse_fn_eppi) {
4139                 goto unknown_op;
4140             }
4141             if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))
4142                 goto illegal_op;
4143 
4144             s->rip_offset = 1;
4145 
4146             if (sse_fn_eppi == SSE_SPECIAL) {
4147                 ot = mo_64_32(s->dflag);
4148                 rm = (modrm & 7) | REX_B(s);
4149                 if (mod != 3)
4150                     gen_lea_modrm(env, s, modrm);
4151                 reg = ((modrm >> 3) & 7) | rex_r;
4152                 val = x86_ldub_code(env, s);
4153                 switch (b) {
4154                 case 0x14: /* pextrb */
4155                     tcg_gen_ld8u_tl(s->T0, cpu_env, offsetof(CPUX86State,
4156                                             xmm_regs[reg].ZMM_B(val & 15)));
4157                     if (mod == 3) {
4158                         gen_op_mov_reg_v(s, ot, rm, s->T0);
4159                     } else {
4160                         tcg_gen_qemu_st_tl(s->T0, s->A0,
4161                                            s->mem_index, MO_UB);
4162                     }
4163                     break;
4164                 case 0x15: /* pextrw */
4165                     tcg_gen_ld16u_tl(s->T0, cpu_env, offsetof(CPUX86State,
4166                                             xmm_regs[reg].ZMM_W(val & 7)));
4167                     if (mod == 3) {
4168                         gen_op_mov_reg_v(s, ot, rm, s->T0);
4169                     } else {
4170                         tcg_gen_qemu_st_tl(s->T0, s->A0,
4171                                            s->mem_index, MO_LEUW);
4172                     }
4173                     break;
4174                 case 0x16:
4175                     if (ot == MO_32) { /* pextrd */
4176                         tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
4177                                         offsetof(CPUX86State,
4178                                                 xmm_regs[reg].ZMM_L(val & 3)));
4179                         if (mod == 3) {
4180                             tcg_gen_extu_i32_tl(cpu_regs[rm], s->tmp2_i32);
4181                         } else {
4182                             tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
4183                                                 s->mem_index, MO_LEUL);
4184                         }
4185                     } else { /* pextrq */
4186 #ifdef TARGET_X86_64
4187                         tcg_gen_ld_i64(s->tmp1_i64, cpu_env,
4188                                         offsetof(CPUX86State,
4189                                                 xmm_regs[reg].ZMM_Q(val & 1)));
4190                         if (mod == 3) {
4191                             tcg_gen_mov_i64(cpu_regs[rm], s->tmp1_i64);
4192                         } else {
4193                             tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
4194                                                 s->mem_index, MO_LEQ);
4195                         }
4196 #else
4197                         goto illegal_op;
4198 #endif
4199                     }
4200                     break;
4201                 case 0x17: /* extractps */
4202                     tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State,
4203                                             xmm_regs[reg].ZMM_L(val & 3)));
4204                     if (mod == 3) {
4205                         gen_op_mov_reg_v(s, ot, rm, s->T0);
4206                     } else {
4207                         tcg_gen_qemu_st_tl(s->T0, s->A0,
4208                                            s->mem_index, MO_LEUL);
4209                     }
4210                     break;
4211                 case 0x20: /* pinsrb */
4212                     if (mod == 3) {
4213                         gen_op_mov_v_reg(s, MO_32, s->T0, rm);
4214                     } else {
4215                         tcg_gen_qemu_ld_tl(s->T0, s->A0,
4216                                            s->mem_index, MO_UB);
4217                     }
4218                     tcg_gen_st8_tl(s->T0, cpu_env, offsetof(CPUX86State,
4219                                             xmm_regs[reg].ZMM_B(val & 15)));
4220                     break;
4221                 case 0x21: /* insertps */
4222                     if (mod == 3) {
4223                         tcg_gen_ld_i32(s->tmp2_i32, cpu_env,
4224                                         offsetof(CPUX86State,xmm_regs[rm]
4225                                                 .ZMM_L((val >> 6) & 3)));
4226                     } else {
4227                         tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4228                                             s->mem_index, MO_LEUL);
4229                     }
4230                     tcg_gen_st_i32(s->tmp2_i32, cpu_env,
4231                                     offsetof(CPUX86State,xmm_regs[reg]
4232                                             .ZMM_L((val >> 4) & 3)));
4233                     if ((val >> 0) & 1)
4234                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4235                                         cpu_env, offsetof(CPUX86State,
4236                                                 xmm_regs[reg].ZMM_L(0)));
4237                     if ((val >> 1) & 1)
4238                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4239                                         cpu_env, offsetof(CPUX86State,
4240                                                 xmm_regs[reg].ZMM_L(1)));
4241                     if ((val >> 2) & 1)
4242                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4243                                         cpu_env, offsetof(CPUX86State,
4244                                                 xmm_regs[reg].ZMM_L(2)));
4245                     if ((val >> 3) & 1)
4246                         tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),
4247                                         cpu_env, offsetof(CPUX86State,
4248                                                 xmm_regs[reg].ZMM_L(3)));
4249                     break;
4250                 case 0x22:
4251                     if (ot == MO_32) { /* pinsrd */
4252                         if (mod == 3) {
4253                             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[rm]);
4254                         } else {
4255                             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
4256                                                 s->mem_index, MO_LEUL);
4257                         }
4258                         tcg_gen_st_i32(s->tmp2_i32, cpu_env,
4259                                         offsetof(CPUX86State,
4260                                                 xmm_regs[reg].ZMM_L(val & 3)));
4261                     } else { /* pinsrq */
4262 #ifdef TARGET_X86_64
4263                         if (mod == 3) {
4264                             gen_op_mov_v_reg(s, ot, s->tmp1_i64, rm);
4265                         } else {
4266                             tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
4267                                                 s->mem_index, MO_LEQ);
4268                         }
4269                         tcg_gen_st_i64(s->tmp1_i64, cpu_env,
4270                                         offsetof(CPUX86State,
4271                                                 xmm_regs[reg].ZMM_Q(val & 1)));
4272 #else
4273                         goto illegal_op;
4274 #endif
4275                     }
4276                     break;
4277                 }
4278                 return;
4279             }
4280 
4281             if (b1) {
4282                 op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4283                 if (mod == 3) {
4284                     op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);
4285                 } else {
4286                     op2_offset = offsetof(CPUX86State,xmm_t0);
4287                     gen_lea_modrm(env, s, modrm);
4288                     gen_ldo_env_A0(s, op2_offset);
4289                 }
4290             } else {
4291                 op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4292                 if (mod == 3) {
4293                     op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4294                 } else {
4295                     op2_offset = offsetof(CPUX86State,mmx_t0);
4296                     gen_lea_modrm(env, s, modrm);
4297                     gen_ldq_env_A0(s, op2_offset);
4298                 }
4299             }
4300             val = x86_ldub_code(env, s);
4301 
4302             if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
4303                 set_cc_op(s, CC_OP_EFLAGS);
4304 
4305                 if (s->dflag == MO_64) {
4306                     /* The helper must use entire 64-bit gp registers */
4307                     val |= 1 << 8;
4308                 }
4309             }
4310 
4311             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4312             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4313             sse_fn_eppi(cpu_env, s->ptr0, s->ptr1, tcg_const_i32(val));
4314             break;
4315 
4316         case 0x33a:
4317             /* Various integer extensions at 0f 3a f[0-f].  */
4318             b = modrm | (b1 << 8);
4319             modrm = x86_ldub_code(env, s);
4320             reg = ((modrm >> 3) & 7) | rex_r;
4321 
4322             switch (b) {
4323             case 0x3f0: /* rorx Gy,Ey, Ib */
4324                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)
4325                     || !(s->prefix & PREFIX_VEX)
4326                     || s->vex_l != 0) {
4327                     goto illegal_op;
4328                 }
4329                 ot = mo_64_32(s->dflag);
4330                 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
4331                 b = x86_ldub_code(env, s);
4332                 if (ot == MO_64) {
4333                     tcg_gen_rotri_tl(s->T0, s->T0, b & 63);
4334                 } else {
4335                     tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
4336                     tcg_gen_rotri_i32(s->tmp2_i32, s->tmp2_i32, b & 31);
4337                     tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
4338                 }
4339                 gen_op_mov_reg_v(s, ot, reg, s->T0);
4340                 break;
4341 
4342             default:
4343                 goto unknown_op;
4344             }
4345             break;
4346 
4347         default:
4348         unknown_op:
4349             gen_unknown_opcode(env, s);
4350             return;
4351         }
4352     } else {
4353         /* generic MMX or SSE operation */
4354         switch(b) {
4355         case 0x70: /* pshufx insn */
4356         case 0xc6: /* pshufx insn */
4357         case 0xc2: /* compare insns */
4358             s->rip_offset = 1;
4359             break;
4360         default:
4361             break;
4362         }
4363         if (is_xmm) {
4364             op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
4365             if (mod != 3) {
4366                 int sz = 4;
4367 
4368                 gen_lea_modrm(env, s, modrm);
4369                 op2_offset = offsetof(CPUX86State,xmm_t0);
4370 
4371                 switch (b) {
4372                 case 0x50 ... 0x5a:
4373                 case 0x5c ... 0x5f:
4374                 case 0xc2:
4375                     /* Most sse scalar operations.  */
4376                     if (b1 == 2) {
4377                         sz = 2;
4378                     } else if (b1 == 3) {
4379                         sz = 3;
4380                     }
4381                     break;
4382 
4383                 case 0x2e:  /* ucomis[sd] */
4384                 case 0x2f:  /* comis[sd] */
4385                     if (b1 == 0) {
4386                         sz = 2;
4387                     } else {
4388                         sz = 3;
4389                     }
4390                     break;
4391                 }
4392 
4393                 switch (sz) {
4394                 case 2:
4395                     /* 32 bit access */
4396                     gen_op_ld_v(s, MO_32, s->T0, s->A0);
4397                     tcg_gen_st32_tl(s->T0, cpu_env,
4398                                     offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
4399                     break;
4400                 case 3:
4401                     /* 64 bit access */
4402                     gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0)));
4403                     break;
4404                 default:
4405                     /* 128 bit access */
4406                     gen_ldo_env_A0(s, op2_offset);
4407                     break;
4408                 }
4409             } else {
4410                 rm = (modrm & 7) | REX_B(s);
4411                 op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
4412             }
4413         } else {
4414             op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
4415             if (mod != 3) {
4416                 gen_lea_modrm(env, s, modrm);
4417                 op2_offset = offsetof(CPUX86State,mmx_t0);
4418                 gen_ldq_env_A0(s, op2_offset);
4419             } else {
4420                 rm = (modrm & 7);
4421                 op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
4422             }
4423         }
4424         switch(b) {
4425         case 0x0f: /* 3DNow! data insns */
4426             val = x86_ldub_code(env, s);
4427             sse_fn_epp = sse_op_table5[val];
4428             if (!sse_fn_epp) {
4429                 goto unknown_op;
4430             }
4431             if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
4432                 goto illegal_op;
4433             }
4434             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4435             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4436             sse_fn_epp(cpu_env, s->ptr0, s->ptr1);
4437             break;
4438         case 0x70: /* pshufx insn */
4439         case 0xc6: /* pshufx insn */
4440             val = x86_ldub_code(env, s);
4441             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4442             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4443             /* XXX: introduce a new table? */
4444             sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;
4445             sse_fn_ppi(s->ptr0, s->ptr1, tcg_const_i32(val));
4446             break;
4447         case 0xc2:
4448             /* compare insns */
4449             val = x86_ldub_code(env, s);
4450             if (val >= 8)
4451                 goto unknown_op;
4452             sse_fn_epp = sse_op_table4[val][b1];
4453 
4454             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4455             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4456             sse_fn_epp(cpu_env, s->ptr0, s->ptr1);
4457             break;
4458         case 0xf7:
4459             /* maskmov : we must prepare A0 */
4460             if (mod != 3)
4461                 goto illegal_op;
4462             tcg_gen_mov_tl(s->A0, cpu_regs[R_EDI]);
4463             gen_extu(s->aflag, s->A0);
4464             gen_add_A0_ds_seg(s);
4465 
4466             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4467             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4468             /* XXX: introduce a new table? */
4469             sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;
4470             sse_fn_eppt(cpu_env, s->ptr0, s->ptr1, s->A0);
4471             break;
4472         default:
4473             tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
4474             tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
4475             sse_fn_epp(cpu_env, s->ptr0, s->ptr1);
4476             break;
4477         }
4478         if (b == 0x2e || b == 0x2f) {
4479             set_cc_op(s, CC_OP_EFLAGS);
4480         }
4481     }
4482 }
4483 
4484 /* convert one instruction. s->base.is_jmp is set if the translation must
4485    be stopped. Return the next pc value */
disas_insn(DisasContext * s,CPUState * cpu)4486 static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
4487 {
4488     CPUX86State *env = cpu->env_ptr;
4489     int b, prefixes;
4490     int shift;
4491     MemOp ot, aflag, dflag;
4492     int modrm, reg, rm, mod, op, opreg, val;
4493     target_ulong next_eip, tval;
4494     int rex_w, rex_r;
4495     target_ulong pc_start = s->base.pc_next;
4496 
4497     s->pc_start = s->pc = pc_start;
4498     s->override = -1;
4499 #ifdef TARGET_X86_64
4500     s->rex_x = 0;
4501     s->rex_b = 0;
4502     s->x86_64_hregs = false;
4503 #endif
4504     s->rip_offset = 0; /* for relative ip address */
4505     s->vex_l = 0;
4506     s->vex_v = 0;
4507     if (sigsetjmp(s->jmpbuf, 0) != 0) {
4508         gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
4509         return s->pc;
4510     }
4511 
4512     prefixes = 0;
4513     rex_w = -1;
4514     rex_r = 0;
4515 
4516  next_byte:
4517     b = x86_ldub_code(env, s);
4518     /* Collect prefixes.  */
4519     switch (b) {
4520     case 0xf3:
4521         prefixes |= PREFIX_REPZ;
4522         goto next_byte;
4523     case 0xf2:
4524         prefixes |= PREFIX_REPNZ;
4525         goto next_byte;
4526     case 0xf0:
4527         prefixes |= PREFIX_LOCK;
4528         goto next_byte;
4529     case 0x2e:
4530         s->override = R_CS;
4531         goto next_byte;
4532     case 0x36:
4533         s->override = R_SS;
4534         goto next_byte;
4535     case 0x3e:
4536         s->override = R_DS;
4537         goto next_byte;
4538     case 0x26:
4539         s->override = R_ES;
4540         goto next_byte;
4541     case 0x64:
4542         s->override = R_FS;
4543         goto next_byte;
4544     case 0x65:
4545         s->override = R_GS;
4546         goto next_byte;
4547     case 0x66:
4548         prefixes |= PREFIX_DATA;
4549         goto next_byte;
4550     case 0x67:
4551         prefixes |= PREFIX_ADR;
4552         goto next_byte;
4553 #ifdef TARGET_X86_64
4554     case 0x40 ... 0x4f:
4555         if (CODE64(s)) {
4556             /* REX prefix */
4557             rex_w = (b >> 3) & 1;
4558             rex_r = (b & 0x4) << 1;
4559             s->rex_x = (b & 0x2) << 2;
4560             REX_B(s) = (b & 0x1) << 3;
4561             /* select uniform byte register addressing */
4562             s->x86_64_hregs = true;
4563             goto next_byte;
4564         }
4565         break;
4566 #endif
4567     case 0xc5: /* 2-byte VEX */
4568     case 0xc4: /* 3-byte VEX */
4569         /* VEX prefixes cannot be used except in 32-bit mode.
4570            Otherwise the instruction is LES or LDS.  */
4571         if (s->code32 && !s->vm86) {
4572             static const int pp_prefix[4] = {
4573                 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
4574             };
4575             int vex3, vex2 = x86_ldub_code(env, s);
4576 
4577             if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
4578                 /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
4579                    otherwise the instruction is LES or LDS.  */
4580                 s->pc--; /* rewind the advance_pc() x86_ldub_code() did */
4581                 break;
4582             }
4583 
4584             /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
4585             if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
4586                             | PREFIX_LOCK | PREFIX_DATA)) {
4587                 goto illegal_op;
4588             }
4589 #ifdef TARGET_X86_64
4590             if (s->x86_64_hregs) {
4591                 goto illegal_op;
4592             }
4593 #endif
4594             rex_r = (~vex2 >> 4) & 8;
4595             if (b == 0xc5) {
4596                 /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
4597                 vex3 = vex2;
4598                 b = x86_ldub_code(env, s) | 0x100;
4599             } else {
4600                 /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
4601 #ifdef TARGET_X86_64
4602                 s->rex_x = (~vex2 >> 3) & 8;
4603                 s->rex_b = (~vex2 >> 2) & 8;
4604 #endif
4605                 vex3 = x86_ldub_code(env, s);
4606                 rex_w = (vex3 >> 7) & 1;
4607                 switch (vex2 & 0x1f) {
4608                 case 0x01: /* Implied 0f leading opcode bytes.  */
4609                     b = x86_ldub_code(env, s) | 0x100;
4610                     break;
4611                 case 0x02: /* Implied 0f 38 leading opcode bytes.  */
4612                     b = 0x138;
4613                     break;
4614                 case 0x03: /* Implied 0f 3a leading opcode bytes.  */
4615                     b = 0x13a;
4616                     break;
4617                 default:   /* Reserved for future use.  */
4618                     goto unknown_op;
4619                 }
4620             }
4621             s->vex_v = (~vex3 >> 3) & 0xf;
4622             s->vex_l = (vex3 >> 2) & 1;
4623             prefixes |= pp_prefix[vex3 & 3] | PREFIX_VEX;
4624         }
4625         break;
4626     }
4627 
4628     /* Post-process prefixes.  */
4629     if (CODE64(s)) {
4630         /* In 64-bit mode, the default data size is 32-bit.  Select 64-bit
4631            data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
4632            over 0x66 if both are present.  */
4633         dflag = (rex_w > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
4634         /* In 64-bit mode, 0x67 selects 32-bit addressing.  */
4635         aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
4636     } else {
4637         /* In 16/32-bit mode, 0x66 selects the opposite data size.  */
4638         if (s->code32 ^ ((prefixes & PREFIX_DATA) != 0)) {
4639             dflag = MO_32;
4640         } else {
4641             dflag = MO_16;
4642         }
4643         /* In 16/32-bit mode, 0x67 selects the opposite addressing.  */
4644         if (s->code32 ^ ((prefixes & PREFIX_ADR) != 0)) {
4645             aflag = MO_32;
4646         }  else {
4647             aflag = MO_16;
4648         }
4649     }
4650 
4651     s->prefix = prefixes;
4652     s->aflag = aflag;
4653     s->dflag = dflag;
4654 
4655     /* now check op code */
4656  reswitch:
4657     switch(b) {
4658     case 0x0f:
4659         /**************************/
4660         /* extended op code */
4661         b = x86_ldub_code(env, s) | 0x100;
4662         goto reswitch;
4663 
4664         /**************************/
4665         /* arith & logic */
4666     case 0x00 ... 0x05:
4667     case 0x08 ... 0x0d:
4668     case 0x10 ... 0x15:
4669     case 0x18 ... 0x1d:
4670     case 0x20 ... 0x25:
4671     case 0x28 ... 0x2d:
4672     case 0x30 ... 0x35:
4673     case 0x38 ... 0x3d:
4674         {
4675             int op, f, val;
4676             op = (b >> 3) & 7;
4677             f = (b >> 1) & 3;
4678 
4679             ot = mo_b_d(b, dflag);
4680 
4681             switch(f) {
4682             case 0: /* OP Ev, Gv */
4683                 modrm = x86_ldub_code(env, s);
4684                 reg = ((modrm >> 3) & 7) | rex_r;
4685                 mod = (modrm >> 6) & 3;
4686                 rm = (modrm & 7) | REX_B(s);
4687                 if (mod != 3) {
4688                     gen_lea_modrm(env, s, modrm);
4689                     opreg = OR_TMP0;
4690                 } else if (op == OP_XORL && rm == reg) {
4691                 xor_zero:
4692                     /* xor reg, reg optimisation */
4693                     set_cc_op(s, CC_OP_CLR);
4694                     tcg_gen_movi_tl(s->T0, 0);
4695                     gen_op_mov_reg_v(s, ot, reg, s->T0);
4696                     break;
4697                 } else {
4698                     opreg = rm;
4699                 }
4700                 gen_op_mov_v_reg(s, ot, s->T1, reg);
4701                 gen_op(s, op, ot, opreg);
4702                 break;
4703             case 1: /* OP Gv, Ev */
4704                 modrm = x86_ldub_code(env, s);
4705                 mod = (modrm >> 6) & 3;
4706                 reg = ((modrm >> 3) & 7) | rex_r;
4707                 rm = (modrm & 7) | REX_B(s);
4708                 if (mod != 3) {
4709                     gen_lea_modrm(env, s, modrm);
4710                     gen_op_ld_v(s, ot, s->T1, s->A0);
4711                 } else if (op == OP_XORL && rm == reg) {
4712                     goto xor_zero;
4713                 } else {
4714                     gen_op_mov_v_reg(s, ot, s->T1, rm);
4715                 }
4716                 gen_op(s, op, ot, reg);
4717                 break;
4718             case 2: /* OP A, Iv */
4719                 val = insn_get(env, s, ot);
4720                 tcg_gen_movi_tl(s->T1, val);
4721                 gen_op(s, op, ot, OR_EAX);
4722                 break;
4723             }
4724         }
4725         break;
4726 
4727     case 0x82:
4728         if (CODE64(s))
4729             goto illegal_op;
4730         /* fall through */
4731     case 0x80: /* GRP1 */
4732     case 0x81:
4733     case 0x83:
4734         {
4735             int val;
4736 
4737             ot = mo_b_d(b, dflag);
4738 
4739             modrm = x86_ldub_code(env, s);
4740             mod = (modrm >> 6) & 3;
4741             rm = (modrm & 7) | REX_B(s);
4742             op = (modrm >> 3) & 7;
4743 
4744             if (mod != 3) {
4745                 if (b == 0x83)
4746                     s->rip_offset = 1;
4747                 else
4748                     s->rip_offset = insn_const_size(ot);
4749                 gen_lea_modrm(env, s, modrm);
4750                 opreg = OR_TMP0;
4751             } else {
4752                 opreg = rm;
4753             }
4754 
4755             switch(b) {
4756             default:
4757             case 0x80:
4758             case 0x81:
4759             case 0x82:
4760                 val = insn_get(env, s, ot);
4761                 break;
4762             case 0x83:
4763                 val = (int8_t)insn_get(env, s, MO_8);
4764                 break;
4765             }
4766             tcg_gen_movi_tl(s->T1, val);
4767             gen_op(s, op, ot, opreg);
4768         }
4769         break;
4770 
4771         /**************************/
4772         /* inc, dec, and other misc arith */
4773     case 0x40 ... 0x47: /* inc Gv */
4774         ot = dflag;
4775         gen_inc(s, ot, OR_EAX + (b & 7), 1);
4776         break;
4777     case 0x48 ... 0x4f: /* dec Gv */
4778         ot = dflag;
4779         gen_inc(s, ot, OR_EAX + (b & 7), -1);
4780         break;
4781     case 0xf6: /* GRP3 */
4782     case 0xf7:
4783         ot = mo_b_d(b, dflag);
4784 
4785         modrm = x86_ldub_code(env, s);
4786         mod = (modrm >> 6) & 3;
4787         rm = (modrm & 7) | REX_B(s);
4788         op = (modrm >> 3) & 7;
4789         if (mod != 3) {
4790             if (op == 0) {
4791                 s->rip_offset = insn_const_size(ot);
4792             }
4793             gen_lea_modrm(env, s, modrm);
4794             /* For those below that handle locked memory, don't load here.  */
4795             if (!(s->prefix & PREFIX_LOCK)
4796                 || op != 2) {
4797                 gen_op_ld_v(s, ot, s->T0, s->A0);
4798             }
4799         } else {
4800             gen_op_mov_v_reg(s, ot, s->T0, rm);
4801         }
4802 
4803         switch(op) {
4804         case 0: /* test */
4805             val = insn_get(env, s, ot);
4806             tcg_gen_movi_tl(s->T1, val);
4807             gen_op_testl_T0_T1_cc(s);
4808             set_cc_op(s, CC_OP_LOGICB + ot);
4809             break;
4810         case 2: /* not */
4811             if (s->prefix & PREFIX_LOCK) {
4812                 if (mod == 3) {
4813                     goto illegal_op;
4814                 }
4815                 tcg_gen_movi_tl(s->T0, ~0);
4816                 tcg_gen_atomic_xor_fetch_tl(s->T0, s->A0, s->T0,
4817                                             s->mem_index, ot | MO_LE);
4818             } else {
4819                 tcg_gen_not_tl(s->T0, s->T0);
4820                 if (mod != 3) {
4821                     gen_op_st_v(s, ot, s->T0, s->A0);
4822                 } else {
4823                     gen_op_mov_reg_v(s, ot, rm, s->T0);
4824                 }
4825             }
4826             break;
4827         case 3: /* neg */
4828             if (s->prefix & PREFIX_LOCK) {
4829                 TCGLabel *label1;
4830                 TCGv a0, t0, t1, t2;
4831 
4832                 if (mod == 3) {
4833                     goto illegal_op;
4834                 }
4835                 a0 = tcg_temp_local_new();
4836                 t0 = tcg_temp_local_new();
4837                 label1 = gen_new_label();
4838 
4839                 tcg_gen_mov_tl(a0, s->A0);
4840                 tcg_gen_mov_tl(t0, s->T0);
4841 
4842                 gen_set_label(label1);
4843                 t1 = tcg_temp_new();
4844                 t2 = tcg_temp_new();
4845                 tcg_gen_mov_tl(t2, t0);
4846                 tcg_gen_neg_tl(t1, t0);
4847                 tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
4848                                           s->mem_index, ot | MO_LE);
4849                 tcg_temp_free(t1);
4850                 tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
4851 
4852                 tcg_temp_free(t2);
4853                 tcg_temp_free(a0);
4854                 tcg_gen_mov_tl(s->T0, t0);
4855                 tcg_temp_free(t0);
4856             } else {
4857                 tcg_gen_neg_tl(s->T0, s->T0);
4858                 if (mod != 3) {
4859                     gen_op_st_v(s, ot, s->T0, s->A0);
4860                 } else {
4861                     gen_op_mov_reg_v(s, ot, rm, s->T0);
4862                 }
4863             }
4864             gen_op_update_neg_cc(s);
4865             set_cc_op(s, CC_OP_SUBB + ot);
4866             break;
4867         case 4: /* mul */
4868             switch(ot) {
4869             case MO_8:
4870                 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX);
4871                 tcg_gen_ext8u_tl(s->T0, s->T0);
4872                 tcg_gen_ext8u_tl(s->T1, s->T1);
4873                 /* XXX: use 32 bit mul which could be faster */
4874                 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
4875                 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
4876                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
4877                 tcg_gen_andi_tl(cpu_cc_src, s->T0, 0xff00);
4878                 set_cc_op(s, CC_OP_MULB);
4879                 break;
4880             case MO_16:
4881                 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX);
4882                 tcg_gen_ext16u_tl(s->T0, s->T0);
4883                 tcg_gen_ext16u_tl(s->T1, s->T1);
4884                 /* XXX: use 32 bit mul which could be faster */
4885                 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
4886                 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
4887                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
4888                 tcg_gen_shri_tl(s->T0, s->T0, 16);
4889                 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
4890                 tcg_gen_mov_tl(cpu_cc_src, s->T0);
4891                 set_cc_op(s, CC_OP_MULW);
4892                 break;
4893             default:
4894             case MO_32:
4895                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
4896                 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]);
4897                 tcg_gen_mulu2_i32(s->tmp2_i32, s->tmp3_i32,
4898                                   s->tmp2_i32, s->tmp3_i32);
4899                 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32);
4900                 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32);
4901                 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4902                 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4903                 set_cc_op(s, CC_OP_MULL);
4904                 break;
4905 #ifdef TARGET_X86_64
4906             case MO_64:
4907                 tcg_gen_mulu2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4908                                   s->T0, cpu_regs[R_EAX]);
4909                 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4910                 tcg_gen_mov_tl(cpu_cc_src, cpu_regs[R_EDX]);
4911                 set_cc_op(s, CC_OP_MULQ);
4912                 break;
4913 #endif
4914             }
4915             break;
4916         case 5: /* imul */
4917             switch(ot) {
4918             case MO_8:
4919                 gen_op_mov_v_reg(s, MO_8, s->T1, R_EAX);
4920                 tcg_gen_ext8s_tl(s->T0, s->T0);
4921                 tcg_gen_ext8s_tl(s->T1, s->T1);
4922                 /* XXX: use 32 bit mul which could be faster */
4923                 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
4924                 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
4925                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
4926                 tcg_gen_ext8s_tl(s->tmp0, s->T0);
4927                 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
4928                 set_cc_op(s, CC_OP_MULB);
4929                 break;
4930             case MO_16:
4931                 gen_op_mov_v_reg(s, MO_16, s->T1, R_EAX);
4932                 tcg_gen_ext16s_tl(s->T0, s->T0);
4933                 tcg_gen_ext16s_tl(s->T1, s->T1);
4934                 /* XXX: use 32 bit mul which could be faster */
4935                 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
4936                 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
4937                 tcg_gen_mov_tl(cpu_cc_dst, s->T0);
4938                 tcg_gen_ext16s_tl(s->tmp0, s->T0);
4939                 tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
4940                 tcg_gen_shri_tl(s->T0, s->T0, 16);
4941                 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
4942                 set_cc_op(s, CC_OP_MULW);
4943                 break;
4944             default:
4945             case MO_32:
4946                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
4947                 tcg_gen_trunc_tl_i32(s->tmp3_i32, cpu_regs[R_EAX]);
4948                 tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32,
4949                                   s->tmp2_i32, s->tmp3_i32);
4950                 tcg_gen_extu_i32_tl(cpu_regs[R_EAX], s->tmp2_i32);
4951                 tcg_gen_extu_i32_tl(cpu_regs[R_EDX], s->tmp3_i32);
4952                 tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31);
4953                 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4954                 tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
4955                 tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32);
4956                 set_cc_op(s, CC_OP_MULL);
4957                 break;
4958 #ifdef TARGET_X86_64
4959             case MO_64:
4960                 tcg_gen_muls2_i64(cpu_regs[R_EAX], cpu_regs[R_EDX],
4961                                   s->T0, cpu_regs[R_EAX]);
4962                 tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[R_EAX]);
4963                 tcg_gen_sari_tl(cpu_cc_src, cpu_regs[R_EAX], 63);
4964                 tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, cpu_regs[R_EDX]);
4965                 set_cc_op(s, CC_OP_MULQ);
4966                 break;
4967 #endif
4968             }
4969             break;
4970         case 6: /* div */
4971             switch(ot) {
4972             case MO_8:
4973                 gen_helper_divb_AL(cpu_env, s->T0);
4974                 break;
4975             case MO_16:
4976                 gen_helper_divw_AX(cpu_env, s->T0);
4977                 break;
4978             default:
4979             case MO_32:
4980                 gen_helper_divl_EAX(cpu_env, s->T0);
4981                 break;
4982 #ifdef TARGET_X86_64
4983             case MO_64:
4984                 gen_helper_divq_EAX(cpu_env, s->T0);
4985                 break;
4986 #endif
4987             }
4988             break;
4989         case 7: /* idiv */
4990             switch(ot) {
4991             case MO_8:
4992                 gen_helper_idivb_AL(cpu_env, s->T0);
4993                 break;
4994             case MO_16:
4995                 gen_helper_idivw_AX(cpu_env, s->T0);
4996                 break;
4997             default:
4998             case MO_32:
4999                 gen_helper_idivl_EAX(cpu_env, s->T0);
5000                 break;
5001 #ifdef TARGET_X86_64
5002             case MO_64:
5003                 gen_helper_idivq_EAX(cpu_env, s->T0);
5004                 break;
5005 #endif
5006             }
5007             break;
5008         default:
5009             goto unknown_op;
5010         }
5011         break;
5012 
5013     case 0xfe: /* GRP4 */
5014     case 0xff: /* GRP5 */
5015         ot = mo_b_d(b, dflag);
5016 
5017         modrm = x86_ldub_code(env, s);
5018         mod = (modrm >> 6) & 3;
5019         rm = (modrm & 7) | REX_B(s);
5020         op = (modrm >> 3) & 7;
5021         if (op >= 2 && b == 0xfe) {
5022             goto unknown_op;
5023         }
5024         if (CODE64(s)) {
5025             if (op == 2 || op == 4) {
5026                 /* operand size for jumps is 64 bit */
5027                 ot = MO_64;
5028             } else if (op == 3 || op == 5) {
5029                 ot = dflag != MO_16 ? MO_32 + (rex_w == 1) : MO_16;
5030             } else if (op == 6) {
5031                 /* default push size is 64 bit */
5032                 ot = mo_pushpop(s, dflag);
5033             }
5034         }
5035         if (mod != 3) {
5036             gen_lea_modrm(env, s, modrm);
5037             if (op >= 2 && op != 3 && op != 5)
5038                 gen_op_ld_v(s, ot, s->T0, s->A0);
5039         } else {
5040             gen_op_mov_v_reg(s, ot, s->T0, rm);
5041         }
5042 
5043         switch(op) {
5044         case 0: /* inc Ev */
5045             if (mod != 3)
5046                 opreg = OR_TMP0;
5047             else
5048                 opreg = rm;
5049             gen_inc(s, ot, opreg, 1);
5050             break;
5051         case 1: /* dec Ev */
5052             if (mod != 3)
5053                 opreg = OR_TMP0;
5054             else
5055                 opreg = rm;
5056             gen_inc(s, ot, opreg, -1);
5057             break;
5058         case 2: /* call Ev */
5059             /* XXX: optimize if memory (no 'and' is necessary) */
5060             if (dflag == MO_16) {
5061                 tcg_gen_ext16u_tl(s->T0, s->T0);
5062             }
5063             next_eip = s->pc - s->cs_base;
5064             tcg_gen_movi_tl(s->T1, next_eip);
5065             gen_push_v(s, s->T1);
5066             gen_op_jmp_v(s->T0);
5067             gen_bnd_jmp(s);
5068             gen_jr(s, s->T0);
5069             break;
5070         case 3: /* lcall Ev */
5071             gen_op_ld_v(s, ot, s->T1, s->A0);
5072             gen_add_A0_im(s, 1 << ot);
5073             gen_op_ld_v(s, MO_16, s->T0, s->A0);
5074         do_lcall:
5075             if (s->pe && !s->vm86) {
5076                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5077                 gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1,
5078                                            tcg_const_i32(dflag - 1),
5079                                            tcg_const_tl(s->pc - s->cs_base));
5080             } else {
5081                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5082                 gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->T1,
5083                                       tcg_const_i32(dflag - 1),
5084                                       tcg_const_i32(s->pc - s->cs_base));
5085             }
5086             tcg_gen_ld_tl(s->tmp4, cpu_env, offsetof(CPUX86State, eip));
5087             gen_jr(s, s->tmp4);
5088             break;
5089         case 4: /* jmp Ev */
5090             if (dflag == MO_16) {
5091                 tcg_gen_ext16u_tl(s->T0, s->T0);
5092             }
5093             gen_op_jmp_v(s->T0);
5094             gen_bnd_jmp(s);
5095             gen_jr(s, s->T0);
5096             break;
5097         case 5: /* ljmp Ev */
5098             gen_op_ld_v(s, ot, s->T1, s->A0);
5099             gen_add_A0_im(s, 1 << ot);
5100             gen_op_ld_v(s, MO_16, s->T0, s->A0);
5101         do_ljmp:
5102             if (s->pe && !s->vm86) {
5103                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5104                 gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1,
5105                                           tcg_const_tl(s->pc - s->cs_base));
5106             } else {
5107                 gen_op_movl_seg_T0_vm(s, R_CS);
5108                 gen_op_jmp_v(s->T1);
5109             }
5110             tcg_gen_ld_tl(s->tmp4, cpu_env, offsetof(CPUX86State, eip));
5111             gen_jr(s, s->tmp4);
5112             break;
5113         case 6: /* push Ev */
5114             gen_push_v(s, s->T0);
5115             break;
5116         default:
5117             goto unknown_op;
5118         }
5119         break;
5120 
5121     case 0x84: /* test Ev, Gv */
5122     case 0x85:
5123         ot = mo_b_d(b, dflag);
5124 
5125         modrm = x86_ldub_code(env, s);
5126         reg = ((modrm >> 3) & 7) | rex_r;
5127 
5128         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5129         gen_op_mov_v_reg(s, ot, s->T1, reg);
5130         gen_op_testl_T0_T1_cc(s);
5131         set_cc_op(s, CC_OP_LOGICB + ot);
5132         break;
5133 
5134     case 0xa8: /* test eAX, Iv */
5135     case 0xa9:
5136         ot = mo_b_d(b, dflag);
5137         val = insn_get(env, s, ot);
5138 
5139         gen_op_mov_v_reg(s, ot, s->T0, OR_EAX);
5140         tcg_gen_movi_tl(s->T1, val);
5141         gen_op_testl_T0_T1_cc(s);
5142         set_cc_op(s, CC_OP_LOGICB + ot);
5143         break;
5144 
5145     case 0x98: /* CWDE/CBW */
5146         switch (dflag) {
5147 #ifdef TARGET_X86_64
5148         case MO_64:
5149             gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
5150             tcg_gen_ext32s_tl(s->T0, s->T0);
5151             gen_op_mov_reg_v(s, MO_64, R_EAX, s->T0);
5152             break;
5153 #endif
5154         case MO_32:
5155             gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX);
5156             tcg_gen_ext16s_tl(s->T0, s->T0);
5157             gen_op_mov_reg_v(s, MO_32, R_EAX, s->T0);
5158             break;
5159         case MO_16:
5160             gen_op_mov_v_reg(s, MO_8, s->T0, R_EAX);
5161             tcg_gen_ext8s_tl(s->T0, s->T0);
5162             gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
5163             break;
5164         default:
5165             tcg_abort();
5166         }
5167         break;
5168     case 0x99: /* CDQ/CWD */
5169         switch (dflag) {
5170 #ifdef TARGET_X86_64
5171         case MO_64:
5172             gen_op_mov_v_reg(s, MO_64, s->T0, R_EAX);
5173             tcg_gen_sari_tl(s->T0, s->T0, 63);
5174             gen_op_mov_reg_v(s, MO_64, R_EDX, s->T0);
5175             break;
5176 #endif
5177         case MO_32:
5178             gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
5179             tcg_gen_ext32s_tl(s->T0, s->T0);
5180             tcg_gen_sari_tl(s->T0, s->T0, 31);
5181             gen_op_mov_reg_v(s, MO_32, R_EDX, s->T0);
5182             break;
5183         case MO_16:
5184             gen_op_mov_v_reg(s, MO_16, s->T0, R_EAX);
5185             tcg_gen_ext16s_tl(s->T0, s->T0);
5186             tcg_gen_sari_tl(s->T0, s->T0, 15);
5187             gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0);
5188             break;
5189         default:
5190             tcg_abort();
5191         }
5192         break;
5193     case 0x1af: /* imul Gv, Ev */
5194     case 0x69: /* imul Gv, Ev, I */
5195     case 0x6b:
5196         ot = dflag;
5197         modrm = x86_ldub_code(env, s);
5198         reg = ((modrm >> 3) & 7) | rex_r;
5199         if (b == 0x69)
5200             s->rip_offset = insn_const_size(ot);
5201         else if (b == 0x6b)
5202             s->rip_offset = 1;
5203         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5204         if (b == 0x69) {
5205             val = insn_get(env, s, ot);
5206             tcg_gen_movi_tl(s->T1, val);
5207         } else if (b == 0x6b) {
5208             val = (int8_t)insn_get(env, s, MO_8);
5209             tcg_gen_movi_tl(s->T1, val);
5210         } else {
5211             gen_op_mov_v_reg(s, ot, s->T1, reg);
5212         }
5213         switch (ot) {
5214 #ifdef TARGET_X86_64
5215         case MO_64:
5216             tcg_gen_muls2_i64(cpu_regs[reg], s->T1, s->T0, s->T1);
5217             tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5218             tcg_gen_sari_tl(cpu_cc_src, cpu_cc_dst, 63);
5219             tcg_gen_sub_tl(cpu_cc_src, cpu_cc_src, s->T1);
5220             break;
5221 #endif
5222         case MO_32:
5223             tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
5224             tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
5225             tcg_gen_muls2_i32(s->tmp2_i32, s->tmp3_i32,
5226                               s->tmp2_i32, s->tmp3_i32);
5227             tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
5228             tcg_gen_sari_i32(s->tmp2_i32, s->tmp2_i32, 31);
5229             tcg_gen_mov_tl(cpu_cc_dst, cpu_regs[reg]);
5230             tcg_gen_sub_i32(s->tmp2_i32, s->tmp2_i32, s->tmp3_i32);
5231             tcg_gen_extu_i32_tl(cpu_cc_src, s->tmp2_i32);
5232             break;
5233         default:
5234             tcg_gen_ext16s_tl(s->T0, s->T0);
5235             tcg_gen_ext16s_tl(s->T1, s->T1);
5236             /* XXX: use 32 bit mul which could be faster */
5237             tcg_gen_mul_tl(s->T0, s->T0, s->T1);
5238             tcg_gen_mov_tl(cpu_cc_dst, s->T0);
5239             tcg_gen_ext16s_tl(s->tmp0, s->T0);
5240             tcg_gen_sub_tl(cpu_cc_src, s->T0, s->tmp0);
5241             gen_op_mov_reg_v(s, ot, reg, s->T0);
5242             break;
5243         }
5244         set_cc_op(s, CC_OP_MULB + ot);
5245         break;
5246     case 0x1c0:
5247     case 0x1c1: /* xadd Ev, Gv */
5248         ot = mo_b_d(b, dflag);
5249         modrm = x86_ldub_code(env, s);
5250         reg = ((modrm >> 3) & 7) | rex_r;
5251         mod = (modrm >> 6) & 3;
5252         gen_op_mov_v_reg(s, ot, s->T0, reg);
5253         if (mod == 3) {
5254             rm = (modrm & 7) | REX_B(s);
5255             gen_op_mov_v_reg(s, ot, s->T1, rm);
5256             tcg_gen_add_tl(s->T0, s->T0, s->T1);
5257             gen_op_mov_reg_v(s, ot, reg, s->T1);
5258             gen_op_mov_reg_v(s, ot, rm, s->T0);
5259         } else {
5260             gen_lea_modrm(env, s, modrm);
5261             if (s->prefix & PREFIX_LOCK) {
5262                 tcg_gen_atomic_fetch_add_tl(s->T1, s->A0, s->T0,
5263                                             s->mem_index, ot | MO_LE);
5264                 tcg_gen_add_tl(s->T0, s->T0, s->T1);
5265             } else {
5266                 gen_op_ld_v(s, ot, s->T1, s->A0);
5267                 tcg_gen_add_tl(s->T0, s->T0, s->T1);
5268                 gen_op_st_v(s, ot, s->T0, s->A0);
5269             }
5270             gen_op_mov_reg_v(s, ot, reg, s->T1);
5271         }
5272         gen_op_update2_cc(s);
5273         set_cc_op(s, CC_OP_ADDB + ot);
5274         break;
5275     case 0x1b0:
5276     case 0x1b1: /* cmpxchg Ev, Gv */
5277         {
5278             TCGv oldv, newv, cmpv;
5279 
5280             ot = mo_b_d(b, dflag);
5281             modrm = x86_ldub_code(env, s);
5282             reg = ((modrm >> 3) & 7) | rex_r;
5283             mod = (modrm >> 6) & 3;
5284             oldv = tcg_temp_new();
5285             newv = tcg_temp_new();
5286             cmpv = tcg_temp_new();
5287             gen_op_mov_v_reg(s, ot, newv, reg);
5288             tcg_gen_mov_tl(cmpv, cpu_regs[R_EAX]);
5289 
5290             if (s->prefix & PREFIX_LOCK) {
5291                 if (mod == 3) {
5292                     goto illegal_op;
5293                 }
5294                 gen_lea_modrm(env, s, modrm);
5295                 tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, cmpv, newv,
5296                                           s->mem_index, ot | MO_LE);
5297                 gen_op_mov_reg_v(s, ot, R_EAX, oldv);
5298             } else {
5299                 if (mod == 3) {
5300                     rm = (modrm & 7) | REX_B(s);
5301                     gen_op_mov_v_reg(s, ot, oldv, rm);
5302                 } else {
5303                     gen_lea_modrm(env, s, modrm);
5304                     gen_op_ld_v(s, ot, oldv, s->A0);
5305                     rm = 0; /* avoid warning */
5306                 }
5307                 gen_extu(ot, oldv);
5308                 gen_extu(ot, cmpv);
5309                 /* store value = (old == cmp ? new : old);  */
5310                 tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv);
5311                 if (mod == 3) {
5312                     gen_op_mov_reg_v(s, ot, R_EAX, oldv);
5313                     gen_op_mov_reg_v(s, ot, rm, newv);
5314                 } else {
5315                     /* Perform an unconditional store cycle like physical cpu;
5316                        must be before changing accumulator to ensure
5317                        idempotency if the store faults and the instruction
5318                        is restarted */
5319                     gen_op_st_v(s, ot, newv, s->A0);
5320                     gen_op_mov_reg_v(s, ot, R_EAX, oldv);
5321                 }
5322             }
5323             tcg_gen_mov_tl(cpu_cc_src, oldv);
5324             tcg_gen_mov_tl(s->cc_srcT, cmpv);
5325             tcg_gen_sub_tl(cpu_cc_dst, cmpv, oldv);
5326             set_cc_op(s, CC_OP_SUBB + ot);
5327             tcg_temp_free(oldv);
5328             tcg_temp_free(newv);
5329             tcg_temp_free(cmpv);
5330         }
5331         break;
5332     case 0x1c7: /* cmpxchg8b */
5333         modrm = x86_ldub_code(env, s);
5334         mod = (modrm >> 6) & 3;
5335         switch ((modrm >> 3) & 7) {
5336         case 1: /* CMPXCHG8, CMPXCHG16 */
5337             if (mod == 3) {
5338                 goto illegal_op;
5339             }
5340 #ifdef TARGET_X86_64
5341             if (dflag == MO_64) {
5342                 if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) {
5343                     goto illegal_op;
5344                 }
5345                 gen_lea_modrm(env, s, modrm);
5346                 if ((s->prefix & PREFIX_LOCK) &&
5347                     (tb_cflags(s->base.tb) & CF_PARALLEL)) {
5348                     gen_helper_cmpxchg16b(cpu_env, s->A0);
5349                 } else {
5350                     gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0);
5351                 }
5352                 set_cc_op(s, CC_OP_EFLAGS);
5353                 break;
5354             }
5355 #endif
5356             if (!(s->cpuid_features & CPUID_CX8)) {
5357                 goto illegal_op;
5358             }
5359             gen_lea_modrm(env, s, modrm);
5360             if ((s->prefix & PREFIX_LOCK) &&
5361                 (tb_cflags(s->base.tb) & CF_PARALLEL)) {
5362                 gen_helper_cmpxchg8b(cpu_env, s->A0);
5363             } else {
5364                 gen_helper_cmpxchg8b_unlocked(cpu_env, s->A0);
5365             }
5366             set_cc_op(s, CC_OP_EFLAGS);
5367             break;
5368 
5369         case 7: /* RDSEED */
5370         case 6: /* RDRAND */
5371             if (mod != 3 ||
5372                 (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) ||
5373                 !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) {
5374                 goto illegal_op;
5375             }
5376             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
5377                 gen_io_start();
5378             }
5379             gen_helper_rdrand(s->T0, cpu_env);
5380             rm = (modrm & 7) | REX_B(s);
5381             gen_op_mov_reg_v(s, dflag, rm, s->T0);
5382             set_cc_op(s, CC_OP_EFLAGS);
5383             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
5384                 gen_jmp(s, s->pc - s->cs_base);
5385             }
5386             break;
5387 
5388         default:
5389             goto illegal_op;
5390         }
5391         break;
5392 
5393         /**************************/
5394         /* push/pop */
5395     case 0x50 ... 0x57: /* push */
5396         gen_op_mov_v_reg(s, MO_32, s->T0, (b & 7) | REX_B(s));
5397         gen_push_v(s, s->T0);
5398         break;
5399     case 0x58 ... 0x5f: /* pop */
5400         ot = gen_pop_T0(s);
5401         /* NOTE: order is important for pop %sp */
5402         gen_pop_update(s, ot);
5403         gen_op_mov_reg_v(s, ot, (b & 7) | REX_B(s), s->T0);
5404         break;
5405     case 0x60: /* pusha */
5406         if (CODE64(s))
5407             goto illegal_op;
5408         gen_pusha(s);
5409         break;
5410     case 0x61: /* popa */
5411         if (CODE64(s))
5412             goto illegal_op;
5413         gen_popa(s);
5414         break;
5415     case 0x68: /* push Iv */
5416     case 0x6a:
5417         ot = mo_pushpop(s, dflag);
5418         if (b == 0x68)
5419             val = insn_get(env, s, ot);
5420         else
5421             val = (int8_t)insn_get(env, s, MO_8);
5422         tcg_gen_movi_tl(s->T0, val);
5423         gen_push_v(s, s->T0);
5424         break;
5425     case 0x8f: /* pop Ev */
5426         modrm = x86_ldub_code(env, s);
5427         mod = (modrm >> 6) & 3;
5428         ot = gen_pop_T0(s);
5429         if (mod == 3) {
5430             /* NOTE: order is important for pop %sp */
5431             gen_pop_update(s, ot);
5432             rm = (modrm & 7) | REX_B(s);
5433             gen_op_mov_reg_v(s, ot, rm, s->T0);
5434         } else {
5435             /* NOTE: order is important too for MMU exceptions */
5436             s->popl_esp_hack = 1 << ot;
5437             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5438             s->popl_esp_hack = 0;
5439             gen_pop_update(s, ot);
5440         }
5441         break;
5442     case 0xc8: /* enter */
5443         {
5444             int level;
5445             val = x86_lduw_code(env, s);
5446             level = x86_ldub_code(env, s);
5447             gen_enter(s, val, level);
5448         }
5449         break;
5450     case 0xc9: /* leave */
5451         gen_leave(s);
5452         break;
5453     case 0x06: /* push es */
5454     case 0x0e: /* push cs */
5455     case 0x16: /* push ss */
5456     case 0x1e: /* push ds */
5457         if (CODE64(s))
5458             goto illegal_op;
5459         gen_op_movl_T0_seg(s, b >> 3);
5460         gen_push_v(s, s->T0);
5461         break;
5462     case 0x1a0: /* push fs */
5463     case 0x1a8: /* push gs */
5464         gen_op_movl_T0_seg(s, (b >> 3) & 7);
5465         gen_push_v(s, s->T0);
5466         break;
5467     case 0x07: /* pop es */
5468     case 0x17: /* pop ss */
5469     case 0x1f: /* pop ds */
5470         if (CODE64(s))
5471             goto illegal_op;
5472         reg = b >> 3;
5473         ot = gen_pop_T0(s);
5474         gen_movl_seg_T0(s, reg);
5475         gen_pop_update(s, ot);
5476         /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp.  */
5477         if (s->base.is_jmp) {
5478             gen_jmp_im(s, s->pc - s->cs_base);
5479             if (reg == R_SS) {
5480                 s->tf = 0;
5481                 gen_eob_inhibit_irq(s, true);
5482             } else {
5483                 gen_eob(s);
5484             }
5485         }
5486         break;
5487     case 0x1a1: /* pop fs */
5488     case 0x1a9: /* pop gs */
5489         ot = gen_pop_T0(s);
5490         gen_movl_seg_T0(s, (b >> 3) & 7);
5491         gen_pop_update(s, ot);
5492         if (s->base.is_jmp) {
5493             gen_jmp_im(s, s->pc - s->cs_base);
5494             gen_eob(s);
5495         }
5496         break;
5497 
5498         /**************************/
5499         /* mov */
5500     case 0x88:
5501     case 0x89: /* mov Gv, Ev */
5502         ot = mo_b_d(b, dflag);
5503         modrm = x86_ldub_code(env, s);
5504         reg = ((modrm >> 3) & 7) | rex_r;
5505 
5506         /* generate a generic store */
5507         gen_ldst_modrm(env, s, modrm, ot, reg, 1);
5508         break;
5509     case 0xc6:
5510     case 0xc7: /* mov Ev, Iv */
5511         ot = mo_b_d(b, dflag);
5512         modrm = x86_ldub_code(env, s);
5513         mod = (modrm >> 6) & 3;
5514         if (mod != 3) {
5515             s->rip_offset = insn_const_size(ot);
5516             gen_lea_modrm(env, s, modrm);
5517         }
5518         val = insn_get(env, s, ot);
5519         tcg_gen_movi_tl(s->T0, val);
5520         if (mod != 3) {
5521             gen_op_st_v(s, ot, s->T0, s->A0);
5522         } else {
5523             gen_op_mov_reg_v(s, ot, (modrm & 7) | REX_B(s), s->T0);
5524         }
5525         break;
5526     case 0x8a:
5527     case 0x8b: /* mov Ev, Gv */
5528         ot = mo_b_d(b, dflag);
5529         modrm = x86_ldub_code(env, s);
5530         reg = ((modrm >> 3) & 7) | rex_r;
5531 
5532         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
5533         gen_op_mov_reg_v(s, ot, reg, s->T0);
5534         break;
5535     case 0x8e: /* mov seg, Gv */
5536         modrm = x86_ldub_code(env, s);
5537         reg = (modrm >> 3) & 7;
5538         if (reg >= 6 || reg == R_CS)
5539             goto illegal_op;
5540         gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
5541         gen_movl_seg_T0(s, reg);
5542         /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp.  */
5543         if (s->base.is_jmp) {
5544             gen_jmp_im(s, s->pc - s->cs_base);
5545             if (reg == R_SS) {
5546                 s->tf = 0;
5547                 gen_eob_inhibit_irq(s, true);
5548             } else {
5549                 gen_eob(s);
5550             }
5551         }
5552         break;
5553     case 0x8c: /* mov Gv, seg */
5554         modrm = x86_ldub_code(env, s);
5555         reg = (modrm >> 3) & 7;
5556         mod = (modrm >> 6) & 3;
5557         if (reg >= 6)
5558             goto illegal_op;
5559         gen_op_movl_T0_seg(s, reg);
5560         ot = mod == 3 ? dflag : MO_16;
5561         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
5562         break;
5563 
5564     case 0x1b6: /* movzbS Gv, Eb */
5565     case 0x1b7: /* movzwS Gv, Eb */
5566     case 0x1be: /* movsbS Gv, Eb */
5567     case 0x1bf: /* movswS Gv, Eb */
5568         {
5569             MemOp d_ot;
5570             MemOp s_ot;
5571 
5572             /* d_ot is the size of destination */
5573             d_ot = dflag;
5574             /* ot is the size of source */
5575             ot = (b & 1) + MO_8;
5576             /* s_ot is the sign+size of source */
5577             s_ot = b & 8 ? MO_SIGN | ot : ot;
5578 
5579             modrm = x86_ldub_code(env, s);
5580             reg = ((modrm >> 3) & 7) | rex_r;
5581             mod = (modrm >> 6) & 3;
5582             rm = (modrm & 7) | REX_B(s);
5583 
5584             if (mod == 3) {
5585                 if (s_ot == MO_SB && byte_reg_is_xH(s, rm)) {
5586                     tcg_gen_sextract_tl(s->T0, cpu_regs[rm - 4], 8, 8);
5587                 } else {
5588                     gen_op_mov_v_reg(s, ot, s->T0, rm);
5589                     switch (s_ot) {
5590                     case MO_UB:
5591                         tcg_gen_ext8u_tl(s->T0, s->T0);
5592                         break;
5593                     case MO_SB:
5594                         tcg_gen_ext8s_tl(s->T0, s->T0);
5595                         break;
5596                     case MO_UW:
5597                         tcg_gen_ext16u_tl(s->T0, s->T0);
5598                         break;
5599                     default:
5600                     case MO_SW:
5601                         tcg_gen_ext16s_tl(s->T0, s->T0);
5602                         break;
5603                     }
5604                 }
5605                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
5606             } else {
5607                 gen_lea_modrm(env, s, modrm);
5608                 gen_op_ld_v(s, s_ot, s->T0, s->A0);
5609                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
5610             }
5611         }
5612         break;
5613 
5614     case 0x8d: /* lea */
5615         modrm = x86_ldub_code(env, s);
5616         mod = (modrm >> 6) & 3;
5617         if (mod == 3)
5618             goto illegal_op;
5619         reg = ((modrm >> 3) & 7) | rex_r;
5620         {
5621             AddressParts a = gen_lea_modrm_0(env, s, modrm);
5622             TCGv ea = gen_lea_modrm_1(s, a);
5623             gen_lea_v_seg(s, s->aflag, ea, -1, -1);
5624             gen_op_mov_reg_v(s, dflag, reg, s->A0);
5625         }
5626         break;
5627 
5628     case 0xa0: /* mov EAX, Ov */
5629     case 0xa1:
5630     case 0xa2: /* mov Ov, EAX */
5631     case 0xa3:
5632         {
5633             target_ulong offset_addr;
5634 
5635             ot = mo_b_d(b, dflag);
5636             switch (s->aflag) {
5637 #ifdef TARGET_X86_64
5638             case MO_64:
5639                 offset_addr = x86_ldq_code(env, s);
5640                 break;
5641 #endif
5642             default:
5643                 offset_addr = insn_get(env, s, s->aflag);
5644                 break;
5645             }
5646             tcg_gen_movi_tl(s->A0, offset_addr);
5647             gen_add_A0_ds_seg(s);
5648             if ((b & 2) == 0) {
5649                 gen_op_ld_v(s, ot, s->T0, s->A0);
5650                 gen_op_mov_reg_v(s, ot, R_EAX, s->T0);
5651             } else {
5652                 gen_op_mov_v_reg(s, ot, s->T0, R_EAX);
5653                 gen_op_st_v(s, ot, s->T0, s->A0);
5654             }
5655         }
5656         break;
5657     case 0xd7: /* xlat */
5658         tcg_gen_mov_tl(s->A0, cpu_regs[R_EBX]);
5659         tcg_gen_ext8u_tl(s->T0, cpu_regs[R_EAX]);
5660         tcg_gen_add_tl(s->A0, s->A0, s->T0);
5661         gen_extu(s->aflag, s->A0);
5662         gen_add_A0_ds_seg(s);
5663         gen_op_ld_v(s, MO_8, s->T0, s->A0);
5664         gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0);
5665         break;
5666     case 0xb0 ... 0xb7: /* mov R, Ib */
5667         val = insn_get(env, s, MO_8);
5668         tcg_gen_movi_tl(s->T0, val);
5669         gen_op_mov_reg_v(s, MO_8, (b & 7) | REX_B(s), s->T0);
5670         break;
5671     case 0xb8 ... 0xbf: /* mov R, Iv */
5672 #ifdef TARGET_X86_64
5673         if (dflag == MO_64) {
5674             uint64_t tmp;
5675             /* 64 bit case */
5676             tmp = x86_ldq_code(env, s);
5677             reg = (b & 7) | REX_B(s);
5678             tcg_gen_movi_tl(s->T0, tmp);
5679             gen_op_mov_reg_v(s, MO_64, reg, s->T0);
5680         } else
5681 #endif
5682         {
5683             ot = dflag;
5684             val = insn_get(env, s, ot);
5685             reg = (b & 7) | REX_B(s);
5686             tcg_gen_movi_tl(s->T0, val);
5687             gen_op_mov_reg_v(s, ot, reg, s->T0);
5688         }
5689         break;
5690 
5691     case 0x91 ... 0x97: /* xchg R, EAX */
5692     do_xchg_reg_eax:
5693         ot = dflag;
5694         reg = (b & 7) | REX_B(s);
5695         rm = R_EAX;
5696         goto do_xchg_reg;
5697     case 0x86:
5698     case 0x87: /* xchg Ev, Gv */
5699         ot = mo_b_d(b, dflag);
5700         modrm = x86_ldub_code(env, s);
5701         reg = ((modrm >> 3) & 7) | rex_r;
5702         mod = (modrm >> 6) & 3;
5703         if (mod == 3) {
5704             rm = (modrm & 7) | REX_B(s);
5705         do_xchg_reg:
5706             gen_op_mov_v_reg(s, ot, s->T0, reg);
5707             gen_op_mov_v_reg(s, ot, s->T1, rm);
5708             gen_op_mov_reg_v(s, ot, rm, s->T0);
5709             gen_op_mov_reg_v(s, ot, reg, s->T1);
5710         } else {
5711             gen_lea_modrm(env, s, modrm);
5712             gen_op_mov_v_reg(s, ot, s->T0, reg);
5713             /* for xchg, lock is implicit */
5714             tcg_gen_atomic_xchg_tl(s->T1, s->A0, s->T0,
5715                                    s->mem_index, ot | MO_LE);
5716             gen_op_mov_reg_v(s, ot, reg, s->T1);
5717         }
5718         break;
5719     case 0xc4: /* les Gv */
5720         /* In CODE64 this is VEX3; see above.  */
5721         op = R_ES;
5722         goto do_lxx;
5723     case 0xc5: /* lds Gv */
5724         /* In CODE64 this is VEX2; see above.  */
5725         op = R_DS;
5726         goto do_lxx;
5727     case 0x1b2: /* lss Gv */
5728         op = R_SS;
5729         goto do_lxx;
5730     case 0x1b4: /* lfs Gv */
5731         op = R_FS;
5732         goto do_lxx;
5733     case 0x1b5: /* lgs Gv */
5734         op = R_GS;
5735     do_lxx:
5736         ot = dflag != MO_16 ? MO_32 : MO_16;
5737         modrm = x86_ldub_code(env, s);
5738         reg = ((modrm >> 3) & 7) | rex_r;
5739         mod = (modrm >> 6) & 3;
5740         if (mod == 3)
5741             goto illegal_op;
5742         gen_lea_modrm(env, s, modrm);
5743         gen_op_ld_v(s, ot, s->T1, s->A0);
5744         gen_add_A0_im(s, 1 << ot);
5745         /* load the segment first to handle exceptions properly */
5746         gen_op_ld_v(s, MO_16, s->T0, s->A0);
5747         gen_movl_seg_T0(s, op);
5748         /* then put the data */
5749         gen_op_mov_reg_v(s, ot, reg, s->T1);
5750         if (s->base.is_jmp) {
5751             gen_jmp_im(s, s->pc - s->cs_base);
5752             gen_eob(s);
5753         }
5754         break;
5755 
5756         /************************/
5757         /* shifts */
5758     case 0xc0:
5759     case 0xc1:
5760         /* shift Ev,Ib */
5761         shift = 2;
5762     grp2:
5763         {
5764             ot = mo_b_d(b, dflag);
5765             modrm = x86_ldub_code(env, s);
5766             mod = (modrm >> 6) & 3;
5767             op = (modrm >> 3) & 7;
5768 
5769             if (mod != 3) {
5770                 if (shift == 2) {
5771                     s->rip_offset = 1;
5772                 }
5773                 gen_lea_modrm(env, s, modrm);
5774                 opreg = OR_TMP0;
5775             } else {
5776                 opreg = (modrm & 7) | REX_B(s);
5777             }
5778 
5779             /* simpler op */
5780             if (shift == 0) {
5781                 gen_shift(s, op, ot, opreg, OR_ECX);
5782             } else {
5783                 if (shift == 2) {
5784                     shift = x86_ldub_code(env, s);
5785                 }
5786                 gen_shifti(s, op, ot, opreg, shift);
5787             }
5788         }
5789         break;
5790     case 0xd0:
5791     case 0xd1:
5792         /* shift Ev,1 */
5793         shift = 1;
5794         goto grp2;
5795     case 0xd2:
5796     case 0xd3:
5797         /* shift Ev,cl */
5798         shift = 0;
5799         goto grp2;
5800 
5801     case 0x1a4: /* shld imm */
5802         op = 0;
5803         shift = 1;
5804         goto do_shiftd;
5805     case 0x1a5: /* shld cl */
5806         op = 0;
5807         shift = 0;
5808         goto do_shiftd;
5809     case 0x1ac: /* shrd imm */
5810         op = 1;
5811         shift = 1;
5812         goto do_shiftd;
5813     case 0x1ad: /* shrd cl */
5814         op = 1;
5815         shift = 0;
5816     do_shiftd:
5817         ot = dflag;
5818         modrm = x86_ldub_code(env, s);
5819         mod = (modrm >> 6) & 3;
5820         rm = (modrm & 7) | REX_B(s);
5821         reg = ((modrm >> 3) & 7) | rex_r;
5822         if (mod != 3) {
5823             gen_lea_modrm(env, s, modrm);
5824             opreg = OR_TMP0;
5825         } else {
5826             opreg = rm;
5827         }
5828         gen_op_mov_v_reg(s, ot, s->T1, reg);
5829 
5830         if (shift) {
5831             TCGv imm = tcg_const_tl(x86_ldub_code(env, s));
5832             gen_shiftd_rm_T1(s, ot, opreg, op, imm);
5833             tcg_temp_free(imm);
5834         } else {
5835             gen_shiftd_rm_T1(s, ot, opreg, op, cpu_regs[R_ECX]);
5836         }
5837         break;
5838 
5839         /************************/
5840         /* floats */
5841     case 0xd8 ... 0xdf:
5842         if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
5843             /* if CR0.EM or CR0.TS are set, generate an FPU exception */
5844             /* XXX: what to do if illegal op ? */
5845             gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5846             break;
5847         }
5848         modrm = x86_ldub_code(env, s);
5849         mod = (modrm >> 6) & 3;
5850         rm = modrm & 7;
5851         op = ((b & 7) << 3) | ((modrm >> 3) & 7);
5852         if (mod != 3) {
5853             /* memory op */
5854             gen_lea_modrm(env, s, modrm);
5855             switch(op) {
5856             case 0x00 ... 0x07: /* fxxxs */
5857             case 0x10 ... 0x17: /* fixxxl */
5858             case 0x20 ... 0x27: /* fxxxl */
5859             case 0x30 ... 0x37: /* fixxx */
5860                 {
5861                     int op1;
5862                     op1 = op & 7;
5863 
5864                     switch(op >> 4) {
5865                     case 0:
5866                         tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
5867                                             s->mem_index, MO_LEUL);
5868                         gen_helper_flds_FT0(cpu_env, s->tmp2_i32);
5869                         break;
5870                     case 1:
5871                         tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
5872                                             s->mem_index, MO_LEUL);
5873                         gen_helper_fildl_FT0(cpu_env, s->tmp2_i32);
5874                         break;
5875                     case 2:
5876                         tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
5877                                             s->mem_index, MO_LEQ);
5878                         gen_helper_fldl_FT0(cpu_env, s->tmp1_i64);
5879                         break;
5880                     case 3:
5881                     default:
5882                         tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
5883                                             s->mem_index, MO_LESW);
5884                         gen_helper_fildl_FT0(cpu_env, s->tmp2_i32);
5885                         break;
5886                     }
5887 
5888                     gen_helper_fp_arith_ST0_FT0(op1);
5889                     if (op1 == 3) {
5890                         /* fcomp needs pop */
5891                         gen_helper_fpop(cpu_env);
5892                     }
5893                 }
5894                 break;
5895             case 0x08: /* flds */
5896             case 0x0a: /* fsts */
5897             case 0x0b: /* fstps */
5898             case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
5899             case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
5900             case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
5901                 switch(op & 7) {
5902                 case 0:
5903                     switch(op >> 4) {
5904                     case 0:
5905                         tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
5906                                             s->mem_index, MO_LEUL);
5907                         gen_helper_flds_ST0(cpu_env, s->tmp2_i32);
5908                         break;
5909                     case 1:
5910                         tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
5911                                             s->mem_index, MO_LEUL);
5912                         gen_helper_fildl_ST0(cpu_env, s->tmp2_i32);
5913                         break;
5914                     case 2:
5915                         tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0,
5916                                             s->mem_index, MO_LEQ);
5917                         gen_helper_fldl_ST0(cpu_env, s->tmp1_i64);
5918                         break;
5919                     case 3:
5920                     default:
5921                         tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
5922                                             s->mem_index, MO_LESW);
5923                         gen_helper_fildl_ST0(cpu_env, s->tmp2_i32);
5924                         break;
5925                     }
5926                     break;
5927                 case 1:
5928                     /* XXX: the corresponding CPUID bit must be tested ! */
5929                     switch(op >> 4) {
5930                     case 1:
5931                         gen_helper_fisttl_ST0(s->tmp2_i32, cpu_env);
5932                         tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
5933                                             s->mem_index, MO_LEUL);
5934                         break;
5935                     case 2:
5936                         gen_helper_fisttll_ST0(s->tmp1_i64, cpu_env);
5937                         tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
5938                                             s->mem_index, MO_LEQ);
5939                         break;
5940                     case 3:
5941                     default:
5942                         gen_helper_fistt_ST0(s->tmp2_i32, cpu_env);
5943                         tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
5944                                             s->mem_index, MO_LEUW);
5945                         break;
5946                     }
5947                     gen_helper_fpop(cpu_env);
5948                     break;
5949                 default:
5950                     switch(op >> 4) {
5951                     case 0:
5952                         gen_helper_fsts_ST0(s->tmp2_i32, cpu_env);
5953                         tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
5954                                             s->mem_index, MO_LEUL);
5955                         break;
5956                     case 1:
5957                         gen_helper_fistl_ST0(s->tmp2_i32, cpu_env);
5958                         tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
5959                                             s->mem_index, MO_LEUL);
5960                         break;
5961                     case 2:
5962                         gen_helper_fstl_ST0(s->tmp1_i64, cpu_env);
5963                         tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0,
5964                                             s->mem_index, MO_LEQ);
5965                         break;
5966                     case 3:
5967                     default:
5968                         gen_helper_fist_ST0(s->tmp2_i32, cpu_env);
5969                         tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
5970                                             s->mem_index, MO_LEUW);
5971                         break;
5972                     }
5973                     if ((op & 7) == 3)
5974                         gen_helper_fpop(cpu_env);
5975                     break;
5976                 }
5977                 break;
5978             case 0x0c: /* fldenv mem */
5979                 gen_helper_fldenv(cpu_env, s->A0, tcg_const_i32(dflag - 1));
5980                 break;
5981             case 0x0d: /* fldcw mem */
5982                 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0,
5983                                     s->mem_index, MO_LEUW);
5984                 gen_helper_fldcw(cpu_env, s->tmp2_i32);
5985                 break;
5986             case 0x0e: /* fnstenv mem */
5987                 gen_helper_fstenv(cpu_env, s->A0, tcg_const_i32(dflag - 1));
5988                 break;
5989             case 0x0f: /* fnstcw mem */
5990                 gen_helper_fnstcw(s->tmp2_i32, cpu_env);
5991                 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
5992                                     s->mem_index, MO_LEUW);
5993                 break;
5994             case 0x1d: /* fldt mem */
5995                 gen_helper_fldt_ST0(cpu_env, s->A0);
5996                 break;
5997             case 0x1f: /* fstpt mem */
5998                 gen_helper_fstt_ST0(cpu_env, s->A0);
5999                 gen_helper_fpop(cpu_env);
6000                 break;
6001             case 0x2c: /* frstor mem */
6002                 gen_helper_frstor(cpu_env, s->A0, tcg_const_i32(dflag - 1));
6003                 break;
6004             case 0x2e: /* fnsave mem */
6005                 gen_helper_fsave(cpu_env, s->A0, tcg_const_i32(dflag - 1));
6006                 break;
6007             case 0x2f: /* fnstsw mem */
6008                 gen_helper_fnstsw(s->tmp2_i32, cpu_env);
6009                 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0,
6010                                     s->mem_index, MO_LEUW);
6011                 break;
6012             case 0x3c: /* fbld */
6013                 gen_helper_fbld_ST0(cpu_env, s->A0);
6014                 break;
6015             case 0x3e: /* fbstp */
6016                 gen_helper_fbst_ST0(cpu_env, s->A0);
6017                 gen_helper_fpop(cpu_env);
6018                 break;
6019             case 0x3d: /* fildll */
6020                 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEQ);
6021                 gen_helper_fildll_ST0(cpu_env, s->tmp1_i64);
6022                 break;
6023             case 0x3f: /* fistpll */
6024                 gen_helper_fistll_ST0(s->tmp1_i64, cpu_env);
6025                 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEQ);
6026                 gen_helper_fpop(cpu_env);
6027                 break;
6028             default:
6029                 goto unknown_op;
6030             }
6031         } else {
6032             /* register float ops */
6033             opreg = rm;
6034 
6035             switch(op) {
6036             case 0x08: /* fld sti */
6037                 gen_helper_fpush(cpu_env);
6038                 gen_helper_fmov_ST0_STN(cpu_env,
6039                                         tcg_const_i32((opreg + 1) & 7));
6040                 break;
6041             case 0x09: /* fxchg sti */
6042             case 0x29: /* fxchg4 sti, undocumented op */
6043             case 0x39: /* fxchg7 sti, undocumented op */
6044                 gen_helper_fxchg_ST0_STN(cpu_env, tcg_const_i32(opreg));
6045                 break;
6046             case 0x0a: /* grp d9/2 */
6047                 switch(rm) {
6048                 case 0: /* fnop */
6049                     /* check exceptions (FreeBSD FPU probe) */
6050                     gen_helper_fwait(cpu_env);
6051                     break;
6052                 default:
6053                     goto unknown_op;
6054                 }
6055                 break;
6056             case 0x0c: /* grp d9/4 */
6057                 switch(rm) {
6058                 case 0: /* fchs */
6059                     gen_helper_fchs_ST0(cpu_env);
6060                     break;
6061                 case 1: /* fabs */
6062                     gen_helper_fabs_ST0(cpu_env);
6063                     break;
6064                 case 4: /* ftst */
6065                     gen_helper_fldz_FT0(cpu_env);
6066                     gen_helper_fcom_ST0_FT0(cpu_env);
6067                     break;
6068                 case 5: /* fxam */
6069                     gen_helper_fxam_ST0(cpu_env);
6070                     break;
6071                 default:
6072                     goto unknown_op;
6073                 }
6074                 break;
6075             case 0x0d: /* grp d9/5 */
6076                 {
6077                     switch(rm) {
6078                     case 0:
6079                         gen_helper_fpush(cpu_env);
6080                         gen_helper_fld1_ST0(cpu_env);
6081                         break;
6082                     case 1:
6083                         gen_helper_fpush(cpu_env);
6084                         gen_helper_fldl2t_ST0(cpu_env);
6085                         break;
6086                     case 2:
6087                         gen_helper_fpush(cpu_env);
6088                         gen_helper_fldl2e_ST0(cpu_env);
6089                         break;
6090                     case 3:
6091                         gen_helper_fpush(cpu_env);
6092                         gen_helper_fldpi_ST0(cpu_env);
6093                         break;
6094                     case 4:
6095                         gen_helper_fpush(cpu_env);
6096                         gen_helper_fldlg2_ST0(cpu_env);
6097                         break;
6098                     case 5:
6099                         gen_helper_fpush(cpu_env);
6100                         gen_helper_fldln2_ST0(cpu_env);
6101                         break;
6102                     case 6:
6103                         gen_helper_fpush(cpu_env);
6104                         gen_helper_fldz_ST0(cpu_env);
6105                         break;
6106                     default:
6107                         goto unknown_op;
6108                     }
6109                 }
6110                 break;
6111             case 0x0e: /* grp d9/6 */
6112                 switch(rm) {
6113                 case 0: /* f2xm1 */
6114                     gen_helper_f2xm1(cpu_env);
6115                     break;
6116                 case 1: /* fyl2x */
6117                     gen_helper_fyl2x(cpu_env);
6118                     break;
6119                 case 2: /* fptan */
6120                     gen_helper_fptan(cpu_env);
6121                     break;
6122                 case 3: /* fpatan */
6123                     gen_helper_fpatan(cpu_env);
6124                     break;
6125                 case 4: /* fxtract */
6126                     gen_helper_fxtract(cpu_env);
6127                     break;
6128                 case 5: /* fprem1 */
6129                     gen_helper_fprem1(cpu_env);
6130                     break;
6131                 case 6: /* fdecstp */
6132                     gen_helper_fdecstp(cpu_env);
6133                     break;
6134                 default:
6135                 case 7: /* fincstp */
6136                     gen_helper_fincstp(cpu_env);
6137                     break;
6138                 }
6139                 break;
6140             case 0x0f: /* grp d9/7 */
6141                 switch(rm) {
6142                 case 0: /* fprem */
6143                     gen_helper_fprem(cpu_env);
6144                     break;
6145                 case 1: /* fyl2xp1 */
6146                     gen_helper_fyl2xp1(cpu_env);
6147                     break;
6148                 case 2: /* fsqrt */
6149                     gen_helper_fsqrt(cpu_env);
6150                     break;
6151                 case 3: /* fsincos */
6152                     gen_helper_fsincos(cpu_env);
6153                     break;
6154                 case 5: /* fscale */
6155                     gen_helper_fscale(cpu_env);
6156                     break;
6157                 case 4: /* frndint */
6158                     gen_helper_frndint(cpu_env);
6159                     break;
6160                 case 6: /* fsin */
6161                     gen_helper_fsin(cpu_env);
6162                     break;
6163                 default:
6164                 case 7: /* fcos */
6165                     gen_helper_fcos(cpu_env);
6166                     break;
6167                 }
6168                 break;
6169             case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
6170             case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
6171             case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
6172                 {
6173                     int op1;
6174 
6175                     op1 = op & 7;
6176                     if (op >= 0x20) {
6177                         gen_helper_fp_arith_STN_ST0(op1, opreg);
6178                         if (op >= 0x30)
6179                             gen_helper_fpop(cpu_env);
6180                     } else {
6181                         gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6182                         gen_helper_fp_arith_ST0_FT0(op1);
6183                     }
6184                 }
6185                 break;
6186             case 0x02: /* fcom */
6187             case 0x22: /* fcom2, undocumented op */
6188                 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6189                 gen_helper_fcom_ST0_FT0(cpu_env);
6190                 break;
6191             case 0x03: /* fcomp */
6192             case 0x23: /* fcomp3, undocumented op */
6193             case 0x32: /* fcomp5, undocumented op */
6194                 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6195                 gen_helper_fcom_ST0_FT0(cpu_env);
6196                 gen_helper_fpop(cpu_env);
6197                 break;
6198             case 0x15: /* da/5 */
6199                 switch(rm) {
6200                 case 1: /* fucompp */
6201                     gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6202                     gen_helper_fucom_ST0_FT0(cpu_env);
6203                     gen_helper_fpop(cpu_env);
6204                     gen_helper_fpop(cpu_env);
6205                     break;
6206                 default:
6207                     goto unknown_op;
6208                 }
6209                 break;
6210             case 0x1c:
6211                 switch(rm) {
6212                 case 0: /* feni (287 only, just do nop here) */
6213                     break;
6214                 case 1: /* fdisi (287 only, just do nop here) */
6215                     break;
6216                 case 2: /* fclex */
6217                     gen_helper_fclex(cpu_env);
6218                     break;
6219                 case 3: /* fninit */
6220                     gen_helper_fninit(cpu_env);
6221                     break;
6222                 case 4: /* fsetpm (287 only, just do nop here) */
6223                     break;
6224                 default:
6225                     goto unknown_op;
6226                 }
6227                 break;
6228             case 0x1d: /* fucomi */
6229                 if (!(s->cpuid_features & CPUID_CMOV)) {
6230                     goto illegal_op;
6231                 }
6232                 gen_update_cc_op(s);
6233                 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6234                 gen_helper_fucomi_ST0_FT0(cpu_env);
6235                 set_cc_op(s, CC_OP_EFLAGS);
6236                 break;
6237             case 0x1e: /* fcomi */
6238                 if (!(s->cpuid_features & CPUID_CMOV)) {
6239                     goto illegal_op;
6240                 }
6241                 gen_update_cc_op(s);
6242                 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6243                 gen_helper_fcomi_ST0_FT0(cpu_env);
6244                 set_cc_op(s, CC_OP_EFLAGS);
6245                 break;
6246             case 0x28: /* ffree sti */
6247                 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6248                 break;
6249             case 0x2a: /* fst sti */
6250                 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6251                 break;
6252             case 0x2b: /* fstp sti */
6253             case 0x0b: /* fstp1 sti, undocumented op */
6254             case 0x3a: /* fstp8 sti, undocumented op */
6255             case 0x3b: /* fstp9 sti, undocumented op */
6256                 gen_helper_fmov_STN_ST0(cpu_env, tcg_const_i32(opreg));
6257                 gen_helper_fpop(cpu_env);
6258                 break;
6259             case 0x2c: /* fucom st(i) */
6260                 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6261                 gen_helper_fucom_ST0_FT0(cpu_env);
6262                 break;
6263             case 0x2d: /* fucomp st(i) */
6264                 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6265                 gen_helper_fucom_ST0_FT0(cpu_env);
6266                 gen_helper_fpop(cpu_env);
6267                 break;
6268             case 0x33: /* de/3 */
6269                 switch(rm) {
6270                 case 1: /* fcompp */
6271                     gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(1));
6272                     gen_helper_fcom_ST0_FT0(cpu_env);
6273                     gen_helper_fpop(cpu_env);
6274                     gen_helper_fpop(cpu_env);
6275                     break;
6276                 default:
6277                     goto unknown_op;
6278                 }
6279                 break;
6280             case 0x38: /* ffreep sti, undocumented op */
6281                 gen_helper_ffree_STN(cpu_env, tcg_const_i32(opreg));
6282                 gen_helper_fpop(cpu_env);
6283                 break;
6284             case 0x3c: /* df/4 */
6285                 switch(rm) {
6286                 case 0:
6287                     gen_helper_fnstsw(s->tmp2_i32, cpu_env);
6288                     tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
6289                     gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
6290                     break;
6291                 default:
6292                     goto unknown_op;
6293                 }
6294                 break;
6295             case 0x3d: /* fucomip */
6296                 if (!(s->cpuid_features & CPUID_CMOV)) {
6297                     goto illegal_op;
6298                 }
6299                 gen_update_cc_op(s);
6300                 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6301                 gen_helper_fucomi_ST0_FT0(cpu_env);
6302                 gen_helper_fpop(cpu_env);
6303                 set_cc_op(s, CC_OP_EFLAGS);
6304                 break;
6305             case 0x3e: /* fcomip */
6306                 if (!(s->cpuid_features & CPUID_CMOV)) {
6307                     goto illegal_op;
6308                 }
6309                 gen_update_cc_op(s);
6310                 gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
6311                 gen_helper_fcomi_ST0_FT0(cpu_env);
6312                 gen_helper_fpop(cpu_env);
6313                 set_cc_op(s, CC_OP_EFLAGS);
6314                 break;
6315             case 0x10 ... 0x13: /* fcmovxx */
6316             case 0x18 ... 0x1b:
6317                 {
6318                     int op1;
6319                     TCGLabel *l1;
6320                     static const uint8_t fcmov_cc[8] = {
6321                         (JCC_B << 1),
6322                         (JCC_Z << 1),
6323                         (JCC_BE << 1),
6324                         (JCC_P << 1),
6325                     };
6326 
6327                     if (!(s->cpuid_features & CPUID_CMOV)) {
6328                         goto illegal_op;
6329                     }
6330                     op1 = fcmov_cc[op & 3] | (((op >> 3) & 1) ^ 1);
6331                     l1 = gen_new_label();
6332                     gen_jcc1_noeob(s, op1, l1);
6333                     gen_helper_fmov_ST0_STN(cpu_env, tcg_const_i32(opreg));
6334                     gen_set_label(l1);
6335                 }
6336                 break;
6337             default:
6338                 goto unknown_op;
6339             }
6340         }
6341         break;
6342         /************************/
6343         /* string ops */
6344 
6345     case 0xa4: /* movsS */
6346     case 0xa5:
6347         ot = mo_b_d(b, dflag);
6348         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6349             gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6350         } else {
6351             gen_movs(s, ot);
6352         }
6353         break;
6354 
6355     case 0xaa: /* stosS */
6356     case 0xab:
6357         ot = mo_b_d(b, dflag);
6358         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6359             gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6360         } else {
6361             gen_stos(s, ot);
6362         }
6363         break;
6364     case 0xac: /* lodsS */
6365     case 0xad:
6366         ot = mo_b_d(b, dflag);
6367         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6368             gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6369         } else {
6370             gen_lods(s, ot);
6371         }
6372         break;
6373     case 0xae: /* scasS */
6374     case 0xaf:
6375         ot = mo_b_d(b, dflag);
6376         if (prefixes & PREFIX_REPNZ) {
6377             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6378         } else if (prefixes & PREFIX_REPZ) {
6379             gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6380         } else {
6381             gen_scas(s, ot);
6382         }
6383         break;
6384 
6385     case 0xa6: /* cmpsS */
6386     case 0xa7:
6387         ot = mo_b_d(b, dflag);
6388         if (prefixes & PREFIX_REPNZ) {
6389             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
6390         } else if (prefixes & PREFIX_REPZ) {
6391             gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
6392         } else {
6393             gen_cmps(s, ot);
6394         }
6395         break;
6396     case 0x6c: /* insS */
6397     case 0x6d:
6398         ot = mo_b_d32(b, dflag);
6399         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
6400         gen_check_io(s, ot, pc_start - s->cs_base,
6401                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
6402         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6403             gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6404         } else {
6405             gen_ins(s, ot);
6406             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6407                 gen_jmp(s, s->pc - s->cs_base);
6408             }
6409         }
6410         break;
6411     case 0x6e: /* outsS */
6412     case 0x6f:
6413         ot = mo_b_d32(b, dflag);
6414         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
6415         gen_check_io(s, ot, pc_start - s->cs_base,
6416                      svm_is_rep(prefixes) | 4);
6417         if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
6418             gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
6419         } else {
6420             gen_outs(s, ot);
6421             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6422                 gen_jmp(s, s->pc - s->cs_base);
6423             }
6424         }
6425         break;
6426 
6427         /************************/
6428         /* port I/O */
6429 
6430     case 0xe4:
6431     case 0xe5:
6432         ot = mo_b_d32(b, dflag);
6433         val = x86_ldub_code(env, s);
6434         tcg_gen_movi_tl(s->T0, val);
6435         gen_check_io(s, ot, pc_start - s->cs_base,
6436                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6437         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6438             gen_io_start();
6439         }
6440         tcg_gen_movi_i32(s->tmp2_i32, val);
6441         gen_helper_in_func(ot, s->T1, s->tmp2_i32);
6442         gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
6443         gen_bpt_io(s, s->tmp2_i32, ot);
6444         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6445             gen_jmp(s, s->pc - s->cs_base);
6446         }
6447         break;
6448     case 0xe6:
6449     case 0xe7:
6450         ot = mo_b_d32(b, dflag);
6451         val = x86_ldub_code(env, s);
6452         tcg_gen_movi_tl(s->T0, val);
6453         gen_check_io(s, ot, pc_start - s->cs_base,
6454                      svm_is_rep(prefixes));
6455         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
6456 
6457         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6458             gen_io_start();
6459         }
6460         tcg_gen_movi_i32(s->tmp2_i32, val);
6461         tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
6462         gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
6463         gen_bpt_io(s, s->tmp2_i32, ot);
6464         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6465             gen_jmp(s, s->pc - s->cs_base);
6466         }
6467         break;
6468     case 0xec:
6469     case 0xed:
6470         ot = mo_b_d32(b, dflag);
6471         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
6472         gen_check_io(s, ot, pc_start - s->cs_base,
6473                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
6474         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6475             gen_io_start();
6476         }
6477         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
6478         gen_helper_in_func(ot, s->T1, s->tmp2_i32);
6479         gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
6480         gen_bpt_io(s, s->tmp2_i32, ot);
6481         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6482             gen_jmp(s, s->pc - s->cs_base);
6483         }
6484         break;
6485     case 0xee:
6486     case 0xef:
6487         ot = mo_b_d32(b, dflag);
6488         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
6489         gen_check_io(s, ot, pc_start - s->cs_base,
6490                      svm_is_rep(prefixes));
6491         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
6492 
6493         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6494             gen_io_start();
6495         }
6496         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
6497         tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
6498         gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
6499         gen_bpt_io(s, s->tmp2_i32, ot);
6500         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
6501             gen_jmp(s, s->pc - s->cs_base);
6502         }
6503         break;
6504 
6505         /************************/
6506         /* control */
6507     case 0xc2: /* ret im */
6508         val = x86_ldsw_code(env, s);
6509         ot = gen_pop_T0(s);
6510         gen_stack_update(s, val + (1 << ot));
6511         /* Note that gen_pop_T0 uses a zero-extending load.  */
6512         gen_op_jmp_v(s->T0);
6513         gen_bnd_jmp(s);
6514         gen_jr(s, s->T0);
6515         break;
6516     case 0xc3: /* ret */
6517         ot = gen_pop_T0(s);
6518         gen_pop_update(s, ot);
6519         /* Note that gen_pop_T0 uses a zero-extending load.  */
6520         gen_op_jmp_v(s->T0);
6521         gen_bnd_jmp(s);
6522         gen_jr(s, s->T0);
6523         break;
6524     case 0xca: /* lret im */
6525         val = x86_ldsw_code(env, s);
6526     do_lret:
6527         if (s->pe && !s->vm86) {
6528             gen_update_cc_op(s);
6529             gen_jmp_im(s, pc_start - s->cs_base);
6530             gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
6531                                       tcg_const_i32(val));
6532         } else {
6533             gen_stack_A0(s);
6534             /* pop offset */
6535             gen_op_ld_v(s, dflag, s->T0, s->A0);
6536             /* NOTE: keeping EIP updated is not a problem in case of
6537                exception */
6538             gen_op_jmp_v(s->T0);
6539             /* pop selector */
6540             gen_add_A0_im(s, 1 << dflag);
6541             gen_op_ld_v(s, dflag, s->T0, s->A0);
6542             gen_op_movl_seg_T0_vm(s, R_CS);
6543             /* add stack offset */
6544             gen_stack_update(s, val + (2 << dflag));
6545         }
6546         gen_eob(s);
6547         break;
6548     case 0xcb: /* lret */
6549         val = 0;
6550         goto do_lret;
6551     case 0xcf: /* iret */
6552         gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
6553         if (!s->pe) {
6554             /* real mode */
6555             gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6556             set_cc_op(s, CC_OP_EFLAGS);
6557         } else if (s->vm86) {
6558             if (s->iopl != 3) {
6559                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6560             } else {
6561                 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
6562                 set_cc_op(s, CC_OP_EFLAGS);
6563             }
6564         } else {
6565             gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
6566                                       tcg_const_i32(s->pc - s->cs_base));
6567             set_cc_op(s, CC_OP_EFLAGS);
6568         }
6569         gen_eob(s);
6570         break;
6571     case 0xe8: /* call im */
6572         {
6573             if (dflag != MO_16) {
6574                 tval = (int32_t)insn_get(env, s, MO_32);
6575             } else {
6576                 tval = (int16_t)insn_get(env, s, MO_16);
6577             }
6578             next_eip = s->pc - s->cs_base;
6579             tval += next_eip;
6580             if (dflag == MO_16) {
6581                 tval &= 0xffff;
6582             } else if (!CODE64(s)) {
6583                 tval &= 0xffffffff;
6584             }
6585             tcg_gen_movi_tl(s->T0, next_eip);
6586             gen_push_v(s, s->T0);
6587             gen_bnd_jmp(s);
6588             gen_jmp(s, tval);
6589         }
6590         break;
6591     case 0x9a: /* lcall im */
6592         {
6593             unsigned int selector, offset;
6594 
6595             if (CODE64(s))
6596                 goto illegal_op;
6597             ot = dflag;
6598             offset = insn_get(env, s, ot);
6599             selector = insn_get(env, s, MO_16);
6600 
6601             tcg_gen_movi_tl(s->T0, selector);
6602             tcg_gen_movi_tl(s->T1, offset);
6603         }
6604         goto do_lcall;
6605     case 0xe9: /* jmp im */
6606         if (dflag != MO_16) {
6607             tval = (int32_t)insn_get(env, s, MO_32);
6608         } else {
6609             tval = (int16_t)insn_get(env, s, MO_16);
6610         }
6611         tval += s->pc - s->cs_base;
6612         if (dflag == MO_16) {
6613             tval &= 0xffff;
6614         } else if (!CODE64(s)) {
6615             tval &= 0xffffffff;
6616         }
6617         gen_bnd_jmp(s);
6618         gen_jmp(s, tval);
6619         break;
6620     case 0xea: /* ljmp im */
6621         {
6622             unsigned int selector, offset;
6623 
6624             if (CODE64(s))
6625                 goto illegal_op;
6626             ot = dflag;
6627             offset = insn_get(env, s, ot);
6628             selector = insn_get(env, s, MO_16);
6629 
6630             tcg_gen_movi_tl(s->T0, selector);
6631             tcg_gen_movi_tl(s->T1, offset);
6632         }
6633         goto do_ljmp;
6634     case 0xeb: /* jmp Jb */
6635         tval = (int8_t)insn_get(env, s, MO_8);
6636         tval += s->pc - s->cs_base;
6637         if (dflag == MO_16) {
6638             tval &= 0xffff;
6639         }
6640         gen_jmp(s, tval);
6641         break;
6642     case 0x70 ... 0x7f: /* jcc Jb */
6643         tval = (int8_t)insn_get(env, s, MO_8);
6644         goto do_jcc;
6645     case 0x180 ... 0x18f: /* jcc Jv */
6646         if (dflag != MO_16) {
6647             tval = (int32_t)insn_get(env, s, MO_32);
6648         } else {
6649             tval = (int16_t)insn_get(env, s, MO_16);
6650         }
6651     do_jcc:
6652         next_eip = s->pc - s->cs_base;
6653         tval += next_eip;
6654         if (dflag == MO_16) {
6655             tval &= 0xffff;
6656         }
6657         gen_bnd_jmp(s);
6658         gen_jcc(s, b, tval, next_eip);
6659         break;
6660 
6661     case 0x190 ... 0x19f: /* setcc Gv */
6662         modrm = x86_ldub_code(env, s);
6663         gen_setcc1(s, b, s->T0);
6664         gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
6665         break;
6666     case 0x140 ... 0x14f: /* cmov Gv, Ev */
6667         if (!(s->cpuid_features & CPUID_CMOV)) {
6668             goto illegal_op;
6669         }
6670         ot = dflag;
6671         modrm = x86_ldub_code(env, s);
6672         reg = ((modrm >> 3) & 7) | rex_r;
6673         gen_cmovcc1(env, s, ot, b, modrm, reg);
6674         break;
6675 
6676         /************************/
6677         /* flags */
6678     case 0x9c: /* pushf */
6679         gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
6680         if (s->vm86 && s->iopl != 3) {
6681             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6682         } else {
6683             gen_update_cc_op(s);
6684             gen_helper_read_eflags(s->T0, cpu_env);
6685             gen_push_v(s, s->T0);
6686         }
6687         break;
6688     case 0x9d: /* popf */
6689         gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
6690         if (s->vm86 && s->iopl != 3) {
6691             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
6692         } else {
6693             ot = gen_pop_T0(s);
6694             if (s->cpl == 0) {
6695                 if (dflag != MO_16) {
6696                     gen_helper_write_eflags(cpu_env, s->T0,
6697                                             tcg_const_i32((TF_MASK | AC_MASK |
6698                                                            ID_MASK | NT_MASK |
6699                                                            IF_MASK |
6700                                                            IOPL_MASK)));
6701                 } else {
6702                     gen_helper_write_eflags(cpu_env, s->T0,
6703                                             tcg_const_i32((TF_MASK | AC_MASK |
6704                                                            ID_MASK | NT_MASK |
6705                                                            IF_MASK | IOPL_MASK)
6706                                                           & 0xffff));
6707                 }
6708             } else {
6709                 if (s->cpl <= s->iopl) {
6710                     if (dflag != MO_16) {
6711                         gen_helper_write_eflags(cpu_env, s->T0,
6712                                                 tcg_const_i32((TF_MASK |
6713                                                                AC_MASK |
6714                                                                ID_MASK |
6715                                                                NT_MASK |
6716                                                                IF_MASK)));
6717                     } else {
6718                         gen_helper_write_eflags(cpu_env, s->T0,
6719                                                 tcg_const_i32((TF_MASK |
6720                                                                AC_MASK |
6721                                                                ID_MASK |
6722                                                                NT_MASK |
6723                                                                IF_MASK)
6724                                                               & 0xffff));
6725                     }
6726                 } else {
6727                     if (dflag != MO_16) {
6728                         gen_helper_write_eflags(cpu_env, s->T0,
6729                                            tcg_const_i32((TF_MASK | AC_MASK |
6730                                                           ID_MASK | NT_MASK)));
6731                     } else {
6732                         gen_helper_write_eflags(cpu_env, s->T0,
6733                                            tcg_const_i32((TF_MASK | AC_MASK |
6734                                                           ID_MASK | NT_MASK)
6735                                                          & 0xffff));
6736                     }
6737                 }
6738             }
6739             gen_pop_update(s, ot);
6740             set_cc_op(s, CC_OP_EFLAGS);
6741             /* abort translation because TF/AC flag may change */
6742             gen_jmp_im(s, s->pc - s->cs_base);
6743             gen_eob(s);
6744         }
6745         break;
6746     case 0x9e: /* sahf */
6747         if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6748             goto illegal_op;
6749         gen_op_mov_v_reg(s, MO_8, s->T0, R_AH);
6750         gen_compute_eflags(s);
6751         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
6752         tcg_gen_andi_tl(s->T0, s->T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
6753         tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, s->T0);
6754         break;
6755     case 0x9f: /* lahf */
6756         if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM))
6757             goto illegal_op;
6758         gen_compute_eflags(s);
6759         /* Note: gen_compute_eflags() only gives the condition codes */
6760         tcg_gen_ori_tl(s->T0, cpu_cc_src, 0x02);
6761         gen_op_mov_reg_v(s, MO_8, R_AH, s->T0);
6762         break;
6763     case 0xf5: /* cmc */
6764         gen_compute_eflags(s);
6765         tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6766         break;
6767     case 0xf8: /* clc */
6768         gen_compute_eflags(s);
6769         tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
6770         break;
6771     case 0xf9: /* stc */
6772         gen_compute_eflags(s);
6773         tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
6774         break;
6775     case 0xfc: /* cld */
6776         tcg_gen_movi_i32(s->tmp2_i32, 1);
6777         tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6778         break;
6779     case 0xfd: /* std */
6780         tcg_gen_movi_i32(s->tmp2_i32, -1);
6781         tcg_gen_st_i32(s->tmp2_i32, cpu_env, offsetof(CPUX86State, df));
6782         break;
6783 
6784         /************************/
6785         /* bit operations */
6786     case 0x1ba: /* bt/bts/btr/btc Gv, im */
6787         ot = dflag;
6788         modrm = x86_ldub_code(env, s);
6789         op = (modrm >> 3) & 7;
6790         mod = (modrm >> 6) & 3;
6791         rm = (modrm & 7) | REX_B(s);
6792         if (mod != 3) {
6793             s->rip_offset = 1;
6794             gen_lea_modrm(env, s, modrm);
6795             if (!(s->prefix & PREFIX_LOCK)) {
6796                 gen_op_ld_v(s, ot, s->T0, s->A0);
6797             }
6798         } else {
6799             gen_op_mov_v_reg(s, ot, s->T0, rm);
6800         }
6801         /* load shift */
6802         val = x86_ldub_code(env, s);
6803         tcg_gen_movi_tl(s->T1, val);
6804         if (op < 4)
6805             goto unknown_op;
6806         op -= 4;
6807         goto bt_op;
6808     case 0x1a3: /* bt Gv, Ev */
6809         op = 0;
6810         goto do_btx;
6811     case 0x1ab: /* bts */
6812         op = 1;
6813         goto do_btx;
6814     case 0x1b3: /* btr */
6815         op = 2;
6816         goto do_btx;
6817     case 0x1bb: /* btc */
6818         op = 3;
6819     do_btx:
6820         ot = dflag;
6821         modrm = x86_ldub_code(env, s);
6822         reg = ((modrm >> 3) & 7) | rex_r;
6823         mod = (modrm >> 6) & 3;
6824         rm = (modrm & 7) | REX_B(s);
6825         gen_op_mov_v_reg(s, MO_32, s->T1, reg);
6826         if (mod != 3) {
6827             AddressParts a = gen_lea_modrm_0(env, s, modrm);
6828             /* specific case: we need to add a displacement */
6829             gen_exts(ot, s->T1);
6830             tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot);
6831             tcg_gen_shli_tl(s->tmp0, s->tmp0, ot);
6832             tcg_gen_add_tl(s->A0, gen_lea_modrm_1(s, a), s->tmp0);
6833             gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
6834             if (!(s->prefix & PREFIX_LOCK)) {
6835                 gen_op_ld_v(s, ot, s->T0, s->A0);
6836             }
6837         } else {
6838             gen_op_mov_v_reg(s, ot, s->T0, rm);
6839         }
6840     bt_op:
6841         tcg_gen_andi_tl(s->T1, s->T1, (1 << (3 + ot)) - 1);
6842         tcg_gen_movi_tl(s->tmp0, 1);
6843         tcg_gen_shl_tl(s->tmp0, s->tmp0, s->T1);
6844         if (s->prefix & PREFIX_LOCK) {
6845             switch (op) {
6846             case 0: /* bt */
6847                 /* Needs no atomic ops; we surpressed the normal
6848                    memory load for LOCK above so do it now.  */
6849                 gen_op_ld_v(s, ot, s->T0, s->A0);
6850                 break;
6851             case 1: /* bts */
6852                 tcg_gen_atomic_fetch_or_tl(s->T0, s->A0, s->tmp0,
6853                                            s->mem_index, ot | MO_LE);
6854                 break;
6855             case 2: /* btr */
6856                 tcg_gen_not_tl(s->tmp0, s->tmp0);
6857                 tcg_gen_atomic_fetch_and_tl(s->T0, s->A0, s->tmp0,
6858                                             s->mem_index, ot | MO_LE);
6859                 break;
6860             default:
6861             case 3: /* btc */
6862                 tcg_gen_atomic_fetch_xor_tl(s->T0, s->A0, s->tmp0,
6863                                             s->mem_index, ot | MO_LE);
6864                 break;
6865             }
6866             tcg_gen_shr_tl(s->tmp4, s->T0, s->T1);
6867         } else {
6868             tcg_gen_shr_tl(s->tmp4, s->T0, s->T1);
6869             switch (op) {
6870             case 0: /* bt */
6871                 /* Data already loaded; nothing to do.  */
6872                 break;
6873             case 1: /* bts */
6874                 tcg_gen_or_tl(s->T0, s->T0, s->tmp0);
6875                 break;
6876             case 2: /* btr */
6877                 tcg_gen_andc_tl(s->T0, s->T0, s->tmp0);
6878                 break;
6879             default:
6880             case 3: /* btc */
6881                 tcg_gen_xor_tl(s->T0, s->T0, s->tmp0);
6882                 break;
6883             }
6884             if (op != 0) {
6885                 if (mod != 3) {
6886                     gen_op_st_v(s, ot, s->T0, s->A0);
6887                 } else {
6888                     gen_op_mov_reg_v(s, ot, rm, s->T0);
6889                 }
6890             }
6891         }
6892 
6893         /* Delay all CC updates until after the store above.  Note that
6894            C is the result of the test, Z is unchanged, and the others
6895            are all undefined.  */
6896         switch (s->cc_op) {
6897         case CC_OP_MULB ... CC_OP_MULQ:
6898         case CC_OP_ADDB ... CC_OP_ADDQ:
6899         case CC_OP_ADCB ... CC_OP_ADCQ:
6900         case CC_OP_SUBB ... CC_OP_SUBQ:
6901         case CC_OP_SBBB ... CC_OP_SBBQ:
6902         case CC_OP_LOGICB ... CC_OP_LOGICQ:
6903         case CC_OP_INCB ... CC_OP_INCQ:
6904         case CC_OP_DECB ... CC_OP_DECQ:
6905         case CC_OP_SHLB ... CC_OP_SHLQ:
6906         case CC_OP_SARB ... CC_OP_SARQ:
6907         case CC_OP_BMILGB ... CC_OP_BMILGQ:
6908             /* Z was going to be computed from the non-zero status of CC_DST.
6909                We can get that same Z value (and the new C value) by leaving
6910                CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
6911                same width.  */
6912             tcg_gen_mov_tl(cpu_cc_src, s->tmp4);
6913             set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
6914             break;
6915         default:
6916             /* Otherwise, generate EFLAGS and replace the C bit.  */
6917             gen_compute_eflags(s);
6918             tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, s->tmp4,
6919                                ctz32(CC_C), 1);
6920             break;
6921         }
6922         break;
6923     case 0x1bc: /* bsf / tzcnt */
6924     case 0x1bd: /* bsr / lzcnt */
6925         ot = dflag;
6926         modrm = x86_ldub_code(env, s);
6927         reg = ((modrm >> 3) & 7) | rex_r;
6928         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
6929         gen_extu(ot, s->T0);
6930 
6931         /* Note that lzcnt and tzcnt are in different extensions.  */
6932         if ((prefixes & PREFIX_REPZ)
6933             && (b & 1
6934                 ? s->cpuid_ext3_features & CPUID_EXT3_ABM
6935                 : s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)) {
6936             int size = 8 << ot;
6937             /* For lzcnt/tzcnt, C bit is defined related to the input. */
6938             tcg_gen_mov_tl(cpu_cc_src, s->T0);
6939             if (b & 1) {
6940                 /* For lzcnt, reduce the target_ulong result by the
6941                    number of zeros that we expect to find at the top.  */
6942                 tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS);
6943                 tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - size);
6944             } else {
6945                 /* For tzcnt, a zero input must return the operand size.  */
6946                 tcg_gen_ctzi_tl(s->T0, s->T0, size);
6947             }
6948             /* For lzcnt/tzcnt, Z bit is defined related to the result.  */
6949             gen_op_update1_cc(s);
6950             set_cc_op(s, CC_OP_BMILGB + ot);
6951         } else {
6952             /* For bsr/bsf, only the Z bit is defined and it is related
6953                to the input and not the result.  */
6954             tcg_gen_mov_tl(cpu_cc_dst, s->T0);
6955             set_cc_op(s, CC_OP_LOGICB + ot);
6956 
6957             /* ??? The manual says that the output is undefined when the
6958                input is zero, but real hardware leaves it unchanged, and
6959                real programs appear to depend on that.  Accomplish this
6960                by passing the output as the value to return upon zero.  */
6961             if (b & 1) {
6962                 /* For bsr, return the bit index of the first 1 bit,
6963                    not the count of leading zeros.  */
6964                 tcg_gen_xori_tl(s->T1, cpu_regs[reg], TARGET_LONG_BITS - 1);
6965                 tcg_gen_clz_tl(s->T0, s->T0, s->T1);
6966                 tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1);
6967             } else {
6968                 tcg_gen_ctz_tl(s->T0, s->T0, cpu_regs[reg]);
6969             }
6970         }
6971         gen_op_mov_reg_v(s, ot, reg, s->T0);
6972         break;
6973         /************************/
6974         /* bcd */
6975     case 0x27: /* daa */
6976         if (CODE64(s))
6977             goto illegal_op;
6978         gen_update_cc_op(s);
6979         gen_helper_daa(cpu_env);
6980         set_cc_op(s, CC_OP_EFLAGS);
6981         break;
6982     case 0x2f: /* das */
6983         if (CODE64(s))
6984             goto illegal_op;
6985         gen_update_cc_op(s);
6986         gen_helper_das(cpu_env);
6987         set_cc_op(s, CC_OP_EFLAGS);
6988         break;
6989     case 0x37: /* aaa */
6990         if (CODE64(s))
6991             goto illegal_op;
6992         gen_update_cc_op(s);
6993         gen_helper_aaa(cpu_env);
6994         set_cc_op(s, CC_OP_EFLAGS);
6995         break;
6996     case 0x3f: /* aas */
6997         if (CODE64(s))
6998             goto illegal_op;
6999         gen_update_cc_op(s);
7000         gen_helper_aas(cpu_env);
7001         set_cc_op(s, CC_OP_EFLAGS);
7002         break;
7003     case 0xd4: /* aam */
7004         if (CODE64(s))
7005             goto illegal_op;
7006         val = x86_ldub_code(env, s);
7007         if (val == 0) {
7008             gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
7009         } else {
7010             gen_helper_aam(cpu_env, tcg_const_i32(val));
7011             set_cc_op(s, CC_OP_LOGICB);
7012         }
7013         break;
7014     case 0xd5: /* aad */
7015         if (CODE64(s))
7016             goto illegal_op;
7017         val = x86_ldub_code(env, s);
7018         gen_helper_aad(cpu_env, tcg_const_i32(val));
7019         set_cc_op(s, CC_OP_LOGICB);
7020         break;
7021         /************************/
7022         /* misc */
7023     case 0x90: /* nop */
7024         /* XXX: correct lock test for all insn */
7025         if (prefixes & PREFIX_LOCK) {
7026             goto illegal_op;
7027         }
7028         /* If REX_B is set, then this is xchg eax, r8d, not a nop.  */
7029         if (REX_B(s)) {
7030             goto do_xchg_reg_eax;
7031         }
7032         if (prefixes & PREFIX_REPZ) {
7033             gen_update_cc_op(s);
7034             gen_jmp_im(s, pc_start - s->cs_base);
7035             gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
7036             s->base.is_jmp = DISAS_NORETURN;
7037         }
7038         break;
7039     case 0x9b: /* fwait */
7040         if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
7041             (HF_MP_MASK | HF_TS_MASK)) {
7042             gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
7043         } else {
7044             gen_helper_fwait(cpu_env);
7045         }
7046         break;
7047     case 0xcc: /* int3 */
7048         gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
7049         break;
7050     case 0xcd: /* int N */
7051         val = x86_ldub_code(env, s);
7052         if (s->vm86 && s->iopl != 3) {
7053             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7054         } else {
7055             gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
7056         }
7057         break;
7058     case 0xce: /* into */
7059         if (CODE64(s))
7060             goto illegal_op;
7061         gen_update_cc_op(s);
7062         gen_jmp_im(s, pc_start - s->cs_base);
7063         gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
7064         break;
7065 #ifdef WANT_ICEBP
7066     case 0xf1: /* icebp (undocumented, exits to external debugger) */
7067         gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
7068         gen_debug(s, pc_start - s->cs_base);
7069         break;
7070 #endif
7071     case 0xfa: /* cli */
7072         if (!s->vm86) {
7073             if (s->cpl <= s->iopl) {
7074                 gen_helper_cli(cpu_env);
7075             } else {
7076                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7077             }
7078         } else {
7079             if (s->iopl == 3) {
7080                 gen_helper_cli(cpu_env);
7081             } else {
7082                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7083             }
7084         }
7085         break;
7086     case 0xfb: /* sti */
7087         if (s->vm86 ? s->iopl == 3 : s->cpl <= s->iopl) {
7088             gen_helper_sti(cpu_env);
7089             /* interruptions are enabled only the first insn after sti */
7090             gen_jmp_im(s, s->pc - s->cs_base);
7091             gen_eob_inhibit_irq(s, true);
7092         } else {
7093             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7094         }
7095         break;
7096     case 0x62: /* bound */
7097         if (CODE64(s))
7098             goto illegal_op;
7099         ot = dflag;
7100         modrm = x86_ldub_code(env, s);
7101         reg = (modrm >> 3) & 7;
7102         mod = (modrm >> 6) & 3;
7103         if (mod == 3)
7104             goto illegal_op;
7105         gen_op_mov_v_reg(s, ot, s->T0, reg);
7106         gen_lea_modrm(env, s, modrm);
7107         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
7108         if (ot == MO_16) {
7109             gen_helper_boundw(cpu_env, s->A0, s->tmp2_i32);
7110         } else {
7111             gen_helper_boundl(cpu_env, s->A0, s->tmp2_i32);
7112         }
7113         break;
7114     case 0x1c8 ... 0x1cf: /* bswap reg */
7115         reg = (b & 7) | REX_B(s);
7116 #ifdef TARGET_X86_64
7117         if (dflag == MO_64) {
7118             gen_op_mov_v_reg(s, MO_64, s->T0, reg);
7119             tcg_gen_bswap64_i64(s->T0, s->T0);
7120             gen_op_mov_reg_v(s, MO_64, reg, s->T0);
7121         } else
7122 #endif
7123         {
7124             gen_op_mov_v_reg(s, MO_32, s->T0, reg);
7125             tcg_gen_ext32u_tl(s->T0, s->T0);
7126             tcg_gen_bswap32_tl(s->T0, s->T0);
7127             gen_op_mov_reg_v(s, MO_32, reg, s->T0);
7128         }
7129         break;
7130     case 0xd6: /* salc */
7131         if (CODE64(s))
7132             goto illegal_op;
7133         gen_compute_eflags_c(s, s->T0);
7134         tcg_gen_neg_tl(s->T0, s->T0);
7135         gen_op_mov_reg_v(s, MO_8, R_EAX, s->T0);
7136         break;
7137     case 0xe0: /* loopnz */
7138     case 0xe1: /* loopz */
7139     case 0xe2: /* loop */
7140     case 0xe3: /* jecxz */
7141         {
7142             TCGLabel *l1, *l2, *l3;
7143 
7144             tval = (int8_t)insn_get(env, s, MO_8);
7145             next_eip = s->pc - s->cs_base;
7146             tval += next_eip;
7147             if (dflag == MO_16) {
7148                 tval &= 0xffff;
7149             }
7150 
7151             l1 = gen_new_label();
7152             l2 = gen_new_label();
7153             l3 = gen_new_label();
7154             b &= 3;
7155             switch(b) {
7156             case 0: /* loopnz */
7157             case 1: /* loopz */
7158                 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
7159                 gen_op_jz_ecx(s, s->aflag, l3);
7160                 gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
7161                 break;
7162             case 2: /* loop */
7163                 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
7164                 gen_op_jnz_ecx(s, s->aflag, l1);
7165                 break;
7166             default:
7167             case 3: /* jcxz */
7168                 gen_op_jz_ecx(s, s->aflag, l1);
7169                 break;
7170             }
7171 
7172             gen_set_label(l3);
7173             gen_jmp_im(s, next_eip);
7174             tcg_gen_br(l2);
7175 
7176             gen_set_label(l1);
7177             gen_jmp_im(s, tval);
7178             gen_set_label(l2);
7179             gen_eob(s);
7180         }
7181         break;
7182     case 0x130: /* wrmsr */
7183     case 0x132: /* rdmsr */
7184         if (s->cpl != 0) {
7185             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7186         } else {
7187             gen_update_cc_op(s);
7188             gen_jmp_im(s, pc_start - s->cs_base);
7189             if (b & 2) {
7190                 gen_helper_rdmsr(cpu_env);
7191             } else {
7192                 gen_helper_wrmsr(cpu_env);
7193             }
7194         }
7195         break;
7196     case 0x131: /* rdtsc */
7197         gen_update_cc_op(s);
7198         gen_jmp_im(s, pc_start - s->cs_base);
7199         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7200             gen_io_start();
7201         }
7202         gen_helper_rdtsc(cpu_env);
7203         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7204             gen_jmp(s, s->pc - s->cs_base);
7205         }
7206         break;
7207     case 0x133: /* rdpmc */
7208         gen_update_cc_op(s);
7209         gen_jmp_im(s, pc_start - s->cs_base);
7210         gen_helper_rdpmc(cpu_env);
7211         break;
7212     case 0x134: /* sysenter */
7213         /* For Intel SYSENTER is valid on 64-bit */
7214         if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7215             goto illegal_op;
7216         if (!s->pe) {
7217             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7218         } else {
7219             gen_helper_sysenter(cpu_env);
7220             gen_eob(s);
7221         }
7222         break;
7223     case 0x135: /* sysexit */
7224         /* For Intel SYSEXIT is valid on 64-bit */
7225         if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
7226             goto illegal_op;
7227         if (!s->pe) {
7228             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7229         } else {
7230             gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
7231             gen_eob(s);
7232         }
7233         break;
7234 #ifdef TARGET_X86_64
7235     case 0x105: /* syscall */
7236         /* XXX: is it usable in real mode ? */
7237         gen_update_cc_op(s);
7238         gen_jmp_im(s, pc_start - s->cs_base);
7239         gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
7240         /* TF handling for the syscall insn is different. The TF bit is  checked
7241            after the syscall insn completes. This allows #DB to not be
7242            generated after one has entered CPL0 if TF is set in FMASK.  */
7243         gen_eob_worker(s, false, true);
7244         break;
7245     case 0x107: /* sysret */
7246         if (!s->pe) {
7247             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7248         } else {
7249             gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
7250             /* condition codes are modified only in long mode */
7251             if (s->lma) {
7252                 set_cc_op(s, CC_OP_EFLAGS);
7253             }
7254             /* TF handling for the sysret insn is different. The TF bit is
7255                checked after the sysret insn completes. This allows #DB to be
7256                generated "as if" the syscall insn in userspace has just
7257                completed.  */
7258             gen_eob_worker(s, false, true);
7259         }
7260         break;
7261 #endif
7262     case 0x1a2: /* cpuid */
7263         gen_update_cc_op(s);
7264         gen_jmp_im(s, pc_start - s->cs_base);
7265         gen_helper_cpuid(cpu_env);
7266         break;
7267     case 0xf4: /* hlt */
7268         if (s->cpl != 0) {
7269             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7270         } else {
7271             gen_update_cc_op(s);
7272             gen_jmp_im(s, pc_start - s->cs_base);
7273             gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
7274             s->base.is_jmp = DISAS_NORETURN;
7275         }
7276         break;
7277     case 0x100:
7278         modrm = x86_ldub_code(env, s);
7279         mod = (modrm >> 6) & 3;
7280         op = (modrm >> 3) & 7;
7281         switch(op) {
7282         case 0: /* sldt */
7283             if (!s->pe || s->vm86)
7284                 goto illegal_op;
7285             gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
7286             tcg_gen_ld32u_tl(s->T0, cpu_env,
7287                              offsetof(CPUX86State, ldt.selector));
7288             ot = mod == 3 ? dflag : MO_16;
7289             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7290             break;
7291         case 2: /* lldt */
7292             if (!s->pe || s->vm86)
7293                 goto illegal_op;
7294             if (s->cpl != 0) {
7295                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7296             } else {
7297                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
7298                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7299                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
7300                 gen_helper_lldt(cpu_env, s->tmp2_i32);
7301             }
7302             break;
7303         case 1: /* str */
7304             if (!s->pe || s->vm86)
7305                 goto illegal_op;
7306             gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
7307             tcg_gen_ld32u_tl(s->T0, cpu_env,
7308                              offsetof(CPUX86State, tr.selector));
7309             ot = mod == 3 ? dflag : MO_16;
7310             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7311             break;
7312         case 3: /* ltr */
7313             if (!s->pe || s->vm86)
7314                 goto illegal_op;
7315             if (s->cpl != 0) {
7316                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7317             } else {
7318                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
7319                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7320                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
7321                 gen_helper_ltr(cpu_env, s->tmp2_i32);
7322             }
7323             break;
7324         case 4: /* verr */
7325         case 5: /* verw */
7326             if (!s->pe || s->vm86)
7327                 goto illegal_op;
7328             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7329             gen_update_cc_op(s);
7330             if (op == 4) {
7331                 gen_helper_verr(cpu_env, s->T0);
7332             } else {
7333                 gen_helper_verw(cpu_env, s->T0);
7334             }
7335             set_cc_op(s, CC_OP_EFLAGS);
7336             break;
7337         default:
7338             goto unknown_op;
7339         }
7340         break;
7341 
7342     case 0x101:
7343         modrm = x86_ldub_code(env, s);
7344         switch (modrm) {
7345         CASE_MODRM_MEM_OP(0): /* sgdt */
7346             gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
7347             gen_lea_modrm(env, s, modrm);
7348             tcg_gen_ld32u_tl(s->T0,
7349                              cpu_env, offsetof(CPUX86State, gdt.limit));
7350             gen_op_st_v(s, MO_16, s->T0, s->A0);
7351             gen_add_A0_im(s, 2);
7352             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base));
7353             if (dflag == MO_16) {
7354                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
7355             }
7356             gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
7357             break;
7358 
7359         case 0xc8: /* monitor */
7360             if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7361                 goto illegal_op;
7362             }
7363             gen_update_cc_op(s);
7364             gen_jmp_im(s, pc_start - s->cs_base);
7365             tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
7366             gen_extu(s->aflag, s->A0);
7367             gen_add_A0_ds_seg(s);
7368             gen_helper_monitor(cpu_env, s->A0);
7369             break;
7370 
7371         case 0xc9: /* mwait */
7372             if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
7373                 goto illegal_op;
7374             }
7375             gen_update_cc_op(s);
7376             gen_jmp_im(s, pc_start - s->cs_base);
7377             gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
7378             gen_eob(s);
7379             break;
7380 
7381         case 0xca: /* clac */
7382             if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7383                 || s->cpl != 0) {
7384                 goto illegal_op;
7385             }
7386             gen_helper_clac(cpu_env);
7387             gen_jmp_im(s, s->pc - s->cs_base);
7388             gen_eob(s);
7389             break;
7390 
7391         case 0xcb: /* stac */
7392             if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
7393                 || s->cpl != 0) {
7394                 goto illegal_op;
7395             }
7396             gen_helper_stac(cpu_env);
7397             gen_jmp_im(s, s->pc - s->cs_base);
7398             gen_eob(s);
7399             break;
7400 
7401         CASE_MODRM_MEM_OP(1): /* sidt */
7402             gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
7403             gen_lea_modrm(env, s, modrm);
7404             tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.limit));
7405             gen_op_st_v(s, MO_16, s->T0, s->A0);
7406             gen_add_A0_im(s, 2);
7407             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base));
7408             if (dflag == MO_16) {
7409                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
7410             }
7411             gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
7412             break;
7413 
7414         case 0xd0: /* xgetbv */
7415             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7416                 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7417                                  | PREFIX_REPZ | PREFIX_REPNZ))) {
7418                 goto illegal_op;
7419             }
7420             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
7421             gen_helper_xgetbv(s->tmp1_i64, cpu_env, s->tmp2_i32);
7422             tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
7423             break;
7424 
7425         case 0xd1: /* xsetbv */
7426             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
7427                 || (s->prefix & (PREFIX_LOCK | PREFIX_DATA
7428                                  | PREFIX_REPZ | PREFIX_REPNZ))) {
7429                 goto illegal_op;
7430             }
7431             if (s->cpl != 0) {
7432                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7433                 break;
7434             }
7435             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
7436                                   cpu_regs[R_EDX]);
7437             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
7438             gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64);
7439             /* End TB because translation flags may change.  */
7440             gen_jmp_im(s, s->pc - s->cs_base);
7441             gen_eob(s);
7442             break;
7443 
7444         case 0xd8: /* VMRUN */
7445             if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7446                 goto illegal_op;
7447             }
7448             if (s->cpl != 0) {
7449                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7450                 break;
7451             }
7452             gen_update_cc_op(s);
7453             gen_jmp_im(s, pc_start - s->cs_base);
7454             gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
7455                              tcg_const_i32(s->pc - pc_start));
7456             tcg_gen_exit_tb(NULL, 0);
7457             s->base.is_jmp = DISAS_NORETURN;
7458             break;
7459 
7460         case 0xd9: /* VMMCALL */
7461             if (!(s->flags & HF_SVME_MASK)) {
7462                 goto illegal_op;
7463             }
7464             gen_update_cc_op(s);
7465             gen_jmp_im(s, pc_start - s->cs_base);
7466             gen_helper_vmmcall(cpu_env);
7467             break;
7468 
7469         case 0xda: /* VMLOAD */
7470             if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7471                 goto illegal_op;
7472             }
7473             if (s->cpl != 0) {
7474                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7475                 break;
7476             }
7477             gen_update_cc_op(s);
7478             gen_jmp_im(s, pc_start - s->cs_base);
7479             gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
7480             break;
7481 
7482         case 0xdb: /* VMSAVE */
7483             if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7484                 goto illegal_op;
7485             }
7486             if (s->cpl != 0) {
7487                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7488                 break;
7489             }
7490             gen_update_cc_op(s);
7491             gen_jmp_im(s, pc_start - s->cs_base);
7492             gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
7493             break;
7494 
7495         case 0xdc: /* STGI */
7496             if ((!(s->flags & HF_SVME_MASK)
7497                    && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7498                 || !s->pe) {
7499                 goto illegal_op;
7500             }
7501             if (s->cpl != 0) {
7502                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7503                 break;
7504             }
7505             gen_update_cc_op(s);
7506             gen_helper_stgi(cpu_env);
7507             gen_jmp_im(s, s->pc - s->cs_base);
7508             gen_eob(s);
7509             break;
7510 
7511         case 0xdd: /* CLGI */
7512             if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7513                 goto illegal_op;
7514             }
7515             if (s->cpl != 0) {
7516                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7517                 break;
7518             }
7519             gen_update_cc_op(s);
7520             gen_jmp_im(s, pc_start - s->cs_base);
7521             gen_helper_clgi(cpu_env);
7522             break;
7523 
7524         case 0xde: /* SKINIT */
7525             if ((!(s->flags & HF_SVME_MASK)
7526                  && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
7527                 || !s->pe) {
7528                 goto illegal_op;
7529             }
7530             gen_update_cc_op(s);
7531             gen_jmp_im(s, pc_start - s->cs_base);
7532             gen_helper_skinit(cpu_env);
7533             break;
7534 
7535         case 0xdf: /* INVLPGA */
7536             if (!(s->flags & HF_SVME_MASK) || !s->pe) {
7537                 goto illegal_op;
7538             }
7539             if (s->cpl != 0) {
7540                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7541                 break;
7542             }
7543             gen_update_cc_op(s);
7544             gen_jmp_im(s, pc_start - s->cs_base);
7545             gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag - 1));
7546             break;
7547 
7548         CASE_MODRM_MEM_OP(2): /* lgdt */
7549             if (s->cpl != 0) {
7550                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7551                 break;
7552             }
7553             gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
7554             gen_lea_modrm(env, s, modrm);
7555             gen_op_ld_v(s, MO_16, s->T1, s->A0);
7556             gen_add_A0_im(s, 2);
7557             gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
7558             if (dflag == MO_16) {
7559                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
7560             }
7561             tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, gdt.base));
7562             tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, gdt.limit));
7563             break;
7564 
7565         CASE_MODRM_MEM_OP(3): /* lidt */
7566             if (s->cpl != 0) {
7567                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7568                 break;
7569             }
7570             gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
7571             gen_lea_modrm(env, s, modrm);
7572             gen_op_ld_v(s, MO_16, s->T1, s->A0);
7573             gen_add_A0_im(s, 2);
7574             gen_op_ld_v(s, CODE64(s) + MO_32, s->T0, s->A0);
7575             if (dflag == MO_16) {
7576                 tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
7577             }
7578             tcg_gen_st_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.base));
7579             tcg_gen_st32_tl(s->T1, cpu_env, offsetof(CPUX86State, idt.limit));
7580             break;
7581 
7582         CASE_MODRM_OP(4): /* smsw */
7583             gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
7584             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, cr[0]));
7585             if (CODE64(s)) {
7586                 mod = (modrm >> 6) & 3;
7587                 ot = (mod != 3 ? MO_16 : s->dflag);
7588             } else {
7589                 ot = MO_16;
7590             }
7591             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
7592             break;
7593         case 0xee: /* rdpkru */
7594             if (prefixes & PREFIX_LOCK) {
7595                 goto illegal_op;
7596             }
7597             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
7598             gen_helper_rdpkru(s->tmp1_i64, cpu_env, s->tmp2_i32);
7599             tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
7600             break;
7601         case 0xef: /* wrpkru */
7602             if (prefixes & PREFIX_LOCK) {
7603                 goto illegal_op;
7604             }
7605             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
7606                                   cpu_regs[R_EDX]);
7607             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
7608             gen_helper_wrpkru(cpu_env, s->tmp2_i32, s->tmp1_i64);
7609             break;
7610         CASE_MODRM_OP(6): /* lmsw */
7611             if (s->cpl != 0) {
7612                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7613                 break;
7614             }
7615             gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
7616             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7617             gen_helper_lmsw(cpu_env, s->T0);
7618             gen_jmp_im(s, s->pc - s->cs_base);
7619             gen_eob(s);
7620             break;
7621 
7622         CASE_MODRM_MEM_OP(7): /* invlpg */
7623             if (s->cpl != 0) {
7624                 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7625                 break;
7626             }
7627             gen_update_cc_op(s);
7628             gen_jmp_im(s, pc_start - s->cs_base);
7629             gen_lea_modrm(env, s, modrm);
7630             gen_helper_invlpg(cpu_env, s->A0);
7631             gen_jmp_im(s, s->pc - s->cs_base);
7632             gen_eob(s);
7633             break;
7634 
7635         case 0xf8: /* swapgs */
7636 #ifdef TARGET_X86_64
7637             if (CODE64(s)) {
7638                 if (s->cpl != 0) {
7639                     gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7640                 } else {
7641                     tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]);
7642                     tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
7643                                   offsetof(CPUX86State, kernelgsbase));
7644                     tcg_gen_st_tl(s->T0, cpu_env,
7645                                   offsetof(CPUX86State, kernelgsbase));
7646                 }
7647                 break;
7648             }
7649 #endif
7650             goto illegal_op;
7651 
7652         case 0xf9: /* rdtscp */
7653             if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP)) {
7654                 goto illegal_op;
7655             }
7656             gen_update_cc_op(s);
7657             gen_jmp_im(s, pc_start - s->cs_base);
7658             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7659                 gen_io_start();
7660             }
7661             gen_helper_rdtscp(cpu_env);
7662             if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7663                 gen_jmp(s, s->pc - s->cs_base);
7664             }
7665             break;
7666 
7667         default:
7668             goto unknown_op;
7669         }
7670         break;
7671 
7672     case 0x108: /* invd */
7673     case 0x109: /* wbinvd */
7674         if (s->cpl != 0) {
7675             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
7676         } else {
7677             gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
7678             /* nothing to do */
7679         }
7680         break;
7681     case 0x63: /* arpl or movslS (x86_64) */
7682 #ifdef TARGET_X86_64
7683         if (CODE64(s)) {
7684             int d_ot;
7685             /* d_ot is the size of destination */
7686             d_ot = dflag;
7687 
7688             modrm = x86_ldub_code(env, s);
7689             reg = ((modrm >> 3) & 7) | rex_r;
7690             mod = (modrm >> 6) & 3;
7691             rm = (modrm & 7) | REX_B(s);
7692 
7693             if (mod == 3) {
7694                 gen_op_mov_v_reg(s, MO_32, s->T0, rm);
7695                 /* sign extend */
7696                 if (d_ot == MO_64) {
7697                     tcg_gen_ext32s_tl(s->T0, s->T0);
7698                 }
7699                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
7700             } else {
7701                 gen_lea_modrm(env, s, modrm);
7702                 gen_op_ld_v(s, MO_32 | MO_SIGN, s->T0, s->A0);
7703                 gen_op_mov_reg_v(s, d_ot, reg, s->T0);
7704             }
7705         } else
7706 #endif
7707         {
7708             TCGLabel *label1;
7709             TCGv t0, t1, t2, a0;
7710 
7711             if (!s->pe || s->vm86)
7712                 goto illegal_op;
7713             t0 = tcg_temp_local_new();
7714             t1 = tcg_temp_local_new();
7715             t2 = tcg_temp_local_new();
7716             ot = MO_16;
7717             modrm = x86_ldub_code(env, s);
7718             reg = (modrm >> 3) & 7;
7719             mod = (modrm >> 6) & 3;
7720             rm = modrm & 7;
7721             if (mod != 3) {
7722                 gen_lea_modrm(env, s, modrm);
7723                 gen_op_ld_v(s, ot, t0, s->A0);
7724                 a0 = tcg_temp_local_new();
7725                 tcg_gen_mov_tl(a0, s->A0);
7726             } else {
7727                 gen_op_mov_v_reg(s, ot, t0, rm);
7728                 a0 = NULL;
7729             }
7730             gen_op_mov_v_reg(s, ot, t1, reg);
7731             tcg_gen_andi_tl(s->tmp0, t0, 3);
7732             tcg_gen_andi_tl(t1, t1, 3);
7733             tcg_gen_movi_tl(t2, 0);
7734             label1 = gen_new_label();
7735             tcg_gen_brcond_tl(TCG_COND_GE, s->tmp0, t1, label1);
7736             tcg_gen_andi_tl(t0, t0, ~3);
7737             tcg_gen_or_tl(t0, t0, t1);
7738             tcg_gen_movi_tl(t2, CC_Z);
7739             gen_set_label(label1);
7740             if (mod != 3) {
7741                 gen_op_st_v(s, ot, t0, a0);
7742                 tcg_temp_free(a0);
7743            } else {
7744                 gen_op_mov_reg_v(s, ot, rm, t0);
7745             }
7746             gen_compute_eflags(s);
7747             tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_Z);
7748             tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t2);
7749             tcg_temp_free(t0);
7750             tcg_temp_free(t1);
7751             tcg_temp_free(t2);
7752         }
7753         break;
7754     case 0x102: /* lar */
7755     case 0x103: /* lsl */
7756         {
7757             TCGLabel *label1;
7758             TCGv t0;
7759             if (!s->pe || s->vm86)
7760                 goto illegal_op;
7761             ot = dflag != MO_16 ? MO_32 : MO_16;
7762             modrm = x86_ldub_code(env, s);
7763             reg = ((modrm >> 3) & 7) | rex_r;
7764             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
7765             t0 = tcg_temp_local_new();
7766             gen_update_cc_op(s);
7767             if (b == 0x102) {
7768                 gen_helper_lar(t0, cpu_env, s->T0);
7769             } else {
7770                 gen_helper_lsl(t0, cpu_env, s->T0);
7771             }
7772             tcg_gen_andi_tl(s->tmp0, cpu_cc_src, CC_Z);
7773             label1 = gen_new_label();
7774             tcg_gen_brcondi_tl(TCG_COND_EQ, s->tmp0, 0, label1);
7775             gen_op_mov_reg_v(s, ot, reg, t0);
7776             gen_set_label(label1);
7777             set_cc_op(s, CC_OP_EFLAGS);
7778             tcg_temp_free(t0);
7779         }
7780         break;
7781     case 0x118:
7782         modrm = x86_ldub_code(env, s);
7783         mod = (modrm >> 6) & 3;
7784         op = (modrm >> 3) & 7;
7785         switch(op) {
7786         case 0: /* prefetchnta */
7787         case 1: /* prefetchnt0 */
7788         case 2: /* prefetchnt0 */
7789         case 3: /* prefetchnt0 */
7790             if (mod == 3)
7791                 goto illegal_op;
7792             gen_nop_modrm(env, s, modrm);
7793             /* nothing more to do */
7794             break;
7795         default: /* nop (multi byte) */
7796             gen_nop_modrm(env, s, modrm);
7797             break;
7798         }
7799         break;
7800     case 0x11a:
7801         modrm = x86_ldub_code(env, s);
7802         if (s->flags & HF_MPX_EN_MASK) {
7803             mod = (modrm >> 6) & 3;
7804             reg = ((modrm >> 3) & 7) | rex_r;
7805             if (prefixes & PREFIX_REPZ) {
7806                 /* bndcl */
7807                 if (reg >= 4
7808                     || (prefixes & PREFIX_LOCK)
7809                     || s->aflag == MO_16) {
7810                     goto illegal_op;
7811                 }
7812                 gen_bndck(env, s, modrm, TCG_COND_LTU, cpu_bndl[reg]);
7813             } else if (prefixes & PREFIX_REPNZ) {
7814                 /* bndcu */
7815                 if (reg >= 4
7816                     || (prefixes & PREFIX_LOCK)
7817                     || s->aflag == MO_16) {
7818                     goto illegal_op;
7819                 }
7820                 TCGv_i64 notu = tcg_temp_new_i64();
7821                 tcg_gen_not_i64(notu, cpu_bndu[reg]);
7822                 gen_bndck(env, s, modrm, TCG_COND_GTU, notu);
7823                 tcg_temp_free_i64(notu);
7824             } else if (prefixes & PREFIX_DATA) {
7825                 /* bndmov -- from reg/mem */
7826                 if (reg >= 4 || s->aflag == MO_16) {
7827                     goto illegal_op;
7828                 }
7829                 if (mod == 3) {
7830                     int reg2 = (modrm & 7) | REX_B(s);
7831                     if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7832                         goto illegal_op;
7833                     }
7834                     if (s->flags & HF_MPX_IU_MASK) {
7835                         tcg_gen_mov_i64(cpu_bndl[reg], cpu_bndl[reg2]);
7836                         tcg_gen_mov_i64(cpu_bndu[reg], cpu_bndu[reg2]);
7837                     }
7838                 } else {
7839                     gen_lea_modrm(env, s, modrm);
7840                     if (CODE64(s)) {
7841                         tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
7842                                             s->mem_index, MO_LEQ);
7843                         tcg_gen_addi_tl(s->A0, s->A0, 8);
7844                         tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
7845                                             s->mem_index, MO_LEQ);
7846                     } else {
7847                         tcg_gen_qemu_ld_i64(cpu_bndl[reg], s->A0,
7848                                             s->mem_index, MO_LEUL);
7849                         tcg_gen_addi_tl(s->A0, s->A0, 4);
7850                         tcg_gen_qemu_ld_i64(cpu_bndu[reg], s->A0,
7851                                             s->mem_index, MO_LEUL);
7852                     }
7853                     /* bnd registers are now in-use */
7854                     gen_set_hflag(s, HF_MPX_IU_MASK);
7855                 }
7856             } else if (mod != 3) {
7857                 /* bndldx */
7858                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7859                 if (reg >= 4
7860                     || (prefixes & PREFIX_LOCK)
7861                     || s->aflag == MO_16
7862                     || a.base < -1) {
7863                     goto illegal_op;
7864                 }
7865                 if (a.base >= 0) {
7866                     tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
7867                 } else {
7868                     tcg_gen_movi_tl(s->A0, 0);
7869                 }
7870                 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
7871                 if (a.index >= 0) {
7872                     tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
7873                 } else {
7874                     tcg_gen_movi_tl(s->T0, 0);
7875                 }
7876                 if (CODE64(s)) {
7877                     gen_helper_bndldx64(cpu_bndl[reg], cpu_env, s->A0, s->T0);
7878                     tcg_gen_ld_i64(cpu_bndu[reg], cpu_env,
7879                                    offsetof(CPUX86State, mmx_t0.MMX_Q(0)));
7880                 } else {
7881                     gen_helper_bndldx32(cpu_bndu[reg], cpu_env, s->A0, s->T0);
7882                     tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndu[reg]);
7883                     tcg_gen_shri_i64(cpu_bndu[reg], cpu_bndu[reg], 32);
7884                 }
7885                 gen_set_hflag(s, HF_MPX_IU_MASK);
7886             }
7887         }
7888         gen_nop_modrm(env, s, modrm);
7889         break;
7890     case 0x11b:
7891         modrm = x86_ldub_code(env, s);
7892         if (s->flags & HF_MPX_EN_MASK) {
7893             mod = (modrm >> 6) & 3;
7894             reg = ((modrm >> 3) & 7) | rex_r;
7895             if (mod != 3 && (prefixes & PREFIX_REPZ)) {
7896                 /* bndmk */
7897                 if (reg >= 4
7898                     || (prefixes & PREFIX_LOCK)
7899                     || s->aflag == MO_16) {
7900                     goto illegal_op;
7901                 }
7902                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7903                 if (a.base >= 0) {
7904                     tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
7905                     if (!CODE64(s)) {
7906                         tcg_gen_ext32u_i64(cpu_bndl[reg], cpu_bndl[reg]);
7907                     }
7908                 } else if (a.base == -1) {
7909                     /* no base register has lower bound of 0 */
7910                     tcg_gen_movi_i64(cpu_bndl[reg], 0);
7911                 } else {
7912                     /* rip-relative generates #ud */
7913                     goto illegal_op;
7914                 }
7915                 tcg_gen_not_tl(s->A0, gen_lea_modrm_1(s, a));
7916                 if (!CODE64(s)) {
7917                     tcg_gen_ext32u_tl(s->A0, s->A0);
7918                 }
7919                 tcg_gen_extu_tl_i64(cpu_bndu[reg], s->A0);
7920                 /* bnd registers are now in-use */
7921                 gen_set_hflag(s, HF_MPX_IU_MASK);
7922                 break;
7923             } else if (prefixes & PREFIX_REPNZ) {
7924                 /* bndcn */
7925                 if (reg >= 4
7926                     || (prefixes & PREFIX_LOCK)
7927                     || s->aflag == MO_16) {
7928                     goto illegal_op;
7929                 }
7930                 gen_bndck(env, s, modrm, TCG_COND_GTU, cpu_bndu[reg]);
7931             } else if (prefixes & PREFIX_DATA) {
7932                 /* bndmov -- to reg/mem */
7933                 if (reg >= 4 || s->aflag == MO_16) {
7934                     goto illegal_op;
7935                 }
7936                 if (mod == 3) {
7937                     int reg2 = (modrm & 7) | REX_B(s);
7938                     if (reg2 >= 4 || (prefixes & PREFIX_LOCK)) {
7939                         goto illegal_op;
7940                     }
7941                     if (s->flags & HF_MPX_IU_MASK) {
7942                         tcg_gen_mov_i64(cpu_bndl[reg2], cpu_bndl[reg]);
7943                         tcg_gen_mov_i64(cpu_bndu[reg2], cpu_bndu[reg]);
7944                     }
7945                 } else {
7946                     gen_lea_modrm(env, s, modrm);
7947                     if (CODE64(s)) {
7948                         tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
7949                                             s->mem_index, MO_LEQ);
7950                         tcg_gen_addi_tl(s->A0, s->A0, 8);
7951                         tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
7952                                             s->mem_index, MO_LEQ);
7953                     } else {
7954                         tcg_gen_qemu_st_i64(cpu_bndl[reg], s->A0,
7955                                             s->mem_index, MO_LEUL);
7956                         tcg_gen_addi_tl(s->A0, s->A0, 4);
7957                         tcg_gen_qemu_st_i64(cpu_bndu[reg], s->A0,
7958                                             s->mem_index, MO_LEUL);
7959                     }
7960                 }
7961             } else if (mod != 3) {
7962                 /* bndstx */
7963                 AddressParts a = gen_lea_modrm_0(env, s, modrm);
7964                 if (reg >= 4
7965                     || (prefixes & PREFIX_LOCK)
7966                     || s->aflag == MO_16
7967                     || a.base < -1) {
7968                     goto illegal_op;
7969                 }
7970                 if (a.base >= 0) {
7971                     tcg_gen_addi_tl(s->A0, cpu_regs[a.base], a.disp);
7972                 } else {
7973                     tcg_gen_movi_tl(s->A0, 0);
7974                 }
7975                 gen_lea_v_seg(s, s->aflag, s->A0, a.def_seg, s->override);
7976                 if (a.index >= 0) {
7977                     tcg_gen_mov_tl(s->T0, cpu_regs[a.index]);
7978                 } else {
7979                     tcg_gen_movi_tl(s->T0, 0);
7980                 }
7981                 if (CODE64(s)) {
7982                     gen_helper_bndstx64(cpu_env, s->A0, s->T0,
7983                                         cpu_bndl[reg], cpu_bndu[reg]);
7984                 } else {
7985                     gen_helper_bndstx32(cpu_env, s->A0, s->T0,
7986                                         cpu_bndl[reg], cpu_bndu[reg]);
7987                 }
7988             }
7989         }
7990         gen_nop_modrm(env, s, modrm);
7991         break;
7992     case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
7993         modrm = x86_ldub_code(env, s);
7994         gen_nop_modrm(env, s, modrm);
7995         break;
7996     case 0x120: /* mov reg, crN */
7997     case 0x122: /* mov crN, reg */
7998         if (s->cpl != 0) {
7999             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
8000         } else {
8001             modrm = x86_ldub_code(env, s);
8002             /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8003              * AMD documentation (24594.pdf) and testing of
8004              * intel 386 and 486 processors all show that the mod bits
8005              * are assumed to be 1's, regardless of actual values.
8006              */
8007             rm = (modrm & 7) | REX_B(s);
8008             reg = ((modrm >> 3) & 7) | rex_r;
8009             if (CODE64(s))
8010                 ot = MO_64;
8011             else
8012                 ot = MO_32;
8013             if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
8014                 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
8015                 reg = 8;
8016             }
8017             switch(reg) {
8018             case 0:
8019             case 2:
8020             case 3:
8021             case 4:
8022             case 8:
8023                 gen_update_cc_op(s);
8024                 gen_jmp_im(s, pc_start - s->cs_base);
8025                 if (b & 2) {
8026                     if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
8027                         gen_io_start();
8028                     }
8029                     gen_op_mov_v_reg(s, ot, s->T0, rm);
8030                     gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
8031                                          s->T0);
8032                     gen_jmp_im(s, s->pc - s->cs_base);
8033                     gen_eob(s);
8034                 } else {
8035                     if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
8036                         gen_io_start();
8037                     }
8038                     gen_helper_read_crN(s->T0, cpu_env, tcg_const_i32(reg));
8039                     gen_op_mov_reg_v(s, ot, rm, s->T0);
8040                     if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
8041                         gen_io_end();
8042                     }
8043                 }
8044                 break;
8045             default:
8046                 goto unknown_op;
8047             }
8048         }
8049         break;
8050     case 0x121: /* mov reg, drN */
8051     case 0x123: /* mov drN, reg */
8052         if (s->cpl != 0) {
8053             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
8054         } else {
8055             modrm = x86_ldub_code(env, s);
8056             /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
8057              * AMD documentation (24594.pdf) and testing of
8058              * intel 386 and 486 processors all show that the mod bits
8059              * are assumed to be 1's, regardless of actual values.
8060              */
8061             rm = (modrm & 7) | REX_B(s);
8062             reg = ((modrm >> 3) & 7) | rex_r;
8063             if (CODE64(s))
8064                 ot = MO_64;
8065             else
8066                 ot = MO_32;
8067             if (reg >= 8) {
8068                 goto illegal_op;
8069             }
8070             if (b & 2) {
8071                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
8072                 gen_op_mov_v_reg(s, ot, s->T0, rm);
8073                 tcg_gen_movi_i32(s->tmp2_i32, reg);
8074                 gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0);
8075                 gen_jmp_im(s, s->pc - s->cs_base);
8076                 gen_eob(s);
8077             } else {
8078                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
8079                 tcg_gen_movi_i32(s->tmp2_i32, reg);
8080                 gen_helper_get_dr(s->T0, cpu_env, s->tmp2_i32);
8081                 gen_op_mov_reg_v(s, ot, rm, s->T0);
8082             }
8083         }
8084         break;
8085     case 0x106: /* clts */
8086         if (s->cpl != 0) {
8087             gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
8088         } else {
8089             gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
8090             gen_helper_clts(cpu_env);
8091             /* abort block because static cpu state changed */
8092             gen_jmp_im(s, s->pc - s->cs_base);
8093             gen_eob(s);
8094         }
8095         break;
8096     /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
8097     case 0x1c3: /* MOVNTI reg, mem */
8098         if (!(s->cpuid_features & CPUID_SSE2))
8099             goto illegal_op;
8100         ot = mo_64_32(dflag);
8101         modrm = x86_ldub_code(env, s);
8102         mod = (modrm >> 6) & 3;
8103         if (mod == 3)
8104             goto illegal_op;
8105         reg = ((modrm >> 3) & 7) | rex_r;
8106         /* generate a generic store */
8107         gen_ldst_modrm(env, s, modrm, ot, reg, 1);
8108         break;
8109     case 0x1ae:
8110         modrm = x86_ldub_code(env, s);
8111         switch (modrm) {
8112         CASE_MODRM_MEM_OP(0): /* fxsave */
8113             if (!(s->cpuid_features & CPUID_FXSR)
8114                 || (prefixes & PREFIX_LOCK)) {
8115                 goto illegal_op;
8116             }
8117             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8118                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8119                 break;
8120             }
8121             gen_lea_modrm(env, s, modrm);
8122             gen_helper_fxsave(cpu_env, s->A0);
8123             break;
8124 
8125         CASE_MODRM_MEM_OP(1): /* fxrstor */
8126             if (!(s->cpuid_features & CPUID_FXSR)
8127                 || (prefixes & PREFIX_LOCK)) {
8128                 goto illegal_op;
8129             }
8130             if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
8131                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8132                 break;
8133             }
8134             gen_lea_modrm(env, s, modrm);
8135             gen_helper_fxrstor(cpu_env, s->A0);
8136             break;
8137 
8138         CASE_MODRM_MEM_OP(2): /* ldmxcsr */
8139             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8140                 goto illegal_op;
8141             }
8142             if (s->flags & HF_TS_MASK) {
8143                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8144                 break;
8145             }
8146             gen_lea_modrm(env, s, modrm);
8147             tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
8148             gen_helper_ldmxcsr(cpu_env, s->tmp2_i32);
8149             break;
8150 
8151         CASE_MODRM_MEM_OP(3): /* stmxcsr */
8152             if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK)) {
8153                 goto illegal_op;
8154             }
8155             if (s->flags & HF_TS_MASK) {
8156                 gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
8157                 break;
8158             }
8159             gen_lea_modrm(env, s, modrm);
8160             tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, mxcsr));
8161             gen_op_st_v(s, MO_32, s->T0, s->A0);
8162             break;
8163 
8164         CASE_MODRM_MEM_OP(4): /* xsave */
8165             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8166                 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8167                                 | PREFIX_REPZ | PREFIX_REPNZ))) {
8168                 goto illegal_op;
8169             }
8170             gen_lea_modrm(env, s, modrm);
8171             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
8172                                   cpu_regs[R_EDX]);
8173             gen_helper_xsave(cpu_env, s->A0, s->tmp1_i64);
8174             break;
8175 
8176         CASE_MODRM_MEM_OP(5): /* xrstor */
8177             if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8178                 || (prefixes & (PREFIX_LOCK | PREFIX_DATA
8179                                 | PREFIX_REPZ | PREFIX_REPNZ))) {
8180                 goto illegal_op;
8181             }
8182             gen_lea_modrm(env, s, modrm);
8183             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
8184                                   cpu_regs[R_EDX]);
8185             gen_helper_xrstor(cpu_env, s->A0, s->tmp1_i64);
8186             /* XRSTOR is how MPX is enabled, which changes how
8187                we translate.  Thus we need to end the TB.  */
8188             gen_update_cc_op(s);
8189             gen_jmp_im(s, s->pc - s->cs_base);
8190             gen_eob(s);
8191             break;
8192 
8193         CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
8194             if (prefixes & PREFIX_LOCK) {
8195                 goto illegal_op;
8196             }
8197             if (prefixes & PREFIX_DATA) {
8198                 /* clwb */
8199                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB)) {
8200                     goto illegal_op;
8201                 }
8202                 gen_nop_modrm(env, s, modrm);
8203             } else {
8204                 /* xsaveopt */
8205                 if ((s->cpuid_ext_features & CPUID_EXT_XSAVE) == 0
8206                     || (s->cpuid_xsave_features & CPUID_XSAVE_XSAVEOPT) == 0
8207                     || (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))) {
8208                     goto illegal_op;
8209                 }
8210                 gen_lea_modrm(env, s, modrm);
8211                 tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
8212                                       cpu_regs[R_EDX]);
8213                 gen_helper_xsaveopt(cpu_env, s->A0, s->tmp1_i64);
8214             }
8215             break;
8216 
8217         CASE_MODRM_MEM_OP(7): /* clflush / clflushopt */
8218             if (prefixes & PREFIX_LOCK) {
8219                 goto illegal_op;
8220             }
8221             if (prefixes & PREFIX_DATA) {
8222                 /* clflushopt */
8223                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT)) {
8224                     goto illegal_op;
8225                 }
8226             } else {
8227                 /* clflush */
8228                 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ))
8229                     || !(s->cpuid_features & CPUID_CLFLUSH)) {
8230                     goto illegal_op;
8231                 }
8232             }
8233             gen_nop_modrm(env, s, modrm);
8234             break;
8235 
8236         case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
8237         case 0xc8 ... 0xcf: /* rdgsbase (f3 0f ae /1) */
8238         case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
8239         case 0xd8 ... 0xdf: /* wrgsbase (f3 0f ae /3) */
8240             if (CODE64(s)
8241                 && (prefixes & PREFIX_REPZ)
8242                 && !(prefixes & PREFIX_LOCK)
8243                 && (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
8244                 TCGv base, treg, src, dst;
8245 
8246                 /* Preserve hflags bits by testing CR4 at runtime.  */
8247                 tcg_gen_movi_i32(s->tmp2_i32, CR4_FSGSBASE_MASK);
8248                 gen_helper_cr4_testbit(cpu_env, s->tmp2_i32);
8249 
8250                 base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
8251                 treg = cpu_regs[(modrm & 7) | REX_B(s)];
8252 
8253                 if (modrm & 0x10) {
8254                     /* wr*base */
8255                     dst = base, src = treg;
8256                 } else {
8257                     /* rd*base */
8258                     dst = treg, src = base;
8259                 }
8260 
8261                 if (s->dflag == MO_32) {
8262                     tcg_gen_ext32u_tl(dst, src);
8263                 } else {
8264                     tcg_gen_mov_tl(dst, src);
8265                 }
8266                 break;
8267             }
8268             goto unknown_op;
8269 
8270         case 0xf8: /* sfence / pcommit */
8271             if (prefixes & PREFIX_DATA) {
8272                 /* pcommit */
8273                 if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT)
8274                     || (prefixes & PREFIX_LOCK)) {
8275                     goto illegal_op;
8276                 }
8277                 break;
8278             }
8279             /* fallthru */
8280         case 0xf9 ... 0xff: /* sfence */
8281             if (!(s->cpuid_features & CPUID_SSE)
8282                 || (prefixes & PREFIX_LOCK)) {
8283                 goto illegal_op;
8284             }
8285             tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
8286             break;
8287         case 0xe8 ... 0xef: /* lfence */
8288             if (!(s->cpuid_features & CPUID_SSE)
8289                 || (prefixes & PREFIX_LOCK)) {
8290                 goto illegal_op;
8291             }
8292             tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
8293             break;
8294         case 0xf0 ... 0xf7: /* mfence */
8295             if (!(s->cpuid_features & CPUID_SSE2)
8296                 || (prefixes & PREFIX_LOCK)) {
8297                 goto illegal_op;
8298             }
8299             tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8300             break;
8301 
8302         default:
8303             goto unknown_op;
8304         }
8305         break;
8306 
8307     case 0x10d: /* 3DNow! prefetch(w) */
8308         modrm = x86_ldub_code(env, s);
8309         mod = (modrm >> 6) & 3;
8310         if (mod == 3)
8311             goto illegal_op;
8312         gen_nop_modrm(env, s, modrm);
8313         break;
8314     case 0x1aa: /* rsm */
8315         gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
8316         if (!(s->flags & HF_SMM_MASK))
8317             goto illegal_op;
8318         gen_update_cc_op(s);
8319         gen_jmp_im(s, s->pc - s->cs_base);
8320         gen_helper_rsm(cpu_env);
8321         gen_eob(s);
8322         break;
8323     case 0x1b8: /* SSE4.2 popcnt */
8324         if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
8325              PREFIX_REPZ)
8326             goto illegal_op;
8327         if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
8328             goto illegal_op;
8329 
8330         modrm = x86_ldub_code(env, s);
8331         reg = ((modrm >> 3) & 7) | rex_r;
8332 
8333         if (s->prefix & PREFIX_DATA) {
8334             ot = MO_16;
8335         } else {
8336             ot = mo_64_32(dflag);
8337         }
8338 
8339         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
8340         gen_extu(ot, s->T0);
8341         tcg_gen_mov_tl(cpu_cc_src, s->T0);
8342         tcg_gen_ctpop_tl(s->T0, s->T0);
8343         gen_op_mov_reg_v(s, ot, reg, s->T0);
8344 
8345         set_cc_op(s, CC_OP_POPCNT);
8346         break;
8347     case 0x10e ... 0x10f:
8348         /* 3DNow! instructions, ignore prefixes */
8349         s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
8350         /* fall through */
8351     case 0x110 ... 0x117:
8352     case 0x128 ... 0x12f:
8353     case 0x138 ... 0x13a:
8354     case 0x150 ... 0x179:
8355     case 0x17c ... 0x17f:
8356     case 0x1c2:
8357     case 0x1c4 ... 0x1c6:
8358     case 0x1d0 ... 0x1fe:
8359         gen_sse(env, s, b, pc_start, rex_r);
8360         break;
8361     default:
8362         goto unknown_op;
8363     }
8364     return s->pc;
8365  illegal_op:
8366     gen_illegal_opcode(s);
8367     return s->pc;
8368  unknown_op:
8369     gen_unknown_opcode(env, s);
8370     return s->pc;
8371 }
8372 
tcg_x86_init(void)8373 void tcg_x86_init(void)
8374 {
8375     static const char reg_names[CPU_NB_REGS][4] = {
8376 #ifdef TARGET_X86_64
8377         [R_EAX] = "rax",
8378         [R_EBX] = "rbx",
8379         [R_ECX] = "rcx",
8380         [R_EDX] = "rdx",
8381         [R_ESI] = "rsi",
8382         [R_EDI] = "rdi",
8383         [R_EBP] = "rbp",
8384         [R_ESP] = "rsp",
8385         [8]  = "r8",
8386         [9]  = "r9",
8387         [10] = "r10",
8388         [11] = "r11",
8389         [12] = "r12",
8390         [13] = "r13",
8391         [14] = "r14",
8392         [15] = "r15",
8393 #else
8394         [R_EAX] = "eax",
8395         [R_EBX] = "ebx",
8396         [R_ECX] = "ecx",
8397         [R_EDX] = "edx",
8398         [R_ESI] = "esi",
8399         [R_EDI] = "edi",
8400         [R_EBP] = "ebp",
8401         [R_ESP] = "esp",
8402 #endif
8403     };
8404     static const char seg_base_names[6][8] = {
8405         [R_CS] = "cs_base",
8406         [R_DS] = "ds_base",
8407         [R_ES] = "es_base",
8408         [R_FS] = "fs_base",
8409         [R_GS] = "gs_base",
8410         [R_SS] = "ss_base",
8411     };
8412     static const char bnd_regl_names[4][8] = {
8413         "bnd0_lb", "bnd1_lb", "bnd2_lb", "bnd3_lb"
8414     };
8415     static const char bnd_regu_names[4][8] = {
8416         "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
8417     };
8418     int i;
8419 
8420     cpu_cc_op = tcg_global_mem_new_i32(cpu_env,
8421                                        offsetof(CPUX86State, cc_op), "cc_op");
8422     cpu_cc_dst = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_dst),
8423                                     "cc_dst");
8424     cpu_cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src),
8425                                     "cc_src");
8426     cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
8427                                      "cc_src2");
8428 
8429     for (i = 0; i < CPU_NB_REGS; ++i) {
8430         cpu_regs[i] = tcg_global_mem_new(cpu_env,
8431                                          offsetof(CPUX86State, regs[i]),
8432                                          reg_names[i]);
8433     }
8434 
8435     for (i = 0; i < 6; ++i) {
8436         cpu_seg_base[i]
8437             = tcg_global_mem_new(cpu_env,
8438                                  offsetof(CPUX86State, segs[i].base),
8439                                  seg_base_names[i]);
8440     }
8441 
8442     for (i = 0; i < 4; ++i) {
8443         cpu_bndl[i]
8444             = tcg_global_mem_new_i64(cpu_env,
8445                                      offsetof(CPUX86State, bnd_regs[i].lb),
8446                                      bnd_regl_names[i]);
8447         cpu_bndu[i]
8448             = tcg_global_mem_new_i64(cpu_env,
8449                                      offsetof(CPUX86State, bnd_regs[i].ub),
8450                                      bnd_regu_names[i]);
8451     }
8452 }
8453 
i386_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cpu)8454 static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
8455 {
8456     DisasContext *dc = container_of(dcbase, DisasContext, base);
8457     CPUX86State *env = cpu->env_ptr;
8458     uint32_t flags = dc->base.tb->flags;
8459     target_ulong cs_base = dc->base.tb->cs_base;
8460 
8461     dc->pe = (flags >> HF_PE_SHIFT) & 1;
8462     dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
8463     dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
8464     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
8465     dc->f_st = 0;
8466     dc->vm86 = (flags >> VM_SHIFT) & 1;
8467     dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
8468     dc->iopl = (flags >> IOPL_SHIFT) & 3;
8469     dc->tf = (flags >> TF_SHIFT) & 1;
8470     dc->cc_op = CC_OP_DYNAMIC;
8471     dc->cc_op_dirty = false;
8472     dc->cs_base = cs_base;
8473     dc->popl_esp_hack = 0;
8474     /* select memory access functions */
8475     dc->mem_index = 0;
8476 #ifdef CONFIG_SOFTMMU
8477     dc->mem_index = cpu_mmu_index(env, false);
8478 #endif
8479     dc->cpuid_features = env->features[FEAT_1_EDX];
8480     dc->cpuid_ext_features = env->features[FEAT_1_ECX];
8481     dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
8482     dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
8483     dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
8484     dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
8485 #ifdef TARGET_X86_64
8486     dc->lma = (flags >> HF_LMA_SHIFT) & 1;
8487     dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
8488 #endif
8489     dc->flags = flags;
8490     dc->jmp_opt = !(dc->tf || dc->base.singlestep_enabled ||
8491                     (flags & HF_INHIBIT_IRQ_MASK));
8492     /* Do not optimize repz jumps at all in icount mode, because
8493        rep movsS instructions are execured with different paths
8494        in !repz_opt and repz_opt modes. The first one was used
8495        always except single step mode. And this setting
8496        disables jumps optimization and control paths become
8497        equivalent in run and single step modes.
8498        Now there will be no jump optimization for repz in
8499        record/replay modes and there will always be an
8500        additional step for ecx=0 when icount is enabled.
8501      */
8502     dc->repz_opt = !dc->jmp_opt && !(tb_cflags(dc->base.tb) & CF_USE_ICOUNT);
8503 #if 0
8504     /* check addseg logic */
8505     if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
8506         printf("ERROR addseg\n");
8507 #endif
8508 
8509     dc->T0 = tcg_temp_new();
8510     dc->T1 = tcg_temp_new();
8511     dc->A0 = tcg_temp_new();
8512 
8513     dc->tmp0 = tcg_temp_new();
8514     dc->tmp1_i64 = tcg_temp_new_i64();
8515     dc->tmp2_i32 = tcg_temp_new_i32();
8516     dc->tmp3_i32 = tcg_temp_new_i32();
8517     dc->tmp4 = tcg_temp_new();
8518     dc->ptr0 = tcg_temp_new_ptr();
8519     dc->ptr1 = tcg_temp_new_ptr();
8520     dc->cc_srcT = tcg_temp_local_new();
8521 }
8522 
i386_tr_tb_start(DisasContextBase * db,CPUState * cpu)8523 static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
8524 {
8525 }
8526 
i386_tr_insn_start(DisasContextBase * dcbase,CPUState * cpu)8527 static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
8528 {
8529     DisasContext *dc = container_of(dcbase, DisasContext, base);
8530 
8531     tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
8532 }
8533 
i386_tr_breakpoint_check(DisasContextBase * dcbase,CPUState * cpu,const CPUBreakpoint * bp)8534 static bool i386_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
8535                                      const CPUBreakpoint *bp)
8536 {
8537     DisasContext *dc = container_of(dcbase, DisasContext, base);
8538     /* If RF is set, suppress an internally generated breakpoint.  */
8539     int flags = dc->base.tb->flags & HF_RF_MASK ? BP_GDB : BP_ANY;
8540     if (bp->flags & flags) {
8541         gen_debug(dc, dc->base.pc_next - dc->cs_base);
8542         dc->base.is_jmp = DISAS_NORETURN;
8543         /* The address covered by the breakpoint must be included in
8544            [tb->pc, tb->pc + tb->size) in order to for it to be
8545            properly cleared -- thus we increment the PC here so that
8546            the generic logic setting tb->size later does the right thing.  */
8547         dc->base.pc_next += 1;
8548         return true;
8549     } else {
8550         return false;
8551     }
8552 }
8553 
i386_tr_translate_insn(DisasContextBase * dcbase,CPUState * cpu)8554 static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
8555 {
8556     DisasContext *dc = container_of(dcbase, DisasContext, base);
8557     target_ulong pc_next = disas_insn(dc, cpu);
8558 
8559     if (dc->tf || (dc->base.tb->flags & HF_INHIBIT_IRQ_MASK)) {
8560         /* if single step mode, we generate only one instruction and
8561            generate an exception */
8562         /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
8563            the flag and abort the translation to give the irqs a
8564            chance to happen */
8565         dc->base.is_jmp = DISAS_TOO_MANY;
8566     } else if ((tb_cflags(dc->base.tb) & CF_USE_ICOUNT)
8567                && ((pc_next & TARGET_PAGE_MASK)
8568                    != ((pc_next + TARGET_MAX_INSN_SIZE - 1)
8569                        & TARGET_PAGE_MASK)
8570                    || (pc_next & ~TARGET_PAGE_MASK) == 0)) {
8571         /* Do not cross the boundary of the pages in icount mode,
8572            it can cause an exception. Do it only when boundary is
8573            crossed by the first instruction in the block.
8574            If current instruction already crossed the bound - it's ok,
8575            because an exception hasn't stopped this code.
8576          */
8577         dc->base.is_jmp = DISAS_TOO_MANY;
8578     } else if ((pc_next - dc->base.pc_first) >= (TARGET_PAGE_SIZE - 32)) {
8579         dc->base.is_jmp = DISAS_TOO_MANY;
8580     }
8581 
8582     dc->base.pc_next = pc_next;
8583 }
8584 
i386_tr_tb_stop(DisasContextBase * dcbase,CPUState * cpu)8585 static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
8586 {
8587     DisasContext *dc = container_of(dcbase, DisasContext, base);
8588 
8589     if (dc->base.is_jmp == DISAS_TOO_MANY) {
8590         gen_jmp_im(dc, dc->base.pc_next - dc->cs_base);
8591         gen_eob(dc);
8592     }
8593 }
8594 
i386_tr_disas_log(const DisasContextBase * dcbase,CPUState * cpu)8595 static void i386_tr_disas_log(const DisasContextBase *dcbase,
8596                               CPUState *cpu)
8597 {
8598     DisasContext *dc = container_of(dcbase, DisasContext, base);
8599 
8600     qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
8601     log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
8602 }
8603 
8604 static const TranslatorOps i386_tr_ops = {
8605     .init_disas_context = i386_tr_init_disas_context,
8606     .tb_start           = i386_tr_tb_start,
8607     .insn_start         = i386_tr_insn_start,
8608     .breakpoint_check   = i386_tr_breakpoint_check,
8609     .translate_insn     = i386_tr_translate_insn,
8610     .tb_stop            = i386_tr_tb_stop,
8611     .disas_log          = i386_tr_disas_log,
8612 };
8613 
8614 /* generate intermediate code for basic block 'tb'.  */
gen_intermediate_code(CPUState * cpu,TranslationBlock * tb,int max_insns)8615 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
8616 {
8617     DisasContext dc;
8618 
8619     translator_loop(&i386_tr_ops, &dc.base, cpu, tb, max_insns);
8620 }
8621 
restore_state_to_opc(CPUX86State * env,TranslationBlock * tb,target_ulong * data)8622 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
8623                           target_ulong *data)
8624 {
8625     int cc_op = data[1];
8626     env->eip = data[0] - tb->cs_base;
8627     if (cc_op != CC_OP_DYNAMIC) {
8628         env->cc_op = cc_op;
8629     }
8630 }
8631