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